diff options
Diffstat (limited to 'linden/indra/llwindow/llgl.cpp')
-rw-r--r-- | linden/indra/llwindow/llgl.cpp | 1378 |
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 | |||
72 | BOOL gClothRipple = FALSE; | ||
73 | BOOL gNoRender = FALSE; | ||
74 | |||
75 | |||
76 | #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS | ||
77 | // ATI prototypes | ||
78 | // vertex blending prototypes | ||
79 | PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL; | ||
80 | PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL; | ||
81 | PFNGLWEIGHTFVARBPROC glWeightfvARB = NULL; | ||
82 | |||
83 | // Vertex buffer object prototypes | ||
84 | PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; | ||
85 | PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; | ||
86 | PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; | ||
87 | PFNGLISBUFFERARBPROC glIsBufferARB = NULL; | ||
88 | PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; | ||
89 | PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB = NULL; | ||
90 | PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB = NULL; | ||
91 | PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL; | ||
92 | PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL; | ||
93 | PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL; | ||
94 | PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL; | ||
95 | |||
96 | // vertex object prototypes | ||
97 | PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL; | ||
98 | PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL; | ||
99 | PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI = NULL; | ||
100 | PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI = NULL; | ||
101 | PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI = NULL; | ||
102 | PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI = NULL; | ||
103 | PFNGLARRAYOBJECTATIPROC glArrayObjectATI = NULL; | ||
104 | PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI = NULL; | ||
105 | PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI = NULL; | ||
106 | PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI = NULL; | ||
107 | PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI = NULL; | ||
108 | PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI = NULL; | ||
109 | PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI = NULL; | ||
110 | |||
111 | // GL_ARB_occlusion_query | ||
112 | PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL; | ||
113 | PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL; | ||
114 | PFNGLISQUERYARBPROC glIsQueryARB = NULL; | ||
115 | PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL; | ||
116 | PFNGLENDQUERYARBPROC glEndQueryARB = NULL; | ||
117 | PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL; | ||
118 | PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL; | ||
119 | PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL; | ||
120 | |||
121 | //shader object prototypes | ||
122 | PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL; | ||
123 | PFNGLGETHANDLEARBPROC glGetHandleARB = NULL; | ||
124 | PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL; | ||
125 | PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL; | ||
126 | PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL; | ||
127 | PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL; | ||
128 | PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL; | ||
129 | PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL; | ||
130 | PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL; | ||
131 | PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL; | ||
132 | PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB = NULL; | ||
133 | PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL; | ||
134 | PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL; | ||
135 | PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL; | ||
136 | PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL; | ||
137 | PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL; | ||
138 | PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL; | ||
139 | PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL; | ||
140 | PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL; | ||
141 | PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL; | ||
142 | PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL; | ||
143 | PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL; | ||
144 | PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL; | ||
145 | PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL; | ||
146 | PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL; | ||
147 | PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL; | ||
148 | PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL; | ||
149 | PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL; | ||
150 | PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL; | ||
151 | PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL; | ||
152 | PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL; | ||
153 | PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL; | ||
154 | PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL; | ||
155 | PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL; | ||
156 | PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL; | ||
157 | PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL; | ||
158 | PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL; | ||
159 | PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL; | ||
160 | PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL; | ||
161 | |||
162 | // vertex shader prototypes | ||
163 | #if LL_LINUX | ||
164 | PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL; | ||
165 | PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL; | ||
166 | PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL; | ||
167 | PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB = NULL; | ||
168 | PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB = NULL; | ||
169 | PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB = NULL; | ||
170 | PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB = NULL; | ||
171 | PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB = NULL; | ||
172 | PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB = NULL; | ||
173 | PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB = NULL; | ||
174 | PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB = NULL; | ||
175 | PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB = NULL; | ||
176 | PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB = NULL; | ||
177 | PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB = NULL; | ||
178 | PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL; | ||
179 | PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL; | ||
180 | PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL; | ||
181 | PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL; | ||
182 | #endif // LL_LINUX | ||
183 | PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL; | ||
184 | PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL; | ||
185 | PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL; | ||
186 | PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL; | ||
187 | PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL; | ||
188 | PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL; | ||
189 | PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL; | ||
190 | #if LL_LINUX | ||
191 | PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL; | ||
192 | PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL; | ||
193 | PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL; | ||
194 | PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB = NULL; | ||
195 | PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB = NULL; | ||
196 | PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB = NULL; | ||
197 | PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB = NULL; | ||
198 | PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB = NULL; | ||
199 | PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL; | ||
200 | PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL; | ||
201 | PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL; | ||
202 | PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL; | ||
203 | PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL; | ||
204 | PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL; | ||
205 | PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL; | ||
206 | PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL; | ||
207 | PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL; | ||
208 | PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL; | ||
209 | PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB = NULL; | ||
210 | PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB = NULL; | ||
211 | PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB = NULL; | ||
212 | PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = NULL; | ||
213 | PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB = NULL; | ||
214 | PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB = NULL; | ||
215 | PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB = NULL; | ||
216 | PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = NULL; | ||
217 | PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB = NULL; | ||
218 | PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB = NULL; | ||
219 | PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB = NULL; | ||
220 | PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB = NULL; | ||
221 | PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = NULL; | ||
222 | PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB = NULL; | ||
223 | PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB = NULL; | ||
224 | PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL; | ||
225 | PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL; | ||
226 | PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL; | ||
227 | PFNGLISPROGRAMARBPROC glIsProgramARB = NULL; | ||
228 | #endif // LL_LINUX | ||
229 | PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL; | ||
230 | PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL; | ||
231 | PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL; | ||
232 | |||
233 | #if LL_WINDOWS | ||
234 | PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; | ||
235 | #endif | ||
236 | |||
237 | #if LL_LINUX | ||
238 | PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; | ||
239 | #endif // LL_LINUX | ||
240 | |||
241 | #endif | ||
242 | |||
243 | LLGLManager gGLManager; | ||
244 | |||
245 | LLGLManager::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 | //--------------------------------------------------------------------- | ||
299 | void 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 | ||
331 | bool 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 | |||
459 | LLString 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 | |||
477 | LLString 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 | |||
486 | void 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 | |||
498 | extern LLCPUInfo gSysCPU; | ||
499 | |||
500 | void 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 | |||
909 | void 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 | |||
916 | void flush_glerror() | ||
917 | { | ||
918 | glGetError(); | ||
919 | } | ||
920 | |||
921 | void 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 | |||
942 | void 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 | ||
956 | std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap; | ||
957 | |||
958 | GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default | ||
959 | GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default | ||
960 | GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default | ||
961 | |||
962 | //static | ||
963 | void LLGLState::initClass() | ||
964 | { | ||
965 | sStateMap[GL_DITHER] = GL_TRUE; | ||
966 | } | ||
967 | |||
968 | //static | ||
969 | void LLGLState::restoreGL() | ||
970 | { | ||
971 | sStateMap.clear(); | ||
972 | initClass(); | ||
973 | } | ||
974 | |||
975 | void 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 | |||
985 | void 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 | |||
1023 | void 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 | |||
1107 | void 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 | |||
1145 | LLGLState::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 | |||
1158 | void 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 | |||
1181 | LLGLState::~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 | |||
1209 | void LLGLManager::initGLStates() | ||
1210 | { | ||
1211 | //gl states moved to classes in llglstates.h | ||
1212 | LLGLState::initClass(); | ||
1213 | } | ||
1214 | |||
1215 | //============================================================================ | ||
1216 | |||
1217 | void 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 | |||
1224 | void 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 | |||
1231 | void 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 | |||
1241 | void 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 | |||
1252 | void enable_cloth_weights(const S32 index) | ||
1253 | { | ||
1254 | #if GL_ARB_vertex_program | ||
1255 | if (index > 0) glEnableVertexAttribArrayARB(index); | ||
1256 | #endif | ||
1257 | } | ||
1258 | |||
1259 | void disable_cloth_weights(const S32 index) | ||
1260 | { | ||
1261 | #if GL_ARB_vertex_program | ||
1262 | if (index > 0) glDisableVertexAttribArrayARB(index); | ||
1263 | #endif | ||
1264 | } | ||
1265 | |||
1266 | void 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 | |||
1274 | void 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 | |||
1282 | void 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 | |||
1291 | void 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 | |||
1300 | void 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 | } | ||