diff options
author | Hamed Zaghaghi <hamed.zaghaghi@gmail.com> | 2008-07-12 14:21:37 +0400 |
---|---|---|
committer | Hamed Zaghaghi <hamed.zaghaghi@gmail.com> | 2008-07-12 14:21:37 +0400 |
commit | a49c9c458aac2a738c3cf90860fb6e942747617e (patch) | |
tree | 98882a609b085452b24c35bbe1a7cc6103d7ee91 /source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | |
parent | 5f15b164c549b336e1c5ef0dff2aaede056fd6f5 (diff) |
improvement of 2d-filter custom shader,
some bugfixes,
now you can use depth buffer and luminance buffer without any settings,
also you can use object's properties in a shader
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_2DFilterManager.cpp')
-rw-r--r-- | source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | 186 |
1 files changed, 122 insertions, 64 deletions
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 23153fcd86c..958fead33ce 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -52,6 +52,7 @@ #include <config.h> #endif +#include "Value.h" RAS_2DFilterManager::RAS_2DFilterManager(): texturewidth(-1), textureheight(-1), @@ -73,12 +74,14 @@ numberoffilters(0) m_filters[passindex] = 0; m_enabled[passindex] = 0; texflag[passindex] = 0; + m_gameObjects[passindex] = NULL; } texname[0] = texname[1] = texname[2] = -1; } RAS_2DFilterManager::~RAS_2DFilterManager() { + FreeTextures(); } unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) @@ -150,6 +153,27 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode) } return 0; } +void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames) +{ + texflag[passindex] = 0; + if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1) + { + texflag[passindex] |= 0x1; + } + if(glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1) + { + texflag[passindex] |= 0x2; + } + + if(m_gameObjects[passindex]) + { + int objProperties = propNames.size(); + int i; + for(i=0; i<objProperties; i++) + if(glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1) + m_properties[passindex].push_back(propNames[i]); + } +} void RAS_2DFilterManager::StartShaderProgram(int passindex) { @@ -177,7 +201,7 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex) } /* send luminance texture to glsl program if it needs */ - if(texflag[passindex] & 0x1){ + if(texflag[passindex] & 0x2){ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture"); glActiveTextureARB(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texname[2]); @@ -203,6 +227,17 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex) { glUniform1fARB(uniformLoc,textureheight); } + + int i, objProperties = m_properties[passindex].size(); + for(i=0; i<objProperties; i++) + { + uniformLoc = glGetUniformLocationARB(m_filters[passindex], m_properties[passindex][i]); + if(uniformLoc != -1) + { + float value = ((CValue*)m_gameObjects[passindex])->GetPropertyNumber(m_properties[passindex][i], 0.0); + glUniform1fARB(uniformLoc,value); + } + } } void RAS_2DFilterManager::EndShaderProgram() @@ -210,14 +245,21 @@ void RAS_2DFilterManager::EndShaderProgram() glUseProgramObjectARB(0); } -void RAS_2DFilterManager::SetupTexture() +void RAS_2DFilterManager::FreeTextures() { - if(texname[0]!=-1 || texname[1]!=-1) - { - glDeleteTextures(2, (GLuint*)texname); - } - glGenTextures(3, (GLuint*)texname); + if(texname[0]!=-1) + glDeleteTextures(1, (GLuint*)&texname[0]); + if(texname[1]!=-1) + glDeleteTextures(1, (GLuint*)&texname[1]); + if(texname[2]!=-1) + glDeleteTextures(1, (GLuint*)&texname[2]); +} +void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance) +{ + FreeTextures(); + + glGenTextures(1, (GLuint*)&texname[0]); glBindTexture(GL_TEXTURE_2D, texname[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); @@ -226,23 +268,29 @@ void RAS_2DFilterManager::SetupTexture() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glBindTexture(GL_TEXTURE_2D, texname[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, 0, GL_DEPTH_COMPONENT, - GL_FLOAT,NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, + if(depth){ + glGenTextures(1, (GLuint*)&texname[1]); + glBindTexture(GL_TEXTURE_2D, texname[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, + 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - glBindTexture(GL_TEXTURE_2D, texname[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, 0, GL_LUMINANCE, - GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + + if(luminance){ + glGenTextures(1, (GLuint*)&texname[2]); + glBindTexture(GL_TEXTURE_2D, texname[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } } void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height) @@ -273,62 +321,72 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height) textureoffsets[(((i*3)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc); } } - - SetupTexture(); } void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) { + bool need_depth=false; + bool need_luminance=false; + int num_filters = 0; + + int passindex; + if(!isshadersupported) return; + for(passindex =0; passindex<MAX_RENDER_PASS; passindex++) + { + if(m_filters[passindex] && m_enabled[passindex]){ + num_filters ++; + if(texflag[passindex] & 0x1) + need_depth = true; + if(texflag[passindex] & 0x2) + need_luminance = true; + if(need_depth && need_luminance) + break; + } + } + + if(num_filters <= 0) + return; + if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight()) { UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight()); + SetupTextures(need_depth, need_luminance); } GLuint viewport[4]={0}; - int passindex; - bool first = true; + if(need_depth){ + glActiveTextureARB(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texname[1]); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0); + } + + if(need_luminance){ + glActiveTextureARB(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, texname[2]); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0); + } + + glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + glViewport(0, 0, texturewidth, textureheight); + + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); for(passindex =0; passindex<MAX_RENDER_PASS; passindex++) { if(m_filters[passindex] && m_enabled[passindex]) { - if(first) - { - /* this pass needs depth texture*/ - if(texflag[passindex] & 0x1){ - glActiveTextureARB(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, texname[1]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0); - } - - /* this pass needs luminance texture*/ - if(texflag[passindex] & 0x2){ - glActiveTextureARB(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, texname[2]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0); - } - - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); - glViewport(0, 0, texturewidth, textureheight); - - glDisable(GL_DEPTH_TEST); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - first = false; - } - StartShaderProgram(passindex); - glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0); - glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); @@ -341,15 +399,12 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) } } - if(!first) - { - glEnable(GL_DEPTH_TEST); - glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); - EndShaderProgram(); - } + glEnable(GL_DEPTH_TEST); + glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); + EndShaderProgram(); } -void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag) +void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text) { if(!isshadersupported) return; @@ -374,16 +429,19 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str glDeleteObjectARB(m_filters[pass]); m_enabled[pass] = 0; m_filters[pass] = 0; + m_gameObjects[pass] = NULL; + m_properties[pass].clear(); texflag[pass] = 0; return; } if(mode == RAS_2DFILTER_CUSTOMFILTER) { - texflag[pass] = tflag; if(m_filters[pass]) glDeleteObjectARB(m_filters[pass]); m_filters[pass] = CreateShaderProgram(text.Ptr()); + m_gameObjects[pass] = gameObj; + AnalyseShader(pass, propNames); m_enabled[pass] = 1; return; } |