Win32: add PREV support to cg meta shaders, clean up code

This commit is contained in:
OV2 2011-07-03 23:12:41 +02:00
parent 7dd4f944ee
commit 85cc112b44
4 changed files with 171 additions and 52 deletions

View File

@ -36,8 +36,10 @@ public:
~CCGShader(void); ~CCGShader(void);
bool LoadShader(const char *path); bool LoadShader(const char *path);
std::vector<shaderPass> shaderPasses; typedef std::vector<shaderPass> passVector;
std::vector<lookupTexture> lookupTextures; typedef std::vector<lookupTexture> lutVector;
passVector shaderPasses;
lutVector lookupTextures;
}; };
#endif #endif

View File

@ -24,16 +24,21 @@ CGLCG::CGLCG(CGcontext cgContext)
ClearPasses(); ClearPasses();
LoadFBOFunctions(); LoadFBOFunctions();
frameCnt=0; frameCnt=0;
prevTex=0;
} }
CGLCG::~CGLCG(void) CGLCG::~CGLCG(void)
{ {
LoadShader(NULL);
} }
void CGLCG::ClearPasses() void CGLCG::ClearPasses()
{ {
/* clean up cg programs, fbos and textures from all regular passes
pass 0 is the orignal texture, so ignore that
*/
if(shaderPasses.size()>1) { if(shaderPasses.size()>1) {
for(std::vector<shaderPass>::iterator it=(shaderPasses.begin()+1);it!=shaderPasses.end();it++) { for(glPassVector::iterator it=(shaderPasses.begin()+1);it!=shaderPasses.end();it++) {
if(it->cgFragmentProgram) if(it->cgFragmentProgram)
cgDestroyProgram(it->cgFragmentProgram); cgDestroyProgram(it->cgFragmentProgram);
if(it->cgVertexProgram) if(it->cgVertexProgram)
@ -44,12 +49,13 @@ void CGLCG::ClearPasses()
glDeleteTextures(1,&it->tex); glDeleteTextures(1,&it->tex);
} }
} }
for(std::vector<lookupTexture>::iterator it=lookupTextures.begin();it!=lookupTextures.end();it++) { for(glLutVector::iterator it=lookupTextures.begin();it!=lookupTextures.end();it++) {
if(it->tex) if(it->tex)
glDeleteTextures(1,&it->tex); glDeleteTextures(1,&it->tex);
} }
shaderPasses.clear(); shaderPasses.clear();
lookupTextures.clear(); lookupTextures.clear();
shaderLoaded = false; shaderLoaded = false;
} }
@ -120,6 +126,11 @@ bool CGLCG::LoadShader(const TCHAR *shaderFile)
ClearPasses(); ClearPasses();
if(prevTex) {
glDeleteTextures(1,&prevTex);
prevTex=0;
}
if (shaderFile == NULL || *shaderFile==TEXT('\0')) if (shaderFile == NULL || *shaderFile==TEXT('\0'))
return true; return true;
@ -138,13 +149,25 @@ bool CGLCG::LoadShader(const TCHAR *shaderFile)
cgGLSetOptimalOptions(vertexProfile); cgGLSetOptimalOptions(vertexProfile);
cgGLSetOptimalOptions(fragmentProfile); cgGLSetOptimalOptions(fragmentProfile);
/* insert dummy pass that will contain the original texture
*/
shaderPasses.push_back(shaderPass()); shaderPasses.push_back(shaderPass());
for(std::vector<CCGShader::shaderPass>::iterator it=cgShader.shaderPasses.begin();it!=cgShader.shaderPasses.end();it++) { for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin();
shaderPasses.push_back(shaderPass()); it!=cgShader.shaderPasses.end();it++) {
shaderPass &pass = shaderPasses.back(); shaderPass pass;
pass.scaleParams = it->scaleParams; pass.scaleParams = it->scaleParams;
pass.linearFilter = (pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet)?GUI.BilinearFilter:it->linearFilter; /* if this is the last pass (the only one that can have CG_SCALE_NONE)
and no filter has been set use the GUI setting
*/
if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) {
pass.linearFilter = GUI.BilinearFilter;
} else {
pass.linearFilter = it->linearFilter;
}
// paths in the meta file can be relative
_tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH);
char *fileContents = ReadShaderFileContents(tempPath); char *fileContents = ReadShaderFileContents(tempPath);
if(!fileContents) if(!fileContents)
@ -167,6 +190,9 @@ bool CGLCG::LoadShader(const TCHAR *shaderFile)
cgGLLoadProgram(pass.cgVertexProgram); cgGLLoadProgram(pass.cgVertexProgram);
cgGLLoadProgram(pass.cgFragmentProgram); cgGLLoadProgram(pass.cgFragmentProgram);
/* generate framebuffer and texture for this pass and apply
default texture settings
*/
glGenFramebuffers(1,&pass.fbo); glGenFramebuffers(1,&pass.fbo);
glGenTextures(1,&pass.tex); glGenTextures(1,&pass.tex);
glBindTexture(GL_TEXTURE_2D,pass.tex); glBindTexture(GL_TEXTURE_2D,pass.tex);
@ -174,19 +200,26 @@ bool CGLCG::LoadShader(const TCHAR *shaderFile)
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
shaderPasses.push_back(pass);
} }
for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) {
lookupTextures.push_back(lookupTexture()); lookupTexture tex;
lookupTexture &tex = lookupTextures.back();
strcpy(tex.id,it->id); strcpy(tex.id,it->id);
/* generate texture for the lut and apply specified filter setting
*/
glGenTextures(1,&tex.tex); glGenTextures(1,&tex.tex);
glBindTexture(GL_TEXTURE_2D,tex.tex); glBindTexture(GL_TEXTURE_2D,tex.tex);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST);
_tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH);
// simple file extension png/tga decision
int strLen = strlen(it->texturePath); int strLen = strlen(it->texturePath);
if(strLen>4) { if(strLen>4) {
if(!strcasecmp(&it->texturePath[strLen-4],".png")) { if(!strcasecmp(&it->texturePath[strLen-4],".png")) {
@ -207,15 +240,27 @@ bool CGLCG::LoadShader(const TCHAR *shaderFile)
stga.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, stga.data); stga.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, stga.data);
} }
} }
} }
lookupTextures.push_back(tex);
} }
/* enable texture unit 1 for the lookup textures
*/
glClientActiveTexture(GL_TEXTURE1); glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,lut_coords); glTexCoordPointer(2,GL_FLOAT,0,lut_coords);
glClientActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0);
/* generate a texture that we can swap with the original texture
and pass back to the main opengl code
*/
glGenTextures(1,&prevTex);
glBindTexture(GL_TEXTURE_2D,prevTex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,512,512,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL);
glBindTexture(GL_TEXTURE_2D,0);
prevTexSize.x = prevTexSize.y = prevTexImageSize.x = prevTexImageSize.y = 0;
memset(prevTexCoords,0,sizeof(prevTexCoords));
shaderLoaded = true; shaderLoaded = true;
return true; return true;
@ -226,6 +271,7 @@ void CGLCG::setTexCoords(int pass,xySize inputSize,xySize textureSize,bool topdo
float tX = inputSize.x / textureSize.x; float tX = inputSize.x / textureSize.x;
float tY = inputSize.y / textureSize.y; float tY = inputSize.y / textureSize.y;
// last pass uses top-down coordinates, all others bottom-up
if(topdown) { if(topdown) {
shaderPasses[pass].texcoords[0] = 0.0f; shaderPasses[pass].texcoords[0] = 0.0f;
shaderPasses[pass].texcoords[1] = tY; shaderPasses[pass].texcoords[1] = tY;
@ -249,7 +295,7 @@ void CGLCG::setTexCoords(int pass,xySize inputSize,xySize textureSize,bool topdo
glTexCoordPointer(2, GL_FLOAT, 0, shaderPasses[pass].texcoords); glTexCoordPointer(2, GL_FLOAT, 0, shaderPasses[pass].texcoords);
} }
void CGLCG::Render(GLuint origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize) void CGLCG::Render(GLuint &origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize)
{ {
GLenum error; GLenum error;
frameCnt++; frameCnt++;
@ -264,10 +310,14 @@ void CGLCG::Render(GLuint origTex, xySize textureSize, xySize inputSize, xySize
cgGLEnableProfile(vertexProfile); cgGLEnableProfile(vertexProfile);
cgGLEnableProfile(fragmentProfile); cgGLEnableProfile(fragmentProfile);
/* set up our dummy pass for easier loop code
*/
shaderPasses[0].tex = origTex; shaderPasses[0].tex = origTex;
shaderPasses[0].outputSize = inputSize; shaderPasses[0].outputSize = inputSize;
shaderPasses[0].textureSize = textureSize; shaderPasses[0].textureSize = textureSize;
/* loop through all real passes
*/
for(int i=1;i<shaderPasses.size();i++) { for(int i=1;i<shaderPasses.size();i++) {
switch(shaderPasses[i].scaleParams.scaleTypeX) { switch(shaderPasses[i].scaleParams.scaleTypeX) {
case CG_SCALE_ABSOLUTE: case CG_SCALE_ABSOLUTE:
@ -295,46 +345,90 @@ void CGLCG::Render(GLuint origTex, xySize textureSize, xySize inputSize, xySize
default: default:
shaderPasses[i].outputSize.y = viewportSize.y; shaderPasses[i].outputSize.y = viewportSize.y;
} }
/* use next power of two in both directions
*/
float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y)); float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y));
shaderPasses[i].textureSize.x = shaderPasses[i].textureSize.y = texSize; shaderPasses[i].textureSize.x = shaderPasses[i].textureSize.y = texSize;
/* set size of output texture
*/
glBindTexture(GL_TEXTURE_2D,shaderPasses[i].tex); glBindTexture(GL_TEXTURE_2D,shaderPasses[i].tex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,(unsigned int)shaderPasses[i].textureSize.x,(unsigned int)shaderPasses[i].textureSize.y,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,NULL); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,(unsigned int)shaderPasses[i].textureSize.x,
(unsigned int)shaderPasses[i].textureSize.y,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,NULL);
/* viewport determines the area we render into the output texture
*/
glViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y); glViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y);
/* set up framebuffer and attach output texture
*/
glBindFramebuffer(GL_FRAMEBUFFER,shaderPasses[i].fbo); glBindFramebuffer(GL_FRAMEBUFFER,shaderPasses[i].fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shaderPasses[i].tex, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shaderPasses[i].tex, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
/* set up input texture (output of previous pass) and apply filter settings
*/
glBindTexture(GL_TEXTURE_2D,shaderPasses[i-1].tex); glBindTexture(GL_TEXTURE_2D,shaderPasses[i-1].tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses[i-1].textureSize.x); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses[i-1].textureSize.x);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST);
/* calculate tex coords first since we pass them to the shader
*/
setTexCoords(i,shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize); setTexCoords(i,shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize);
setShaderVars(i); setShaderVars(i);
cgGLBindProgram(shaderPasses[i].cgVertexProgram); cgGLBindProgram(shaderPasses[i].cgVertexProgram);
cgGLBindProgram(shaderPasses[i].cgFragmentProgram); cgGLBindProgram(shaderPasses[i].cgFragmentProgram);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays (GL_QUADS, 0, 4); glDrawArrays (GL_QUADS, 0, 4);
} }
/* disable framebuffer
*/
glBindFramebuffer(GL_FRAMEBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,0);
/* switch original and prev texture and make sure the
new original texture has the same size as the old one
*/
origTex = prevTex;
prevTex = shaderPasses[0].tex;
prevTexSize.x = textureSize.x;
prevTexSize.y = textureSize.y;
prevTexImageSize.x = inputSize.x;
prevTexImageSize.y = inputSize.y;
memcpy(prevTexCoords,shaderPasses[1].texcoords,sizeof(prevTexCoords));
glBindTexture(GL_TEXTURE_2D,origTex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureSize.x,textureSize.y,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL);
/* bind output of last pass to be rendered on the backbuffer
*/
glBindTexture(GL_TEXTURE_2D,shaderPasses.back().tex); glBindTexture(GL_TEXTURE_2D,shaderPasses.back().tex);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses.back().textureSize.x); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses.back().textureSize.x);
/* calculate and apply viewport and texture coordinates to
that will be used in the main ogl code
*/
RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y); RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y);
glViewport(displayRect.left,windowSize.y-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top); glViewport(displayRect.left,windowSize.y-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top);
setTexCoords(shaderPasses.size()-1,shaderPasses.back().outputSize,shaderPasses.back().textureSize,true); setTexCoords(shaderPasses.size()-1,shaderPasses.back().outputSize,shaderPasses.back().textureSize,true);
/* render to backbuffer without shaders
*/
cgGLDisableProfile(vertexProfile); cgGLDisableProfile(vertexProfile);
cgGLDisableProfile(fragmentProfile); cgGLDisableProfile(fragmentProfile);
} }
void CGLCG::setShaderVars(int pass) void CGLCG::setShaderVars(int pass)
{ {
float inputSize[2] = {shaderPasses[pass-1].outputSize.x,shaderPasses[pass-1].outputSize.y}; /* mvp paramater
float textureSize[2] = {shaderPasses[pass-1].textureSize.x,shaderPasses[pass-1].textureSize.y}; */
float outputSize[2] = {shaderPasses[pass].outputSize.x,shaderPasses[pass].outputSize.y};
CGparameter cgpModelViewProj = cgGetNamedParameter(shaderPasses[pass].cgVertexProgram, "modelViewProj"); CGparameter cgpModelViewProj = cgGetNamedParameter(shaderPasses[pass].cgVertexProgram, "modelViewProj");
cgGLSetStateMatrixParameter(cgpModelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); cgGLSetStateMatrixParameter(cgpModelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
#define setProgram2fv(pass,varname,floats)\ #define setProgram2fv(pass,varname,floats)\
@ -375,34 +469,54 @@ void CGLCG::setShaderVars(int pass)
}\ }\
}\ }\
/* IN paramater
*/
float inputSize[2] = {shaderPasses[pass-1].outputSize.x,shaderPasses[pass-1].outputSize.y};
float textureSize[2] = {shaderPasses[pass-1].textureSize.x,shaderPasses[pass-1].textureSize.y};
float outputSize[2] = {shaderPasses[pass].outputSize.x,shaderPasses[pass].outputSize.y};
setProgram2fv(pass,"IN.video_size",inputSize); setProgram2fv(pass,"IN.video_size",inputSize);
setProgram2fv(pass,"IN.texture_size",textureSize); setProgram2fv(pass,"IN.texture_size",textureSize);
setProgram2fv(pass,"IN.output_size",outputSize); setProgram2fv(pass,"IN.output_size",outputSize);
setProgram1f(pass,"IN.frame_count",(float)frameCnt); setProgram1f(pass,"IN.frame_count",(float)frameCnt);
float video_Size[2] = {shaderPasses[0].outputSize.x,shaderPasses[0].outputSize.y}; /* ORIG parameter
float texture_Size[2] = {shaderPasses[0].textureSize.x,shaderPasses[0].textureSize.y}; */
float orig_videoSize[2] = {shaderPasses[0].outputSize.x,shaderPasses[0].outputSize.y};
float orig_textureSize[2] = {shaderPasses[0].textureSize.x,shaderPasses[0].textureSize.y};
setProgram2fv(pass,"ORIG.video_size",orig_videoSize);
setProgram2fv(pass,"ORIG.video_size",video_Size); setProgram2fv(pass,"ORIG.texture_size",orig_textureSize);
setProgram2fv(pass,"ORIG.texture_size",texture_Size);
setTextureParameter(pass,"ORIG.texture",shaderPasses[0].tex); setTextureParameter(pass,"ORIG.texture",shaderPasses[0].tex);
setTexCoordsParameter(pass,"ORIG.tex_coord",shaderPasses[1].texcoords); setTexCoordsParameter(pass,"ORIG.tex_coord",shaderPasses[1].texcoords);
/* PREV parameter
*/
float prev_videoSize[2] = {prevTexImageSize.x,prevTexImageSize.y};
float prev_textureSize[2] = {prevTexSize.x,prevTexSize.y};
setProgram2fv(pass,"PREV.video_size",prev_videoSize);
setProgram2fv(pass,"PREV.texture_size",prev_textureSize);
setTextureParameter(pass,"PREV.texture",prevTex);
setTexCoordsParameter(pass,"PREV.tex_coord",prevTexCoords);
/* LUT parameters
*/
for(int i=0;i<lookupTextures.size();i++) { for(int i=0;i<lookupTextures.size();i++) {
setTextureParameter(pass,lookupTextures[i].id,lookupTextures[i].tex); setTextureParameter(pass,lookupTextures[i].id,lookupTextures[i].tex);
} }
if(pass>1) { /* PASSX parameters, only for third pass and up
*/
if(pass>2) {
for(int i=1;i<pass-1;i++) { for(int i=1;i<pass-1;i++) {
char varname[100]; char varname[100];
float video_Size[2] = {shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y}; float pass_videoSize[2] = {shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y};
float texture_Size[2] = {shaderPasses[i].textureSize.x,shaderPasses[i].textureSize.y}; float pass_textureSize[2] = {shaderPasses[i].textureSize.x,shaderPasses[i].textureSize.y};
sprintf(varname,"PASS%d.video_size",i); sprintf(varname,"PASS%d.video_size",i);
setProgram2fv(pass,varname,video_Size); setProgram2fv(pass,varname,pass_videoSize);
sprintf(varname,"PASS%d.texture_size",i); sprintf(varname,"PASS%d.texture_size",i);
setProgram2fv(pass,varname,texture_Size); setProgram2fv(pass,varname,pass_textureSize);
sprintf(varname,"PASS%d.texture",i); sprintf(varname,"PASS%d.texture",i);
setTextureParameter(pass,varname,shaderPasses[i].tex); setTextureParameter(pass,varname,shaderPasses[i].tex);
sprintf(varname,"PASS%d.tex_coord",i); sprintf(varname,"PASS%d.tex_coord",i);

View File

@ -51,8 +51,10 @@ private:
_lookupTexture() {tex=NULL;} _lookupTexture() {tex=NULL;}
} lookupTexture; } lookupTexture;
std::vector<shaderPass> shaderPasses; typedef std::vector<shaderPass> glPassVector;
std::vector<lookupTexture> lookupTextures; typedef std::vector<lookupTexture> glLutVector;
glPassVector shaderPasses;
glLutVector lookupTextures;
bool fboFunctionsLoaded; bool fboFunctionsLoaded;
bool shaderLoaded; bool shaderLoaded;
@ -66,6 +68,10 @@ private:
CGcontext cgContext; CGcontext cgContext;
int frameCnt; int frameCnt;
static const GLfloat lut_coords[8]; static const GLfloat lut_coords[8];
GLuint prevTex;
xySize prevTexSize;
xySize prevTexImageSize;
GLfloat prevTexCoords[8];
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
@ -80,7 +86,7 @@ public:
~CGLCG(void); ~CGLCG(void);
bool LoadShader(const TCHAR *shaderFile); bool LoadShader(const TCHAR *shaderFile);
void Render(GLuint origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize); void Render(GLuint &origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize);
void ClearPasses(); void ClearPasses();
}; };

View File

@ -289,8 +289,7 @@ bool COpenGL::Initialize(HWND hWnd)
cgShader = new CGLCG(cgContext); cgShader = new CGLCG(cgContext);
} }
GetClientRect(hWnd,&windowRect); ApplyDisplayChanges();
ChangeRenderSize(windowRect.right,windowRect.bottom);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -322,13 +321,13 @@ void COpenGL::DeInitialize()
afterRenderHeight = 0; afterRenderHeight = 0;
shaderFunctionsLoaded = false; shaderFunctionsLoaded = false;
shader_type = OGL_SHADER_NONE; shader_type = OGL_SHADER_NONE;
if(cgAvailable)
unloadCgLibrary();
cgAvailable = false;
if(cgShader) { if(cgShader) {
delete cgShader; delete cgShader;
cgShader = NULL; cgShader = NULL;
} }
if(cgAvailable)
unloadCgLibrary();
cgAvailable = false;
} }
void COpenGL::CreateDrawSurface() void COpenGL::CreateDrawSurface()
@ -350,6 +349,7 @@ void COpenGL::CreateDrawSurface()
glGenBuffers(1,&drawBuffer); glGenBuffers(1,&drawBuffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,drawBuffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER,drawBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER,quadTextureSize*quadTextureSize*2,NULL,GL_STREAM_DRAW); glBufferData(GL_PIXEL_UNPACK_BUFFER,quadTextureSize*quadTextureSize*2,NULL,GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,0);
} else { } else {
noPboBuffer = new BYTE[quadTextureSize*quadTextureSize*2]; noPboBuffer = new BYTE[quadTextureSize*quadTextureSize*2];
} }
@ -357,7 +357,6 @@ void COpenGL::CreateDrawSurface()
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
} }
ApplyDisplayChanges();
} }
void COpenGL::DestroyDrawSurface() void COpenGL::DestroyDrawSurface()
@ -450,13 +449,7 @@ void COpenGL::Render(SSurface Src)
afterRenderHeight = dstRect.bottom; afterRenderHeight = dstRect.bottom;
afterRenderWidth = dstRect.right; afterRenderWidth = dstRect.right;
/* disable UNPACK_BUFFER, since ApplyDisplayChanges can lead to texture ChangeRenderSize(0,0);
calls in the cg shader class which are not allowed */
if(pboFunctionsLoaded)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
ApplyDisplayChanges();
if(pboFunctionsLoaded)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer);
} }
glBindTexture(GL_TEXTURE_2D,drawTexture); glBindTexture(GL_TEXTURE_2D,drawTexture);
@ -518,7 +511,13 @@ void COpenGL::Render(SSurface Src)
bool COpenGL::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight) bool COpenGL::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight)
{ {
RECT displayRect=CalculateDisplayRect(afterRenderWidth,afterRenderHeight,newWidth,newHeight); RECT displayRect, windowSize;
if(newWidth==0||newHeight==0) {
GetClientRect(hWnd,&windowSize);
newWidth = windowSize.right;
newHeight = windowSize.bottom;
}
displayRect=CalculateDisplayRect(afterRenderWidth,afterRenderHeight,newWidth,newHeight);
glViewport(displayRect.left,newHeight-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top); glViewport(displayRect.left,newHeight-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top);
SetupVertices(); SetupVertices();
return true; return true;
@ -534,9 +533,7 @@ bool COpenGL::ApplyDisplayChanges(void)
else else
SetShaders(NULL); SetShaders(NULL);
RECT windowSize; ChangeRenderSize(0,0);
GetClientRect(hWnd,&windowSize);
ChangeRenderSize(windowSize.right,windowSize.bottom);
return true; return true;
} }