3 #include "cl_collision.h"
4 #include "dpsoftrast.h"
7 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
8 extern D3DCAPS9 vid_d3d9caps;
11 #define MAX_RENDERTARGETS 4
13 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
14 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)"};
15 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"};
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_vertexgeneric_t *preparevertices_vertexgeneric;
170 r_vertexmesh_t *preparevertices_vertexmesh;
171 int preparevertices_numvertices;
173 r_meshbuffer_t *draw_dynamicindexbuffer;
175 qboolean usevbo_staticvertex;
176 qboolean usevbo_staticindex;
177 qboolean usevbo_dynamicvertex;
178 qboolean usevbo_dynamicindex;
180 memexpandablearray_t meshbufferarray;
185 // rtexture_t *d3drt_depthtexture;
186 // rtexture_t *d3drt_colortextures[MAX_RENDERTARGETS];
187 IDirect3DSurface9 *d3drt_depthsurface;
188 IDirect3DSurface9 *d3drt_colorsurfaces[MAX_RENDERTARGETS];
189 IDirect3DSurface9 *d3drt_backbufferdepthsurface;
190 IDirect3DSurface9 *d3drt_backbuffercolorsurface;
191 void *d3dvertexbuffer;
193 size_t d3dvertexsize;
198 static gl_state_t gl_state;
202 note: here's strip order for a terrain row:
209 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
211 *elements++ = i + row;
213 *elements++ = i + row + 1;
216 *elements++ = i + row + 1;
219 for (y = 0;y < rows - 1;y++)
221 for (x = 0;x < columns - 1;x++)
224 *elements++ = i + columns;
226 *elements++ = i + columns + 1;
229 *elements++ = i + columns + 1;
240 for (y = 0;y < rows - 1;y++)
242 for (x = 0;x < columns - 1;x++)
246 *elements++ = i + columns;
247 *elements++ = i + columns + 1;
248 *elements++ = i + columns;
249 *elements++ = i + columns + 1;
255 int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
256 unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
257 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
258 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
260 void GL_VBOStats_f(void)
262 GL_Mesh_ListVBOs(true);
265 static void GL_Backend_ResetState(void);
267 static void R_Mesh_InitVertexDeclarations(void);
268 static void R_Mesh_DestroyVertexDeclarations(void);
270 static void R_Mesh_SetUseVBO(void)
272 switch(vid.renderpath)
274 case RENDERPATH_GL11:
275 case RENDERPATH_GL13:
276 case RENDERPATH_GL20:
277 case RENDERPATH_CGGL:
278 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
279 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
280 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
281 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
283 case RENDERPATH_D3D9:
284 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
285 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
287 case RENDERPATH_D3D10:
288 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
290 case RENDERPATH_D3D11:
291 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
293 case RENDERPATH_SOFT:
294 gl_state.usevbo_staticvertex = false;
295 gl_state.usevbo_staticindex = false;
296 gl_state.usevbo_dynamicvertex = false;
297 gl_state.usevbo_dynamicindex = false;
302 static void gl_backend_start(void)
304 memset(&gl_state, 0, sizeof(gl_state));
306 R_Mesh_InitVertexDeclarations();
309 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
311 Con_DPrintf("OpenGL backend started.\n");
315 GL_Backend_ResetState();
317 switch(vid.renderpath)
319 case RENDERPATH_GL11:
320 case RENDERPATH_GL13:
321 case RENDERPATH_GL20:
322 case RENDERPATH_CGGL:
324 case RENDERPATH_D3D9:
326 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
327 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
330 case RENDERPATH_D3D10:
331 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
333 case RENDERPATH_D3D11:
334 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
336 case RENDERPATH_SOFT:
341 static void gl_backend_shutdown(void)
343 Con_DPrint("OpenGL Backend shutting down\n");
345 switch(vid.renderpath)
347 case RENDERPATH_GL11:
348 case RENDERPATH_GL13:
349 case RENDERPATH_GL20:
350 case RENDERPATH_CGGL:
352 case RENDERPATH_D3D9:
354 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
355 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
358 case RENDERPATH_D3D10:
359 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
361 case RENDERPATH_D3D11:
362 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
364 case RENDERPATH_SOFT:
368 if (gl_state.preparevertices_tempdata)
369 Mem_Free(gl_state.preparevertices_tempdata);
370 if (gl_state.preparevertices_dynamicvertexbuffer)
371 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
373 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
375 R_Mesh_DestroyVertexDeclarations();
377 memset(&gl_state, 0, sizeof(gl_state));
380 static void gl_backend_newmap(void)
384 static void gl_backend_devicelost(void)
387 r_meshbuffer_t *buffer;
389 gl_state.d3dvertexbuffer = NULL;
391 switch(vid.renderpath)
393 case RENDERPATH_GL11:
394 case RENDERPATH_GL13:
395 case RENDERPATH_GL20:
396 case RENDERPATH_CGGL:
398 case RENDERPATH_D3D9:
400 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
401 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
404 case RENDERPATH_D3D10:
405 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
407 case RENDERPATH_D3D11:
408 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
410 case RENDERPATH_SOFT:
413 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
414 for (i = 0;i < endindex;i++)
416 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
417 if (!buffer || !buffer->isdynamic)
419 switch(vid.renderpath)
421 case RENDERPATH_GL11:
422 case RENDERPATH_GL13:
423 case RENDERPATH_GL20:
424 case RENDERPATH_CGGL:
426 case RENDERPATH_D3D9:
428 if (buffer->devicebuffer)
430 if (buffer->isindexbuffer)
431 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
433 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
434 buffer->devicebuffer = NULL;
438 case RENDERPATH_D3D10:
439 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
441 case RENDERPATH_D3D11:
442 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
444 case RENDERPATH_SOFT:
450 static void gl_backend_devicerestored(void)
452 switch(vid.renderpath)
454 case RENDERPATH_GL11:
455 case RENDERPATH_GL13:
456 case RENDERPATH_GL20:
457 case RENDERPATH_CGGL:
459 case RENDERPATH_D3D9:
461 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
462 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
465 case RENDERPATH_D3D10:
466 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
468 case RENDERPATH_D3D11:
469 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
471 case RENDERPATH_SOFT:
476 void gl_backend_init(void)
480 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
482 polygonelement3s[i * 3 + 0] = 0;
483 polygonelement3s[i * 3 + 1] = i + 1;
484 polygonelement3s[i * 3 + 2] = i + 2;
486 // elements for rendering a series of quads as triangles
487 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
489 quadelement3s[i * 6 + 0] = i * 4;
490 quadelement3s[i * 6 + 1] = i * 4 + 1;
491 quadelement3s[i * 6 + 2] = i * 4 + 2;
492 quadelement3s[i * 6 + 3] = i * 4;
493 quadelement3s[i * 6 + 4] = i * 4 + 2;
494 quadelement3s[i * 6 + 5] = i * 4 + 3;
497 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
498 polygonelement3i[i] = polygonelement3s[i];
499 for (i = 0;i < QUADELEMENTS_MAXQUADS*3;i++)
500 quadelement3i[i] = quadelement3s[i];
502 Cvar_RegisterVariable(&r_render);
503 Cvar_RegisterVariable(&r_renderview);
504 Cvar_RegisterVariable(&r_waterwarp);
505 Cvar_RegisterVariable(&gl_polyblend);
506 Cvar_RegisterVariable(&v_flipped);
507 Cvar_RegisterVariable(&gl_dither);
508 Cvar_RegisterVariable(&gl_vbo);
509 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
510 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
511 Cvar_RegisterVariable(&gl_paranoid);
512 Cvar_RegisterVariable(&gl_printcheckerror);
514 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
515 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
516 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
518 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");
520 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
523 void GL_SetMirrorState(qboolean state);
525 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
529 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
530 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
532 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
534 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
535 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
536 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
538 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
541 static int bboxedges[12][2] =
560 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
562 int i, ix1, iy1, ix2, iy2;
563 float x1, y1, x2, y2;
574 scissor[0] = r_refdef.view.viewport.x;
575 scissor[1] = r_refdef.view.viewport.y;
576 scissor[2] = r_refdef.view.viewport.width;
577 scissor[3] = r_refdef.view.viewport.height;
579 // if view is inside the box, just say yes it's visible
580 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
583 x1 = y1 = x2 = y2 = 0;
585 // transform all corners that are infront of the nearclip plane
586 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
587 plane4f[3] = r_refdef.view.frustum[4].dist;
589 for (i = 0;i < 8;i++)
591 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
592 dist[i] = DotProduct4(corner[i], plane4f);
593 sign[i] = dist[i] > 0;
596 VectorCopy(corner[i], vertex[numvertices]);
600 // if some points are behind the nearclip, add clipped edge points to make
601 // sure that the scissor boundary is complete
602 if (numvertices > 0 && numvertices < 8)
604 // add clipped edge points
605 for (i = 0;i < 12;i++)
609 if (sign[j] != sign[k])
611 f = dist[j] / (dist[j] - dist[k]);
612 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
618 // if we have no points to check, it is behind the view plane
622 // if we have some points to transform, check what screen area is covered
623 x1 = y1 = x2 = y2 = 0;
625 //Con_Printf("%i vertices to transform...\n", numvertices);
626 for (i = 0;i < numvertices;i++)
628 VectorCopy(vertex[i], v);
629 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
630 //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]);
633 if (x1 > v2[0]) x1 = v2[0];
634 if (x2 < v2[0]) x2 = v2[0];
635 if (y1 > v2[1]) y1 = v2[1];
636 if (y2 < v2[1]) y2 = v2[1];
645 // now convert the scissor rectangle to integer screen coordinates
646 ix1 = (int)(x1 - 1.0f);
647 //iy1 = vid.height - (int)(y2 - 1.0f);
648 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
649 iy1 = (int)(y1 - 1.0f);
650 ix2 = (int)(x2 + 1.0f);
651 //iy2 = vid.height - (int)(y1 + 1.0f);
652 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
653 iy2 = (int)(y2 + 1.0f);
654 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
656 // clamp it to the screen
657 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
658 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
659 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
660 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
662 // if it is inside out, it's not visible
663 if (ix2 <= ix1 || iy2 <= iy1)
666 // the light area is visible, set up the scissor rectangle
669 scissor[2] = ix2 - ix1;
670 scissor[3] = iy2 - iy1;
672 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
673 switch(vid.renderpath)
675 case RENDERPATH_D3D9:
676 case RENDERPATH_D3D10:
677 case RENDERPATH_D3D11:
678 scissor[1] = vid.height - scissor[1] - scissor[3];
680 case RENDERPATH_GL11:
681 case RENDERPATH_GL13:
682 case RENDERPATH_GL20:
683 case RENDERPATH_CGGL:
684 case RENDERPATH_SOFT:
692 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
696 float clipPlane[4], v3[3], v4[3];
699 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
701 VectorSet(normal, normalx, normaly, normalz);
702 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
703 VectorScale(normal, dist, v3);
704 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
705 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
706 clipPlane[3] = -DotProduct(v4, clipPlane);
710 // testing code for comparing results
712 VectorCopy4(clipPlane, clipPlane2);
713 R_EntityMatrix(&identitymatrix);
714 VectorSet(q, normal[0], normal[1], normal[2], -dist);
715 qglClipPlane(GL_CLIP_PLANE0, q);
716 qglGetClipPlane(GL_CLIP_PLANE0, q);
717 VectorCopy4(q, clipPlane);
721 // Calculate the clip-space corner point opposite the clipping plane
722 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
723 // transform it into camera space by multiplying it
724 // by the inverse of the projection matrix
725 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
726 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
728 q[3] = (1.0f + m[10]) / m[14];
730 // Calculate the scaled plane vector
731 d = 2.0f / DotProduct4(clipPlane, q);
733 // Replace the third row of the projection matrix
734 m[2] = clipPlane[0] * d;
735 m[6] = clipPlane[1] * d;
736 m[10] = clipPlane[2] * d + 1.0f;
737 m[14] = clipPlane[3] * d;
740 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)
742 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
744 memset(v, 0, sizeof(*v));
745 v->type = R_VIEWPORTTYPE_ORTHO;
746 v->cameramatrix = *cameramatrix;
753 memset(m, 0, sizeof(m));
754 m[0] = 2/(right - left);
755 m[5] = 2/(top - bottom);
756 m[10] = -2/(zFar - zNear);
757 m[12] = - (right + left)/(right - left);
758 m[13] = - (top + bottom)/(top - bottom);
759 m[14] = - (zFar + zNear)/(zFar - zNear);
761 switch(vid.renderpath)
763 case RENDERPATH_GL11:
764 case RENDERPATH_GL13:
765 case RENDERPATH_GL20:
766 case RENDERPATH_CGGL:
767 case RENDERPATH_SOFT:
769 case RENDERPATH_D3D9:
770 case RENDERPATH_D3D10:
771 case RENDERPATH_D3D11:
772 m[10] = -1/(zFar - zNear);
773 m[14] = -zNear/(zFar-zNear);
776 v->screentodepth[0] = -farclip / (farclip - nearclip);
777 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
779 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
782 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
784 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
790 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
791 R_Viewport_TransformToScreen(v, test1, test2);
792 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
797 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)
799 matrix4x4_t tempmatrix, basematrix;
801 memset(v, 0, sizeof(*v));
803 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
804 v->cameramatrix = *cameramatrix;
811 memset(m, 0, sizeof(m));
812 m[0] = 1.0 / frustumx;
813 m[5] = 1.0 / frustumy;
814 m[10] = -(farclip + nearclip) / (farclip - nearclip);
816 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
817 v->screentodepth[0] = -farclip / (farclip - nearclip);
818 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
820 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
821 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
822 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
823 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
826 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
828 if(v_flipped.integer)
836 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
839 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)
841 matrix4x4_t tempmatrix, basematrix;
842 const float nudge = 1.0 - 1.0 / (1<<23);
844 memset(v, 0, sizeof(*v));
846 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
847 v->cameramatrix = *cameramatrix;
854 memset(m, 0, sizeof(m));
855 m[ 0] = 1.0 / frustumx;
856 m[ 5] = 1.0 / frustumy;
859 m[14] = -2 * nearclip * nudge;
860 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
861 v->screentodepth[1] = m[14] * -0.5;
863 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
864 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
865 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
866 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
869 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
871 if(v_flipped.integer)
879 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
882 float cubeviewmatrix[6][16] =
884 // standard cubemap projections
922 float rectviewmatrix[6][16] =
924 // sign-preserving cubemap projections
963 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
965 matrix4x4_t tempmatrix, basematrix;
967 memset(v, 0, sizeof(*v));
968 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
969 v->cameramatrix = *cameramatrix;
973 memset(m, 0, sizeof(m));
975 m[10] = -(farclip + nearclip) / (farclip - nearclip);
977 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
979 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
980 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
981 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
984 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
986 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
989 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)
991 matrix4x4_t tempmatrix, basematrix;
993 memset(v, 0, sizeof(*v));
994 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
995 v->cameramatrix = *cameramatrix;
996 v->x = (side & 1) * size;
997 v->y = (side >> 1) * size;
1001 memset(m, 0, sizeof(m));
1002 m[0] = m[5] = 1.0f * ((float)size - border) / size;
1003 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1005 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1007 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
1008 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1009 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1011 switch(vid.renderpath)
1013 case RENDERPATH_GL20:
1014 case RENDERPATH_CGGL:
1015 case RENDERPATH_GL13:
1016 case RENDERPATH_GL11:
1017 case RENDERPATH_SOFT:
1019 case RENDERPATH_D3D9:
1022 case RENDERPATH_D3D10:
1023 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1025 case RENDERPATH_D3D11:
1026 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1031 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1033 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1036 void R_SetViewport(const r_viewport_t *v)
1041 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1042 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1044 // copy over the matrices to our state
1045 gl_viewmatrix = v->viewmatrix;
1046 gl_projectionmatrix = v->projectmatrix;
1048 switch(vid.renderpath)
1050 case RENDERPATH_GL20:
1051 case RENDERPATH_CGGL:
1053 // qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1055 case RENDERPATH_GL13:
1056 case RENDERPATH_GL11:
1058 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1059 // Load the projection matrix into OpenGL
1060 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1061 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1062 qglLoadMatrixf(m);CHECKGLERROR
1063 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1065 case RENDERPATH_D3D9:
1068 D3DVIEWPORT9 d3dviewport;
1069 d3dviewport.X = gl_viewport.x;
1070 d3dviewport.Y = gl_viewport.y;
1071 d3dviewport.Width = gl_viewport.width;
1072 d3dviewport.Height = gl_viewport.height;
1073 d3dviewport.MinZ = gl_state.depthrange[0];
1074 d3dviewport.MaxZ = gl_state.depthrange[1];
1075 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1079 case RENDERPATH_D3D10:
1080 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1082 case RENDERPATH_D3D11:
1083 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1085 case RENDERPATH_SOFT:
1086 DPSOFTRAST_Viewport(v->x, v->y, v->width, v->height);
1090 // force an update of the derived matrices
1091 gl_modelmatrixchanged = true;
1092 R_EntityMatrix(&gl_modelmatrix);
1095 void R_GetViewport(r_viewport_t *v)
1100 static void GL_BindVBO(int bufferobject)
1102 if (gl_state.vertexbufferobject != bufferobject)
1104 gl_state.vertexbufferobject = bufferobject;
1106 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1110 static void GL_BindEBO(int bufferobject)
1112 if (gl_state.elementbufferobject != bufferobject)
1114 gl_state.elementbufferobject = bufferobject;
1116 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1120 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1123 switch(vid.renderpath)
1125 case RENDERPATH_GL11:
1126 case RENDERPATH_GL13:
1127 case RENDERPATH_GL20:
1128 case RENDERPATH_CGGL:
1129 if (!vid.support.ext_framebuffer_object)
1131 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1132 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1133 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1134 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1135 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1136 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1137 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1139 case RENDERPATH_D3D9:
1140 case RENDERPATH_D3D10:
1141 case RENDERPATH_D3D11:
1143 case RENDERPATH_SOFT:
1149 void R_Mesh_DestroyFramebufferObject(int fbo)
1151 switch(vid.renderpath)
1153 case RENDERPATH_GL11:
1154 case RENDERPATH_GL13:
1155 case RENDERPATH_GL20:
1156 case RENDERPATH_CGGL:
1158 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1160 case RENDERPATH_D3D9:
1161 case RENDERPATH_D3D10:
1162 case RENDERPATH_D3D11:
1164 case RENDERPATH_SOFT:
1170 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1172 // 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)
1173 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)
1176 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1177 if (gl_state.d3drt_depthsurface != depthsurface)
1179 gl_state.d3drt_depthsurface = depthsurface;
1180 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1182 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1184 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1185 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1187 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1189 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1190 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1192 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1194 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1195 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1197 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1199 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1200 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1205 void R_Mesh_ResetRenderTargets(void)
1207 switch(vid.renderpath)
1209 case RENDERPATH_GL11:
1210 case RENDERPATH_GL13:
1211 case RENDERPATH_GL20:
1212 case RENDERPATH_CGGL:
1213 if (gl_state.framebufferobject)
1215 gl_state.framebufferobject = 0;
1216 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1219 case RENDERPATH_D3D9:
1221 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1224 case RENDERPATH_D3D10:
1225 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1227 case RENDERPATH_D3D11:
1228 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1230 case RENDERPATH_SOFT:
1231 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1236 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1240 rtexture_t *textures[5];
1241 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1242 textures[4] = depthtexture;
1243 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1244 for (j = 0;j < 5;j++)
1246 for (i = 0;i < vid.teximageunits;i++)
1247 if (gl_state.units[i].texture == textures[j])
1248 R_Mesh_TexBind(i, NULL);
1249 // set up framebuffer object or render targets for the active rendering API
1250 switch(vid.renderpath)
1252 case RENDERPATH_GL11:
1253 case RENDERPATH_GL13:
1254 case RENDERPATH_GL20:
1255 case RENDERPATH_CGGL:
1256 if (gl_state.framebufferobject != fbo)
1258 gl_state.framebufferobject = fbo;
1259 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1262 case RENDERPATH_D3D9:
1264 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1265 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1268 IDirect3DSurface9 *colorsurfaces[4];
1269 for (i = 0;i < 4;i++)
1271 colorsurfaces[i] = NULL;
1273 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1275 // set the render targets for real
1276 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1277 // release the texture surface levels (they won't be lost while bound...)
1278 for (i = 0;i < 4;i++)
1280 IDirect3DSurface9_Release(colorsurfaces[i]);
1283 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1286 case RENDERPATH_D3D10:
1287 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1289 case RENDERPATH_D3D11:
1290 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1292 case RENDERPATH_SOFT:
1296 unsigned int *pointers[5];
1297 memset(pointers, 0, sizeof(pointers));
1298 for (i = 0;i < 5;i++)
1299 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1300 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1301 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1302 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1305 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1311 static int d3dcmpforglfunc(int f)
1315 case GL_NEVER: return D3DCMP_NEVER;
1316 case GL_LESS: return D3DCMP_LESS;
1317 case GL_EQUAL: return D3DCMP_EQUAL;
1318 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1319 case GL_GREATER: return D3DCMP_GREATER;
1320 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1321 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1322 case GL_ALWAYS: return D3DCMP_ALWAYS;
1323 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1327 static int d3dstencilopforglfunc(int f)
1331 case GL_KEEP: return D3DSTENCILOP_KEEP;
1332 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1333 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1334 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1340 static void GL_Backend_ResetState(void)
1343 gl_state.active = true;
1344 gl_state.depthtest = true;
1345 gl_state.alphatest = false;
1346 gl_state.alphafunc = GL_GEQUAL;
1347 gl_state.alphafuncvalue = 0.5f;
1348 gl_state.blendfunc1 = GL_ONE;
1349 gl_state.blendfunc2 = GL_ZERO;
1350 gl_state.blend = false;
1351 gl_state.depthmask = GL_TRUE;
1352 gl_state.colormask = 15;
1353 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1354 gl_state.lockrange_first = 0;
1355 gl_state.lockrange_count = 0;
1356 gl_state.cullface = GL_NONE;
1357 gl_state.cullfaceenable = false;
1358 gl_state.polygonoffset[0] = 0;
1359 gl_state.polygonoffset[1] = 0;
1360 gl_state.framebufferobject = 0;
1361 gl_state.depthfunc = GL_LEQUAL;
1363 switch(vid.renderpath)
1365 case RENDERPATH_D3D9:
1368 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1369 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
1370 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
1371 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, gl_state.alphafuncvalue * 256.0f, 255));
1372 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1373 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1374 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1375 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1376 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1377 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1381 case RENDERPATH_D3D10:
1382 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1384 case RENDERPATH_D3D11:
1385 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1387 case RENDERPATH_GL20:
1388 case RENDERPATH_CGGL:
1391 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1392 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1393 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1394 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1395 qglDisable(GL_BLEND);CHECKGLERROR
1396 qglCullFace(gl_state.cullface);CHECKGLERROR
1397 qglDisable(GL_CULL_FACE);CHECKGLERROR
1398 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1399 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1400 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1401 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1403 if (vid.support.arb_vertex_buffer_object)
1405 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1406 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1409 if (vid.support.ext_framebuffer_object)
1411 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1412 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1415 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1416 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1418 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1419 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1420 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1422 if (vid.support.ext_framebuffer_object)
1423 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1425 gl_state.unit = MAX_TEXTUREUNITS;
1426 gl_state.clientunit = MAX_TEXTUREUNITS;
1427 for (i = 0;i < vid.teximageunits;i++)
1429 GL_ActiveTexture(i);
1430 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1431 if (vid.support.ext_texture_3d)
1433 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1435 if (vid.support.arb_texture_cube_map)
1437 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1441 for (i = 0;i < vid.texarrayunits;i++)
1443 GL_ClientActiveTexture(i);
1445 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1446 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1450 case RENDERPATH_GL13:
1451 case RENDERPATH_GL11:
1454 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1455 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1456 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1457 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1458 qglDisable(GL_BLEND);CHECKGLERROR
1459 qglCullFace(gl_state.cullface);CHECKGLERROR
1460 qglDisable(GL_CULL_FACE);CHECKGLERROR
1461 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1462 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1463 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1464 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1466 if (vid.support.arb_vertex_buffer_object)
1468 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1469 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1472 if (vid.support.ext_framebuffer_object)
1474 //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1475 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1478 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1479 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1481 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1482 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1483 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1485 if (vid.support.ext_framebuffer_object)
1486 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1488 gl_state.unit = MAX_TEXTUREUNITS;
1489 gl_state.clientunit = MAX_TEXTUREUNITS;
1490 for (i = 0;i < vid.texunits;i++)
1492 GL_ActiveTexture(i);
1493 GL_ClientActiveTexture(i);
1494 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1495 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1496 if (vid.support.ext_texture_3d)
1498 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1499 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1501 if (vid.support.arb_texture_cube_map)
1503 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1504 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1507 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1508 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1509 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1510 qglLoadIdentity();CHECKGLERROR
1511 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1512 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1516 case RENDERPATH_SOFT:
1517 DPSOFTRAST_ColorMask(1,1,1,1);
1518 DPSOFTRAST_AlphaTest(gl_state.alphatest);
1519 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1520 DPSOFTRAST_CullFace(gl_state.cullface);
1521 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1522 DPSOFTRAST_DepthMask(gl_state.depthmask);
1523 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1524 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1525 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1530 void GL_ActiveTexture(unsigned int num)
1532 if (gl_state.unit != num)
1534 gl_state.unit = num;
1535 switch(vid.renderpath)
1537 case RENDERPATH_GL11:
1538 case RENDERPATH_GL13:
1539 case RENDERPATH_GL20:
1540 case RENDERPATH_CGGL:
1541 if (qglActiveTexture)
1544 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1548 case RENDERPATH_D3D9:
1549 case RENDERPATH_D3D10:
1550 case RENDERPATH_D3D11:
1552 case RENDERPATH_SOFT:
1558 void GL_ClientActiveTexture(unsigned int num)
1560 if (gl_state.clientunit != num)
1562 gl_state.clientunit = num;
1563 switch(vid.renderpath)
1565 case RENDERPATH_GL11:
1566 case RENDERPATH_GL13:
1567 case RENDERPATH_GL20:
1568 case RENDERPATH_CGGL:
1569 if (qglActiveTexture)
1572 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1576 case RENDERPATH_D3D9:
1577 case RENDERPATH_D3D10:
1578 case RENDERPATH_D3D11:
1580 case RENDERPATH_SOFT:
1586 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1588 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1590 qboolean blendenable;
1591 gl_state.blendfunc1 = blendfunc1;
1592 gl_state.blendfunc2 = blendfunc2;
1593 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1594 switch(vid.renderpath)
1596 case RENDERPATH_GL11:
1597 case RENDERPATH_GL13:
1598 case RENDERPATH_GL20:
1599 case RENDERPATH_CGGL:
1601 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1602 if (gl_state.blend != blendenable)
1604 gl_state.blend = blendenable;
1605 if (!gl_state.blend)
1607 qglDisable(GL_BLEND);CHECKGLERROR
1611 qglEnable(GL_BLEND);CHECKGLERROR
1615 case RENDERPATH_D3D9:
1620 D3DBLEND d3dblendfunc[2];
1621 glblendfunc[0] = gl_state.blendfunc1;
1622 glblendfunc[1] = gl_state.blendfunc2;
1623 for (i = 0;i < 2;i++)
1625 switch(glblendfunc[i])
1627 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1628 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1629 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1630 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1631 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1632 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1633 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1634 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1635 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1636 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1639 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1640 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1641 if (gl_state.blend != blendenable)
1643 gl_state.blend = blendenable;
1644 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1649 case RENDERPATH_D3D10:
1650 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1652 case RENDERPATH_D3D11:
1653 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1655 case RENDERPATH_SOFT:
1656 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1662 void GL_DepthMask(int state)
1664 if (gl_state.depthmask != state)
1666 gl_state.depthmask = state;
1667 switch(vid.renderpath)
1669 case RENDERPATH_GL11:
1670 case RENDERPATH_GL13:
1671 case RENDERPATH_GL20:
1672 case RENDERPATH_CGGL:
1674 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1676 case RENDERPATH_D3D9:
1678 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1681 case RENDERPATH_D3D10:
1682 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1684 case RENDERPATH_D3D11:
1685 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1687 case RENDERPATH_SOFT:
1688 DPSOFTRAST_DepthMask(gl_state.depthmask);
1694 void GL_DepthTest(int state)
1696 if (gl_state.depthtest != state)
1698 gl_state.depthtest = state;
1699 switch(vid.renderpath)
1701 case RENDERPATH_GL11:
1702 case RENDERPATH_GL13:
1703 case RENDERPATH_GL20:
1704 case RENDERPATH_CGGL:
1706 if (gl_state.depthtest)
1708 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1712 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1715 case RENDERPATH_D3D9:
1717 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1720 case RENDERPATH_D3D10:
1721 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1723 case RENDERPATH_D3D11:
1724 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1726 case RENDERPATH_SOFT:
1727 DPSOFTRAST_DepthTest(gl_state.depthtest);
1733 void GL_DepthFunc(int state)
1735 if (gl_state.depthfunc != state)
1737 gl_state.depthfunc = state;
1738 switch(vid.renderpath)
1740 case RENDERPATH_GL11:
1741 case RENDERPATH_GL13:
1742 case RENDERPATH_GL20:
1743 case RENDERPATH_CGGL:
1745 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1747 case RENDERPATH_D3D9:
1749 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1752 case RENDERPATH_D3D10:
1753 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1755 case RENDERPATH_D3D11:
1756 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1758 case RENDERPATH_SOFT:
1759 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1765 void GL_DepthRange(float nearfrac, float farfrac)
1767 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1769 gl_state.depthrange[0] = nearfrac;
1770 gl_state.depthrange[1] = farfrac;
1771 switch(vid.renderpath)
1773 case RENDERPATH_GL11:
1774 case RENDERPATH_GL13:
1775 case RENDERPATH_GL20:
1776 case RENDERPATH_CGGL:
1777 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1779 case RENDERPATH_D3D9:
1782 D3DVIEWPORT9 d3dviewport;
1783 d3dviewport.X = gl_viewport.x;
1784 d3dviewport.Y = gl_viewport.y;
1785 d3dviewport.Width = gl_viewport.width;
1786 d3dviewport.Height = gl_viewport.height;
1787 d3dviewport.MinZ = gl_state.depthrange[0];
1788 d3dviewport.MaxZ = gl_state.depthrange[1];
1789 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1793 case RENDERPATH_D3D10:
1794 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1796 case RENDERPATH_D3D11:
1797 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1799 case RENDERPATH_SOFT:
1800 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1806 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)
1808 switch (vid.renderpath)
1810 case RENDERPATH_GL11:
1811 case RENDERPATH_GL13:
1812 case RENDERPATH_GL20:
1813 case RENDERPATH_CGGL:
1817 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1821 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1823 if (vid.support.ati_separate_stencil)
1825 qglStencilMask(writemask);CHECKGLERROR
1826 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1827 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1828 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1830 else if (vid.support.ext_stencil_two_side)
1832 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1833 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1834 qglStencilMask(writemask);CHECKGLERROR
1835 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1836 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1837 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1838 qglStencilMask(writemask);CHECKGLERROR
1839 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1840 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1843 case RENDERPATH_D3D9:
1845 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1846 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1847 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1848 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1849 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1850 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1851 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1852 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1853 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1854 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1855 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1856 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1857 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1860 case RENDERPATH_D3D10:
1861 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1863 case RENDERPATH_D3D11:
1864 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1866 case RENDERPATH_SOFT:
1867 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1872 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1874 switch (vid.renderpath)
1876 case RENDERPATH_GL11:
1877 case RENDERPATH_GL13:
1878 case RENDERPATH_GL20:
1879 case RENDERPATH_CGGL:
1883 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1887 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1889 if (vid.support.ext_stencil_two_side)
1891 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1893 qglStencilMask(writemask);CHECKGLERROR
1894 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1895 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1898 case RENDERPATH_D3D9:
1900 if (vid.support.ati_separate_stencil)
1901 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1902 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1903 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1904 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1905 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1906 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1907 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1908 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1909 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1912 case RENDERPATH_D3D10:
1913 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1915 case RENDERPATH_D3D11:
1916 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1918 case RENDERPATH_SOFT:
1919 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1924 void GL_PolygonOffset(float planeoffset, float depthoffset)
1926 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
1928 gl_state.polygonoffset[0] = planeoffset;
1929 gl_state.polygonoffset[1] = depthoffset;
1930 switch(vid.renderpath)
1932 case RENDERPATH_GL11:
1933 case RENDERPATH_GL13:
1934 case RENDERPATH_GL20:
1935 case RENDERPATH_CGGL:
1936 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1938 case RENDERPATH_D3D9:
1940 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1941 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1944 case RENDERPATH_D3D10:
1945 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1947 case RENDERPATH_D3D11:
1948 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1950 case RENDERPATH_SOFT:
1951 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1957 void GL_SetMirrorState(qboolean state)
1959 if (v_flipped_state != state)
1961 v_flipped_state = state;
1962 if (gl_state.cullface == GL_BACK)
1963 gl_state.cullface = GL_FRONT;
1964 else if (gl_state.cullface == GL_FRONT)
1965 gl_state.cullface = GL_BACK;
1968 switch(vid.renderpath)
1970 case RENDERPATH_GL11:
1971 case RENDERPATH_GL13:
1972 case RENDERPATH_GL20:
1973 case RENDERPATH_CGGL:
1974 qglCullFace(gl_state.cullface);
1976 case RENDERPATH_D3D9:
1978 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
1981 case RENDERPATH_D3D10:
1982 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1984 case RENDERPATH_D3D11:
1985 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1987 case RENDERPATH_SOFT:
1988 DPSOFTRAST_CullFace(gl_state.cullface);
1994 void GL_CullFace(int state)
1998 if(state == GL_FRONT)
2000 else if(state == GL_BACK)
2004 switch(vid.renderpath)
2006 case RENDERPATH_GL11:
2007 case RENDERPATH_GL13:
2008 case RENDERPATH_GL20:
2009 case RENDERPATH_CGGL:
2012 if (state != GL_NONE)
2014 if (!gl_state.cullfaceenable)
2016 gl_state.cullfaceenable = true;
2017 qglEnable(GL_CULL_FACE);CHECKGLERROR
2019 if (gl_state.cullface != state)
2021 gl_state.cullface = state;
2022 qglCullFace(gl_state.cullface);CHECKGLERROR
2027 if (gl_state.cullfaceenable)
2029 gl_state.cullfaceenable = false;
2030 qglDisable(GL_CULL_FACE);CHECKGLERROR
2034 case RENDERPATH_D3D9:
2036 if (gl_state.cullface != state)
2038 gl_state.cullface = state;
2039 switch(gl_state.cullface)
2042 gl_state.cullfaceenable = false;
2043 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2046 gl_state.cullfaceenable = true;
2047 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2050 gl_state.cullfaceenable = true;
2051 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2057 case RENDERPATH_D3D10:
2058 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2060 case RENDERPATH_D3D11:
2061 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2063 case RENDERPATH_SOFT:
2064 DPSOFTRAST_CullFace(gl_state.cullface);
2069 void GL_AlphaTest(int state)
2071 if (gl_state.alphatest != state)
2073 gl_state.alphatest = state;
2074 switch(vid.renderpath)
2076 case RENDERPATH_GL11:
2077 case RENDERPATH_GL13:
2078 case RENDERPATH_GL20:
2079 case RENDERPATH_CGGL:
2081 if (gl_state.alphatest)
2083 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2087 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2090 case RENDERPATH_D3D9:
2092 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
2095 case RENDERPATH_D3D10:
2096 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2098 case RENDERPATH_D3D11:
2099 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2101 case RENDERPATH_SOFT:
2102 DPSOFTRAST_AlphaTest(gl_state.alphatest);
2108 void GL_AlphaFunc(int state, float value)
2110 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
2112 gl_state.alphafunc = state;
2113 gl_state.alphafuncvalue = value;
2114 switch(vid.renderpath)
2116 case RENDERPATH_GL11:
2117 case RENDERPATH_GL13:
2118 case RENDERPATH_GL20:
2119 case RENDERPATH_CGGL:
2121 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
2123 case RENDERPATH_D3D9:
2125 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
2126 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
2129 case RENDERPATH_D3D10:
2130 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2132 case RENDERPATH_D3D11:
2133 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2135 case RENDERPATH_SOFT:
2136 DPSOFTRAST_AlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);
2142 void GL_ColorMask(int r, int g, int b, int a)
2144 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2145 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2146 if (gl_state.colormask != state)
2148 gl_state.colormask = state;
2149 switch(vid.renderpath)
2151 case RENDERPATH_GL11:
2152 case RENDERPATH_GL13:
2153 case RENDERPATH_GL20:
2154 case RENDERPATH_CGGL:
2156 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2158 case RENDERPATH_D3D9:
2160 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
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__);
2169 case RENDERPATH_SOFT:
2170 DPSOFTRAST_ColorMask(r, g, b, a);
2176 void GL_Color(float cr, float cg, float cb, float ca)
2178 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)
2180 gl_state.color4f[0] = cr;
2181 gl_state.color4f[1] = cg;
2182 gl_state.color4f[2] = cb;
2183 gl_state.color4f[3] = ca;
2184 switch(vid.renderpath)
2186 case RENDERPATH_GL11:
2187 case RENDERPATH_GL13:
2188 case RENDERPATH_GL20:
2189 case RENDERPATH_CGGL:
2191 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2194 case RENDERPATH_D3D9:
2195 case RENDERPATH_D3D10:
2196 case RENDERPATH_D3D11:
2197 // no equivalent in D3D
2199 case RENDERPATH_SOFT:
2200 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2206 void GL_Scissor (int x, int y, int width, int height)
2208 switch(vid.renderpath)
2210 case RENDERPATH_GL11:
2211 case RENDERPATH_GL13:
2212 case RENDERPATH_GL20:
2213 case RENDERPATH_CGGL:
2215 qglScissor(x, y,width,height);
2218 case RENDERPATH_D3D9:
2224 d3drect.right = x + width;
2225 d3drect.bottom = y + height;
2226 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2230 case RENDERPATH_D3D10:
2231 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2233 case RENDERPATH_D3D11:
2234 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2236 case RENDERPATH_SOFT:
2237 DPSOFTRAST_Scissor(x, y, width, height);
2242 void GL_ScissorTest(int state)
2244 if (gl_state.scissortest != state)
2246 gl_state.scissortest = state;
2247 switch(vid.renderpath)
2249 case RENDERPATH_GL11:
2250 case RENDERPATH_GL13:
2251 case RENDERPATH_GL20:
2252 case RENDERPATH_CGGL:
2254 if(gl_state.scissortest)
2255 qglEnable(GL_SCISSOR_TEST);
2257 qglDisable(GL_SCISSOR_TEST);
2260 case RENDERPATH_D3D9:
2262 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2265 case RENDERPATH_D3D10:
2266 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2268 case RENDERPATH_D3D11:
2269 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2271 case RENDERPATH_SOFT:
2272 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2278 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2280 static const float blackcolor[4] = {0, 0, 0, 0};
2281 // prevent warnings when trying to clear a buffer that does not exist
2283 colorvalue = blackcolor;
2286 mask &= ~GL_STENCIL_BUFFER_BIT;
2289 switch(vid.renderpath)
2291 case RENDERPATH_GL11:
2292 case RENDERPATH_GL13:
2293 case RENDERPATH_GL20:
2294 case RENDERPATH_CGGL:
2296 if (mask & GL_COLOR_BUFFER_BIT)
2298 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2300 if (mask & GL_DEPTH_BUFFER_BIT)
2302 qglClearDepth(depthvalue);CHECKGLERROR
2304 if (mask & GL_STENCIL_BUFFER_BIT)
2306 qglClearStencil(stencilvalue);CHECKGLERROR
2308 qglClear(mask);CHECKGLERROR
2310 case RENDERPATH_D3D9:
2312 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);
2315 case RENDERPATH_D3D10:
2316 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2318 case RENDERPATH_D3D11:
2319 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2321 case RENDERPATH_SOFT:
2322 if (mask & GL_COLOR_BUFFER_BIT)
2323 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2324 if (mask & GL_DEPTH_BUFFER_BIT)
2325 DPSOFTRAST_ClearDepth(depthvalue);
2330 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2332 switch(vid.renderpath)
2334 case RENDERPATH_GL11:
2335 case RENDERPATH_GL13:
2336 case RENDERPATH_GL20:
2337 case RENDERPATH_CGGL:
2339 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2341 case RENDERPATH_D3D9:
2344 // LordHavoc: we can't directly download the backbuffer because it may be
2345 // multisampled, and it may not be lockable, so we blit it to a lockable
2346 // surface of the same dimensions (but without multisample) to resolve the
2347 // multisample buffer to a normal image, and then lock that...
2348 IDirect3DSurface9 *stretchsurface = NULL;
2349 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2351 D3DLOCKED_RECT lockedrect;
2352 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2354 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2357 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2358 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2359 memcpy(outpixels + line * width * 4, row, width * 4);
2360 IDirect3DSurface9_UnlockRect(stretchsurface);
2363 IDirect3DSurface9_Release(stretchsurface);
2366 //IDirect3DSurface9 *syssurface = NULL;
2367 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2368 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2369 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2370 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2371 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2372 //IDirect3DSurface9_UnlockRect(syssurface);
2373 //IDirect3DSurface9_Release(syssurface);
2377 case RENDERPATH_D3D10:
2378 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2380 case RENDERPATH_D3D11:
2381 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2383 case RENDERPATH_SOFT:
2384 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2389 // called at beginning of frame
2390 void R_Mesh_Start(void)
2393 R_Mesh_ResetRenderTargets();
2395 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2397 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2398 Cvar_SetValueQuick(&gl_paranoid, 1);
2402 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2406 char compilelog[MAX_INPUTLINE];
2407 shaderobject = qglCreateShaderObjectARB(shadertypeenum);CHECKGLERROR
2410 qglShaderSourceARB(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2411 qglCompileShaderARB(shaderobject);CHECKGLERROR
2412 qglGetObjectParameterivARB(shaderobject, GL_OBJECT_COMPILE_STATUS_ARB, &shadercompiled);CHECKGLERROR
2413 qglGetInfoLogARB(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2414 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2416 int i, j, pretextlines = 0;
2417 for (i = 0;i < numstrings - 1;i++)
2418 for (j = 0;strings[i][j];j++)
2419 if (strings[i][j] == '\n')
2421 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2423 if (!shadercompiled)
2425 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2428 qglAttachObjectARB(programobject, shaderobject);CHECKGLERROR
2429 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2433 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)
2435 GLint programlinked;
2436 GLuint programobject = 0;
2437 char linklog[MAX_INPUTLINE];
2440 programobject = qglCreateProgramObjectARB();CHECKGLERROR
2444 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER_ARB, "vertex", vertexstrings_count, vertexstrings_list))
2447 #ifdef GL_GEOMETRY_SHADER_ARB
2448 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER_ARB, "geometry", geometrystrings_count, geometrystrings_list))
2452 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER_ARB, "fragment", fragmentstrings_count, fragmentstrings_list))
2455 qglLinkProgramARB(programobject);CHECKGLERROR
2456 qglGetObjectParameterivARB(programobject, GL_OBJECT_LINK_STATUS_ARB, &programlinked);CHECKGLERROR
2457 qglGetInfoLogARB(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2460 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2461 Con_DPrintf("program link log:\n%s\n", linklog);
2462 // software vertex shader is ok but software fragment shader is WAY
2463 // too slow, fail program if so.
2464 // NOTE: this string might be ATI specific, but that's ok because the
2465 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2466 // software fragment shader due to low instruction and dependent
2468 if (strstr(linklog, "fragment shader will run in software"))
2469 programlinked = false;
2473 return programobject;
2475 qglDeleteObjectARB(programobject);CHECKGLERROR
2479 void GL_Backend_FreeProgram(unsigned int prog)
2482 qglDeleteObjectARB(prog);
2486 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2491 for (i = 0;i < count;i++)
2492 *out++ = *in++ + offset;
2495 memcpy(out, in, sizeof(*out) * count);
2498 // renders triangles using vertices from the active arrays
2499 int paranoidblah = 0;
2500 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)
2502 unsigned int numelements = numtriangles * 3;
2504 size_t bufferoffset3i;
2506 size_t bufferoffset3s;
2507 if (numvertices < 3 || numtriangles < 1)
2509 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2510 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);
2513 if (!gl_mesh_prefer_short_elements.integer)
2517 if (element3i_indexbuffer)
2518 element3i_indexbuffer = NULL;
2520 // adjust the pointers for firsttriangle
2522 element3i += firsttriangle * 3;
2523 if (element3i_indexbuffer)
2524 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2526 element3s += firsttriangle * 3;
2527 if (element3s_indexbuffer)
2528 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2529 switch(vid.renderpath)
2531 case RENDERPATH_GL11:
2532 case RENDERPATH_GL13:
2533 case RENDERPATH_GL20:
2534 case RENDERPATH_CGGL:
2535 // check if the user specified to ignore static index buffers
2536 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2538 element3i_indexbuffer = NULL;
2539 element3s_indexbuffer = NULL;
2542 case RENDERPATH_D3D9:
2543 case RENDERPATH_D3D10:
2544 case RENDERPATH_D3D11:
2546 case RENDERPATH_SOFT:
2549 // upload a dynamic index buffer if needed
2552 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2554 if (gl_state.draw_dynamicindexbuffer)
2555 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2557 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2558 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2559 element3s_bufferoffset = 0;
2564 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2566 if (gl_state.draw_dynamicindexbuffer)
2567 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2569 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2570 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2571 element3i_bufferoffset = 0;
2574 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2575 bufferoffset3i = element3i_bufferoffset;
2576 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2577 bufferoffset3s = element3s_bufferoffset;
2578 r_refdef.stats.draws++;
2579 r_refdef.stats.draws_vertices += numvertices;
2580 r_refdef.stats.draws_elements += numelements;
2581 if (gl_paranoid.integer)
2584 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2586 unsigned int j, size;
2588 // note: there's no validation done here on buffer objects because it
2589 // is somewhat difficult to get at the data, and gl_paranoid can be
2590 // used without buffer objects if the need arises
2591 // (the data could be gotten using glMapBuffer but it would be very
2592 // slow due to uncachable video memory reads)
2593 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2594 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2596 if (gl_state.pointer_vertex_pointer)
2597 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2599 if (gl_state.pointer_color_enabled)
2601 if (!qglIsEnabled(GL_COLOR_ARRAY))
2602 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2604 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2605 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2608 for (i = 0;i < vid.texarrayunits;i++)
2610 if (gl_state.units[i].arrayenabled)
2612 GL_ClientActiveTexture(i);
2613 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2614 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2616 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2617 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++)
2624 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2626 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2628 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2635 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2637 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2639 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2645 if (r_render.integer || r_refdef.draw2dstage)
2647 switch(vid.renderpath)
2649 case RENDERPATH_GL11:
2650 case RENDERPATH_GL13:
2651 case RENDERPATH_GL20:
2652 case RENDERPATH_CGGL:
2654 if (gl_mesh_testmanualfeeding.integer)
2656 unsigned int i, j, element;
2658 qglBegin(GL_TRIANGLES);
2659 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2662 element = element3i[i];
2664 element = element3s[i];
2666 element = firstvertex + i;
2667 for (j = 0;j < vid.texarrayunits;j++)
2669 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2671 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2673 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2674 if (vid.texarrayunits > 1)
2676 if (gl_state.units[j].pointer_texcoord_components == 4)
2677 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2678 else if (gl_state.units[j].pointer_texcoord_components == 3)
2679 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2680 else if (gl_state.units[j].pointer_texcoord_components == 2)
2681 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2683 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2687 if (gl_state.units[j].pointer_texcoord_components == 4)
2688 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2689 else if (gl_state.units[j].pointer_texcoord_components == 3)
2690 qglTexCoord3f(p[0], p[1], p[2]);
2691 else if (gl_state.units[j].pointer_texcoord_components == 2)
2692 qglTexCoord2f(p[0], p[1]);
2694 qglTexCoord1f(p[0]);
2697 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2699 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2700 if (vid.texarrayunits > 1)
2702 if (gl_state.units[j].pointer_texcoord_components == 4)
2703 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2704 else if (gl_state.units[j].pointer_texcoord_components == 3)
2705 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2706 else if (gl_state.units[j].pointer_texcoord_components == 2)
2707 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2708 else if (gl_state.units[j].pointer_texcoord_components == 1)
2709 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2713 if (gl_state.units[j].pointer_texcoord_components == 4)
2714 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2715 else if (gl_state.units[j].pointer_texcoord_components == 3)
2716 qglTexCoord3f(s[0], s[1], s[2]);
2717 else if (gl_state.units[j].pointer_texcoord_components == 2)
2718 qglTexCoord2f(s[0], s[1]);
2719 else if (gl_state.units[j].pointer_texcoord_components == 1)
2720 qglTexCoord1f(s[0]);
2723 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2725 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2726 if (vid.texarrayunits > 1)
2728 if (gl_state.units[j].pointer_texcoord_components == 4)
2729 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2730 else if (gl_state.units[j].pointer_texcoord_components == 3)
2731 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2732 else if (gl_state.units[j].pointer_texcoord_components == 2)
2733 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2734 else if (gl_state.units[j].pointer_texcoord_components == 1)
2735 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2739 if (gl_state.units[j].pointer_texcoord_components == 4)
2740 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2741 else if (gl_state.units[j].pointer_texcoord_components == 3)
2742 qglTexCoord3f(sb[0], sb[1], sb[2]);
2743 else if (gl_state.units[j].pointer_texcoord_components == 2)
2744 qglTexCoord2f(sb[0], sb[1]);
2745 else if (gl_state.units[j].pointer_texcoord_components == 1)
2746 qglTexCoord1f(sb[0]);
2751 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2753 if (gl_state.pointer_color_gltype == GL_FLOAT)
2755 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2756 qglColor4f(p[0], p[1], p[2], p[3]);
2758 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2760 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2761 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2764 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2766 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2767 if (gl_state.pointer_vertex_components == 4)
2768 qglVertex4f(p[0], p[1], p[2], p[3]);
2769 else if (gl_state.pointer_vertex_components == 3)
2770 qglVertex3f(p[0], p[1], p[2]);
2772 qglVertex2f(p[0], p[1]);
2778 else if (bufferobject3s)
2780 GL_BindEBO(bufferobject3s);
2781 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2783 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2788 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2792 else if (bufferobject3i)
2794 GL_BindEBO(bufferobject3i);
2795 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2797 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2802 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2809 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2811 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2816 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2823 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2825 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2830 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2836 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2840 case RENDERPATH_D3D9:
2842 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2844 if (element3s_indexbuffer)
2846 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2847 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2849 else if (element3i_indexbuffer)
2851 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2852 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2855 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2860 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2862 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2864 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2868 case RENDERPATH_D3D10:
2869 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2871 case RENDERPATH_D3D11:
2872 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2874 case RENDERPATH_SOFT:
2875 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
2881 // restores backend state, used when done with 3D rendering
2882 void R_Mesh_Finish(void)
2884 R_Mesh_ResetRenderTargets();
2887 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
2889 r_meshbuffer_t *buffer;
2890 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
2892 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
2893 memset(buffer, 0, sizeof(*buffer));
2894 buffer->bufferobject = 0;
2895 buffer->devicebuffer = NULL;
2897 buffer->isindexbuffer = isindexbuffer;
2898 buffer->isdynamic = isdynamic;
2899 buffer->isindex16 = isindex16;
2900 strlcpy(buffer->name, name, sizeof(buffer->name));
2901 R_Mesh_UpdateMeshBuffer(buffer, data, size);
2905 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
2909 if (buffer->isindexbuffer)
2911 r_refdef.stats.indexbufferuploadcount++;
2912 r_refdef.stats.indexbufferuploadsize += size;
2916 r_refdef.stats.vertexbufferuploadcount++;
2917 r_refdef.stats.vertexbufferuploadsize += size;
2919 switch(vid.renderpath)
2921 case RENDERPATH_GL11:
2922 case RENDERPATH_GL13:
2923 case RENDERPATH_GL20:
2924 case RENDERPATH_CGGL:
2925 if (!buffer->bufferobject)
2926 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
2927 if (buffer->isindexbuffer)
2928 GL_BindEBO(buffer->bufferobject);
2930 GL_BindVBO(buffer->bufferobject);
2931 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
2933 case RENDERPATH_D3D9:
2937 void *datapointer = NULL;
2938 if (buffer->isindexbuffer)
2940 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
2941 if (size > buffer->size || !buffer->devicebuffer)
2943 if (buffer->devicebuffer)
2944 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
2945 buffer->devicebuffer = NULL;
2946 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)))
2947 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);
2948 buffer->devicebuffer = (void *)d3d9indexbuffer;
2949 buffer->size = size;
2951 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2954 memcpy(datapointer, data, size);
2956 memset(datapointer, 0, size);
2957 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
2962 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
2963 if (size > buffer->size || !buffer->devicebuffer)
2965 if (buffer->devicebuffer)
2966 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
2967 buffer->devicebuffer = NULL;
2968 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
2969 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);
2970 buffer->devicebuffer = (void *)d3d9vertexbuffer;
2971 buffer->size = size;
2973 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2976 memcpy(datapointer, data, size);
2978 memset(datapointer, 0, size);
2979 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
2985 case RENDERPATH_D3D10:
2986 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2988 case RENDERPATH_D3D11:
2989 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2991 case RENDERPATH_SOFT:
2996 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3000 switch(vid.renderpath)
3002 case RENDERPATH_GL11:
3003 case RENDERPATH_GL13:
3004 case RENDERPATH_GL20:
3005 case RENDERPATH_CGGL:
3006 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3008 case RENDERPATH_D3D9:
3010 if (gl_state.d3dvertexbuffer == (void *)buffer)
3011 gl_state.d3dvertexbuffer = NULL;
3012 if (buffer->devicebuffer)
3014 if (buffer->isindexbuffer)
3015 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3017 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3018 buffer->devicebuffer = NULL;
3022 case RENDERPATH_D3D10:
3023 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3025 case RENDERPATH_D3D11:
3026 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3028 case RENDERPATH_SOFT:
3031 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3034 void GL_Mesh_ListVBOs(qboolean printeach)
3037 size_t ebocount = 0, ebomemory = 0;
3038 size_t vbocount = 0, vbomemory = 0;
3039 r_meshbuffer_t *buffer;
3040 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3041 for (i = 0;i < endindex;i++)
3043 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3046 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)");}
3047 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)");}
3049 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);
3054 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3056 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3057 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)
3059 gl_state.pointer_vertex_components = components;
3060 gl_state.pointer_vertex_gltype = gltype;
3061 gl_state.pointer_vertex_stride = stride;
3062 gl_state.pointer_vertex_pointer = pointer;
3063 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3064 gl_state.pointer_vertex_offset = bufferoffset;
3066 GL_BindVBO(bufferobject);
3067 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3071 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3073 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3074 // the pointer only.
3077 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3078 // caller wants color array enabled
3079 if (!gl_state.pointer_color_enabled)
3081 gl_state.pointer_color_enabled = true;
3083 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3085 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)
3087 gl_state.pointer_color_components = components;
3088 gl_state.pointer_color_gltype = gltype;
3089 gl_state.pointer_color_stride = stride;
3090 gl_state.pointer_color_pointer = pointer;
3091 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3092 gl_state.pointer_color_offset = bufferoffset;
3094 GL_BindVBO(bufferobject);
3095 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3100 // caller wants color array disabled
3101 if (gl_state.pointer_color_enabled)
3103 gl_state.pointer_color_enabled = false;
3105 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3106 // when color array is on the glColor gets trashed, set it again
3107 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3112 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)
3114 gltextureunit_t *unit = gl_state.units + unitnum;
3115 // update array settings
3117 // note: there is no need to check bufferobject here because all cases
3118 // that involve a valid bufferobject also supply a texcoord array
3121 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3122 // texture array unit is enabled, enable the array
3123 if (!unit->arrayenabled)
3125 unit->arrayenabled = true;
3126 GL_ClientActiveTexture(unitnum);
3127 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3130 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)
3132 unit->pointer_texcoord_components = components;
3133 unit->pointer_texcoord_gltype = gltype;
3134 unit->pointer_texcoord_stride = stride;
3135 unit->pointer_texcoord_pointer = pointer;
3136 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3137 unit->pointer_texcoord_offset = bufferoffset;
3138 GL_ClientActiveTexture(unitnum);
3139 GL_BindVBO(bufferobject);
3140 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3145 // texture array unit is disabled, disable the array
3146 if (unit->arrayenabled)
3148 unit->arrayenabled = false;
3149 GL_ClientActiveTexture(unitnum);
3150 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3155 int R_Mesh_TexBound(unsigned int unitnum, int id)
3157 gltextureunit_t *unit = gl_state.units + unitnum;
3158 if (unitnum >= vid.teximageunits)
3160 if (id == GL_TEXTURE_2D)
3162 if (id == GL_TEXTURE_3D)
3164 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3165 return unit->tcubemap;
3169 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3171 switch(vid.renderpath)
3173 case RENDERPATH_GL11:
3174 case RENDERPATH_GL13:
3175 case RENDERPATH_GL20:
3176 case RENDERPATH_CGGL:
3177 R_Mesh_TexBind(0, tex);
3178 GL_ActiveTexture(0);CHECKGLERROR
3179 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3181 case RENDERPATH_D3D9:
3184 IDirect3DSurface9 *currentsurface = NULL;
3185 IDirect3DSurface9 *texturesurface = NULL;
3188 sourcerect.left = sx;
3189 sourcerect.top = sy;
3190 sourcerect.right = sx + width;
3191 sourcerect.bottom = sy + height;
3194 destrect.right = tx + width;
3195 destrect.bottom = ty + height;
3196 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3198 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3200 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3201 IDirect3DSurface9_Release(currentsurface);
3203 IDirect3DSurface9_Release(texturesurface);
3208 case RENDERPATH_D3D10:
3209 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3211 case RENDERPATH_D3D11:
3212 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3214 case RENDERPATH_SOFT:
3215 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3221 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};
3224 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3226 gltextureunit_t *unit = gl_state.units + unitnum;
3227 int tex2d, tex3d, texcubemap, texnum;
3228 if (unitnum >= vid.teximageunits)
3230 // if (unit->texture == tex)
3232 switch(vid.renderpath)
3234 case RENDERPATH_GL20:
3235 case RENDERPATH_CGGL:
3238 tex = r_texture_white;
3239 // not initialized enough yet...
3243 unit->texture = tex;
3244 texnum = R_GetTexture(tex);
3245 switch(tex->gltexturetypeenum)
3247 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3248 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3249 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;
3252 case RENDERPATH_GL13:
3253 case RENDERPATH_GL11:
3254 unit->texture = tex;
3260 texnum = R_GetTexture(tex);
3261 switch(tex->gltexturetypeenum)
3269 case GL_TEXTURE_CUBE_MAP_ARB:
3270 texcubemap = texnum;
3274 // update 2d texture binding
3275 if (unit->t2d != tex2d)
3277 GL_ActiveTexture(unitnum);
3282 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3289 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3293 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3295 // update 3d texture binding
3296 if (unit->t3d != tex3d)
3298 GL_ActiveTexture(unitnum);
3303 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3310 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3314 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3316 // update cubemap texture binding
3317 if (unit->tcubemap != texcubemap)
3319 GL_ActiveTexture(unitnum);
3322 if (unit->tcubemap == 0)
3324 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3331 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3334 unit->tcubemap = texcubemap;
3335 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3338 case RENDERPATH_D3D9:
3341 extern cvar_t gl_texture_anisotropy;
3344 tex = r_texture_white;
3345 // not initialized enough yet...
3349 if (unit->texture == tex)
3351 unit->texture = tex;
3352 // upload texture if needed
3354 R_RealGetTexture(tex);
3355 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3356 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3357 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3358 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3359 if (tex->d3daddressw)
3360 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3361 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3362 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3363 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3364 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3365 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3366 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3370 case RENDERPATH_D3D10:
3371 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3373 case RENDERPATH_D3D11:
3374 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3376 case RENDERPATH_SOFT:
3379 tex = r_texture_white;
3380 // not initialized enough yet...
3384 if (unit->texture == tex)
3386 unit->texture = tex;
3387 DPSOFTRAST_SetTexture(unitnum, R_GetTexture(tex));
3392 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3394 gltextureunit_t *unit = gl_state.units + unitnum;
3395 switch(vid.renderpath)
3397 case RENDERPATH_GL11:
3398 case RENDERPATH_GL13:
3399 case RENDERPATH_GL20:
3400 case RENDERPATH_CGGL:
3401 if (matrix && matrix->m[3][3])
3403 // texmatrix specified, check if it is different
3404 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3407 unit->texmatrixenabled = true;
3408 unit->matrix = *matrix;
3410 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3411 GL_ActiveTexture(unitnum);
3412 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3413 qglLoadMatrixf(glmatrix);CHECKGLERROR
3414 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3419 // no texmatrix specified, revert to identity
3420 if (unit->texmatrixenabled)
3422 unit->texmatrixenabled = false;
3423 unit->matrix = identitymatrix;
3425 GL_ActiveTexture(unitnum);
3426 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3427 qglLoadIdentity();CHECKGLERROR
3428 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3432 case RENDERPATH_D3D9:
3433 case RENDERPATH_D3D10:
3434 case RENDERPATH_D3D11:
3436 case RENDERPATH_SOFT:
3441 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3443 gltextureunit_t *unit = gl_state.units + unitnum;
3445 switch(vid.renderpath)
3447 case RENDERPATH_GL20:
3448 case RENDERPATH_CGGL:
3451 case RENDERPATH_GL13:
3452 // GL_ARB_texture_env_combine
3454 combinergb = GL_MODULATE;
3456 combinealpha = GL_MODULATE;
3461 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3463 if (combinergb == GL_DECAL)
3464 combinergb = GL_INTERPOLATE_ARB;
3465 if (unit->combine != GL_COMBINE_ARB)
3467 unit->combine = GL_COMBINE_ARB;
3468 GL_ActiveTexture(unitnum);
3469 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3470 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3472 if (unit->combinergb != combinergb)
3474 unit->combinergb = combinergb;
3475 GL_ActiveTexture(unitnum);
3476 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3478 if (unit->combinealpha != combinealpha)
3480 unit->combinealpha = combinealpha;
3481 GL_ActiveTexture(unitnum);
3482 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3484 if (unit->rgbscale != rgbscale)
3486 unit->rgbscale = rgbscale;
3487 GL_ActiveTexture(unitnum);
3488 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3490 if (unit->alphascale != alphascale)
3492 unit->alphascale = alphascale;
3493 GL_ActiveTexture(unitnum);
3494 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3499 if (unit->combine != combinergb)
3501 unit->combine = combinergb;
3502 GL_ActiveTexture(unitnum);
3503 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3507 case RENDERPATH_GL11:
3510 combinergb = GL_MODULATE;
3511 if (unit->combine != combinergb)
3513 unit->combine = combinergb;
3514 GL_ActiveTexture(unitnum);
3515 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3518 case RENDERPATH_D3D9:
3519 case RENDERPATH_D3D10:
3520 case RENDERPATH_D3D11:
3522 case RENDERPATH_SOFT:
3527 void R_Mesh_ResetTextureState(void)
3529 unsigned int unitnum;
3534 switch(vid.renderpath)
3536 case RENDERPATH_GL20:
3537 case RENDERPATH_CGGL:
3538 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3540 gltextureunit_t *unit = gl_state.units + unitnum;
3544 GL_ActiveTexture(unitnum);
3545 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3550 GL_ActiveTexture(unitnum);
3551 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3556 GL_ActiveTexture(unitnum);
3557 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3560 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3562 gltextureunit_t *unit = gl_state.units + unitnum;
3563 if (unit->arrayenabled)
3565 unit->arrayenabled = false;
3566 GL_ClientActiveTexture(unitnum);
3567 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3570 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3572 gltextureunit_t *unit = gl_state.units + unitnum;
3573 if (unit->texmatrixenabled)
3575 unit->texmatrixenabled = false;
3576 unit->matrix = identitymatrix;
3578 GL_ActiveTexture(unitnum);
3579 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3580 qglLoadIdentity();CHECKGLERROR
3581 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3585 case RENDERPATH_GL13:
3586 case RENDERPATH_GL11:
3587 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3589 gltextureunit_t *unit = gl_state.units + unitnum;
3593 GL_ActiveTexture(unitnum);
3594 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3595 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3600 GL_ActiveTexture(unitnum);
3601 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3602 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3607 GL_ActiveTexture(unitnum);
3608 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3609 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3611 if (unit->arrayenabled)
3613 unit->arrayenabled = false;
3614 GL_ClientActiveTexture(unitnum);
3615 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3617 if (unit->texmatrixenabled)
3619 unit->texmatrixenabled = false;
3620 unit->matrix = identitymatrix;
3622 GL_ActiveTexture(unitnum);
3623 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3624 qglLoadIdentity();CHECKGLERROR
3625 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3627 if (unit->combine != GL_MODULATE)
3629 unit->combine = GL_MODULATE;
3630 GL_ActiveTexture(unitnum);
3631 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3635 case RENDERPATH_D3D9:
3636 case RENDERPATH_D3D10:
3637 case RENDERPATH_D3D11:
3639 case RENDERPATH_SOFT:
3647 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3648 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3649 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3651 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3653 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3657 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3659 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3660 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3661 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3665 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3667 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3668 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3669 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3670 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3671 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3672 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3673 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3677 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
3678 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3679 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3682 static void R_Mesh_InitVertexDeclarations(void)
3685 r_vertex3f_d3d9decl = NULL;
3686 r_vertexgeneric_d3d9decl = NULL;
3687 r_vertexmesh_d3d9decl = NULL;
3688 switch(vid.renderpath)
3690 case RENDERPATH_GL20:
3691 case RENDERPATH_CGGL:
3692 case RENDERPATH_GL13:
3693 case RENDERPATH_GL11:
3695 case RENDERPATH_D3D9:
3696 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
3697 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3698 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3700 case RENDERPATH_D3D10:
3701 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3703 case RENDERPATH_D3D11:
3704 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3706 case RENDERPATH_SOFT:
3712 static void R_Mesh_DestroyVertexDeclarations(void)
3715 if (r_vertex3f_d3d9decl)
3716 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
3717 r_vertex3f_d3d9decl = NULL;
3718 if (r_vertexgeneric_d3d9decl)
3719 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3720 r_vertexgeneric_d3d9decl = NULL;
3721 if (r_vertexmesh_d3d9decl)
3722 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3723 r_vertexmesh_d3d9decl = NULL;
3727 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
3729 // upload temporary vertexbuffer for this rendering
3730 if (!gl_state.usevbo_staticvertex)
3731 vertexbuffer = NULL;
3732 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3734 if (gl_state.preparevertices_dynamicvertexbuffer)
3735 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
3737 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
3738 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3740 switch(vid.renderpath)
3742 case RENDERPATH_GL20:
3743 case RENDERPATH_CGGL:
3746 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3747 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3748 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3749 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3750 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3751 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3752 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3756 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3757 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3758 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3759 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3760 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3761 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3762 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3765 case RENDERPATH_GL13:
3768 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3769 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3770 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3771 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3775 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3776 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3777 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3778 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3781 case RENDERPATH_GL11:
3784 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3785 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3786 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3790 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
3791 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3792 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3795 case RENDERPATH_D3D9:
3797 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
3799 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
3801 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3802 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3803 gl_state.d3dvertexdata = (void *)vertex3f;
3804 gl_state.d3dvertexsize = sizeof(float[3]);
3807 case RENDERPATH_D3D10:
3808 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3810 case RENDERPATH_D3D11:
3811 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3813 case RENDERPATH_SOFT:
3814 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
3815 DPSOFTRAST_SetColorPointer(NULL, 0);
3816 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
3817 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
3818 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
3819 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
3820 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
3827 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
3830 size = sizeof(r_vertexgeneric_t) * numvertices;
3831 if (gl_state.preparevertices_tempdatamaxsize < size)
3833 gl_state.preparevertices_tempdatamaxsize = size;
3834 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3836 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
3837 gl_state.preparevertices_numvertices = numvertices;
3838 return gl_state.preparevertices_vertexgeneric;
3841 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
3843 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
3844 gl_state.preparevertices_vertexgeneric = NULL;
3845 gl_state.preparevertices_numvertices = 0;
3849 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
3852 r_vertexgeneric_t *vertex;
3853 switch(vid.renderpath)
3855 case RENDERPATH_GL20:
3856 case RENDERPATH_CGGL:
3857 if (!vid.useinterleavedarrays)
3859 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3860 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3861 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3862 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3863 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3864 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3865 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3869 case RENDERPATH_GL13:
3870 case RENDERPATH_GL11:
3871 if (!vid.useinterleavedarrays)
3873 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3874 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3875 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3876 if (vid.texunits >= 2)
3877 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3878 if (vid.texunits >= 3)
3879 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3883 case RENDERPATH_D3D9:
3884 case RENDERPATH_D3D10:
3885 case RENDERPATH_D3D11:
3887 case RENDERPATH_SOFT:
3888 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
3889 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
3890 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
3891 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
3892 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
3893 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
3894 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
3898 // no quick path for this case, convert to vertex structs
3899 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
3900 for (i = 0;i < numvertices;i++)
3901 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3904 for (i = 0;i < numvertices;i++)
3905 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
3909 float tempcolor4f[4];
3910 unsigned char tempcolor4ub[4];
3911 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
3912 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
3913 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
3914 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
3915 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
3916 for (i = 0;i < numvertices;i++)
3917 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
3920 for (i = 0;i < numvertices;i++)
3921 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
3922 R_Mesh_PrepareVertices_Generic_Unlock();
3923 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
3926 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
3928 // upload temporary vertexbuffer for this rendering
3929 if (!gl_state.usevbo_staticvertex)
3930 vertexbuffer = NULL;
3931 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3933 if (gl_state.preparevertices_dynamicvertexbuffer)
3934 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3936 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3937 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3939 switch(vid.renderpath)
3941 case RENDERPATH_GL20:
3942 case RENDERPATH_CGGL:
3945 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3946 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3947 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3948 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3949 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3950 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3951 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3955 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3956 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3957 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3958 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3959 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3960 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3961 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3964 case RENDERPATH_GL13:
3967 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3968 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3969 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3970 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3974 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3975 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3976 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3977 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3980 case RENDERPATH_GL11:
3983 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3984 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3985 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3989 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3990 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3991 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3994 case RENDERPATH_D3D9:
3996 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
3998 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4000 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4001 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4002 gl_state.d3dvertexdata = (void *)vertex;
4003 gl_state.d3dvertexsize = sizeof(*vertex);
4006 case RENDERPATH_D3D10:
4007 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4009 case RENDERPATH_D3D11:
4010 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4012 case RENDERPATH_SOFT:
4013 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4014 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4015 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4016 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4017 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4018 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4019 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4026 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4029 size = sizeof(r_vertexmesh_t) * numvertices;
4030 if (gl_state.preparevertices_tempdatamaxsize < size)
4032 gl_state.preparevertices_tempdatamaxsize = size;
4033 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4035 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4036 gl_state.preparevertices_numvertices = numvertices;
4037 return gl_state.preparevertices_vertexmesh;
4040 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4042 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4043 gl_state.preparevertices_vertexmesh = NULL;
4044 gl_state.preparevertices_numvertices = 0;
4048 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)
4051 r_vertexmesh_t *vertex;
4052 switch(vid.renderpath)
4054 case RENDERPATH_GL20:
4055 case RENDERPATH_CGGL:
4056 if (!vid.useinterleavedarrays)
4058 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4059 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4060 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4061 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4062 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4063 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4064 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4068 case RENDERPATH_GL13:
4069 case RENDERPATH_GL11:
4070 if (!vid.useinterleavedarrays)
4072 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4073 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4074 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4075 if (vid.texunits >= 2)
4076 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4077 if (vid.texunits >= 3)
4078 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4082 case RENDERPATH_D3D9:
4083 case RENDERPATH_D3D10:
4084 case RENDERPATH_D3D11:
4086 case RENDERPATH_SOFT:
4087 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4088 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4089 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4090 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4091 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4092 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4093 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4097 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4098 for (i = 0;i < numvertices;i++)
4099 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4101 for (i = 0;i < numvertices;i++)
4102 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4104 for (i = 0;i < numvertices;i++)
4105 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4107 for (i = 0;i < numvertices;i++)
4108 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4111 for (i = 0;i < numvertices;i++)
4112 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4116 float tempcolor4f[4];
4117 unsigned char tempcolor4ub[4];
4118 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4119 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4120 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4121 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4122 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4123 for (i = 0;i < numvertices;i++)
4124 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4126 if (texcoordtexture2f)
4127 for (i = 0;i < numvertices;i++)
4128 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4129 if (texcoordlightmap2f)
4130 for (i = 0;i < numvertices;i++)
4131 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4132 R_Mesh_PrepareVertices_Mesh_Unlock();
4133 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4136 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4138 // upload temporary vertexbuffer for this rendering
4139 if (!gl_state.usevbo_staticvertex)
4140 vertexbuffer = NULL;
4141 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4143 if (gl_state.preparevertices_dynamicvertexbuffer)
4144 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4146 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4147 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4149 switch(vid.renderpath)
4151 case RENDERPATH_GL20:
4152 case RENDERPATH_CGGL:
4155 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4156 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4157 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4158 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4159 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4160 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4161 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4165 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4166 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4167 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4168 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4169 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4170 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4171 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4174 case RENDERPATH_GL13:
4177 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4178 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4179 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4180 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4184 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4185 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4186 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4187 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4190 case RENDERPATH_GL11:
4193 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4194 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4195 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4199 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4200 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4201 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4204 case RENDERPATH_D3D9:
4206 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4208 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4210 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4211 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4212 gl_state.d3dvertexdata = (void *)vertex;
4213 gl_state.d3dvertexsize = sizeof(*vertex);
4216 case RENDERPATH_D3D10:
4217 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4219 case RENDERPATH_D3D11:
4220 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4222 case RENDERPATH_SOFT:
4223 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4224 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4225 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4226 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4227 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4228 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4229 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);