Patch 17909: 2D Filter texture coordinates changes, by Dalai Felinto:

* The second opengl texture coordinate (gl_TexCoord[1]) are now filled
  in as well, and will give canvas coordinates from 0.0 to 1.0. The
  first texture coordinates still give the coordinates in the texture
  that is being used, which may not match the canvas exactly, so both
  coordinates are needed.
* Also optimization to allow using smaller texture sizes with multiple
  smaller viewports.
* Print the detailed GLSL shader errors (once), for easier debugging.
This commit is contained in:
Brecht Van Lommel 2008-11-01 14:00:16 +00:00
parent 54401d36aa
commit 00b02f055a
2 changed files with 110 additions and 71 deletions

@ -78,6 +78,7 @@ numberoffilters(0)
m_gameObjects[passindex] = NULL; m_gameObjects[passindex] = NULL;
} }
texname[0] = texname[1] = texname[2] = -1; texname[0] = texname[1] = texname[2] = -1;
errorprinted= false;
} }
RAS_2DFilterManager::~RAS_2DFilterManager() RAS_2DFilterManager::~RAS_2DFilterManager()
@ -85,6 +86,35 @@ RAS_2DFilterManager::~RAS_2DFilterManager()
FreeTextures(); FreeTextures();
} }
void RAS_2DFilterManager::PrintShaderErrors(unsigned int shader, const char *task, const char *code)
{
GLcharARB log[5000];
GLsizei length = 0;
const char *c, *pos, *end;
int line = 1;
if(errorprinted)
return;
errorprinted= true;
glGetInfoLogARB(shader, sizeof(log), &length, log);
end = code + strlen(code);
printf("2D Filter GLSL Shader: %s error:\n", task);
c = code;
while ((c < end) && (pos = strchr(c, '\n'))) {
printf("%2d ", line);
fwrite(c, (pos+1)-c, 1, stdout);
c = pos+1;
line++;
}
printf("%s", c);
printf("%s\n", log);
}
unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource)
{ {
GLuint program = 0; GLuint program = 0;
@ -95,11 +125,12 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource)
glCompileShaderARB(fShader); glCompileShaderARB(fShader);
glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success); glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success);
if(!success) if(!success)
{ {
/*Shader Comile Error*/ /*Shader Comile Error*/
std::cout << "2dFilters - Shader compile error" << std::endl; PrintShaderErrors(fShader, "compile", shadersource);
return 0; return 0;
} }
@ -111,7 +142,7 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource)
if (!success) if (!success)
{ {
/*Program Link Error*/ /*Program Link Error*/
std::cout << "2dFilters - Shader program link error" << std::endl; PrintShaderErrors(fShader, "link", shadersource);
return 0; return 0;
} }
@ -120,7 +151,7 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource)
if (!success) if (!success)
{ {
/*Program Validation Error*/ /*Program Validation Error*/
std::cout << "2dFilters - Shader program validation error" << std::endl; PrintShaderErrors(fShader, "validate", shadersource);
return 0; return 0;
} }
@ -154,6 +185,7 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
} }
return 0; return 0;
} }
void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames) void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
{ {
texflag[passindex] = 0; texflag[passindex] = 0;
@ -249,11 +281,11 @@ void RAS_2DFilterManager::EndShaderProgram()
void RAS_2DFilterManager::FreeTextures() void RAS_2DFilterManager::FreeTextures()
{ {
if(texname[0]!=-1) if(texname[0]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[0]); glDeleteTextures(1, (GLuint*)&texname[0]);
if(texname[1]!=-1) if(texname[1]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[1]); glDeleteTextures(1, (GLuint*)&texname[1]);
if(texname[2]!=-1) if(texname[2]!=(unsigned int)-1)
glDeleteTextures(1, (GLuint*)&texname[2]); glDeleteTextures(1, (GLuint*)&texname[2]);
} }
@ -300,8 +332,8 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
RAS_Rect canvas_rect = canvas->GetWindowArea(); RAS_Rect canvas_rect = canvas->GetWindowArea();
canvaswidth = canvas->GetWidth(); canvaswidth = canvas->GetWidth();
canvasheight = canvas->GetHeight(); canvasheight = canvas->GetHeight();
texturewidth = canvaswidth + canvas_rect.GetLeft(); texturewidth = canvaswidth;
textureheight = canvasheight + canvas_rect.GetBottom(); textureheight = canvasheight;
GLint i,j; GLint i,j;
i = 0; i = 0;
@ -365,17 +397,17 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if(need_depth){ if(need_depth){
glActiveTextureARB(GL_TEXTURE1); glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]); glBindTexture(GL_TEXTURE_2D, texname[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], texturewidth,textureheight, 0);
} }
if(need_luminance){ if(need_luminance){
glActiveTextureARB(GL_TEXTURE2); glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]); glBindTexture(GL_TEXTURE_2D, texname[2]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0 , texturewidth,textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1] , texturewidth,textureheight, 0);
} }
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0,0, texturewidth, textureheight); glViewport(viewport[0],viewport[1], texturewidth, textureheight);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
@ -393,15 +425,20 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glActiveTextureARB(GL_TEXTURE0); glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]); glBindTexture(GL_TEXTURE_2D, texname[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], texturewidth, textureheight, 0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
float canvascoordx, canvascoordy;
canvascoordx = (GLfloat) texturewidth / canvaswidth;
canvascoordy = (GLfloat) textureheight / canvasheight;
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glTexCoord2f(1.0, 1.0); glVertex2f(1,1); glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, canvascoordy); glVertex2f(1,1);
glTexCoord2f(0.0, 1.0); glVertex2f(-1,1); glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, canvascoordy); glVertex2f(-1,1);
glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1); glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex2f(-1,-1);
glTexCoord2f(1.0, 0.0); glVertex2f(1,-1); glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, 0.0); glVertex2f(1,-1);
glEnd(); glEnd();
} }
} }

@ -38,6 +38,7 @@ private:
void AnalyseShader(int passindex, vector<STR_String>& propNames); void AnalyseShader(int passindex, vector<STR_String>& propNames);
void StartShaderProgram(int passindex); void StartShaderProgram(int passindex);
void EndShaderProgram(); void EndShaderProgram();
void PrintShaderErrors(unsigned int shader, const char *task, const char *code);
void SetupTextures(bool depth, bool luminance); void SetupTextures(bool depth, bool luminance);
void FreeTextures(); void FreeTextures();
@ -58,6 +59,7 @@ private:
short texflag[MAX_RENDER_PASS]; short texflag[MAX_RENDER_PASS];
bool isshadersupported; bool isshadersupported;
bool errorprinted;
unsigned int m_filters[MAX_RENDER_PASS]; unsigned int m_filters[MAX_RENDER_PASS];
short m_enabled[MAX_RENDER_PASS]; short m_enabled[MAX_RENDER_PASS];