User loadable pixel shader textures implementation. Texsize + random textures need to be done next

git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@1107 6778bc44-b910-0410-a7a0-be141de4315d
This commit is contained in:
psperl
2008-07-19 02:20:55 +00:00
parent 16593bfde2
commit 1a6c429af1
16 changed files with 948 additions and 708 deletions

View File

@ -332,13 +332,13 @@ int BuiltinParams::load_all_builtin_param(const PresetInputs & presetInputs, Pre
load_builtin_param_float("sy", (void*)&presetOutputs.sy, presetOutputs.sy_mesh, P_FLAG_PER_PIXEL |P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("b1n", (void*)&presetOutputs.shader.blur1n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2n", (void*)&presetOutputs.shader.blur2n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3n", (void*)&presetOutputs.shader.blur3n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1x", (void*)&presetOutputs.shader.blur1x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2x", (void*)&presetOutputs.shader.blur2x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3x", (void*)&presetOutputs.shader.blur3x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1ed", (void*)&presetOutputs.shader.blur1ed, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1n", (void*)&presetOutputs.warpShader.blur1n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2n", (void*)&presetOutputs.warpShader.blur2n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3n", (void*)&presetOutputs.warpShader.blur3n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1x", (void*)&presetOutputs.warpShader.blur1x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2x", (void*)&presetOutputs.warpShader.blur2x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3x", (void*)&presetOutputs.warpShader.blur3x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1ed", (void*)&presetOutputs.warpShader.blur1ed, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_r", (void*)&presetOutputs.wave.r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_g", (void*)&presetOutputs.wave.g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");

View File

@ -32,7 +32,7 @@ Func.cpp Eval.cpp PerFrameEqn.cpp PerPointEqn.cpp fftsg.cpp KeyHandler.cpp
timer.cpp wipemalloc.cpp BuiltinFuncs.cpp BuiltinParams.cpp Renderer.cpp
PresetLoader.cpp PresetChooser.cpp PresetFrameIO.cpp PresetMerge.cpp PipelineContext.cpp
ConfigFile.cpp IdlePreset.cpp TextureManager.cpp TimeKeeper.cpp Filters.cpp Renderable.cpp Pipeline.cpp PerPixelMesh.cpp
MilkdropWaveform.cpp Waveform.cpp VideoEcho.cpp Shader.cpp PerlinNoise.cpp ${GLEW_SOURCES})
MilkdropWaveform.cpp Waveform.cpp VideoEcho.cpp Shader.cpp PerlinNoise.cpp UserTexture.cpp ShaderEngine.cpp ${GLEW_SOURCES})
if (USE_DEVIL)
SET (projectM_SOURCES ${projectM_SOURCES})

View File

@ -442,7 +442,7 @@ int Parser::parse_line(std::istream & fs, Preset * preset)
if (!strncmp(eqn_string, WARP_STRING, WARP_STRING_LENGTH))
{
//std::cout << "parsing warp string block\n" << std::endl;
parse_string_block(fs, &preset->presetOutputs().shader.warp);
parse_string_block(fs, &preset->presetOutputs().warpShader.programSource);
return PROJECTM_SUCCESS;
}
@ -451,7 +451,7 @@ int Parser::parse_line(std::istream & fs, Preset * preset)
if (!strncmp(eqn_string, COMPOSITE_STRING, COMPOSITE_STRING_LENGTH))
{
//std::cout << "parsing composite string block\n" << std::endl;
parse_string_block(fs, &preset->presetOutputs().shader.composite);
parse_string_block(fs, &preset->presetOutputs().compositeShader.programSource);
return PROJECTM_SUCCESS;
}
@ -1543,7 +1543,7 @@ void Parser::parse_string_block(std::istream & fs, std::string * out_string) {
skipList.insert('`');
readStringUntil(fs, out_string, false, skipList);
std::cout << "out_string:\n " << *out_string << "\n" << std::endl;
//std::cout << "out_string:\n " << *out_string << "\n" << std::endl;
}
@ -1655,15 +1655,15 @@ bool Parser::scanForComment(std::istream & fs) {
return true;
else
c = fs.get();
if (c == EOF)
if (c == EOF)
return true;
if (c == '\n')
{
return true;
}
}
} else {
} else {
fs.unget();
return false;
}
@ -1686,10 +1686,10 @@ void Parser::readStringUntil(std::istream & fs, std::string * out_buffer, bool w
/* Now interpret the character */
switch (c)
{
case '/':
case '/':
{
bool commentExisted = scanForComment(fs);
if (!commentExisted) {
if (!commentExisted) {
out_buffer->push_back(c);
break;
} else {
@ -1700,7 +1700,7 @@ void Parser::readStringUntil(std::istream & fs, std::string * out_buffer, bool w
case '\n':
if (!out_buffer->empty() && ((*out_buffer)[out_buffer->length() -1] == '\n'))
return;
line_count++;
if (wrapAround)
{

View File

@ -1,5 +1,5 @@
/*
* ShaderEngine.cpp
* PerlinNoise.cpp
*
* Created on: Jul 11, 2008
* Author: pete
@ -13,27 +13,19 @@ PerlinNoise::PerlinNoise()
{
for (int x = 0; x < 256;x++)
for (int y = 0; y < 256;y++)
noise_lq[x][y] = noise(x + 3240*y);
noise_lq[x][y] = noise(x , y);
for (int x = 0; x < 32;x++)
for (int y = 0; y < 32;y++)
noise_lq_lite[x][y] = noise(x,y);
int seed = rand()%1000;
int seed2 = rand()%1000;
int seed3 = rand()%1000;
noise_lq_lite[x][y] = noise(4*x,16*y);
for (int x = 0; x < 256;x++)
for (int y = 0; y < 256;y++)
noise_mq[x][y] = InterpolatedNoise((float)x/(float)4.0,(float)y/(float)4.0);
noise_mq[x][y] = InterpolatedNoise((float)x/(float)2.0,(float)y/(float)2.0);
for (int x = 0; x < 256;x++)
for (int y = 0; y < 256;y++)
noise_hq[x][y] = InterpolatedNoise((float)x/(float)8.0,(float)y/(float)8.0);
for (int x = 0; x < 512;x++)
for (int y = 0; y < 512;y++)
noise_perlin[x][y] = perlin_noise_2d(x,y,6321,7,seed2,0.5,128);
noise_hq[x][y] = InterpolatedNoise((float)x/(float)3.0,(float)y/(float)3.0);
for (int x = 0; x < 32;x++)
for (int y = 0; y < 32;y++)
@ -45,7 +37,14 @@ PerlinNoise::PerlinNoise()
for (int z = 0; z < 32;z++)
noise_hq_vol[x][y][z] = noise(x,y,z);//perlin_noise_3d(x,y,z,6121,7,seed3,0.5,64);
int seed = rand()%1000;
int size = 512;
int octaves = sqrt(size);
for (int x = 0; x < size;x++)
for (int y = 0; y < size;y++)
noise_perlin[x][y] = perlin_noise_2d(x,y,6321,octaves,seed,0.5,size/4);
}
PerlinNoise::~PerlinNoise()

View File

@ -1,12 +1,12 @@
/*
* ShaderEngine.hpp
* PerlinNoise.hpp
*
* Created on: Jul 11, 2008
* Author: pete
*/
#ifndef SHADERENGINE_HPP_
#define SHADERENGINE_HPP_
#ifndef PERLINNOISE_HPP_
#define PERLINNOISE_HPP_
#include <math.h>
@ -100,11 +100,6 @@ private:
}
static inline float tri_interp(float a, float b, float c)
{
return a+(b-a)*c*c*(3-2*c);
}
static inline float perlin_octave_2d(float x,float y, int width, int seed, float period)
{
@ -128,20 +123,29 @@ private:
return value;
}
static inline float perlin_noise_2d(int x, int y, int width, int octaves, int seed, float persistance, float basePeriod)
{
float p = persistance;
float val = 0.0;
for (int i = 0; i<octaves;i++)
static inline float perlin_octave_2d_cos(float x,float y, int width, int seed, float period)
{
val += perlin_octave_2d(x,y,width,seed,basePeriod) * p;
basePeriod *= 0.5;
p *= persistance;
float freq=1/(float)(period);
int num=(int)(width*freq);
int step_x=(int)(x*freq);
int step_y=(int)(y*freq);
float zone_x=x*freq-step_x;
float zone_y=y*freq-step_y;
int box=step_x+step_y*num;
int noisedata=(box+seed);
float a=cos_interp(noise(noisedata),noise(noisedata+1),zone_x);
float b=cos_interp(noise(noisedata+num),noise(noisedata+1+num),zone_x);
float value=cos_interp(a,b,zone_y);
return value;
}
return val;
}
static inline float perlin_octave_3d(float x,float y, float z,int width, int seed, float period)
{
@ -200,6 +204,21 @@ private:
}
static inline float perlin_noise_2d(int x, int y, int width, int octaves, int seed, float persistance, float basePeriod)
{
float p = persistance;
float val = 0.0;
for (int i = 0; i<octaves;i++)
{
val += perlin_octave_2d_cos(x,y,width,seed,basePeriod) * p;
basePeriod *= 0.5;
p *= persistance;
}
return val;
}
static inline float perlin_noise_3d(int x, int y, int z, int width, int octaves, int seed, float persistance, float basePeriod)
{
float p = persistance;
@ -219,4 +238,4 @@ private:
};
#endif /* SHADERENGINE_HPP_ */
#endif /* PERLINNOISE_HPP_ */

View File

@ -18,7 +18,8 @@ public:
float screenDecay;
Shader shader;
Shader warpShader;
Shader compositeShader;
std::vector<RenderItem*> drawables;
std::vector<RenderItem*> compositeDrawables;

View File

@ -63,7 +63,7 @@ Preset::Preset(const std::string & absoluteFilePath, const std::string & presetN
m_presetOutputs.customWaves.clear();
m_presetOutputs.customShapes.clear();
initialize(absoluteFilePath);
}
@ -107,7 +107,7 @@ int Preset::add_per_pixel_eqn(char * name, GenExpr * gen_expr)
assert(name);
if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: per pixel equation (name = \"%s\")\n", name);
/* Search for the parameter so we know what matrix the per pixel equation is referencing */
@ -236,7 +236,7 @@ void Preset::evalPerFrameEquations()
}
void Preset::preloadInitialize() {
/// @note commented this out because it should be unnecessary
// Clear equation trees
//init_cond_tree.clear();
@ -303,7 +303,7 @@ void Preset::initialize(std::istream & in)
{
if (PRESET_DEBUG)
std::cerr << "[Preset] failed to load from stream " << std::endl;
std::cerr << "[Preset] failed to load from stream " << std::endl;
/// @bug how should we handle this problem? a well define exception?
throw retval;
@ -347,12 +347,12 @@ void Preset::loadCustomShapeUnspecInitConds()
void Preset::evaluateFrame()
{
// Evaluate all equation objects according to milkdrop flow diagram
// Evaluate all equation objects according to milkdrop flow diagram
evalPerFrameInitEquations();
evalPerFrameEquations();
// Important step to ensure custom shapes and waves don't stamp on the q variable values
// Important step to ensure custom shapes and waves don't stamp on the q variable values
// calculated by the per frame (init) and per pixel equations.
transfer_q_variables(customWaves);
transfer_q_variables(customShapes);
@ -369,7 +369,7 @@ void Preset::evaluateFrame()
// Setup pointers of the custom waves and shapes to the preset outputs instance
/// @slow an extra O(N) per frame, could do this during eval
m_presetOutputs.customWaves = PresetOutputs::cwave_container(customWaves);
m_presetOutputs.customWaves = PresetOutputs::cwave_container(customWaves);
m_presetOutputs.customShapes = PresetOutputs::cshape_container(customShapes);
}
@ -382,7 +382,7 @@ void Preset::initialize_PerPixelMeshes()
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.cx_mesh[x][y]=m_presetOutputs.cx;
}}
@ -390,68 +390,68 @@ void Preset::initialize_PerPixelMeshes()
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.cy_mesh[x][y]=m_presetOutputs.cy;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.sx_mesh[x][y]=m_presetOutputs.sx;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.sy_mesh[x][y]=m_presetOutputs.sy;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.dx_mesh[x][y]=m_presetOutputs.dx;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.dy_mesh[x][y]=m_presetOutputs.dy;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.zoom_mesh[x][y]=m_presetOutputs.zoom;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.zoomexp_mesh[x][y]=m_presetOutputs.zoomexp;
m_presetOutputs.zoomexp_mesh[x][y]=m_presetOutputs.zoomexp;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.rot_mesh[x][y]=m_presetOutputs.rot;
}}
for (x=0;x<m_presetInputs.gx;x++){
for(y=0;y<m_presetInputs.gy;y++){
m_presetOutputs.warp_mesh[x][y]=m_presetOutputs.warp;
}}
}
// Evaluates all per-pixel equations
// Evaluates all per-pixel equations
void Preset::evalPerPixelEqns()
{
@ -467,9 +467,9 @@ void Preset::evalPerPixelEqns()
int Preset::readIn(std::istream & fs) {
line_mode_t line_mode;
presetOutputs().shader.composite.clear();
presetOutputs().shader.warp.clear();
presetOutputs().compositeShader.programSource.clear();
presetOutputs().warpShader.programSource.clear();
/* Parse any comments */
if (Parser::parse_top_comment(fs) < 0)
{
@ -489,7 +489,7 @@ int Preset::readIn(std::istream & fs) {
/// @note We ignore the preset name because [preset00] is just not so useful
// Loop through each line in file, trying to succesfully parse the file.
// Loop through each line in file, trying to succesfully parse the file.
// If a line does not parse correctly, keep trucking along to next line.
int retval;
while ((retval = Parser::parse_line(fs, this)) != EOF)

View File

@ -9,10 +9,9 @@
#include <iostream>
#include <algorithm>
#include <cassert>
#include <fstream>
#include "omptl/omptl"
#include "omptl/omptl_algorithm"
#include "PerlinNoise.hpp"
#include "UserTexture.hpp"
class Preset;
@ -21,10 +20,7 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec
{
int x; int y;
#ifdef USE_CG
this->compositeShadersEnabled = false;
this->warpShadersEnabled = false;
#endif
this->totalframes = 1;
this->noSwitch = false;
this->showfps = false;
@ -105,520 +101,23 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec
}
}
#ifdef USE_CG
SetupCg();
std::cout<<"Generating Noise Textures"<<std::endl;
PerlinNoise noise;
glGenTextures( 1, &blur1_tex );
glBindTexture(GL_TEXTURE_2D, blur1_tex);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTexParameterf(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 / 2, texsize / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTexParameterf(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 / 4, texsize / 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTexParameterf(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);
blur1_enabled = false;
blur2_enabled = false;
blur3_enabled = false;
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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
shaderEngine.SetParams(renderTarget->texsize,renderTarget->textureID[1],aspect,beatDetect,textureManager);
#endif
}
void Renderer::SetPipeline(Pipeline &pipeline)
{
currentPipe = &pipeline;
#ifdef USE_CG
rand_preset[0] = (rand()%100) * .01;
rand_preset[1] = (rand()%100) * .01;
rand_preset[2] = (rand()%100) * .01;
rand_preset[3] = (rand()%100) * .01;
if(warpShadersEnabled) cgDestroyProgram(myCgWarpProgram);
if(compositeShadersEnabled) cgDestroyProgram(myCgCompositeProgram);
warpShadersEnabled = LoadCgProgram(pipeline.shader.warp, myCgWarpProgram);
compositeShadersEnabled = LoadCgProgram(pipeline.shader.composite, myCgCompositeProgram);
pipeline.shader.warp.clear();
pipeline.shader.composite.clear();
shaderEngine.reset();
shaderEngine.loadShader(pipeline.warpShader);
shaderEngine.loadShader(pipeline.compositeShader);
#endif
}
#ifdef USE_CG
bool Renderer::LoadCgProgram(std::string program, CGprogram &p)
{
//if (p != NULL) cgDestroyProgram(p);
//p = NULL;
if (program.length() > 0)
{
size_t found = program.rfind('}');
if (found!=std::string::npos)
{
//std::cout << "last '}' found at: " << int(found) << std::endl;
program.replace(int(found),1,"OUT.color.xyz=ret.xyz;\nOUT.color.w=1;\nreturn OUT;\n}");
}
else return false;
found = program.rfind('{');
if (found!=std::string::npos)
{
//std::cout << "first '{' found at: " << int(found) << std::endl;
program.replace(int(found),1,"{\nfloat rad=getrad;\nfloat ang=getang;\n");
}
else return false;
found = program.find("shader_body");
if (found!=std::string::npos)
{
//std::cout << "first 'shader_body' found at: " << int(found) << std::endl;
program.replace(int(found),11,"outtype projectm(float2 uv : TEXCOORD0)\n");
}
else return false;
found = 0;
found = program.find("sampler_", found);
while (found != std::string::npos)
{
found+=8;
size_t end = program.find_first_of(" ;,\n)", found);
if(end != std::string::npos)
{
std::string sampler = program.substr((int)found,(int)end-found);
std::cout<<sampler<<std::endl;
}
found = program.find("sampler_", found);
}
found = program.find("GetBlur3");
if (found!=std::string::npos)
blur1_enabled = blur2_enabled = blur3_enabled = true;
else
{
found = program.find("GetBlur2");
if (found!=std::string::npos)
blur1_enabled = blur2_enabled = true;
else
{
found = program.find("GetBlur1");
if (found!=std::string::npos)
blur1_enabled = true;
}
}
std::string temp;
temp.append(cgTemplate);
temp.append(program);
std::cout<<"Cg: Compilation Results:"<<std::endl<<std::endl;
std::cout<<program<<std::endl;
p = cgCreateProgram(myCgContext,
CG_SOURCE,
temp.c_str(),//temp.c_str(),
myCgProfile,
"projectm",
NULL);
checkForCgCompileError("creating shader program");
if (p==NULL) return false;
cgGLLoadProgram(p);
if (checkForCgCompileError("loading shader program"))
{
p = NULL;
return false;
}
return true;
}
else return false;
}
bool Renderer::checkForCgCompileError(const char *situation)
{
CGerror error;
const char *string = cgGetLastErrorString(&error);
error = cgGetError();
if (error != CG_NO_ERROR) {
std::cout<<"Cg: Compilation Error"<<std::endl;
std::cout<<"Cg: %"<<situation<<" - "<<string<<std::endl;
if (error == CG_COMPILER_ERROR) {
std::cout<<"Cg: "<< cgGetLastListing( myCgContext )<<std::endl;
}
return true;
}
return false;
}
void Renderer::checkForCgError(const char *situation)
{
CGerror error;
const char *string = cgGetLastErrorString(&error);
if (error != CG_NO_ERROR) {
std::cout<<"Cg: %"<<situation<<" - "<<string<<std::endl;
if (error == CG_COMPILER_ERROR) {
std::cout<<"Cg: "<< cgGetLastListing( myCgContext )<<std::endl;
}
exit(1);
}
}
void Renderer::SetupCg()
{
std::string line;
std::ifstream myfile (CMAKE_INSTALL_PREFIX "/share/projectM/shaders/projectM.cg");
if (myfile.is_open())
{
while (! myfile.eof() )
{
std::getline (myfile,line);
cgTemplate.append(line + "\n");
}
myfile.close();
}
else std::cout << "Unable to load shader template" << std::endl;
std::ifstream myfile2 (CMAKE_INSTALL_PREFIX "/share/projectM/shaders/blur.cg");
if (myfile2.is_open())
{
while (! myfile2.eof() )
{
std::getline (myfile2,line);
blurProgram.append(line + "\n");
}
myfile2.close();
}
else std::cout << "Unable to load blur template" << std::endl;
myCgContext = cgCreateContext();
checkForCgError("creating context");
cgGLSetDebugMode( CG_FALSE );
cgSetParameterSettingMode(myCgContext, CG_DEFERRED_PARAMETER_SETTING);
myCgProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(myCgProfile);
checkForCgError("selecting fragment profile");
std::cout<<"Cg: Initialized profile: "<<cgGetProfileString(myCgProfile)<<std::endl;
blur1Program = cgCreateProgram(myCgContext,
CG_SOURCE,
blurProgram.c_str(),
myCgProfile,
"blur1",
NULL);
checkForCgCompileError("creating blur1 program");
if (blur1Program==NULL) exit(1);
cgGLLoadProgram(blur1Program);
checkForCgError("loading blur1 program");
blur2Program = cgCreateProgram(myCgContext,
CG_SOURCE,
blurProgram.c_str(),
myCgProfile,
"blur2",
NULL);
checkForCgCompileError("creating blur2 program");
if (blur2Program==NULL) exit(1);
cgGLLoadProgram(blur2Program);
checkForCgError("loading blur2 program");
}
void Renderer::SetupCgVariables(CGprogram program, const Pipeline &pipeline, const PipelineContext &context)
{
float slow_roam_cos[4] = { 0.5 + 0.5*cos(context.time * 0.005),0.5 + 0.5*cos(context.time * 0.008),0.5 + 0.5*cos(context.time * 0.013),0.5 + 0.5*cos(context.time * 0.022)};
float roam_cos[4] ={ 0.5 + 0.5*cos(context.time * 0.3),0.5 + 0.5*cos(context.time * 1.3),0.5 + 0.5*cos(context.time * 5),0.5 + 0.5*cos(context.time * 20)};
float slow_roam_sin[4] = { 0.5 + 0.5*sin(context.time * 0.005),0.5 + 0.5*sin(context.time * 0.008),0.5 + 0.5*sin(context.time * 0.013),0.5 + 0.5*sin(context.time * 0.022)};
float roam_sin[4] ={ 0.5 + 0.5*sin(context.time * 0.3),0.5 + 0.5*sin(context.time * 1.3),0.5 + 0.5*sin(context.time * 5),0.5 + 0.5*sin(context.time * 20)};
cgGLSetParameter4fv(cgGetNamedParameter(program, "slow_roam_cos"), slow_roam_cos);
cgGLSetParameter4fv(cgGetNamedParameter(program, "roam_cos"), roam_cos);
cgGLSetParameter4fv(cgGetNamedParameter(program, "slow_roam_sin"), slow_roam_sin);
cgGLSetParameter4fv(cgGetNamedParameter(program, "roam_sin"), roam_sin);
cgGLSetParameter1f(cgGetNamedParameter(program, "time"), context.time);
cgGLSetParameter4f(cgGetNamedParameter(program, "rand_preset"), rand_preset[0], rand_preset[1],rand_preset[2],rand_preset[3]);
cgGLSetParameter4f(cgGetNamedParameter(program, "rand_frame"), (rand()%100) * .01,(rand()%100) * .01,(rand()%100) * .01,(rand()%100) * .01);
cgGLSetParameter1f(cgGetNamedParameter(program, "fps"), context.fps);
cgGLSetParameter1f(cgGetNamedParameter(program, "frame"), context.frame);
cgGLSetParameter1f(cgGetNamedParameter(program, "progress"), context.progress);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur1_min"), pipeline.shader.blur1n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur1_max"), pipeline.shader.blur1x);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur2_min"), pipeline.shader.blur2n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur2_max"), pipeline.shader.blur2x);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur3_min"), pipeline.shader.blur3n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur3_max"), pipeline.shader.blur3x);
cgGLSetParameter1f(cgGetNamedParameter(program, "bass"), beatDetect->bass);
cgGLSetParameter1f(cgGetNamedParameter(program, "mid"), beatDetect->mid);
cgGLSetParameter1f(cgGetNamedParameter(program, "treb"), beatDetect->treb);
cgGLSetParameter1f(cgGetNamedParameter(program, "bass_att"), beatDetect->bass_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "mid_att"), beatDetect->mid_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "treb_att"), beatDetect->treb_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "vol"), beatDetect->vol);
cgGLSetParameter1f(cgGetNamedParameter(program, "vol_att"), beatDetect->vol);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize"), renderTarget->texsize, renderTarget->texsize, 1/(float)renderTarget->texsize,1/(float)renderTarget->texsize);
cgGLSetParameter4f(cgGetNamedParameter(program, "aspect"), 1/aspect,1,aspect,1);
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_main"),renderTarget->textureID[1]);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_main"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq_lite"),noise_texture_lq_lite);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq_lite"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_mq"),noise_texture_mq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_mq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_hq"),noise_texture_hq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_hq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq"),noise_texture_lq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_perlin"),noise_texture_perlin);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_perlin"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_hq"),noise_texture_hq_vol);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_hq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_lq"),noise_texture_lq_vol);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_lq"));
if (blur1_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur1"),blur1_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur1"));
}
if (blur2_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur2"),blur2_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur2"));
}
if (blur3_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur3"),blur3_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur3"));
}
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_lq"), 256, 256,1.0/(float)256,1.0/(float)256);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_mq"), 64, 64,1.0/(float)64,1.0/(float)64);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_hq"), 32, 32,1.0/(float)32,1.0/(float)32);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_perlin"), 512, 512,1.0/(float)512,1.0/(float)512);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_lq_lite"), 32, 32,1.0/(float)32,1.0/(float)32);
}
void Renderer::SetupCgQVariables(CGprogram program, const PresetOutputs &q)
{
cgGLSetParameter4f(cgGetNamedParameter(program, "_qa"), q.q1, q.q2, q.q3, q.q4);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qb"), q.q5, q.q6, q.q7, q.q8);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qc"), q.q9, q.q10, q.q11, q.q12);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qd"), q.q13, q.q14, q.q15, q.q16);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qe"), q.q17, q.q18, q.q19, q.q20);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qf"), q.q21, q.q22, q.q23, q.q24);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qg"), q.q25, q.q26, q.q27, q.q28);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qh"), q.q29, q.q30, q.q31, q.q32);
}
void Renderer::RenderBlurTextures(const Pipeline *pipeline, const PipelineContext &pipelineContext)
{
if(blur1_enabled || blur2_enabled || blur3_enabled)
{
float tex[4][2] = {{0, 1},
{0, 0},
{1, 0},
{1, 1}};
glBlendFunc(GL_ONE, GL_ZERO);
glColor4f(1.0, 1.0, 1.0, 1.0f);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,tex);
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling profile");
if (blur1_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur1Program, "srctexsize"), renderTarget->texsize, renderTarget->texsize, 1/(float)renderTarget->texsize,1/(float)renderTarget->texsize);
cgGLBindProgram(blur1Program);
checkForCgError("binding blur1 program");
float points[4][2] = {{0, 1},
{0, 0},
{1, 0},
{1, 1}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur1_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,renderTarget->texsize, renderTarget->texsize);
cgGLUnbindProgram(myCgProfile);
checkForCgError("unbinding blur1 program");
}
if (blur2_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur2Program, "srctexsize"), renderTarget->texsize, renderTarget->texsize, 1/(float)renderTarget->texsize,1/(float)renderTarget->texsize);
cgGLBindProgram(blur2Program);
checkForCgError("binding blur2 program");
float points[4][2] = {{0, 0.5},
{0, 0},
{0.5, 0},
{0.5, 0.5}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur2_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,renderTarget->texsize/2, renderTarget->texsize/2);
}
if (blur3_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur2Program, "srctexsize"), renderTarget->texsize/2, renderTarget->texsize/2, 2/(float)renderTarget->texsize,2/(float)renderTarget->texsize);
float points[4][2] = {{0, 0.25},
{0, 0},
{0.25, 0},
{0.25, 0.25}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur3_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,renderTarget->texsize/4, renderTarget->texsize/4);
}
if (blur2_enabled || blur3_enabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("unbinding blur2 program");
}
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling blur profile");
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
#endif
void Renderer::ResetTextures()
{
@ -666,7 +165,7 @@ void Renderer::SetupPass1(const Pipeline* pipeline, const PipelineContext &pipel
glLoadIdentity();
#ifdef USE_CG
RenderBlurTextures(pipeline,pipelineContext);
shaderEngine.RenderBlurTextures(pipeline,pipelineContext,renderTarget->texsize);
#endif
}
@ -762,28 +261,11 @@ void Renderer::RenderFrame(const Pipeline* pipeline, const PipelineContext &pipe
SetupPass1(pipeline, pipelineContext);
#ifdef USE_CG
if (warpShadersEnabled)
{
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling warp profile");
cgGLBindProgram(myCgWarpProgram);
checkForCgError("binding warp program");
SetupCgVariables(myCgWarpProgram, *pipeline, pipelineContext);
}
shaderEngine.enableShader(currentPipe->warpShader,pipeline,&pipelineContext);
#endif
Interpolation(pipeline);
#ifdef USE_CG
if (warpShadersEnabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("disabling fragment profile");
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling fragment profile");
}
shaderEngine.disableShader();
#endif
@ -796,34 +278,20 @@ void Renderer::RenderFrame(PresetOutputs *presetOutputs, PresetInputs *presetInp
SetupPass1(presetOutputs, *presetInputs);
#ifdef USE_CG
if (warpShadersEnabled)
{
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling warp profile");
cgGLBindProgram(myCgWarpProgram);
checkForCgError("binding warp program");
SetupCgVariables(myCgWarpProgram, *presetOutputs, *presetInputs);
SetupCgQVariables(myCgWarpProgram, *presetOutputs);
}
shaderEngine.enableShader(presetOutputs->warpShader,presetOutputs,presetInputs);
#endif
Interpolation(presetOutputs, presetInputs);
#ifdef USE_CG
if (warpShadersEnabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("disabling fragment profile");
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling fragment profile");
}
shaderEngine.disableShader();
#endif
RenderItems(presetOutputs, *presetInputs);
FinishPass1();
#ifdef USE_CG
if (compositeShadersEnabled)
SetupCgQVariables(myCgCompositeProgram, *presetOutputs);
shaderEngine.SetupCgQVariables(presetOutputs->compositeShader, *presetOutputs);
#endif
Pass2(presetOutputs, *presetInputs);
}
@ -934,7 +402,7 @@ void Renderer::Interpolation(const Pipeline *pipeline)
glTexCoordPointer(2,GL_FLOAT,0,t);
mesh.Reset();
currentPipe = const_cast<Pipeline*>(pipeline);
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++)
@ -1401,15 +869,15 @@ void Renderer::draw_stats()
other_font->Render(buffer);
#ifdef USE_CG
glRasterPos2f(0, -.29+offset);
sprintf( buffer, "shader profile: %s", cgGetProfileString(myCgProfile));
sprintf( buffer, "shader profile: %s", shaderEngine.profileName.c_str());
other_font->Render(buffer);
glRasterPos2f(0, -.33+offset);
sprintf( buffer, " warp shader: %s", warpShadersEnabled ? "on" : "off");
sprintf( buffer, " warp shader: %s", currentPipe->warpShader.enabled ? "on" : "off");
other_font->Render(buffer);
glRasterPos2f(0, -.37+offset);
sprintf( buffer, " comp shader: %s", compositeShadersEnabled ? "on" : "off");
sprintf( buffer, " comp shader: %s", currentPipe->compositeShader.enabled ? "on" : "off");
other_font->Render(buffer);
#endif
glPopMatrix();
@ -1458,17 +926,7 @@ void Renderer::CompositeOutput(const Pipeline* pipeline, const PipelineContext &
glEnable(GL_TEXTURE_2D);
#ifdef USE_CG
if (compositeShadersEnabled)
{
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling warp profile");
cgGLBindProgram(myCgCompositeProgram);
checkForCgError("binding warp program");
SetupCgVariables(myCgCompositeProgram, *pipeline, pipelineContext);
}
shaderEngine.enableShader(currentPipe->compositeShader,pipeline,&pipelineContext);
#endif
@ -1497,13 +955,7 @@ void Renderer::CompositeOutput(const Pipeline* pipeline, const PipelineContext &
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#ifdef USE_CG
if (compositeShadersEnabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("disabling fragment profile");
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling fragment profile");
}
shaderEngine.disableShader();
#endif
for (std::vector<RenderItem*>::const_iterator pos = pipeline->compositeDrawables.begin(); pos != pipeline->compositeDrawables.end(); ++pos)

View File

@ -5,6 +5,7 @@
#include "PresetFrameIO.hpp"
#include "BeatDetect.hpp"
#include <string>
#include <set>
#ifdef USE_GLES1
#include <GLES/gl.h>
@ -30,15 +31,13 @@
#endif
#endif /** USE_FTGL */
#ifdef USE_CG
#include <Cg/cg.h> /* Can't include this? Is Cg Toolkit installed! */
#include <Cg/cgGL.h>
#endif
#include "Pipeline.hpp"
#include "PerPixelMesh.hpp"
#include "Transformation.hpp"
#include "ShaderEngine.hpp"
class UserTexture;
class BeatDetect;
class TextureManager;
@ -65,9 +64,14 @@ public:
int drawtitle;
int texsize;
#ifdef USE_CG
ShaderEngine shaderEngine;
#endif
PerPixelMesh mesh;
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(PresetOutputs *presetOutputs, PresetInputs *presetInputs);
@ -117,47 +121,7 @@ private:
std::string menu_fontURL;
std::string presetURL;
#ifdef USE_CG
std::string cgTemplate;
std::string blurProgram;
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;
bool blur1_enabled;
bool blur2_enabled;
bool blur3_enabled;
GLuint blur1_tex;
GLuint blur2_tex;
GLuint blur3_tex;
float rand_preset[4];
bool warpShadersEnabled;
bool compositeShadersEnabled;
CGcontext myCgContext;
CGprofile myCgProfile;
CGprogram myCgWarpProgram;
CGprogram myCgCompositeProgram;
CGprogram blur1Program;
CGprogram blur2Program;
bool LoadCgProgram(std::string program, CGprogram &p);
bool checkForCgCompileError(const char *situation);
void checkForCgError(const char *situation);
void SetupCg();
void SetupCgVariables(CGprogram program, const Pipeline &pipeline, const PipelineContext &pipelineContext);
void SetupCgQVariables(CGprogram program, const PresetOutputs &presetOutputs);
void RenderBlurTextures(const Pipeline* pipeline, const PipelineContext &pipelineContext);
#endif
#ifdef USE_FTGL
FTGLPixmapFont *title_font;

View File

@ -8,6 +8,6 @@
#include "Shader.hpp"
Shader::Shader()
: blur1n(1), blur2n(1), blur3n(1),
: enabled(false),blur1n(1), blur2n(1), blur3n(1),
blur1x(1), blur2x(1), blur3x(1),
blur1ed(1){}

View File

@ -9,10 +9,21 @@
#define SHADER_HPP_
#include <string>
#include <set>
#include <vector>
#include "UserTexture.hpp"
class Shader
{
public:
std::vector<UserTexture*> textures;
std::set<std::string> textureNames;
bool enabled;
float blur1n;
float blur2n;
float blur3n;
@ -21,8 +32,7 @@ public:
float blur3x;
float blur1ed;
std::string warp;
std::string composite;
std::string programSource;
Shader();
};

View File

@ -0,0 +1,685 @@
/*
* ShaderEngine.cpp
*
* Created on: Jul 18, 2008
* Author: pete
*/
#include <fstream>
#include "PerlinNoise.hpp"
#include "ShaderEngine.hpp"
ShaderEngine::ShaderEngine()
{
#ifdef USE_CG
SetupCg();
std::cout<<"Generating Noise Textures"<<std::endl;
PerlinNoise noise;
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);
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);
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);
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);
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);
/*
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);
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);
*/
#endif
}
ShaderEngine::~ShaderEngine()
{
// TODO Auto-generated destructor stub
}
#ifdef USE_CG
void ShaderEngine::SetParams(const int texsize, const unsigned int texId, const float aspect, BeatDetect *beatDetect, TextureManager *textureManager )
{
mainTextureId = texId;
this->beatDetect = beatDetect;
this->textureManager = textureManager;
this->aspect = aspect;
this->texsize = texsize;
glGenTextures( 1, &blur1_tex );
glBindTexture(GL_TEXTURE_2D, blur1_tex);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 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 / 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, &blur3_tex );
glBindTexture(GL_TEXTURE_2D, blur3_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);
blur1_enabled = false;
blur2_enabled = false;
blur3_enabled = false;
}
bool ShaderEngine::LoadCgProgram( Shader &shader)
{
//if (p != NULL) cgDestroyProgram(p);
//p = NULL;
std::string program = shader.programSource;
if (program.length() > 0)
{
size_t found = program.rfind('}');
if (found!=std::string::npos)
{
//std::cout << "last '}' found at: " << int(found) << std::endl;
program.replace(int(found),1,"OUT.color.xyz=ret.xyz;\nOUT.color.w=1;\nreturn OUT;\n}");
}
else return false;
found = program.rfind('{');
if (found!=std::string::npos)
{
//std::cout << "first '{' found at: " << int(found) << std::endl;
program.replace(int(found),1,"{\nfloat rad=getrad;\nfloat ang=getang;\n");
}
else return false;
found = program.find("shader_body");
if (found!=std::string::npos)
{
//std::cout << "first 'shader_body' found at: " << int(found) << std::endl;
program.replace(int(found),11,"outtype projectm(float2 uv : TEXCOORD0)\n");
}
else return false;
shader.textures.clear();
shader.textureNames.clear();
found = 0;
found = program.find("sampler_", 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 sampler = program.substr((int)found,(int)end-found);
UserTexture* texture = new UserTexture(sampler);
if (texture->name == "main") texture->texID = mainTextureId;
else if (texture->name == "noise_lq") texture->texID = noise_texture_lq;
else if (texture->name == "noise_mq") texture->texID = noise_texture_mq;
else if (texture->name == "noise_hq") texture->texID = noise_texture_hq;
else if (texture->name == "noise_lq_lite") texture->texID = noise_texture_lq_lite;
else if (texture->name == "noisevol_lq") texture->texID = noise_texture_lq_vol;
else if (texture->name == "noisevol_hq") texture->texID = noise_texture_hq_vol;
else if (texture->name == "noise_perlin") texture->texID = noise_texture_perlin;
else
{
texture->texID = textureManager->getTexture( texture->name + ".jpg");
if (texture->texID == 0) texture->texID = textureManager->getTexture( texture->name + ".dds");
if (texture->texID == 0) texture->texID = textureManager->getTexture( texture->name + ".png");
if (texture->texID == 0) texture->texID = textureManager->getTexture( texture->name + ".tga");
if (texture->texID == 0) texture->texID = textureManager->getTexture( texture->name + ".bmp");
}
if (texture->texID != 0 && shader.textureNames.find(texture->qname)==shader.textureNames.end())
{
shader.textures.push_back(texture);
shader.textureNames.insert(texture->name);
}
else delete(texture);
}
found = program.find("sampler_", found);
}
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);
UserTexture* texture;
std::cout<<"texsize_"<<tex<<" found"<<std::endl;
}
found = program.find("texsize_", found);
}
found = program.find("GetBlur3");
if (found!=std::string::npos)
blur1_enabled = blur2_enabled = blur3_enabled = true;
else
{
found = program.find("GetBlur2");
if (found!=std::string::npos)
blur1_enabled = blur2_enabled = true;
else
{
found = program.find("GetBlur1");
if (found!=std::string::npos)
blur1_enabled = true;
}
}
std::string temp;
temp.append(cgTemplate);
temp.append(program);
std::cout<<"Cg: Compilation Results:"<<std::endl<<std::endl;
std::cout<<program<<std::endl;
CGprogram p = cgCreateProgram(myCgContext,
CG_SOURCE,
temp.c_str(),//temp.c_str(),
myCgProfile,
"projectm",
NULL);
checkForCgCompileError("creating shader program");
if (p==NULL) return false;
cgGLLoadProgram(p);
if (checkForCgCompileError("loading shader program"))
{
p = NULL;
return false;
}
programs[&shader]= p;
return true;
}
else return false;
}
bool ShaderEngine::checkForCgCompileError(const char *situation)
{
CGerror error;
const char *string = cgGetLastErrorString(&error);
error = cgGetError();
if (error != CG_NO_ERROR) {
std::cout<<"Cg: Compilation Error"<<std::endl;
std::cout<<"Cg: %"<<situation<<" - "<<string<<std::endl;
if (error == CG_COMPILER_ERROR) {
std::cout<<"Cg: "<< cgGetLastListing( myCgContext )<<std::endl;
}
return true;
}
return false;
}
void ShaderEngine::checkForCgError(const char *situation)
{
CGerror error;
const char *string = cgGetLastErrorString(&error);
if (error != CG_NO_ERROR) {
std::cout<<"Cg: %"<<situation<<" - "<<string<<std::endl;
if (error == CG_COMPILER_ERROR) {
std::cout<<"Cg: "<< cgGetLastListing( myCgContext )<<std::endl;
}
exit(1);
}
}
void ShaderEngine::SetupCg()
{
std::string line;
std::ifstream myfile (CMAKE_INSTALL_PREFIX "/share/projectM/shaders/projectM.cg");
if (myfile.is_open())
{
while (! myfile.eof() )
{
std::getline (myfile,line);
cgTemplate.append(line + "\n");
}
myfile.close();
}
else std::cout << "Unable to load shader template" << std::endl;
std::ifstream myfile2 (CMAKE_INSTALL_PREFIX "/share/projectM/shaders/blur.cg");
if (myfile2.is_open())
{
while (! myfile2.eof() )
{
std::getline (myfile2,line);
blurProgram.append(line + "\n");
}
myfile2.close();
}
else std::cout << "Unable to load blur template" << std::endl;
myCgContext = cgCreateContext();
checkForCgError("creating context");
cgGLSetDebugMode( CG_FALSE );
cgSetParameterSettingMode(myCgContext, CG_DEFERRED_PARAMETER_SETTING);
myCgProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(myCgProfile);
checkForCgError("selecting fragment profile");
profileName = cgGetProfileString(myCgProfile);
std::cout<<"Cg: Initialized profile: "<<profileName<<std::endl;
blur1Program = cgCreateProgram(myCgContext,
CG_SOURCE,
blurProgram.c_str(),
myCgProfile,
"blur1",
NULL);
checkForCgCompileError("creating blur1 program");
if (blur1Program==NULL) exit(1);
cgGLLoadProgram(blur1Program);
checkForCgError("loading blur1 program");
blur2Program = cgCreateProgram(myCgContext,
CG_SOURCE,
blurProgram.c_str(),
myCgProfile,
"blur2",
NULL);
checkForCgCompileError("creating blur2 program");
if (blur2Program==NULL) exit(1);
cgGLLoadProgram(blur2Program);
checkForCgError("loading blur2 program");
}
void ShaderEngine::SetupCgVariables(CGprogram program, const Pipeline &pipeline, const PipelineContext &context)
{
float slow_roam_cos[4] = { 0.5 + 0.5*cos(context.time * 0.005),0.5 + 0.5*cos(context.time * 0.008),0.5 + 0.5*cos(context.time * 0.013),0.5 + 0.5*cos(context.time * 0.022)};
float roam_cos[4] ={ 0.5 + 0.5*cos(context.time * 0.3),0.5 + 0.5*cos(context.time * 1.3),0.5 + 0.5*cos(context.time * 5),0.5 + 0.5*cos(context.time * 20)};
float slow_roam_sin[4] = { 0.5 + 0.5*sin(context.time * 0.005),0.5 + 0.5*sin(context.time * 0.008),0.5 + 0.5*sin(context.time * 0.013),0.5 + 0.5*sin(context.time * 0.022)};
float roam_sin[4] ={ 0.5 + 0.5*sin(context.time * 0.3),0.5 + 0.5*sin(context.time * 1.3),0.5 + 0.5*sin(context.time * 5),0.5 + 0.5*sin(context.time * 20)};
cgGLSetParameter4fv(cgGetNamedParameter(program, "slow_roam_cos"), slow_roam_cos);
cgGLSetParameter4fv(cgGetNamedParameter(program, "roam_cos"), roam_cos);
cgGLSetParameter4fv(cgGetNamedParameter(program, "slow_roam_sin"), slow_roam_sin);
cgGLSetParameter4fv(cgGetNamedParameter(program, "roam_sin"), roam_sin);
cgGLSetParameter1f(cgGetNamedParameter(program, "time"), context.time);
cgGLSetParameter4f(cgGetNamedParameter(program, "rand_preset"), rand_preset[0], rand_preset[1],rand_preset[2],rand_preset[3]);
cgGLSetParameter4f(cgGetNamedParameter(program, "rand_frame"), (rand()%100) * .01,(rand()%100) * .01,(rand()%100) * .01,(rand()%100) * .01);
cgGLSetParameter1f(cgGetNamedParameter(program, "fps"), context.fps);
cgGLSetParameter1f(cgGetNamedParameter(program, "frame"), context.frame);
cgGLSetParameter1f(cgGetNamedParameter(program, "progress"), context.progress);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur1_min"), pipeline.warpShader.blur1n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur1_max"), pipeline.warpShader.blur1x);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur2_min"), pipeline.warpShader.blur2n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur2_max"), pipeline.warpShader.blur2x);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur3_min"), pipeline.warpShader.blur3n);
cgGLSetParameter1f(cgGetNamedParameter(program, "blur3_max"), pipeline.warpShader.blur3x);
cgGLSetParameter1f(cgGetNamedParameter(program, "bass"), beatDetect->bass);
cgGLSetParameter1f(cgGetNamedParameter(program, "mid"), beatDetect->mid);
cgGLSetParameter1f(cgGetNamedParameter(program, "treb"), beatDetect->treb);
cgGLSetParameter1f(cgGetNamedParameter(program, "bass_att"), beatDetect->bass_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "mid_att"), beatDetect->mid_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "treb_att"), beatDetect->treb_att);
cgGLSetParameter1f(cgGetNamedParameter(program, "vol"), beatDetect->vol);
cgGLSetParameter1f(cgGetNamedParameter(program, "vol_att"), beatDetect->vol);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize"), texsize, texsize, 1/(float)texsize,1/(float)texsize);
cgGLSetParameter4f(cgGetNamedParameter(program, "aspect"), 1/aspect,1,aspect,1);
//glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[1]);
/*
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_main"),renderTarget->textureID[1]);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_main"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq_lite"),noise_texture_lq_lite);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq_lite"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_mq"),noise_texture_mq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_mq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_hq"),noise_texture_hq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_hq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq"),noise_texture_lq);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_lq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noise_perlin"),noise_texture_perlin);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noise_perlin"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_hq"),noise_texture_hq_vol);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_hq"));
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_lq"),noise_texture_lq_vol);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_noisevol_lq"));
*/
if (blur1_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur1"),blur1_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur1"));
}
if (blur2_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur2"),blur2_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur2"));
}
if (blur3_enabled)
{
cgGLSetTextureParameter(cgGetNamedParameter(program, "sampler_blur3"),blur3_tex);
cgGLEnableTextureParameter(cgGetNamedParameter(program, "sampler_blur3"));
}
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_lq"), 256, 256,1.0/(float)256,1.0/(float)256);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_mq"), 64, 64,1.0/(float)64,1.0/(float)64);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_hq"), 32, 32,1.0/(float)32,1.0/(float)32);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_perlin"), 512, 512,1.0/(float)512,1.0/(float)512);
cgGLSetParameter4f(cgGetNamedParameter(program, "texsize_noise_lq_lite"), 32, 32,1.0/(float)32,1.0/(float)32);
}
void ShaderEngine::SetupUserTexture(CGprogram 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);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture->wrap ? GL_REPEAT : GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture->wrap ? GL_REPEAT : GL_CLAMP);
std::string samplerName = "sampler_" + texture->qname;
//std::cout<<"Setting up "<<samplerName<<std::endl;
CGparameter param = cgGetNamedParameter(program, samplerName.c_str());
checkForCgError("getting parameter");
cgGLSetTextureParameter(param,texture->texID);
checkForCgError("setting parameter");
cgGLEnableTextureParameter(param);
checkForCgError("enabling parameter");
//std::cout<<texture->texID<<" "<<texture->qname<<std::endl;
if (texture->texsizeDefined)
{
std::string texsizeName = "texsize_" + texture->name;
cgGLSetParameter4f(cgGetNamedParameter(program, texsizeName.c_str() ), texture->width, texture->height, 1/(float)texture->width,1/(float)texture->height);
}
}
void ShaderEngine::SetupCgQVariables(Shader &shader, const PresetOutputs &q)
{
CGprogram program = programs[&shader];
if (shader.enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(program, "_qa"), q.q1, q.q2, q.q3, q.q4);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qb"), q.q5, q.q6, q.q7, q.q8);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qc"), q.q9, q.q10, q.q11, q.q12);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qd"), q.q13, q.q14, q.q15, q.q16);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qe"), q.q17, q.q18, q.q19, q.q20);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qf"), q.q21, q.q22, q.q23, q.q24);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qg"), q.q25, q.q26, q.q27, q.q28);
cgGLSetParameter4f(cgGetNamedParameter(program, "_qh"), q.q29, q.q30, q.q31, q.q32);
}
}
void ShaderEngine::RenderBlurTextures(const Pipeline *pipeline, const PipelineContext &pipelineContext, const int texsize)
{
if(blur1_enabled || blur2_enabled || blur3_enabled)
{
float tex[4][2] = {{0, 1},
{0, 0},
{1, 0},
{1, 1}};
glBlendFunc(GL_ONE, GL_ZERO);
glColor4f(1.0, 1.0, 1.0, 1.0f);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,tex);
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling profile");
if (blur1_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur1Program, "srctexsize"), texsize, texsize, 1/(float)texsize,1/(float)texsize);
cgGLBindProgram(blur1Program);
checkForCgError("binding blur1 program");
float points[4][2] = {{0, 1},
{0, 0},
{1, 0},
{1, 1}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur1_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,texsize, texsize);
cgGLUnbindProgram(myCgProfile);
checkForCgError("unbinding blur1 program");
}
if (blur2_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur2Program, "srctexsize"), texsize, texsize, 1/(float)texsize,1/(float)texsize);
cgGLBindProgram(blur2Program);
checkForCgError("binding blur2 program");
float points[4][2] = {{0, 0.5},
{0, 0},
{0.5, 0},
{0.5, 0.5}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur2_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,texsize/2, texsize/2);
}
if (blur3_enabled)
{
cgGLSetParameter4f(cgGetNamedParameter(blur2Program, "srctexsize"), texsize/2, texsize/2, 2/(float)texsize,2/(float)texsize);
float points[4][2] = {{0, 0.25},
{0, 0},
{0.25, 0},
{0.25, 0.25}};
glVertexPointer(2,GL_FLOAT,0,points);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindTexture(GL_TEXTURE_2D, blur3_tex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,texsize/4, texsize/4);
}
if (blur2_enabled || blur3_enabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("unbinding blur2 program");
}
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling blur profile");
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
void ShaderEngine::loadShader(Shader &shader)
{
if (shader.enabled)
{
cgDestroyProgram(programs[&shader]);
programs.erase(&shader);
}
shader.enabled = LoadCgProgram(shader);
//shader.programSource.clear();
}
void ShaderEngine::disableShader()
{
if (enabled)
{
cgGLUnbindProgram(myCgProfile);
checkForCgError("disabling fragment profile");
cgGLDisableProfile(myCgProfile);
checkForCgError("disabling fragment profile");
}
enabled = false;
}
void ShaderEngine::enableShader(Shader &shader, const Pipeline *pipeline, const PipelineContext *pipelineContext)
{
enabled = false;
if (shader.enabled)
{
CGprogram program = programs[&shader];
cgGLEnableProfile(myCgProfile);
checkForCgError("enabling warp profile");
cgGLBindProgram(program);
checkForCgError("binding warp program");
SetupCgVariables(program, *pipeline, *pipelineContext);
for (std::vector<UserTexture*>::const_iterator pos = shader.textures.begin(); pos != shader.textures.end(); ++pos)
SetupUserTexture(program, *pos);
enabled = true;
}
}
void ShaderEngine::reset()
{
rand_preset[0] = (rand()%100) * .01;
rand_preset[1] = (rand()%100) * .01;
rand_preset[2] = (rand()%100) * .01;
rand_preset[3] = (rand()%100) * .01;
//if(warpShadersEnabled) cgDestroyProgram(myCgWarpProgram);
//if(compositeShadersEnabled) cgDestroyProgram(myCgCompositeProgram);
}
#endif

View File

@ -0,0 +1,110 @@
/*
* ShaderEngine.hpp
*
* Created on: Jul 18, 2008
* Author: pete
*/
#ifndef SHADERENGINE_HPP_
#define SHADERENGINE_HPP_
#ifdef USE_GLES1
#include <GLES/gl.h>
#else
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#endif
#ifdef USE_CG
#include <Cg/cg.h> /* Can't include this? Is Cg Toolkit installed! */
#include <Cg/cgGL.h>
#endif
#include "Pipeline.hpp"
#include "PipelineContext.hpp"
#include "BeatDetect.hpp"
#include "TextureManager.hpp"
#include <stdlib.h>
#include <iostream>
#include <map>
#include "Shader.hpp"
#include "PresetFrameIO.hpp"
class ShaderEngine
{
#ifdef USE_CG
unsigned int mainTextureId;
int texsize;
float aspect;
BeatDetect *beatDetect;
TextureManager *textureManager;
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;
bool blur1_enabled;
bool blur2_enabled;
bool blur3_enabled;
GLuint blur1_tex;
GLuint blur2_tex;
GLuint blur3_tex;
float rand_preset[4];
CGcontext myCgContext;
CGprofile myCgProfile;
CGprogram blur1Program;
CGprogram blur2Program;
bool enabled;
std::map<Shader*,CGprogram> programs;
std::string cgTemplate;
std::string blurProgram;
bool LoadCgProgram(Shader &shader);
bool checkForCgCompileError(const char *situation);
void checkForCgError(const char *situation);
void SetupCg();
void SetupCgVariables(CGprogram program, const Pipeline &pipeline, const PipelineContext &pipelineContext);
void SetupUserTexture(CGprogram program, const UserTexture* texture);
#endif
public:
ShaderEngine();
virtual ~ShaderEngine();
void SetupCgQVariables(Shader &shader, const PresetOutputs &presetOutputs);
void RenderBlurTextures(const Pipeline* pipeline, const PipelineContext &pipelineContext, const int texsize);
void loadShader(Shader &shader);
void SetParams(const int texsize, const unsigned int texId, const float aspect, BeatDetect *beatDetect, TextureManager *textureManager);
void enableShader(Shader &shader, const Pipeline *pipeline, const PipelineContext *pipelineContext);
void disableShader();
void reset();
std::string profileName;
};
#endif /* SHADERENGINE_HPP_ */

View File

@ -155,9 +155,9 @@ GLuint TextureManager::getTexture(const std::string imageURL)
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_POWER_OF_TWO
//SOIL_FLAG_POWER_OF_TWO
// SOIL_FLAG_MIPMAPS
| SOIL_FLAG_MULTIPLY_ALPHA
SOIL_FLAG_MULTIPLY_ALPHA
| SOIL_FLAG_COMPRESS_TO_DXT
//| SOIL_FLAG_DDS_LOAD_DIRECT
);

View File

@ -48,6 +48,10 @@
#define uv_orig uv
uniform sampler2D sampler_main;
uniform sampler2D sampler_fw_main;
uniform sampler2D sampler_pw_main;
uniform sampler2D sampler_fc_main;
uniform sampler2D sampler_pc_main;
uniform sampler2D sampler_noise_lq;
uniform sampler2D sampler_noise_lq_lite;
@ -109,10 +113,6 @@ float vol_att;
float4 texsize;
float4 aspect;
#define sampler_pw_main sampler_main
#define sampler_pc_main sampler_main
#define sampler_fw_main sampler_main
#define sampler_fc_main sampler_main
struct outtype {float4 color : COLOR;};
outtype OUT;

View File

@ -461,7 +461,7 @@ void projectM::projectM_init ( int gx, int gy, int fps, int texsize, int width,
this->presetInputs2.gy = gy;
this->renderer = new Renderer ( width, height, gx, gy, texsize, beatDetect, settings().presetURL, settings().titleFontURL, settings().menuFontURL );
renderer->SetPipeline(presetOutputs);
running = true;
#ifdef USE_THREADS