llgl.cpp

Go to the documentation of this file.
00001 
00032 // This file sets some global GL parameters, and implements some 
00033 // useful functions for GL operations.
00034 
00035 #define GLH_EXT_SINGLE_FILE
00036 
00037 #include "linden_common.h"
00038 
00039 #include "boost/tokenizer.hpp"
00040 
00041 #include "llsys.h"
00042 
00043 #include "llgl.h"
00044 #include "llglimmediate.h"
00045 
00046 #include "llerror.h"
00047 #include "llquaternion.h"
00048 #include "llmath.h"
00049 #include "m4math.h"
00050 #include "llstring.h"
00051 
00052 #include "llglheaders.h"
00053 
00054 #ifdef _DEBUG
00055 //#define GL_STATE_VERIFY
00056 #endif
00057 
00058 BOOL gDebugGL = FALSE;
00059 BOOL gClothRipple = FALSE;
00060 BOOL gNoRender = FALSE;
00061 LLMatrix4 gGLObliqueProjectionInverse;
00062 
00063 LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
00064 
00065 #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
00066 // ATI prototypes
00067 // vertex blending prototypes
00068 PFNGLWEIGHTPOINTERARBPROC                       glWeightPointerARB = NULL;
00069 PFNGLVERTEXBLENDARBPROC                         glVertexBlendARB = NULL;
00070 PFNGLWEIGHTFVARBPROC                            glWeightfvARB = NULL;
00071 
00072 // Vertex buffer object prototypes
00073 PFNGLBINDBUFFERARBPROC                          glBindBufferARB = NULL;
00074 PFNGLDELETEBUFFERSARBPROC                       glDeleteBuffersARB = NULL;
00075 PFNGLGENBUFFERSARBPROC                          glGenBuffersARB = NULL;
00076 PFNGLISBUFFERARBPROC                            glIsBufferARB = NULL;
00077 PFNGLBUFFERDATAARBPROC                          glBufferDataARB = NULL;
00078 PFNGLBUFFERSUBDATAARBPROC                       glBufferSubDataARB = NULL;
00079 PFNGLGETBUFFERSUBDATAARBPROC            glGetBufferSubDataARB = NULL;
00080 PFNGLMAPBUFFERARBPROC                           glMapBufferARB = NULL;
00081 PFNGLUNMAPBUFFERARBPROC                         glUnmapBufferARB = NULL;
00082 PFNGLGETBUFFERPARAMETERIVARBPROC        glGetBufferParameterivARB = NULL;
00083 PFNGLGETBUFFERPOINTERVARBPROC           glGetBufferPointervARB = NULL;
00084 
00085 // vertex object prototypes
00086 PFNGLNEWOBJECTBUFFERATIPROC                     glNewObjectBufferATI = NULL;
00087 PFNGLISOBJECTBUFFERATIPROC                      glIsObjectBufferATI = NULL;
00088 PFNGLUPDATEOBJECTBUFFERATIPROC          glUpdateObjectBufferATI = NULL;
00089 PFNGLGETOBJECTBUFFERFVATIPROC           glGetObjectBufferfvATI = NULL;
00090 PFNGLGETOBJECTBUFFERIVATIPROC           glGetObjectBufferivATI = NULL;
00091 PFNGLFREEOBJECTBUFFERATIPROC            glFreeObjectBufferATI = NULL;
00092 PFNGLARRAYOBJECTATIPROC                         glArrayObjectATI = NULL;
00093 PFNGLVERTEXATTRIBARRAYOBJECTATIPROC     glVertexAttribArrayObjectATI = NULL;
00094 PFNGLGETARRAYOBJECTFVATIPROC            glGetArrayObjectfvATI = NULL;
00095 PFNGLGETARRAYOBJECTIVATIPROC            glGetArrayObjectivATI = NULL;
00096 PFNGLVARIANTARRAYOBJECTATIPROC          glVariantObjectArrayATI = NULL;
00097 PFNGLGETVARIANTARRAYOBJECTFVATIPROC     glGetVariantArrayObjectfvATI = NULL;
00098 PFNGLGETVARIANTARRAYOBJECTIVATIPROC     glGetVariantArrayObjectivATI = NULL;
00099 
00100 // GL_ARB_occlusion_query
00101 PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
00102 PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
00103 PFNGLISQUERYARBPROC glIsQueryARB = NULL;
00104 PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
00105 PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
00106 PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
00107 PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
00108 PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
00109 
00110 // GL_ARB_point_parameters
00111 PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
00112 PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
00113 
00114 // GL_EXT_framebuffer_object
00115 PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL;
00116 PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
00117 PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
00118 PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
00119 PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
00120 PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT = NULL;
00121 PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT = NULL;
00122 PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
00123 PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT = NULL;
00124 PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
00125 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL;
00126 PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT = NULL;
00127 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
00128 PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
00129 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
00130 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
00131 PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
00132 
00133 //shader object prototypes
00134 PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
00135 PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
00136 PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
00137 PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
00138 PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
00139 PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
00140 PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
00141 PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
00142 PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
00143 PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
00144 PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB = NULL;
00145 PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
00146 PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
00147 PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
00148 PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
00149 PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
00150 PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL;
00151 PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL;
00152 PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL;
00153 PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
00154 PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
00155 PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
00156 PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
00157 PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
00158 PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
00159 PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
00160 PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
00161 PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL;
00162 PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL;
00163 PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL;
00164 PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL;
00165 PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
00166 PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
00167 PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL;
00168 PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
00169 PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
00170 PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
00171 PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
00172 PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
00173 
00174 // vertex shader prototypes
00175 #if LL_LINUX
00176 PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
00177 PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
00178 PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
00179 PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB = NULL;
00180 PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB = NULL;
00181 PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB = NULL;
00182 PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB = NULL;
00183 PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB = NULL;
00184 PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB = NULL;
00185 PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB = NULL;
00186 PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB = NULL;
00187 PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB = NULL;
00188 PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB = NULL;
00189 PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB = NULL;
00190 PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
00191 PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
00192 PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
00193 PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
00194 #endif // LL_LINUX
00195 PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
00196 PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
00197 PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
00198 PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
00199 PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
00200 PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
00201 PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
00202 #if LL_LINUX
00203 PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
00204 PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
00205 PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
00206 PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB = NULL;
00207 PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB = NULL;
00208 PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB = NULL;
00209 PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB = NULL;
00210 PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB = NULL;
00211 PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
00212 PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
00213 PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
00214 PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
00215 PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
00216 PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
00217 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
00218 PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
00219 PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL;
00220 PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
00221 PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB = NULL;
00222 PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB = NULL;
00223 PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB = NULL;
00224 PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = NULL;
00225 PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB = NULL;
00226 PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB = NULL;
00227 PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB = NULL;
00228 PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = NULL;
00229 PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB = NULL;
00230 PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB = NULL;
00231 PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB = NULL;
00232 PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB = NULL;
00233 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = NULL;
00234 PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB = NULL;
00235 PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB = NULL;
00236 PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
00237 PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
00238 PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
00239 PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
00240 #endif // LL_LINUX
00241 PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
00242 PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
00243 PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
00244 
00245 #if LL_WINDOWS
00246 PFNWGLSWAPINTERVALEXTPROC                       wglSwapIntervalEXT = NULL;
00247 #endif
00248 
00249 #if LL_LINUX
00250 PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
00251 #endif // LL_LINUX
00252 
00253 #endif
00254 
00255 LLGLManager gGLManager;
00256 
00257 LLGLManager::LLGLManager() :
00258         mInited(FALSE),
00259         mIsDisabled(FALSE),
00260 
00261         mHasMultitexture(FALSE),
00262         mNumTextureUnits(1),
00263         mHasMipMapGeneration(FALSE),
00264         mHasPalettedTextures(FALSE),
00265         mHasCompressedTextures(FALSE),
00266         mHasFramebufferObject(FALSE),
00267 
00268         mHasVertexBufferObject(FALSE),
00269         mHasPBuffer(FALSE),
00270         mHasShaderObjects(FALSE),
00271         mHasVertexShader(FALSE),
00272         mHasFragmentShader(FALSE),
00273         mHasOcclusionQuery(FALSE),
00274         mHasPointParameters(FALSE),
00275 
00276         mHasAnisotropic(FALSE),
00277         mHasARBEnvCombine(FALSE),
00278         mHasCubeMap(FALSE),
00279 
00280         mIsATI(FALSE),
00281         mIsNVIDIA(FALSE),
00282         mIsIntel(FALSE),
00283         mIsGF2or4MX(FALSE),
00284         mIsGF3(FALSE),
00285         mIsGFFX(FALSE),
00286         mATIOffsetVerticalLines(FALSE),
00287 
00288         mHasRequirements(TRUE),
00289 
00290         mHasSeparateSpecularColor(FALSE),
00291 
00292         mDriverVersionMajor(1),
00293         mDriverVersionMinor(0),
00294         mDriverVersionRelease(0),
00295         mGLVersion(1.0f),
00296                 
00297         mVRAM(0),
00298         mGLMaxVertexRange(0),
00299         mGLMaxIndexRange(0)
00300 {
00301 }
00302 
00303 //---------------------------------------------------------------------
00304 // Global initialization for GL
00305 //---------------------------------------------------------------------
00306 void LLGLManager::initWGL()
00307 {
00308         mHasPBuffer = FALSE;
00309 #if LL_WINDOWS && !LL_MESA_HEADLESS
00310         if (!glh_init_extensions("WGL_ARB_pixel_format"))
00311         {
00312                 LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
00313         }
00314 
00315         if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
00316         {
00317         GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
00318         }
00319 
00320         if( !glh_init_extensions("WGL_ARB_pbuffer") )
00321         {
00322                 LL_WARNS("RenderInit") << "No ARB WGL PBuffer extensions" << LL_ENDL;
00323         }
00324 
00325         if( !glh_init_extensions("WGL_ARB_render_texture") )
00326         {
00327                 LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
00328         }
00329 
00330         mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) &&
00331                                         ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) &&
00332                                         ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts);
00333 #endif
00334 }
00335 
00336 // return false if unable (or unwilling due to old drivers) to init GL
00337 bool LLGLManager::initGL()
00338 {
00339         if (mInited)
00340         {
00341                 LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
00342         }
00343 
00344         GLint alpha_bits;
00345         glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
00346         if( 8 != alpha_bits )
00347         {
00348                 LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha.  Avatar texture compositing will fail." << LL_ENDL;
00349         }
00350 
00351         // Extract video card strings and convert to upper case to
00352         // work around driver-to-driver variation in capitalization.
00353         mGLVendor = LLString((const char *)glGetString(GL_VENDOR));
00354         LLString::toUpper(mGLVendor);
00355 
00356         mGLRenderer = LLString((const char *)glGetString(GL_RENDERER));
00357         LLString::toUpper(mGLRenderer);
00358 
00359         parse_gl_version( &mDriverVersionMajor, 
00360                 &mDriverVersionMinor, 
00361                 &mDriverVersionRelease, 
00362                 &mDriverVersionVendorString );
00363 
00364         mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
00365         
00366         // Trailing space necessary to keep "nVidia Corpor_ati_on" cards
00367         // from being recognized as ATI.
00368         if (mGLVendor.substr(0,4) == "ATI ")
00369         {
00370                 mGLVendorShort = "ATI";
00371                 BOOL mobile = FALSE;
00372                 if (mGLRenderer.find("MOBILITY") != LLString::npos)
00373                 {
00374                         mobile = TRUE;
00375                 }
00376                 mIsATI = TRUE;
00377 
00378 #if LL_WINDOWS && !LL_MESA_HEADLESS
00379                 if (mDriverVersionRelease < 3842)
00380                 {
00381                         mATIOffsetVerticalLines = TRUE;
00382                 }
00383 #endif // LL_WINDOWS
00384         }
00385         else if (mGLVendor.find("NVIDIA ") != LLString::npos)
00386         {
00387                 mGLVendorShort = "NVIDIA";
00388                 mIsNVIDIA = TRUE;
00389                 if (   mGLRenderer.find("GEFORCE4 MX") != LLString::npos
00390                         || mGLRenderer.find("GEFORCE2") != LLString::npos
00391                         || mGLRenderer.find("GEFORCE 2") != LLString::npos
00392                         || mGLRenderer.find("GEFORCE4 460 GO") != LLString::npos
00393                         || mGLRenderer.find("GEFORCE4 440 GO") != LLString::npos
00394                         || mGLRenderer.find("GEFORCE4 420 GO") != LLString::npos)
00395                 {
00396                         mIsGF2or4MX = TRUE;
00397                 }
00398                 else if (mGLRenderer.find("GEFORCE FX") != LLString::npos
00399                                  || mGLRenderer.find("QUADRO FX") != LLString::npos
00400                                  || mGLRenderer.find("NV34") != LLString::npos)
00401                 {
00402                         mIsGFFX = TRUE;
00403                 }
00404                 else if(mGLRenderer.find("GEFORCE3") != LLString::npos)
00405                 {
00406                         mIsGF3 = TRUE;
00407                 }
00408 
00409         }
00410         else if (mGLVendor.find("INTEL") != LLString::npos
00411 #if LL_LINUX
00412                  // The Mesa-based drivers put this in the Renderer string,
00413                  // not the Vendor string.
00414                  || mGLRenderer.find("INTEL") != LLString::npos
00415 #endif //LL_LINUX
00416                  )
00417         {
00418                 mGLVendorShort = "INTEL";
00419                 mIsIntel = TRUE;
00420         }
00421         else
00422         {
00423                 mGLVendorShort = "MISC";
00424         }
00425         
00426         // This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
00427         initExtensions();
00428 
00429         if (mHasMultitexture)
00430         {
00431                 GLint num_tex_units;            
00432                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
00433                 mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS);
00434                 if (mIsIntel)
00435                 {
00436                         mNumTextureUnits = llmin(mNumTextureUnits, 2);
00437                 }
00438         }
00439         else
00440         {
00441                 mHasRequirements = FALSE;
00442 
00443                 // We don't support cards that don't support the GL_ARB_multitexture extension
00444                 LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL;
00445                 return false;
00446         }
00447         
00448 
00449         initGLStates();
00450         return true;
00451 }
00452 
00453 void LLGLManager::getGLInfo(LLSD& info)
00454 {
00455         info["GLInfo"]["GLVendor"] = LLString((const char *)glGetString(GL_VENDOR));
00456         info["GLInfo"]["GLRenderer"] = LLString((const char *)glGetString(GL_RENDERER));
00457         info["GLInfo"]["GLVersion"] = LLString((const char *)glGetString(GL_VERSION));
00458 
00459 #if !LL_MESA_HEADLESS
00460         LLString all_exts = (const char *)gGLHExts.mSysExts;
00461         boost::char_separator<char> sep(" ");
00462         boost::tokenizer<boost::char_separator<char> > tok(all_exts, sep);
00463         for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
00464         {
00465                 info["GLInfo"]["GLExtensions"].append(*i);
00466         }
00467 #endif
00468 }
00469 
00470 LLString LLGLManager::getGLInfoString()
00471 {
00472         LLString info_str;
00473         LLString all_exts, line;
00474 
00475         info_str += LLString("GL_VENDOR      ") + LLString((const char *)glGetString(GL_VENDOR)) + LLString("\n");
00476         info_str += LLString("GL_RENDERER    ") + LLString((const char *)glGetString(GL_RENDERER)) + LLString("\n");
00477         info_str += LLString("GL_VERSION     ") + LLString((const char *)glGetString(GL_VERSION)) + LLString("\n");
00478 
00479 #if !LL_MESA_HEADLESS
00480         all_exts = (const char *)gGLHExts.mSysExts;
00481         LLString::replaceChar(all_exts, ' ', '\n');
00482         info_str += LLString("GL_EXTENSIONS:\n") + all_exts + LLString("\n");
00483 #endif
00484         
00485         return info_str;
00486 }
00487 
00488 void LLGLManager::printGLInfoString()
00489 {
00490         LLString info_str;
00491         LLString all_exts, line;
00492         
00493         LL_INFOS("RenderInit") << "GL_VENDOR:     " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
00494         LL_INFOS("RenderInit") << "GL_RENDERER:   " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
00495         LL_INFOS("RenderInit") << "GL_VERSION:    " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
00496 
00497 #if !LL_MESA_HEADLESS
00498         all_exts = (const char *)gGLHExts.mSysExts;
00499         LLString::replaceChar(all_exts, ' ', '\n');
00500         LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
00501 #endif
00502 }
00503 
00504 LLString LLGLManager::getRawGLString()
00505 {
00506         LLString gl_string;
00507         gl_string.assign((char*)glGetString(GL_VENDOR));
00508         gl_string.append(" ");
00509         gl_string.append((char*)glGetString(GL_RENDERER));
00510         return gl_string;
00511 }
00512 
00513 void LLGLManager::shutdownGL()
00514 {
00515         if (mInited)
00516         {
00517                 glFinish();
00518                 stop_glerror();
00519                 mInited = FALSE;
00520         }
00521 }
00522 
00523 // these are used to turn software blending on. They appear in the Debug/Avatar menu
00524 // presence of vertex skinning/blending or vertex programs will set these to FALSE by default.
00525 
00526 extern LLCPUInfo gSysCPU;
00527 
00528 void LLGLManager::initExtensions()
00529 {
00530 #if LL_MESA_HEADLESS
00531 # if GL_ARB_multitexture
00532         mHasMultitexture = TRUE;
00533 # else
00534         mHasMultitexture = FALSE;
00535 # endif
00536 # if GL_ARB_texture_env_combine
00537         mHasARBEnvCombine = TRUE;       
00538 # else
00539         mHasARBEnvCombine = FALSE;
00540 # endif
00541 # if GL_ARB_texture_compression
00542         mHasCompressedTextures = TRUE;
00543 # else
00544         mHasCompressedTextures = FALSE;
00545 # endif
00546 # if GL_ARB_vertex_buffer_object
00547         mHasVertexBufferObject = TRUE;
00548 # else
00549         mHasVertexBufferObject = FALSE;
00550 # endif
00551 # if GL_EXT_framebuffer_object
00552         mHasFramebufferObject = TRUE;
00553 # else
00554         mHasFramebufferObject = FALSE;
00555 # endif
00556         mHasMipMapGeneration = FALSE;
00557         mHasPalettedTextures = FALSE;
00558         mHasSeparateSpecularColor = FALSE;
00559         mHasAnisotropic = FALSE;
00560         mHasCubeMap = FALSE;
00561         mHasOcclusionQuery = FALSE;
00562         mHasPointParameters = FALSE;
00563         mHasShaderObjects = FALSE;
00564         mHasVertexShader = FALSE;
00565         mHasFragmentShader = FALSE;
00566 #else // LL_MESA_HEADLESS
00567         mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
00568         mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
00569         mHasPalettedTextures = glh_init_extension("GL_EXT_paletted_texture");
00570         mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
00571         mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
00572         glh_init_extensions("GL_ARB_texture_cube_map");
00573         mHasCubeMap = ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
00574         mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
00575         mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
00576         mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
00577         mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
00578         // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
00579         mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
00580                 && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
00581 #if !LL_DARWIN
00582         mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
00583 #endif
00584         mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
00585         mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
00586                                                 && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
00587         mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
00588 #endif
00589 
00590 #if LL_LINUX
00591         // Our extension support for the Linux Client is very young with some
00592         // potential driver gotchas, so offer a semi-secret way to turn it off.
00593         if (getenv("LL_GL_NOEXT"))      /* Flawfinder: ignore */
00594         {
00595                 //mHasMultitexture = FALSE; // NEEDED!
00596                 mHasARBEnvCombine = FALSE;
00597                 mHasCompressedTextures = FALSE;
00598                 mHasVertexBufferObject = FALSE;
00599                 mHasFramebufferObject = FALSE;
00600                 mHasMipMapGeneration = FALSE;
00601                 mHasPalettedTextures = FALSE;
00602                 mHasSeparateSpecularColor = FALSE;
00603                 mHasAnisotropic = FALSE;
00604                 mHasCubeMap = FALSE;
00605                 mHasOcclusionQuery = FALSE;
00606                 mHasPointParameters = FALSE;
00607                 mHasShaderObjects = FALSE;
00608                 mHasVertexShader = FALSE;
00609                 mHasFragmentShader = FALSE;
00610                 LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL;
00611         }
00612         else if (getenv("LL_GL_BASICEXT"))      /* Flawfinder: ignore */
00613         {
00614                 // This switch attempts to turn off all support for exotic
00615                 // extensions which I believe correspond to fatal driver
00616                 // bug reports.  This should be the default until we get a
00617                 // proper blacklist/whitelist on Linux.
00618                 mHasMipMapGeneration = FALSE;
00619                 mHasPalettedTextures = FALSE;
00620                 mHasAnisotropic = FALSE;
00621                 //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
00622                 //mHasOcclusionQuery = FALSE; // source of many ATI system hangs
00623                 mHasShaderObjects = FALSE;
00624                 mHasVertexShader = FALSE;
00625                 mHasFragmentShader = FALSE;
00626                 LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
00627         }
00628         if (getenv("LL_GL_BLACKLIST"))  /* Flawfinder: ignore */
00629         {
00630                 // This lets advanced troubleshooters disable specific
00631                 // GL extensions to isolate problems with their hardware.
00632                 // SL-28126
00633                 const char *const blacklist = getenv("LL_GL_BLACKLIST");        /* Flawfinder: ignore */
00634                 LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL;
00635                 if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE;
00636                 if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE;
00637                 if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE;
00638                 if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
00639                 if (strchr(blacklist,'e')) mHasPalettedTextures = FALSE;//S
00640 //              if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
00641 //              if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
00642                 if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
00643                 if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S
00644                 if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
00645 //              if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
00646                 if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
00647                 if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S
00648                 if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S
00649                 if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
00650                 if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
00651                 if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
00652         }
00653 #endif // LL_LINUX
00654 
00655 #if LL_DARWIN || LL_LINUX
00656         // MBW -- 12/4/2003 -- Using paletted textures causes a bunch of avatar rendering problems on the Mac.
00657         // Not sure if this is due to driver problems or incorrect use of the extension, but I'm disabling it for now.
00658         // Tofu - 2006-10-03 -- Same problem on Linux.
00659         mHasPalettedTextures = false;
00660 #endif
00661         
00662         if (!mHasMultitexture)
00663         {
00664                 LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL;
00665         }
00666         if (!mHasMipMapGeneration)
00667         {
00668                 LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL;
00669         }
00670         if (!mHasARBEnvCombine)
00671         {
00672                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL;
00673         }
00674         if (!mHasPalettedTextures)
00675         {
00676                 LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_paletted_texture" << LL_ENDL;
00677         }
00678         if (!mHasSeparateSpecularColor)
00679         {
00680                 LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL;
00681         }
00682         if (!mHasAnisotropic)
00683         {
00684                 LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL;
00685         }
00686         if (!mHasCompressedTextures)
00687         {
00688                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL;
00689         }
00690         if (!mHasOcclusionQuery)
00691         {
00692                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL;
00693         }
00694         if (!mHasPointParameters)
00695         {
00696                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
00697         }
00698         if (!mHasShaderObjects)
00699         {
00700                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL;
00701         }
00702         if (!mHasVertexShader)
00703         {
00704                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL;
00705         }
00706         if (!mHasFragmentShader)
00707         {
00708                 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
00709         }
00710 
00711         // Disable certain things due to known bugs
00712         if (mIsIntel && mHasMipMapGeneration)
00713         {
00714                 LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL;
00715                 mHasMipMapGeneration = FALSE;
00716         }
00717         if (mIsATI && mHasMipMapGeneration)
00718         {
00719                 LL_INFOS("RenderInit") << "Disabling mip-map generation for ATI GPUs (performance opt)" << LL_ENDL;
00720                 mHasMipMapGeneration = FALSE;
00721         }
00722         
00723         // Misc
00724         glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
00725         glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
00726         
00727 #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
00728         LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
00729         if (mHasVertexBufferObject)
00730         {
00731                 glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferARB");
00732                 if (glBindBufferARB)
00733                 {
00734                         glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffersARB");
00735                         glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffersARB");
00736                         glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBufferARB");
00737                         glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferDataARB");
00738                         glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubDataARB");
00739                         glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubDataARB");
00740                         glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferARB");
00741                         glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBufferARB");
00742                         glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameterivARB");
00743                         glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointervARB");
00744                 }
00745                 else
00746                 {
00747                         mHasVertexBufferObject = FALSE;
00748                 }
00749         }
00750         if (mHasFramebufferObject)
00751         {
00752                 glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsRenderbufferEXT");
00753                 glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindRenderbufferEXT");
00754                 glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffersEXT");
00755                 glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffersEXT");
00756                 glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageEXT");
00757                 glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameterivEXT");
00758                 glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsFramebufferEXT");
00759                 glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindFramebufferEXT");
00760                 glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffersEXT");
00761                 glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffersEXT");
00762                 glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatusEXT");
00763                 glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1DEXT");
00764                 glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2DEXT");
00765                 glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3DEXT");
00766                 glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbufferEXT");
00767                 glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
00768                 glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
00769         }
00770 #if !LL_LINUX
00771         // This is expected to be a static symbol on Linux GL implementations
00772         glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
00773         if (!glDrawRangeElements)
00774         {
00775                 mGLMaxVertexRange = 0;
00776                 mGLMaxIndexRange = 0;
00777         }
00778 #endif // !LL_LINUX
00779 #if LL_LINUX
00780         // On Linux we need to get glColorTableEXT dynamically.
00781         if (mHasPalettedTextures)
00782         {
00783                 glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableEXT");
00784         }
00785 #endif // LL_LINUX
00786         if (mHasOcclusionQuery)
00787         {
00788                 glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
00789                 glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueriesARB");
00790                 glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQueryARB");
00791                 glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryARB");
00792                 glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryARB");
00793                 glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryivARB");
00794                 glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
00795                 glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
00796         }
00797         if (mHasPointParameters)
00798         {
00799                 glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
00800                 glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
00801         }
00802         if (mHasShaderObjects)
00803         {
00804                 glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
00805                 glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
00806                 glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
00807                 glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
00808                 glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
00809                 glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
00810                 glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
00811                 glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
00812                 glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
00813                 glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
00814                 glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
00815                 glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
00816                 glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
00817                 glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
00818                 glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
00819                 glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
00820                 glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
00821                 glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
00822                 glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
00823                 glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
00824                 glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
00825                 glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
00826                 glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
00827                 glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
00828                 glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
00829                 glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
00830                 glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
00831                 glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
00832                 glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
00833                 glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
00834                 glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
00835                 glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
00836                 glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
00837                 glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
00838                 glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
00839                 glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
00840                 glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
00841                 glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
00842                 glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
00843         }
00844         if (mHasVertexShader)
00845         {
00846                 glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
00847                 glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
00848                 glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
00849                 glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
00850                 glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
00851                 glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
00852                 glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
00853                 glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
00854                 glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
00855                 glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
00856                 glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
00857                 glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
00858                 glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
00859                 glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
00860                 glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
00861                 glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
00862                 glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
00863                 glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
00864                 glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
00865                 glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
00866                 glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
00867                 glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
00868                 glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
00869                 glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
00870                 glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
00871                 glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
00872                 glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
00873                 glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
00874                 glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
00875                 glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
00876                 glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
00877                 glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
00878                 glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
00879                 glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
00880                 glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
00881                 glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
00882                 glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
00883                 glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
00884                 glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
00885                 glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
00886                 glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
00887                 glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
00888                 glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
00889                 glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
00890                 glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
00891                 glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
00892                 glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
00893                 glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
00894                 glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
00895                 glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
00896                 glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
00897                 glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
00898                 glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
00899                 glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
00900                 glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
00901                 glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
00902                 glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
00903                 glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
00904                 glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
00905                 glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
00906                 glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
00907                 glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
00908                 glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
00909                 glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
00910                 glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
00911         }
00912         LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
00913 #endif
00914 
00915         mInited = TRUE;
00916 }
00917 
00918 void rotate_quat(LLQuaternion& rotation)
00919 {
00920         F32 angle_radians, x, y, z;
00921         rotation.getAngleAxis(&angle_radians, &x, &y, &z);
00922         glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
00923 }
00924 
00925 void flush_glerror()
00926 {
00927         glGetError();
00928 }
00929 
00930 void assert_glerror()
00931 {
00932         if (gNoRender || !gDebugGL) 
00933         {
00934                 return;
00935         }
00936         if (!gGLManager.mInited)
00937         {
00938                 LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
00939         }
00940         //  Create or update texture to be used with this data 
00941         GLenum error;
00942         error = glGetError();
00943         if (error)
00944         {
00945 #ifndef LL_LINUX // *FIX: !  This should be an error for linux as well.
00946                 GLubyte const * gl_error_msg = gluErrorString(error);
00947                 if (NULL != gl_error_msg)
00948                 {
00949                         LL_ERRS("RenderState") << "GL Error:" << gl_error_msg << LL_ENDL;
00950                 }
00951                 else
00952                 {
00953                         // gluErrorString returns NULL for some extensions' error codes.
00954                         // you'll probably have to grep for the number in glext.h.
00955                         LL_ERRS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << LL_ENDL;
00956                 }
00957 #endif
00958         }
00959 }
00960 
00961 void clear_glerror()
00962 {
00963         //  Create or update texture to be used with this data 
00964         GLenum error;
00965         error = glGetError();
00966 }
00967 
00969 //
00970 // LLGLState
00971 //
00972 
00973 // Static members
00974 std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
00975 
00976 GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
00977 GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
00978 GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
00979 
00980 //static
00981 void LLGLState::initClass() 
00982 {
00983         sStateMap[GL_DITHER] = GL_TRUE;
00984         sStateMap[GL_TEXTURE_2D] = GL_TRUE;
00985 }
00986 
00987 //static
00988 void LLGLState::restoreGL()
00989 {
00990         sStateMap.clear();
00991         initClass();
00992 }
00993 
00994 //static
00995 // Really shouldn't be needed, but seems we sometimes do.
00996 void LLGLState::resetTextureStates()
00997 {
00998         gGL.flush();
00999         GLint maxTextureUnits;
01000         
01001         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
01002         for (S32 j = maxTextureUnits-1; j >=0; j--)
01003         {
01004                 glActiveTextureARB(GL_TEXTURE0_ARB+j);
01005                 glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
01006                 j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D);
01007         }
01008 }
01009 
01010 void LLGLState::dumpStates() 
01011 {
01012         LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
01013         for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
01014                  iter != sStateMap.end(); ++iter)
01015         {
01016                 LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
01017         }
01018 }
01019 
01020 void LLGLState::checkStates()  
01021 {
01022         if (!gDebugGL)
01023         {
01024                 return;
01025         }
01026 
01027         stop_glerror();
01028 
01029         GLint activeTexture;
01030         glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
01031         
01032         if (activeTexture != GL_TEXTURE0_ARB)
01033         {
01034                 LL_GL_ERRS << "Texture channel corrupted. " << LL_ENDL;
01035         }
01036         
01037         GLint src;
01038         GLint dst;
01039         glGetIntegerv(GL_BLEND_SRC, &src);
01040         glGetIntegerv(GL_BLEND_DST, &dst);
01041         
01042         if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
01043         {
01044                 LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << LL_ENDL;
01045         }
01046         
01047         for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
01048                  iter != sStateMap.end(); ++iter)
01049         {
01050                 LLGLenum state = iter->first;
01051                 LLGLboolean cur_state = iter->second;
01052                 LLGLboolean gl_state = glIsEnabled(state);
01053                 if(cur_state != gl_state)
01054                 {
01055                         dumpStates();
01056                         LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
01057                 }
01058         }
01059         
01060         stop_glerror();
01061 }
01062 
01063 void LLGLState::checkTextureChannels()
01064 {
01065         if (!gDebugGL)
01066         {
01067                 return;
01068         }
01069 
01070         GLint activeTexture;
01071         glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
01072         
01073         BOOL error = FALSE;
01074 
01075         if (activeTexture != GL_TEXTURE0_ARB)
01076         {
01077                 error = TRUE;
01078                 LL_WARNS("RenderState") << "Active texture channel corrupted. " << LL_ENDL;
01079         }
01080         else if (!glIsEnabled(GL_TEXTURE_2D))
01081         {
01082                 error = TRUE;
01083                 LL_WARNS("RenderState") << "GL_TEXTURE_2D not enabled on texture channel 0." << LL_ENDL;
01084         }
01085         else 
01086         {
01087                 GLint tex_env_mode = 0;
01088 
01089                 glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
01090                 if (tex_env_mode != GL_MODULATE)
01091                 {
01092                         error = TRUE;
01093                         LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << LL_ENDL;
01094                 }
01095         }
01096 
01097         GLint maxTextureUnits;
01098         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
01099 
01100         static const char* label[] =
01101         {
01102                 "GL_TEXTURE_2D",
01103                 "GL_TEXTURE_COORD_ARRAY",
01104                 "GL_TEXTURE_1D",
01105                 "GL_TEXTURE_CUBE_MAP_ARB",
01106                 "GL_TEXTURE_GEN_S",
01107                 "GL_TEXTURE_GEN_T",
01108                 "GL_TEXTURE_GEN_Q",
01109                 "GL_TEXTURE_GEN_R"
01110         };
01111 
01112         static GLint value[] =
01113         {
01114                 GL_TEXTURE_2D,
01115                 GL_TEXTURE_COORD_ARRAY,
01116                 GL_TEXTURE_1D,
01117                 GL_TEXTURE_CUBE_MAP_ARB,
01118                 GL_TEXTURE_GEN_S,
01119                 GL_TEXTURE_GEN_T,
01120                 GL_TEXTURE_GEN_Q,
01121                 GL_TEXTURE_GEN_R
01122         };
01123 
01124         GLint stackDepth = 0;
01125         LLMatrix4 identity;
01126         LLMatrix4 matrix;
01127 
01128         for (GLint i = 0; i < maxTextureUnits; i++)
01129         {
01130                 glActiveTextureARB(GL_TEXTURE0_ARB+i);
01131                 glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
01132 
01133                 glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
01134 
01135                 if (stackDepth != 1)
01136                 {
01137                         error = TRUE;
01138                         LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
01139                 }
01140 
01141                 glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
01142 
01143                 if (matrix != identity)
01144                 {
01145                         error = TRUE;
01146                         LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
01147                 }
01148 
01149                 for (S32 j = (i == 0 ? 1 : 0); j < 8; j++)
01150                 {
01151                         if (glIsEnabled(value[j]))
01152                         {
01153                                 error = TRUE;
01154                                 LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
01155                         }
01156                 }
01157         }
01158 
01159         glActiveTextureARB(GL_TEXTURE0_ARB);
01160         glClientActiveTextureARB(GL_TEXTURE0_ARB);
01161 
01162         if (error)
01163         {
01164                 LL_GL_ERRS << "GL texture state corruption detected." << LL_ENDL;
01165         }
01166 }
01167 
01168 void LLGLState::checkClientArrays(U32 data_mask)
01169 {
01170         if (!gDebugGL)
01171         {
01172                 return;
01173         }
01174 
01175         stop_glerror();
01176         BOOL error = FALSE;
01177 
01178         GLint active_texture;
01179         glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &active_texture);
01180 
01181         if (active_texture != GL_TEXTURE0_ARB)
01182         {
01183                 llwarns << "Client active texture corrupted: " << active_texture << llendl;
01184                 error = TRUE;
01185         }
01186 
01187         glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
01188         if (active_texture != GL_TEXTURE0_ARB)
01189         {
01190                 llwarns << "Active texture corrupted: " << active_texture << llendl;
01191                 error = TRUE;
01192         }
01193 
01194         static const char* label[] =
01195         {
01196                 "GL_VERTEX_ARRAY",
01197                 "GL_NORMAL_ARRAY",
01198                 "GL_COLOR_ARRAY",
01199                 "GL_TEXTURE_COORD_ARRAY"
01200         };
01201 
01202         static GLint value[] =
01203         {
01204                 GL_VERTEX_ARRAY,
01205                 GL_NORMAL_ARRAY,
01206                 GL_COLOR_ARRAY,
01207                 GL_TEXTURE_COORD_ARRAY
01208         };
01209 
01210          U32 mask[] = 
01211         { //copied from llvertexbuffer.h
01212                 0x0001, //MAP_VERTEX,
01213                 0x0002, //MAP_NORMAL,
01214                 0x0010, //MAP_COLOR,
01215                 0x0004, //MAP_TEXCOORD
01216         };
01217 
01218 
01219         for (S32 j = 0; j < 4; j++)
01220         {
01221                 if (glIsEnabled(value[j]))
01222                 {
01223                         if (!(mask[j] & data_mask))
01224                         {
01225                                 error = TRUE;
01226                                 LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
01227                         }
01228                 }
01229                 else
01230                 {
01231                         if (mask[j] & data_mask)
01232                         {
01233                                 error = TRUE;
01234                                 LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
01235                         }
01236                 }
01237         }
01238 
01239         glClientActiveTextureARB(GL_TEXTURE1_ARB);
01240         glActiveTextureARB(GL_TEXTURE1_ARB);
01241         if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
01242         {
01243                 if (!(data_mask & 0x0008))
01244                 {
01245                         error = TRUE;
01246                         LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
01247                 }
01248         }
01249         else
01250         {
01251                 if (data_mask & 0x0008)
01252                 {
01253                         error = TRUE;
01254                         LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
01255                 }
01256         }
01257 
01258         if (glIsEnabled(GL_TEXTURE_2D))
01259         {
01260                 if (!(data_mask & 0x0008))
01261                 {
01262                         error = TRUE;
01263                         LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
01264                 }
01265         }
01266         else
01267         {
01268                 if (data_mask & 0x0008)
01269                 {
01270                         error = TRUE;
01271                         LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
01272                 }
01273         }
01274 
01275         glClientActiveTextureARB(GL_TEXTURE0_ARB);
01276         glActiveTextureARB(GL_TEXTURE0_ARB);
01277 
01278         if (error)
01279         {
01280                 LL_GL_ERRS << "GL client array corruption detected." << LL_ENDL;
01281         }
01282 }
01283 
01285 
01286 LLGLState::LLGLState(LLGLenum state, S32 enabled) :
01287         mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
01288 {
01289         stop_glerror();
01290         if (state)
01291         {
01292                 mWasEnabled = sStateMap[state];
01293                 llassert(mWasEnabled == glIsEnabled(state));
01294                 setEnabled(enabled);
01295                 stop_glerror();
01296         }
01297 }
01298 
01299 void LLGLState::setEnabled(S32 enabled)
01300 {
01301         if (!mState)
01302         {
01303                 return;
01304         }
01305         if (enabled == CURRENT_STATE)
01306         {
01307                 enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
01308         }
01309         else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
01310         {
01311                 gGL.flush();
01312                 glEnable(mState);
01313                 sStateMap[mState] = GL_TRUE;
01314         }
01315         else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
01316         {
01317                 gGL.flush();
01318                 glDisable(mState);
01319                 sStateMap[mState] = GL_FALSE;
01320         }
01321         mIsEnabled = enabled;
01322 }
01323 
01324 LLGLState::~LLGLState() 
01325 {
01326         stop_glerror();
01327         if (mState)
01328         {
01329                 if (gDebugGL)
01330                 {
01331                         llassert_always(sStateMap[mState] == glIsEnabled(mState));
01332                 }
01333 
01334                 if (mIsEnabled != mWasEnabled)
01335                 {
01336                         gGL.flush();
01337                         if (mWasEnabled)
01338                         {
01339                                 glEnable(mState);
01340                                 sStateMap[mState] = GL_TRUE;
01341                         }
01342                         else
01343                         {
01344                                 glDisable(mState);
01345                                 sStateMap[mState] = GL_FALSE;
01346                         }
01347                 }
01348         }
01349         stop_glerror();
01350 }
01351 
01353 
01354 void LLGLManager::initGLStates()
01355 {
01356         //gl states moved to classes in llglstates.h
01357         LLGLState::initClass();
01358 }
01359 
01361 
01362 void enable_vertex_weighting(const S32 index)
01363 {
01364 #if GL_ARB_vertex_program
01365         if (index > 0) glEnableVertexAttribArrayARB(index);     // vertex weights
01366 #endif
01367 }
01368 
01369 void disable_vertex_weighting(const S32 index)
01370 {
01371 #if GL_ARB_vertex_program
01372         if (index > 0) glDisableVertexAttribArrayARB(index);    // vertex weights
01373 #endif
01374 }
01375 
01376 void enable_binormals(const S32 index)
01377 {
01378 #if GL_ARB_vertex_program
01379         if (index > 0)
01380         {
01381                 glEnableVertexAttribArrayARB(index);    // binormals
01382         }
01383 #endif
01384 }
01385 
01386 void disable_binormals(const S32 index)
01387 {
01388 #if GL_ARB_vertex_program
01389         if (index > 0)
01390         {
01391                 glDisableVertexAttribArrayARB(index);   // binormals
01392         }
01393 #endif
01394 }
01395 
01396 
01397 void enable_cloth_weights(const S32 index)
01398 {
01399 #if GL_ARB_vertex_program
01400         if (index > 0)  glEnableVertexAttribArrayARB(index);
01401 #endif
01402 }
01403 
01404 void disable_cloth_weights(const S32 index)
01405 {
01406 #if GL_ARB_vertex_program
01407         if (index > 0) glDisableVertexAttribArrayARB(index);
01408 #endif
01409 }
01410 
01411 void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights)
01412 {
01413 #if GL_ARB_vertex_program
01414         if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights);
01415         stop_glerror();
01416 #endif
01417 }
01418 
01419 void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
01420 {
01421 #if GL_ARB_vertex_program
01422         if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
01423         stop_glerror();
01424 #endif
01425 }
01426 
01427 void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
01428 {
01429 #if GL_ARB_vertex_program
01430         if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
01431         stop_glerror();
01432 #endif
01433 }
01434 
01435 
01436 void set_palette(U8 *palette_data)
01437 {
01438         if (gGLManager.mHasPalettedTextures)
01439         {
01440                 glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette_data);
01441         }
01442 }
01443 
01444 
01445 void parse_gl_version( S32* major, S32* minor, S32* release, LLString* vendor_specific )
01446 {
01447         // GL_VERSION returns a null-terminated string with the format: 
01448         // <major>.<minor>[.<release>] [<vendor specific>]
01449 
01450         const char* version = (const char*) glGetString(GL_VERSION);
01451         *major = 0;
01452         *minor = 0;
01453         *release = 0;
01454         vendor_specific->assign("");
01455 
01456         if( !version )
01457         {
01458                 return;
01459         }
01460 
01461         LLString ver_copy( version );
01462         S32 len = (S32)strlen( version );       /* Flawfinder: ignore */
01463         S32 i = 0;
01464         S32 start;
01465         // Find the major version
01466         start = i;
01467         for( ; i < len; i++ )
01468         {
01469                 if( '.' == version[i] )
01470                 {
01471                         break;
01472                 }
01473         }
01474         LLString major_str = ver_copy.substr(start,i-start);
01475         LLString::convertToS32(major_str, *major);
01476 
01477         if( '.' == version[i] )
01478         {
01479                 i++;
01480         }
01481 
01482         // Find the minor version
01483         start = i;
01484         for( ; i < len; i++ )
01485         {
01486                 if( ('.' == version[i]) || isspace(version[i]) )
01487                 {
01488                         break;
01489                 }
01490         }
01491         LLString minor_str = ver_copy.substr(start,i-start);
01492         LLString::convertToS32(minor_str, *minor);
01493 
01494         // Find the release number (optional)
01495         if( '.' == version[i] )
01496         {
01497                 i++;
01498 
01499                 start = i;
01500                 for( ; i < len; i++ )
01501                 {
01502                         if( isspace(version[i]) )
01503                         {
01504                                 break;
01505                         }
01506                 }
01507 
01508                 LLString release_str = ver_copy.substr(start,i-start);
01509                 LLString::convertToS32(release_str, *release);
01510         }
01511 
01512         // Skip over any white space
01513         while( version[i] && isspace( version[i] ) )
01514         {
01515                 i++;
01516         }
01517 
01518         // Copy the vendor-specific string (optional)
01519         if( version[i] )
01520         {
01521                 vendor_specific->assign( version + i );
01522         }
01523 }
01524 
01525 LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection)
01526 {
01527         mModelview = modelview;
01528         mProjection = projection;
01529 
01530         setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]);
01531 }
01532 
01533 void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
01534 {
01535         glh::matrix4f& P = mProjection;
01536         glh::matrix4f& M = mModelview;
01537     
01538         glh::matrix4f invtrans_MVP = (P * M).inverse().transpose();
01539     glh::vec4f oplane(a,b,c,d);
01540     glh::vec4f cplane;
01541     invtrans_MVP.mult_matrix_vec(oplane, cplane);
01542 
01543     cplane /= fabs(cplane[2]); // normalize such that depth is not scaled
01544     cplane[3] -= 1;
01545 
01546     if(cplane[2] < 0)
01547         cplane *= -1;
01548 
01549     glh::matrix4f suffix;
01550     suffix.set_row(2, cplane);
01551     glh::matrix4f newP = suffix * P;
01552     glMatrixMode(GL_PROJECTION);
01553         glPushMatrix();
01554     glLoadMatrixf(newP.m);
01555         gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
01556     glMatrixMode(GL_MODELVIEW);
01557 }
01558 
01559 LLGLUserClipPlane::~LLGLUserClipPlane()
01560 {
01561         glMatrixMode(GL_PROJECTION);
01562         glPopMatrix();
01563         glMatrixMode(GL_MODELVIEW);
01564 }
01565 
01566 LLGLNamePool::LLGLNamePool()
01567 {
01568 }
01569 
01570 void LLGLNamePool::registerPool(LLGLNamePool* pool)
01571 {
01572         pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool);
01573         if (iter == sInstances.end())
01574         {
01575                 sInstances.push_back(pool);
01576         }
01577 }
01578 
01579 LLGLNamePool::~LLGLNamePool()
01580 {
01581         pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
01582         if (iter != sInstances.end())
01583         {
01584                 sInstances.erase(iter);
01585         }
01586 }
01587 
01588 void LLGLNamePool::upkeep()
01589 {
01590         std::sort(mNameList.begin(), mNameList.end(), CompareUsed());
01591 }
01592 
01593 void LLGLNamePool::cleanup()
01594 {
01595         for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
01596         {
01597                 releaseName(iter->name);
01598         }
01599 
01600         mNameList.clear();
01601 }
01602 
01603 GLuint LLGLNamePool::allocate()
01604 {
01605         for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
01606         {
01607                 if (!iter->used)
01608                 {
01609                         iter->used = TRUE;
01610                         return iter->name;
01611                 }
01612         }
01613 
01614         NameEntry entry;
01615         entry.name = allocateName();
01616         entry.used = TRUE;
01617         mNameList.push_back(entry);
01618 
01619         return entry.name;
01620 }
01621 
01622 void LLGLNamePool::release(GLuint name)
01623 {
01624         for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
01625         {
01626                 if (iter->name == name)
01627                 {
01628                         iter->used = FALSE;
01629                         return;
01630                 }
01631         }
01632 }
01633 
01634 //static
01635 void LLGLNamePool::upkeepPools()
01636 {
01637         for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
01638         {
01639                 LLGLNamePool* pool = *iter;
01640                 pool->upkeep();
01641         }
01642 }
01643 
01644 //static
01645 void LLGLNamePool::cleanupPools()
01646 {
01647         for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
01648         {
01649                 LLGLNamePool* pool = *iter;
01650                 pool->cleanup();
01651         }
01652 }
01653 
01654 LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func)
01655 : mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
01656 {
01657         if (depth_enabled != sDepthEnabled)
01658         {
01659                 gGL.flush();
01660                 if (depth_enabled) glEnable(GL_DEPTH_TEST);
01661                 else glDisable(GL_DEPTH_TEST);
01662                 sDepthEnabled = depth_enabled;
01663         }
01664         if (depth_func != sDepthFunc)
01665         {
01666                 gGL.flush();
01667                 glDepthFunc(depth_func);
01668                 sDepthFunc = depth_func;
01669         }
01670         if (write_enabled != sWriteEnabled)
01671         {
01672                 gGL.flush();
01673                 glDepthMask(write_enabled);
01674                 sWriteEnabled = write_enabled;
01675         }
01676 }
01677 
01678 LLGLDepthTest::~LLGLDepthTest()
01679 {
01680         if (sDepthEnabled != mPrevDepthEnabled )
01681         {
01682                 gGL.flush();
01683                 if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST);
01684                 else glDisable(GL_DEPTH_TEST);
01685                 sDepthEnabled = mPrevDepthEnabled;
01686         }
01687         if (sDepthFunc != mPrevDepthFunc)
01688         {
01689                 gGL.flush();
01690                 glDepthFunc(mPrevDepthFunc);
01691                 sDepthFunc = mPrevDepthFunc;
01692         }
01693         if (sWriteEnabled != mPrevWriteEnabled )
01694         {
01695                 gGL.flush();
01696                 glDepthMask(mPrevWriteEnabled);
01697                 sWriteEnabled = mPrevWriteEnabled;
01698         }
01699 }
01700 
01701 LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
01702 {
01703         for (U32 i = 0; i < 4; i++)
01704         {
01705                 P.element(2, i) = P.element(3, i) * 0.99999f;
01706         }
01707 
01708         glMatrixMode(GL_PROJECTION);
01709         glPushMatrix();
01710         glLoadMatrixf(P.m);
01711         glMatrixMode(GL_MODELVIEW);
01712 }
01713 
01714 LLGLClampToFarClip::~LLGLClampToFarClip()
01715 {
01716         glMatrixMode(GL_PROJECTION);
01717         glPopMatrix();
01718         glMatrixMode(GL_MODELVIEW);
01719 }
01720 

Generated on Fri May 16 08:33:02 2008 for SecondLife by  doxygen 1.5.5