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