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

Generated on Thu Jul 1 06:08:39 2010 for Second Life Viewer by  doxygen 1.4.7