mirror of https://github.com/snes9xgit/snes9x.git
Win32: add PREV support to cg meta shaders, clean up code
This commit is contained in:
parent
7dd4f944ee
commit
85cc112b44
|
@ -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
|
||||||
|
|
172
win32/CGLCG.cpp
172
win32/CGLCG.cpp
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue