3 #include "cl_collision.h"
5 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
6 cvar_t gl_mesh_testarrayelement = {0, "gl_mesh_testarrayelement", "0", "use glBegin(GL_TRIANGLES);glArrayElement();glEnd(); primitives instead of glDrawElements (useful to test for driver bugs with glDrawElements)"};
7 cvar_t gl_mesh_testmanualfeeding = {0, "gl_mesh_testmanualfeeding", "0", "use glBegin(GL_TRIANGLES);glTexCoord2f();glVertex3f();glEnd(); primitives instead of glDrawElements (useful to test for driver bugs with glDrawElements)"};
8 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
9 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
11 cvar_t r_render = {0, "r_render", "1", "enables rendering calls (you want this on!)"};
12 cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
13 cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
14 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
15 cvar_t gl_lockarrays = {0, "gl_lockarrays", "1", "enables use of glLockArraysEXT, may cause glitches with some broken drivers"};
17 int gl_maxdrawrangeelementsvertices;
18 int gl_maxdrawrangeelementsindices;
23 void GL_PrintError(int errornumber, char *filename, int linenumber)
27 #ifdef GL_INVALID_ENUM
29 Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
32 #ifdef GL_INVALID_VALUE
33 case GL_INVALID_VALUE:
34 Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
37 #ifdef GL_INVALID_OPERATION
38 case GL_INVALID_OPERATION:
39 Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
42 #ifdef GL_STACK_OVERFLOW
43 case GL_STACK_OVERFLOW:
44 Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
47 #ifdef GL_STACK_UNDERFLOW
48 case GL_STACK_UNDERFLOW:
49 Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
52 #ifdef GL_OUT_OF_MEMORY
53 case GL_OUT_OF_MEMORY:
54 Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
57 #ifdef GL_TABLE_TOO_LARGE
58 case GL_TABLE_TOO_LARGE:
59 Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
63 Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
69 #define BACKENDACTIVECHECK if (!backendactive) Sys_Error("GL backend function called when backend is not active");
71 void SCR_ScreenShot_f (void);
73 static matrix4x4_t backend_viewmatrix;
74 static matrix4x4_t backend_modelmatrix;
75 static matrix4x4_t backend_modelviewmatrix;
76 static matrix4x4_t backend_projectmatrix;
78 static unsigned int backendunits, backendimageunits, backendarrayunits, backendactive;
81 note: here's strip order for a terrain row:
88 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
90 *elements++ = i + row;
92 *elements++ = i + row + 1;
95 *elements++ = i + row + 1;
98 for (y = 0;y < rows - 1;y++)
100 for (x = 0;x < columns - 1;x++)
103 *elements++ = i + columns;
105 *elements++ = i + columns + 1;
108 *elements++ = i + columns + 1;
119 for (y = 0;y < rows - 1;y++)
121 for (x = 0;x < columns - 1;x++)
125 *elements++ = i + columns;
126 *elements++ = i + columns + 1;
127 *elements++ = i + columns;
128 *elements++ = i + columns + 1;
134 int polygonelements[(POLYGONELEMENTS_MAXPOINTS-2)*3];
135 int quadelements[QUADELEMENTS_MAXQUADS*6];
137 void GL_Backend_AllocArrays(void)
141 void GL_Backend_FreeArrays(void)
145 static void gl_backend_start(void)
147 Con_Print("OpenGL Backend starting...\n");
150 if (qglDrawRangeElements != NULL)
153 qglGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &gl_maxdrawrangeelementsvertices);
155 qglGetIntegerv(GL_MAX_ELEMENTS_INDICES, &gl_maxdrawrangeelementsindices);
157 Con_Printf("glDrawRangeElements detected (max vertices %i, max indices %i)\n", gl_maxdrawrangeelementsvertices, gl_maxdrawrangeelementsindices);
160 backendunits = bound(1, gl_textureunits, MAX_TEXTUREUNITS);
161 backendimageunits = backendunits;
162 backendarrayunits = backendunits;
163 if (gl_support_fragment_shader)
166 qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (int *)&backendimageunits);
168 qglGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, (int *)&backendarrayunits);
170 Con_Printf("GLSL shader support detected: texture units = %i texenv, %i image, %i array\n", backendunits, backendimageunits, backendarrayunits);
171 backendimageunits = bound(1, backendimageunits, MAX_TEXTUREUNITS);
172 backendarrayunits = bound(1, backendarrayunits, MAX_TEXTUREUNITS);
174 else if (backendunits > 1)
175 Con_Printf("multitexture detected: texture units = %i\n", backendunits);
177 Con_Printf("singletexture\n");
179 GL_Backend_AllocArrays();
181 Con_Printf("OpenGL backend started.\n");
185 backendactive = true;
188 static void gl_backend_shutdown(void)
191 backendimageunits = 0;
192 backendarrayunits = 0;
193 backendactive = false;
195 Con_Print("OpenGL Backend shutting down\n");
197 GL_Backend_FreeArrays();
200 static void gl_backend_newmap(void)
204 void gl_backend_init(void)
208 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
210 polygonelements[i * 3 + 0] = 0;
211 polygonelements[i * 3 + 1] = i + 1;
212 polygonelements[i * 3 + 2] = i + 2;
214 // elements for rendering a series of quads as triangles
215 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
217 quadelements[i * 6 + 0] = i * 4;
218 quadelements[i * 6 + 1] = i * 4 + 1;
219 quadelements[i * 6 + 2] = i * 4 + 2;
220 quadelements[i * 6 + 3] = i * 4;
221 quadelements[i * 6 + 4] = i * 4 + 2;
222 quadelements[i * 6 + 5] = i * 4 + 3;
225 Cvar_RegisterVariable(&r_render);
226 Cvar_RegisterVariable(&r_waterwarp);
227 Cvar_RegisterVariable(&gl_polyblend);
228 Cvar_RegisterVariable(&gl_dither);
229 Cvar_RegisterVariable(&gl_lockarrays);
230 Cvar_RegisterVariable(&gl_paranoid);
231 Cvar_RegisterVariable(&gl_printcheckerror);
233 Cvar_SetValue("r_render", 0);
236 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
237 Cvar_RegisterVariable(&gl_mesh_testarrayelement);
238 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
240 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
243 void GL_SetupView_Orientation_Identity (void)
245 backend_viewmatrix = identitymatrix;
246 memset(&backend_modelmatrix, 0, sizeof(backend_modelmatrix));
249 void GL_SetupView_Orientation_FromEntity(const matrix4x4_t *matrix)
251 matrix4x4_t tempmatrix, basematrix;
252 Matrix4x4_Invert_Simple(&tempmatrix, matrix);
253 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
254 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
255 Matrix4x4_Concat(&backend_viewmatrix, &basematrix, &tempmatrix);
256 //Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[2], 1, 0, 0);
257 //Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[0], 0, 1, 0);
258 //Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[1], 0, 0, 1);
259 //Matrix4x4_ConcatTranslate(&backend_viewmatrix, -origin[0], -origin[1], -origin[2]);
260 memset(&backend_modelmatrix, 0, sizeof(backend_modelmatrix));
263 void GL_SetupView_Mode_Perspective (double frustumx, double frustumy, double zNear, double zFar)
269 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
270 qglLoadIdentity();CHECKGLERROR
272 qglFrustum(-frustumx * zNear, frustumx * zNear, -frustumy * zNear, frustumy * zNear, zNear, zFar);CHECKGLERROR
273 qglGetDoublev(GL_PROJECTION_MATRIX, m);CHECKGLERROR
274 Matrix4x4_FromArrayDoubleGL(&backend_projectmatrix, m);
275 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
276 GL_SetupView_Orientation_Identity();
280 void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double frustumx, double frustumy, double zNear)
286 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
287 qglLoadIdentity();CHECKGLERROR
289 nudge = 1.0 - 1.0 / (1<<23);
290 m[ 0] = 1.0 / frustumx;
295 m[ 5] = 1.0 / frustumy;
304 m[14] = -2 * zNear * nudge;
306 qglLoadMatrixd(m);CHECKGLERROR
307 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
308 GL_SetupView_Orientation_Identity();
310 Matrix4x4_FromArrayDoubleGL(&backend_projectmatrix, m);
313 void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double zNear, double zFar)
319 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
320 qglLoadIdentity();CHECKGLERROR
321 qglOrtho(x1, x2, y2, y1, zNear, zFar);CHECKGLERROR
322 qglGetDoublev(GL_PROJECTION_MATRIX, m);CHECKGLERROR
323 Matrix4x4_FromArrayDoubleGL(&backend_projectmatrix, m);
324 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
325 GL_SetupView_Orientation_Identity();
329 typedef struct gltextureunit_s
331 int t1d, t2d, t3d, tcubemap;
333 unsigned int arraycomponents;
334 const void *pointer_texcoord;
335 int rgbscale, alphascale;
336 int combinergb, combinealpha;
337 // FIXME: add more combine stuff
338 // texmatrixenabled exists only to avoid unnecessary texmatrix compares
339 int texmatrixenabled;
344 static struct gl_state_s
352 int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order)
357 unsigned int clientunit;
358 gltextureunit_t units[MAX_TEXTUREUNITS];
362 const void *pointer_vertex;
363 const void *pointer_color;
367 void GL_SetupTextureState(void)
370 gltextureunit_t *unit;
372 gl_state.unit = MAX_TEXTUREUNITS;
373 gl_state.clientunit = MAX_TEXTUREUNITS;
374 for (i = 0;i < MAX_TEXTUREUNITS;i++)
376 unit = gl_state.units + i;
381 unit->arrayenabled = false;
382 unit->arraycomponents = 0;
383 unit->pointer_texcoord = NULL;
385 unit->alphascale = 1;
386 unit->combinergb = GL_MODULATE;
387 unit->combinealpha = GL_MODULATE;
388 unit->texmatrixenabled = false;
389 unit->matrix = identitymatrix;
392 for (i = 0;i < backendimageunits;i++)
395 qglBindTexture(GL_TEXTURE_1D, 0);CHECKGLERROR
396 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
399 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
401 if (gl_texturecubemap)
403 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
407 for (i = 0;i < backendarrayunits;i++)
409 GL_ClientActiveTexture(i);
410 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
411 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
414 for (i = 0;i < backendunits;i++)
417 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
418 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
421 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
423 if (gl_texturecubemap)
425 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
427 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
428 qglLoadIdentity();CHECKGLERROR
429 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
430 if (gl_combine.integer)
432 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
433 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR
434 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR
435 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
436 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
437 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
438 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
439 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR
440 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);CHECKGLERROR
441 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);CHECKGLERROR
442 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
443 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);CHECKGLERROR
444 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
445 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
446 qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
447 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
448 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
452 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
459 void GL_Backend_ResetState(void)
461 memset(&gl_state, 0, sizeof(gl_state));
462 gl_state.depthtest = true;
463 gl_state.alphatest = false;
464 gl_state.blendfunc1 = GL_ONE;
465 gl_state.blendfunc2 = GL_ZERO;
466 gl_state.blend = false;
467 gl_state.depthmask = GL_TRUE;
468 gl_state.colormask = 15;
469 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
470 gl_state.lockrange_first = 0;
471 gl_state.lockrange_count = 0;
472 gl_state.pointer_vertex = NULL;
473 gl_state.pointer_color = NULL;
474 gl_state.cullface = GL_FRONT; // quake is backwards, this culls back faces
475 gl_state.cullfaceenable = true;
479 qglColorMask(1, 1, 1, 1);
480 qglAlphaFunc(GL_GEQUAL, 0.5);CHECKGLERROR
481 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
482 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
483 qglDisable(GL_BLEND);CHECKGLERROR
484 qglCullFace(gl_state.cullface);CHECKGLERROR
485 qglEnable(GL_CULL_FACE);CHECKGLERROR
486 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
487 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
488 qglDepthMask(gl_state.depthmask);CHECKGLERROR
490 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
491 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
493 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
494 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
496 GL_Color(0, 0, 0, 0);
497 GL_Color(1, 1, 1, 1);
499 GL_SetupTextureState();
502 void GL_ActiveTexture(unsigned int num)
504 if (gl_state.unit != num)
507 if (qglActiveTexture)
510 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
516 void GL_ClientActiveTexture(unsigned int num)
518 if (gl_state.clientunit != num)
520 gl_state.clientunit = num;
521 if (qglActiveTexture)
524 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
530 void GL_BlendFunc(int blendfunc1, int blendfunc2)
532 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
535 qglBlendFunc(gl_state.blendfunc1 = blendfunc1, gl_state.blendfunc2 = blendfunc2);CHECKGLERROR
536 if (gl_state.blendfunc2 == GL_ZERO)
538 if (gl_state.blendfunc1 == GL_ONE)
543 qglDisable(GL_BLEND);CHECKGLERROR
551 qglEnable(GL_BLEND);CHECKGLERROR
560 qglEnable(GL_BLEND);CHECKGLERROR
566 void GL_DepthMask(int state)
568 if (gl_state.depthmask != state)
571 qglDepthMask(gl_state.depthmask = state);CHECKGLERROR
575 void GL_DepthTest(int state)
577 if (gl_state.depthtest != state)
579 gl_state.depthtest = state;
581 if (gl_state.depthtest)
583 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
587 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
592 void GL_CullFace(int state)
595 if (state != GL_NONE)
597 if (!gl_state.cullfaceenable)
599 gl_state.cullfaceenable = true;
600 qglEnable(GL_CULL_FACE);CHECKGLERROR
602 if (gl_state.cullface != state)
604 gl_state.cullface = state;
605 qglCullFace(gl_state.cullface);CHECKGLERROR
610 if (gl_state.cullfaceenable)
612 gl_state.cullfaceenable = false;
613 qglDisable(GL_CULL_FACE);CHECKGLERROR
618 void GL_AlphaTest(int state)
620 if (gl_state.alphatest != state)
622 gl_state.alphatest = state;
624 if (gl_state.alphatest)
626 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
630 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
635 void GL_ColorMask(int r, int g, int b, int a)
637 int state = r*8 + g*4 + b*2 + a*1;
638 if (gl_state.colormask != state)
640 gl_state.colormask = state;
642 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
646 void GL_Color(float cr, float cg, float cb, float ca)
648 if (gl_state.pointer_color || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
650 gl_state.color4f[0] = cr;
651 gl_state.color4f[1] = cg;
652 gl_state.color4f[2] = cb;
653 gl_state.color4f[3] = ca;
655 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
660 void GL_LockArrays(int first, int count)
662 if (gl_state.lockrange_count != count || gl_state.lockrange_first != first)
664 if (gl_state.lockrange_count)
666 gl_state.lockrange_count = 0;
668 qglUnlockArraysEXT();
671 if (count && gl_supportslockarrays && gl_lockarrays.integer && r_render.integer)
673 gl_state.lockrange_first = first;
674 gl_state.lockrange_count = count;
676 qglLockArraysEXT(first, count);
682 void GL_Scissor (int x, int y, int width, int height)
685 qglScissor(x, vid.height - (y + height),width,height);
689 void GL_ScissorTest(int state)
691 if(gl_state.scissortest == state)
695 if((gl_state.scissortest = state))
696 qglEnable(GL_SCISSOR_TEST);
698 qglDisable(GL_SCISSOR_TEST);
702 void GL_Clear(int mask)
705 qglClear(mask);CHECKGLERROR
708 void GL_TransformToScreen(const vec4_t in, vec4_t out)
712 Matrix4x4_Transform4 (&backend_viewmatrix, in, temp);
713 Matrix4x4_Transform4 (&backend_projectmatrix, temp, out);
715 out[0] = r_view.x + (out[0] * iw + 1.0f) * r_view.width * 0.5f;
716 out[1] = r_view.y + r_view.height - (out[1] * iw + 1.0f) * r_view.height * 0.5f;
717 out[2] = r_view.z + (out[2] * iw + 1.0f) * r_view.depth * 0.5f;
720 // called at beginning of frame
721 void R_Mesh_Start(void)
725 if (gl_printcheckerror.integer && !gl_paranoid.integer)
727 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
728 Cvar_SetValueQuick(&gl_paranoid, 1);
730 GL_Backend_ResetState();
733 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
737 char compilelog[MAX_INPUTLINE];
738 shaderobject = qglCreateShaderObjectARB(shadertypeenum);CHECKGLERROR
741 qglShaderSourceARB(shaderobject, numstrings, strings, NULL);CHECKGLERROR
742 qglCompileShaderARB(shaderobject);CHECKGLERROR
743 qglGetObjectParameterivARB(shaderobject, GL_OBJECT_COMPILE_STATUS_ARB, &shadercompiled);CHECKGLERROR
744 qglGetInfoLogARB(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
746 Con_DPrintf("%s shader compile log:\n%s\n", shadertype, compilelog);
749 qglDeleteObjectARB(shaderobject);CHECKGLERROR
752 qglAttachObjectARB(programobject, shaderobject);CHECKGLERROR
753 qglDeleteObjectARB(shaderobject);CHECKGLERROR
757 unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list)
760 GLuint programobject = 0;
761 char linklog[MAX_INPUTLINE];
764 programobject = qglCreateProgramObjectARB();CHECKGLERROR
768 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER_ARB, "vertex", vertexstrings_count, vertexstrings_list))
771 #ifdef GL_GEOMETRY_SHADER_ARB
772 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER_ARB, "geometry", geometrystrings_count, geometrystrings_list))
776 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER_ARB, "fragment", fragmentstrings_count, fragmentstrings_list))
779 qglLinkProgramARB(programobject);CHECKGLERROR
780 qglGetObjectParameterivARB(programobject, GL_OBJECT_LINK_STATUS_ARB, &programlinked);CHECKGLERROR
781 qglGetInfoLogARB(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
784 Con_DPrintf("program link log:\n%s\n", linklog);
785 // software vertex shader is ok but software fragment shader is WAY
786 // too slow, fail program if so.
787 // NOTE: this string might be ATI specific, but that's ok because the
788 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
789 // software fragment shader due to low instruction and dependent
791 if (strstr(linklog, "fragment shader will run in software"))
792 programlinked = false;
796 return programobject;
798 qglDeleteObjectARB(programobject);CHECKGLERROR
802 void GL_Backend_FreeProgram(unsigned int prog)
805 qglDeleteObjectARB(prog);
809 int gl_backend_rebindtextures;
811 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
816 for (i = 0;i < count;i++)
817 *out++ = *in++ + offset;
820 memcpy(out, in, sizeof(*out) * count);
823 // renders triangles using vertices from the active arrays
824 int paranoidblah = 0;
825 void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *elements)
827 unsigned int numelements = numtriangles * 3;
828 if (numvertices < 3 || numtriangles < 1)
830 Con_Printf("R_Mesh_Draw(%d, %d, %d, %8p);\n", firstvertex, numvertices, numtriangles, elements);
834 r_refdef.stats.meshes++;
835 r_refdef.stats.meshes_elements += numelements;
836 if (gl_paranoid.integer)
838 unsigned int i, j, size;
840 if (!qglIsEnabled(GL_VERTEX_ARRAY))
841 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
843 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
845 if (gl_state.pointer_color)
847 if (!qglIsEnabled(GL_COLOR_ARRAY))
848 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
850 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
853 for (i = 0;i < backendarrayunits;i++)
855 if (gl_state.units[i].arrayenabled)
857 GL_ClientActiveTexture(i);
858 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
859 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
861 for (j = 0, size = numvertices * gl_state.units[i].arraycomponents, p = (int *)((float *)gl_state.units[i].pointer_texcoord + firstvertex * gl_state.units[i].arraycomponents);j < size;j++, p++)
865 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
867 if (elements[i] < firstvertex || elements[i] >= firstvertex + numvertices)
869 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in elements list\n", elements[i], firstvertex, firstvertex + numvertices);
875 if (r_render.integer)
878 if (gl_mesh_testmanualfeeding.integer)
882 qglBegin(GL_TRIANGLES);
883 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
885 for (j = 0;j < backendarrayunits;j++)
887 if (gl_state.units[j].pointer_texcoord)
889 if (backendarrayunits > 1)
891 if (gl_state.units[j].arraycomponents == 4)
893 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 4;
894 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
896 else if (gl_state.units[j].arraycomponents == 3)
898 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
899 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
901 else if (gl_state.units[j].arraycomponents == 2)
903 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
904 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
908 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 1;
909 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
914 if (gl_state.units[j].arraycomponents == 4)
916 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 4;
917 qglTexCoord4f(p[0], p[1], p[2], p[3]);
919 else if (gl_state.units[j].arraycomponents == 3)
921 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
922 qglTexCoord3f(p[0], p[1], p[2]);
924 else if (gl_state.units[j].arraycomponents == 2)
926 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
927 qglTexCoord2f(p[0], p[1]);
931 p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 1;
937 if (gl_state.pointer_color)
939 p = ((const GLfloat *)(gl_state.pointer_color)) + elements[i] * 4;
940 qglColor4f(p[0], p[1], p[2], p[3]);
942 p = ((const GLfloat *)(gl_state.pointer_vertex)) + elements[i] * 3;
943 qglVertex3f(p[0], p[1], p[2]);
948 else if (gl_mesh_testarrayelement.integer)
951 qglBegin(GL_TRIANGLES);
952 for (i = 0;i < numtriangles * 3;i++)
954 qglArrayElement(elements[i]);
959 else if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
961 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_INT, elements);
966 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);
972 // restores backend state, used when done with 3D rendering
973 void R_Mesh_Finish(void)
981 for (i = 0;i < backendimageunits;i++)
984 qglBindTexture(GL_TEXTURE_1D, 0);CHECKGLERROR
985 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
988 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
990 if (gl_texturecubemap)
992 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
995 for (i = 0;i < backendarrayunits;i++)
997 GL_ActiveTexture(backendarrayunits - 1 - i);
998 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1000 for (i = 0;i < backendunits;i++)
1002 GL_ActiveTexture(backendunits - 1 - i);
1003 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1004 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1007 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1009 if (gl_texturecubemap)
1011 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1013 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1014 if (gl_combine.integer)
1016 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
1017 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
1020 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1021 qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1023 qglDisable(GL_BLEND);CHECKGLERROR
1024 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1025 qglDepthMask(GL_TRUE);CHECKGLERROR
1026 qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);CHECKGLERROR
1029 void R_Mesh_Matrix(const matrix4x4_t *matrix)
1031 if (memcmp(matrix, &backend_modelmatrix, sizeof(matrix4x4_t)))
1033 double glmatrix[16];
1034 backend_modelmatrix = *matrix;
1035 Matrix4x4_Concat(&backend_modelviewmatrix, &backend_viewmatrix, matrix);
1036 Matrix4x4_ToArrayDoubleGL(&backend_modelviewmatrix, glmatrix);
1038 qglLoadMatrixd(glmatrix);CHECKGLERROR
1042 void R_Mesh_VertexPointer(const float *vertex3f)
1044 if (gl_state.pointer_vertex != vertex3f)
1046 gl_state.pointer_vertex = vertex3f;
1048 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), gl_state.pointer_vertex);
1053 void R_Mesh_ColorPointer(const float *color4f)
1055 if (gl_state.pointer_color != color4f)
1058 if (!gl_state.pointer_color)
1060 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1064 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1065 // when color array is on the glColor gets trashed, set it again
1066 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
1068 gl_state.pointer_color = color4f;
1069 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), gl_state.pointer_color);CHECKGLERROR
1073 void R_Mesh_TexCoordPointer(unsigned int unitnum, unsigned int numcomponents, const float *texcoord)
1075 gltextureunit_t *unit = gl_state.units + unitnum;
1076 // update array settings
1081 if (unit->pointer_texcoord != texcoord || unit->arraycomponents != numcomponents)
1083 unit->pointer_texcoord = texcoord;
1084 unit->arraycomponents = numcomponents;
1085 GL_ClientActiveTexture(unitnum);
1086 qglTexCoordPointer(unit->arraycomponents, GL_FLOAT, sizeof(float) * unit->arraycomponents, unit->pointer_texcoord);CHECKGLERROR
1088 // texture array unit is enabled, enable the array
1089 if (!unit->arrayenabled)
1091 unit->arrayenabled = true;
1092 GL_ClientActiveTexture(unitnum);
1093 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1098 // texture array unit is disabled, disable the array
1099 if (unit->arrayenabled)
1101 unit->arrayenabled = false;
1102 GL_ClientActiveTexture(unitnum);
1103 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1108 void R_Mesh_TexBindAll(unsigned int unitnum, int tex1d, int tex2d, int tex3d, int texcubemap)
1110 gltextureunit_t *unit = gl_state.units + unitnum;
1111 if (unitnum >= backendimageunits)
1113 // update 1d texture binding
1114 if (unit->t1d != tex1d)
1116 GL_ActiveTexture(unitnum);
1117 if (unitnum < backendunits)
1123 qglEnable(GL_TEXTURE_1D);CHECKGLERROR
1130 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1135 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1137 // update 2d texture binding
1138 if (unit->t2d != tex2d)
1140 GL_ActiveTexture(unitnum);
1141 if (unitnum < backendunits)
1147 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
1154 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1159 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1161 // update 3d texture binding
1162 if (unit->t3d != tex3d)
1164 GL_ActiveTexture(unitnum);
1165 if (unitnum < backendunits)
1171 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
1178 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1183 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1185 // update cubemap texture binding
1186 if (unit->tcubemap != texcubemap)
1188 GL_ActiveTexture(unitnum);
1189 if (unitnum < backendunits)
1193 if (unit->tcubemap == 0)
1195 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1202 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1206 unit->tcubemap = texcubemap;
1207 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1211 void R_Mesh_TexBind1D(unsigned int unitnum, int texnum)
1213 gltextureunit_t *unit = gl_state.units + unitnum;
1214 if (unitnum >= backendimageunits)
1216 // update 1d texture binding
1217 if (unit->t1d != texnum)
1219 GL_ActiveTexture(unitnum);
1220 if (unitnum < backendunits)
1226 qglEnable(GL_TEXTURE_1D);CHECKGLERROR
1233 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1238 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1240 // update 2d texture binding
1243 GL_ActiveTexture(unitnum);
1244 if (unitnum < backendunits)
1248 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1252 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1254 // update 3d texture binding
1257 GL_ActiveTexture(unitnum);
1258 if (unitnum < backendunits)
1262 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1266 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1268 // update cubemap texture binding
1271 GL_ActiveTexture(unitnum);
1272 if (unitnum < backendunits)
1276 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1280 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1284 void R_Mesh_TexBind(unsigned int unitnum, int texnum)
1286 gltextureunit_t *unit = gl_state.units + unitnum;
1287 if (unitnum >= backendimageunits)
1289 // update 1d texture binding
1292 GL_ActiveTexture(unitnum);
1293 if (unitnum < backendunits)
1297 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1301 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1303 // update 2d texture binding
1304 if (unit->t2d != texnum)
1306 GL_ActiveTexture(unitnum);
1307 if (unitnum < backendunits)
1313 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
1320 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1325 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1327 // update 3d texture binding
1330 GL_ActiveTexture(unitnum);
1331 if (unitnum < backendunits)
1335 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1339 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1341 // update cubemap texture binding
1342 if (unit->tcubemap != 0)
1344 GL_ActiveTexture(unitnum);
1345 if (unitnum < backendunits)
1349 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1353 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1357 void R_Mesh_TexBind3D(unsigned int unitnum, int texnum)
1359 gltextureunit_t *unit = gl_state.units + unitnum;
1360 if (unitnum >= backendimageunits)
1362 // update 1d texture binding
1365 GL_ActiveTexture(unitnum);
1366 if (unitnum < backendunits)
1370 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1374 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1376 // update 2d texture binding
1379 GL_ActiveTexture(unitnum);
1380 if (unitnum < backendunits)
1384 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1388 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1390 // update 3d texture binding
1391 if (unit->t3d != texnum)
1393 GL_ActiveTexture(unitnum);
1394 if (unitnum < backendunits)
1400 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
1407 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1412 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1414 // update cubemap texture binding
1415 if (unit->tcubemap != 0)
1417 GL_ActiveTexture(unitnum);
1418 if (unitnum < backendunits)
1422 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1426 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1430 void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum)
1432 gltextureunit_t *unit = gl_state.units + unitnum;
1433 if (unitnum >= backendimageunits)
1435 // update 1d texture binding
1438 GL_ActiveTexture(unitnum);
1439 if (unitnum < backendunits)
1443 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1447 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1449 // update 2d texture binding
1452 GL_ActiveTexture(unitnum);
1453 if (unitnum < backendunits)
1457 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1461 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1463 // update 3d texture binding
1466 GL_ActiveTexture(unitnum);
1467 if (unitnum < backendunits)
1471 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1475 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1477 // update cubemap texture binding
1478 if (unit->tcubemap != texnum)
1480 GL_ActiveTexture(unitnum);
1481 if (unitnum < backendunits)
1485 if (unit->tcubemap == 0)
1487 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1494 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1498 unit->tcubemap = texnum;
1499 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1503 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
1505 gltextureunit_t *unit = gl_state.units + unitnum;
1506 if (matrix->m[3][3])
1508 // texmatrix specified, check if it is different
1509 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
1511 double glmatrix[16];
1512 unit->texmatrixenabled = true;
1513 unit->matrix = *matrix;
1515 Matrix4x4_ToArrayDoubleGL(&unit->matrix, glmatrix);
1516 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1517 GL_ActiveTexture(unitnum);
1518 qglLoadMatrixd(glmatrix);CHECKGLERROR
1519 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1524 // no texmatrix specified, revert to identity
1525 if (unit->texmatrixenabled)
1527 unit->texmatrixenabled = false;
1529 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1530 GL_ActiveTexture(unitnum);
1531 qglLoadIdentity();CHECKGLERROR
1532 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1537 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
1539 gltextureunit_t *unit = gl_state.units + unitnum;
1541 if (gl_combine.integer)
1543 // GL_ARB_texture_env_combine
1545 combinergb = GL_MODULATE;
1547 combinealpha = GL_MODULATE;
1552 if (unit->combinergb != combinergb)
1554 unit->combinergb = combinergb;
1555 GL_ActiveTexture(unitnum);
1556 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
1558 if (unit->combinealpha != combinealpha)
1560 unit->combinealpha = combinealpha;
1561 GL_ActiveTexture(unitnum);
1562 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
1564 if (unit->rgbscale != rgbscale)
1566 GL_ActiveTexture(unitnum);
1567 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (unit->rgbscale = rgbscale));CHECKGLERROR
1569 if (unit->alphascale != alphascale)
1571 GL_ActiveTexture(unitnum);
1572 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = alphascale));CHECKGLERROR
1579 combinergb = GL_MODULATE;
1580 if (unit->combinergb != combinergb)
1582 unit->combinergb = combinergb;
1583 GL_ActiveTexture(unitnum);
1584 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR
1589 void R_Mesh_TextureState(const rmeshstate_t *m)
1596 if (gl_backend_rebindtextures)
1598 gl_backend_rebindtextures = false;
1599 GL_SetupTextureState();
1603 for (i = 0;i < backendimageunits;i++)
1604 R_Mesh_TexBindAll(i, m->tex1d[i], m->tex[i], m->tex3d[i], m->texcubemap[i]);
1605 for (i = 0;i < backendarrayunits;i++)
1607 if (m->pointer_texcoord3f[i])
1608 R_Mesh_TexCoordPointer(i, 3, m->pointer_texcoord3f[i]);
1610 R_Mesh_TexCoordPointer(i, 2, m->pointer_texcoord[i]);
1612 for (i = 0;i < backendunits;i++)
1614 R_Mesh_TexMatrix(i, &m->texmatrix[i]);
1615 R_Mesh_TexCombine(i, m->texcombinergb[i], m->texcombinealpha[i], m->texrgbscale[i], m->texalphascale[i]);
1620 void R_Mesh_ResetTextureState(void)
1622 unsigned int unitnum;
1627 if (gl_backend_rebindtextures)
1629 gl_backend_rebindtextures = false;
1630 GL_SetupTextureState();
1634 for (unitnum = 0;unitnum < backendimageunits;unitnum++)
1636 gltextureunit_t *unit = gl_state.units + unitnum;
1637 // update 1d texture binding
1640 GL_ActiveTexture(unitnum);
1641 if (unitnum < backendunits)
1643 qglDisable(GL_TEXTURE_1D);CHECKGLERROR
1646 qglBindTexture(GL_TEXTURE_1D, unit->t1d);CHECKGLERROR
1648 // update 2d texture binding
1651 GL_ActiveTexture(unitnum);
1652 if (unitnum < backendunits)
1654 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1657 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
1659 // update 3d texture binding
1662 GL_ActiveTexture(unitnum);
1663 if (unitnum < backendunits)
1665 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1668 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
1670 // update cubemap texture binding
1673 GL_ActiveTexture(unitnum);
1674 if (unitnum < backendunits)
1676 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1679 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
1682 for (unitnum = 0;unitnum < backendarrayunits;unitnum++)
1684 gltextureunit_t *unit = gl_state.units + unitnum;
1685 // texture array unit is disabled, disable the array
1686 if (unit->arrayenabled)
1688 unit->arrayenabled = false;
1689 GL_ClientActiveTexture(unitnum);
1690 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1693 for (unitnum = 0;unitnum < backendunits;unitnum++)
1695 gltextureunit_t *unit = gl_state.units + unitnum;
1696 // no texmatrix specified, revert to identity
1697 if (unit->texmatrixenabled)
1699 unit->texmatrixenabled = false;
1701 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1702 GL_ActiveTexture(unitnum);
1703 qglLoadIdentity();CHECKGLERROR
1704 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1706 if (gl_combine.integer)
1708 // GL_ARB_texture_env_combine
1709 if (unit->combinergb != GL_MODULATE)
1711 unit->combinergb = GL_MODULATE;
1712 GL_ActiveTexture(unitnum);
1713 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
1715 if (unit->combinealpha != GL_MODULATE)
1717 unit->combinealpha = GL_MODULATE;
1718 GL_ActiveTexture(unitnum);
1719 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
1721 if (unit->rgbscale != 1)
1723 GL_ActiveTexture(unitnum);
1724 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (unit->rgbscale = 1));CHECKGLERROR
1726 if (unit->alphascale != 1)
1728 GL_ActiveTexture(unitnum);
1729 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = 1));CHECKGLERROR
1735 if (unit->combinergb != GL_MODULATE)
1737 unit->combinergb = GL_MODULATE;
1738 GL_ActiveTexture(unitnum);
1739 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR
1745 void R_Mesh_Draw_ShowTris(int firstvertex, int numvertices, int numtriangles, const int *elements)
1749 for (;numtriangles;numtriangles--, elements += 3)
1751 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
1752 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
1753 qglArrayElement(elements[2]);qglArrayElement(elements[0]);