aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llgl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llrender/llgl.cpp')
-rw-r--r--linden/indra/llrender/llgl.cpp1763
1 files changed, 1763 insertions, 0 deletions
diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp
new file mode 100644
index 0000000..843bc79
--- /dev/null
+++ b/linden/indra/llrender/llgl.cpp
@@ -0,0 +1,1763 @@
1/**
2 * @file llgl.cpp
3 * @brief LLGL implementation
4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 *
7 * Copyright (c) 2001-2008, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32// This file sets some global GL parameters, and implements some
33// useful functions for GL operations.
34
35#define GLH_EXT_SINGLE_FILE
36
37#include "linden_common.h"
38
39#include "boost/tokenizer.hpp"
40
41#include "llsys.h"
42
43#include "llgl.h"
44#include "llrender.h"
45
46#include "llerror.h"
47#include "llquaternion.h"
48#include "llmath.h"
49#include "m4math.h"
50#include "llstring.h"
51
52#include "llglheaders.h"
53
54#ifdef _DEBUG
55//#define GL_STATE_VERIFY
56#endif
57
58BOOL gDebugGL = FALSE;
59BOOL gClothRipple = FALSE;
60BOOL gNoRender = FALSE;
61LLMatrix4 gGLObliqueProjectionInverse;
62
63#define LL_GL_NAME_POOLING 0
64
65LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
66
67#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
68// ATI prototypes
69// vertex blending prototypes
70PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL;
71PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL;
72PFNGLWEIGHTFVARBPROC glWeightfvARB = NULL;
73
74// Vertex buffer object prototypes
75PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
76PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
77PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
78PFNGLISBUFFERARBPROC glIsBufferARB = NULL;
79PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
80PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB = NULL;
81PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB = NULL;
82PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
83PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
84PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
85PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
86
87// vertex object prototypes
88PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL;
89PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL;
90PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI = NULL;
91PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI = NULL;
92PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI = NULL;
93PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI = NULL;
94PFNGLARRAYOBJECTATIPROC glArrayObjectATI = NULL;
95PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI = NULL;
96PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI = NULL;
97PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI = NULL;
98PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI = NULL;
99PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI = NULL;
100PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI = NULL;
101
102// GL_ARB_occlusion_query
103PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
104PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
105PFNGLISQUERYARBPROC glIsQueryARB = NULL;
106PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
107PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
108PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
109PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
110PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
111
112// GL_ARB_point_parameters
113PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
114PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
115
116// GL_EXT_framebuffer_object
117PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL;
118PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
119PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
120PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
121PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
122PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT = NULL;
123PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT = NULL;
124PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
125PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT = NULL;
126PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
127PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL;
128PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT = NULL;
129PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
130PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
131PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
132PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
133PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
134
135//shader object prototypes
136PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
137PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
138PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
139PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
140PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
141PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
142PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
143PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
144PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
145PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
146PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB = NULL;
147PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
148PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
149PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
150PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
151PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
152PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL;
153PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL;
154PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL;
155PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
156PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
157PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
158PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
159PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
160PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
161PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
162PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
163PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL;
164PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL;
165PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL;
166PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL;
167PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
168PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
169PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL;
170PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
171PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
172PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
173PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
174PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
175
176// vertex shader prototypes
177#if LL_LINUX
178PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
179PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
180PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
181PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB = NULL;
182PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB = NULL;
183PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB = NULL;
184PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB = NULL;
185PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB = NULL;
186PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB = NULL;
187PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB = NULL;
188PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB = NULL;
189PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB = NULL;
190PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB = NULL;
191PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB = NULL;
192PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
193PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
194PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
195PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
196#endif // LL_LINUX
197PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
198PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
199PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
200PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
201PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
202PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
203PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
204#if LL_LINUX
205PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
206PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
207PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
208PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB = NULL;
209PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB = NULL;
210PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB = NULL;
211PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB = NULL;
212PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB = NULL;
213PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
214PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
215PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
216PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
217PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
218PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
219PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
220PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
221PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL;
222PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
223PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB = NULL;
224PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB = NULL;
225PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB = NULL;
226PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = NULL;
227PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB = NULL;
228PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB = NULL;
229PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB = NULL;
230PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = NULL;
231PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB = NULL;
232PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB = NULL;
233PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB = NULL;
234PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB = NULL;
235PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = NULL;
236PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB = NULL;
237PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB = NULL;
238PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
239PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
240PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
241PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
242#endif // LL_LINUX
243PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
244PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
245PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
246
247#if LL_WINDOWS
248PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
249#endif
250
251#if LL_LINUX
252PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
253#endif // LL_LINUX
254
255#endif
256
257LLGLManager gGLManager;
258
259LLGLManager::LLGLManager() :
260 mInited(FALSE),
261 mIsDisabled(FALSE),
262
263 mHasMultitexture(FALSE),
264 mNumTextureUnits(1),
265 mHasMipMapGeneration(FALSE),
266 mHasPalettedTextures(FALSE),
267 mHasCompressedTextures(FALSE),
268 mHasFramebufferObject(FALSE),
269
270 mHasVertexBufferObject(FALSE),
271 mHasPBuffer(FALSE),
272 mHasShaderObjects(FALSE),
273 mHasVertexShader(FALSE),
274 mHasFragmentShader(FALSE),
275 mHasOcclusionQuery(FALSE),
276 mHasPointParameters(FALSE),
277
278 mHasAnisotropic(FALSE),
279 mHasARBEnvCombine(FALSE),
280 mHasCubeMap(FALSE),
281
282 mIsATI(FALSE),
283 mIsNVIDIA(FALSE),
284 mIsIntel(FALSE),
285 mIsGF2or4MX(FALSE),
286 mIsGF3(FALSE),
287 mIsGFFX(FALSE),
288 mATIOffsetVerticalLines(FALSE),
289 mATIOldDriver(FALSE),
290
291 mHasRequirements(TRUE),
292
293 mHasSeparateSpecularColor(FALSE),
294
295 mDriverVersionMajor(1),
296 mDriverVersionMinor(0),
297 mDriverVersionRelease(0),
298 mGLVersion(1.0f),
299
300 mVRAM(0),
301 mGLMaxVertexRange(0),
302 mGLMaxIndexRange(0)
303{
304}
305
306//---------------------------------------------------------------------
307// Global initialization for GL
308//---------------------------------------------------------------------
309void LLGLManager::initWGL()
310{
311 mHasPBuffer = FALSE;
312#if LL_WINDOWS && !LL_MESA_HEADLESS
313 if (!glh_init_extensions("WGL_ARB_pixel_format"))
314 {
315 LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
316 }
317
318 if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
319 {
320 GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
321 }
322
323 if( !glh_init_extensions("WGL_ARB_pbuffer") )
324 {
325 LL_WARNS("RenderInit") << "No ARB WGL PBuffer extensions" << LL_ENDL;
326 }
327
328 if( !glh_init_extensions("WGL_ARB_render_texture") )
329 {
330 LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
331 }
332
333 mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) &&
334 ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) &&
335 ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts);
336#endif
337}
338
339// return false if unable (or unwilling due to old drivers) to init GL
340bool LLGLManager::initGL()
341{
342 if (mInited)
343 {
344 LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
345 }
346
347 GLint alpha_bits;
348 glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
349 if( 8 != alpha_bits )
350 {
351 LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha. Avatar texture compositing will fail." << LL_ENDL;
352 }
353
354 // Extract video card strings and convert to upper case to
355 // work around driver-to-driver variation in capitalization.
356 mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
357 LLStringUtil::toUpper(mGLVendor);
358
359 mGLRenderer = std::string((const char *)glGetString(GL_RENDERER));
360 LLStringUtil::toUpper(mGLRenderer);
361
362 parse_gl_version( &mDriverVersionMajor,
363 &mDriverVersionMinor,
364 &mDriverVersionRelease,
365 &mDriverVersionVendorString );
366
367 mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
368
369 // Trailing space necessary to keep "nVidia Corpor_ati_on" cards
370 // from being recognized as ATI.
371 if (mGLVendor.substr(0,4) == "ATI ")
372 {
373 mGLVendorShort = "ATI";
374 BOOL mobile = FALSE;
375 if (mGLRenderer.find("MOBILITY") != std::string::npos)
376 {
377 mobile = TRUE;
378 }
379 mIsATI = TRUE;
380
381#if LL_WINDOWS && !LL_MESA_HEADLESS
382 if (mDriverVersionRelease < 3842)
383 {
384 mATIOffsetVerticalLines = TRUE;
385 }
386#endif // LL_WINDOWS
387
388#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
389 // release 7277 is a point at which we verify that ATI OpenGL
390 // drivers get pretty stable with SL, ~Catalyst 8.2,
391 // for both Win32 and Linux.
392 if (mDriverVersionRelease < 7277 &&
393 mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
394 {
395 mATIOldDriver = TRUE;
396 }
397#endif // (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
398 }
399 else if (mGLVendor.find("NVIDIA ") != std::string::npos)
400 {
401 mGLVendorShort = "NVIDIA";
402 mIsNVIDIA = TRUE;
403 if ( mGLRenderer.find("GEFORCE4 MX") != std::string::npos
404 || mGLRenderer.find("GEFORCE2") != std::string::npos
405 || mGLRenderer.find("GEFORCE 2") != std::string::npos
406 || mGLRenderer.find("GEFORCE4 460 GO") != std::string::npos
407 || mGLRenderer.find("GEFORCE4 440 GO") != std::string::npos
408 || mGLRenderer.find("GEFORCE4 420 GO") != std::string::npos)
409 {
410 mIsGF2or4MX = TRUE;
411 }
412 else if (mGLRenderer.find("GEFORCE FX") != std::string::npos
413 || mGLRenderer.find("QUADRO FX") != std::string::npos
414 || mGLRenderer.find("NV34") != std::string::npos)
415 {
416 mIsGFFX = TRUE;
417 }
418 else if(mGLRenderer.find("GEFORCE3") != std::string::npos)
419 {
420 mIsGF3 = TRUE;
421 }
422
423 }
424 else if (mGLVendor.find("INTEL") != std::string::npos
425#if LL_LINUX
426 // The Mesa-based drivers put this in the Renderer string,
427 // not the Vendor string.
428 || mGLRenderer.find("INTEL") != std::string::npos
429#endif //LL_LINUX
430 )
431 {
432 mGLVendorShort = "INTEL";
433 mIsIntel = TRUE;
434 }
435 else
436 {
437 mGLVendorShort = "MISC";
438 }
439
440 // This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
441 initExtensions();
442
443 if (mHasMultitexture)
444 {
445 GLint num_tex_units;
446 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
447 mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS);
448 if (mIsIntel)
449 {
450 mNumTextureUnits = llmin(mNumTextureUnits, 2);
451 }
452 }
453 else
454 {
455 mHasRequirements = FALSE;
456
457 // We don't support cards that don't support the GL_ARB_multitexture extension
458 LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL;
459 return false;
460 }
461
462
463 initGLStates();
464 return true;
465}
466
467void LLGLManager::getGLInfo(LLSD& info)
468{
469 info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
470 info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
471 info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
472
473#if !LL_MESA_HEADLESS
474 std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
475 boost::char_separator<char> sep(" ");
476 boost::tokenizer<boost::char_separator<char> > tok(all_exts, sep);
477 for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
478 {
479 info["GLInfo"]["GLExtensions"].append(*i);
480 }
481#endif
482}
483
484std::string LLGLManager::getGLInfoString()
485{
486 std::string info_str;
487 std::string all_exts, line;
488
489 info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
490 info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
491 info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
492
493#if !LL_MESA_HEADLESS
494 all_exts = (const char *)gGLHExts.mSysExts;
495 LLStringUtil::replaceChar(all_exts, ' ', '\n');
496 info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
497#endif
498
499 return info_str;
500}
501
502void LLGLManager::printGLInfoString()
503{
504 std::string info_str;
505 std::string all_exts, line;
506
507 LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
508 LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
509 LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
510
511#if !LL_MESA_HEADLESS
512 all_exts = std::string(gGLHExts.mSysExts);
513 LLStringUtil::replaceChar(all_exts, ' ', '\n');
514 LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
515#endif
516}
517
518std::string LLGLManager::getRawGLString()
519{
520 std::string gl_string;
521 gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
522 return gl_string;
523}
524
525void LLGLManager::shutdownGL()
526{
527 if (mInited)
528 {
529 glFinish();
530 stop_glerror();
531 mInited = FALSE;
532 }
533}
534
535// these are used to turn software blending on. They appear in the Debug/Avatar menu
536// presence of vertex skinning/blending or vertex programs will set these to FALSE by default.
537
538extern LLCPUInfo gSysCPU;
539
540void LLGLManager::initExtensions()
541{
542#if LL_MESA_HEADLESS
543# if GL_ARB_multitexture
544 mHasMultitexture = TRUE;
545# else
546 mHasMultitexture = FALSE;
547# endif
548# if GL_ARB_texture_env_combine
549 mHasARBEnvCombine = TRUE;
550# else
551 mHasARBEnvCombine = FALSE;
552# endif
553# if GL_ARB_texture_compression
554 mHasCompressedTextures = TRUE;
555# else
556 mHasCompressedTextures = FALSE;
557# endif
558# if GL_ARB_vertex_buffer_object
559 mHasVertexBufferObject = TRUE;
560# else
561 mHasVertexBufferObject = FALSE;
562# endif
563# if GL_EXT_framebuffer_object
564 mHasFramebufferObject = TRUE;
565# else
566 mHasFramebufferObject = FALSE;
567# endif
568 mHasMipMapGeneration = FALSE;
569 mHasPalettedTextures = FALSE;
570 mHasSeparateSpecularColor = FALSE;
571 mHasAnisotropic = FALSE;
572 mHasCubeMap = FALSE;
573 mHasOcclusionQuery = FALSE;
574 mHasPointParameters = FALSE;
575 mHasShaderObjects = FALSE;
576 mHasVertexShader = FALSE;
577 mHasFragmentShader = FALSE;
578#else // LL_MESA_HEADLESS
579 mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
580 mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
581 mHasPalettedTextures = glh_init_extension("GL_EXT_paletted_texture");
582 mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
583 mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
584 glh_init_extensions("GL_ARB_texture_cube_map");
585 mHasCubeMap = ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
586 mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
587 mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
588 mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
589 mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
590 // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
591 mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
592 && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
593#if !LL_DARWIN
594 mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
595#endif
596 mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
597 mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
598 && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
599 mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
600#endif
601
602#if LL_LINUX
603 // Our extension support for the Linux Client is very young with some
604 // potential driver gotchas, so offer a semi-secret way to turn it off.
605 if (getenv("LL_GL_NOEXT")) /* Flawfinder: ignore */
606 {
607 //mHasMultitexture = FALSE; // NEEDED!
608 mHasARBEnvCombine = FALSE;
609 mHasCompressedTextures = FALSE;
610 mHasVertexBufferObject = FALSE;
611 mHasFramebufferObject = FALSE;
612 mHasMipMapGeneration = FALSE;
613 mHasPalettedTextures = FALSE;
614 mHasSeparateSpecularColor = FALSE;
615 mHasAnisotropic = FALSE;
616 mHasCubeMap = FALSE;
617 mHasOcclusionQuery = FALSE;
618 mHasPointParameters = FALSE;
619 mHasShaderObjects = FALSE;
620 mHasVertexShader = FALSE;
621 mHasFragmentShader = FALSE;
622 LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL;
623 }
624 else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */
625 {
626 // This switch attempts to turn off all support for exotic
627 // extensions which I believe correspond to fatal driver
628 // bug reports. This should be the default until we get a
629 // proper blacklist/whitelist on Linux.
630 mHasMipMapGeneration = FALSE;
631 mHasPalettedTextures = FALSE;
632 mHasAnisotropic = FALSE;
633 //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
634 //mHasOcclusionQuery = FALSE; // source of many ATI system hangs
635 mHasShaderObjects = FALSE;
636 mHasVertexShader = FALSE;
637 mHasFragmentShader = FALSE;
638 LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
639 }
640 if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */
641 {
642 // This lets advanced troubleshooters disable specific
643 // GL extensions to isolate problems with their hardware.
644 // SL-28126
645 const char *const blacklist = getenv("LL_GL_BLACKLIST"); /* Flawfinder: ignore */
646 LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL;
647 if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE;
648 if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE;
649 if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE;
650 if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
651 if (strchr(blacklist,'e')) mHasPalettedTextures = FALSE;//S
652// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
653// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
654 if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
655 if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S
656 if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
657// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
658 if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
659 if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S
660 if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S
661 if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
662 if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
663 if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
664 }
665#endif // LL_LINUX
666
667#if LL_DARWIN || LL_LINUX
668 // MBW -- 12/4/2003 -- Using paletted textures causes a bunch of avatar rendering problems on the Mac.
669 // Not sure if this is due to driver problems or incorrect use of the extension, but I'm disabling it for now.
670 // Tofu - 2006-10-03 -- Same problem on Linux.
671 mHasPalettedTextures = false;
672#endif
673
674 if (!mHasMultitexture)
675 {
676 LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL;
677 }
678 if (!mHasMipMapGeneration)
679 {
680 LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL;
681 }
682 if (!mHasARBEnvCombine)
683 {
684 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL;
685 }
686 if (!mHasPalettedTextures)
687 {
688 LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_paletted_texture" << LL_ENDL;
689 }
690 if (!mHasSeparateSpecularColor)
691 {
692 LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL;
693 }
694 if (!mHasAnisotropic)
695 {
696 LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL;
697 }
698 if (!mHasCompressedTextures)
699 {
700 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL;
701 }
702 if (!mHasOcclusionQuery)
703 {
704 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL;
705 }
706 if (!mHasPointParameters)
707 {
708 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
709 }
710 if (!mHasShaderObjects)
711 {
712 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL;
713 }
714 if (!mHasVertexShader)
715 {
716 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL;
717 }
718 if (!mHasFragmentShader)
719 {
720 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
721 }
722
723 // Disable certain things due to known bugs
724 if (mIsIntel && mHasMipMapGeneration)
725 {
726 LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL;
727 mHasMipMapGeneration = FALSE;
728 }
729 if (mIsATI && mHasMipMapGeneration)
730 {
731 LL_INFOS("RenderInit") << "Disabling mip-map generation for ATI GPUs (performance opt)" << LL_ENDL;
732 mHasMipMapGeneration = FALSE;
733 }
734
735 // Misc
736 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
737 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
738
739#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
740 LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
741 if (mHasVertexBufferObject)
742 {
743 glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferARB");
744 if (glBindBufferARB)
745 {
746 glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffersARB");
747 glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffersARB");
748 glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBufferARB");
749 glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferDataARB");
750 glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubDataARB");
751 glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubDataARB");
752 glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferARB");
753 glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBufferARB");
754 glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameterivARB");
755 glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointervARB");
756 }
757 else
758 {
759 mHasVertexBufferObject = FALSE;
760 }
761 }
762 if (mHasFramebufferObject)
763 {
764 glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsRenderbufferEXT");
765 glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindRenderbufferEXT");
766 glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffersEXT");
767 glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffersEXT");
768 glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageEXT");
769 glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameterivEXT");
770 glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsFramebufferEXT");
771 glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindFramebufferEXT");
772 glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffersEXT");
773 glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffersEXT");
774 glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatusEXT");
775 glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1DEXT");
776 glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2DEXT");
777 glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3DEXT");
778 glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbufferEXT");
779 glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
780 glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
781 }
782#if !LL_LINUX
783 // This is expected to be a static symbol on Linux GL implementations
784 glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
785 if (!glDrawRangeElements)
786 {
787 mGLMaxVertexRange = 0;
788 mGLMaxIndexRange = 0;
789 }
790#endif // !LL_LINUX
791#if LL_LINUX
792 // On Linux we need to get glColorTableEXT dynamically.
793 if (mHasPalettedTextures)
794 {
795 glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableEXT");
796 }
797#endif // LL_LINUX
798 if (mHasOcclusionQuery)
799 {
800 glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
801 glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueriesARB");
802 glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQueryARB");
803 glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryARB");
804 glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryARB");
805 glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryivARB");
806 glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
807 glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
808 }
809 if (mHasPointParameters)
810 {
811 glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
812 glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
813 }
814 if (mHasShaderObjects)
815 {
816 glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
817 glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
818 glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
819 glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
820 glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
821 glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
822 glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
823 glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
824 glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
825 glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
826 glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
827 glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
828 glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
829 glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
830 glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
831 glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
832 glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
833 glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
834 glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
835 glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
836 glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
837 glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
838 glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
839 glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
840 glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
841 glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
842 glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
843 glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
844 glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
845 glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
846 glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
847 glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
848 glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
849 glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
850 glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
851 glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
852 glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
853 glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
854 glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
855 }
856 if (mHasVertexShader)
857 {
858 glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
859 glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
860 glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
861 glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
862 glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
863 glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
864 glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
865 glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
866 glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
867 glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
868 glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
869 glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
870 glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
871 glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
872 glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
873 glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
874 glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
875 glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
876 glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
877 glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
878 glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
879 glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
880 glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
881 glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
882 glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
883 glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
884 glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
885 glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
886 glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
887 glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
888 glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
889 glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
890 glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
891 glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
892 glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
893 glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
894 glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
895 glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
896 glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
897 glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
898 glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
899 glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
900 glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
901 glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
902 glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
903 glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
904 glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
905 glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
906 glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
907 glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
908 glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
909 glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
910 glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
911 glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
912 glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
913 glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
914 glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
915 glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
916 glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
917 glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
918 glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
919 glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
920 glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
921 glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
922 glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
923 }
924 LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
925#endif
926
927 mInited = TRUE;
928}
929
930void rotate_quat(LLQuaternion& rotation)
931{
932 F32 angle_radians, x, y, z;
933 rotation.getAngleAxis(&angle_radians, &x, &y, &z);
934 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
935}
936
937void flush_glerror()
938{
939 glGetError();
940}
941
942void assert_glerror()
943{
944 if (gNoRender || !gDebugGL)
945 {
946 return;
947 }
948 if (!gGLManager.mInited)
949 {
950 LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
951 }
952 // Create or update texture to be used with this data
953 GLenum error;
954 error = glGetError();
955 BOOL quit = FALSE;
956 while (error)
957 {
958 quit = TRUE;
959#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
960 GLubyte const * gl_error_msg = gluErrorString(error);
961 if (NULL != gl_error_msg)
962 {
963 LL_WARNS("RenderState") << "GL Error:" << gl_error_msg << LL_ENDL;
964 }
965 else
966 {
967 // gluErrorString returns NULL for some extensions' error codes.
968 // you'll probably have to grep for the number in glext.h.
969 LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << LL_ENDL;
970 }
971 error = glGetError();
972#endif
973 }
974
975 if (quit)
976 {
977 llerrs << "One or more unhandled GL errors." << llendl;
978 }
979}
980
981void clear_glerror()
982{
983 // Create or update texture to be used with this data
984 GLenum error;
985 error = glGetError();
986}
987
988///////////////////////////////////////////////////////////////
989//
990// LLGLState
991//
992
993// Static members
994std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
995
996GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
997GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
998GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
999
1000//static
1001void LLGLState::initClass()
1002{
1003 sStateMap[GL_DITHER] = GL_TRUE;
1004 sStateMap[GL_TEXTURE_2D] = GL_TRUE;
1005
1006 //make sure multisample defaults to disabled
1007 sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
1008 glDisable(GL_MULTISAMPLE_ARB);
1009
1010 //default vertex arrays to enabled.
1011 glEnableClientState(GL_VERTEX_ARRAY);
1012}
1013
1014//static
1015void LLGLState::restoreGL()
1016{
1017 sStateMap.clear();
1018 initClass();
1019}
1020
1021//static
1022// Really shouldn't be needed, but seems we sometimes do.
1023void LLGLState::resetTextureStates()
1024{
1025 gGL.flush();
1026 GLint maxTextureUnits;
1027
1028 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
1029 for (S32 j = maxTextureUnits-1; j >=0; j--)
1030 {
1031 gGL.getTexUnit(j)->activate();
1032 glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
1033 j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D);
1034 }
1035}
1036
1037void LLGLState::dumpStates()
1038{
1039 LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
1040 for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
1041 iter != sStateMap.end(); ++iter)
1042 {
1043 LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
1044 }
1045}
1046
1047void LLGLState::checkStates(const std::string& msg)
1048{
1049 if (!gDebugGL)
1050 {
1051 return;
1052 }
1053
1054 stop_glerror();
1055
1056 GLint activeTexture;
1057 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
1058
1059 if (activeTexture != GL_TEXTURE0_ARB)
1060 {
1061 LL_GL_ERRS << "Texture channel corrupted. " << LL_ENDL;
1062 }
1063
1064 GLint src;
1065 GLint dst;
1066 glGetIntegerv(GL_BLEND_SRC, &src);
1067 glGetIntegerv(GL_BLEND_DST, &dst);
1068
1069 if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
1070 {
1071 LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << LL_ENDL;
1072 }
1073
1074 for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
1075 iter != sStateMap.end(); ++iter)
1076 {
1077 LLGLenum state = iter->first;
1078 LLGLboolean cur_state = iter->second;
1079 LLGLboolean gl_state = glIsEnabled(state);
1080 if(cur_state != gl_state)
1081 {
1082 dumpStates();
1083 LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
1084 }
1085 }
1086
1087 stop_glerror();
1088}
1089
1090void LLGLState::checkTextureChannels(const std::string& msg)
1091{
1092 if (!gDebugGL)
1093 {
1094 return;
1095 }
1096
1097 GLint activeTexture;
1098 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
1099
1100 BOOL error = FALSE;
1101
1102 if (activeTexture != GL_TEXTURE0_ARB)
1103 {
1104 error = TRUE;
1105 LL_WARNS("RenderState") << "Active texture channel corrupted. " << LL_ENDL;
1106 }
1107 else if (!glIsEnabled(GL_TEXTURE_2D))
1108 {
1109 error = TRUE;
1110 LL_WARNS("RenderState") << "GL_TEXTURE_2D not enabled on texture channel 0." << LL_ENDL;
1111 }
1112 else
1113 {
1114 GLint tex_env_mode = 0;
1115
1116 glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
1117 if (tex_env_mode != GL_MODULATE)
1118 {
1119 error = TRUE;
1120 LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << LL_ENDL;
1121 }
1122 }
1123
1124 GLint maxTextureUnits;
1125 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
1126
1127 static const char* label[] =
1128 {
1129 "GL_TEXTURE_2D",
1130 "GL_TEXTURE_COORD_ARRAY",
1131 "GL_TEXTURE_1D",
1132 "GL_TEXTURE_CUBE_MAP_ARB",
1133 "GL_TEXTURE_GEN_S",
1134 "GL_TEXTURE_GEN_T",
1135 "GL_TEXTURE_GEN_Q",
1136 "GL_TEXTURE_GEN_R"
1137 };
1138
1139 static GLint value[] =
1140 {
1141 GL_TEXTURE_2D,
1142 GL_TEXTURE_COORD_ARRAY,
1143 GL_TEXTURE_1D,
1144 GL_TEXTURE_CUBE_MAP_ARB,
1145 GL_TEXTURE_GEN_S,
1146 GL_TEXTURE_GEN_T,
1147 GL_TEXTURE_GEN_Q,
1148 GL_TEXTURE_GEN_R
1149 };
1150
1151 GLint stackDepth = 0;
1152 LLMatrix4 identity;
1153 LLMatrix4 matrix;
1154
1155 for (GLint i = 0; i < maxTextureUnits; i++)
1156 {
1157 gGL.getTexUnit(i)->activate();
1158 glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
1159
1160 glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
1161
1162 if (stackDepth != 1)
1163 {
1164 error = TRUE;
1165 LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
1166 }
1167
1168 glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
1169
1170 if (matrix != identity)
1171 {
1172 error = TRUE;
1173 LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
1174 }
1175
1176 for (S32 j = (i == 0 ? 1 : 0); j < 8; j++)
1177 {
1178 if (glIsEnabled(value[j]))
1179 {
1180 error = TRUE;
1181 LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
1182 }
1183 }
1184 }
1185
1186 gGL.getTexUnit(0)->activate();
1187 glClientActiveTextureARB(GL_TEXTURE0_ARB);
1188
1189 if (error)
1190 {
1191 LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
1192 }
1193}
1194
1195void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
1196{
1197 if (!gDebugGL)
1198 {
1199 return;
1200 }
1201
1202 stop_glerror();
1203 BOOL error = FALSE;
1204
1205 GLint active_texture;
1206 glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &active_texture);
1207
1208 if (active_texture != GL_TEXTURE0_ARB)
1209 {
1210 llwarns << "Client active texture corrupted: " << active_texture << llendl;
1211 error = TRUE;
1212 }
1213
1214 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
1215 if (active_texture != GL_TEXTURE0_ARB)
1216 {
1217 llwarns << "Active texture corrupted: " << active_texture << llendl;
1218 error = TRUE;
1219 }
1220
1221 static const char* label[] =
1222 {
1223 "GL_VERTEX_ARRAY",
1224 "GL_NORMAL_ARRAY",
1225 "GL_COLOR_ARRAY",
1226 "GL_TEXTURE_COORD_ARRAY"
1227 };
1228
1229 static GLint value[] =
1230 {
1231 GL_VERTEX_ARRAY,
1232 GL_NORMAL_ARRAY,
1233 GL_COLOR_ARRAY,
1234 GL_TEXTURE_COORD_ARRAY
1235 };
1236
1237 U32 mask[] =
1238 { //copied from llvertexbuffer.h
1239 0x0001, //MAP_VERTEX,
1240 0x0002, //MAP_NORMAL,
1241 0x0010, //MAP_COLOR,
1242 0x0004, //MAP_TEXCOORD
1243 };
1244
1245
1246 for (S32 j = 0; j < 4; j++)
1247 {
1248 if (glIsEnabled(value[j]))
1249 {
1250 if (!(mask[j] & data_mask))
1251 {
1252 error = TRUE;
1253 LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
1254 }
1255 }
1256 else
1257 {
1258 if (mask[j] & data_mask)
1259 {
1260 error = TRUE;
1261 LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
1262 }
1263 }
1264 }
1265
1266 glClientActiveTextureARB(GL_TEXTURE1_ARB);
1267 gGL.getTexUnit(1)->activate();
1268 if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
1269 {
1270 if (!(data_mask & 0x0008))
1271 {
1272 error = TRUE;
1273 LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
1274 }
1275 }
1276 else
1277 {
1278 if (data_mask & 0x0008)
1279 {
1280 error = TRUE;
1281 LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
1282 }
1283 }
1284
1285 if (glIsEnabled(GL_TEXTURE_2D))
1286 {
1287 if (!(data_mask & 0x0008))
1288 {
1289 error = TRUE;
1290 LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
1291 }
1292 }
1293 else
1294 {
1295 if (data_mask & 0x0008)
1296 {
1297 error = TRUE;
1298 LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
1299 }
1300 }
1301
1302 glClientActiveTextureARB(GL_TEXTURE0_ARB);
1303 gGL.getTexUnit(0)->activate();
1304
1305 if (error)
1306 {
1307 LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
1308 }
1309}
1310
1311///////////////////////////////////////////////////////////////////////
1312
1313LLGLState::LLGLState(LLGLenum state, S32 enabled) :
1314 mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
1315{
1316 stop_glerror();
1317 if (state)
1318 {
1319 mWasEnabled = sStateMap[state];
1320 llassert(mWasEnabled == glIsEnabled(state));
1321 setEnabled(enabled);
1322 stop_glerror();
1323 }
1324}
1325
1326void LLGLState::setEnabled(S32 enabled)
1327{
1328 if (!mState)
1329 {
1330 return;
1331 }
1332 if (enabled == CURRENT_STATE)
1333 {
1334 enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
1335 }
1336 else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
1337 {
1338 gGL.flush();
1339 glEnable(mState);
1340 sStateMap[mState] = GL_TRUE;
1341 }
1342 else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
1343 {
1344 gGL.flush();
1345 glDisable(mState);
1346 sStateMap[mState] = GL_FALSE;
1347 }
1348 mIsEnabled = enabled;
1349}
1350
1351LLGLState::~LLGLState()
1352{
1353 stop_glerror();
1354 if (mState)
1355 {
1356 if (gDebugGL)
1357 {
1358 llassert_always(sStateMap[mState] == glIsEnabled(mState));
1359 }
1360
1361 if (mIsEnabled != mWasEnabled)
1362 {
1363 gGL.flush();
1364 if (mWasEnabled)
1365 {
1366 glEnable(mState);
1367 sStateMap[mState] = GL_TRUE;
1368 }
1369 else
1370 {
1371 glDisable(mState);
1372 sStateMap[mState] = GL_FALSE;
1373 }
1374 }
1375 }
1376 stop_glerror();
1377}
1378
1379////////////////////////////////////////////////////////////////////////////////
1380
1381void LLGLManager::initGLStates()
1382{
1383 //gl states moved to classes in llglstates.h
1384 LLGLState::initClass();
1385}
1386
1387////////////////////////////////////////////////////////////////////////////////
1388
1389void enable_vertex_weighting(const S32 index)
1390{
1391#if GL_ARB_vertex_program
1392 if (index > 0) glEnableVertexAttribArrayARB(index); // vertex weights
1393#endif
1394}
1395
1396void disable_vertex_weighting(const S32 index)
1397{
1398#if GL_ARB_vertex_program
1399 if (index > 0) glDisableVertexAttribArrayARB(index); // vertex weights
1400#endif
1401}
1402
1403void enable_binormals(const S32 index)
1404{
1405#if GL_ARB_vertex_program
1406 if (index > 0)
1407 {
1408 glEnableVertexAttribArrayARB(index); // binormals
1409 }
1410#endif
1411}
1412
1413void disable_binormals(const S32 index)
1414{
1415#if GL_ARB_vertex_program
1416 if (index > 0)
1417 {
1418 glDisableVertexAttribArrayARB(index); // binormals
1419 }
1420#endif
1421}
1422
1423
1424void enable_cloth_weights(const S32 index)
1425{
1426#if GL_ARB_vertex_program
1427 if (index > 0) glEnableVertexAttribArrayARB(index);
1428#endif
1429}
1430
1431void disable_cloth_weights(const S32 index)
1432{
1433#if GL_ARB_vertex_program
1434 if (index > 0) glDisableVertexAttribArrayARB(index);
1435#endif
1436}
1437
1438void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights)
1439{
1440#if GL_ARB_vertex_program
1441 if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights);
1442 stop_glerror();
1443#endif
1444}
1445
1446void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
1447{
1448#if GL_ARB_vertex_program
1449 if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
1450 stop_glerror();
1451#endif
1452}
1453
1454void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
1455{
1456#if GL_ARB_vertex_program
1457 if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
1458 stop_glerror();
1459#endif
1460}
1461
1462
1463void set_palette(U8 *palette_data)
1464{
1465 if (gGLManager.mHasPalettedTextures)
1466 {
1467 glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette_data);
1468 }
1469}
1470
1471
1472void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
1473{
1474 // GL_VERSION returns a null-terminated string with the format:
1475 // <major>.<minor>[.<release>] [<vendor specific>]
1476
1477 const char* version = (const char*) glGetString(GL_VERSION);
1478 *major = 0;
1479 *minor = 0;
1480 *release = 0;
1481 vendor_specific->assign("");
1482
1483 if( !version )
1484 {
1485 return;
1486 }
1487
1488 std::string ver_copy( version );
1489 S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
1490 S32 i = 0;
1491 S32 start;
1492 // Find the major version
1493 start = i;
1494 for( ; i < len; i++ )
1495 {
1496 if( '.' == version[i] )
1497 {
1498 break;
1499 }
1500 }
1501 std::string major_str = ver_copy.substr(start,i-start);
1502 LLStringUtil::convertToS32(major_str, *major);
1503
1504 if( '.' == version[i] )
1505 {
1506 i++;
1507 }
1508
1509 // Find the minor version
1510 start = i;
1511 for( ; i < len; i++ )
1512 {
1513 if( ('.' == version[i]) || isspace(version[i]) )
1514 {
1515 break;
1516 }
1517 }
1518 std::string minor_str = ver_copy.substr(start,i-start);
1519 LLStringUtil::convertToS32(minor_str, *minor);
1520
1521 // Find the release number (optional)
1522 if( '.' == version[i] )
1523 {
1524 i++;
1525
1526 start = i;
1527 for( ; i < len; i++ )
1528 {
1529 if( isspace(version[i]) )
1530 {
1531 break;
1532 }
1533 }
1534
1535 std::string release_str = ver_copy.substr(start,i-start);
1536 LLStringUtil::convertToS32(release_str, *release);
1537 }
1538
1539 // Skip over any white space
1540 while( version[i] && isspace( version[i] ) )
1541 {
1542 i++;
1543 }
1544
1545 // Copy the vendor-specific string (optional)
1546 if( version[i] )
1547 {
1548 vendor_specific->assign( version + i );
1549 }
1550}
1551
1552LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection)
1553{
1554 mModelview = modelview;
1555 mProjection = projection;
1556
1557 setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]);
1558}
1559
1560void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
1561{
1562 glh::matrix4f& P = mProjection;
1563 glh::matrix4f& M = mModelview;
1564
1565 glh::matrix4f invtrans_MVP = (P * M).inverse().transpose();
1566 glh::vec4f oplane(a,b,c,d);
1567 glh::vec4f cplane;
1568 invtrans_MVP.mult_matrix_vec(oplane, cplane);
1569
1570 cplane /= fabs(cplane[2]); // normalize such that depth is not scaled
1571 cplane[3] -= 1;
1572
1573 if(cplane[2] < 0)
1574 cplane *= -1;
1575
1576 glh::matrix4f suffix;
1577 suffix.set_row(2, cplane);
1578 glh::matrix4f newP = suffix * P;
1579 glMatrixMode(GL_PROJECTION);
1580 glPushMatrix();
1581 glLoadMatrixf(newP.m);
1582 gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
1583 glMatrixMode(GL_MODELVIEW);
1584}
1585
1586LLGLUserClipPlane::~LLGLUserClipPlane()
1587{
1588 glMatrixMode(GL_PROJECTION);
1589 glPopMatrix();
1590 glMatrixMode(GL_MODELVIEW);
1591}
1592
1593LLGLNamePool::LLGLNamePool()
1594{
1595}
1596
1597void LLGLNamePool::registerPool(LLGLNamePool* pool)
1598{
1599 pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool);
1600 if (iter == sInstances.end())
1601 {
1602 sInstances.push_back(pool);
1603 }
1604}
1605
1606LLGLNamePool::~LLGLNamePool()
1607{
1608 pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
1609 if (iter != sInstances.end())
1610 {
1611 sInstances.erase(iter);
1612 }
1613}
1614
1615void LLGLNamePool::upkeep()
1616{
1617 std::sort(mNameList.begin(), mNameList.end(), CompareUsed());
1618}
1619
1620void LLGLNamePool::cleanup()
1621{
1622 for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
1623 {
1624 releaseName(iter->name);
1625 }
1626
1627 mNameList.clear();
1628}
1629
1630GLuint LLGLNamePool::allocate()
1631{
1632#if LL_GL_NAME_POOLING
1633 for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
1634 {
1635 if (!iter->used)
1636 {
1637 iter->used = TRUE;
1638 return iter->name;
1639 }
1640 }
1641
1642 NameEntry entry;
1643 entry.name = allocateName();
1644 entry.used = TRUE;
1645 mNameList.push_back(entry);
1646
1647 return entry.name;
1648#else
1649 return allocateName();
1650#endif
1651}
1652
1653void LLGLNamePool::release(GLuint name)
1654{
1655#if LL_GL_NAME_POOLING
1656 for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
1657 {
1658 if (iter->name == name)
1659 {
1660 if (iter->used)
1661 {
1662 iter->used = FALSE;
1663 return;
1664 }
1665 else
1666 {
1667 llerrs << "Attempted to release a pooled name that is not in use!" << llendl;
1668 }
1669 }
1670 }
1671 llerrs << "Attempted to release a non pooled name!" << llendl;
1672#else
1673 releaseName(name);
1674#endif
1675}
1676
1677//static
1678void LLGLNamePool::upkeepPools()
1679{
1680 for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
1681 {
1682 LLGLNamePool* pool = *iter;
1683 pool->upkeep();
1684 }
1685}
1686
1687//static
1688void LLGLNamePool::cleanupPools()
1689{
1690 for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
1691 {
1692 LLGLNamePool* pool = *iter;
1693 pool->cleanup();
1694 }
1695}
1696
1697LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func)
1698: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
1699{
1700 if (depth_enabled != sDepthEnabled)
1701 {
1702 gGL.flush();
1703 if (depth_enabled) glEnable(GL_DEPTH_TEST);
1704 else glDisable(GL_DEPTH_TEST);
1705 sDepthEnabled = depth_enabled;
1706 }
1707 if (depth_func != sDepthFunc)
1708 {
1709 gGL.flush();
1710 glDepthFunc(depth_func);
1711 sDepthFunc = depth_func;
1712 }
1713 if (write_enabled != sWriteEnabled)
1714 {
1715 gGL.flush();
1716 glDepthMask(write_enabled);
1717 sWriteEnabled = write_enabled;
1718 }
1719}
1720
1721LLGLDepthTest::~LLGLDepthTest()
1722{
1723 if (sDepthEnabled != mPrevDepthEnabled )
1724 {
1725 gGL.flush();
1726 if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST);
1727 else glDisable(GL_DEPTH_TEST);
1728 sDepthEnabled = mPrevDepthEnabled;
1729 }
1730 if (sDepthFunc != mPrevDepthFunc)
1731 {
1732 gGL.flush();
1733 glDepthFunc(mPrevDepthFunc);
1734 sDepthFunc = mPrevDepthFunc;
1735 }
1736 if (sWriteEnabled != mPrevWriteEnabled )
1737 {
1738 gGL.flush();
1739 glDepthMask(mPrevWriteEnabled);
1740 sWriteEnabled = mPrevWriteEnabled;
1741 }
1742}
1743
1744LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
1745{
1746 for (U32 i = 0; i < 4; i++)
1747 {
1748 P.element(2, i) = P.element(3, i) * 0.99999f;
1749 }
1750
1751 glMatrixMode(GL_PROJECTION);
1752 glPushMatrix();
1753 glLoadMatrixf(P.m);
1754 glMatrixMode(GL_MODELVIEW);
1755}
1756
1757LLGLClampToFarClip::~LLGLClampToFarClip()
1758{
1759 glMatrixMode(GL_PROJECTION);
1760 glPopMatrix();
1761 glMatrixMode(GL_MODELVIEW);
1762}
1763