Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

OpenGLRenderer.cpp

Go to the documentation of this file.
00001 
00007 #include "OpenGLRenderer.h"
00008 
00009 // Depth
00010 const int NEVER         = GL_NEVER;
00011 const int LESS          = GL_LESS;
00012 const int EQUAL         = GL_EQUAL;
00013 const int LEQUAL        = GL_LEQUAL;
00014 const int GREATER       = GL_GREATER;
00015 const int NOTEQUAL      = GL_NOTEQUAL;
00016 const int GEQUAL        = GL_GEQUAL;
00017 const int ALWAYS        = GL_ALWAYS;
00018 
00019 // Blending
00020 const int ZERO                                  = GL_ZERO;
00021 const int ONE                                   = GL_ONE;
00022 const int SRC_COLOR                             = GL_SRC_COLOR;
00023 const int ONE_MINUS_SRC_COLOR   = GL_ONE_MINUS_SRC_COLOR;
00024 const int DST_COLOR                             = GL_DST_COLOR;
00025 const int ONE_MINUS_DST_COLOR   = GL_ONE_MINUS_DST_COLOR;
00026 const int SRC_ALPHA                             = GL_SRC_ALPHA;
00027 const int ONE_MINUS_SRC_ALPHA   = GL_ONE_MINUS_SRC_ALPHA;
00028 const int DST_ALPHA                             = GL_DST_ALPHA;
00029 const int ONE_MINUS_DST_ALPHA   = GL_ONE_MINUS_DST_ALPHA;
00030 const int SRC_ALPHA_SATURATE    = GL_SRC_ALPHA_SATURATE;
00031 
00032 const int BLENDMODE_ADD                                 = GL_FUNC_ADD_EXT;
00033 const int BLENDMODE_SUBTRACT                    = GL_FUNC_SUBTRACT_EXT;
00034 const int BLENDMODE_REVERSE_SUBSTRACT   = GL_FUNC_REVERSE_SUBTRACT_EXT;
00035 const int BLENDMODE_MIN                                 = GL_MIN_EXT;
00036 const int BLENDMOXE_MAX                                 = GL_MAX_EXT;
00037 
00038 GLenum OpenGLRenderer::targets[] = { GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_ARB};
00039 
00040 OpenGLRenderer::OpenGLRenderer() {
00041         init();
00042 }
00043 
00044 /********************************************************************
00045  * Init
00046  */
00047 void OpenGLRenderer::init() {
00048         if (GL_ARB_multitexture_supported) {
00049                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures);
00050                 if (maxTextures > MAX_TEXTURES) maxTextures = MAX_TEXTURES;
00051         }
00052         else
00053                 maxTextures = 1;
00054 
00055         resetToDefaults();
00056         setDefaults();
00057 }
00058 
00059 
00060 /********************************************************************
00061  * Set defaults
00062  */
00063 void OpenGLRenderer::setDefaults() {
00064         glEnable(GL_DEPTH_TEST);
00065         glDepthFunc(GL_LEQUAL);
00066         glPixelStorei(GL_PACK_ALIGNMENT, 1);
00067         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00068         glFrontFace(GL_CW);
00069 
00070         glShadeModel(GL_SMOOTH);
00071         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00072 }
00073 
00074 /********************************************************************
00075  * Change depth func
00076  */
00077 void OpenGLRenderer::changeDepthFunc(const int depthFunc) {
00078         if (depthFunc != currentDepthFunc) {
00079                 if (depthFunc == DEPTH_NONE) {
00080                         glDisable(GL_DEPTH_TEST);
00081                 }
00082                 else {
00083                         if (currentDepthFunc == DEPTH_NONE)
00084                                 glEnable(GL_DEPTH_TEST);
00085                         glDepthFunc(depthFunc);
00086                 }
00087                 currentDepthFunc = depthFunc;
00088         }
00089 }
00090 
00091 /********************************************************************
00092  * Change blending
00093  */
00094 void OpenGLRenderer::changeBlending(const int src, const int dest, const int blendMode) {
00095         if (src != BLENDING_NONE) {
00096                 if (currentBlendSrc == BLENDING_NONE)
00097                         glEnable(GL_BLEND);
00098 
00099                 if (src != currentBlendSrc || dest != currentBlendDest)
00100                         glBlendFunc(currentBlendSrc = src, currentBlendDest = dest);
00101 
00102                 if (blendMode != currentBlendMode)
00103                         glBlendEquationEXT(currentBlendMode = blendMode);
00104         }
00105         else {
00106                 if (currentBlendSrc != BLENDING_NONE) {
00107                         glDisable(GL_BLEND);
00108                         currentBlendSrc = BLENDING_NONE;
00109                 }
00110         }
00111 }
00112 
00113 /********************************************************************
00114  * Change mask
00115  */
00116 void OpenGLRenderer::changeMask(const int mask) {
00117         if (mask != currentMask) {
00118                 if ((mask & DEPTH) != (currentMask & DEPTH))
00119                         glDepthMask(mask & DEPTH);
00120 
00121                 if ((mask & COLOR) != (currentMask & COLOR))
00122                         glColorMask(((mask & RED) >> 1) & 1, ((mask & GREEN) >> 2) & 1, ((mask & BLUE) >> 3) & 1, ((mask & ALPHA) >> 4 & 1));
00123 
00124                 currentMask = mask;
00125         }
00126 }
00127 
00128 /********************************************************************
00129  * Create texture
00130  */
00131 bool OpenGLRenderer::createTexture(Texture &texture) {
00132         GLenum target = targets[texture.textureKind];
00133         int nImages = 1;
00134 
00135         glGenTextures(1, &texture.textureID);
00136         glBindTexture(target, texture.textureID);
00137 
00138         switch (texture.textureKind) {
00139                 case TEXTURE_2D:
00140                         glTexParameteri(target, GL_TEXTURE_WRAP_S, (texture.clampS ? GL_CLAMP_TO_EDGE_EXT : GL_REPEAT));
00141                         glTexParameteri(target, GL_TEXTURE_WRAP_T, (texture.clampT ? GL_CLAMP_TO_EDGE_EXT : GL_REPEAT));
00142                         break;
00143 
00144                 case TEXTURE_CUBEMAP:
00145                         nImages = 6;
00146                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);
00147                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);
00148                         break;
00149 
00150                 default:
00151                         return false;
00152         }
00153 
00154         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00155 
00156         glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00157 
00158         for (int i=0; i<nImages; i++) {
00159                 Image *image = texture.images[i];
00160 
00161                 GLenum imgTarget = (texture.textureKind == TEXTURE_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i;
00162 
00163                 gluBuild2DMipmaps(imgTarget, 3, image->getWidth(), image->getHeight(), image->getFormat(), GL_UNSIGNED_BYTE, image->getData());
00164         }
00165 
00166         return true;
00167 }
00168 
00169 /********************************************************************
00170  * Remove texture
00171  */
00172 void OpenGLRenderer::removeTexture(Texture &texture) {
00173         glDeleteTextures(1, &texture.textureID);
00174 }
00175 
00176 /********************************************************************
00177  * Change texture unit
00178  */
00179 void OpenGLRenderer::changeTextureUnit(const int tex) {
00180         if (tex != currentTextureUnit)
00181                 glActiveTextureARB(GL_TEXTURE0_ARB + (currentTextureUnit =tex));
00182 }
00183 
00184 /********************************************************************
00185  * Change texture
00186  */
00187 void OpenGLRenderer::changeTexture(const TextureID textureID) {
00188         TextureID currTex = currentTextures[currentTextureUnit];
00189 
00190         if (textureID != currTex) {
00191                 if (textureID == TEXTURE_NONE) {
00192                         glDisable(targets[textures[currTex].textureKind]);
00193                 }
00194                 else {
00195                         GLenum target = targets[textures[textureID].textureKind];
00196 
00197                         if (currTex == TEXTURE_NONE) {
00198                                 glEnable(target);
00199                         }
00200                         else {
00201                                 if (textures[textureID].textureKind != textures[currTex].textureKind) {
00202                                         glDisable(targets[textures[currTex].textureKind]);
00203                                         glEnable(target);
00204                                 }
00205                         }
00206 
00207                         glBindTexture(target, textures[textureID].textureID);
00208                 }
00209                 currentTextures[currentTextureUnit] = textureID;
00210         }
00211 
00219 }
00220 
00221 /********************************************************************
00222  * Assign named textures
00223  */
00224 void OpenGLRenderer::assignNamedTextures() {
00225         if (currentShader != SHADER_NONE) {
00226                 for (int i=0; i<nNamedTextures; i++) {
00227                         int location = glGetUniformLocationARB(shaders[currentShader].programObj, selectedTextureNames[i]);
00228                         if (location >= 0) glUniform1iARB(location, i);
00229                 }
00230         }
00231 }
00232 
00233 /********************************************************************
00234  * Create shader
00235  */
00236 bool OpenGLRenderer::createShader(Shader &shader, const char *vertexShaderText, const char *fragmentShaderText) {
00237         const char *shaderStrings[2];
00238         int vResult, fResult, lResult;
00239         char str[4096];
00240 
00241         shaderStrings[0] = "#define saturate(x) clamp(x,0.0,1.0)\n"
00242                                            "#define lerp mix\n";
00243 
00244         shader.programObj = glCreateProgramObjectARB();
00245 
00246         shader.vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
00247         shaderStrings[1] = vertexShaderText;
00248         glShaderSourceARB(shader.vertexShader, 2, shaderStrings, NULL);
00249         glCompileShaderARB(shader.vertexShader);
00250         glGetObjectParameterivARB(shader.vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &vResult);
00251         if (vResult) {
00252                 glAttachObjectARB(shader.programObj, shader.vertexShader);
00253         }
00254         else {
00255                 glGetInfoLogARB(shader.vertexShader, sizeof(str), NULL, str);
00256                 LOG_ERROR(("Vertex shader error! Log:\n%s", str));
00257         }
00258 
00259         shader.fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
00260         shaderStrings[1] = fragmentShaderText;
00261         glShaderSourceARB(shader.fragmentShader, 2, shaderStrings, NULL);
00262         glCompileShaderARB(shader.fragmentShader);
00263         glGetObjectParameterivARB(shader.fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &fResult);
00264         if (fResult) {
00265                 glAttachObjectARB(shader.programObj, shader.fragmentShader);
00266         }
00267         else {
00268                 glGetInfoLogARB(shader.fragmentShader, sizeof(str), NULL, str);
00269                 LOG_ERROR(("Fragment shader error! Log:\n%s", str));
00270         }
00271 
00272 
00273         if (vResult && fResult) {
00274                 glLinkProgramARB(shader.programObj);
00275                 glGetObjectParameterivARB(shader.programObj, GL_OBJECT_LINK_STATUS_ARB, &lResult);
00276 
00277                 //glGetInfoLogARB(shader.programObj, sizeof(str), NULL, str);
00278                 //LOG_ERROR(("Program ARB error! Log:\n%s", str));
00279 
00280                 if (lResult) {
00281                         return true;
00282                 }
00283                 else {
00284                         glGetInfoLogARB(shader.programObj, sizeof(str), NULL, str);
00285                         LOG_ERROR(("Program object error! Log:\n%s", str));
00286                 }
00287         }
00288 
00289         removeShader(shader);
00290         return false;
00291 }
00292 
00293 /********************************************************************
00294  * Remove shader
00295  */
00296 void OpenGLRenderer::removeShader(Shader &shader) {
00297         glDeleteObjectARB(shader.vertexShader);
00298         glDeleteObjectARB(shader.fragmentShader);
00299         glDeleteObjectARB(shader.programObj);
00300 }
00301 
00302 /********************************************************************
00303  * Change shader
00304  */
00305 void OpenGLRenderer::changeShader(const ShaderID shader) {
00306         if (shader != currentShader) {
00307                 if (shader == SHADER_NONE)
00308                         glUseProgramObjectARB(0);
00309                 else
00310                         glUseProgramObjectARB(shaders[shader].programObj);
00311 
00312                 currentShader = shader;
00313         }
00314 }
00315 
00316 /********************************************************************
00317  * Change shader constant 1f
00318  */
00319 void OpenGLRenderer::changeShaderConstant1f(const char *name, const float constant) {
00320         if (currentShader != SHADER_NONE) {
00321                 int location = glGetUniformLocationARB(shaders[currentShader].programObj, name);
00322                 if (location >= 0) glUniform1fARB(location, constant);
00323         }
00324 }
00325 
00326 /********************************************************************
00327  * Change shader constant 2f
00328  */
00329 void OpenGLRenderer::changeShaderConstant2f(const char *name, const Vec2 &constant) {
00330         if (currentShader != SHADER_NONE) {
00331                 int location = glGetUniformLocationARB(shaders[currentShader].programObj, name);
00332                 //if (location >= 0) glUniform2fvARB(location, 1, (float *)&constant);
00333                 if (location >= 0) glUniform2fARB(location, constant.x, constant.y);
00334         }
00335 }
00336 
00337 /********************************************************************
00338  * Change shader constant 3f
00339  */
00340 void OpenGLRenderer::changeShaderConstant3f(const char *name, const Vec3 &constant) {
00341         if (currentShader != SHADER_NONE) {
00342                 int location = glGetUniformLocationARB(shaders[currentShader].programObj, name);
00343                 //if (location >= 0) glUniform3fvARB(location, 1, (float *)&constant);
00344                 if (location >= 0) glUniform3fARB(location, constant.x, constant.y, constant.z);
00345         }
00346 }
00347 
00348 /********************************************************************
00349  * Change shader constant 4f
00350  */
00351 void OpenGLRenderer::changeShaderConstant4f(const char *name, const Vec4 &constant) {
00352         if (currentShader != SHADER_NONE) {
00353                 int location = glGetUniformLocationARB(shaders[currentShader].programObj, name);
00354                 //if (location >= 0) glUniform4fvARB(location, 1, (float *)&constant);
00355                 if (location >= 0) glUniform4fARB(location, constant.x, constant.y, constant.z, constant.w);
00356         }
00357 }
00358 
00359 
00360 /********************************************************************
00361  * Create fragment shader
00362  */
00363 void OpenGLRenderer::createFragmentShader(FragmentShader &fragmentShader) {
00364         //if (fragmentShader.type == GL_FRAGMENT_SHADER_GL2) {
00365 
00366         //}if (fragmentShader.type == GL_FRAGMENT_PROGRAM_ARB) {
00368                 glGenProgramsARB(1, &fragmentShader.shaderID);
00369                 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragmentShader.shaderID);
00370         }
00371         //else if (fragmentShader.type == GL_FRAGMENT_SHADER_ATI) {
00372         //      fragmentShader.shaderID = glGenFragmentShadersATI(1);
00373         //      glBindFragmentShaderATI(fragmentShader.shaderID);
00374         //}
00375 }
00376 
00377 /********************************************************************
00378  * Remove fragment shader
00379  */
00380 void OpenGLRenderer::removeFragmentShader(FragmentShader &fragmentShader) {
00381         if (fragmentShader.type == GL_FRAGMENT_PROGRAM_ARB) {
00382                 glDeleteProgramsARB(1, &fragmentShader.shaderID);
00383         }
00384         //else if (fragmentShader.type == GL_FRAGMENT_SHADER_ATI) {
00385         //      glDeleteFragmentShaderATI(fragmentShader.shaderID);
00386         //}
00387         //else if (fragmentShader.type == GL_REGISTER_COMBINERS_NV) {
00388         //      glDeleteLists(fragmentShader.shaderID, 1);
00389         //}
00390 }
00391 
00392 /********************************************************************
00393  * Upload fragment shader
00394  */
00395 void OpenGLRenderer::uploadFragmentShader(FragmentShader &fragmentShader) {
00396         glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, fragmentShader.length, fragmentShader.program);
00397 }
00398 
00399 /********************************************************************
00400  * Create vertex shader
00401  */
00402 void OpenGLRenderer::createVertexShader(VertexShader &vertexShader) {
00403         glGenProgramsARB(1, &vertexShader.shaderID);
00404         glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader.shaderID);
00405 }
00406 
00407 /********************************************************************
00408  * Remove vertex shader
00409  */
00410 void OpenGLRenderer::removeVertexShader(VertexShader &vertexShader) {
00411         glDeleteProgramsARB(1, &vertexShader.shaderID);
00412 }
00413 
00414 /********************************************************************
00415  * Upload vertex shader
00416  */
00417 void OpenGLRenderer::uploadVertexShader(VertexShader &vertexShader) {
00418         glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, vertexShader.length, vertexShader.program);
00419 }
00420 
00421 /********************************************************************
00422  * Change fragment shader
00423  */
00424 void OpenGLRenderer::changeFragmentShader(const ShaderID shader) {
00425         if (currentFragmentShader != shader) {
00426                 if (shader == SHADER_NONE) {
00427                         glDisable(fragmentShaders[currentFragmentShader].type);
00428                 }
00429                 else {
00430                         if (currentFragmentShader == SHADER_NONE) {
00431                                 glEnable(fragmentShaders[shader].type);
00432                         }
00433                         else if (fragmentShaders[currentFragmentShader].type != fragmentShaders[shader].type) {
00434                                 glDisable(fragmentShaders[currentFragmentShader].type);
00435                                 glEnable(fragmentShaders[shader].type);
00436                         }
00437 
00438                         if (fragmentShaders[shader].type == GL_FRAGMENT_PROGRAM_ARB) {
00439                                 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragmentShaders[shader].shaderID);
00440                         }
00447                 }
00448 
00449                 currentFragmentShader = shader;
00450         }
00451 }
00452 
00453 /********************************************************************
00454  * Change vertex shader
00455  */
00456 void OpenGLRenderer::changeVertexShader(const ShaderID shader) {
00457         if (currentVertexShader != shader) {
00458                 if (shader == SHADER_NONE) {
00459                         glDisable(GL_VERTEX_PROGRAM_ARB);
00460                 }
00461                 else {
00462                         if (currentVertexShader == SHADER_NONE) {
00463                                 glEnable(GL_VERTEX_PROGRAM_ARB);
00464                         }
00465 
00466                         glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShaders[shader].shaderID);
00467                 }
00468 
00469                 currentVertexShader = shader;
00470         }
00471 }

Generated on Sun Jun 5 15:47:05 2005 for Defacto by  doxygen 1.4.3