aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow/llgl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llwindow/llgl.cpp')
-rw-r--r--linden/indra/llwindow/llgl.cpp1378
1 files changed, 1378 insertions, 0 deletions
diff --git a/linden/indra/llwindow/llgl.cpp b/linden/indra/llwindow/llgl.cpp
new file mode 100644
index 0000000..547a353
--- /dev/null
+++ b/linden/indra/llwindow/llgl.cpp
@@ -0,0 +1,1378 @@
1/**
2 * @file llgl.cpp
3* @brief LLGL implementation
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// This file sets some global GL parameters, and implements some
29// useful functions for GL operations.
30
31#define GLH_EXT_SINGLE_FILE
32
33#include "linden_common.h"
34
35#include "llsys.h"
36
37#include "llgl.h"
38
39#include "llerror.h"
40#include "llquaternion.h"
41#include "llmath.h"
42#include "m4math.h"
43#include "llstring.h"
44
45#include "llglheaders.h"
46
47
48#if LL_LINUX && !LL_MESA_HEADLESS
49// The __APPLE__ hack is to make glh_extensions.h not symbol-clash horribly
50# define __APPLE__
51# include "GL/glh_extensions.h"
52# undef __APPLE__
53
54/* Although SDL very likely ends up calling glXGetProcAddress() itself,
55 if we do it ourselves then we avoid getting bogus addresses back on
56 some systems. Weird. */
57/*# include "SDL/SDL.h"
58 # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */
59#define GLX_GLXEXT_PROTOTYPES 1
60# include "GL/glx.h"
61# include "GL/glxext.h"
62// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol
63// is considered 'legacy' but works on more machines.
64# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p))
65#endif // LL_LINUX && !LL_MESA_HEADLESS
66
67
68#ifdef _DEBUG
69//#define GL_STATE_VERIFY
70#endif
71
72BOOL gClothRipple = FALSE;
73BOOL gNoRender = FALSE;
74
75
76#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
77// ATI prototypes
78// vertex blending prototypes
79PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL;
80PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL;
81PFNGLWEIGHTFVARBPROC glWeightfvARB = NULL;
82
83// Vertex buffer object prototypes
84PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
85PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
86PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
87PFNGLISBUFFERARBPROC glIsBufferARB = NULL;
88PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
89PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB = NULL;
90PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB = NULL;
91PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
92PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
93PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
94PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
95
96// vertex object prototypes
97PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL;
98PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL;
99PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI = NULL;
100PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI = NULL;
101PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI = NULL;
102PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI = NULL;
103PFNGLARRAYOBJECTATIPROC glArrayObjectATI = NULL;
104PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI = NULL;
105PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI = NULL;
106PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI = NULL;
107PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI = NULL;
108PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI = NULL;
109PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI = NULL;
110
111// GL_ARB_occlusion_query
112PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
113PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
114PFNGLISQUERYARBPROC glIsQueryARB = NULL;
115PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
116PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
117PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
118PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
119PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
120
121//shader object prototypes
122PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
123PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
124PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
125PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
126PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
127PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
128PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
129PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
130PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
131PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
132PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB = NULL;
133PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
134PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
135PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
136PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
137PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
138PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL;
139PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL;
140PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL;
141PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
142PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
143PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
144PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
145PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
146PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
147PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
148PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
149PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL;
150PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL;
151PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL;
152PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL;
153PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
154PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
155PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL;
156PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
157PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
158PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
159PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
160PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
161
162// vertex shader prototypes
163#if LL_LINUX
164PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
165PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
166PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
167PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB = NULL;
168PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB = NULL;
169PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB = NULL;
170PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB = NULL;
171PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB = NULL;
172PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB = NULL;
173PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB = NULL;
174PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB = NULL;
175PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB = NULL;
176PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB = NULL;
177PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB = NULL;
178PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
179PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
180PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
181PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
182#endif // LL_LINUX
183PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
184PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
185PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
186PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
187PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
188PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
189PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
190#if LL_LINUX
191PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
192PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
193PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
194PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB = NULL;
195PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB = NULL;
196PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB = NULL;
197PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB = NULL;
198PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB = NULL;
199PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
200PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
201PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
202PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
203PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
204PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
205PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
206PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
207PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL;
208PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
209PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB = NULL;
210PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB = NULL;
211PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB = NULL;
212PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = NULL;
213PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB = NULL;
214PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB = NULL;
215PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB = NULL;
216PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = NULL;
217PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB = NULL;
218PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB = NULL;
219PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB = NULL;
220PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB = NULL;
221PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = NULL;
222PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB = NULL;
223PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB = NULL;
224PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
225PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
226PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
227PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
228#endif // LL_LINUX
229PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
230PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
231PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
232
233#if LL_WINDOWS
234PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
235#endif
236
237#if LL_LINUX
238PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
239#endif // LL_LINUX
240
241#endif
242
243LLGLManager gGLManager;
244
245LLGLManager::LLGLManager()
246{
247 mInited = FALSE;
248 mIsDisabled = FALSE;
249 mHasCubeMap = FALSE;
250 mHasMultitexture = FALSE;
251 mHasAnyAGP = FALSE;
252 mHasMipMapGeneration = FALSE;
253 mHasAnisotropic = FALSE;
254 mHasCompressedTextures = FALSE;
255 mHasNVVertexArrayRange = FALSE;
256 mHasNVFence = FALSE;
257 mHasARBEnvCombine = FALSE;
258 mHasATIVAO = FALSE;
259 mIsRadeon8500 = FALSE;
260 mIsRadeon9700 = FALSE;
261 mIsMobilityRadeon9000 = FALSE;
262 mIsGF2or4MX = FALSE;
263 mIsGF3 = FALSE;
264 mIsGFFX = FALSE;
265 mIsATI = FALSE;
266 mATIOffsetVerticalLines = FALSE;
267 mHasVertexShader = FALSE;
268 mHasFragmentShader = FALSE;
269 mHasShaderObjects = FALSE;
270
271#if LL_WINDOWS
272 mHasWGLARBPixelFormat = FALSE;
273#endif // LL_WINDOWS
274
275#if LL_DARWIN
276 mHasAPPLEVertexArrayRange = FALSE;
277 mHasAPPLEFence = FALSE;
278 mHasAPPLEVAO = FALSE;
279#endif
280
281 mIsNVIDIA = FALSE;
282 mIsIntel = FALSE;
283
284 mDriverVersionMajor = 1;
285 mDriverVersionMinor = 0;
286 mDriverVersionRelease = 0;
287 mGLVersion = 1.0f;
288
289 mNumTextureUnits = 1;
290 mVRAM = 0;
291 mGLMaxVertexRange = 0;
292 mGLMaxIndexRange = 0;
293 mSoftwareBlendSSE = TRUE;
294}
295
296//---------------------------------------------------------------------
297// Global initialization for GL
298//---------------------------------------------------------------------
299void LLGLManager::initWGL()
300{
301 mHasPBuffer = FALSE;
302#if LL_WINDOWS && !LL_MESA_HEADLESS
303 if (!glh_init_extensions("WGL_ARB_pixel_format"))
304 {
305 llwarns << "No ARB pixel format extensions" << llendl;
306 }
307
308 if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
309 {
310 GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
311 }
312
313 mHasWGLARBPixelFormat = glh_init_extensions("WGL_ARB_pbuffer");
314 if( !mHasWGLARBPixelFormat )
315 {
316 llwarns << "No ARB WGL PBuffer extensions" << llendl;
317 }
318
319 if( !glh_init_extensions("WGL_ARB_render_texture") )
320 {
321 llwarns << "No ARB WGL render texture extensions" << llendl;
322 }
323
324 mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) &&
325 ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) &&
326 ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts);
327#endif
328}
329
330// return false if unable (or unwilling due to old drivers) to init GL
331bool LLGLManager::initGL()
332{
333 if (mInited)
334 {
335 llerrs << "Calling init on LLGLManager after already initialized!" << llendl;
336 }
337
338 GLint alpha_bits;
339 glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
340 if( 8 != alpha_bits )
341 {
342 llwarns << "Frame buffer has less than 8 bits of alpha. Avatar texture compositing will fail." << llendl;
343 }
344
345 // This function uses at least one variable that's initialized below.
346 // Moved this call down to after we figure out which card we're dealing with. -- MBW 2003.10.07
347// initExtensions();
348
349 // Extract video card strings and convert to upper case to
350 // work around driver-to-driver variation in capitalization.
351 mGLVendor = LLString((const char *)glGetString(GL_VENDOR));
352 LLString::toUpper(mGLVendor);
353
354 mGLRenderer = LLString((const char *)glGetString(GL_RENDERER));
355 LLString::toUpper(mGLRenderer);
356
357 parse_gl_version( &mDriverVersionMajor,
358 &mDriverVersionMinor,
359 &mDriverVersionRelease,
360 &mDriverVersionVendorString );
361
362 mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
363
364 // Trailing space necessary to keep "nVidia Corpor_ati_on" cards
365 // from being recognized as ATI.
366 if (mGLVendor.substr(0,4) == "ATI ")
367 {
368 BOOL mobile = FALSE;
369 if (mGLRenderer.find("MOBILITY") != LLString::npos)
370 {
371 mobile = TRUE;
372 }
373 mIsATI = TRUE;
374 if ( mGLRenderer.find("9500") != LLString::npos
375 || mGLRenderer.find("9600") != LLString::npos
376 || mGLRenderer.find("9700") != LLString::npos
377 || mGLRenderer.find("9800") != LLString::npos )
378 {
379 mIsRadeon9700 = TRUE;
380 }
381 else if (mGLRenderer.find("8500") != LLString::npos
382 || mGLRenderer.find( "9000") != LLString::npos
383 || mGLRenderer.find("9100") != LLString::npos
384 || mGLRenderer.find("9200") != LLString::npos)
385 {
386 mIsRadeon8500 = TRUE;
387 if (mobile && mGLRenderer.find("9000") != LLString::npos)
388 {
389 mIsMobilityRadeon9000 = TRUE;
390 }
391 }
392
393#if LL_WINDOWS && !LL_MESA_HEADLESS
394 if (mIsRadeon9700 && mDriverVersionRelease < 3833)
395 {
396 return false; // Unsupported hardware
397 }
398
399 if (mDriverVersionRelease < 3842)
400 {
401 mATIOffsetVerticalLines = TRUE;
402 }
403#endif // LL_WINDOWS
404 }
405 else if (mGLVendor.find("NVIDIA ") != LLString::npos)
406 {
407 mIsNVIDIA = TRUE;
408 if ( mGLRenderer.find("GEFORCE4 MX") != LLString::npos
409 || mGLRenderer.find("GEFORCE2") != LLString::npos
410 || mGLRenderer.find("GEFORCE 2") != LLString::npos
411 || mGLRenderer.find("GEFORCE4 460 GO") != LLString::npos
412 || mGLRenderer.find("GEFORCE4 440 GO") != LLString::npos
413 || mGLRenderer.find("GEFORCE4 420 GO") != LLString::npos)
414 {
415 mIsGF2or4MX = TRUE;
416 }
417 else if (mGLRenderer.find("GEFORCE FX") != LLString::npos
418 || mGLRenderer.find("QUADRO FX") != LLString::npos
419 || mGLRenderer.find("NV34") != LLString::npos)
420 {
421 mIsGFFX = TRUE;
422 }
423 else if(mGLRenderer.find("GEFORCE3") != LLString::npos)
424 {
425 mIsGF3 = TRUE;
426 }
427
428 }
429 else if (mGLVendor.find("INTEL") != LLString::npos)
430 {
431 mIsIntel = TRUE;
432 }
433
434 // This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
435 initExtensions();
436
437 if (mHasMultitexture)
438 {
439 GLint num_tex_units;
440 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
441 mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS);
442 if (mIsIntel)
443 {
444 mNumTextureUnits = llmin(mNumTextureUnits, 2);
445 }
446 }
447 else
448 {
449 // We don't support cards that don't support the GL_ARB_multitexture extension
450 llwarns << "GL Drivers do not support GL_ARB_multitexture" << llendl;
451 return false;
452 }
453
454
455 initGLStates();
456 return true;
457}
458
459LLString LLGLManager::getGLInfoString()
460{
461 LLString info_str;
462 LLString all_exts, line;
463
464 info_str += LLString("GL_VENDOR ") + LLString((const char *)glGetString(GL_VENDOR)) + LLString("\n");
465 info_str += LLString("GL_RENDERER ") + LLString((const char *)glGetString(GL_RENDERER)) + LLString("\n");
466 info_str += LLString("GL_VERSION ") + LLString((const char *)glGetString(GL_VERSION)) + LLString("\n");
467
468#if !LL_MESA_HEADLESS
469 all_exts = (const char *)gGLHExts.mSysExts;
470 LLString::replaceChar(all_exts, ' ', '\n');
471 info_str += LLString("GL_EXTENSIONS:\n") + all_exts + LLString("\n");
472#endif
473
474 return info_str;
475}
476
477LLString LLGLManager::getRawGLString()
478{
479 LLString gl_string;
480 gl_string.assign((char*)glGetString(GL_VENDOR));
481 gl_string.append(" ");
482 gl_string.append((char*)glGetString(GL_RENDERER));
483 return gl_string;
484}
485
486void LLGLManager::shutdownGL()
487{
488 if (mInited)
489 {
490 stop_glerror();
491 mInited = FALSE;
492 }
493}
494
495// these are used to turn software blending on. They appear in the Debug/Avatar menu
496// presence of vertex skinning/blending or vertex programs will set these to FALSE by default.
497
498extern LLCPUInfo gSysCPU;
499
500void LLGLManager::initExtensions()
501{
502 mSoftwareBlendSSE = gSysCPU.hasSSE();
503
504#if LL_MESA_HEADLESS
505# if GL_ARB_multitexture
506 mHasMultitexture = TRUE;
507# else
508 mHasMultitexture = FALSE;
509# endif
510# if GL_ARB_texture_env_combine
511 mHasARBEnvCombine = TRUE;
512# else
513 mHasARBEnvCombine = FALSE;
514# endif
515# if GL_ARB_texture_compression
516 mHasCompressedTextures = TRUE;
517# else
518 mHasCompressedTextures = FALSE;
519# endif
520# if GL_ARB_vertex_buffer_object
521 mHasVertexBufferObject = TRUE;
522# else
523 mHasVertexBufferObject = FALSE;
524# endif
525 mHasMipMapGeneration = FALSE;
526 mHasPalettedTextures = FALSE;
527 mHasNVVertexArrayRange = FALSE;
528 mHasNVFence = FALSE;
529 mHasSeparateSpecularColor = FALSE;
530 mHasAnisotropic = FALSE;
531 mHasCubeMap = FALSE;
532 mHasATIVAO = FALSE;
533 mHasOcclusionQuery = FALSE;
534 mHasShaderObjects = FALSE;
535 mHasVertexShader = FALSE;
536 mHasFragmentShader = FALSE;
537#else // LL_MESA_HEADLESS
538 mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
539 mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
540 mHasPalettedTextures = glh_init_extension("GL_EXT_paletted_texture");
541 mHasNVVertexArrayRange = glh_init_extensions("GL_NV_vertex_array_range");
542 mHasNVFence = glh_init_extensions("GL_NV_fence");
543 mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
544 mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
545 glh_init_extensions("GL_ARB_texture_cube_map");
546 mHasCubeMap = ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
547 mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
548 mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
549 mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
550 mHasATIVAO = ExtensionExists("GL_ATI_vertex_array_object", gGLHExts.mSysExts);
551 mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
552 mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
553 mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
554 && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
555 mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
556#endif
557
558#if LL_LINUX
559 // Our extension support for the Linux Client is very young with some
560 // potential driver gotchas, so offer a semi-secret way to turn it off.
561 if (getenv("LL_GL_NOEXT"))
562 {
563 //mHasMultitexture = FALSE; // NEEDED!
564 mHasARBEnvCombine = FALSE;
565 mHasCompressedTextures = FALSE;
566 mHasVertexBufferObject = FALSE;
567 mHasMipMapGeneration = FALSE;
568 mHasPalettedTextures = FALSE;
569 mHasNVVertexArrayRange = FALSE;
570 mHasNVFence = FALSE;
571 mHasSeparateSpecularColor = FALSE;
572 mHasAnisotropic = FALSE;
573 mHasCubeMap = FALSE;
574 mHasATIVAO = FALSE;
575 mHasOcclusionQuery = FALSE;
576 mHasShaderObjects = FALSE;
577 mHasVertexShader = FALSE;
578 mHasFragmentShader = FALSE;
579 llwarns << "GL extension support DISABLED via LL_GL_NOEXT" <<
580 llendl;
581 }
582 else if (getenv("LL_GL_BASICEXT"))
583 {
584 // This switch attempts to turn off all support for exotic
585 // extensions which I believe correspond to fatal driver
586 // bug reports. This should be the default until we get a
587 // proper blacklist/whitelist on Linux.
588 mHasMipMapGeneration = FALSE;
589 mHasPalettedTextures = FALSE;
590 mHasNVVertexArrayRange = FALSE;
591 mHasNVFence = FALSE;
592 mHasAnisotropic = FALSE;
593 mHasATIVAO = FALSE;
594 mHasOcclusionQuery = FALSE; // source of many ATI system hangs
595 mHasShaderObjects = FALSE;
596 mHasVertexShader = FALSE;
597 mHasFragmentShader = FALSE;
598 llwarns << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" <<
599 llendl;
600 }
601 if (getenv("LL_GL_BLACKLIST"))
602 {
603 // This lets advanced troubleshooters disable specific
604 // GL extensions to isolate problems with their hardware.
605 // SL-28126
606 const char *const blacklist = getenv("LL_GL_BLACKLIST");
607 llwarns << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << llendl;
608 if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE;
609 if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE;
610 if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE;
611 if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
612 if (strchr(blacklist,'e')) mHasPalettedTextures = FALSE;//S
613 if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
614 if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
615 if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
616 if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S
617 if (strchr(blacklist,'j')) mHasCubeMap = FALSE;
618 if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
619 if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
620 if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S
621 if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S
622 if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
623 }
624#endif // LL_LINUX
625
626#if LL_DARWIN || LL_LINUX
627 // MBW -- 12/4/2003 -- Using paletted textures causes a bunch of avatar rendering problems on the Mac.
628 // Not sure if this is due to driver problems or incorrect use of the extension, but I'm disabling it for now.
629 // Tofu - 2006-10-03 -- Same problem on Linux.
630 mHasPalettedTextures = false;
631#endif
632
633 if (!mHasMultitexture)
634 {
635 llinfos << "Couldn't initialize multitexturing" << llendl;
636 }
637 if (!mHasMipMapGeneration)
638 {
639 llinfos << "Couldn't initialize mipmap generation" << llendl;
640 }
641 if (!mHasARBEnvCombine)
642 {
643 llinfos << "Couldn't initialize GL_ARB_texture_env_combine" << llendl;
644 }
645 if (!mHasPalettedTextures)
646 {
647 llinfos << "Couldn't initialize GL_EXT_paletted_texture" << llendl;
648 }
649 if (!mHasNVVertexArrayRange)
650 {
651 llinfos << "Couldn't initialize GL_NV_vertex_array_range" << llendl;
652 }
653 if (!mHasNVFence)
654 {
655 llinfos << "Couldn't initialize GL_NV_fence" << llendl;
656 }
657 if (!mHasSeparateSpecularColor)
658 {
659 llinfos << "Couldn't initialize separate specular color" << llendl;
660 }
661 if (!mHasAnisotropic)
662 {
663 llinfos << "Couldn't initialize anisotropic filtering" << llendl;
664 }
665 if (!mHasCompressedTextures)
666 {
667 llinfos << "Couldn't initialize GL_ARB_texture_compression" << llendl;
668 }
669 if (!mHasOcclusionQuery)
670 {
671 llinfos << "Couldn't initialize GL_ARB_occlusion_query" << llendl;
672 }
673 if (!mHasShaderObjects)
674 {
675 llinfos << "Couldn't initialize GL_ARB_shader_objects" << llendl;
676 }
677 if (!mHasVertexShader)
678 {
679 llinfos << "Couldn't initialize GL_ARB_vertex_shader" << llendl;
680 }
681 if (!mHasFragmentShader)
682 {
683 llinfos << "Couldn't initialize GL_ARB_fragment_shader" << llendl;
684 }
685
686 // Disable certain things due to known bugs
687 if (mIsIntel && mHasMipMapGeneration)
688 {
689 llinfos << "Disabling mip-map generation for Intel GPUs" << llendl;
690 mHasMipMapGeneration = FALSE;
691 }
692 if (mIsATI && mHasMipMapGeneration)
693 {
694 llinfos << "Disabling mip-map generation for ATI GPUs (performance opt)" << llendl;
695 mHasMipMapGeneration = FALSE;
696 }
697
698 // Misc
699 if (mHasNVFence || mHasATIVAO)
700 {
701 mHasAnyAGP = TRUE;
702 }
703 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
704 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
705
706 // Apple specific
707#if LL_DARWIN
708 mHasAPPLEVertexArrayRange = glh_init_extensions("GL_APPLE_vertex_array_range");
709 if (!mHasAPPLEVertexArrayRange)
710 {
711 llinfos << "Couldn't initialize GL_APPLE_vertex_array_range" << llendl;
712 }
713
714 mHasAPPLEFence = glh_init_extensions("GL_APPLE_fence");
715 if (!mHasAPPLEFence)
716 {
717 llinfos << "Couldn't initialize GL_APPLE_fence" << llendl;
718 }
719
720 mHasAPPLEVAO = glh_init_extensions("GL_APPLE_vertex_array_object");
721 if (mHasAPPLEVAO)
722 {
723 llinfos << "Has GL_APPLE_vertex_array_object!" << llendl;
724 }
725
726 if(mHasAPPLEFence)
727 {
728 mHasAnyAGP = TRUE;
729 }
730#endif // LL_DARWIN
731
732#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
733 llinfos << "GL Probe: Getting symbols" << llendl;
734 if (mHasVertexBufferObject)
735 {
736 glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferARB");
737 glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffersARB");
738 glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffersARB");
739 glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBufferARB");
740 glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferDataARB");
741 glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubDataARB");
742 glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubDataARB");
743 glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferARB");
744 glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBufferARB");
745 glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameterivARB");
746 glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointervARB");
747 }
748 if (mHasATIVAO)
749 {
750 // Initialize the extension.
751 llinfos << "Has ATI_vertex_array_object!" << llendl;
752 glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)GLH_EXT_GET_PROC_ADDRESS("glNewObjectBufferATI");
753 glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)GLH_EXT_GET_PROC_ADDRESS("glIsObjectBufferATI");
754 glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)GLH_EXT_GET_PROC_ADDRESS("glUpdateObjectBufferATI");
755 glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectBufferfvATI");
756 glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectBufferivATI");
757 glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)GLH_EXT_GET_PROC_ADDRESS("glFreeObjectBufferATI");
758 glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)GLH_EXT_GET_PROC_ADDRESS("glArrayObjectATI");
759 glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribArrayObjectATI");
760 glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetArrayObjectfvATI");
761 glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetArrayObjectivATI");
762 glVariantObjectArrayATI = (PFNGLVARIANTARRAYOBJECTATIPROC)GLH_EXT_GET_PROC_ADDRESS("glVariantObjectArrayATI");
763 glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVariantArrayObjectfvATI");
764 glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVariantArrayObjectivATI");
765 }
766#if !LL_LINUX
767 // This is expected to be a static symbol on Linux GL implementations
768 glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
769 if (!glDrawRangeElements)
770 {
771 mGLMaxVertexRange = 0;
772 mGLMaxIndexRange = 0;
773 }
774#endif // !LL_LINUX
775#if LL_LINUX
776 // On Linux we need to get glColorTableEXT dynamically.
777 if (mHasPalettedTextures)
778 {
779 glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableEXT");
780 }
781#endif // LL_LINUX
782 if (mHasOcclusionQuery)
783 {
784 glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
785 glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueriesARB");
786 glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQueryARB");
787 glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryARB");
788 glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryARB");
789 glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryivARB");
790 glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
791 glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
792 }
793 if (mHasShaderObjects)
794 {
795 glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
796 glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
797 glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
798 glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
799 glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
800 glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
801 glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
802 glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
803 glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
804 glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
805 glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
806 glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
807 glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
808 glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
809 glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
810 glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
811 glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
812 glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
813 glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
814 glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
815 glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
816 glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
817 glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
818 glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
819 glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
820 glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
821 glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
822 glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
823 glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
824 glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
825 glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
826 glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
827 glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
828 glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
829 glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
830 glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
831 glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
832 glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
833 glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
834 }
835 if (mHasVertexShader)
836 {
837 glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
838 glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
839 glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
840 glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
841 glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
842 glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
843 glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
844 glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
845 glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
846 glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
847 glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
848 glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
849 glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
850 glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
851 glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
852 glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
853 glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
854 glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
855 glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
856 glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
857 glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
858 glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
859 glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
860 glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
861 glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
862 glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
863 glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
864 glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
865 glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
866 glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
867 glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
868 glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
869 glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
870 glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
871 glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
872 glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
873 glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
874 glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
875 glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
876 glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
877 glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
878 glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
879 glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
880 glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
881 glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
882 glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
883 glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
884 glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
885 glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
886 glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
887 glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
888 glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
889 glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
890 glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
891 glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
892 glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
893 glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
894 glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
895 glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
896 glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
897 glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
898 glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
899 glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
900 glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
901 glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
902 }
903 llinfos << "GL Probe: Got symbols" << llendl;
904#endif
905
906 mInited = TRUE;
907}
908
909void rotate_quat(LLQuaternion& rotation)
910{
911 F32 angle_radians, x, y, z;
912 rotation.getAngleAxis(&angle_radians, &x, &y, &z);
913 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
914}
915
916void flush_glerror()
917{
918 glGetError();
919}
920
921void assert_glerror()
922{
923 if (gNoRender)
924 {
925 return;
926 }
927 if (!gGLManager.mInited)
928 {
929 llerrs << "GL not initialized" << llendl;
930 }
931 // Create or update texture to be used with this data
932 GLenum error;
933 error = glGetError();
934 if (error)
935 {
936#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
937 llerrs << "GL Error:" << gluErrorString(error) << llendl;
938#endif
939 }
940}
941
942void clear_glerror()
943{
944 // Create or update texture to be used with this data
945 GLenum error;
946 error = glGetError();
947}
948
949//============================================================================
950
951//
952// LLGLState
953//
954
955// Static members
956std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
957
958GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
959GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
960GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
961
962//static
963void LLGLState::initClass()
964{
965 sStateMap[GL_DITHER] = GL_TRUE;
966}
967
968//static
969void LLGLState::restoreGL()
970{
971 sStateMap.clear();
972 initClass();
973}
974
975void LLGLState::dumpStates()
976{
977 llinfos << "GL States:" << llendl;
978 for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
979 iter != sStateMap.end(); ++iter)
980 {
981 llinfos << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << llendl;
982 }
983}
984
985void LLGLState::checkStates()
986{
987 stop_glerror();
988
989 GLint activeTexture;
990 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
991
992 if (activeTexture != GL_TEXTURE0_ARB)
993 {
994 LL_GL_ERRS << "Texture channel corrupted. " << llendl;
995 }
996
997 GLint src;
998 GLint dst;
999 glGetIntegerv(GL_BLEND_SRC, &src);
1000 glGetIntegerv(GL_BLEND_DST, &dst);
1001
1002 if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
1003 {
1004 LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << llendl;
1005 }
1006
1007 for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
1008 iter != sStateMap.end(); ++iter)
1009 {
1010 LLGLenum state = iter->first;
1011 LLGLboolean cur_state = iter->second;
1012 LLGLboolean gl_state = glIsEnabled(state);
1013 if(cur_state != gl_state)
1014 {
1015 dumpStates();
1016 LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << llendl;
1017 }
1018 }
1019
1020 stop_glerror();
1021}
1022
1023void LLGLState::checkTextureChannels()
1024{
1025 GLint activeTexture;
1026 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
1027
1028 BOOL error = FALSE;
1029
1030 if (activeTexture != GL_TEXTURE0_ARB)
1031 {
1032 error = TRUE;
1033 llwarns << "Active texture channel corrupted. " << llendl;
1034 }
1035
1036 GLint maxTextureUnits;
1037 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
1038
1039 static const char* label[] =
1040 {
1041 "GL_TEXTURE_2D",
1042 "GL_TEXTURE_COORD_ARRAY",
1043 "GL_TEXTURE_1D",
1044 "GL_TEXTURE_CUBE_MAP_ARB",
1045 "GL_TEXTURE_GEN_S",
1046 "GL_TEXTURE_GEN_T",
1047 "GL_TEXTURE_GEN_Q",
1048 "GL_TEXTURE_GEN_R"
1049 };
1050
1051 static GLint value[] =
1052 {
1053 GL_TEXTURE_2D,
1054 GL_TEXTURE_COORD_ARRAY,
1055 GL_TEXTURE_1D,
1056 GL_TEXTURE_CUBE_MAP_ARB,
1057 GL_TEXTURE_GEN_S,
1058 GL_TEXTURE_GEN_T,
1059 GL_TEXTURE_GEN_Q,
1060 GL_TEXTURE_GEN_R
1061 };
1062
1063 GLint stackDepth = 0;
1064 LLMatrix4 identity;
1065 LLMatrix4 matrix;
1066
1067 for (GLint i = 0; i < maxTextureUnits; i++)
1068 {
1069 glActiveTextureARB(GL_TEXTURE0_ARB+i);
1070 glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
1071
1072 glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
1073
1074 if (stackDepth != 1)
1075 {
1076 error = TRUE;
1077 llwarns << "Texture matrix stack corrupted." << llendl;
1078 }
1079
1080 glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
1081
1082 if (matrix != identity)
1083 {
1084 error = TRUE;
1085 llwarns << "Texture matrix in channel " << i << " corrupt." << llendl;
1086 }
1087
1088 for (S32 j = (i == 0 ? 2 : 0); j < 8; j++)
1089 {
1090 if (glIsEnabled(value[j]))
1091 {
1092 error = TRUE;
1093 llwarns << "Texture channel " << i << " still has " << label[j] << " enabled." << llendl;
1094 }
1095 }
1096 }
1097
1098 glActiveTextureARB(GL_TEXTURE0_ARB);
1099 glClientActiveTextureARB(GL_TEXTURE0_ARB);
1100
1101 if (error)
1102 {
1103 LL_GL_ERRS << "GL texture state corruption detected." << llendl;
1104 }
1105}
1106
1107void LLGLState::checkClientArrays()
1108{
1109 BOOL error = FALSE;
1110 static const char* label[] =
1111 {
1112 //"GL_INDEX_ARRAY",
1113 "GL_NORMAL_ARRAY",
1114 //"GL_VERTEX_ARRAY",
1115 "GL_COLOR_ARRAY",
1116 "GL_TEXTURE_COORD_ARRAY"
1117 };
1118
1119 static GLint value[] =
1120 {
1121 //GL_INDEX_ARRAY,
1122 GL_NORMAL_ARRAY,
1123 //GL_VERTEX_ARRAY,
1124 GL_COLOR_ARRAY,
1125 GL_TEXTURE_COORD_ARRAY
1126 };
1127
1128 for (S32 j = 0; j < 3; j++)
1129 {
1130 if (glIsEnabled(value[j]))
1131 {
1132 error = TRUE;
1133 llwarns << "GL still has " << label[j] << " enabled." << llendl;
1134 }
1135 }
1136
1137 if (error)
1138 {
1139 LL_GL_ERRS << "GL client array corruption detected." << llendl;
1140 }
1141}
1142
1143//============================================================================
1144
1145LLGLState::LLGLState(LLGLenum state, S32 enabled)
1146{
1147 stop_glerror();
1148 mState = state;
1149 if (state)
1150 {
1151 mWasEnabled = sStateMap[state];
1152 llassert(mWasEnabled == glIsEnabled(state));
1153 setEnabled(enabled);
1154 stop_glerror();
1155 }
1156}
1157
1158void LLGLState::setEnabled(S32 enabled)
1159{
1160 if (!mState)
1161 {
1162 return;
1163 }
1164 if (enabled == CURRENT_STATE)
1165 {
1166 enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
1167 }
1168 else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
1169 {
1170 glEnable(mState);
1171 sStateMap[mState] = GL_TRUE;
1172 }
1173 else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
1174 {
1175 glDisable(mState);
1176 sStateMap[mState] = GL_FALSE;
1177 }
1178 mIsEnabled = enabled;
1179}
1180
1181LLGLState::~LLGLState()
1182{
1183 stop_glerror();
1184 if (mState)
1185 {
1186#if LL_DEBUG
1187 LLGLboolean cur_state = sStateMap[mState];
1188 llassert(cur_state == glIsEnabled(mState));
1189#endif
1190 if (mIsEnabled != mWasEnabled)
1191 {
1192 if (mWasEnabled)
1193 {
1194 glEnable(mState);
1195 sStateMap[mState] = GL_TRUE;
1196 }
1197 else
1198 {
1199 glDisable(mState);
1200 sStateMap[mState] = GL_FALSE;
1201 }
1202 }
1203 }
1204 stop_glerror();
1205}
1206
1207//============================================================================
1208
1209void LLGLManager::initGLStates()
1210{
1211 //gl states moved to classes in llglstates.h
1212 LLGLState::initClass();
1213}
1214
1215//============================================================================
1216
1217void enable_vertex_weighting(const S32 index)
1218{
1219#if GL_ARB_vertex_program
1220 if (index > 0) glEnableVertexAttribArrayARB(index); // vertex weights
1221#endif
1222}
1223
1224void disable_vertex_weighting(const S32 index)
1225{
1226#if GL_ARB_vertex_program
1227 if (index > 0) glDisableVertexAttribArrayARB(index); // vertex weights
1228#endif
1229}
1230
1231void enable_binormals(const S32 index)
1232{
1233#if GL_ARB_vertex_program
1234 if (index > 0)
1235 {
1236 glEnableVertexAttribArrayARB(index); // binormals
1237 }
1238#endif
1239}
1240
1241void disable_binormals(const S32 index)
1242{
1243#if GL_ARB_vertex_program
1244 if (index > 0)
1245 {
1246 glDisableVertexAttribArrayARB(index); // binormals
1247 }
1248#endif
1249}
1250
1251
1252void enable_cloth_weights(const S32 index)
1253{
1254#if GL_ARB_vertex_program
1255 if (index > 0) glEnableVertexAttribArrayARB(index);
1256#endif
1257}
1258
1259void disable_cloth_weights(const S32 index)
1260{
1261#if GL_ARB_vertex_program
1262 if (index > 0) glDisableVertexAttribArrayARB(index);
1263#endif
1264}
1265
1266void set_vertex_weights(const S32 index, const F32 *weights)
1267{
1268#if GL_ARB_vertex_program
1269 if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, weights);
1270 stop_glerror();
1271#endif
1272}
1273
1274void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
1275{
1276#if GL_ARB_vertex_program
1277 if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
1278 stop_glerror();
1279#endif
1280}
1281
1282void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
1283{
1284#if GL_ARB_vertex_program
1285 if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
1286 stop_glerror();
1287#endif
1288}
1289
1290
1291void set_palette(U8 *palette_data)
1292{
1293 if (gGLManager.mHasPalettedTextures)
1294 {
1295 glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette_data);
1296 }
1297}
1298
1299
1300void parse_gl_version( S32* major, S32* minor, S32* release, LLString* vendor_specific )
1301{
1302 // GL_VERSION returns a null-terminated string with the format:
1303 // <major>.<minor>[.<release>] [<vendor specific>]
1304
1305 const char* version = (const char*) glGetString(GL_VERSION);
1306 *major = 0;
1307 *minor = 0;
1308 *release = 0;
1309 vendor_specific->assign("");
1310
1311 if( !version )
1312 {
1313 return;
1314 }
1315
1316 LLString ver_copy( version );
1317 S32 len = (S32)strlen( version );
1318 S32 i = 0;
1319 S32 start;
1320 // Find the major version
1321 start = i;
1322 for( ; i < len; i++ )
1323 {
1324 if( '.' == version[i] )
1325 {
1326 break;
1327 }
1328 }
1329 LLString major_str = ver_copy.substr(start,i-start);
1330 LLString::convertToS32(major_str, *major);
1331
1332 if( '.' == version[i] )
1333 {
1334 i++;
1335 }
1336
1337 // Find the minor version
1338 start = i;
1339 for( ; i < len; i++ )
1340 {
1341 if( ('.' == version[i]) || isspace(version[i]) )
1342 {
1343 break;
1344 }
1345 }
1346 LLString minor_str = ver_copy.substr(start,i-start);
1347 LLString::convertToS32(minor_str, *minor);
1348
1349 // Find the release number (optional)
1350 if( '.' == version[i] )
1351 {
1352 i++;
1353
1354 start = i;
1355 for( ; i < len; i++ )
1356 {
1357 if( isspace(version[i]) )
1358 {
1359 break;
1360 }
1361 }
1362
1363 LLString release_str = ver_copy.substr(start,i-start);
1364 LLString::convertToS32(release_str, *release);
1365 }
1366
1367 // Skip over any white space
1368 while( version[i] && isspace( version[i] ) )
1369 {
1370 i++;
1371 }
1372
1373 // Copy the vendor-specific string (optional)
1374 if( version[i] )
1375 {
1376 vendor_specific->assign( version + i );
1377 }
1378}