3 #include "cl_collision.h"
6 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
7 extern D3DCAPS9 vid_d3d9caps;
10 #define MAX_RENDERTARGETS 4
12 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
13 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)"};
14 cvar_t gl_mesh_prefer_short_elements = {CVAR_SAVE, "gl_mesh_prefer_short_elements", "1", "use GL_UNSIGNED_SHORT element arrays instead of GL_UNSIGNED_INT"};
15 cvar_t gl_mesh_separatearrays = {0, "gl_mesh_separatearrays", "1", "use several separate vertex arrays rather than one combined stream"};
16 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
17 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
19 cvar_t r_render = {0, "r_render", "1", "enables rendering 3D views (you want this on!)"};
20 cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
21 cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
22 cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
23 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
24 cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
25 cvar_t gl_vbo_dynamicvertex = {CVAR_SAVE, "gl_vbo_dynamicvertex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
26 cvar_t gl_vbo_dynamicindex = {CVAR_SAVE, "gl_vbo_dynamicindex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
27 cvar_t gl_fbo = {CVAR_SAVE, "gl_fbo", "1", "make use of GL_ARB_framebuffer_object extension to enable shadowmaps and other features using pixel formats different from the framebuffer"};
29 cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
30 qboolean v_flipped_state = false;
32 r_viewport_t gl_viewport;
33 matrix4x4_t gl_modelmatrix;
34 matrix4x4_t gl_viewmatrix;
35 matrix4x4_t gl_modelviewmatrix;
36 matrix4x4_t gl_projectionmatrix;
37 matrix4x4_t gl_modelviewprojectionmatrix;
38 float gl_modelview16f[16];
39 float gl_modelviewprojection16f[16];
40 qboolean gl_modelmatrixchanged;
42 int gl_maxdrawrangeelementsvertices;
43 int gl_maxdrawrangeelementsindices;
48 void GL_PrintError(int errornumber, const char *filename, int linenumber)
52 #ifdef GL_INVALID_ENUM
54 Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
57 #ifdef GL_INVALID_VALUE
58 case GL_INVALID_VALUE:
59 Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
62 #ifdef GL_INVALID_OPERATION
63 case GL_INVALID_OPERATION:
64 Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
67 #ifdef GL_STACK_OVERFLOW
68 case GL_STACK_OVERFLOW:
69 Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
72 #ifdef GL_STACK_UNDERFLOW
73 case GL_STACK_UNDERFLOW:
74 Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
77 #ifdef GL_OUT_OF_MEMORY
78 case GL_OUT_OF_MEMORY:
79 Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
82 #ifdef GL_TABLE_TOO_LARGE
83 case GL_TABLE_TOO_LARGE:
84 Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
87 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
88 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
89 Con_Printf("GL_INVALID_FRAMEBUFFER_OPERATION at %s:%i\n", filename, linenumber);
93 Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
99 #define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
101 void SCR_ScreenShot_f (void);
103 typedef struct gltextureunit_s
105 int pointer_texcoord_components;
106 int pointer_texcoord_gltype;
107 size_t pointer_texcoord_stride;
108 const void *pointer_texcoord_pointer;
109 const r_meshbuffer_t *pointer_texcoord_vertexbuffer;
110 size_t pointer_texcoord_offset;
113 int t2d, t3d, tcubemap;
115 int rgbscale, alphascale;
117 int combinergb, combinealpha;
118 // texmatrixenabled exists only to avoid unnecessary texmatrix compares
119 int texmatrixenabled;
124 typedef struct gl_state_s
132 int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order)
136 float polygonoffset[2];
139 float alphafuncvalue;
142 unsigned int clientunit;
143 gltextureunit_t units[MAX_TEXTUREUNITS];
147 int vertexbufferobject;
148 int elementbufferobject;
149 int framebufferobject;
150 qboolean pointer_color_enabled;
152 int pointer_vertex_components;
153 int pointer_vertex_gltype;
154 size_t pointer_vertex_stride;
155 const void *pointer_vertex_pointer;
156 const r_meshbuffer_t *pointer_vertex_vertexbuffer;
157 size_t pointer_vertex_offset;
159 int pointer_color_components;
160 int pointer_color_gltype;
161 size_t pointer_color_stride;
162 const void *pointer_color_pointer;
163 const r_meshbuffer_t *pointer_color_vertexbuffer;
164 size_t pointer_color_offset;
166 void *preparevertices_tempdata;
167 size_t preparevertices_tempdatamaxsize;
168 r_meshbuffer_t *preparevertices_dynamicvertexbuffer;
169 r_vertexposition_t *preparevertices_vertexposition;
170 r_vertexgeneric_t *preparevertices_vertexgeneric;
171 r_vertexmesh_t *preparevertices_vertexmesh;
172 int preparevertices_numvertices;
174 r_meshbuffer_t *draw_dynamicindexbuffer;
176 qboolean usevbo_staticvertex;
177 qboolean usevbo_staticindex;
178 qboolean usevbo_dynamicvertex;
179 qboolean usevbo_dynamicindex;
181 memexpandablearray_t meshbufferarray;
186 // rtexture_t *d3drt_depthtexture;
187 // rtexture_t *d3drt_colortextures[MAX_RENDERTARGETS];
188 IDirect3DSurface9 *d3drt_depthsurface;
189 IDirect3DSurface9 *d3drt_colorsurfaces[MAX_RENDERTARGETS];
190 IDirect3DSurface9 *d3drt_backbufferdepthsurface;
191 IDirect3DSurface9 *d3drt_backbuffercolorsurface;
192 void *d3dvertexbuffer;
194 size_t d3dvertexsize;
199 static gl_state_t gl_state;
203 note: here's strip order for a terrain row:
210 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
212 *elements++ = i + row;
214 *elements++ = i + row + 1;
217 *elements++ = i + row + 1;
220 for (y = 0;y < rows - 1;y++)
222 for (x = 0;x < columns - 1;x++)
225 *elements++ = i + columns;
227 *elements++ = i + columns + 1;
230 *elements++ = i + columns + 1;
241 for (y = 0;y < rows - 1;y++)
243 for (x = 0;x < columns - 1;x++)
247 *elements++ = i + columns;
248 *elements++ = i + columns + 1;
249 *elements++ = i + columns;
250 *elements++ = i + columns + 1;
256 int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
257 unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
258 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
259 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
261 void GL_VBOStats_f(void)
263 GL_Mesh_ListVBOs(true);
266 static void GL_Backend_ResetState(void);
268 static void R_Mesh_InitVertexDeclarations(void);
269 static void R_Mesh_DestroyVertexDeclarations(void);
271 static void R_Mesh_SetUseVBO(void)
273 switch(vid.renderpath)
275 case RENDERPATH_GL11:
276 case RENDERPATH_GL13:
277 case RENDERPATH_GL20:
278 case RENDERPATH_CGGL:
279 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
280 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
281 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
282 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
284 case RENDERPATH_D3D9:
285 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
286 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
288 case RENDERPATH_D3D10:
289 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
291 case RENDERPATH_D3D11:
292 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
297 static void gl_backend_start(void)
299 memset(&gl_state, 0, sizeof(gl_state));
301 R_Mesh_InitVertexDeclarations();
304 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
306 Con_DPrintf("OpenGL backend started.\n");
310 GL_Backend_ResetState();
312 switch(vid.renderpath)
314 case RENDERPATH_GL11:
315 case RENDERPATH_GL13:
316 case RENDERPATH_GL20:
317 case RENDERPATH_CGGL:
319 case RENDERPATH_D3D9:
321 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
322 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
325 case RENDERPATH_D3D10:
326 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
328 case RENDERPATH_D3D11:
329 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
334 static void gl_backend_shutdown(void)
336 Con_DPrint("OpenGL Backend shutting down\n");
338 switch(vid.renderpath)
340 case RENDERPATH_GL11:
341 case RENDERPATH_GL13:
342 case RENDERPATH_GL20:
343 case RENDERPATH_CGGL:
345 case RENDERPATH_D3D9:
347 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
348 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
351 case RENDERPATH_D3D10:
352 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
354 case RENDERPATH_D3D11:
355 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
359 if (gl_state.preparevertices_tempdata)
360 Mem_Free(gl_state.preparevertices_tempdata);
361 if (gl_state.preparevertices_dynamicvertexbuffer)
362 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
364 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
366 R_Mesh_DestroyVertexDeclarations();
368 memset(&gl_state, 0, sizeof(gl_state));
371 static void gl_backend_newmap(void)
375 static void gl_backend_devicelost(void)
378 r_meshbuffer_t *buffer;
380 gl_state.d3dvertexbuffer = NULL;
382 switch(vid.renderpath)
384 case RENDERPATH_GL11:
385 case RENDERPATH_GL13:
386 case RENDERPATH_GL20:
387 case RENDERPATH_CGGL:
389 case RENDERPATH_D3D9:
391 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
392 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
395 case RENDERPATH_D3D10:
396 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
398 case RENDERPATH_D3D11:
399 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
402 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
403 for (i = 0;i < endindex;i++)
405 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
406 if (!buffer || !buffer->isdynamic)
408 switch(vid.renderpath)
410 case RENDERPATH_GL11:
411 case RENDERPATH_GL13:
412 case RENDERPATH_GL20:
413 case RENDERPATH_CGGL:
415 case RENDERPATH_D3D9:
417 if (buffer->devicebuffer)
419 if (buffer->isindexbuffer)
420 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
422 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
423 buffer->devicebuffer = NULL;
427 case RENDERPATH_D3D10:
428 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
430 case RENDERPATH_D3D11:
431 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
437 static void gl_backend_devicerestored(void)
439 switch(vid.renderpath)
441 case RENDERPATH_GL11:
442 case RENDERPATH_GL13:
443 case RENDERPATH_GL20:
444 case RENDERPATH_CGGL:
446 case RENDERPATH_D3D9:
448 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
449 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
452 case RENDERPATH_D3D10:
453 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
455 case RENDERPATH_D3D11:
456 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
461 void gl_backend_init(void)
465 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
467 polygonelement3s[i * 3 + 0] = 0;
468 polygonelement3s[i * 3 + 1] = i + 1;
469 polygonelement3s[i * 3 + 2] = i + 2;
471 // elements for rendering a series of quads as triangles
472 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
474 quadelement3s[i * 6 + 0] = i * 4;
475 quadelement3s[i * 6 + 1] = i * 4 + 1;
476 quadelement3s[i * 6 + 2] = i * 4 + 2;
477 quadelement3s[i * 6 + 3] = i * 4;
478 quadelement3s[i * 6 + 4] = i * 4 + 2;
479 quadelement3s[i * 6 + 5] = i * 4 + 3;
482 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
483 polygonelement3i[i] = polygonelement3s[i];
484 for (i = 0;i < QUADELEMENTS_MAXQUADS*3;i++)
485 quadelement3i[i] = quadelement3s[i];
487 Cvar_RegisterVariable(&r_render);
488 Cvar_RegisterVariable(&r_renderview);
489 Cvar_RegisterVariable(&r_waterwarp);
490 Cvar_RegisterVariable(&gl_polyblend);
491 Cvar_RegisterVariable(&v_flipped);
492 Cvar_RegisterVariable(&gl_dither);
493 Cvar_RegisterVariable(&gl_vbo);
494 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
495 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
496 Cvar_RegisterVariable(&gl_paranoid);
497 Cvar_RegisterVariable(&gl_printcheckerror);
499 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
500 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
501 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
502 Cvar_RegisterVariable(&gl_mesh_separatearrays);
504 Cmd_AddCommand("gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
506 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
509 void GL_SetMirrorState(qboolean state);
511 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
515 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
516 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
518 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
520 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
521 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
522 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
524 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
527 static int bboxedges[12][2] =
546 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
548 int i, ix1, iy1, ix2, iy2;
549 float x1, y1, x2, y2;
560 scissor[0] = r_refdef.view.viewport.x;
561 scissor[1] = r_refdef.view.viewport.y;
562 scissor[2] = r_refdef.view.viewport.width;
563 scissor[3] = r_refdef.view.viewport.height;
565 // if view is inside the box, just say yes it's visible
566 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
569 x1 = y1 = x2 = y2 = 0;
571 // transform all corners that are infront of the nearclip plane
572 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
573 plane4f[3] = r_refdef.view.frustum[4].dist;
575 for (i = 0;i < 8;i++)
577 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
578 dist[i] = DotProduct4(corner[i], plane4f);
579 sign[i] = dist[i] > 0;
582 VectorCopy(corner[i], vertex[numvertices]);
586 // if some points are behind the nearclip, add clipped edge points to make
587 // sure that the scissor boundary is complete
588 if (numvertices > 0 && numvertices < 8)
590 // add clipped edge points
591 for (i = 0;i < 12;i++)
595 if (sign[j] != sign[k])
597 f = dist[j] / (dist[j] - dist[k]);
598 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
604 // if we have no points to check, it is behind the view plane
608 // if we have some points to transform, check what screen area is covered
609 x1 = y1 = x2 = y2 = 0;
611 //Con_Printf("%i vertices to transform...\n", numvertices);
612 for (i = 0;i < numvertices;i++)
614 VectorCopy(vertex[i], v);
615 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
616 //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
619 if (x1 > v2[0]) x1 = v2[0];
620 if (x2 < v2[0]) x2 = v2[0];
621 if (y1 > v2[1]) y1 = v2[1];
622 if (y2 < v2[1]) y2 = v2[1];
631 // now convert the scissor rectangle to integer screen coordinates
632 ix1 = (int)(x1 - 1.0f);
633 //iy1 = vid.height - (int)(y2 - 1.0f);
634 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
635 iy1 = (int)(y1 - 1.0f);
636 ix2 = (int)(x2 + 1.0f);
637 //iy2 = vid.height - (int)(y1 + 1.0f);
638 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
639 iy2 = (int)(y2 + 1.0f);
640 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
642 // clamp it to the screen
643 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
644 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
645 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
646 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
648 // if it is inside out, it's not visible
649 if (ix2 <= ix1 || iy2 <= iy1)
652 // the light area is visible, set up the scissor rectangle
655 scissor[2] = ix2 - ix1;
656 scissor[3] = iy2 - iy1;
658 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
659 switch(vid.renderpath)
661 case RENDERPATH_D3D9:
662 case RENDERPATH_D3D10:
663 case RENDERPATH_D3D11:
664 scissor[1] = vid.height - scissor[1] - scissor[3];
666 case RENDERPATH_GL11:
667 case RENDERPATH_GL13:
668 case RENDERPATH_GL20:
669 case RENDERPATH_CGGL:
677 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
681 float clipPlane[4], v3[3], v4[3];
684 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
686 VectorSet(normal, normalx, normaly, normalz);
687 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
688 VectorScale(normal, dist, v3);
689 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
690 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
691 clipPlane[3] = -DotProduct(v4, clipPlane);
695 // testing code for comparing results
697 VectorCopy4(clipPlane, clipPlane2);
698 R_EntityMatrix(&identitymatrix);
699 VectorSet(q, normal[0], normal[1], normal[2], -dist);
700 qglClipPlane(GL_CLIP_PLANE0, q);
701 qglGetClipPlane(GL_CLIP_PLANE0, q);
702 VectorCopy4(q, clipPlane);
706 // Calculate the clip-space corner point opposite the clipping plane
707 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
708 // transform it into camera space by multiplying it
709 // by the inverse of the projection matrix
710 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
711 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
713 q[3] = (1.0f + m[10]) / m[14];
715 // Calculate the scaled plane vector
716 d = 2.0f / DotProduct4(clipPlane, q);
718 // Replace the third row of the projection matrix
719 m[2] = clipPlane[0] * d;
720 m[6] = clipPlane[1] * d;
721 m[10] = clipPlane[2] * d + 1.0f;
722 m[14] = clipPlane[3] * d;
725 void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float nearclip, float farclip, const float *nearplane)
727 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
729 memset(v, 0, sizeof(*v));
730 v->type = R_VIEWPORTTYPE_ORTHO;
731 v->cameramatrix = *cameramatrix;
738 memset(m, 0, sizeof(m));
739 m[0] = 2/(right - left);
740 m[5] = 2/(top - bottom);
741 m[10] = -2/(zFar - zNear);
742 m[12] = - (right + left)/(right - left);
743 m[13] = - (top + bottom)/(top - bottom);
744 m[14] = - (zFar + zNear)/(zFar - zNear);
746 switch(vid.renderpath)
748 case RENDERPATH_GL11:
749 case RENDERPATH_GL13:
750 case RENDERPATH_GL20:
751 case RENDERPATH_CGGL:
753 case RENDERPATH_D3D9:
754 case RENDERPATH_D3D10:
755 case RENDERPATH_D3D11:
756 m[10] = -1/(zFar - zNear);
757 m[14] = -zNear/(zFar-zNear);
760 v->screentodepth[0] = -farclip / (farclip - nearclip);
761 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
763 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
766 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
768 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
774 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
775 R_Viewport_TransformToScreen(v, test1, test2);
776 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
781 void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
783 matrix4x4_t tempmatrix, basematrix;
785 memset(v, 0, sizeof(*v));
787 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
788 v->cameramatrix = *cameramatrix;
795 memset(m, 0, sizeof(m));
796 m[0] = 1.0 / frustumx;
797 m[5] = 1.0 / frustumy;
798 m[10] = -(farclip + nearclip) / (farclip - nearclip);
800 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
801 v->screentodepth[0] = -farclip / (farclip - nearclip);
802 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
804 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
805 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
806 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
807 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
810 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
812 if(v_flipped.integer)
820 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
823 void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, const float *nearplane)
825 matrix4x4_t tempmatrix, basematrix;
826 const float nudge = 1.0 - 1.0 / (1<<23);
828 memset(v, 0, sizeof(*v));
830 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
831 v->cameramatrix = *cameramatrix;
838 memset(m, 0, sizeof(m));
839 m[ 0] = 1.0 / frustumx;
840 m[ 5] = 1.0 / frustumy;
843 m[14] = -2 * nearclip * nudge;
844 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
845 v->screentodepth[1] = m[14] * -0.5;
847 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
848 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
849 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
850 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
853 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
855 if(v_flipped.integer)
863 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
866 float cubeviewmatrix[6][16] =
868 // standard cubemap projections
906 float rectviewmatrix[6][16] =
908 // sign-preserving cubemap projections
947 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
949 matrix4x4_t tempmatrix, basematrix;
951 memset(v, 0, sizeof(*v));
952 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
953 v->cameramatrix = *cameramatrix;
957 memset(m, 0, sizeof(m));
959 m[10] = -(farclip + nearclip) / (farclip - nearclip);
961 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
963 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
964 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
965 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
968 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
970 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
973 void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane)
975 matrix4x4_t tempmatrix, basematrix;
977 memset(v, 0, sizeof(*v));
978 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
979 v->cameramatrix = *cameramatrix;
980 v->x = (side & 1) * size;
981 v->y = (side >> 1) * size;
985 memset(m, 0, sizeof(m));
986 m[0] = m[5] = 1.0f * ((float)size - border) / size;
987 m[10] = -(farclip + nearclip) / (farclip - nearclip);
989 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
991 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
992 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
993 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
995 switch(vid.renderpath)
997 case RENDERPATH_GL20:
998 case RENDERPATH_CGGL:
999 case RENDERPATH_GL13:
1000 case RENDERPATH_GL11:
1002 case RENDERPATH_D3D9:
1005 case RENDERPATH_D3D10:
1006 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1008 case RENDERPATH_D3D11:
1009 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1014 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1016 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1019 void R_SetViewport(const r_viewport_t *v)
1024 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1025 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1027 // copy over the matrices to our state
1028 gl_viewmatrix = v->viewmatrix;
1029 gl_projectionmatrix = v->projectmatrix;
1031 switch(vid.renderpath)
1033 case RENDERPATH_GL20:
1034 case RENDERPATH_CGGL:
1036 // qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1038 case RENDERPATH_GL13:
1039 case RENDERPATH_GL11:
1041 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1042 // Load the projection matrix into OpenGL
1043 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1044 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1045 qglLoadMatrixf(m);CHECKGLERROR
1046 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1048 case RENDERPATH_D3D9:
1051 D3DVIEWPORT9 d3dviewport;
1052 d3dviewport.X = gl_viewport.x;
1053 d3dviewport.Y = gl_viewport.y;
1054 d3dviewport.Width = gl_viewport.width;
1055 d3dviewport.Height = gl_viewport.height;
1056 d3dviewport.MinZ = gl_state.depthrange[0];
1057 d3dviewport.MaxZ = gl_state.depthrange[1];
1058 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1062 case RENDERPATH_D3D10:
1063 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1065 case RENDERPATH_D3D11:
1066 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1070 // force an update of the derived matrices
1071 gl_modelmatrixchanged = true;
1072 R_EntityMatrix(&gl_modelmatrix);
1075 void R_GetViewport(r_viewport_t *v)
1080 static void GL_BindVBO(int bufferobject)
1082 if (gl_state.vertexbufferobject != bufferobject)
1084 gl_state.vertexbufferobject = bufferobject;
1086 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1090 static void GL_BindEBO(int bufferobject)
1092 if (gl_state.elementbufferobject != bufferobject)
1094 gl_state.elementbufferobject = bufferobject;
1096 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1100 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1103 switch(vid.renderpath)
1105 case RENDERPATH_GL11:
1106 case RENDERPATH_GL13:
1107 case RENDERPATH_GL20:
1108 case RENDERPATH_CGGL:
1109 if (!vid.support.ext_framebuffer_object)
1111 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1112 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1113 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1114 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1115 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1116 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1117 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1119 case RENDERPATH_D3D9:
1120 case RENDERPATH_D3D10:
1121 case RENDERPATH_D3D11:
1127 void R_Mesh_DestroyFramebufferObject(int fbo)
1129 switch(vid.renderpath)
1131 case RENDERPATH_GL11:
1132 case RENDERPATH_GL13:
1133 case RENDERPATH_GL20:
1134 case RENDERPATH_CGGL:
1136 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1138 case RENDERPATH_D3D9:
1139 case RENDERPATH_D3D10:
1140 case RENDERPATH_D3D11:
1146 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1148 // LordHavoc: for some weird reason the redundant SetDepthStencilSurface calls are necessary (otherwise the lights fail depth test, as if they were using the shadowmap depth surface and render target still)
1149 if (gl_state.d3drt_depthsurface == depthsurface && gl_state.d3drt_colorsurfaces[0] == colorsurface0 && gl_state.d3drt_colorsurfaces[1] == colorsurface1 && gl_state.d3drt_colorsurfaces[2] == colorsurface2 && gl_state.d3drt_colorsurfaces[3] == colorsurface3)
1152 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1153 if (gl_state.d3drt_depthsurface != depthsurface)
1155 gl_state.d3drt_depthsurface = depthsurface;
1156 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1158 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1160 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1161 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1163 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1165 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1166 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1168 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1170 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1171 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1173 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1175 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1176 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1181 void R_Mesh_ResetRenderTargets(void)
1183 switch(vid.renderpath)
1185 case RENDERPATH_GL11:
1186 case RENDERPATH_GL13:
1187 case RENDERPATH_GL20:
1188 case RENDERPATH_CGGL:
1189 if (gl_state.framebufferobject)
1191 gl_state.framebufferobject = 0;
1192 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1195 case RENDERPATH_D3D9:
1197 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1200 case RENDERPATH_D3D10:
1201 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1203 case RENDERPATH_D3D11:
1204 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1209 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1213 rtexture_t *textures[5];
1214 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1215 textures[4] = depthtexture;
1216 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1217 for (j = 0;j < 5;j++)
1219 for (i = 0;i < vid.teximageunits;i++)
1220 if (gl_state.units[i].texture == textures[j])
1221 R_Mesh_TexBind(i, NULL);
1222 // set up framebuffer object or render targets for the active rendering API
1223 switch(vid.renderpath)
1225 case RENDERPATH_GL11:
1226 case RENDERPATH_GL13:
1227 case RENDERPATH_GL20:
1228 case RENDERPATH_CGGL:
1229 if (gl_state.framebufferobject != fbo)
1231 gl_state.framebufferobject = fbo;
1232 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1235 case RENDERPATH_D3D9:
1237 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1238 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1241 IDirect3DSurface9 *colorsurfaces[4];
1242 for (i = 0;i < 4;i++)
1244 colorsurfaces[i] = NULL;
1246 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1248 // set the render targets for real
1249 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1250 // release the texture surface levels (they won't be lost while bound...)
1251 for (i = 0;i < 4;i++)
1253 IDirect3DSurface9_Release(colorsurfaces[i]);
1256 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1259 case RENDERPATH_D3D10:
1260 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1262 case RENDERPATH_D3D11:
1263 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1269 static int d3dcmpforglfunc(int f)
1273 case GL_NEVER: return D3DCMP_NEVER;
1274 case GL_LESS: return D3DCMP_LESS;
1275 case GL_EQUAL: return D3DCMP_EQUAL;
1276 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1277 case GL_GREATER: return D3DCMP_GREATER;
1278 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1279 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1280 case GL_ALWAYS: return D3DCMP_ALWAYS;
1281 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1285 static int d3dstencilopforglfunc(int f)
1289 case GL_KEEP: return D3DSTENCILOP_KEEP;
1290 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1291 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1292 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1298 static void GL_Backend_ResetState(void)
1301 gl_state.active = true;
1302 gl_state.depthtest = true;
1303 gl_state.alphatest = false;
1304 gl_state.alphafunc = GL_GEQUAL;
1305 gl_state.alphafuncvalue = 0.5f;
1306 gl_state.blendfunc1 = GL_ONE;
1307 gl_state.blendfunc2 = GL_ZERO;
1308 gl_state.blend = false;
1309 gl_state.depthmask = GL_TRUE;
1310 gl_state.colormask = 15;
1311 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1312 gl_state.lockrange_first = 0;
1313 gl_state.lockrange_count = 0;
1314 gl_state.cullface = GL_NONE;
1315 gl_state.cullfaceenable = false;
1316 gl_state.polygonoffset[0] = 0;
1317 gl_state.polygonoffset[1] = 0;
1318 gl_state.framebufferobject = 0;
1319 gl_state.depthfunc = GL_LEQUAL;
1321 switch(vid.renderpath)
1323 case RENDERPATH_D3D9:
1326 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1327 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
1328 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
1329 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, gl_state.alphafuncvalue * 256.0f, 255));
1330 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1331 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1332 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1333 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1334 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1335 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1339 case RENDERPATH_D3D10:
1340 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1342 case RENDERPATH_D3D11:
1343 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1345 case RENDERPATH_GL20:
1346 case RENDERPATH_CGGL:
1349 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1350 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1351 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1352 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1353 qglDisable(GL_BLEND);CHECKGLERROR
1354 qglCullFace(gl_state.cullface);CHECKGLERROR
1355 qglDisable(GL_CULL_FACE);CHECKGLERROR
1356 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1357 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1358 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1359 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1361 if (vid.support.arb_vertex_buffer_object)
1363 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1364 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1367 if (vid.support.ext_framebuffer_object)
1369 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1370 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1373 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1374 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1376 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1377 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1378 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1380 if (vid.support.ext_framebuffer_object)
1381 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1383 gl_state.unit = MAX_TEXTUREUNITS;
1384 gl_state.clientunit = MAX_TEXTUREUNITS;
1385 for (i = 0;i < vid.teximageunits;i++)
1387 GL_ActiveTexture(i);
1388 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1389 if (vid.support.ext_texture_3d)
1391 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1393 if (vid.support.arb_texture_cube_map)
1395 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1399 for (i = 0;i < vid.texarrayunits;i++)
1401 GL_ClientActiveTexture(i);
1403 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1404 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1408 case RENDERPATH_GL13:
1409 case RENDERPATH_GL11:
1412 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1413 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1414 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1415 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1416 qglDisable(GL_BLEND);CHECKGLERROR
1417 qglCullFace(gl_state.cullface);CHECKGLERROR
1418 qglDisable(GL_CULL_FACE);CHECKGLERROR
1419 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1420 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1421 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1422 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1424 if (vid.support.arb_vertex_buffer_object)
1426 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1427 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1430 if (vid.support.ext_framebuffer_object)
1432 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1433 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1436 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1437 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1439 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1440 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1441 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1443 if (vid.support.ext_framebuffer_object)
1444 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1446 gl_state.unit = MAX_TEXTUREUNITS;
1447 gl_state.clientunit = MAX_TEXTUREUNITS;
1448 for (i = 0;i < vid.texunits;i++)
1450 GL_ActiveTexture(i);
1451 GL_ClientActiveTexture(i);
1452 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1453 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1454 if (vid.support.ext_texture_3d)
1456 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1457 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1459 if (vid.support.arb_texture_cube_map)
1461 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1462 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1465 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1466 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1467 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1468 qglLoadIdentity();CHECKGLERROR
1469 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1470 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1477 void GL_ActiveTexture(unsigned int num)
1479 if (gl_state.unit != num)
1481 gl_state.unit = num;
1482 switch(vid.renderpath)
1484 case RENDERPATH_GL11:
1485 case RENDERPATH_GL13:
1486 case RENDERPATH_GL20:
1487 case RENDERPATH_CGGL:
1488 if (qglActiveTexture)
1491 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1495 case RENDERPATH_D3D9:
1496 case RENDERPATH_D3D10:
1497 case RENDERPATH_D3D11:
1503 void GL_ClientActiveTexture(unsigned int num)
1505 if (gl_state.clientunit != num)
1507 gl_state.clientunit = num;
1508 switch(vid.renderpath)
1510 case RENDERPATH_GL11:
1511 case RENDERPATH_GL13:
1512 case RENDERPATH_GL20:
1513 case RENDERPATH_CGGL:
1514 if (qglActiveTexture)
1517 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1521 case RENDERPATH_D3D9:
1522 case RENDERPATH_D3D10:
1523 case RENDERPATH_D3D11:
1529 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1531 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1533 qboolean blendenable;
1534 gl_state.blendfunc1 = blendfunc1;
1535 gl_state.blendfunc2 = blendfunc2;
1536 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1537 switch(vid.renderpath)
1539 case RENDERPATH_GL11:
1540 case RENDERPATH_GL13:
1541 case RENDERPATH_GL20:
1542 case RENDERPATH_CGGL:
1544 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1545 if (gl_state.blend != blendenable)
1547 gl_state.blend = blendenable;
1548 if (!gl_state.blend)
1550 qglDisable(GL_BLEND);CHECKGLERROR
1554 qglEnable(GL_BLEND);CHECKGLERROR
1558 case RENDERPATH_D3D9:
1563 D3DBLEND d3dblendfunc[2];
1564 glblendfunc[0] = gl_state.blendfunc1;
1565 glblendfunc[1] = gl_state.blendfunc2;
1566 for (i = 0;i < 2;i++)
1568 switch(glblendfunc[i])
1570 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1571 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1572 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1573 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1574 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1575 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1576 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1577 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1578 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1579 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1582 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1583 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1584 if (gl_state.blend != blendenable)
1586 gl_state.blend = blendenable;
1587 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1592 case RENDERPATH_D3D10:
1593 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1595 case RENDERPATH_D3D11:
1596 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1602 void GL_DepthMask(int state)
1604 if (gl_state.depthmask != state)
1606 gl_state.depthmask = state;
1607 switch(vid.renderpath)
1609 case RENDERPATH_GL11:
1610 case RENDERPATH_GL13:
1611 case RENDERPATH_GL20:
1612 case RENDERPATH_CGGL:
1614 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1616 case RENDERPATH_D3D9:
1618 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1621 case RENDERPATH_D3D10:
1622 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1624 case RENDERPATH_D3D11:
1625 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1631 void GL_DepthTest(int state)
1633 if (gl_state.depthtest != state)
1635 gl_state.depthtest = state;
1636 switch(vid.renderpath)
1638 case RENDERPATH_GL11:
1639 case RENDERPATH_GL13:
1640 case RENDERPATH_GL20:
1641 case RENDERPATH_CGGL:
1643 if (gl_state.depthtest)
1645 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1649 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1652 case RENDERPATH_D3D9:
1654 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1657 case RENDERPATH_D3D10:
1658 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1660 case RENDERPATH_D3D11:
1661 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1667 void GL_DepthFunc(int state)
1669 if (gl_state.depthfunc != state)
1671 gl_state.depthfunc = state;
1672 switch(vid.renderpath)
1674 case RENDERPATH_GL11:
1675 case RENDERPATH_GL13:
1676 case RENDERPATH_GL20:
1677 case RENDERPATH_CGGL:
1679 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1681 case RENDERPATH_D3D9:
1683 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1686 case RENDERPATH_D3D10:
1687 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1689 case RENDERPATH_D3D11:
1690 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1696 void GL_DepthRange(float nearfrac, float farfrac)
1698 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1700 gl_state.depthrange[0] = nearfrac;
1701 gl_state.depthrange[1] = farfrac;
1702 switch(vid.renderpath)
1704 case RENDERPATH_GL11:
1705 case RENDERPATH_GL13:
1706 case RENDERPATH_GL20:
1707 case RENDERPATH_CGGL:
1708 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1710 case RENDERPATH_D3D9:
1713 D3DVIEWPORT9 d3dviewport;
1714 d3dviewport.X = gl_viewport.x;
1715 d3dviewport.Y = gl_viewport.y;
1716 d3dviewport.Width = gl_viewport.width;
1717 d3dviewport.Height = gl_viewport.height;
1718 d3dviewport.MinZ = gl_state.depthrange[0];
1719 d3dviewport.MaxZ = gl_state.depthrange[1];
1720 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1724 case RENDERPATH_D3D10:
1725 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1727 case RENDERPATH_D3D11:
1728 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1734 void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask)
1736 switch (vid.renderpath)
1738 case RENDERPATH_GL11:
1739 case RENDERPATH_GL13:
1740 case RENDERPATH_GL20:
1741 case RENDERPATH_CGGL:
1745 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1749 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1751 if (vid.support.ati_separate_stencil)
1753 qglStencilMask(writemask);CHECKGLERROR
1754 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1755 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1756 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1758 else if (vid.support.ext_stencil_two_side)
1760 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1761 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1762 qglStencilMask(writemask);CHECKGLERROR
1763 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1764 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1765 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1766 qglStencilMask(writemask);CHECKGLERROR
1767 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1768 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1771 case RENDERPATH_D3D9:
1773 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1774 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1775 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1776 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1777 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1778 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1779 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1780 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1781 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1782 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1783 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1784 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1785 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1788 case RENDERPATH_D3D10:
1789 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1791 case RENDERPATH_D3D11:
1792 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1797 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1799 switch (vid.renderpath)
1801 case RENDERPATH_GL11:
1802 case RENDERPATH_GL13:
1803 case RENDERPATH_GL20:
1804 case RENDERPATH_CGGL:
1808 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1812 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1814 if (vid.support.ext_stencil_two_side)
1816 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1818 qglStencilMask(writemask);CHECKGLERROR
1819 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1820 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1823 case RENDERPATH_D3D9:
1825 if (vid.support.ati_separate_stencil)
1826 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1827 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1828 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1829 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1830 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1831 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1832 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1833 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1834 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1837 case RENDERPATH_D3D10:
1838 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1840 case RENDERPATH_D3D11:
1841 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1846 void GL_PolygonOffset(float planeoffset, float depthoffset)
1848 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
1850 gl_state.polygonoffset[0] = planeoffset;
1851 gl_state.polygonoffset[1] = depthoffset;
1852 switch(vid.renderpath)
1854 case RENDERPATH_GL11:
1855 case RENDERPATH_GL13:
1856 case RENDERPATH_GL20:
1857 case RENDERPATH_CGGL:
1858 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1860 case RENDERPATH_D3D9:
1862 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1863 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1866 case RENDERPATH_D3D10:
1867 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1869 case RENDERPATH_D3D11:
1870 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1876 void GL_SetMirrorState(qboolean state)
1878 if (v_flipped_state != state)
1880 v_flipped_state = state;
1881 if (gl_state.cullface == GL_BACK)
1882 gl_state.cullface = GL_FRONT;
1883 else if (gl_state.cullface == GL_FRONT)
1884 gl_state.cullface = GL_BACK;
1887 switch(vid.renderpath)
1889 case RENDERPATH_GL11:
1890 case RENDERPATH_GL13:
1891 case RENDERPATH_GL20:
1892 case RENDERPATH_CGGL:
1893 qglCullFace(gl_state.cullface);
1895 case RENDERPATH_D3D9:
1897 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
1900 case RENDERPATH_D3D10:
1901 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1903 case RENDERPATH_D3D11:
1904 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1910 void GL_CullFace(int state)
1914 if(state == GL_FRONT)
1916 else if(state == GL_BACK)
1920 switch(vid.renderpath)
1922 case RENDERPATH_GL11:
1923 case RENDERPATH_GL13:
1924 case RENDERPATH_GL20:
1925 case RENDERPATH_CGGL:
1928 if (state != GL_NONE)
1930 if (!gl_state.cullfaceenable)
1932 gl_state.cullfaceenable = true;
1933 qglEnable(GL_CULL_FACE);CHECKGLERROR
1935 if (gl_state.cullface != state)
1937 gl_state.cullface = state;
1938 qglCullFace(gl_state.cullface);CHECKGLERROR
1943 if (gl_state.cullfaceenable)
1945 gl_state.cullfaceenable = false;
1946 qglDisable(GL_CULL_FACE);CHECKGLERROR
1950 case RENDERPATH_D3D9:
1952 if (gl_state.cullface != state)
1954 gl_state.cullface = state;
1955 switch(gl_state.cullface)
1958 gl_state.cullfaceenable = false;
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1962 gl_state.cullfaceenable = true;
1963 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
1966 gl_state.cullfaceenable = true;
1967 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
1973 case RENDERPATH_D3D10:
1974 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1976 case RENDERPATH_D3D11:
1977 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1982 void GL_AlphaTest(int state)
1984 if (gl_state.alphatest != state)
1986 gl_state.alphatest = state;
1987 switch(vid.renderpath)
1989 case RENDERPATH_GL11:
1990 case RENDERPATH_GL13:
1991 case RENDERPATH_GL20:
1992 case RENDERPATH_CGGL:
1994 if (gl_state.alphatest)
1996 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2000 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2003 case RENDERPATH_D3D9:
2005 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
2008 case RENDERPATH_D3D10:
2009 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2011 case RENDERPATH_D3D11:
2012 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2018 void GL_AlphaFunc(int state, float value)
2020 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
2022 gl_state.alphafunc = state;
2023 gl_state.alphafuncvalue = value;
2024 switch(vid.renderpath)
2026 case RENDERPATH_GL11:
2027 case RENDERPATH_GL13:
2028 case RENDERPATH_GL20:
2029 case RENDERPATH_CGGL:
2031 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
2033 case RENDERPATH_D3D9:
2035 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
2036 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
2039 case RENDERPATH_D3D10:
2040 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2042 case RENDERPATH_D3D11:
2043 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2049 void GL_ColorMask(int r, int g, int b, int a)
2051 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2052 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2053 if (gl_state.colormask != state)
2055 gl_state.colormask = state;
2056 switch(vid.renderpath)
2058 case RENDERPATH_GL11:
2059 case RENDERPATH_GL13:
2060 case RENDERPATH_GL20:
2061 case RENDERPATH_CGGL:
2063 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2065 case RENDERPATH_D3D9:
2067 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2070 case RENDERPATH_D3D10:
2071 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2073 case RENDERPATH_D3D11:
2074 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2080 void GL_Color(float cr, float cg, float cb, float ca)
2082 if (gl_state.pointer_color_enabled || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
2084 gl_state.color4f[0] = cr;
2085 gl_state.color4f[1] = cg;
2086 gl_state.color4f[2] = cb;
2087 gl_state.color4f[3] = ca;
2088 switch(vid.renderpath)
2090 case RENDERPATH_GL11:
2091 case RENDERPATH_GL13:
2092 case RENDERPATH_GL20:
2093 case RENDERPATH_CGGL:
2095 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2098 case RENDERPATH_D3D9:
2099 case RENDERPATH_D3D10:
2100 case RENDERPATH_D3D11:
2101 // no equivalent in D3D
2107 void GL_Scissor (int x, int y, int width, int height)
2109 switch(vid.renderpath)
2111 case RENDERPATH_GL11:
2112 case RENDERPATH_GL13:
2113 case RENDERPATH_GL20:
2114 case RENDERPATH_CGGL:
2116 qglScissor(x, y,width,height);
2119 case RENDERPATH_D3D9:
2125 d3drect.right = x + width;
2126 d3drect.bottom = y + height;
2127 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2131 case RENDERPATH_D3D10:
2132 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2134 case RENDERPATH_D3D11:
2135 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2140 void GL_ScissorTest(int state)
2142 if (gl_state.scissortest != state)
2144 gl_state.scissortest = state;
2145 switch(vid.renderpath)
2147 case RENDERPATH_GL11:
2148 case RENDERPATH_GL13:
2149 case RENDERPATH_GL20:
2150 case RENDERPATH_CGGL:
2152 if(gl_state.scissortest)
2153 qglEnable(GL_SCISSOR_TEST);
2155 qglDisable(GL_SCISSOR_TEST);
2158 case RENDERPATH_D3D9:
2160 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2163 case RENDERPATH_D3D10:
2164 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2166 case RENDERPATH_D3D11:
2167 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2173 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2175 static const float blackcolor[4] = {0, 0, 0, 0};
2176 // prevent warnings when trying to clear a buffer that does not exist
2178 colorvalue = blackcolor;
2181 mask &= ~GL_STENCIL_BUFFER_BIT;
2184 switch(vid.renderpath)
2186 case RENDERPATH_GL11:
2187 case RENDERPATH_GL13:
2188 case RENDERPATH_GL20:
2189 case RENDERPATH_CGGL:
2191 if (mask & GL_COLOR_BUFFER_BIT)
2193 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2195 if (mask & GL_DEPTH_BUFFER_BIT)
2197 qglClearDepth(depthvalue);CHECKGLERROR
2199 if (mask & GL_STENCIL_BUFFER_BIT)
2201 qglClearStencil(stencilvalue);CHECKGLERROR
2203 qglClear(mask);CHECKGLERROR
2205 case RENDERPATH_D3D9:
2207 IDirect3DDevice9_Clear(vid_d3d9dev, 0, NULL, ((mask & GL_COLOR_BUFFER_BIT) ? D3DCLEAR_TARGET : 0) | ((mask & GL_STENCIL_BUFFER_BIT) ? D3DCLEAR_STENCIL : 0) | ((mask & GL_DEPTH_BUFFER_BIT) ? D3DCLEAR_ZBUFFER : 0), D3DCOLOR_COLORVALUE(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]), depthvalue, stencilvalue);
2210 case RENDERPATH_D3D10:
2211 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2213 case RENDERPATH_D3D11:
2214 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2219 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2221 switch(vid.renderpath)
2223 case RENDERPATH_GL11:
2224 case RENDERPATH_GL13:
2225 case RENDERPATH_GL20:
2226 case RENDERPATH_CGGL:
2228 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2230 case RENDERPATH_D3D9:
2233 // LordHavoc: we can't directly download the backbuffer because it may be
2234 // multisampled, and it may not be lockable, so we blit it to a lockable
2235 // surface of the same dimensions (but without multisample) to resolve the
2236 // multisample buffer to a normal image, and then lock that...
2237 IDirect3DSurface9 *stretchsurface = NULL;
2238 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2240 D3DLOCKED_RECT lockedrect;
2241 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2243 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2246 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2247 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2248 memcpy(outpixels + line * width * 4, row, width * 4);
2249 IDirect3DSurface9_UnlockRect(stretchsurface);
2252 IDirect3DSurface9_Release(stretchsurface);
2255 //IDirect3DSurface9 *syssurface = NULL;
2256 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2257 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2258 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2259 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2260 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2261 //IDirect3DSurface9_UnlockRect(syssurface);
2262 //IDirect3DSurface9_Release(syssurface);
2266 case RENDERPATH_D3D10:
2267 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2269 case RENDERPATH_D3D11:
2270 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2275 // called at beginning of frame
2276 void R_Mesh_Start(void)
2279 R_Mesh_ResetRenderTargets();
2281 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2283 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2284 Cvar_SetValueQuick(&gl_paranoid, 1);
2288 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2292 char compilelog[MAX_INPUTLINE];
2293 shaderobject = qglCreateShaderObjectARB(shadertypeenum);CHECKGLERROR
2296 qglShaderSourceARB(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2297 qglCompileShaderARB(shaderobject);CHECKGLERROR
2298 qglGetObjectParameterivARB(shaderobject, GL_OBJECT_COMPILE_STATUS_ARB, &shadercompiled);CHECKGLERROR
2299 qglGetInfoLogARB(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2300 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2302 int i, j, pretextlines = 0;
2303 for (i = 0;i < numstrings - 1;i++)
2304 for (j = 0;strings[i][j];j++)
2305 if (strings[i][j] == '\n')
2307 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2309 if (!shadercompiled)
2311 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2314 qglAttachObjectARB(programobject, shaderobject);CHECKGLERROR
2315 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2319 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)
2321 GLint programlinked;
2322 GLuint programobject = 0;
2323 char linklog[MAX_INPUTLINE];
2326 programobject = qglCreateProgramObjectARB();CHECKGLERROR
2330 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER_ARB, "vertex", vertexstrings_count, vertexstrings_list))
2333 #ifdef GL_GEOMETRY_SHADER_ARB
2334 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER_ARB, "geometry", geometrystrings_count, geometrystrings_list))
2338 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER_ARB, "fragment", fragmentstrings_count, fragmentstrings_list))
2341 qglLinkProgramARB(programobject);CHECKGLERROR
2342 qglGetObjectParameterivARB(programobject, GL_OBJECT_LINK_STATUS_ARB, &programlinked);CHECKGLERROR
2343 qglGetInfoLogARB(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2346 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2347 Con_DPrintf("program link log:\n%s\n", linklog);
2348 // software vertex shader is ok but software fragment shader is WAY
2349 // too slow, fail program if so.
2350 // NOTE: this string might be ATI specific, but that's ok because the
2351 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2352 // software fragment shader due to low instruction and dependent
2354 if (strstr(linklog, "fragment shader will run in software"))
2355 programlinked = false;
2359 return programobject;
2361 qglDeleteObjectARB(programobject);CHECKGLERROR
2365 void GL_Backend_FreeProgram(unsigned int prog)
2368 qglDeleteObjectARB(prog);
2372 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2377 for (i = 0;i < count;i++)
2378 *out++ = *in++ + offset;
2381 memcpy(out, in, sizeof(*out) * count);
2384 // renders triangles using vertices from the active arrays
2385 int paranoidblah = 0;
2386 void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, size_t element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, size_t element3s_bufferoffset)
2388 unsigned int numelements = numtriangles * 3;
2390 size_t bufferoffset3i;
2392 size_t bufferoffset3s;
2393 if (numvertices < 3 || numtriangles < 1)
2395 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2396 Con_DPrintf("R_Mesh_Draw(%d, %d, %d, %d, %8p, %8p, %8x, %8p, %8p, %8x);\n", firstvertex, numvertices, firsttriangle, numtriangles, (void *)element3i, (void *)element3i_indexbuffer, (int)element3i_bufferoffset, (void *)element3s, (void *)element3s_indexbuffer, (int)element3s_bufferoffset);
2399 if (!gl_mesh_prefer_short_elements.integer)
2403 if (element3i_indexbuffer)
2404 element3i_indexbuffer = NULL;
2406 // adjust the pointers for firsttriangle
2408 element3i += firsttriangle * 3;
2409 if (element3i_indexbuffer)
2410 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2412 element3s += firsttriangle * 3;
2413 if (element3s_indexbuffer)
2414 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2415 switch(vid.renderpath)
2417 case RENDERPATH_GL11:
2418 case RENDERPATH_GL13:
2419 case RENDERPATH_GL20:
2420 case RENDERPATH_CGGL:
2421 // check if the user specified to ignore static index buffers
2422 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2424 element3i_indexbuffer = NULL;
2425 element3s_indexbuffer = NULL;
2428 case RENDERPATH_D3D9:
2429 case RENDERPATH_D3D10:
2430 case RENDERPATH_D3D11:
2433 // upload a dynamic index buffer if needed
2436 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2438 if (gl_state.draw_dynamicindexbuffer)
2439 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2441 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2442 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2443 element3s_bufferoffset = 0;
2448 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2450 if (gl_state.draw_dynamicindexbuffer)
2451 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2453 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2454 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2455 element3i_bufferoffset = 0;
2458 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2459 bufferoffset3i = element3i_bufferoffset;
2460 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2461 bufferoffset3s = element3s_bufferoffset;
2462 r_refdef.stats.draws++;
2463 r_refdef.stats.draws_vertices += numvertices;
2464 r_refdef.stats.draws_elements += numelements;
2465 if (gl_paranoid.integer)
2468 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2470 unsigned int j, size;
2472 // note: there's no validation done here on buffer objects because it
2473 // is somewhat difficult to get at the data, and gl_paranoid can be
2474 // used without buffer objects if the need arises
2475 // (the data could be gotten using glMapBuffer but it would be very
2476 // slow due to uncachable video memory reads)
2477 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2478 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2480 if (gl_state.pointer_vertex_pointer)
2481 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2483 if (gl_state.pointer_color_enabled)
2485 if (!qglIsEnabled(GL_COLOR_ARRAY))
2486 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2488 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2489 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2492 for (i = 0;i < vid.texarrayunits;i++)
2494 if (gl_state.units[i].arrayenabled)
2496 GL_ClientActiveTexture(i);
2497 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2498 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2500 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2501 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++)
2508 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2510 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2512 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2519 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2521 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2523 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2529 if (r_render.integer || r_refdef.draw2dstage)
2531 switch(vid.renderpath)
2533 case RENDERPATH_GL11:
2534 case RENDERPATH_GL13:
2535 case RENDERPATH_GL20:
2536 case RENDERPATH_CGGL:
2538 if (gl_mesh_testmanualfeeding.integer)
2540 unsigned int i, j, element;
2542 qglBegin(GL_TRIANGLES);
2543 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2546 element = element3i[i];
2548 element = element3s[i];
2550 element = firstvertex + i;
2551 for (j = 0;j < vid.texarrayunits;j++)
2553 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2555 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2557 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2558 if (vid.texarrayunits > 1)
2560 if (gl_state.units[j].pointer_texcoord_components == 4)
2561 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2562 else if (gl_state.units[j].pointer_texcoord_components == 3)
2563 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2564 else if (gl_state.units[j].pointer_texcoord_components == 2)
2565 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2567 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2571 if (gl_state.units[j].pointer_texcoord_components == 4)
2572 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2573 else if (gl_state.units[j].pointer_texcoord_components == 3)
2574 qglTexCoord3f(p[0], p[1], p[2]);
2575 else if (gl_state.units[j].pointer_texcoord_components == 2)
2576 qglTexCoord2f(p[0], p[1]);
2578 qglTexCoord1f(p[0]);
2581 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2583 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2584 if (vid.texarrayunits > 1)
2586 if (gl_state.units[j].pointer_texcoord_components == 4)
2587 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2588 else if (gl_state.units[j].pointer_texcoord_components == 3)
2589 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2590 else if (gl_state.units[j].pointer_texcoord_components == 2)
2591 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2592 else if (gl_state.units[j].pointer_texcoord_components == 1)
2593 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2597 if (gl_state.units[j].pointer_texcoord_components == 4)
2598 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2599 else if (gl_state.units[j].pointer_texcoord_components == 3)
2600 qglTexCoord3f(s[0], s[1], s[2]);
2601 else if (gl_state.units[j].pointer_texcoord_components == 2)
2602 qglTexCoord2f(s[0], s[1]);
2603 else if (gl_state.units[j].pointer_texcoord_components == 1)
2604 qglTexCoord1f(s[0]);
2607 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2609 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2610 if (vid.texarrayunits > 1)
2612 if (gl_state.units[j].pointer_texcoord_components == 4)
2613 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2614 else if (gl_state.units[j].pointer_texcoord_components == 3)
2615 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2616 else if (gl_state.units[j].pointer_texcoord_components == 2)
2617 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2618 else if (gl_state.units[j].pointer_texcoord_components == 1)
2619 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2623 if (gl_state.units[j].pointer_texcoord_components == 4)
2624 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2625 else if (gl_state.units[j].pointer_texcoord_components == 3)
2626 qglTexCoord3f(sb[0], sb[1], sb[2]);
2627 else if (gl_state.units[j].pointer_texcoord_components == 2)
2628 qglTexCoord2f(sb[0], sb[1]);
2629 else if (gl_state.units[j].pointer_texcoord_components == 1)
2630 qglTexCoord1f(sb[0]);
2635 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2637 if (gl_state.pointer_color_gltype == GL_FLOAT)
2639 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2640 qglColor4f(p[0], p[1], p[2], p[3]);
2642 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2644 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2645 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2648 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2650 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2651 if (gl_state.pointer_vertex_components == 4)
2652 qglVertex4f(p[0], p[1], p[2], p[3]);
2653 else if (gl_state.pointer_vertex_components == 3)
2654 qglVertex3f(p[0], p[1], p[2]);
2656 qglVertex2f(p[0], p[1]);
2662 else if (bufferobject3s)
2664 GL_BindEBO(bufferobject3s);
2665 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2667 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2672 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2676 else if (bufferobject3i)
2678 GL_BindEBO(bufferobject3i);
2679 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2681 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2686 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2693 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2695 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2700 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2707 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2709 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2714 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2720 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2724 case RENDERPATH_D3D9:
2726 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2728 if (element3s_indexbuffer)
2730 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2731 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2733 else if (element3i_indexbuffer)
2735 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2736 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2739 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2744 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s + firsttriangle*3, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2746 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i + firsttriangle*3, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2748 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *) ((byte *) gl_state.d3dvertexdata + (numvertices * gl_state.d3dvertexsize)), gl_state.d3dvertexsize);
2752 case RENDERPATH_D3D10:
2753 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2755 case RENDERPATH_D3D11:
2756 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2762 // restores backend state, used when done with 3D rendering
2763 void R_Mesh_Finish(void)
2765 R_Mesh_ResetRenderTargets();
2768 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
2770 r_meshbuffer_t *buffer;
2771 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
2773 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
2774 memset(buffer, 0, sizeof(*buffer));
2775 buffer->bufferobject = 0;
2776 buffer->devicebuffer = NULL;
2778 buffer->isindexbuffer = isindexbuffer;
2779 buffer->isdynamic = isdynamic;
2780 buffer->isindex16 = isindex16;
2781 strlcpy(buffer->name, name, sizeof(buffer->name));
2782 R_Mesh_UpdateMeshBuffer(buffer, data, size);
2786 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
2790 if (buffer->isindexbuffer)
2792 r_refdef.stats.indexbufferuploadcount++;
2793 r_refdef.stats.indexbufferuploadsize += size;
2797 r_refdef.stats.vertexbufferuploadcount++;
2798 r_refdef.stats.vertexbufferuploadsize += size;
2800 switch(vid.renderpath)
2802 case RENDERPATH_GL11:
2803 case RENDERPATH_GL13:
2804 case RENDERPATH_GL20:
2805 case RENDERPATH_CGGL:
2806 if (!buffer->bufferobject)
2807 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
2808 if (buffer->isindexbuffer)
2809 GL_BindEBO(buffer->bufferobject);
2811 GL_BindVBO(buffer->bufferobject);
2812 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
2814 case RENDERPATH_D3D9:
2818 void *datapointer = NULL;
2819 if (buffer->isindexbuffer)
2821 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
2822 if (size > buffer->size || !buffer->devicebuffer)
2824 if (buffer->devicebuffer)
2825 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
2826 buffer->devicebuffer = NULL;
2827 if (FAILED(result = IDirect3DDevice9_CreateIndexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, buffer->isindex16 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9indexbuffer, NULL)))
2828 Sys_Error("IDirect3DDevice9_CreateIndexBuffer(%p, %d, %x, %x, %x, %p, NULL) returned %x\n", vid_d3d9dev, (int)size, buffer->isdynamic ? (int)D3DUSAGE_DYNAMIC : 0, buffer->isindex16 ? (int)D3DFMT_INDEX16 : (int)D3DFMT_INDEX32, buffer->isdynamic ? (int)D3DPOOL_DEFAULT : (int)D3DPOOL_MANAGED, &d3d9indexbuffer, (int)result);
2829 buffer->devicebuffer = (void *)d3d9indexbuffer;
2830 buffer->size = size;
2832 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2835 memcpy(datapointer, data, size);
2837 memset(datapointer, 0, size);
2838 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
2843 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
2844 if (size > buffer->size || !buffer->devicebuffer)
2846 if (buffer->devicebuffer)
2847 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
2848 buffer->devicebuffer = NULL;
2849 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
2850 Sys_Error("IDirect3DDevice9_CreateVertexBuffer(%p, %d, %x, %x, %x, %p, NULL) returned %x\n", vid_d3d9dev, (int)size, buffer->isdynamic ? (int)D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? (int)D3DPOOL_DEFAULT : (int)D3DPOOL_MANAGED, &d3d9vertexbuffer, (int)result);
2851 buffer->devicebuffer = (void *)d3d9vertexbuffer;
2852 buffer->size = size;
2854 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2857 memcpy(datapointer, data, size);
2859 memset(datapointer, 0, size);
2860 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
2866 case RENDERPATH_D3D10:
2867 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2869 case RENDERPATH_D3D11:
2870 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2875 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
2879 switch(vid.renderpath)
2881 case RENDERPATH_GL11:
2882 case RENDERPATH_GL13:
2883 case RENDERPATH_GL20:
2884 case RENDERPATH_CGGL:
2885 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
2887 case RENDERPATH_D3D9:
2889 if (gl_state.d3dvertexbuffer == (void *)buffer)
2890 gl_state.d3dvertexbuffer = NULL;
2891 if (buffer->devicebuffer)
2893 if (buffer->isindexbuffer)
2894 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
2896 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
2897 buffer->devicebuffer = NULL;
2901 case RENDERPATH_D3D10:
2902 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2904 case RENDERPATH_D3D11:
2905 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2908 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
2911 void GL_Mesh_ListVBOs(qboolean printeach)
2914 size_t ebocount = 0, ebomemory = 0;
2915 size_t vbocount = 0, vbomemory = 0;
2916 r_meshbuffer_t *buffer;
2917 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
2918 for (i = 0;i < endindex;i++)
2920 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
2923 if (buffer->isindexbuffer) {ebocount++;ebomemory += buffer->size;if (printeach) Con_Printf("indexbuffer #%i %s = %i bytes%s\n", i, buffer->name, (int)buffer->size, buffer->isdynamic ? " (dynamic)" : " (static)");}
2924 else {vbocount++;vbomemory += buffer->size;if (printeach) Con_Printf("vertexbuffer #%i %s = %i bytes%s\n", i, buffer->name, (int)buffer->size, buffer->isdynamic ? " (dynamic)" : " (static)");}
2926 Con_Printf("vertex buffers: %i indexbuffers totalling %i bytes (%.3f MB), %i vertexbuffers totalling %i bytes (%.3f MB), combined %i bytes (%.3fMB)\n", (int)ebocount, (int)ebomemory, ebomemory / 1048576.0, (int)vbocount, (int)vbomemory, vbomemory / 1048576.0, (int)(ebomemory + vbomemory), (ebomemory + vbomemory) / 1048576.0);
2931 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
2933 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2934 if (gl_state.pointer_vertex_components != components || gl_state.pointer_vertex_gltype != gltype || gl_state.pointer_vertex_stride != stride || gl_state.pointer_vertex_pointer != pointer || gl_state.pointer_vertex_vertexbuffer != vertexbuffer || gl_state.pointer_vertex_offset != bufferoffset)
2936 gl_state.pointer_vertex_components = components;
2937 gl_state.pointer_vertex_gltype = gltype;
2938 gl_state.pointer_vertex_stride = stride;
2939 gl_state.pointer_vertex_pointer = pointer;
2940 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
2941 gl_state.pointer_vertex_offset = bufferoffset;
2943 GL_BindVBO(bufferobject);
2944 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
2948 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
2950 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
2951 // the pointer only.
2954 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2955 // caller wants color array enabled
2956 if (!gl_state.pointer_color_enabled)
2958 gl_state.pointer_color_enabled = true;
2960 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
2962 if (gl_state.pointer_color_components != components || gl_state.pointer_color_gltype != gltype || gl_state.pointer_color_stride != stride || gl_state.pointer_color_pointer != pointer || gl_state.pointer_color_vertexbuffer != vertexbuffer || gl_state.pointer_color_offset != bufferoffset)
2964 gl_state.pointer_color_components = components;
2965 gl_state.pointer_color_gltype = gltype;
2966 gl_state.pointer_color_stride = stride;
2967 gl_state.pointer_color_pointer = pointer;
2968 gl_state.pointer_color_vertexbuffer = vertexbuffer;
2969 gl_state.pointer_color_offset = bufferoffset;
2971 GL_BindVBO(bufferobject);
2972 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
2977 // caller wants color array disabled
2978 if (gl_state.pointer_color_enabled)
2980 gl_state.pointer_color_enabled = false;
2982 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
2983 // when color array is on the glColor gets trashed, set it again
2984 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
2989 void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
2991 gltextureunit_t *unit = gl_state.units + unitnum;
2992 // update array settings
2994 // note: there is no need to check bufferobject here because all cases
2995 // that involve a valid bufferobject also supply a texcoord array
2998 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2999 // texture array unit is enabled, enable the array
3000 if (!unit->arrayenabled)
3002 unit->arrayenabled = true;
3003 GL_ClientActiveTexture(unitnum);
3004 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3007 if (unit->pointer_texcoord_components != components || unit->pointer_texcoord_gltype != gltype || unit->pointer_texcoord_stride != stride || unit->pointer_texcoord_pointer != pointer || unit->pointer_texcoord_vertexbuffer != vertexbuffer || unit->pointer_texcoord_offset != bufferoffset)
3009 unit->pointer_texcoord_components = components;
3010 unit->pointer_texcoord_gltype = gltype;
3011 unit->pointer_texcoord_stride = stride;
3012 unit->pointer_texcoord_pointer = pointer;
3013 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3014 unit->pointer_texcoord_offset = bufferoffset;
3015 GL_ClientActiveTexture(unitnum);
3016 GL_BindVBO(bufferobject);
3017 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3022 // texture array unit is disabled, disable the array
3023 if (unit->arrayenabled)
3025 unit->arrayenabled = false;
3026 GL_ClientActiveTexture(unitnum);
3027 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3032 int R_Mesh_TexBound(unsigned int unitnum, int id)
3034 gltextureunit_t *unit = gl_state.units + unitnum;
3035 if (unitnum >= vid.teximageunits)
3037 if (id == GL_TEXTURE_2D)
3039 if (id == GL_TEXTURE_3D)
3041 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3042 return unit->tcubemap;
3046 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3048 switch(vid.renderpath)
3050 case RENDERPATH_GL11:
3051 case RENDERPATH_GL13:
3052 case RENDERPATH_GL20:
3053 case RENDERPATH_CGGL:
3054 R_Mesh_TexBind(0, tex);
3055 GL_ActiveTexture(0);CHECKGLERROR
3056 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3058 case RENDERPATH_D3D9:
3061 IDirect3DSurface9 *currentsurface = NULL;
3062 IDirect3DSurface9 *texturesurface = NULL;
3065 sourcerect.left = sx;
3066 sourcerect.top = sy;
3067 sourcerect.right = sx + width;
3068 sourcerect.bottom = sy + height;
3071 destrect.right = tx + width;
3072 destrect.bottom = ty + height;
3073 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3075 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3077 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3078 IDirect3DSurface9_Release(currentsurface);
3080 IDirect3DSurface9_Release(texturesurface);
3085 case RENDERPATH_D3D10:
3086 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3088 case RENDERPATH_D3D11:
3089 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3095 int d3drswrap[16] = {D3DRS_WRAP0, D3DRS_WRAP1, D3DRS_WRAP2, D3DRS_WRAP3, D3DRS_WRAP4, D3DRS_WRAP5, D3DRS_WRAP6, D3DRS_WRAP7, D3DRS_WRAP8, D3DRS_WRAP9, D3DRS_WRAP10, D3DRS_WRAP11, D3DRS_WRAP12, D3DRS_WRAP13, D3DRS_WRAP14, D3DRS_WRAP15};
3098 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3100 gltextureunit_t *unit = gl_state.units + unitnum;
3101 int tex2d, tex3d, texcubemap, texnum;
3102 if (unitnum >= vid.teximageunits)
3104 // if (unit->texture == tex)
3106 switch(vid.renderpath)
3108 case RENDERPATH_GL20:
3109 case RENDERPATH_CGGL:
3112 tex = r_texture_white;
3113 // not initialized enough yet...
3117 unit->texture = tex;
3118 texnum = R_GetTexture(tex);
3119 switch(tex->gltexturetypeenum)
3121 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3122 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3123 case GL_TEXTURE_CUBE_MAP_ARB: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR}break;
3126 case RENDERPATH_GL13:
3127 case RENDERPATH_GL11:
3128 unit->texture = tex;
3134 texnum = R_GetTexture(tex);
3135 switch(tex->gltexturetypeenum)
3143 case GL_TEXTURE_CUBE_MAP_ARB:
3144 texcubemap = texnum;
3148 // update 2d texture binding
3149 if (unit->t2d != tex2d)
3151 GL_ActiveTexture(unitnum);
3156 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3163 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3167 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3169 // update 3d texture binding
3170 if (unit->t3d != tex3d)
3172 GL_ActiveTexture(unitnum);
3177 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3184 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3188 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3190 // update cubemap texture binding
3191 if (unit->tcubemap != texcubemap)
3193 GL_ActiveTexture(unitnum);
3196 if (unit->tcubemap == 0)
3198 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3205 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3208 unit->tcubemap = texcubemap;
3209 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3212 case RENDERPATH_D3D9:
3215 extern cvar_t gl_texture_anisotropy;
3218 tex = r_texture_white;
3219 // not initialized enough yet...
3223 if (unit->texture == tex)
3225 unit->texture = tex;
3226 // upload texture if needed
3228 R_RealGetTexture(tex);
3229 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3230 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3231 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3232 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3233 if (tex->d3daddressw)
3234 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3235 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3236 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3237 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3238 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3239 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3240 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3244 case RENDERPATH_D3D10:
3245 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3247 case RENDERPATH_D3D11:
3248 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3253 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3255 gltextureunit_t *unit = gl_state.units + unitnum;
3256 switch(vid.renderpath)
3258 case RENDERPATH_GL11:
3259 case RENDERPATH_GL13:
3260 case RENDERPATH_GL20:
3261 case RENDERPATH_CGGL:
3262 if (matrix && matrix->m[3][3])
3264 // texmatrix specified, check if it is different
3265 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3268 unit->texmatrixenabled = true;
3269 unit->matrix = *matrix;
3271 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3272 GL_ActiveTexture(unitnum);
3273 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3274 qglLoadMatrixf(glmatrix);CHECKGLERROR
3275 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3280 // no texmatrix specified, revert to identity
3281 if (unit->texmatrixenabled)
3283 unit->texmatrixenabled = false;
3284 unit->matrix = identitymatrix;
3286 GL_ActiveTexture(unitnum);
3287 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3288 qglLoadIdentity();CHECKGLERROR
3289 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3293 case RENDERPATH_D3D9:
3294 case RENDERPATH_D3D10:
3295 case RENDERPATH_D3D11:
3300 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3302 gltextureunit_t *unit = gl_state.units + unitnum;
3304 switch(vid.renderpath)
3306 case RENDERPATH_GL20:
3307 case RENDERPATH_CGGL:
3310 case RENDERPATH_GL13:
3311 // GL_ARB_texture_env_combine
3313 combinergb = GL_MODULATE;
3315 combinealpha = GL_MODULATE;
3320 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3322 if (combinergb == GL_DECAL)
3323 combinergb = GL_INTERPOLATE_ARB;
3324 if (unit->combine != GL_COMBINE_ARB)
3326 unit->combine = GL_COMBINE_ARB;
3327 GL_ActiveTexture(unitnum);
3328 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3329 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3331 if (unit->combinergb != combinergb)
3333 unit->combinergb = combinergb;
3334 GL_ActiveTexture(unitnum);
3335 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3337 if (unit->combinealpha != combinealpha)
3339 unit->combinealpha = combinealpha;
3340 GL_ActiveTexture(unitnum);
3341 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3343 if (unit->rgbscale != rgbscale)
3345 unit->rgbscale = rgbscale;
3346 GL_ActiveTexture(unitnum);
3347 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3349 if (unit->alphascale != alphascale)
3351 unit->alphascale = alphascale;
3352 GL_ActiveTexture(unitnum);
3353 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3358 if (unit->combine != combinergb)
3360 unit->combine = combinergb;
3361 GL_ActiveTexture(unitnum);
3362 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3366 case RENDERPATH_GL11:
3369 combinergb = GL_MODULATE;
3370 if (unit->combine != combinergb)
3372 unit->combine = combinergb;
3373 GL_ActiveTexture(unitnum);
3374 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3377 case RENDERPATH_D3D9:
3378 case RENDERPATH_D3D10:
3379 case RENDERPATH_D3D11:
3384 void R_Mesh_ResetTextureState(void)
3386 unsigned int unitnum;
3391 switch(vid.renderpath)
3393 case RENDERPATH_GL20:
3394 case RENDERPATH_CGGL:
3395 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3397 gltextureunit_t *unit = gl_state.units + unitnum;
3401 GL_ActiveTexture(unitnum);
3402 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3407 GL_ActiveTexture(unitnum);
3408 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3413 GL_ActiveTexture(unitnum);
3414 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3417 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3419 gltextureunit_t *unit = gl_state.units + unitnum;
3420 if (unit->arrayenabled)
3422 unit->arrayenabled = false;
3423 GL_ClientActiveTexture(unitnum);
3424 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3427 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3429 gltextureunit_t *unit = gl_state.units + unitnum;
3430 if (unit->texmatrixenabled)
3432 unit->texmatrixenabled = false;
3433 unit->matrix = identitymatrix;
3435 GL_ActiveTexture(unitnum);
3436 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3437 qglLoadIdentity();CHECKGLERROR
3438 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3442 case RENDERPATH_GL13:
3443 case RENDERPATH_GL11:
3444 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3446 gltextureunit_t *unit = gl_state.units + unitnum;
3450 GL_ActiveTexture(unitnum);
3451 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3452 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3457 GL_ActiveTexture(unitnum);
3458 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3459 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3464 GL_ActiveTexture(unitnum);
3465 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3466 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3468 if (unit->arrayenabled)
3470 unit->arrayenabled = false;
3471 GL_ClientActiveTexture(unitnum);
3472 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3474 if (unit->texmatrixenabled)
3476 unit->texmatrixenabled = false;
3477 unit->matrix = identitymatrix;
3479 GL_ActiveTexture(unitnum);
3480 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3481 qglLoadIdentity();CHECKGLERROR
3482 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3484 if (unit->combine != GL_MODULATE)
3486 unit->combine = GL_MODULATE;
3487 GL_ActiveTexture(unitnum);
3488 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3492 case RENDERPATH_D3D9:
3493 case RENDERPATH_D3D10:
3494 case RENDERPATH_D3D11:
3502 //#define r_vertexposition_d3d9fvf (D3DFVF_XYZ)
3503 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3504 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3506 D3DVERTEXELEMENT9 r_vertexposition_d3d9elements[] =
3508 {0, (int)((size_t)&((r_vertexposition_t *)0)->vertex3f), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3512 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3514 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3515 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3516 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3520 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3522 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3523 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3524 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3525 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3526 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3527 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3528 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3532 IDirect3DVertexDeclaration9 *r_vertexposition_d3d9decl;
3533 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3534 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3537 static void R_Mesh_InitVertexDeclarations(void)
3540 r_vertexposition_d3d9decl = NULL;
3541 r_vertexgeneric_d3d9decl = NULL;
3542 r_vertexmesh_d3d9decl = NULL;
3543 switch(vid.renderpath)
3545 case RENDERPATH_GL20:
3546 case RENDERPATH_CGGL:
3547 case RENDERPATH_GL13:
3548 case RENDERPATH_GL11:
3550 case RENDERPATH_D3D9:
3551 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexposition_d3d9elements, &r_vertexposition_d3d9decl);
3552 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3553 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3555 case RENDERPATH_D3D10:
3556 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3558 case RENDERPATH_D3D11:
3559 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3565 static void R_Mesh_DestroyVertexDeclarations(void)
3568 if (r_vertexposition_d3d9decl)
3569 IDirect3DVertexDeclaration9_Release(r_vertexposition_d3d9decl);
3570 r_vertexposition_d3d9decl = NULL;
3571 if (r_vertexgeneric_d3d9decl)
3572 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3573 r_vertexgeneric_d3d9decl = NULL;
3574 if (r_vertexmesh_d3d9decl)
3575 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3576 r_vertexmesh_d3d9decl = NULL;
3580 r_vertexposition_t *R_Mesh_PrepareVertices_Position_Lock(int numvertices)
3583 size = sizeof(r_vertexposition_t) * numvertices;
3584 if (gl_state.preparevertices_tempdatamaxsize < size)
3586 gl_state.preparevertices_tempdatamaxsize = size;
3587 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3589 gl_state.preparevertices_vertexposition = (r_vertexposition_t *)gl_state.preparevertices_tempdata;
3590 gl_state.preparevertices_numvertices = numvertices;
3591 return gl_state.preparevertices_vertexposition;
3594 qboolean R_Mesh_PrepareVertices_Position_Unlock(void)
3596 R_Mesh_PrepareVertices_Position(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexposition, NULL);
3597 gl_state.preparevertices_vertexposition = NULL;
3598 gl_state.preparevertices_numvertices = 0;
3602 void R_Mesh_PrepareVertices_Position_Arrays(int numvertices, const float *vertex3f)
3605 r_vertexposition_t *vertex;
3606 switch(vid.renderpath)
3608 case RENDERPATH_GL20:
3609 case RENDERPATH_CGGL:
3610 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3611 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3612 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3613 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3614 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3615 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3616 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3618 case RENDERPATH_GL13:
3619 case RENDERPATH_GL11:
3620 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3621 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3622 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3623 if (vid.texunits >= 2)
3624 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3625 if (vid.texunits >= 3)
3626 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3628 case RENDERPATH_D3D9:
3630 gl_state.d3dvertexbuffer = NULL;
3631 gl_state.d3dvertexdata = (void *)vertex3f;
3632 gl_state.d3dvertexsize = sizeof(float[3]);
3635 case RENDERPATH_D3D10:
3636 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3638 case RENDERPATH_D3D11:
3639 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3643 // no quick path for this case, convert to vertex structs
3644 vertex = R_Mesh_PrepareVertices_Position_Lock(numvertices);
3645 for (i = 0;i < numvertices;i++)
3646 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3647 R_Mesh_PrepareVertices_Position_Unlock();
3648 R_Mesh_PrepareVertices_Position(numvertices, vertex, NULL);
3651 void R_Mesh_PrepareVertices_Position(int numvertices, const r_vertexposition_t *vertex, const r_meshbuffer_t *vertexbuffer)
3653 // upload temporary vertexbuffer for this rendering
3654 if (!gl_state.usevbo_staticvertex)
3655 vertexbuffer = NULL;
3656 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3658 if (gl_state.preparevertices_dynamicvertexbuffer)
3659 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3661 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3662 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3664 switch(vid.renderpath)
3666 case RENDERPATH_GL20:
3667 case RENDERPATH_CGGL:
3670 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3671 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3672 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3673 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3674 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3675 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3676 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3680 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3681 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3682 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3683 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3684 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3685 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3686 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3689 case RENDERPATH_GL13:
3692 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3693 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3694 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3695 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3699 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3700 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3701 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3702 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3705 case RENDERPATH_GL11:
3708 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3709 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3710 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3714 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3715 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3716 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3719 case RENDERPATH_D3D9:
3721 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexposition_d3d9decl);
3723 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
3725 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3726 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3727 gl_state.d3dvertexdata = (void *)vertex;
3728 gl_state.d3dvertexsize = sizeof(*vertex);
3731 case RENDERPATH_D3D10:
3732 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3734 case RENDERPATH_D3D11:
3735 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3742 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
3745 size = sizeof(r_vertexgeneric_t) * numvertices;
3746 if (gl_state.preparevertices_tempdatamaxsize < size)
3748 gl_state.preparevertices_tempdatamaxsize = size;
3749 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3751 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
3752 gl_state.preparevertices_numvertices = numvertices;
3753 return gl_state.preparevertices_vertexgeneric;
3756 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
3758 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
3759 gl_state.preparevertices_vertexgeneric = NULL;
3760 gl_state.preparevertices_numvertices = 0;
3764 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
3767 r_vertexgeneric_t *vertex;
3768 switch(vid.renderpath)
3770 case RENDERPATH_GL20:
3771 case RENDERPATH_CGGL:
3772 if (gl_mesh_separatearrays.integer)
3774 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3775 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3776 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3777 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3778 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3779 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3780 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3784 case RENDERPATH_GL13:
3785 case RENDERPATH_GL11:
3786 if (gl_mesh_separatearrays.integer)
3788 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3789 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3790 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3791 if (vid.texunits >= 2)
3792 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3793 if (vid.texunits >= 3)
3794 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3798 case RENDERPATH_D3D9:
3799 case RENDERPATH_D3D10:
3800 case RENDERPATH_D3D11:
3804 // no quick path for this case, convert to vertex structs
3805 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
3806 for (i = 0;i < numvertices;i++)
3807 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3810 for (i = 0;i < numvertices;i++)
3811 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
3815 float tempcolor4f[4];
3816 unsigned char tempcolor4ub[4];
3817 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
3818 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
3819 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
3820 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
3821 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
3822 for (i = 0;i < numvertices;i++)
3823 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
3826 for (i = 0;i < numvertices;i++)
3827 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
3828 R_Mesh_PrepareVertices_Generic_Unlock();
3829 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
3832 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
3834 // upload temporary vertexbuffer for this rendering
3835 if (!gl_state.usevbo_staticvertex)
3836 vertexbuffer = NULL;
3837 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3839 if (gl_state.preparevertices_dynamicvertexbuffer)
3840 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3842 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3843 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3845 switch(vid.renderpath)
3847 case RENDERPATH_GL20:
3848 case RENDERPATH_CGGL:
3851 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3852 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3853 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3854 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3855 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3856 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3857 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3861 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3862 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3863 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3864 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3865 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3866 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3867 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3870 case RENDERPATH_GL13:
3873 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3874 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3875 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3876 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3880 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3881 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3882 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3883 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3886 case RENDERPATH_GL11:
3889 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3890 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3891 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3895 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3896 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3897 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3900 case RENDERPATH_D3D9:
3902 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
3904 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
3906 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3907 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3908 gl_state.d3dvertexdata = (void *)vertex;
3909 gl_state.d3dvertexsize = sizeof(*vertex);
3912 case RENDERPATH_D3D10:
3913 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3915 case RENDERPATH_D3D11:
3916 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3923 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
3926 size = sizeof(r_vertexmesh_t) * numvertices;
3927 if (gl_state.preparevertices_tempdatamaxsize < size)
3929 gl_state.preparevertices_tempdatamaxsize = size;
3930 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3932 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
3933 gl_state.preparevertices_numvertices = numvertices;
3934 return gl_state.preparevertices_vertexmesh;
3937 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
3939 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
3940 gl_state.preparevertices_vertexmesh = NULL;
3941 gl_state.preparevertices_numvertices = 0;
3945 void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *color4f, const float *texcoordtexture2f, const float *texcoordlightmap2f)
3948 r_vertexmesh_t *vertex;
3949 switch(vid.renderpath)
3951 case RENDERPATH_GL20:
3952 case RENDERPATH_CGGL:
3953 if (gl_mesh_separatearrays.integer)
3955 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3956 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3957 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
3958 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
3959 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
3960 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
3961 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
3965 case RENDERPATH_GL13:
3966 case RENDERPATH_GL11:
3967 if (gl_mesh_separatearrays.integer)
3969 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3970 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3971 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
3972 if (vid.texunits >= 2)
3973 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
3974 if (vid.texunits >= 3)
3975 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3979 case RENDERPATH_D3D9:
3980 case RENDERPATH_D3D10:
3981 case RENDERPATH_D3D11:
3985 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
3986 for (i = 0;i < numvertices;i++)
3987 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3989 for (i = 0;i < numvertices;i++)
3990 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
3992 for (i = 0;i < numvertices;i++)
3993 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
3995 for (i = 0;i < numvertices;i++)
3996 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
3999 for (i = 0;i < numvertices;i++)
4000 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4004 float tempcolor4f[4];
4005 unsigned char tempcolor4ub[4];
4006 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4007 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4008 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4009 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4010 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4011 for (i = 0;i < numvertices;i++)
4012 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4014 if (texcoordtexture2f)
4015 for (i = 0;i < numvertices;i++)
4016 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4017 if (texcoordlightmap2f)
4018 for (i = 0;i < numvertices;i++)
4019 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4020 R_Mesh_PrepareVertices_Mesh_Unlock();
4021 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4024 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4026 // upload temporary vertexbuffer for this rendering
4027 if (!gl_state.usevbo_staticvertex)
4028 vertexbuffer = NULL;
4029 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4031 if (gl_state.preparevertices_dynamicvertexbuffer)
4032 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4034 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4035 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4037 switch(vid.renderpath)
4039 case RENDERPATH_GL20:
4040 case RENDERPATH_CGGL:
4043 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4044 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4045 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4046 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4047 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4048 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4049 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4053 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4054 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4055 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4056 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4057 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4058 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4059 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4062 case RENDERPATH_GL13:
4065 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4066 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4067 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4068 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4072 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4073 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4074 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4075 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4078 case RENDERPATH_GL11:
4081 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4082 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4083 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4087 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4088 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4089 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4092 case RENDERPATH_D3D9:
4094 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4096 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4098 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4099 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4100 gl_state.d3dvertexdata = (void *)vertex;
4101 gl_state.d3dvertexsize = sizeof(*vertex);
4104 case RENDERPATH_D3D10:
4105 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4107 case RENDERPATH_D3D11:
4108 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);