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