mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-28 18:15:46 +00:00
Texture manager rewrite to add sampler support (used by shaders)
Renderer target rewrite to remove FBO support (better fps) Render to texture support restored
This commit is contained in:
@ -1,252 +0,0 @@
|
||||
/**
|
||||
* projectM -- Milkdrop-esque visualisation SDK
|
||||
* Copyright (C)2003-2004 projectM Team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* See 'LICENSE.txt' included within this release
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* $Id: FBO.c,v 1.1.1.1 2005/12/23 18:05:00 psperl Exp $
|
||||
*
|
||||
* Render this methods
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include "Common.hpp"
|
||||
#include "FBO.hpp"
|
||||
|
||||
RenderTarget::~RenderTarget() {
|
||||
|
||||
|
||||
glDeleteTextures( 1, &this->textureID[0]);
|
||||
|
||||
#ifdef USE_FBO
|
||||
if (useFBO)
|
||||
{
|
||||
glDeleteTextures( 1, &this->textureID[1] );
|
||||
glDeleteRenderbuffers(1, &this->depthb[0]);
|
||||
glDeleteFramebuffers(1, &this->fbuffer[0]);
|
||||
if(renderToTexture)
|
||||
{
|
||||
glDeleteTextures( 1, &this->textureID[2] );
|
||||
glDeleteRenderbuffers(1, &this->depthb[1]);
|
||||
glDeleteFramebuffers(1, &this->fbuffer[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
GLuint RenderTarget::initRenderToTexture()
|
||||
{
|
||||
#ifdef USE_FBO
|
||||
|
||||
if (this->useFBO==1)
|
||||
{
|
||||
if (this->renderToTexture == 1) {
|
||||
return this->textureID[2];
|
||||
}
|
||||
|
||||
this->renderToTexture=1;
|
||||
|
||||
GLuint fb2, depth_rb2;
|
||||
glGenFramebuffers(1, &fb2);
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, fb2 );
|
||||
this->fbuffer[1] = fb2;
|
||||
this->depthb[1]= depth_rb2;
|
||||
glGenTextures(1, &this->textureID[2]);
|
||||
glBindTexture(GL_TEXTURE_2D, this->textureID[2]);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->textureID[2], 0 );
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||
return this->textureID[2];
|
||||
}
|
||||
|
||||
std::cerr << "[projecM] warning: initRenderToTexture failed." << std::endl;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/** Creates new pbuffers */
|
||||
RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) {
|
||||
|
||||
int mindim = 0;
|
||||
int origtexsize = 0;
|
||||
|
||||
this->renderToTexture = 0;
|
||||
this->texsize = texsize;
|
||||
|
||||
#ifdef USE_FBO
|
||||
|
||||
useFBO = true;
|
||||
|
||||
GLuint fb, depth_rb, rgba_tex, other_tex;
|
||||
glGenFramebuffers(1, &fb);
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, fb );
|
||||
|
||||
this->fbuffer[0] = fb;
|
||||
this->depthb[0]= depth_rb;
|
||||
|
||||
glGenTextures(1, &other_tex);
|
||||
glBindTexture(GL_TEXTURE_2D,other_tex);
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glGenerateMipmapEXT(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
||||
|
||||
glGenTextures(1, &rgba_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, rgba_tex);
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glGenerateMipmapEXT(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgba_tex, 0 );
|
||||
this->textureID[0] = rgba_tex;
|
||||
this->textureID[1] = other_tex;
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
// Can reach here via two code paths:
|
||||
// (1) useFBO was set to false externally by cmake / system setting / etc.
|
||||
// (2) useFBO was true but forced to false as it failed to pass all the GLU extension checks.
|
||||
|
||||
/** Fallback pbuffer creation via teximage hack */
|
||||
/** Check the texture size against the viewport size */
|
||||
/** If the viewport is smaller, then we'll need to scale the texture size down */
|
||||
/** If the viewport is larger, scale it up */
|
||||
mindim = width < height ? width : height;
|
||||
origtexsize = this->texsize;
|
||||
this->texsize = nearestPower2( mindim, SCALE_MINIFY );
|
||||
glGenTextures(1, &this->textureID[0] );
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, this->textureID[0] );
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB,
|
||||
this->texsize, this->texsize,
|
||||
0,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** Locks the pbuffer */
|
||||
void RenderTarget::lock() {
|
||||
|
||||
#ifdef USE_FBO
|
||||
if(this->useFBO)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, this->fbuffer[0]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Unlocks the pbuffer */
|
||||
void RenderTarget::unlock() {
|
||||
|
||||
#ifdef USE_FBO
|
||||
if(this->useFBO)
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, this->textureID[1] );
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D,
|
||||
0, 0, 0, 0, 0,
|
||||
this->texsize, this->texsize );
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/** Fallback texture path */
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, this->textureID[0] );
|
||||
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, this->texsize, this->texsize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the nearest power of two to the given number using the
|
||||
* appropriate rule
|
||||
*/
|
||||
int RenderTarget::nearestPower2( int value, TextureScale scaleRule ) {
|
||||
|
||||
int x = value;
|
||||
int power = 0;
|
||||
|
||||
while ( ( x & 0x01 ) != 1 ) {
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
if ( x == 1 ) {
|
||||
return value;
|
||||
} else {
|
||||
x = value;
|
||||
while ( x != 0 ) {
|
||||
x >>= 1;
|
||||
power++;
|
||||
}
|
||||
switch ( scaleRule ) {
|
||||
case SCALE_NEAREST:
|
||||
if ( ( ( 1 << power ) - value ) <= ( value - ( 1 << ( power - 1 ) ) ) ) {
|
||||
return 1 << power;
|
||||
} else {
|
||||
return 1 << ( power - 1 );
|
||||
}
|
||||
case SCALE_MAGNIFY:
|
||||
return 1 << power;
|
||||
case SCALE_MINIFY:
|
||||
return 1 << ( power - 1 );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* projectM -- Milkdrop-esque visualisation SDK
|
||||
* Copyright (C)2003-2007 projectM Team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* See 'LICENSE.txt' included within this release
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* $Id: FBO.hpp,v 1.1.1.1 2005/12/23 18:05:00 psperl Exp $
|
||||
*
|
||||
* Opaque render target
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RENDERTARGET_H
|
||||
#define _RENDERTARGET_H
|
||||
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
typedef enum { SCALE_NEAREST, SCALE_MAGNIFY, SCALE_MINIFY } TextureScale;
|
||||
|
||||
class RenderTarget {
|
||||
|
||||
|
||||
public:
|
||||
/** Texture size */
|
||||
int texsize;
|
||||
|
||||
int useFBO;
|
||||
int renderToTexture;
|
||||
|
||||
~RenderTarget();
|
||||
|
||||
RenderTarget( int texsize, int width, int height );
|
||||
void lock();
|
||||
void unlock();
|
||||
GLuint initRenderToTexture();
|
||||
int nearestPower2( int value, TextureScale scaleRule );
|
||||
|
||||
/** Opaque pbuffer context and pbuffer */
|
||||
/*
|
||||
#ifdef __APPLE__
|
||||
void *origContext;
|
||||
void *pbufferContext;
|
||||
void *pbuffer;
|
||||
#endif
|
||||
*/
|
||||
/** Render target texture ID for non-pbuffer systems */
|
||||
GLuint textureID[3];
|
||||
#ifdef USE_FBO
|
||||
GLuint fbuffer[2];
|
||||
GLuint depthb[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /** !_RENDERTARGET_H */
|
||||
@ -6,13 +6,12 @@ libRenderer_la_SOURCES = \
|
||||
SOIL2/image_helper.c \
|
||||
SOIL2/SOIL2.c \
|
||||
SOIL2/etc1_utils.c \
|
||||
FBO.cpp \
|
||||
MilkdropWaveform.cpp \
|
||||
PerPixelMesh.cpp \
|
||||
Pipeline.cpp \
|
||||
Renderer.cpp \
|
||||
ShaderEngine.cpp \
|
||||
UserTexture.cpp \
|
||||
Texture.cpp \
|
||||
Waveform.cpp \
|
||||
Filters.cpp \
|
||||
PerlinNoise.cpp \
|
||||
@ -25,9 +24,9 @@ libRenderer_la_SOURCES = \
|
||||
RenderItemDistanceMetric.cpp \
|
||||
RenderItemMatcher.cpp \
|
||||
BeatDetect.hpp PipelineContext.hpp ShaderEngine.hpp\
|
||||
FBO.hpp RenderItemDistanceMetric.hpp TextureManager.hpp\
|
||||
RenderItemDistanceMetric.hpp TextureManager.hpp\
|
||||
Filters.hpp RenderItemMatcher.hpp Transformation.hpp\
|
||||
MilkdropWaveform.hpp RenderItemMergeFunction.hpp UserTexture.hpp\
|
||||
MilkdropWaveform.hpp RenderItemMergeFunction.hpp Texture.hpp\
|
||||
PerPixelMesh.hpp Renderable.hpp VideoEcho.hpp\
|
||||
PerlinNoise.hpp Renderer.hpp Waveform.hpp\
|
||||
Pipeline.hpp Shader.hpp\
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
|
||||
#include "Common.hpp"
|
||||
#include "Renderable.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include <math.h>
|
||||
#include "ShaderEngine.hpp"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@ -179,10 +180,13 @@ void Shape::Draw(RenderContext &context)
|
||||
{
|
||||
if (imageUrl !="")
|
||||
{
|
||||
GLuint tex= context.textureManager->getTexture(imageUrl);
|
||||
if (tex != 0)
|
||||
TextureSamplerDesc tex = context.textureManager->getTexture(imageUrl, GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
if (tex.first != NULL)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex.first->texID);
|
||||
glBindSampler(0, tex.second->samplerID);
|
||||
|
||||
context.aspectRatio=1.0;
|
||||
}
|
||||
}
|
||||
@ -220,10 +224,7 @@ void Shape::Draw(RenderContext &context)
|
||||
|
||||
glUseProgram(context.programID_v2f_c4f_t2f);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho));
|
||||
|
||||
glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0);
|
||||
|
||||
glBindVertexArray(m_vaoID_texture);
|
||||
@ -296,6 +297,9 @@ void Shape::Draw(RenderContext &context)
|
||||
glDrawArrays(GL_LINE_LOOP,0,sides);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindSampler(0, 0);
|
||||
|
||||
if (thickOutline==1) glLineWidth(context.texsize < 512 ? 1 : context.texsize/512);
|
||||
|
||||
delete[] buffer_data;
|
||||
|
||||
@ -10,16 +10,19 @@
|
||||
#include <cassert>
|
||||
#include "omptl/omptl"
|
||||
#include "omptl/omptl_algorithm"
|
||||
#include "UserTexture.hpp"
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
|
||||
Pipeline* Renderer::currentPipe;
|
||||
|
||||
|
||||
class Preset;
|
||||
|
||||
Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetect *beatDetect, std::string _presetURL,
|
||||
Renderer::Renderer(int width, int height, int gx, int gy, int _texsize, BeatDetect *_beatDetect, std::string _presetURL,
|
||||
std::string _titlefontURL, std::string _menufontURL) :
|
||||
title_fontURL(_titlefontURL), menu_fontURL(_menufontURL), presetURL(_presetURL), m_presetName("None"), vw(width),
|
||||
vh(height), texsize(texsize), mesh(gx, gy)
|
||||
vh(height), texsize(_texsize), mesh(gx, gy)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
@ -40,12 +43,12 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec
|
||||
|
||||
/** Other stuff... */
|
||||
this->correction = true;
|
||||
this->aspect = (float) height / (float) width;;
|
||||
|
||||
/// @bug put these on member init list
|
||||
this->renderTarget = new RenderTarget(texsize, width, height);
|
||||
this->textureManager = new TextureManager(presetURL);
|
||||
this->beatDetect = beatDetect;
|
||||
this->textureManager = NULL;
|
||||
this->beatDetect = _beatDetect;
|
||||
|
||||
textureRenderToTexture = 0;
|
||||
|
||||
#ifdef USE_FTGL
|
||||
/** Load the standard fonts if they do exist */
|
||||
@ -159,7 +162,6 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
shaderEngine.setParams(renderTarget->texsize, renderTarget->textureID[1], aspect, beatDetect, textureManager);
|
||||
}
|
||||
|
||||
void Renderer::SetPipeline(Pipeline &pipeline)
|
||||
@ -173,8 +175,6 @@ void Renderer::ResetTextures()
|
||||
{
|
||||
textureManager->Clear();
|
||||
|
||||
delete (renderTarget);
|
||||
renderTarget = new RenderTarget(texsize, vw, vh);
|
||||
reset(vw, vh);
|
||||
|
||||
textureManager->Preload();
|
||||
@ -183,12 +183,11 @@ void Renderer::ResetTextures()
|
||||
void Renderer::SetupPass1(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
totalframes++;
|
||||
renderTarget->lock();
|
||||
glViewport(0, 0, renderTarget->texsize, renderTarget->texsize);
|
||||
glViewport(0, 0, texsizeX, texsizeY);
|
||||
|
||||
renderContext.mat_ortho = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -40.0f, 40.0f);
|
||||
|
||||
shaderEngine.RenderBlurTextures(pipeline, pipelineContext, renderTarget->texsize);
|
||||
shaderEngine.RenderBlurTextures(pipeline, pipelineContext);
|
||||
}
|
||||
|
||||
void Renderer::RenderItems(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
@ -212,8 +211,8 @@ void Renderer::RenderItems(const Pipeline &pipeline, const PipelineContext &pipe
|
||||
void Renderer::FinishPass1()
|
||||
{
|
||||
draw_title_to_texture();
|
||||
renderTarget->unlock();
|
||||
|
||||
textureManager->updateMainTexture();
|
||||
}
|
||||
|
||||
void Renderer::Pass2(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
@ -225,25 +224,14 @@ void Renderer::Pass2(const Pipeline &pipeline, const PipelineContext &pipelineCo
|
||||
//video texture memory and render fullscreen.
|
||||
|
||||
/** Reset the viewport size */
|
||||
#ifdef USE_FBO
|
||||
if (renderTarget->renderToTexture)
|
||||
if (textureRenderToTexture)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, this->renderTarget->fbuffer[1]);
|
||||
glViewport(0, 0, this->renderTarget->texsize, this->renderTarget->texsize);
|
||||
glViewport(0, 0, texsizeX, texsizeY);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
glViewport(0, 0, this->vw, this->vh);
|
||||
glViewport(0, 0, this->vw, this->vh);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, this->renderTarget->textureID[0]);
|
||||
|
||||
renderContext.mat_ortho = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f, -40.0f, 40.0f);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glLineWidth(this->renderTarget->texsize < 512 ? 1 : this->renderTarget->texsize / 512.0);
|
||||
|
||||
CompositeOutput(pipeline, pipelineContext);
|
||||
CompositeOutput(pipeline, pipelineContext);
|
||||
|
||||
/* FTGL does not support OpenGL ES
|
||||
#ifndef EMSCRIPTEN
|
||||
@ -268,70 +256,44 @@ void Renderer::Pass2(const Pipeline &pipeline, const PipelineContext &pipelineCo
|
||||
glTranslatef(0.5, 0.5, 0);
|
||||
*/
|
||||
|
||||
#ifdef USE_FBO
|
||||
if (renderTarget->renderToTexture)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
if (textureRenderToTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, textureRenderToTexture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsizeX, texsizeY);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::RenderFrame(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
|
||||
#ifdef USE_FBO
|
||||
// when not 'renderToTexture', the user may use its own couple FBO/texture
|
||||
// so retrieve this external FBO if it exists, (0 means no FBO) and unbind it
|
||||
GLint externalFBO = 0;
|
||||
if (!renderTarget->renderToTexture)
|
||||
{
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &externalFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetupPass1(pipeline, pipelineContext);
|
||||
|
||||
Interpolation(pipeline, pipelineContext);
|
||||
|
||||
RenderItems(pipeline, pipelineContext);
|
||||
FinishPass1();
|
||||
|
||||
#ifdef USE_FBO
|
||||
// when not 'renderToTexture', the user may use its own couple FBO/texture
|
||||
// if it exists (0 means no external FBO)
|
||||
// then rebind it just before calling the final pass: Pass2
|
||||
if (!renderTarget->renderToTexture && externalFBO != 0)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, externalFBO);
|
||||
#endif
|
||||
FinishPass1();
|
||||
|
||||
Pass2(pipeline, pipelineContext);
|
||||
}
|
||||
|
||||
void Renderer::Interpolation(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
if (this->renderTarget->useFBO)
|
||||
glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[1]);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[0]);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, textureManager->getMainTexture()->texID);
|
||||
|
||||
//Texture wrapping( clamp vs. wrap)
|
||||
if (pipeline.textureWrap == 0)
|
||||
{
|
||||
#ifdef GL_TRANSITION
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
#else
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
int size = (mesh.height - 1) * mesh.width * 4 * 2;
|
||||
|
||||
if (pipeline.staticPerPixel)
|
||||
@ -357,15 +319,15 @@ void Renderer::Interpolation(const Pipeline &pipeline, const PipelineContext &pi
|
||||
mesh.Reset();
|
||||
omptl::transform(mesh.p.begin(), mesh.p.end(), mesh.identity.begin(), mesh.p.begin(), &Renderer::PerPixel);
|
||||
|
||||
for (int j = 0; j < mesh.height - 1; j++)
|
||||
{
|
||||
for (int j = 0; j < mesh.height - 1; j++)
|
||||
{
|
||||
int base = j * mesh.width * 2 * 4;
|
||||
|
||||
for (int i = 0; i < mesh.width; i++)
|
||||
{
|
||||
for (int i = 0; i < mesh.width; i++)
|
||||
{
|
||||
int strip = base + i * 8;
|
||||
int index = j * mesh.width + i;
|
||||
int index2 = (j + 1) * mesh.width + i;
|
||||
int index = j * mesh.width + i;
|
||||
int index2 = (j + 1) * mesh.width + i;
|
||||
|
||||
p[strip + 2] = mesh.p[index].x;
|
||||
p[strip + 3] = mesh.p[index].y;
|
||||
@ -374,8 +336,8 @@ void Renderer::Interpolation(const Pipeline &pipeline, const PipelineContext &pi
|
||||
p[strip + 7] = mesh.p[index2].y;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_Interpolation);
|
||||
@ -385,10 +347,7 @@ void Renderer::Interpolation(const Pipeline &pipeline, const PipelineContext &pi
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
shaderEngine.enableWarpShader(currentPipe->warpShader, pipeline, pipelineContext);
|
||||
|
||||
glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(renderContext.mat_ortho));
|
||||
glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0);
|
||||
shaderEngine.enableWarpShader(currentPipe->warpShader, pipeline, pipelineContext, renderContext.mat_ortho);
|
||||
|
||||
glVertexAttrib4f(1, 1.0, 1.0, 1.0, pipeline.screenDecay);
|
||||
|
||||
@ -396,23 +355,19 @@ void Renderer::Interpolation(const Pipeline &pipeline, const PipelineContext &pi
|
||||
|
||||
glBindVertexArray(m_vao_Interpolation);
|
||||
|
||||
for (int j = 0; j < mesh.height - 1; j++)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP,j* mesh.width* 2,mesh.width*2);
|
||||
for (int j = 0; j < mesh.height - 1; j++)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP,j* mesh.width* 2,mesh.width*2);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
Pipeline* Renderer::currentPipe;
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
|
||||
int x;
|
||||
|
||||
if (renderTarget)
|
||||
delete (renderTarget);
|
||||
if (textureManager)
|
||||
delete (textureManager);
|
||||
|
||||
@ -437,6 +392,8 @@ Renderer::~Renderer()
|
||||
|
||||
glDeleteBuffers(1, &m_vbo_CompositeOutput);
|
||||
glDeleteVertexArrays(1, &m_vao_CompositeOutput);
|
||||
|
||||
glDeleteTextures(1, &textureRenderToTexture);
|
||||
}
|
||||
|
||||
void Renderer::reset(int w, int h)
|
||||
@ -445,45 +402,53 @@ void Renderer::reset(int w, int h)
|
||||
this -> vw = w;
|
||||
this -> vh = h;
|
||||
|
||||
shaderEngine.setAspect(aspect);
|
||||
|
||||
glCullFace(GL_BACK);
|
||||
//glFrontFace( GL_CCW );
|
||||
|
||||
#ifndef GL_TRANSITION
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
#endif
|
||||
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
texsizeX = w;
|
||||
texsizeY = h;
|
||||
|
||||
// snap to 16x16 blocks
|
||||
texsizeX = ((texsizeX+15)/16)*16;
|
||||
texsizeY = ((texsizeY+15)/16)*16;
|
||||
|
||||
if (textureManager != NULL) {
|
||||
delete textureManager;
|
||||
}
|
||||
textureManager = new TextureManager(presetURL, texsizeX, texsizeY);
|
||||
|
||||
shaderEngine.setParams(texsizeX, texsizeY, beatDetect, textureManager);
|
||||
shaderEngine.reset();
|
||||
shaderEngine.loadPresetShaders(*currentPipe);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// TODO: how to port this to modern openGL ?
|
||||
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
|
||||
// if (!this->renderTarget->useFBO)
|
||||
// {
|
||||
// this->renderTarget->fallbackRescale(w, h);
|
||||
// }
|
||||
}
|
||||
|
||||
GLuint Renderer::initRenderToTexture()
|
||||
{
|
||||
return renderTarget->initRenderToTexture();
|
||||
if (textureRenderToTexture == 0) {
|
||||
glGenTextures(1, &textureRenderToTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, textureRenderToTexture);
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsizeX, texsizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
return textureRenderToTexture;
|
||||
}
|
||||
|
||||
void Renderer::draw_title_to_texture()
|
||||
@ -747,6 +712,15 @@ void Renderer::draw_fps(float realfps)
|
||||
|
||||
void Renderer::CompositeOutput(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, textureManager->getMainTexture()->texID);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
renderContext.mat_ortho = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f, -40.0f, 40.0f);
|
||||
|
||||
shaderEngine.enableCompositeShader(currentPipe->compositeShader, pipeline, pipelineContext);
|
||||
|
||||
glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(renderContext.mat_ortho));
|
||||
@ -756,8 +730,6 @@ void Renderer::CompositeOutput(const Pipeline &pipeline, const PipelineContext &
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindVertexArray(m_vao_CompositeOutput);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
@ -770,4 +742,37 @@ void Renderer::CompositeOutput(const Pipeline &pipeline, const PipelineContext &
|
||||
!= pipeline.compositeDrawables.end(); ++pos)
|
||||
(*pos)->Draw(renderContext);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the nearest power of two to the given number using the
|
||||
* appropriate rule
|
||||
*/
|
||||
int Renderer::nearestPower2( int value ) {
|
||||
|
||||
int x = value;
|
||||
int power = 0;
|
||||
|
||||
while ( ( x & 0x01 ) != 1 ) {
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
if ( x == 1 ) {
|
||||
return value;
|
||||
} else {
|
||||
x = value;
|
||||
while ( x != 0 ) {
|
||||
x >>= 1;
|
||||
power++;
|
||||
}
|
||||
if ( ( ( 1 << power ) - value ) <= ( value - ( 1 << ( power - 1 ) ) ) ) {
|
||||
return 1 << power;
|
||||
} else {
|
||||
return 1 << ( power - 1 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#ifndef Renderer_HPP
|
||||
#define Renderer_HPP
|
||||
|
||||
#include "FBO.hpp"
|
||||
#include "BeatDetect.hpp"
|
||||
#include "Common.hpp"
|
||||
#include <string>
|
||||
@ -23,7 +22,7 @@
|
||||
#endif /** USE_FTGL */
|
||||
|
||||
|
||||
class UserTexture;
|
||||
class Texture;
|
||||
class BeatDetect;
|
||||
class TextureManager;
|
||||
|
||||
@ -49,9 +48,10 @@ public:
|
||||
std::string title;
|
||||
int drawtitle;
|
||||
int texsize;
|
||||
int texsizeX;
|
||||
int texsizeY;
|
||||
|
||||
|
||||
Renderer( int width, int height, int gx, int gy, int texsize, BeatDetect *beatDetect, std::string presetURL, std::string title_fontURL, std::string menu_fontURL);
|
||||
Renderer(int width, int height, int gx, int gy, int _texsize, BeatDetect *_beatDetect, std::string presetURL, std::string title_fontURL, std::string menu_fontURL);
|
||||
~Renderer();
|
||||
|
||||
void RenderFrame(const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
@ -75,7 +75,6 @@ public:
|
||||
private:
|
||||
|
||||
PerPixelMesh mesh;
|
||||
RenderTarget *renderTarget;
|
||||
BeatDetect *beatDetect;
|
||||
TextureManager *textureManager;
|
||||
static Pipeline* currentPipe;
|
||||
@ -130,6 +129,10 @@ private:
|
||||
void draw_title_to_screen(bool flip);
|
||||
void draw_title_to_texture();
|
||||
|
||||
int nearestPower2( int value );
|
||||
|
||||
GLuint textureRenderToTexture;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -364,12 +364,14 @@ unsigned int
|
||||
const char *filename,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
unsigned int flags,
|
||||
int *width,
|
||||
int *height
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
unsigned char* img;
|
||||
int width, height, channels;
|
||||
int channels;
|
||||
unsigned int tex_id;
|
||||
/* does the user want direct uploading of the image as a DDS file? */
|
||||
if( flags & SOIL_FLAG_DDS_LOAD_DIRECT )
|
||||
@ -407,7 +409,7 @@ unsigned int
|
||||
}
|
||||
|
||||
/* try to load the image */
|
||||
img = SOIL_load_image( filename, &width, &height, &channels, force_channels );
|
||||
img = SOIL_load_image( filename, width, height, &channels, force_channels );
|
||||
/* channels holds the original number of channels, which may have been forced */
|
||||
if( (force_channels >= 1) && (force_channels <= 4) )
|
||||
{
|
||||
@ -421,7 +423,7 @@ unsigned int
|
||||
}
|
||||
/* OK, make it a texture! */
|
||||
tex_id = SOIL_internal_create_OGL_texture(
|
||||
img, &width, &height, channels,
|
||||
img, width, height, channels,
|
||||
reuse_texture_ID, flags,
|
||||
GL_TEXTURE_2D, GL_TEXTURE_2D,
|
||||
GL_MAX_TEXTURE_SIZE );
|
||||
@ -496,12 +498,14 @@ unsigned int
|
||||
int buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
unsigned int flags,
|
||||
int * width,
|
||||
int * height
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
unsigned char* img;
|
||||
int width, height, channels;
|
||||
int channels;
|
||||
unsigned int tex_id;
|
||||
/* does the user want direct uploading of the image as a DDS file? */
|
||||
if( flags & SOIL_FLAG_DDS_LOAD_DIRECT )
|
||||
@ -547,7 +551,7 @@ unsigned int
|
||||
/* try to load the image */
|
||||
img = SOIL_load_image_from_memory(
|
||||
buffer, buffer_length,
|
||||
&width, &height, &channels,
|
||||
width, height, &channels,
|
||||
force_channels );
|
||||
/* channels holds the original number of channels, which may have been forced */
|
||||
if( (force_channels >= 1) && (force_channels <= 4) )
|
||||
@ -562,7 +566,7 @@ unsigned int
|
||||
}
|
||||
/* OK, make it a texture! */
|
||||
tex_id = SOIL_internal_create_OGL_texture(
|
||||
img, &width, &height, channels,
|
||||
img, width, height, channels,
|
||||
reuse_texture_ID, flags,
|
||||
GL_TEXTURE_2D, GL_TEXTURE_2D,
|
||||
GL_MAX_TEXTURE_SIZE );
|
||||
|
||||
@ -166,8 +166,9 @@ unsigned int
|
||||
const char *filename,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
unsigned int flags,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
/**
|
||||
Loads 6 images from disk into an OpenGL cubemap texture.
|
||||
@ -249,7 +250,9 @@ unsigned int
|
||||
int buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
unsigned int flags,
|
||||
int * width,
|
||||
int * height
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@ -7,6 +7,4 @@
|
||||
|
||||
#include "Shader.hpp"
|
||||
|
||||
Shader::Shader()
|
||||
: enabled(false)
|
||||
{}
|
||||
Shader::Shader() {}
|
||||
|
||||
@ -10,15 +10,13 @@
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "UserTexture.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
|
||||
std::map<std::string, UserTexture*> textures;
|
||||
|
||||
bool enabled;
|
||||
std::map<std::string, TextureSamplerDesc> textures;
|
||||
|
||||
std::string programSource;
|
||||
std::string presetPath;
|
||||
|
||||
@ -6,10 +6,11 @@
|
||||
*/
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "PerlinNoise.hpp"
|
||||
#include "ShaderEngine.hpp"
|
||||
#include "BeatDetect.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "HLSLTranslator.hpp"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#ifdef USE_GLES
|
||||
#define GLSL_VERSION "300 es"
|
||||
@ -63,7 +64,7 @@ std::string presetCompVertexShader(
|
||||
"}\n");
|
||||
|
||||
|
||||
std::string v2f_c4f_vert(
|
||||
const std::string ShaderEngine::v2f_c4f_vert(
|
||||
"#version "
|
||||
GLSL_VERSION
|
||||
"\n"
|
||||
@ -82,7 +83,7 @@ std::string v2f_c4f_vert(
|
||||
" fragment_color = vertex_color;\n"
|
||||
"}\n");
|
||||
|
||||
std::string v2f_c4f_frag(
|
||||
const std::string ShaderEngine::v2f_c4f_frag(
|
||||
"#version "
|
||||
GLSL_VERSION
|
||||
"\n"
|
||||
@ -95,7 +96,7 @@ std::string v2f_c4f_frag(
|
||||
" color = fragment_color;\n"
|
||||
"}\n");
|
||||
|
||||
std::string v2f_c4f_t2f_vert(
|
||||
const std::string ShaderEngine::v2f_c4f_t2f_vert(
|
||||
"#version "
|
||||
GLSL_VERSION
|
||||
"\n"
|
||||
@ -114,7 +115,7 @@ std::string v2f_c4f_t2f_vert(
|
||||
" fragment_texture = vertex_texture;\n"
|
||||
"}\n");
|
||||
|
||||
std::string v2f_c4f_t2f_frag(
|
||||
const std::string ShaderEngine::v2f_c4f_t2f_frag(
|
||||
"#version "
|
||||
GLSL_VERSION
|
||||
"\n"
|
||||
@ -133,10 +134,6 @@ std::string v2f_c4f_t2f_frag(
|
||||
|
||||
|
||||
std::string PresetShaderIncludes = ""
|
||||
// "float2 a = 1.0 + 2.0 * 3.0 + 4.0;\n"
|
||||
// "float2 _uv, dx, dy, _c7;\n"
|
||||
// "float2 uv_y =(_uv.xy)-( float2(0,-1.2) + float2(dx.y,dy.y)*8 + float2(dx.x,dy.x)*4 )*(_c7).zw;\n"
|
||||
|
||||
"#define M_PI 3.14159265359\n"
|
||||
"#define M_PI_2 6.28318530718\n"
|
||||
"#define M_INV_PI_2 0.159154943091895\n"
|
||||
@ -432,114 +429,14 @@ bool ShaderEngine::checkCompileStatus(GLuint shader, const std::string & shaderT
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShaderEngine::setParams(const int texsize, const unsigned int texId, const float aspect, BeatDetect *beatDetect,
|
||||
TextureManager *textureManager)
|
||||
void ShaderEngine::setParams(const int _texsizeX, const int _texsizeY, BeatDetect *_beatDetect,
|
||||
TextureManager *_textureManager)
|
||||
{
|
||||
mainTextureId = texId;
|
||||
this->beatDetect = beatDetect;
|
||||
this->textureManager = textureManager;
|
||||
this->aspect = aspect;
|
||||
this->texsize = texsize;
|
||||
this->beatDetect = _beatDetect;
|
||||
this->textureManager = _textureManager;
|
||||
|
||||
textureManager->setTexture("main", texId, texsize, texsize);
|
||||
|
||||
#ifndef GL_TRANSITION
|
||||
glGenTextures(1, &blur1_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, blur1_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texsize/2, texsize/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glGenTextures(1, &blur2_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, blur2_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texsize / 4, texsize / 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glGenTextures(1, &blur3_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, blur3_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texsize / 8, texsize / 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
#endif
|
||||
|
||||
blur1_enabled = false;
|
||||
blur2_enabled = false;
|
||||
blur3_enabled = false;
|
||||
|
||||
//std::cout << "Generating Noise Textures" << std::endl;
|
||||
|
||||
PerlinNoise noise;
|
||||
#ifndef GL_TRANSITION
|
||||
glGenTextures(1, &noise_texture_lq_lite);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq_lite);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_lq_lite);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noise_lq_lite", noise_texture_lq_lite, 32, 32);
|
||||
|
||||
glGenTextures(1, &noise_texture_lq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_lq);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noise_lq", noise_texture_lq, 256, 256);
|
||||
|
||||
glGenTextures(1, &noise_texture_mq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_mq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_mq);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noise_mq", noise_texture_mq, 256, 256);
|
||||
|
||||
glGenTextures(1, &noise_texture_hq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_hq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_hq);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noise_hq", noise_texture_hq, 256, 256);
|
||||
|
||||
glGenTextures(1, &noise_texture_perlin);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_perlin);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_perlin);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noise_perlin", noise_texture_perlin, 512, 512);
|
||||
|
||||
glGenTextures( 1, &noise_texture_lq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_lq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D,0,4,32,32,32,0,GL_LUMINANCE,GL_FLOAT,noise.noise_lq_vol);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noisevol_lq", noise_texture_lq_vol, 256, 256);
|
||||
|
||||
glGenTextures( 1, &noise_texture_hq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_hq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D,0,4,32,32,32,0,GL_LUMINANCE,GL_FLOAT,noise.noise_hq_vol);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
textureManager->setTexture("noisevol_hq", noise_texture_hq_vol, 8, 8);
|
||||
#endif
|
||||
this->texsizeX = _texsizeX;
|
||||
this->texsizeY = _texsizeY;
|
||||
}
|
||||
|
||||
// compile a user-defined shader from a preset. returns program ID if successful.
|
||||
@ -592,24 +489,6 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
|
||||
pmShader.textures.clear();
|
||||
|
||||
std::vector<std::string> standard_samplers = {
|
||||
"main",
|
||||
"fc_main",
|
||||
"pc_main",
|
||||
"fw_main",
|
||||
"pw_main",
|
||||
"noise_lq",
|
||||
"noise_lq_lite",
|
||||
"noise_mq",
|
||||
"noise_hq",
|
||||
"noisevol_lq",
|
||||
"noisevol_hq",
|
||||
"blur1",
|
||||
"blur2",
|
||||
"blur3",
|
||||
};
|
||||
|
||||
|
||||
// set up texture samplers for all samplers references in the shader program
|
||||
found = 0;
|
||||
found = program.find("sampler_", found);
|
||||
@ -621,117 +500,98 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
std::string sampler = program.substr((int) found, (int) end - found);
|
||||
UserTexture* texture = new UserTexture(sampler);
|
||||
std::string lowerCaseName(sampler);
|
||||
std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), tolower);
|
||||
|
||||
texture->texID = textureManager->getTexture(texture->name);
|
||||
if (texture->texID != 0)
|
||||
TextureSamplerDesc texDesc = textureManager->getTexture(sampler, GL_REPEAT, GL_LINEAR);
|
||||
|
||||
if (texDesc.first == NULL)
|
||||
{
|
||||
texture->width = textureManager->getTextureWidth(texture->name);
|
||||
texture->height = textureManager->getTextureHeight(texture->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Insert uniform keyword for GLSL sampler declarations
|
||||
std::string sampler_lowercase(sampler);
|
||||
std::transform(sampler_lowercase.begin(), sampler_lowercase.end(), sampler_lowercase.begin(), ::tolower);
|
||||
std::vector<std::string>::iterator it = standard_samplers.begin();
|
||||
it = std::find(standard_samplers.begin(), standard_samplers.end(), sampler_lowercase);
|
||||
|
||||
// Declare a uniform for sampler defined in preset but out from the shader body
|
||||
if (it == standard_samplers.end() && found < program_start) {
|
||||
int index = found;
|
||||
while(index >= 0 && program[index] != '\n') { index--; }
|
||||
program.insert(index+1, "uniform ");
|
||||
found += 8;
|
||||
program_start += 8;
|
||||
}
|
||||
|
||||
if (sampler.substr(0, 4) == "rand")
|
||||
if (lowerCaseName.substr(0, 4) == "rand")
|
||||
{
|
||||
std::string random_name = textureManager->getRandomTextureName(texture->name);
|
||||
std::string random_name = textureManager->getRandomTextureName(lowerCaseName);
|
||||
if (random_name.size() > 0)
|
||||
{
|
||||
texture->texID = textureManager->getTexture(random_name);
|
||||
texture->width = textureManager->getTextureWidth(random_name);
|
||||
texture->height = textureManager->getTextureHeight(random_name);
|
||||
texDesc = textureManager->getTexture(random_name, GL_REPEAT, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string extensions[6];
|
||||
extensions[0] = ".jpg";
|
||||
extensions[1] = ".dds";
|
||||
extensions[2] = ".png";
|
||||
extensions[3] = ".tga";
|
||||
extensions[4] = ".bmp";
|
||||
extensions[5] = ".dib";
|
||||
|
||||
for (int x = 0; x < 6; x++)
|
||||
{
|
||||
|
||||
std::string filename = texture->name + extensions[x];
|
||||
texture->texID = textureManager->getTexture(filename);
|
||||
if (texture->texID != 0)
|
||||
{
|
||||
texture->width = textureManager->getTextureWidth(filename);
|
||||
texture->height = textureManager->getTextureHeight(filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
texDesc = textureManager->tryLoadingTexture(sampler);
|
||||
}
|
||||
}
|
||||
if (texture->texID != 0 && pmShader.textures.find(texture->qname) == pmShader.textures.end())
|
||||
pmShader.textures[texture->qname] = texture;
|
||||
|
||||
if (texDesc.first == NULL)
|
||||
{
|
||||
std::cerr << "Texture loading error for: " << sampler << std::endl;
|
||||
}
|
||||
else
|
||||
delete (texture);
|
||||
{
|
||||
// The shader declares a new sampler -> declaring it with a "uniform" outside the shader body
|
||||
if (texDesc.first->userTexture) {
|
||||
if (found < program_start) {
|
||||
int index = found;
|
||||
while(index >= 0 && program[index] != '\n') { index--; }
|
||||
program.insert(index+1, "uniform ");
|
||||
found += 8;
|
||||
program_start += 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Add built-in textures
|
||||
// Add user textures only if used
|
||||
if (!texDesc.first->userTexture || found > program_start)
|
||||
{
|
||||
std::map<std::string, TextureSamplerDesc>::const_iterator iter = pmShader.textures.cbegin();
|
||||
for ( ; iter != pmShader.textures.cend(); ++iter)
|
||||
{
|
||||
if (iter->first == sampler)
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter == pmShader.textures.cend())
|
||||
pmShader.textures[sampler] = texDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found = program.find("sampler_", found);
|
||||
}
|
||||
|
||||
textureManager->clearRandomTextures();
|
||||
|
||||
// add texture size vars
|
||||
found = 0;
|
||||
found = program.find("texsize_", found);
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
found += 8;
|
||||
size_t end = program.find_first_of(" ;.,\n\r)", found);
|
||||
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
std::string tex = program.substr((int) found, (int) end - found);
|
||||
if (pmShader.textures.find(tex) != pmShader.textures.end())
|
||||
{
|
||||
UserTexture* texture = pmShader.textures[tex];
|
||||
texture->texsizeDefined = true;
|
||||
//std::cout << "texsize_" << tex << " found" << std::endl;
|
||||
}
|
||||
}
|
||||
found = program.find("texsize_", found);
|
||||
}
|
||||
|
||||
// blur programs
|
||||
blur1_enabled = false;
|
||||
blur2_enabled = false;
|
||||
blur3_enabled = false;
|
||||
|
||||
if (program.find("GetMain") != std::string::npos || program.find("GetPixel") != std::string::npos)
|
||||
{
|
||||
pmShader.textures["main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR);
|
||||
}
|
||||
|
||||
found = program.find("GetBlur3");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
blur1_enabled = blur2_enabled = blur3_enabled = true;
|
||||
pmShader.textures["blur3"] = textureManager->getTexture("blur3", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = program.find("GetBlur2");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
blur1_enabled = blur2_enabled = true;
|
||||
pmShader.textures["blur2"] = textureManager->getTexture("blur2", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = program.find("GetBlur1");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
blur1_enabled = true;
|
||||
pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,71 +698,49 @@ void ShaderEngine::SetupShaderVariables(GLuint program, const Pipeline &pipeline
|
||||
glProgramUniform1f(program, glGetUniformLocation(program, "vol"), beatDetect->vol);
|
||||
glProgramUniform1f(program, glGetUniformLocation(program, "vol_att"), beatDetect->vol);
|
||||
|
||||
glProgramUniform4f(program, glGetUniformLocation(program, "texsize"), texsize, texsize, 1 / (float) texsize, 1 / (float) texsize);
|
||||
glProgramUniform4f(program, glGetUniformLocation(program, "aspect"), 1 / aspect, 1, aspect, 1);
|
||||
glProgramUniform4f(program, glGetUniformLocation(program, "texsize"), texsizeX, texsizeY, 1 / (float) texsizeX, 1 / (float) texsizeY);
|
||||
glProgramUniform4f(program, glGetUniformLocation(program, "aspect"), 1 / aspectX, 1, aspectX, 1);
|
||||
|
||||
/*
|
||||
if (blur1_enabled)
|
||||
{
|
||||
cgGLSetTextureParameter(program, glGetUniformLocation(program, "sampler_blur1"), blur1_tex);
|
||||
cgGLEnableTextureParameter(program, glGetUniformLocation(program, "sampler_blur1"));
|
||||
}
|
||||
if (blur2_enabled)
|
||||
{
|
||||
cgGLSetTextureParameter(glGetUniformLocation(program, "sampler_blur2"), blur2_tex);
|
||||
cgGLEnableTextureParameter(glGetUniformLocation(program, "sampler_blur2"));
|
||||
}
|
||||
if (blur3_enabled)
|
||||
{
|
||||
cgGLSetTextureParameter(glGetUniformLocation(program, "sampler_blur3"), blur3_tex);
|
||||
cgGLEnableTextureParameter(glGetUniformLocation(program, "sampler_blur3"));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void ShaderEngine::setupUserTexture(GLuint program, const UserTexture* texture)
|
||||
void ShaderEngine::SetupTextures(GLuint program, const Shader &shader)
|
||||
{
|
||||
std::string samplerName = "sampler_" + texture->qname;
|
||||
|
||||
// FIXME: check if each texture binding will overwrite previous one
|
||||
uint texNum = 0;
|
||||
for (std::map<std::string, TextureSamplerDesc>::const_iterator iter = shader.textures.begin(); iter
|
||||
!= shader.textures.end(); ++iter)
|
||||
{
|
||||
std::string texName = iter->first;
|
||||
Texture * texture = iter->second.first;
|
||||
Sampler * sampler = iter->second.second;
|
||||
std::string samplerName = "sampler_" + texName;
|
||||
|
||||
// https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Binding_textures_to_samplers
|
||||
GLint param = glGetUniformLocation(program, samplerName.c_str());
|
||||
if (param < 0) {
|
||||
// FIXME: turn this on and fix it.
|
||||
// i think sampler names are carrying over from previous shaders...
|
||||
// std::cerr << "invalid uniform name " << samplerName << std::endl;
|
||||
return;
|
||||
}
|
||||
// https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Binding_textures_to_samplers
|
||||
GLint param = glGetUniformLocation(program, samplerName.c_str());
|
||||
if (param < 0) {
|
||||
// unused uniform have been optimized out by glsl compiler
|
||||
continue;
|
||||
}
|
||||
|
||||
glUniform1i(param, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + 0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texID);
|
||||
glActiveTexture(GL_TEXTURE0 + texNum);
|
||||
glBindTexture(texture->type, texture->texID);
|
||||
glBindSampler(texNum, sampler->samplerID);
|
||||
|
||||
if (texture->texsizeDefined)
|
||||
{
|
||||
std::string texsizeName = "texsize_" + texture->name;
|
||||
glUniform1i(param, texNum);
|
||||
|
||||
std::string texsizeName = "texsize_" + texName;
|
||||
GLint textSizeParam = glGetUniformLocation(program, texsizeName.c_str());
|
||||
if (param >= 0) {
|
||||
glProgramUniform4f(program, textSizeParam, texture->width, texture->height,
|
||||
1 / (float) texture->width, 1 / (float) texture->height);
|
||||
} else {
|
||||
std::cerr << "invalid texsizeName " << texsizeName << std::endl;
|
||||
std::cerr << "invalid texsize name " << texsizeName << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderEngine::setupUserTextureState(GLuint program, const UserTexture* texture)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texID);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texture->bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture->bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
#ifndef GL_TRANSITION
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture->wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture->wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
texNum++;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderEngine::SetupShaderQVariables(GLuint program, const Pipeline &q)
|
||||
@ -924,12 +762,7 @@ void ShaderEngine::SetupShaderQVariables(GLuint program, const Pipeline &q)
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderEngine::setAspect(float aspect)
|
||||
{
|
||||
this->aspect = aspect;
|
||||
}
|
||||
|
||||
void ShaderEngine::RenderBlurTextures(const Pipeline &pipeline, const PipelineContext &pipelineContext, const int texsize)
|
||||
void ShaderEngine::RenderBlurTextures(const Pipeline &pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
#ifndef GL_TRANSITION
|
||||
if (blur1_enabled || blur2_enabled || blur3_enabled)
|
||||
@ -1058,19 +891,24 @@ bool ShaderEngine::linkProgram(GLuint programID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma mark Preset Shaders
|
||||
|
||||
void ShaderEngine::loadPresetShaders(Pipeline &pipeline) {
|
||||
/*
|
||||
// compile and link warp and composite shaders from pipeline
|
||||
programID_presetWarp = loadPresetShader(PresentWarpShader, pipeline.warpShader, pipeline.warpShaderFilename);
|
||||
programID_presetComp = loadPresetShader(PresentCompositeShader, pipeline.compositeShader, pipeline.compositeShaderFilename);
|
||||
if (!pipeline.compositeShader.programSource.empty()) {
|
||||
programID_presetComp = loadPresetShader(PresentCompositeShader, pipeline.compositeShader, pipeline.compositeShaderFilename);
|
||||
if (programID_presetComp != GL_FALSE)
|
||||
presetCompShaderLoaded = true;
|
||||
}
|
||||
|
||||
if (programID_presetComp != GL_FALSE)
|
||||
presetCompShaderLoaded = true;
|
||||
|
||||
if (programID_presetWarp != GL_FALSE)
|
||||
presetWarpShaderLoaded = true;
|
||||
|
||||
if (!pipeline.warpShader.programSource.empty()) {
|
||||
programID_presetWarp = loadPresetShader(PresentWarpShader, pipeline.warpShader, pipeline.warpShaderFilename);
|
||||
if (programID_presetWarp != GL_FALSE) {
|
||||
uniform_vertex_transf_warp_shader = glGetUniformLocation(programID_presetWarp, "vertex_transformation");
|
||||
presetWarpShaderLoaded = true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
std::cout << "Preset composite shader active: " << presetCompShaderLoaded << ", preset warp shader active: " << presetWarpShaderLoaded << std::endl;
|
||||
}
|
||||
|
||||
@ -1082,14 +920,7 @@ GLuint ShaderEngine::loadPresetShader(const ShaderEngine::PresentShaderType shad
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
// pass texture info from preset to shader
|
||||
for (auto &userTexture : presetShader.textures) {
|
||||
setupUserTextureState(program, userTexture.second);
|
||||
setupUserTexture(program, userTexture.second);
|
||||
}
|
||||
|
||||
return program;
|
||||
|
||||
}
|
||||
|
||||
// deactivate preset shaders
|
||||
@ -1173,40 +1004,43 @@ GLuint ShaderEngine::CompileShaderProgram(const std::string & VertexShaderCode,
|
||||
|
||||
// use the appropriate shader program for rendering the interpolation.
|
||||
// it will use the preset shader if available, otherwise the textured shader
|
||||
void ShaderEngine::enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext) {
|
||||
if (presetWarpShaderLoaded && PRESET_SHADERS_ENABLED) {
|
||||
bool ShaderEngine::enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext, const glm::mat4 & mat_ortho) {
|
||||
if (presetWarpShaderLoaded) {
|
||||
glUseProgram(programID_presetWarp);
|
||||
|
||||
for (std::map<std::string, UserTexture*>::const_iterator pos = shader.textures.begin(); pos != shader.textures.end(); ++pos)
|
||||
setupUserTextureState(programID_presetWarp, pos->second);
|
||||
|
||||
for (std::map<std::string, UserTexture*>::const_iterator pos = shader.textures.begin(); pos
|
||||
!= shader.textures.end(); ++pos)
|
||||
setupUserTexture(programID_presetWarp, pos->second);
|
||||
SetupTextures(programID_presetWarp, shader);
|
||||
|
||||
SetupShaderVariables(programID_presetWarp, pipeline, pipelineContext);
|
||||
SetupShaderQVariables(programID_presetWarp, pipeline);
|
||||
|
||||
} else {
|
||||
glUseProgram(programID_v2f_c4f_t2f);
|
||||
glUniformMatrix4fv(uniform_vertex_transf_warp_shader, 1, GL_FALSE, glm::value_ptr(mat_ortho));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
glUseProgram(programID_v2f_c4f_t2f);
|
||||
|
||||
glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(mat_ortho));
|
||||
glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShaderEngine::enableCompositeShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext) {
|
||||
if (presetCompShaderLoaded && PRESET_SHADERS_ENABLED) {
|
||||
bool ShaderEngine::enableCompositeShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext) {
|
||||
if (presetCompShaderLoaded) {
|
||||
glUseProgram(programID_presetComp);
|
||||
|
||||
for (std::map<std::string, UserTexture*>::const_iterator pos = shader.textures.begin(); pos != shader.textures.end(); ++pos)
|
||||
setupUserTextureState(programID_presetComp, pos->second);
|
||||
|
||||
for (std::map<std::string, UserTexture*>::const_iterator pos = shader.textures.begin(); pos
|
||||
!= shader.textures.end(); ++pos)
|
||||
setupUserTexture(programID_presetComp, pos->second);
|
||||
SetupTextures(programID_presetComp, shader);
|
||||
|
||||
SetupShaderVariables(programID_presetComp, pipeline, pipelineContext);
|
||||
SetupShaderQVariables(programID_presetComp, pipeline);
|
||||
|
||||
} else {
|
||||
glUseProgram(programID_v2f_c4f_t2f);
|
||||
return true;
|
||||
}
|
||||
|
||||
glUseProgram(programID_v2f_c4f_t2f);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
#ifndef SHADERENGINE_HPP_
|
||||
#define SHADERENGINE_HPP_
|
||||
|
||||
#define PRESET_SHADERS_ENABLED 1
|
||||
|
||||
#include "Common.hpp"
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
@ -24,6 +22,8 @@ class ShaderEngine;
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include "Shader.hpp"
|
||||
|
||||
|
||||
class ShaderEngine
|
||||
{
|
||||
public:
|
||||
@ -38,13 +38,16 @@ public:
|
||||
ShaderEngine();
|
||||
virtual ~ShaderEngine();
|
||||
void loadPresetShaders(Pipeline &pipeline);
|
||||
void enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
void enableCompositeShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
void RenderBlurTextures(const Pipeline &pipeline, const PipelineContext &pipelineContext, const int texsize);
|
||||
void setAspect(float aspect);
|
||||
void setParams(const int texsize, const unsigned int texId, const float aspect, BeatDetect *beatDetect, TextureManager *textureManager);
|
||||
bool enableWarpShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext, const glm::mat4 & mat_ortho);
|
||||
bool enableCompositeShader(Shader &shader, const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
void RenderBlurTextures(const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
void setParams(const int _texsizeX, const int texsizeY, BeatDetect *beatDetect, TextureManager *_textureManager);
|
||||
void reset();
|
||||
|
||||
static GLuint CompileShaderProgram(const std::string & VertexShaderCode, const std::string & FragmentShaderCode, const std::string & shaderTypeString);
|
||||
static bool checkCompileStatus(GLuint shader, const std::string & shaderTitle);
|
||||
static bool linkProgram(GLuint programID);
|
||||
|
||||
static GLint Uniform_V2F_C4F_VertexTranformation() { return UNIFORM_V2F_C4F_VERTEX_TRANFORMATION; }
|
||||
static GLint Uniform_V2F_C4F_VertexPointSize() { return UNIFORM_V2F_C4F_VERTEX_POINT_SIZE; }
|
||||
static GLint Uniform_V2F_C4F_T2F_VertexTranformation() { return UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION; }
|
||||
@ -53,20 +56,24 @@ public:
|
||||
GLuint programID_v2f_c4f;
|
||||
GLuint programID_v2f_c4f_t2f;
|
||||
|
||||
const static std::string v2f_c4f_vert;
|
||||
const static std::string v2f_c4f_frag;
|
||||
const static std::string v2f_c4f_t2f_vert;
|
||||
const static std::string v2f_c4f_t2f_frag;
|
||||
|
||||
private:
|
||||
unsigned int mainTextureId;
|
||||
int texsize;
|
||||
float aspect;
|
||||
int texsizeX;
|
||||
int texsizeY;
|
||||
float aspectX;
|
||||
float aspectY;
|
||||
BeatDetect *beatDetect;
|
||||
TextureManager *textureManager;
|
||||
GLint uniform_vertex_transf_warp_shader;
|
||||
|
||||
GLuint noise_texture_lq_lite;
|
||||
GLuint noise_texture_lq;
|
||||
GLuint noise_texture_mq;
|
||||
GLuint noise_texture_hq;
|
||||
GLuint noise_texture_perlin;
|
||||
GLuint noise_texture_lq_vol;
|
||||
GLuint noise_texture_hq_vol;
|
||||
GLuint programID_warp_fallback;
|
||||
GLuint programID_comp_fallback;
|
||||
GLuint programID_blur1;
|
||||
GLuint programID_blur2;
|
||||
|
||||
bool blur1_enabled;
|
||||
bool blur2_enabled;
|
||||
@ -79,11 +86,8 @@ private:
|
||||
|
||||
void SetupShaderQVariables(GLuint program, const Pipeline &q);
|
||||
void SetupShaderVariables(GLuint program, const Pipeline &pipeline, const PipelineContext &pipelineContext);
|
||||
void setupUserTexture(GLuint program, const UserTexture* texture);
|
||||
void setupUserTextureState(GLuint program, const UserTexture* texture);
|
||||
void SetupTextures(GLuint program, const Shader &shader);
|
||||
GLuint compilePresetShader(const ShaderEngine::PresentShaderType shaderType, Shader &shader, const std::string &shaderFilename);
|
||||
bool checkCompileStatus(GLuint shader, const std::string & shaderTitle);
|
||||
bool linkProgram(GLuint programID);
|
||||
void disablePresetShaders();
|
||||
GLuint loadPresetShader(const PresentShaderType shaderType, Shader &shader, std::string &shaderFilename);
|
||||
|
||||
@ -92,14 +96,9 @@ private:
|
||||
|
||||
// programs generated from preset shader code
|
||||
GLuint programID_presetComp, programID_presetWarp;
|
||||
GLuint programID_blur1, programID_blur2;
|
||||
|
||||
bool presetCompShaderLoaded, presetWarpShaderLoaded;
|
||||
|
||||
|
||||
GLuint CompileShaderProgram(const std::string & VertexShaderCode, const std::string & FragmentShaderCode, const std::string & shaderTypeString);
|
||||
|
||||
|
||||
static GLint UNIFORM_V2F_C4F_VERTEX_TRANFORMATION;
|
||||
static GLint UNIFORM_V2F_C4F_VERTEX_POINT_SIZE;
|
||||
static GLint UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION;
|
||||
|
||||
70
src/libprojectM/Renderer/Texture.cpp
Normal file
70
src/libprojectM/Renderer/Texture.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "Texture.hpp"
|
||||
|
||||
Sampler::Sampler(const GLint _wrap_mode, const GLint _filter_mode) :
|
||||
wrap_mode(_wrap_mode),
|
||||
filter_mode(_filter_mode)
|
||||
{
|
||||
glGenSamplers(1, &samplerID);
|
||||
glSamplerParameteri(samplerID, GL_TEXTURE_MIN_FILTER, _filter_mode);
|
||||
glSamplerParameteri(samplerID, GL_TEXTURE_MAG_FILTER, _filter_mode);
|
||||
glSamplerParameteri(samplerID, GL_TEXTURE_WRAP_S, _wrap_mode);
|
||||
glSamplerParameteri(samplerID, GL_TEXTURE_WRAP_T, _wrap_mode);
|
||||
}
|
||||
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
glDeleteSamplers(1, &samplerID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Texture::Texture(const int _width, const int _height, const bool _userTexture) :
|
||||
type(GL_TEXTURE_2D),
|
||||
width(_width),
|
||||
height(_height),
|
||||
userTexture(_userTexture)
|
||||
{
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
Texture::Texture(const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture) :
|
||||
texID(_texID),
|
||||
type(_type),
|
||||
width(_width),
|
||||
height(_height),
|
||||
userTexture(_userTexture)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
glDeleteTextures(1, &texID);
|
||||
|
||||
for(std::vector<Sampler*>::const_iterator iter = samplers.begin(); iter != samplers.end(); iter++)
|
||||
{
|
||||
delete (*iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Sampler* Texture::getSampler(const GLint _wrap_mode, const GLint _filter_mode)
|
||||
{
|
||||
for(std::vector<Sampler*>::const_iterator iter = samplers.begin(); iter != samplers.end(); iter++)
|
||||
{
|
||||
if ((*iter)->wrap_mode == _wrap_mode && (*iter)->filter_mode == _filter_mode)
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
}
|
||||
|
||||
// Sampler not found -> adding it
|
||||
Sampler * sampler = new Sampler(_wrap_mode, _filter_mode);
|
||||
samplers.push_back(sampler);
|
||||
|
||||
return sampler;
|
||||
}
|
||||
42
src/libprojectM/Renderer/Texture.hpp
Normal file
42
src/libprojectM/Renderer/Texture.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef TEXTURE_HPP_
|
||||
#define TEXTURE_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
|
||||
class Sampler
|
||||
{
|
||||
public:
|
||||
GLuint samplerID;
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
|
||||
Sampler(const GLint _wrap_mode, const GLint _filter_mode);
|
||||
~Sampler();
|
||||
};
|
||||
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
|
||||
GLuint texID;
|
||||
GLenum type;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
bool userTexture;
|
||||
std::vector<Sampler*> samplers;
|
||||
|
||||
Texture(const int _width, const int _height, const bool _userTexture);
|
||||
Texture(const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture);
|
||||
~Texture();
|
||||
|
||||
Sampler *getSampler(const GLint _wrap_mode, const GLint _filter_mode);
|
||||
};
|
||||
|
||||
typedef std::pair<Texture*, Sampler*> TextureSamplerDesc;
|
||||
|
||||
#endif /* TEXTURE_HPP_ */
|
||||
@ -1,10 +1,9 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
#ifdef USE_DEVIL
|
||||
#include <IL/ilut.h>
|
||||
#else
|
||||
#include "SOIL2/SOIL2.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "win32-dirent.h"
|
||||
@ -23,253 +22,347 @@
|
||||
#include "TextureManager.hpp"
|
||||
#include "Common.hpp"
|
||||
#include "IdleTextures.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "PerlinNoise.hpp"
|
||||
|
||||
|
||||
|
||||
TextureManager::TextureManager(const std::string _presetURL): presetURL(_presetURL)
|
||||
|
||||
TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX, const int texsizeY):
|
||||
presetsURL(_presetsURL)
|
||||
{
|
||||
#ifdef USE_DEVIL
|
||||
ilInit();
|
||||
iluInit();
|
||||
ilutInit();
|
||||
ilutRenderer(ILUT_OPENGL);
|
||||
#endif
|
||||
extensions.push_back(".jpg");
|
||||
extensions.push_back(".dds");
|
||||
extensions.push_back(".png");
|
||||
extensions.push_back(".tga");
|
||||
extensions.push_back(".bmp");
|
||||
extensions.push_back(".dib");
|
||||
|
||||
Preload();
|
||||
loadTextureDir();
|
||||
Preload();
|
||||
loadTextureDir();
|
||||
|
||||
// Create main texture ans associated samplers
|
||||
mainTexture = new Texture(texsizeX, texsizeY, false);
|
||||
mainTexture->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
mainTexture->getSampler(GL_REPEAT, GL_NEAREST);
|
||||
mainTexture->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
mainTexture->getSampler(GL_CLAMP_TO_EDGE, GL_NEAREST);
|
||||
textures["main"] = mainTexture;
|
||||
|
||||
PerlinNoise noise;
|
||||
|
||||
GLuint noise_texture_lq_lite;
|
||||
glGenTextures(1, &noise_texture_lq_lite);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq_lite);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_lq_lite);
|
||||
Texture * textureNoise_lq_lite = new Texture(noise_texture_lq_lite, GL_TEXTURE_2D, 32, 32, false);
|
||||
textureNoise_lq_lite->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_lq_lite"] = textureNoise_lq_lite;
|
||||
|
||||
GLuint noise_texture_lq;
|
||||
glGenTextures(1, &noise_texture_lq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_lq);
|
||||
Texture * textureNoise_lq = new Texture(noise_texture_lq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_lq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_lq"] = textureNoise_lq;
|
||||
|
||||
GLuint noise_texture_mq;
|
||||
glGenTextures(1, &noise_texture_mq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_mq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_mq);
|
||||
Texture * textureNoise_mq = new Texture(noise_texture_mq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_mq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_mq"] = textureNoise_mq;
|
||||
|
||||
GLuint noise_texture_hq;
|
||||
glGenTextures(1, &noise_texture_hq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_hq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_hq);
|
||||
Texture * textureNoise_hq = new Texture(noise_texture_hq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_hq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_hq"] = textureNoise_hq;
|
||||
|
||||
GLuint noise_texture_lq_vol;
|
||||
glGenTextures( 1, &noise_texture_lq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_lq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,GL_LUMINANCE ,GL_FLOAT ,noise.noise_lq_vol);
|
||||
Texture * textureNoise_lq_vol = new Texture(noise_texture_lq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
textureNoise_lq_vol->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noisevol_lq"] = textureNoise_lq_vol;
|
||||
|
||||
GLuint noise_texture_hq_vol;
|
||||
glGenTextures( 1, &noise_texture_hq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_hq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, GL_LUMINANCE, GL_FLOAT, noise.noise_hq_vol);
|
||||
Texture * textureNoise_hq_vol = new Texture(noise_texture_hq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
textureNoise_hq_vol->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noisevol_hq"] = textureNoise_hq_vol;
|
||||
}
|
||||
|
||||
TextureManager::~TextureManager()
|
||||
{
|
||||
Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
void TextureManager::Preload()
|
||||
{
|
||||
int width, height;
|
||||
|
||||
#ifdef USE_DEVIL
|
||||
ILuint image;
|
||||
ilGenImages(1, &image);
|
||||
ilBindImage(image);
|
||||
ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) M_data, M_bytes);
|
||||
GLuint tex = ilutGLBindTexImage();
|
||||
#else
|
||||
unsigned int tex = SOIL_load_OGL_texture_from_memory(
|
||||
M_data,
|
||||
M_bytes,
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
unsigned int tex = SOIL_load_OGL_texture_from_memory(
|
||||
M_data,
|
||||
M_bytes,
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
SOIL_FLAG_POWER_OF_TWO
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
,&width,&height);
|
||||
|
||||
SOIL_FLAG_POWER_OF_TWO
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
// | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
);
|
||||
#endif
|
||||
|
||||
textures["M.tga"]=tex;
|
||||
Texture * newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
textures["M.tga"] = newTex;
|
||||
|
||||
#ifdef USE_DEVIL
|
||||
ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) project_data,project_bytes);
|
||||
tex = ilutGLBindTexImage();
|
||||
#else
|
||||
tex = SOIL_load_OGL_texture_from_memory(
|
||||
project_data,
|
||||
project_bytes,
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
// tex = SOIL_load_OGL_texture_from_memory(
|
||||
// project_data,
|
||||
// project_bytes,
|
||||
// SOIL_LOAD_AUTO,
|
||||
// SOIL_CREATE_NEW_ID,
|
||||
// SOIL_FLAG_POWER_OF_TWO
|
||||
// | SOIL_FLAG_MULTIPLY_ALPHA
|
||||
// ,&width,&height);
|
||||
|
||||
SOIL_FLAG_POWER_OF_TWO
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
//| SOIL_FLAG_COMPRESS_TO_DXT
|
||||
);
|
||||
#endif
|
||||
// newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
// newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
// textures["project.tga"] = newTex;
|
||||
|
||||
// textures["project.tga"]=tex;
|
||||
tex = SOIL_load_OGL_texture_from_memory(
|
||||
headphones_data,
|
||||
headphones_bytes,
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
SOIL_FLAG_POWER_OF_TWO
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
,&width,&height);
|
||||
|
||||
#ifdef USE_DEVIL
|
||||
ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) headphones_data, headphones_bytes);
|
||||
tex = ilutGLBindTexImage();
|
||||
#else
|
||||
tex = SOIL_load_OGL_texture_from_memory(
|
||||
headphones_data,
|
||||
headphones_bytes,
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
|
||||
SOIL_FLAG_POWER_OF_TWO
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
// | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
);
|
||||
#endif
|
||||
|
||||
textures["headphones.tga"]=tex;
|
||||
newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
textures["headphones.tga"] = newTex;
|
||||
}
|
||||
|
||||
void TextureManager::Clear()
|
||||
{
|
||||
for(std::map<std::string, Texture*>::const_iterator iter = textures.begin(); iter != textures.end(); iter++)
|
||||
delete(iter->second);
|
||||
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
|
||||
for(std::map<std::string, GLuint>::const_iterator iter = textures.begin(); iter != textures.end(); iter++)
|
||||
TextureSamplerDesc TextureManager::getTexture(const std::string fullName, const GLenum defaultWrap, const GLenum defaultFilter)
|
||||
{
|
||||
std::string name;
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
|
||||
ExtractTextureSettings(fullName, wrap_mode, filter_mode, name);
|
||||
if (textures.find(name) == textures.end())
|
||||
{
|
||||
glDeleteTextures(1,&iter->second);
|
||||
return {NULL, NULL};
|
||||
}
|
||||
textures.clear();
|
||||
|
||||
if (fullName == name) {
|
||||
// Warp and filter mode not specified in sampler name
|
||||
// applying default
|
||||
wrap_mode = defaultWrap;
|
||||
filter_mode = defaultFilter;
|
||||
}
|
||||
|
||||
Texture * texture = textures[name];
|
||||
Sampler * sampler = texture->getSampler(wrap_mode, filter_mode);
|
||||
|
||||
return {texture, sampler};
|
||||
}
|
||||
|
||||
void TextureManager::setTexture(const std::string name, const unsigned int texId, const int width, const int height)
|
||||
|
||||
TextureSamplerDesc TextureManager::tryLoadingTexture(const std::string name)
|
||||
{
|
||||
textures[name] = texId;
|
||||
widths[name] = width;
|
||||
heights[name] = height;
|
||||
}
|
||||
TextureSamplerDesc texDesc;
|
||||
|
||||
//void TextureManager::unloadTextures(const PresetOutputs::cshape_container &shapes)
|
||||
//{
|
||||
/*
|
||||
for (PresetOutputs::cshape_container::const_iterator pos = shapes.begin();
|
||||
pos != shapes.end(); ++pos)
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
{
|
||||
std::string filename = name + extensions[x];
|
||||
std::string fullURL = presetsURL + PATH_SEPARATOR + filename;
|
||||
|
||||
if( (*pos)->enabled==1)
|
||||
{
|
||||
texDesc = loadTexture(name, fullURL);
|
||||
|
||||
if ( (*pos)->textured)
|
||||
{
|
||||
std::string imageUrl = (*pos)->getImageUrl();
|
||||
if (imageUrl != "")
|
||||
{
|
||||
std::string fullUrl = presetURL + "/" + imageUrl;
|
||||
ReleaseTexture(LoadTexture(fullUrl.c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (texDesc.first != NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//}
|
||||
|
||||
GLuint TextureManager::getTexture(const std::string filename)
|
||||
{
|
||||
std::string fullURL = presetURL + PATH_SEPARATOR + filename;
|
||||
return getTextureFullpath(filename,fullURL);
|
||||
return texDesc;
|
||||
}
|
||||
|
||||
GLuint TextureManager::getTextureFullpath(const std::string filename, const std::string imageURL)
|
||||
TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std::string fileName)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (textures.find(filename)!= textures.end())
|
||||
{
|
||||
return textures[filename];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int tex = SOIL_load_OGL_texture(
|
||||
fileName.c_str(),
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
SOIL_FLAG_MULTIPLY_ALPHA
|
||||
,&width,&height);
|
||||
|
||||
#ifdef USE_DEVIL
|
||||
GLuint tex = ilutGLLoadImage((char *)imageURL.c_str());
|
||||
#else
|
||||
int width, height;
|
||||
if (tex == 0)
|
||||
{
|
||||
return {NULL, NULL};
|
||||
}
|
||||
|
||||
unsigned int tex = SOIL_load_OGL_texture(
|
||||
imageURL.c_str(),
|
||||
SOIL_LOAD_AUTO,
|
||||
SOIL_CREATE_NEW_ID,
|
||||
Texture * newTexture = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
Sampler * sampler = newTexture->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
|
||||
//SOIL_FLAG_POWER_OF_TWO
|
||||
// SOIL_FLAG_MIPMAPS
|
||||
SOIL_FLAG_MULTIPLY_ALPHA
|
||||
//| SOIL_FLAG_COMPRESS_TO_DXT
|
||||
//| SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
//,&width,&height);
|
||||
);
|
||||
textures[name] = newTexture;
|
||||
|
||||
#endif
|
||||
textures[filename]=tex;
|
||||
widths[filename]=width;
|
||||
heights[filename]=height;
|
||||
return tex;
|
||||
|
||||
|
||||
}
|
||||
return {newTexture, sampler};
|
||||
}
|
||||
|
||||
int TextureManager::getTextureWidth(const std::string imageURL)
|
||||
{
|
||||
return widths[imageURL];
|
||||
}
|
||||
|
||||
int TextureManager::getTextureHeight(const std::string imageURL)
|
||||
{
|
||||
return heights[imageURL];
|
||||
}
|
||||
|
||||
unsigned int TextureManager::getTextureMemorySize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TextureManager::loadTextureDir()
|
||||
{
|
||||
std::string dirname = "/usr/local/share/projectM/textures";
|
||||
std::string dirname = std::string(DATADIR_PATH) + "/presets";
|
||||
|
||||
DIR * m_dir;
|
||||
DIR * m_dir;
|
||||
|
||||
// Allocate a new a stream given the current directory name
|
||||
if ((m_dir = opendir(dirname.c_str())) == NULL)
|
||||
{
|
||||
std::cout<<"No Textures Loaded from "<<dirname<<std::endl;
|
||||
return; // no files loaded. m_entries is empty
|
||||
}
|
||||
// Allocate a new a stream given the current directory name
|
||||
if ((m_dir = opendir(dirname.c_str())) == NULL)
|
||||
{
|
||||
std::cout<<"No Textures Loaded from "<<dirname<<std::endl;
|
||||
return; // no files loaded. m_entries is empty
|
||||
}
|
||||
|
||||
struct dirent * dir_entry;
|
||||
struct dirent * dir_entry;
|
||||
|
||||
while ((dir_entry = readdir(m_dir)) != NULL)
|
||||
{
|
||||
while ((dir_entry = readdir(m_dir)) != NULL)
|
||||
{
|
||||
// Convert char * to friendly string
|
||||
std::string filename(dir_entry->d_name);
|
||||
|
||||
// Convert char * to friendly string
|
||||
std::string filename(dir_entry->d_name);
|
||||
if (filename.length() > 0 && filename[0] == '.')
|
||||
continue;
|
||||
|
||||
if (filename.length() > 0 && filename[0] == '.')
|
||||
continue;
|
||||
std::string lowerCaseFileName(filename);
|
||||
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
|
||||
|
||||
// Create full path name
|
||||
std::string fullname = dirname + PATH_SEPARATOR + filename;
|
||||
// Remove extension
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
{
|
||||
size_t found = lowerCaseFileName.find(extensions[x]);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
std::string name = filename;
|
||||
name.replace(int(found), extensions[x].size(), "");
|
||||
|
||||
unsigned int texId = getTextureFullpath(filename, fullname);
|
||||
if(texId != 0)
|
||||
{
|
||||
user_textures.push_back(texId);
|
||||
textures[filename]=texId;
|
||||
user_texture_names.push_back(filename);
|
||||
}
|
||||
}
|
||||
// Create full path name
|
||||
std::string fullname = dirname + PATH_SEPARATOR + filename;
|
||||
loadTexture(name, fullname);
|
||||
|
||||
if (m_dir)
|
||||
{
|
||||
closedir(m_dir);
|
||||
m_dir = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dir)
|
||||
{
|
||||
closedir(m_dir);
|
||||
m_dir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string TextureManager::getRandomTextureName(std::string random_id)
|
||||
{
|
||||
if (user_texture_names.size() > 0)
|
||||
{
|
||||
std::string random_name = user_texture_names[rand() % user_texture_names.size()];
|
||||
random_textures.push_back(random_id);
|
||||
textures[random_id] = textures[random_name];
|
||||
return random_name;
|
||||
}
|
||||
else return "";
|
||||
|
||||
std::vector<std::string> user_texture_names;
|
||||
|
||||
for(std::map<std::string, Texture*>::const_iterator iter = textures.begin(); iter != textures.end(); iter++)
|
||||
{
|
||||
if (iter->second->userTexture) {
|
||||
user_texture_names.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
|
||||
if (user_texture_names.size() > 0)
|
||||
{
|
||||
std::string random_name = user_texture_names[rand() % user_texture_names.size()];
|
||||
random_textures.push_back(random_id);
|
||||
textures[random_id] = textures[random_name];
|
||||
return random_name;
|
||||
}
|
||||
else return "";
|
||||
}
|
||||
|
||||
void TextureManager::clearRandomTextures()
|
||||
{
|
||||
for (std::vector<std::string>::iterator pos = random_textures.begin(); pos != random_textures.end(); ++pos)
|
||||
{
|
||||
textures.erase(*pos);
|
||||
widths.erase(*pos);
|
||||
heights.erase(*pos);
|
||||
}
|
||||
random_textures.clear();
|
||||
for (std::vector<std::string>::iterator pos = random_textures.begin(); pos != random_textures.end(); ++pos)
|
||||
{
|
||||
textures.erase(*pos);
|
||||
}
|
||||
random_textures.clear();
|
||||
|
||||
}
|
||||
|
||||
void TextureManager::ExtractTextureSettings(const std::string qualifiedName, GLint & _wrap_mode, GLint & _filter_mode, std::string & name)
|
||||
{
|
||||
std::string lowerQualifiedName(qualifiedName);
|
||||
std::transform(lowerQualifiedName.begin(), lowerQualifiedName.end(), lowerQualifiedName.begin(), tolower);
|
||||
|
||||
_wrap_mode = GL_REPEAT;
|
||||
_filter_mode = GL_LINEAR;
|
||||
|
||||
if (lowerQualifiedName.substr(0,3) == "fc_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
_filter_mode = GL_LINEAR;
|
||||
_wrap_mode = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
else if (lowerQualifiedName.substr(0,3) == "fw_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
_filter_mode = GL_LINEAR;
|
||||
_wrap_mode = GL_REPEAT;
|
||||
}
|
||||
else if (lowerQualifiedName.substr(0,3) == "pc_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
_filter_mode = GL_NEAREST;
|
||||
_wrap_mode = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
else if (lowerQualifiedName.substr(0,3) == "pw_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
_filter_mode = GL_NEAREST;
|
||||
_wrap_mode = GL_REPEAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = qualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
const Texture * TextureManager::getMainTexture() const {
|
||||
return mainTexture;
|
||||
}
|
||||
|
||||
const std::vector<Texture*> & TextureManager::getBlurTextures() const {
|
||||
return blurTextures;
|
||||
}
|
||||
|
||||
|
||||
void TextureManager::updateMainTexture()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, mainTexture->texID);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, mainTexture->width, mainTexture->height);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@ -5,29 +5,36 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "projectM-opengl.h"
|
||||
#include "Texture.hpp"
|
||||
|
||||
|
||||
class TextureManager
|
||||
{
|
||||
std::string presetURL;
|
||||
std::map<std::string,unsigned int> textures;
|
||||
std::map<std::string,unsigned int> heights;
|
||||
std::map<std::string,unsigned int> widths;
|
||||
std::vector<unsigned int> user_textures;
|
||||
std::vector<std::string> user_texture_names;
|
||||
std::string presetsURL;
|
||||
std::map<std::string, Texture*> textures;
|
||||
std::vector<Texture*> blurTextures;
|
||||
Texture * mainTexture;
|
||||
|
||||
std::vector<std::string> random_textures;
|
||||
void loadTextureDir();
|
||||
TextureSamplerDesc loadTexture(const std::string name, const std::string imageUrl);
|
||||
void ExtractTextureSettings(const std::string qualifiedName, GLint &_wrap_mode, GLint &_filter_mode, std::string & name);
|
||||
std::vector<std::string> extensions;
|
||||
|
||||
public:
|
||||
TextureManager(std::string _presetsURL, const int texsizeX, const int texsizeY);
|
||||
~TextureManager();
|
||||
TextureManager(std::string _presetURL);
|
||||
//void unloadTextures(const PresetOutputs::cshape_container &shapes);
|
||||
|
||||
void Clear();
|
||||
void Preload();
|
||||
unsigned int getTexture(const std::string filenamne);
|
||||
unsigned int getTextureFullpath(const std::string filename, const std::string imageUrl);
|
||||
unsigned int getTextureMemorySize();
|
||||
int getTextureWidth(const std::string imageUrl);
|
||||
int getTextureHeight(const std::string imageUrl);
|
||||
void setTexture(const std::string name, const unsigned int texId, const int width, const int height);
|
||||
void loadTextureDir();
|
||||
TextureSamplerDesc tryLoadingTexture(const std::string name);
|
||||
TextureSamplerDesc getTexture(const std::string fullName, const GLenum defaultWrap, const GLenum defaultFilter);
|
||||
const Texture * getMainTexture() const;
|
||||
const std::vector<Texture *> & getBlurTextures() const;
|
||||
|
||||
void updateMainTexture();
|
||||
|
||||
std::string getRandomTextureName(std::string rand_name);
|
||||
void clearRandomTextures();
|
||||
};
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* UserTexture.cpp
|
||||
*
|
||||
* Created on: Jul 16, 2008
|
||||
* Author: pete
|
||||
*/
|
||||
|
||||
#include "UserTexture.hpp"
|
||||
|
||||
UserTexture::UserTexture(std::string qualifiedName): qname(qualifiedName)
|
||||
{
|
||||
|
||||
if (qualifiedName.substr(0,3) == "fc_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
bilinear = true;
|
||||
wrap = false;
|
||||
}
|
||||
else if (qualifiedName.substr(0,3) == "fw_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
bilinear = true;
|
||||
wrap = true;
|
||||
}
|
||||
else if (qualifiedName.substr(0,3) == "pc_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
bilinear = false;
|
||||
wrap = false;
|
||||
}
|
||||
else if (qualifiedName.substr(0,3) == "pw_")
|
||||
{
|
||||
name = qualifiedName.substr(3);
|
||||
bilinear = false;
|
||||
wrap = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = qualifiedName;
|
||||
bilinear = true;
|
||||
wrap = true;
|
||||
}
|
||||
|
||||
texsizeDefined = false;
|
||||
}
|
||||
|
||||
UserTexture::~UserTexture()
|
||||
{
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* UserTexture.hpp
|
||||
*
|
||||
* Created on: Jul 16, 2008
|
||||
* Author: pete
|
||||
*/
|
||||
|
||||
#ifndef USERTEXTURE_HPP_
|
||||
#define USERTEXTURE_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
class UserTexture
|
||||
{
|
||||
public:
|
||||
|
||||
bool wrap;
|
||||
bool bilinear;
|
||||
|
||||
bool texsizeDefined;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
unsigned int texID;
|
||||
|
||||
std::string qname;
|
||||
std::string name;
|
||||
|
||||
UserTexture(std::string qualifiedName);
|
||||
virtual ~UserTexture();
|
||||
};
|
||||
|
||||
#endif /* USERTEXTURE_HPP_ */
|
||||
@ -84,12 +84,9 @@ void VideoEcho::Draw(RenderContext &context)
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glUseProgram(context.programID_v2f_c4f_t2f);
|
||||
|
||||
glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho));
|
||||
|
||||
glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0);
|
||||
|
||||
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
//
|
||||
|
||||
#include "pmSDL.hpp"
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "Renderer/ShaderEngine.hpp"
|
||||
|
||||
void projectMSDL::audioInputCallbackF32(void *userdata, unsigned char *stream, int len) {
|
||||
projectMSDL *app = (projectMSDL *) userdata;
|
||||
@ -211,6 +214,11 @@ void projectMSDL::renderFrame() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
projectM::renderFrame();
|
||||
|
||||
if (renderToTexture) {
|
||||
renderTexture();
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(win);
|
||||
}
|
||||
|
||||
@ -228,15 +236,107 @@ projectMSDL::projectMSDL(std::string config_file, int flags) : projectM(config_f
|
||||
isFullScreen = false;
|
||||
}
|
||||
|
||||
void projectMSDL::init(SDL_Window *window, SDL_GLContext *_glCtx) {
|
||||
void projectMSDL::init(SDL_Window *window, SDL_GLContext *_glCtx, const bool _renderToTexture) {
|
||||
win = window;
|
||||
glCtx = _glCtx;
|
||||
selectRandom(true);
|
||||
projectM_resetGL(width, height);
|
||||
|
||||
renderToTexture = _renderToTexture;
|
||||
|
||||
if (renderToTexture) {
|
||||
programID = ShaderEngine::CompileShaderProgram(ShaderEngine::v2f_c4f_t2f_vert, ShaderEngine::v2f_c4f_t2f_frag, "v2f_c4f_t2f");
|
||||
textureID = projectM::initRenderToTexture();
|
||||
|
||||
float points[16] = {
|
||||
-0.8, -0.8,
|
||||
0.0, 0.0,
|
||||
|
||||
-0.8, 0.8,
|
||||
0.0, 1.0,
|
||||
|
||||
0.8, -0.8,
|
||||
1.0, 0.0,
|
||||
|
||||
0.8, 0.8,
|
||||
1.0, 1.0,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, points, GL_DYNAMIC_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0); // Positions
|
||||
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2)); // Textures
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string projectMSDL::getActivePresetName()
|
||||
{
|
||||
return std::string("hey");
|
||||
unsigned int index = 0;
|
||||
if (selectedPresetIndex(index)) {
|
||||
return getPresetName(index);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
void projectMSDL::renderTexture() {
|
||||
static int frame = 0;
|
||||
frame++;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glViewport(0, 0, getWindowWidth(), getWindowHeight());
|
||||
|
||||
glUseProgram(programID);
|
||||
|
||||
glUniform1i(glGetUniformLocation(programID, "texture_sampler"), 0);
|
||||
|
||||
glm::mat4 mat_proj = glm::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 2.0f, 10.0f);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glm::mat4 mat_model = glm::mat4(1.0f);
|
||||
mat_model = glm::translate(mat_model, glm::vec3(cos(frame*0.023),
|
||||
cos(frame*0.017),
|
||||
-5+sin(frame*0.022)*2));
|
||||
mat_model = glm::rotate(mat_model, glm::radians((float) sin(frame*0.0043)*360),
|
||||
glm::vec3(sin(frame*0.0017),
|
||||
sin(frame *0.0032),
|
||||
1));
|
||||
|
||||
glm::mat4 mat_transf = glm::mat4(1.0f);
|
||||
mat_transf = mat_proj * mat_model;
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(programID, "vertex_transformation"), 1, GL_FALSE, glm::value_ptr(mat_transf));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
|
||||
glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ public:
|
||||
|
||||
projectMSDL(Settings settings, int flags);
|
||||
projectMSDL(std::string config_file, int flags);
|
||||
void init(SDL_Window *window, SDL_GLContext *glCtx);
|
||||
void init(SDL_Window *window, SDL_GLContext *glCtx, const bool renderToTexture = false);
|
||||
int openAudioInput();
|
||||
void beginAudioCapture();
|
||||
void endAudioCapture();
|
||||
@ -54,6 +54,11 @@ private:
|
||||
projectM::Settings settings;
|
||||
SDL_AudioDeviceID audioInputDevice;
|
||||
unsigned int width, height;
|
||||
bool renderToTexture;
|
||||
GLuint programID = 0;
|
||||
GLuint m_vbo = 0;
|
||||
GLuint m_vao = 0;
|
||||
GLuint textureID = 0;
|
||||
|
||||
// audio input device characteristics
|
||||
unsigned short audioChannelsCount;
|
||||
@ -67,6 +72,7 @@ private:
|
||||
|
||||
void keyHandler(SDL_Event *);
|
||||
SDL_AudioDeviceID selectAudioInput(int count);
|
||||
void renderTexture();
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user