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;
140 qboolean alphatocoverage;
143 unsigned int clientunit;
144 gltextureunit_t units[MAX_TEXTUREUNITS];
148 int vertexbufferobject;
149 int elementbufferobject;
150 int framebufferobject;
151 int defaultframebufferobject; // deal with platforms that use a non-zero default fbo
152 qboolean pointer_color_enabled;
154 int pointer_vertex_components;
155 int pointer_vertex_gltype;
156 size_t pointer_vertex_stride;
157 const void *pointer_vertex_pointer;
158 const r_meshbuffer_t *pointer_vertex_vertexbuffer;
159 size_t pointer_vertex_offset;
161 int pointer_color_components;
162 int pointer_color_gltype;
163 size_t pointer_color_stride;
164 const void *pointer_color_pointer;
165 const r_meshbuffer_t *pointer_color_vertexbuffer;
166 size_t pointer_color_offset;
168 void *preparevertices_tempdata;
169 size_t preparevertices_tempdatamaxsize;
170 r_meshbuffer_t *preparevertices_dynamicvertexbuffer;
171 r_vertexgeneric_t *preparevertices_vertexgeneric;
172 r_vertexmesh_t *preparevertices_vertexmesh;
173 int preparevertices_numvertices;
175 r_meshbuffer_t *draw_dynamicindexbuffer;
177 qboolean usevbo_staticvertex;
178 qboolean usevbo_staticindex;
179 qboolean usevbo_dynamicvertex;
180 qboolean usevbo_dynamicindex;
182 memexpandablearray_t meshbufferarray;
187 // rtexture_t *d3drt_depthtexture;
188 // rtexture_t *d3drt_colortextures[MAX_RENDERTARGETS];
189 IDirect3DSurface9 *d3drt_depthsurface;
190 IDirect3DSurface9 *d3drt_colorsurfaces[MAX_RENDERTARGETS];
191 IDirect3DSurface9 *d3drt_backbufferdepthsurface;
192 IDirect3DSurface9 *d3drt_backbuffercolorsurface;
193 void *d3dvertexbuffer;
195 size_t d3dvertexsize;
200 static gl_state_t gl_state;
204 note: here's strip order for a terrain row:
211 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
213 *elements++ = i + row;
215 *elements++ = i + row + 1;
218 *elements++ = i + row + 1;
221 for (y = 0;y < rows - 1;y++)
223 for (x = 0;x < columns - 1;x++)
226 *elements++ = i + columns;
228 *elements++ = i + columns + 1;
231 *elements++ = i + columns + 1;
242 for (y = 0;y < rows - 1;y++)
244 for (x = 0;x < columns - 1;x++)
248 *elements++ = i + columns;
249 *elements++ = i + columns + 1;
250 *elements++ = i + columns;
251 *elements++ = i + columns + 1;
257 int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
258 unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
259 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
260 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
262 void GL_VBOStats_f(void)
264 GL_Mesh_ListVBOs(true);
267 static void GL_Backend_ResetState(void);
269 static void R_Mesh_InitVertexDeclarations(void);
270 static void R_Mesh_DestroyVertexDeclarations(void);
272 static void R_Mesh_SetUseVBO(void)
274 switch(vid.renderpath)
276 case RENDERPATH_GL11:
277 case RENDERPATH_GL13:
278 case RENDERPATH_GL20:
279 case RENDERPATH_GLES1:
280 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
281 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
282 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
283 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
285 case RENDERPATH_D3D9:
286 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
287 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
289 case RENDERPATH_D3D10:
290 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
292 case RENDERPATH_D3D11:
293 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
295 case RENDERPATH_SOFT:
296 gl_state.usevbo_staticvertex = false;
297 gl_state.usevbo_staticindex = false;
298 gl_state.usevbo_dynamicvertex = false;
299 gl_state.usevbo_dynamicindex = false;
301 case RENDERPATH_GLES2:
302 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
303 gl_state.usevbo_staticindex = false;
304 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
305 gl_state.usevbo_dynamicindex = false;
310 static void gl_backend_start(void)
312 memset(&gl_state, 0, sizeof(gl_state));
314 R_Mesh_InitVertexDeclarations();
317 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
319 Con_DPrintf("OpenGL backend started.\n");
323 GL_Backend_ResetState();
325 switch(vid.renderpath)
327 case RENDERPATH_GL11:
328 case RENDERPATH_GL13:
329 case RENDERPATH_GL20:
330 case RENDERPATH_GLES1:
331 case RENDERPATH_GLES2:
332 // fetch current fbo here (default fbo is not 0 on some GLES devices)
333 if (vid.support.ext_framebuffer_object)
334 qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &gl_state.defaultframebufferobject);
336 case RENDERPATH_D3D9:
338 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
339 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
342 case RENDERPATH_D3D10:
343 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
345 case RENDERPATH_D3D11:
346 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
348 case RENDERPATH_SOFT:
353 static void gl_backend_shutdown(void)
355 Con_DPrint("OpenGL Backend shutting down\n");
357 switch(vid.renderpath)
359 case RENDERPATH_GL11:
360 case RENDERPATH_GL13:
361 case RENDERPATH_GL20:
362 case RENDERPATH_SOFT:
363 case RENDERPATH_GLES1:
364 case RENDERPATH_GLES2:
366 case RENDERPATH_D3D9:
368 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
369 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
372 case RENDERPATH_D3D10:
373 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
375 case RENDERPATH_D3D11:
376 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
380 if (gl_state.preparevertices_tempdata)
381 Mem_Free(gl_state.preparevertices_tempdata);
382 if (gl_state.preparevertices_dynamicvertexbuffer)
383 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
385 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
387 R_Mesh_DestroyVertexDeclarations();
389 memset(&gl_state, 0, sizeof(gl_state));
392 static void gl_backend_newmap(void)
396 static void gl_backend_devicelost(void)
399 r_meshbuffer_t *buffer;
401 gl_state.d3dvertexbuffer = NULL;
403 switch(vid.renderpath)
405 case RENDERPATH_GL11:
406 case RENDERPATH_GL13:
407 case RENDERPATH_GL20:
408 case RENDERPATH_SOFT:
409 case RENDERPATH_GLES1:
410 case RENDERPATH_GLES2:
412 case RENDERPATH_D3D9:
414 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
415 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
418 case RENDERPATH_D3D10:
419 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
421 case RENDERPATH_D3D11:
422 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
425 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
426 for (i = 0;i < endindex;i++)
428 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
429 if (!buffer || !buffer->isdynamic)
431 switch(vid.renderpath)
433 case RENDERPATH_GL11:
434 case RENDERPATH_GL13:
435 case RENDERPATH_GL20:
436 case RENDERPATH_SOFT:
437 case RENDERPATH_GLES1:
438 case RENDERPATH_GLES2:
440 case RENDERPATH_D3D9:
442 if (buffer->devicebuffer)
444 if (buffer->isindexbuffer)
445 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
447 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
448 buffer->devicebuffer = NULL;
452 case RENDERPATH_D3D10:
453 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
455 case RENDERPATH_D3D11:
456 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
462 static void gl_backend_devicerestored(void)
464 switch(vid.renderpath)
466 case RENDERPATH_GL11:
467 case RENDERPATH_GL13:
468 case RENDERPATH_GL20:
469 case RENDERPATH_SOFT:
470 case RENDERPATH_GLES1:
471 case RENDERPATH_GLES2:
473 case RENDERPATH_D3D9:
475 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
476 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
479 case RENDERPATH_D3D10:
480 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
482 case RENDERPATH_D3D11:
483 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
488 void gl_backend_init(void)
492 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
494 polygonelement3s[i * 3 + 0] = 0;
495 polygonelement3s[i * 3 + 1] = i + 1;
496 polygonelement3s[i * 3 + 2] = i + 2;
498 // elements for rendering a series of quads as triangles
499 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
501 quadelement3s[i * 6 + 0] = i * 4;
502 quadelement3s[i * 6 + 1] = i * 4 + 1;
503 quadelement3s[i * 6 + 2] = i * 4 + 2;
504 quadelement3s[i * 6 + 3] = i * 4;
505 quadelement3s[i * 6 + 4] = i * 4 + 2;
506 quadelement3s[i * 6 + 5] = i * 4 + 3;
509 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
510 polygonelement3i[i] = polygonelement3s[i];
511 for (i = 0;i < QUADELEMENTS_MAXQUADS*6;i++)
512 quadelement3i[i] = quadelement3s[i];
514 Cvar_RegisterVariable(&r_render);
515 Cvar_RegisterVariable(&r_renderview);
516 Cvar_RegisterVariable(&r_waterwarp);
517 Cvar_RegisterVariable(&gl_polyblend);
518 Cvar_RegisterVariable(&v_flipped);
519 Cvar_RegisterVariable(&gl_dither);
520 Cvar_RegisterVariable(&gl_vbo);
521 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
522 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
523 Cvar_RegisterVariable(&gl_paranoid);
524 Cvar_RegisterVariable(&gl_printcheckerror);
526 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
527 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
528 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
530 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");
532 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
535 void GL_SetMirrorState(qboolean state);
537 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
541 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
542 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
544 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
546 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
547 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
548 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
550 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
555 switch(vid.renderpath)
557 case RENDERPATH_GL11:
558 case RENDERPATH_GL13:
559 case RENDERPATH_GL20:
560 case RENDERPATH_GLES1:
561 case RENDERPATH_GLES2:
564 case RENDERPATH_D3D9:
565 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
567 case RENDERPATH_D3D10:
568 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
570 case RENDERPATH_D3D11:
571 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
573 case RENDERPATH_SOFT:
579 static int bboxedges[12][2] =
598 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
600 int i, ix1, iy1, ix2, iy2;
601 float x1, y1, x2, y2;
612 scissor[0] = r_refdef.view.viewport.x;
613 scissor[1] = r_refdef.view.viewport.y;
614 scissor[2] = r_refdef.view.viewport.width;
615 scissor[3] = r_refdef.view.viewport.height;
617 // if view is inside the box, just say yes it's visible
618 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
621 x1 = y1 = x2 = y2 = 0;
623 // transform all corners that are infront of the nearclip plane
624 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
625 plane4f[3] = r_refdef.view.frustum[4].dist;
627 for (i = 0;i < 8;i++)
629 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
630 dist[i] = DotProduct4(corner[i], plane4f);
631 sign[i] = dist[i] > 0;
634 VectorCopy(corner[i], vertex[numvertices]);
638 // if some points are behind the nearclip, add clipped edge points to make
639 // sure that the scissor boundary is complete
640 if (numvertices > 0 && numvertices < 8)
642 // add clipped edge points
643 for (i = 0;i < 12;i++)
647 if (sign[j] != sign[k])
649 f = dist[j] / (dist[j] - dist[k]);
650 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
656 // if we have no points to check, it is behind the view plane
660 // if we have some points to transform, check what screen area is covered
661 x1 = y1 = x2 = y2 = 0;
663 //Con_Printf("%i vertices to transform...\n", numvertices);
664 for (i = 0;i < numvertices;i++)
666 VectorCopy(vertex[i], v);
667 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
668 //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]);
671 if (x1 > v2[0]) x1 = v2[0];
672 if (x2 < v2[0]) x2 = v2[0];
673 if (y1 > v2[1]) y1 = v2[1];
674 if (y2 < v2[1]) y2 = v2[1];
683 // now convert the scissor rectangle to integer screen coordinates
684 ix1 = (int)(x1 - 1.0f);
685 //iy1 = vid.height - (int)(y2 - 1.0f);
686 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
687 iy1 = (int)(y1 - 1.0f);
688 ix2 = (int)(x2 + 1.0f);
689 //iy2 = vid.height - (int)(y1 + 1.0f);
690 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
691 iy2 = (int)(y2 + 1.0f);
692 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
694 // clamp it to the screen
695 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
696 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
697 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
698 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
700 // if it is inside out, it's not visible
701 if (ix2 <= ix1 || iy2 <= iy1)
704 // the light area is visible, set up the scissor rectangle
707 scissor[2] = ix2 - ix1;
708 scissor[3] = iy2 - iy1;
710 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
711 switch(vid.renderpath)
713 case RENDERPATH_D3D9:
714 case RENDERPATH_D3D10:
715 case RENDERPATH_D3D11:
716 scissor[1] = vid.height - scissor[1] - scissor[3];
718 case RENDERPATH_GL11:
719 case RENDERPATH_GL13:
720 case RENDERPATH_GL20:
721 case RENDERPATH_SOFT:
722 case RENDERPATH_GLES1:
723 case RENDERPATH_GLES2:
731 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
735 float clipPlane[4], v3[3], v4[3];
738 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
740 VectorSet(normal, normalx, normaly, normalz);
741 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
742 VectorScale(normal, -dist, v3);
743 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
744 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
745 clipPlane[3] = -DotProduct(v4, clipPlane);
749 // testing code for comparing results
751 VectorCopy4(clipPlane, clipPlane2);
752 R_EntityMatrix(&identitymatrix);
753 VectorSet(q, normal[0], normal[1], normal[2], -dist);
754 qglClipPlane(GL_CLIP_PLANE0, q);
755 qglGetClipPlane(GL_CLIP_PLANE0, q);
756 VectorCopy4(q, clipPlane);
760 // Calculate the clip-space corner point opposite the clipping plane
761 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
762 // transform it into camera space by multiplying it
763 // by the inverse of the projection matrix
764 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
765 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
767 q[3] = (1.0f + m[10]) / m[14];
769 // Calculate the scaled plane vector
770 d = 2.0f / DotProduct4(clipPlane, q);
772 // Replace the third row of the projection matrix
773 m[2] = clipPlane[0] * d;
774 m[6] = clipPlane[1] * d;
775 m[10] = clipPlane[2] * d + 1.0f;
776 m[14] = clipPlane[3] * d;
779 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)
781 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
783 memset(v, 0, sizeof(*v));
784 v->type = R_VIEWPORTTYPE_ORTHO;
785 v->cameramatrix = *cameramatrix;
792 memset(m, 0, sizeof(m));
793 m[0] = 2/(right - left);
794 m[5] = 2/(top - bottom);
795 m[10] = -2/(zFar - zNear);
796 m[12] = - (right + left)/(right - left);
797 m[13] = - (top + bottom)/(top - bottom);
798 m[14] = - (zFar + zNear)/(zFar - zNear);
800 switch(vid.renderpath)
802 case RENDERPATH_GL11:
803 case RENDERPATH_GL13:
804 case RENDERPATH_GL20:
805 case RENDERPATH_SOFT:
806 case RENDERPATH_GLES1:
807 case RENDERPATH_GLES2:
809 case RENDERPATH_D3D9:
810 case RENDERPATH_D3D10:
811 case RENDERPATH_D3D11:
812 m[10] = -1/(zFar - zNear);
813 m[14] = -zNear/(zFar-zNear);
816 v->screentodepth[0] = -farclip / (farclip - nearclip);
817 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
819 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
822 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
824 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
830 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
831 R_Viewport_TransformToScreen(v, test1, test2);
832 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
837 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)
839 matrix4x4_t tempmatrix, basematrix;
841 memset(v, 0, sizeof(*v));
843 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
844 v->cameramatrix = *cameramatrix;
851 memset(m, 0, sizeof(m));
852 m[0] = 1.0 / frustumx;
853 m[5] = 1.0 / frustumy;
854 m[10] = -(farclip + nearclip) / (farclip - nearclip);
856 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
857 v->screentodepth[0] = -farclip / (farclip - nearclip);
858 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
860 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
861 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
862 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
863 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
866 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
868 if(v_flipped.integer)
876 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
879 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)
881 matrix4x4_t tempmatrix, basematrix;
882 const float nudge = 1.0 - 1.0 / (1<<23);
884 memset(v, 0, sizeof(*v));
886 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
887 v->cameramatrix = *cameramatrix;
894 memset(m, 0, sizeof(m));
895 m[ 0] = 1.0 / frustumx;
896 m[ 5] = 1.0 / frustumy;
899 m[14] = -2 * nearclip * nudge;
900 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
901 v->screentodepth[1] = m[14] * -0.5;
903 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
904 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
905 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
906 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
909 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
911 if(v_flipped.integer)
919 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
922 float cubeviewmatrix[6][16] =
924 // standard cubemap projections
962 float rectviewmatrix[6][16] =
964 // sign-preserving cubemap projections
1003 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
1005 matrix4x4_t tempmatrix, basematrix;
1007 memset(v, 0, sizeof(*v));
1008 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1009 v->cameramatrix = *cameramatrix;
1013 memset(m, 0, sizeof(m));
1015 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1017 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1019 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
1020 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1021 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1024 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1026 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1029 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)
1031 matrix4x4_t tempmatrix, basematrix;
1033 memset(v, 0, sizeof(*v));
1034 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1035 v->cameramatrix = *cameramatrix;
1036 v->x = (side & 1) * size;
1037 v->y = (side >> 1) * size;
1041 memset(m, 0, sizeof(m));
1042 m[0] = m[5] = 1.0f * ((float)size - border) / size;
1043 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1045 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1047 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
1048 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1049 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1051 switch(vid.renderpath)
1053 case RENDERPATH_GL20:
1054 case RENDERPATH_GL13:
1055 case RENDERPATH_GL11:
1056 case RENDERPATH_SOFT:
1057 case RENDERPATH_GLES1:
1058 case RENDERPATH_GLES2:
1060 case RENDERPATH_D3D9:
1063 case RENDERPATH_D3D10:
1064 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1066 case RENDERPATH_D3D11:
1067 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1072 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1074 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1077 void R_SetViewport(const r_viewport_t *v)
1082 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1083 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1085 // copy over the matrices to our state
1086 gl_viewmatrix = v->viewmatrix;
1087 gl_projectionmatrix = v->projectmatrix;
1089 switch(vid.renderpath)
1091 case RENDERPATH_GL13:
1092 case RENDERPATH_GL11:
1093 case RENDERPATH_GLES1:
1095 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1096 // Load the projection matrix into OpenGL
1097 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1098 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1099 qglLoadMatrixf(m);CHECKGLERROR
1100 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1102 case RENDERPATH_D3D9:
1105 D3DVIEWPORT9 d3dviewport;
1106 d3dviewport.X = gl_viewport.x;
1107 d3dviewport.Y = gl_viewport.y;
1108 d3dviewport.Width = gl_viewport.width;
1109 d3dviewport.Height = gl_viewport.height;
1110 d3dviewport.MinZ = gl_state.depthrange[0];
1111 d3dviewport.MaxZ = gl_state.depthrange[1];
1112 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1116 case RENDERPATH_D3D10:
1117 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1119 case RENDERPATH_D3D11:
1120 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1122 case RENDERPATH_SOFT:
1123 DPSOFTRAST_Viewport(v->x, v->y, v->width, v->height);
1125 case RENDERPATH_GL20:
1126 case RENDERPATH_GLES2:
1128 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1132 // force an update of the derived matrices
1133 gl_modelmatrixchanged = true;
1134 R_EntityMatrix(&gl_modelmatrix);
1137 void R_GetViewport(r_viewport_t *v)
1142 static void GL_BindVBO(int bufferobject)
1144 if (gl_state.vertexbufferobject != bufferobject)
1146 gl_state.vertexbufferobject = bufferobject;
1148 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1152 static void GL_BindEBO(int bufferobject)
1154 if (gl_state.elementbufferobject != bufferobject)
1156 gl_state.elementbufferobject = bufferobject;
1158 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1162 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1165 switch(vid.renderpath)
1167 case RENDERPATH_GL11:
1168 case RENDERPATH_GL13:
1169 case RENDERPATH_GL20:
1170 case RENDERPATH_GLES1:
1171 case RENDERPATH_GLES2:
1172 if (!vid.support.ext_framebuffer_object)
1174 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1175 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1176 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1177 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1178 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1179 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1180 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1182 case RENDERPATH_D3D9:
1183 case RENDERPATH_D3D10:
1184 case RENDERPATH_D3D11:
1186 case RENDERPATH_SOFT:
1192 void R_Mesh_DestroyFramebufferObject(int fbo)
1194 switch(vid.renderpath)
1196 case RENDERPATH_GL11:
1197 case RENDERPATH_GL13:
1198 case RENDERPATH_GL20:
1199 case RENDERPATH_GLES1:
1200 case RENDERPATH_GLES2:
1202 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1204 case RENDERPATH_D3D9:
1205 case RENDERPATH_D3D10:
1206 case RENDERPATH_D3D11:
1208 case RENDERPATH_SOFT:
1214 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1216 // 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)
1217 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)
1220 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1221 if (gl_state.d3drt_depthsurface != depthsurface)
1223 gl_state.d3drt_depthsurface = depthsurface;
1224 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1226 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1228 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1229 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1231 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1233 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1234 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1236 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1238 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1239 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1241 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1243 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1244 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1249 void R_Mesh_ResetRenderTargets(void)
1251 switch(vid.renderpath)
1253 case RENDERPATH_GL11:
1254 case RENDERPATH_GL13:
1255 case RENDERPATH_GL20:
1256 case RENDERPATH_GLES1:
1257 case RENDERPATH_GLES2:
1258 if (gl_state.framebufferobject)
1260 gl_state.framebufferobject = 0;
1261 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1264 case RENDERPATH_D3D9:
1266 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1269 case RENDERPATH_D3D10:
1270 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1272 case RENDERPATH_D3D11:
1273 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1275 case RENDERPATH_SOFT:
1276 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1281 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1285 rtexture_t *textures[5];
1286 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1287 textures[4] = depthtexture;
1288 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1289 for (j = 0;j < 5;j++)
1291 for (i = 0;i < vid.teximageunits;i++)
1292 if (gl_state.units[i].texture == textures[j])
1293 R_Mesh_TexBind(i, NULL);
1294 // set up framebuffer object or render targets for the active rendering API
1295 switch(vid.renderpath)
1297 case RENDERPATH_GL11:
1298 case RENDERPATH_GL13:
1299 case RENDERPATH_GL20:
1300 case RENDERPATH_GLES1:
1301 case RENDERPATH_GLES2:
1302 if (gl_state.framebufferobject != fbo)
1304 gl_state.framebufferobject = fbo;
1305 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1308 case RENDERPATH_D3D9:
1310 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1311 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1314 IDirect3DSurface9 *colorsurfaces[4];
1315 for (i = 0;i < 4;i++)
1317 colorsurfaces[i] = NULL;
1319 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1321 // set the render targets for real
1322 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1323 // release the texture surface levels (they won't be lost while bound...)
1324 for (i = 0;i < 4;i++)
1326 IDirect3DSurface9_Release(colorsurfaces[i]);
1329 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1332 case RENDERPATH_D3D10:
1333 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1335 case RENDERPATH_D3D11:
1336 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1338 case RENDERPATH_SOFT:
1342 unsigned int *pointers[5];
1343 memset(pointers, 0, sizeof(pointers));
1344 for (i = 0;i < 5;i++)
1345 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1346 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1347 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1348 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1351 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1357 static int d3dcmpforglfunc(int f)
1361 case GL_NEVER: return D3DCMP_NEVER;
1362 case GL_LESS: return D3DCMP_LESS;
1363 case GL_EQUAL: return D3DCMP_EQUAL;
1364 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1365 case GL_GREATER: return D3DCMP_GREATER;
1366 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1367 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1368 case GL_ALWAYS: return D3DCMP_ALWAYS;
1369 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1373 static int d3dstencilopforglfunc(int f)
1377 case GL_KEEP: return D3DSTENCILOP_KEEP;
1378 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1379 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1380 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1385 extern cvar_t r_transparent_alphatocoverage;
1387 static void GL_Backend_ResetState(void)
1390 gl_state.active = true;
1391 gl_state.depthtest = true;
1392 gl_state.alphatest = false;
1393 gl_state.alphafunc = GL_GEQUAL;
1394 gl_state.alphafuncvalue = 0.5f;
1395 gl_state.alphatocoverage = false;
1396 gl_state.blendfunc1 = GL_ONE;
1397 gl_state.blendfunc2 = GL_ZERO;
1398 gl_state.blend = false;
1399 gl_state.depthmask = GL_TRUE;
1400 gl_state.colormask = 15;
1401 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1402 gl_state.lockrange_first = 0;
1403 gl_state.lockrange_count = 0;
1404 gl_state.cullface = GL_FRONT;
1405 gl_state.cullfaceenable = false;
1406 gl_state.polygonoffset[0] = 0;
1407 gl_state.polygonoffset[1] = 0;
1408 gl_state.framebufferobject = 0;
1409 gl_state.depthfunc = GL_LEQUAL;
1411 switch(vid.renderpath)
1413 case RENDERPATH_D3D9:
1416 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1417 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1418 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1419 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1420 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1421 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1422 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1426 case RENDERPATH_D3D10:
1427 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1429 case RENDERPATH_D3D11:
1430 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1432 case RENDERPATH_GL11:
1433 case RENDERPATH_GL13:
1434 case RENDERPATH_GLES1:
1437 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1438 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1439 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1440 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1441 qglDisable(GL_BLEND);CHECKGLERROR
1442 qglCullFace(gl_state.cullface);CHECKGLERROR
1443 qglDisable(GL_CULL_FACE);CHECKGLERROR
1444 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1445 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1446 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1447 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1449 if (vid.support.arb_vertex_buffer_object)
1451 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1452 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1455 if (vid.support.ext_framebuffer_object)
1457 //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1458 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1461 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1462 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1464 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1465 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1466 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1468 if (vid.support.ext_framebuffer_object)
1469 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1471 gl_state.unit = MAX_TEXTUREUNITS;
1472 gl_state.clientunit = MAX_TEXTUREUNITS;
1473 for (i = 0;i < vid.texunits;i++)
1475 GL_ActiveTexture(i);
1476 GL_ClientActiveTexture(i);
1477 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1478 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1479 if (vid.support.ext_texture_3d)
1481 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1482 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1484 if (vid.support.arb_texture_cube_map)
1486 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1487 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1490 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1491 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1492 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1493 qglLoadIdentity();CHECKGLERROR
1494 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1495 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1499 case RENDERPATH_SOFT:
1500 DPSOFTRAST_ColorMask(1,1,1,1);
1501 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1502 DPSOFTRAST_CullFace(gl_state.cullface);
1503 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1504 DPSOFTRAST_DepthMask(gl_state.depthmask);
1505 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1506 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1507 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1509 case RENDERPATH_GL20:
1510 case RENDERPATH_GLES2:
1512 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1513 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1514 qglDisable(GL_BLEND);CHECKGLERROR
1515 qglCullFace(gl_state.cullface);CHECKGLERROR
1516 qglDisable(GL_CULL_FACE);CHECKGLERROR
1517 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1518 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1519 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1520 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1521 if (vid.support.arb_vertex_buffer_object)
1523 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1524 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1526 if (vid.support.ext_framebuffer_object)
1527 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1528 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1529 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1530 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1531 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1532 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1533 gl_state.unit = MAX_TEXTUREUNITS;
1534 gl_state.clientunit = MAX_TEXTUREUNITS;
1535 for (i = 0;i < vid.teximageunits;i++)
1537 GL_ActiveTexture(i);
1538 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1539 if (vid.support.ext_texture_3d)
1541 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1543 if (vid.support.arb_texture_cube_map)
1545 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1548 for (i = 0;i < vid.texarrayunits;i++)
1551 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1552 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1559 void GL_ActiveTexture(unsigned int num)
1561 if (gl_state.unit != num)
1563 gl_state.unit = num;
1564 switch(vid.renderpath)
1566 case RENDERPATH_GL11:
1567 case RENDERPATH_GL13:
1568 case RENDERPATH_GL20:
1569 case RENDERPATH_GLES1:
1570 case RENDERPATH_GLES2:
1571 if (qglActiveTexture)
1574 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1578 case RENDERPATH_D3D9:
1579 case RENDERPATH_D3D10:
1580 case RENDERPATH_D3D11:
1582 case RENDERPATH_SOFT:
1588 void GL_ClientActiveTexture(unsigned int num)
1590 if (gl_state.clientunit != num)
1592 gl_state.clientunit = num;
1593 switch(vid.renderpath)
1595 case RENDERPATH_GL11:
1596 case RENDERPATH_GL13:
1597 case RENDERPATH_GLES1:
1598 if (qglActiveTexture)
1601 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1605 case RENDERPATH_D3D9:
1606 case RENDERPATH_D3D10:
1607 case RENDERPATH_D3D11:
1609 case RENDERPATH_SOFT:
1611 case RENDERPATH_GL20:
1612 case RENDERPATH_GLES2:
1618 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1620 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1622 qboolean blendenable;
1623 gl_state.blendfunc1 = blendfunc1;
1624 gl_state.blendfunc2 = blendfunc2;
1625 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1626 switch(vid.renderpath)
1628 case RENDERPATH_GL11:
1629 case RENDERPATH_GL13:
1630 case RENDERPATH_GL20:
1631 case RENDERPATH_GLES1:
1632 case RENDERPATH_GLES2:
1634 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1635 if (gl_state.blend != blendenable)
1637 gl_state.blend = blendenable;
1638 if (!gl_state.blend)
1640 qglDisable(GL_BLEND);CHECKGLERROR
1644 qglEnable(GL_BLEND);CHECKGLERROR
1648 case RENDERPATH_D3D9:
1653 D3DBLEND d3dblendfunc[2];
1654 glblendfunc[0] = gl_state.blendfunc1;
1655 glblendfunc[1] = gl_state.blendfunc2;
1656 for (i = 0;i < 2;i++)
1658 switch(glblendfunc[i])
1660 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1661 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1662 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1663 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1664 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1665 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1666 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1667 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1668 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1669 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1672 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1673 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1674 if (gl_state.blend != blendenable)
1676 gl_state.blend = blendenable;
1677 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1682 case RENDERPATH_D3D10:
1683 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1685 case RENDERPATH_D3D11:
1686 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1688 case RENDERPATH_SOFT:
1689 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1695 void GL_DepthMask(int state)
1697 if (gl_state.depthmask != state)
1699 gl_state.depthmask = state;
1700 switch(vid.renderpath)
1702 case RENDERPATH_GL11:
1703 case RENDERPATH_GL13:
1704 case RENDERPATH_GL20:
1705 case RENDERPATH_GLES1:
1706 case RENDERPATH_GLES2:
1708 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1710 case RENDERPATH_D3D9:
1712 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1715 case RENDERPATH_D3D10:
1716 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1718 case RENDERPATH_D3D11:
1719 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1721 case RENDERPATH_SOFT:
1722 DPSOFTRAST_DepthMask(gl_state.depthmask);
1728 void GL_DepthTest(int state)
1730 if (gl_state.depthtest != state)
1732 gl_state.depthtest = state;
1733 switch(vid.renderpath)
1735 case RENDERPATH_GL11:
1736 case RENDERPATH_GL13:
1737 case RENDERPATH_GL20:
1738 case RENDERPATH_GLES1:
1739 case RENDERPATH_GLES2:
1741 if (gl_state.depthtest)
1743 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1747 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1750 case RENDERPATH_D3D9:
1752 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1755 case RENDERPATH_D3D10:
1756 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1758 case RENDERPATH_D3D11:
1759 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1761 case RENDERPATH_SOFT:
1762 DPSOFTRAST_DepthTest(gl_state.depthtest);
1768 void GL_DepthFunc(int state)
1770 if (gl_state.depthfunc != state)
1772 gl_state.depthfunc = state;
1773 switch(vid.renderpath)
1775 case RENDERPATH_GL11:
1776 case RENDERPATH_GL13:
1777 case RENDERPATH_GL20:
1778 case RENDERPATH_GLES1:
1779 case RENDERPATH_GLES2:
1781 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1783 case RENDERPATH_D3D9:
1785 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1788 case RENDERPATH_D3D10:
1789 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1791 case RENDERPATH_D3D11:
1792 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1794 case RENDERPATH_SOFT:
1795 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1801 void GL_DepthRange(float nearfrac, float farfrac)
1803 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1805 gl_state.depthrange[0] = nearfrac;
1806 gl_state.depthrange[1] = farfrac;
1807 switch(vid.renderpath)
1809 case RENDERPATH_GL11:
1810 case RENDERPATH_GL13:
1811 case RENDERPATH_GL20:
1812 case RENDERPATH_GLES1:
1813 case RENDERPATH_GLES2:
1814 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1816 case RENDERPATH_D3D9:
1819 D3DVIEWPORT9 d3dviewport;
1820 d3dviewport.X = gl_viewport.x;
1821 d3dviewport.Y = gl_viewport.y;
1822 d3dviewport.Width = gl_viewport.width;
1823 d3dviewport.Height = gl_viewport.height;
1824 d3dviewport.MinZ = gl_state.depthrange[0];
1825 d3dviewport.MaxZ = gl_state.depthrange[1];
1826 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1830 case RENDERPATH_D3D10:
1831 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1833 case RENDERPATH_D3D11:
1834 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1836 case RENDERPATH_SOFT:
1837 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1843 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)
1845 switch (vid.renderpath)
1847 case RENDERPATH_GL11:
1848 case RENDERPATH_GL13:
1849 case RENDERPATH_GL20:
1850 case RENDERPATH_GLES1:
1851 case RENDERPATH_GLES2:
1855 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1859 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1861 if (vid.support.ati_separate_stencil)
1863 qglStencilMask(writemask);CHECKGLERROR
1864 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1865 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1866 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1868 else if (vid.support.ext_stencil_two_side)
1870 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1871 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1872 qglStencilMask(writemask);CHECKGLERROR
1873 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1874 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1875 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1876 qglStencilMask(writemask);CHECKGLERROR
1877 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1878 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1881 case RENDERPATH_D3D9:
1883 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1884 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1885 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1886 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1887 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1888 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1889 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1890 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1891 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1892 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1893 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1894 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1895 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1898 case RENDERPATH_D3D10:
1899 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1901 case RENDERPATH_D3D11:
1902 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1904 case RENDERPATH_SOFT:
1905 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1910 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1912 switch (vid.renderpath)
1914 case RENDERPATH_GL11:
1915 case RENDERPATH_GL13:
1916 case RENDERPATH_GL20:
1917 case RENDERPATH_GLES1:
1918 case RENDERPATH_GLES2:
1922 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1926 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1928 if (vid.support.ext_stencil_two_side)
1930 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1932 qglStencilMask(writemask);CHECKGLERROR
1933 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1934 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1937 case RENDERPATH_D3D9:
1939 if (vid.support.ati_separate_stencil)
1940 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1941 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1942 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1943 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1944 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1945 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1946 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1947 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1948 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1951 case RENDERPATH_D3D10:
1952 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1954 case RENDERPATH_D3D11:
1955 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1957 case RENDERPATH_SOFT:
1958 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1963 void GL_PolygonOffset(float planeoffset, float depthoffset)
1965 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
1967 gl_state.polygonoffset[0] = planeoffset;
1968 gl_state.polygonoffset[1] = depthoffset;
1969 switch(vid.renderpath)
1971 case RENDERPATH_GL11:
1972 case RENDERPATH_GL13:
1973 case RENDERPATH_GL20:
1974 case RENDERPATH_GLES1:
1975 case RENDERPATH_GLES2:
1976 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1978 case RENDERPATH_D3D9:
1980 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1981 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1984 case RENDERPATH_D3D10:
1985 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1987 case RENDERPATH_D3D11:
1988 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1990 case RENDERPATH_SOFT:
1991 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1997 void GL_SetMirrorState(qboolean state)
1999 if (v_flipped_state != state)
2001 v_flipped_state = state;
2002 if (gl_state.cullface == GL_BACK)
2003 gl_state.cullface = GL_FRONT;
2004 else if (gl_state.cullface == GL_FRONT)
2005 gl_state.cullface = GL_BACK;
2008 switch(vid.renderpath)
2010 case RENDERPATH_GL11:
2011 case RENDERPATH_GL13:
2012 case RENDERPATH_GL20:
2013 case RENDERPATH_GLES1:
2014 case RENDERPATH_GLES2:
2015 qglCullFace(gl_state.cullface);CHECKGLERROR
2017 case RENDERPATH_D3D9:
2019 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2022 case RENDERPATH_D3D10:
2023 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2025 case RENDERPATH_D3D11:
2026 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2028 case RENDERPATH_SOFT:
2029 DPSOFTRAST_CullFace(gl_state.cullface);
2035 void GL_CullFace(int state)
2039 if(state == GL_FRONT)
2041 else if(state == GL_BACK)
2045 switch(vid.renderpath)
2047 case RENDERPATH_GL11:
2048 case RENDERPATH_GL13:
2049 case RENDERPATH_GL20:
2050 case RENDERPATH_GLES1:
2051 case RENDERPATH_GLES2:
2054 if (state != GL_NONE)
2056 if (!gl_state.cullfaceenable)
2058 gl_state.cullfaceenable = true;
2059 qglEnable(GL_CULL_FACE);CHECKGLERROR
2061 if (gl_state.cullface != state)
2063 gl_state.cullface = state;
2064 qglCullFace(gl_state.cullface);CHECKGLERROR
2069 if (gl_state.cullfaceenable)
2071 gl_state.cullfaceenable = false;
2072 qglDisable(GL_CULL_FACE);CHECKGLERROR
2076 case RENDERPATH_D3D9:
2078 if (gl_state.cullface != state)
2080 gl_state.cullface = state;
2081 switch(gl_state.cullface)
2084 gl_state.cullfaceenable = false;
2085 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2088 gl_state.cullfaceenable = true;
2089 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2092 gl_state.cullfaceenable = true;
2093 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2099 case RENDERPATH_D3D10:
2100 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2102 case RENDERPATH_D3D11:
2103 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2105 case RENDERPATH_SOFT:
2106 if (gl_state.cullface != state)
2108 gl_state.cullface = state;
2109 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2110 DPSOFTRAST_CullFace(gl_state.cullface);
2116 void GL_AlphaTest(int state)
2118 if (gl_state.alphatest != state)
2120 gl_state.alphatest = state;
2121 switch(vid.renderpath)
2123 case RENDERPATH_GL11:
2124 case RENDERPATH_GL13:
2125 case RENDERPATH_GLES1:
2126 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2128 if (gl_state.alphatest)
2130 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2134 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2137 case RENDERPATH_D3D9:
2138 case RENDERPATH_D3D10:
2139 case RENDERPATH_D3D11:
2140 case RENDERPATH_SOFT:
2141 case RENDERPATH_GL20:
2142 case RENDERPATH_GLES2:
2148 void GL_AlphaToCoverage(qboolean state)
2150 if (gl_state.alphatocoverage != state)
2152 gl_state.alphatocoverage = state;
2153 switch(vid.renderpath)
2155 case RENDERPATH_GL11:
2156 case RENDERPATH_GL13:
2157 case RENDERPATH_GLES1:
2158 case RENDERPATH_GLES2:
2159 case RENDERPATH_D3D9:
2160 case RENDERPATH_D3D10:
2161 case RENDERPATH_D3D11:
2162 case RENDERPATH_SOFT:
2164 case RENDERPATH_GL20:
2165 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2167 if (gl_state.alphatocoverage)
2169 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2170 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2174 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2175 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2182 void GL_ColorMask(int r, int g, int b, int a)
2184 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2185 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2186 if (gl_state.colormask != state)
2188 gl_state.colormask = state;
2189 switch(vid.renderpath)
2191 case RENDERPATH_GL11:
2192 case RENDERPATH_GL13:
2193 case RENDERPATH_GL20:
2194 case RENDERPATH_GLES1:
2195 case RENDERPATH_GLES2:
2197 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2199 case RENDERPATH_D3D9:
2201 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2204 case RENDERPATH_D3D10:
2205 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2207 case RENDERPATH_D3D11:
2208 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2210 case RENDERPATH_SOFT:
2211 DPSOFTRAST_ColorMask(r, g, b, a);
2217 void GL_Color(float cr, float cg, float cb, float ca)
2219 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)
2221 gl_state.color4f[0] = cr;
2222 gl_state.color4f[1] = cg;
2223 gl_state.color4f[2] = cb;
2224 gl_state.color4f[3] = ca;
2225 switch(vid.renderpath)
2227 case RENDERPATH_GL11:
2228 case RENDERPATH_GL13:
2229 case RENDERPATH_GLES1:
2231 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2234 case RENDERPATH_D3D9:
2235 case RENDERPATH_D3D10:
2236 case RENDERPATH_D3D11:
2237 // no equivalent in D3D
2239 case RENDERPATH_SOFT:
2240 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2242 case RENDERPATH_GL20:
2243 case RENDERPATH_GLES2:
2244 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2250 void GL_Scissor (int x, int y, int width, int height)
2252 switch(vid.renderpath)
2254 case RENDERPATH_GL11:
2255 case RENDERPATH_GL13:
2256 case RENDERPATH_GL20:
2257 case RENDERPATH_GLES1:
2258 case RENDERPATH_GLES2:
2260 qglScissor(x, y,width,height);
2263 case RENDERPATH_D3D9:
2269 d3drect.right = x + width;
2270 d3drect.bottom = y + height;
2271 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2275 case RENDERPATH_D3D10:
2276 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2278 case RENDERPATH_D3D11:
2279 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2281 case RENDERPATH_SOFT:
2282 DPSOFTRAST_Scissor(x, y, width, height);
2287 void GL_ScissorTest(int state)
2289 if (gl_state.scissortest != state)
2291 gl_state.scissortest = state;
2292 switch(vid.renderpath)
2294 case RENDERPATH_GL11:
2295 case RENDERPATH_GL13:
2296 case RENDERPATH_GL20:
2297 case RENDERPATH_GLES1:
2298 case RENDERPATH_GLES2:
2300 if(gl_state.scissortest)
2301 qglEnable(GL_SCISSOR_TEST);
2303 qglDisable(GL_SCISSOR_TEST);
2306 case RENDERPATH_D3D9:
2308 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2311 case RENDERPATH_D3D10:
2312 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2314 case RENDERPATH_D3D11:
2315 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2317 case RENDERPATH_SOFT:
2318 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2324 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2326 static const float blackcolor[4] = {0, 0, 0, 0};
2327 // prevent warnings when trying to clear a buffer that does not exist
2329 colorvalue = blackcolor;
2332 mask &= ~GL_STENCIL_BUFFER_BIT;
2335 switch(vid.renderpath)
2337 case RENDERPATH_GL11:
2338 case RENDERPATH_GL13:
2339 case RENDERPATH_GL20:
2340 case RENDERPATH_GLES1:
2341 case RENDERPATH_GLES2:
2343 if (mask & GL_COLOR_BUFFER_BIT)
2345 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2347 if (mask & GL_DEPTH_BUFFER_BIT)
2349 qglClearDepth(depthvalue);CHECKGLERROR
2351 if (mask & GL_STENCIL_BUFFER_BIT)
2353 qglClearStencil(stencilvalue);CHECKGLERROR
2355 qglClear(mask);CHECKGLERROR
2357 case RENDERPATH_D3D9:
2359 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);
2362 case RENDERPATH_D3D10:
2363 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2365 case RENDERPATH_D3D11:
2366 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2368 case RENDERPATH_SOFT:
2369 if (mask & GL_COLOR_BUFFER_BIT)
2370 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2371 if (mask & GL_DEPTH_BUFFER_BIT)
2372 DPSOFTRAST_ClearDepth(depthvalue);
2377 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2379 switch(vid.renderpath)
2381 case RENDERPATH_GL11:
2382 case RENDERPATH_GL13:
2383 case RENDERPATH_GL20:
2384 case RENDERPATH_GLES1:
2385 case RENDERPATH_GLES2:
2387 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2389 case RENDERPATH_D3D9:
2392 // LordHavoc: we can't directly download the backbuffer because it may be
2393 // multisampled, and it may not be lockable, so we blit it to a lockable
2394 // surface of the same dimensions (but without multisample) to resolve the
2395 // multisample buffer to a normal image, and then lock that...
2396 IDirect3DSurface9 *stretchsurface = NULL;
2397 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2399 D3DLOCKED_RECT lockedrect;
2400 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2402 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2405 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2406 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2407 memcpy(outpixels + line * width * 4, row, width * 4);
2408 IDirect3DSurface9_UnlockRect(stretchsurface);
2411 IDirect3DSurface9_Release(stretchsurface);
2414 //IDirect3DSurface9 *syssurface = NULL;
2415 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2416 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2417 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2418 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2419 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2420 //IDirect3DSurface9_UnlockRect(syssurface);
2421 //IDirect3DSurface9_Release(syssurface);
2425 case RENDERPATH_D3D10:
2426 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2428 case RENDERPATH_D3D11:
2429 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2431 case RENDERPATH_SOFT:
2432 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2437 // called at beginning of frame
2438 void R_Mesh_Start(void)
2441 R_Mesh_ResetRenderTargets();
2443 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2445 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2446 Cvar_SetValueQuick(&gl_paranoid, 1);
2450 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2454 char compilelog[MAX_INPUTLINE];
2455 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2458 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2459 qglCompileShader(shaderobject);CHECKGLERROR
2460 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2461 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2462 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2464 int i, j, pretextlines = 0;
2465 for (i = 0;i < numstrings - 1;i++)
2466 for (j = 0;strings[i][j];j++)
2467 if (strings[i][j] == '\n')
2469 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2471 if (!shadercompiled)
2473 qglDeleteShader(shaderobject);CHECKGLERROR
2476 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2477 qglDeleteShader(shaderobject);CHECKGLERROR
2481 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)
2483 GLint programlinked;
2484 GLuint programobject = 0;
2485 char linklog[MAX_INPUTLINE];
2488 programobject = qglCreateProgram();CHECKGLERROR
2492 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2493 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2494 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2495 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2496 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2497 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2498 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2499 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2500 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2501 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2502 if(vid.support.gl20shaders130)
2503 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2505 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2508 #ifdef GL_GEOMETRY_SHADER
2509 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2513 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2516 qglLinkProgram(programobject);CHECKGLERROR
2517 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2518 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2521 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2522 Con_DPrintf("program link log:\n%s\n", linklog);
2523 // software vertex shader is ok but software fragment shader is WAY
2524 // too slow, fail program if so.
2525 // NOTE: this string might be ATI specific, but that's ok because the
2526 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2527 // software fragment shader due to low instruction and dependent
2529 if (strstr(linklog, "fragment shader will run in software"))
2530 programlinked = false;
2534 return programobject;
2536 qglDeleteProgram(programobject);CHECKGLERROR
2540 void GL_Backend_FreeProgram(unsigned int prog)
2543 qglDeleteProgram(prog);
2547 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2552 for (i = 0;i < count;i++)
2553 *out++ = *in++ + offset;
2556 memcpy(out, in, sizeof(*out) * count);
2559 // renders triangles using vertices from the active arrays
2560 int paranoidblah = 0;
2561 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)
2563 unsigned int numelements = numtriangles * 3;
2565 size_t bufferoffset3i;
2567 size_t bufferoffset3s;
2568 if (numvertices < 3 || numtriangles < 1)
2570 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2571 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);
2574 if (!gl_mesh_prefer_short_elements.integer)
2578 if (element3i_indexbuffer)
2579 element3i_indexbuffer = NULL;
2581 // adjust the pointers for firsttriangle
2583 element3i += firsttriangle * 3;
2584 if (element3i_indexbuffer)
2585 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2587 element3s += firsttriangle * 3;
2588 if (element3s_indexbuffer)
2589 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2590 switch(vid.renderpath)
2592 case RENDERPATH_GL11:
2593 case RENDERPATH_GL13:
2594 case RENDERPATH_GL20:
2595 case RENDERPATH_GLES1:
2596 case RENDERPATH_GLES2:
2597 // check if the user specified to ignore static index buffers
2598 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2600 element3i_indexbuffer = NULL;
2601 element3s_indexbuffer = NULL;
2604 case RENDERPATH_D3D9:
2605 case RENDERPATH_D3D10:
2606 case RENDERPATH_D3D11:
2608 case RENDERPATH_SOFT:
2611 // upload a dynamic index buffer if needed
2614 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2616 if (gl_state.draw_dynamicindexbuffer)
2617 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2619 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2620 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2621 element3s_bufferoffset = 0;
2626 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2628 if (gl_state.draw_dynamicindexbuffer)
2629 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2631 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2632 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2633 element3i_bufferoffset = 0;
2636 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2637 bufferoffset3i = element3i_bufferoffset;
2638 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2639 bufferoffset3s = element3s_bufferoffset;
2640 r_refdef.stats.draws++;
2641 r_refdef.stats.draws_vertices += numvertices;
2642 r_refdef.stats.draws_elements += numelements;
2643 if (gl_paranoid.integer)
2646 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2648 unsigned int j, size;
2650 // note: there's no validation done here on buffer objects because it
2651 // is somewhat difficult to get at the data, and gl_paranoid can be
2652 // used without buffer objects if the need arises
2653 // (the data could be gotten using glMapBuffer but it would be very
2654 // slow due to uncachable video memory reads)
2655 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2656 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2658 if (gl_state.pointer_vertex_pointer)
2659 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2661 if (gl_state.pointer_color_enabled)
2663 if (!qglIsEnabled(GL_COLOR_ARRAY))
2664 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2666 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2667 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2670 for (i = 0;i < vid.texarrayunits;i++)
2672 if (gl_state.units[i].arrayenabled)
2674 GL_ClientActiveTexture(i);
2675 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2676 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2678 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2679 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++)
2686 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2688 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2690 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2697 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2699 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2701 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2707 if (r_render.integer || r_refdef.draw2dstage)
2709 switch(vid.renderpath)
2711 case RENDERPATH_GL11:
2712 case RENDERPATH_GL13:
2713 case RENDERPATH_GL20:
2715 if (gl_mesh_testmanualfeeding.integer)
2717 unsigned int i, j, element;
2719 qglBegin(GL_TRIANGLES);
2720 if(vid.renderpath == RENDERPATH_GL20)
2722 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2725 element = element3i[i];
2727 element = element3s[i];
2729 element = firstvertex + i;
2730 for (j = 0;j < vid.texarrayunits;j++)
2732 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2734 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2736 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2737 if (gl_state.units[j].pointer_texcoord_components == 4)
2738 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2739 else if (gl_state.units[j].pointer_texcoord_components == 3)
2740 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2741 else if (gl_state.units[j].pointer_texcoord_components == 2)
2742 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2744 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2746 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2748 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2749 if (gl_state.units[j].pointer_texcoord_components == 4)
2750 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2751 else if (gl_state.units[j].pointer_texcoord_components == 3)
2752 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2753 else if (gl_state.units[j].pointer_texcoord_components == 2)
2754 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2755 else if (gl_state.units[j].pointer_texcoord_components == 1)
2756 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2758 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2760 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2761 if (gl_state.units[j].pointer_texcoord_components == 4)
2762 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2763 else if (gl_state.units[j].pointer_texcoord_components == 3)
2764 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2765 else if (gl_state.units[j].pointer_texcoord_components == 2)
2766 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2767 else if (gl_state.units[j].pointer_texcoord_components == 1)
2768 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2772 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2774 if (gl_state.pointer_color_gltype == GL_FLOAT)
2776 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2777 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2779 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2781 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2782 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2785 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2787 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2788 if (gl_state.pointer_vertex_components == 4)
2789 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2790 else if (gl_state.pointer_vertex_components == 3)
2791 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2793 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2799 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2802 element = element3i[i];
2804 element = element3s[i];
2806 element = firstvertex + i;
2807 for (j = 0;j < vid.texarrayunits;j++)
2809 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2811 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2813 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2814 if (vid.texarrayunits > 1)
2816 if (gl_state.units[j].pointer_texcoord_components == 4)
2817 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2818 else if (gl_state.units[j].pointer_texcoord_components == 3)
2819 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2820 else if (gl_state.units[j].pointer_texcoord_components == 2)
2821 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2823 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2827 if (gl_state.units[j].pointer_texcoord_components == 4)
2828 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2829 else if (gl_state.units[j].pointer_texcoord_components == 3)
2830 qglTexCoord3f(p[0], p[1], p[2]);
2831 else if (gl_state.units[j].pointer_texcoord_components == 2)
2832 qglTexCoord2f(p[0], p[1]);
2834 qglTexCoord1f(p[0]);
2837 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2839 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2840 if (vid.texarrayunits > 1)
2842 if (gl_state.units[j].pointer_texcoord_components == 4)
2843 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2844 else if (gl_state.units[j].pointer_texcoord_components == 3)
2845 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2846 else if (gl_state.units[j].pointer_texcoord_components == 2)
2847 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2848 else if (gl_state.units[j].pointer_texcoord_components == 1)
2849 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2853 if (gl_state.units[j].pointer_texcoord_components == 4)
2854 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2855 else if (gl_state.units[j].pointer_texcoord_components == 3)
2856 qglTexCoord3f(s[0], s[1], s[2]);
2857 else if (gl_state.units[j].pointer_texcoord_components == 2)
2858 qglTexCoord2f(s[0], s[1]);
2859 else if (gl_state.units[j].pointer_texcoord_components == 1)
2860 qglTexCoord1f(s[0]);
2863 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2865 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2866 if (vid.texarrayunits > 1)
2868 if (gl_state.units[j].pointer_texcoord_components == 4)
2869 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2870 else if (gl_state.units[j].pointer_texcoord_components == 3)
2871 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2872 else if (gl_state.units[j].pointer_texcoord_components == 2)
2873 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2874 else if (gl_state.units[j].pointer_texcoord_components == 1)
2875 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2879 if (gl_state.units[j].pointer_texcoord_components == 4)
2880 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2881 else if (gl_state.units[j].pointer_texcoord_components == 3)
2882 qglTexCoord3f(sb[0], sb[1], sb[2]);
2883 else if (gl_state.units[j].pointer_texcoord_components == 2)
2884 qglTexCoord2f(sb[0], sb[1]);
2885 else if (gl_state.units[j].pointer_texcoord_components == 1)
2886 qglTexCoord1f(sb[0]);
2891 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2893 if (gl_state.pointer_color_gltype == GL_FLOAT)
2895 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2896 qglColor4f(p[0], p[1], p[2], p[3]);
2898 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2900 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2901 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2904 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2906 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2907 if (gl_state.pointer_vertex_components == 4)
2908 qglVertex4f(p[0], p[1], p[2], p[3]);
2909 else if (gl_state.pointer_vertex_components == 3)
2910 qglVertex3f(p[0], p[1], p[2]);
2912 qglVertex2f(p[0], p[1]);
2919 else if (bufferobject3s)
2921 GL_BindEBO(bufferobject3s);
2922 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2924 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2929 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2933 else if (bufferobject3i)
2935 GL_BindEBO(bufferobject3i);
2936 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2938 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2943 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2950 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2952 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2957 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2964 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2966 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2971 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2977 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2981 case RENDERPATH_D3D9:
2983 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2985 if (element3s_indexbuffer)
2987 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2988 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2990 else if (element3i_indexbuffer)
2992 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2993 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2996 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3001 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3003 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3005 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3009 case RENDERPATH_D3D10:
3010 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3012 case RENDERPATH_D3D11:
3013 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3015 case RENDERPATH_SOFT:
3016 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3018 case RENDERPATH_GLES1:
3019 case RENDERPATH_GLES2:
3020 // GLES does not have glDrawRangeElements, and generally
3021 // underperforms with index buffers, so this code path is
3022 // relatively straightforward...
3024 if (gl_paranoid.integer)
3026 int r, prog, enabled, i;
3027 GLsizei attriblength;
3030 GLchar attribname[1024];
3031 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
3032 if (r != GL_FRAMEBUFFER_COMPLETE_EXT)
3033 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3034 #ifndef GL_CURRENT_PROGRAM
3035 #define GL_CURRENT_PROGRAM 0x8B8D
3037 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3038 if (r < 0 || r > 10000)
3039 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3041 for (i = 0;i < 8;i++)
3043 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3046 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3047 Con_DPrintf("prog %i position %i length %i size %04X type %i name \"%s\"\n", prog, i, (int)attriblength, (int)attribsize, (int)attribtype, (char *)attribname);
3053 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3058 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3063 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3071 // restores backend state, used when done with 3D rendering
3072 void R_Mesh_Finish(void)
3074 R_Mesh_ResetRenderTargets();
3077 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3079 r_meshbuffer_t *buffer;
3080 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3082 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3083 memset(buffer, 0, sizeof(*buffer));
3084 buffer->bufferobject = 0;
3085 buffer->devicebuffer = NULL;
3087 buffer->isindexbuffer = isindexbuffer;
3088 buffer->isdynamic = isdynamic;
3089 buffer->isindex16 = isindex16;
3090 strlcpy(buffer->name, name, sizeof(buffer->name));
3091 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3095 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3099 if (buffer->isindexbuffer)
3101 r_refdef.stats.indexbufferuploadcount++;
3102 r_refdef.stats.indexbufferuploadsize += size;
3106 r_refdef.stats.vertexbufferuploadcount++;
3107 r_refdef.stats.vertexbufferuploadsize += size;
3109 switch(vid.renderpath)
3111 case RENDERPATH_GL11:
3112 case RENDERPATH_GL13:
3113 case RENDERPATH_GL20:
3114 case RENDERPATH_GLES1:
3115 case RENDERPATH_GLES2:
3116 if (!buffer->bufferobject)
3117 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3118 if (buffer->isindexbuffer)
3119 GL_BindEBO(buffer->bufferobject);
3121 GL_BindVBO(buffer->bufferobject);
3122 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
3124 case RENDERPATH_D3D9:
3128 void *datapointer = NULL;
3129 if (buffer->isindexbuffer)
3131 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3132 if (size > buffer->size || !buffer->devicebuffer)
3134 if (buffer->devicebuffer)
3135 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3136 buffer->devicebuffer = NULL;
3137 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)))
3138 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);
3139 buffer->devicebuffer = (void *)d3d9indexbuffer;
3140 buffer->size = size;
3142 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3145 memcpy(datapointer, data, size);
3147 memset(datapointer, 0, size);
3148 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3153 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3154 if (size > buffer->size || !buffer->devicebuffer)
3156 if (buffer->devicebuffer)
3157 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3158 buffer->devicebuffer = NULL;
3159 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3160 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);
3161 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3162 buffer->size = size;
3164 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3167 memcpy(datapointer, data, size);
3169 memset(datapointer, 0, size);
3170 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3176 case RENDERPATH_D3D10:
3177 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3179 case RENDERPATH_D3D11:
3180 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3182 case RENDERPATH_SOFT:
3187 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3191 switch(vid.renderpath)
3193 case RENDERPATH_GL11:
3194 case RENDERPATH_GL13:
3195 case RENDERPATH_GL20:
3196 case RENDERPATH_GLES1:
3197 case RENDERPATH_GLES2:
3198 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3200 case RENDERPATH_D3D9:
3202 if (gl_state.d3dvertexbuffer == (void *)buffer)
3203 gl_state.d3dvertexbuffer = NULL;
3204 if (buffer->devicebuffer)
3206 if (buffer->isindexbuffer)
3207 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3209 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3210 buffer->devicebuffer = NULL;
3214 case RENDERPATH_D3D10:
3215 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3217 case RENDERPATH_D3D11:
3218 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3220 case RENDERPATH_SOFT:
3223 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3226 void GL_Mesh_ListVBOs(qboolean printeach)
3229 size_t ebocount = 0, ebomemory = 0;
3230 size_t vbocount = 0, vbomemory = 0;
3231 r_meshbuffer_t *buffer;
3232 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3233 for (i = 0;i < endindex;i++)
3235 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3238 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)");}
3239 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)");}
3241 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);
3246 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3248 switch(vid.renderpath)
3250 case RENDERPATH_GL11:
3251 case RENDERPATH_GL13:
3252 case RENDERPATH_GLES1:
3253 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)
3255 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3256 gl_state.pointer_vertex_components = components;
3257 gl_state.pointer_vertex_gltype = gltype;
3258 gl_state.pointer_vertex_stride = stride;
3259 gl_state.pointer_vertex_pointer = pointer;
3260 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3261 gl_state.pointer_vertex_offset = bufferoffset;
3263 GL_BindVBO(bufferobject);
3264 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3267 case RENDERPATH_GL20:
3268 case RENDERPATH_GLES2:
3269 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)
3271 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3272 gl_state.pointer_vertex_components = components;
3273 gl_state.pointer_vertex_gltype = gltype;
3274 gl_state.pointer_vertex_stride = stride;
3275 gl_state.pointer_vertex_pointer = pointer;
3276 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3277 gl_state.pointer_vertex_offset = bufferoffset;
3279 GL_BindVBO(bufferobject);
3280 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3283 case RENDERPATH_D3D9:
3284 case RENDERPATH_D3D10:
3285 case RENDERPATH_D3D11:
3286 case RENDERPATH_SOFT:
3291 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3293 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3294 // the pointer only.
3295 switch(vid.renderpath)
3297 case RENDERPATH_GL11:
3298 case RENDERPATH_GL13:
3299 case RENDERPATH_GLES1:
3303 // caller wants color array enabled
3304 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3305 if (!gl_state.pointer_color_enabled)
3307 gl_state.pointer_color_enabled = true;
3309 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3311 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)
3313 gl_state.pointer_color_components = components;
3314 gl_state.pointer_color_gltype = gltype;
3315 gl_state.pointer_color_stride = stride;
3316 gl_state.pointer_color_pointer = pointer;
3317 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3318 gl_state.pointer_color_offset = bufferoffset;
3320 GL_BindVBO(bufferobject);
3321 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3326 // caller wants color array disabled
3327 if (gl_state.pointer_color_enabled)
3329 gl_state.pointer_color_enabled = false;
3331 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3332 // when color array is on the glColor gets trashed, set it again
3333 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3337 case RENDERPATH_GL20:
3338 case RENDERPATH_GLES2:
3342 // caller wants color array enabled
3343 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3344 if (!gl_state.pointer_color_enabled)
3346 gl_state.pointer_color_enabled = true;
3348 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3350 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)
3352 gl_state.pointer_color_components = components;
3353 gl_state.pointer_color_gltype = gltype;
3354 gl_state.pointer_color_stride = stride;
3355 gl_state.pointer_color_pointer = pointer;
3356 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3357 gl_state.pointer_color_offset = bufferoffset;
3359 GL_BindVBO(bufferobject);
3360 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3365 // caller wants color array disabled
3366 if (gl_state.pointer_color_enabled)
3368 gl_state.pointer_color_enabled = false;
3370 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3371 // when color array is on the glColor gets trashed, set it again
3372 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3376 case RENDERPATH_D3D9:
3377 case RENDERPATH_D3D10:
3378 case RENDERPATH_D3D11:
3379 case RENDERPATH_SOFT:
3384 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)
3386 gltextureunit_t *unit = gl_state.units + unitnum;
3387 // update array settings
3388 // note: there is no need to check bufferobject here because all cases
3389 // that involve a valid bufferobject also supply a texcoord array
3390 switch(vid.renderpath)
3392 case RENDERPATH_GL11:
3393 case RENDERPATH_GL13:
3394 case RENDERPATH_GLES1:
3398 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3399 // texture array unit is enabled, enable the array
3400 if (!unit->arrayenabled)
3402 unit->arrayenabled = true;
3403 GL_ClientActiveTexture(unitnum);
3404 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3407 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)
3409 unit->pointer_texcoord_components = components;
3410 unit->pointer_texcoord_gltype = gltype;
3411 unit->pointer_texcoord_stride = stride;
3412 unit->pointer_texcoord_pointer = pointer;
3413 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3414 unit->pointer_texcoord_offset = bufferoffset;
3415 GL_ClientActiveTexture(unitnum);
3416 GL_BindVBO(bufferobject);
3417 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3422 // texture array unit is disabled, disable the array
3423 if (unit->arrayenabled)
3425 unit->arrayenabled = false;
3426 GL_ClientActiveTexture(unitnum);
3427 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3431 case RENDERPATH_GL20:
3432 case RENDERPATH_GLES2:
3436 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3437 // texture array unit is enabled, enable the array
3438 if (!unit->arrayenabled)
3440 unit->arrayenabled = true;
3441 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3444 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)
3446 unit->pointer_texcoord_components = components;
3447 unit->pointer_texcoord_gltype = gltype;
3448 unit->pointer_texcoord_stride = stride;
3449 unit->pointer_texcoord_pointer = pointer;
3450 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3451 unit->pointer_texcoord_offset = bufferoffset;
3452 GL_BindVBO(bufferobject);
3453 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3458 // texture array unit is disabled, disable the array
3459 if (unit->arrayenabled)
3461 unit->arrayenabled = false;
3462 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3466 case RENDERPATH_D3D9:
3467 case RENDERPATH_D3D10:
3468 case RENDERPATH_D3D11:
3469 case RENDERPATH_SOFT:
3474 int R_Mesh_TexBound(unsigned int unitnum, int id)
3476 gltextureunit_t *unit = gl_state.units + unitnum;
3477 if (unitnum >= vid.teximageunits)
3479 if (id == GL_TEXTURE_2D)
3481 if (id == GL_TEXTURE_3D)
3483 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3484 return unit->tcubemap;
3488 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3490 switch(vid.renderpath)
3492 case RENDERPATH_GL11:
3493 case RENDERPATH_GL13:
3494 case RENDERPATH_GL20:
3495 case RENDERPATH_GLES1:
3496 case RENDERPATH_GLES2:
3497 R_Mesh_TexBind(0, tex);
3498 GL_ActiveTexture(0);CHECKGLERROR
3499 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3501 case RENDERPATH_D3D9:
3504 IDirect3DSurface9 *currentsurface = NULL;
3505 IDirect3DSurface9 *texturesurface = NULL;
3508 sourcerect.left = sx;
3509 sourcerect.top = sy;
3510 sourcerect.right = sx + width;
3511 sourcerect.bottom = sy + height;
3514 destrect.right = tx + width;
3515 destrect.bottom = ty + height;
3516 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3518 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3520 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3521 IDirect3DSurface9_Release(currentsurface);
3523 IDirect3DSurface9_Release(texturesurface);
3528 case RENDERPATH_D3D10:
3529 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3531 case RENDERPATH_D3D11:
3532 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3534 case RENDERPATH_SOFT:
3535 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3541 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};
3544 void R_Mesh_ClearBindingsForTexture(int texnum)
3546 gltextureunit_t *unit;
3547 unsigned int unitnum;
3548 // this doesn't really unbind the texture, but it does prevent a mistaken "do nothing" behavior on the next time this same texnum is bound on the same unit as the same type (this mainly affects r_shadow_bouncegrid because 3D textures are so rarely used)
3549 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3551 unit = gl_state.units + unitnum;
3552 if (unit->t2d == texnum)
3554 if (unit->t3d == texnum)
3556 if (unit->tcubemap == texnum)
3557 unit->tcubemap = -1;
3561 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3563 gltextureunit_t *unit = gl_state.units + unitnum;
3564 int tex2d, tex3d, texcubemap, texnum;
3565 if (unitnum >= vid.teximageunits)
3567 // if (unit->texture == tex)
3569 switch(vid.renderpath)
3571 case RENDERPATH_GL20:
3572 case RENDERPATH_GLES2:
3575 tex = r_texture_white;
3576 // not initialized enough yet...
3580 unit->texture = tex;
3581 texnum = R_GetTexture(tex);
3582 switch(tex->gltexturetypeenum)
3584 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3585 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3586 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;
3589 case RENDERPATH_GL11:
3590 case RENDERPATH_GL13:
3591 case RENDERPATH_GLES1:
3592 unit->texture = tex;
3598 texnum = R_GetTexture(tex);
3599 switch(tex->gltexturetypeenum)
3607 case GL_TEXTURE_CUBE_MAP_ARB:
3608 texcubemap = texnum;
3612 // update 2d texture binding
3613 if (unit->t2d != tex2d)
3615 GL_ActiveTexture(unitnum);
3620 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3627 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3631 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3633 // update 3d texture binding
3634 if (unit->t3d != tex3d)
3636 GL_ActiveTexture(unitnum);
3641 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3648 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3652 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3654 // update cubemap texture binding
3655 if (unit->tcubemap != texcubemap)
3657 GL_ActiveTexture(unitnum);
3660 if (unit->tcubemap == 0)
3662 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3669 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3672 unit->tcubemap = texcubemap;
3673 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3676 case RENDERPATH_D3D9:
3679 extern cvar_t gl_texture_anisotropy;
3682 tex = r_texture_white;
3683 // not initialized enough yet...
3687 // upload texture if needed
3689 if (unit->texture == tex)
3691 unit->texture = tex;
3692 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3693 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3694 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3695 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3696 if (tex->d3daddressw)
3697 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3698 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3699 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3700 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3701 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3702 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3703 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3707 case RENDERPATH_D3D10:
3708 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3710 case RENDERPATH_D3D11:
3711 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3713 case RENDERPATH_SOFT:
3716 tex = r_texture_white;
3717 // not initialized enough yet...
3721 texnum = R_GetTexture(tex);
3722 if (unit->texture == tex)
3724 unit->texture = tex;
3725 DPSOFTRAST_SetTexture(unitnum, texnum);
3730 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3732 gltextureunit_t *unit = gl_state.units + unitnum;
3733 switch(vid.renderpath)
3735 case RENDERPATH_GL11:
3736 case RENDERPATH_GL13:
3737 case RENDERPATH_GL20:
3738 case RENDERPATH_GLES1:
3739 case RENDERPATH_GLES2:
3740 if (matrix && matrix->m[3][3])
3742 // texmatrix specified, check if it is different
3743 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3746 unit->texmatrixenabled = true;
3747 unit->matrix = *matrix;
3749 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3750 GL_ActiveTexture(unitnum);
3751 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3752 qglLoadMatrixf(glmatrix);CHECKGLERROR
3753 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3758 // no texmatrix specified, revert to identity
3759 if (unit->texmatrixenabled)
3761 unit->texmatrixenabled = false;
3762 unit->matrix = identitymatrix;
3764 GL_ActiveTexture(unitnum);
3765 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3766 qglLoadIdentity();CHECKGLERROR
3767 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3771 case RENDERPATH_D3D9:
3772 case RENDERPATH_D3D10:
3773 case RENDERPATH_D3D11:
3775 case RENDERPATH_SOFT:
3780 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3782 gltextureunit_t *unit = gl_state.units + unitnum;
3784 switch(vid.renderpath)
3786 case RENDERPATH_GL20:
3787 case RENDERPATH_GLES2:
3790 case RENDERPATH_GL13:
3791 case RENDERPATH_GLES1:
3792 // GL_ARB_texture_env_combine
3794 combinergb = GL_MODULATE;
3796 combinealpha = GL_MODULATE;
3801 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3803 if (combinergb == GL_DECAL)
3804 combinergb = GL_INTERPOLATE_ARB;
3805 if (unit->combine != GL_COMBINE_ARB)
3807 unit->combine = GL_COMBINE_ARB;
3808 GL_ActiveTexture(unitnum);
3809 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3810 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3812 if (unit->combinergb != combinergb)
3814 unit->combinergb = combinergb;
3815 GL_ActiveTexture(unitnum);
3816 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3818 if (unit->combinealpha != combinealpha)
3820 unit->combinealpha = combinealpha;
3821 GL_ActiveTexture(unitnum);
3822 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3824 if (unit->rgbscale != rgbscale)
3826 unit->rgbscale = rgbscale;
3827 GL_ActiveTexture(unitnum);
3828 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3830 if (unit->alphascale != alphascale)
3832 unit->alphascale = alphascale;
3833 GL_ActiveTexture(unitnum);
3834 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3839 if (unit->combine != combinergb)
3841 unit->combine = combinergb;
3842 GL_ActiveTexture(unitnum);
3843 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3847 case RENDERPATH_GL11:
3850 combinergb = GL_MODULATE;
3851 if (unit->combine != combinergb)
3853 unit->combine = combinergb;
3854 GL_ActiveTexture(unitnum);
3855 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3858 case RENDERPATH_D3D9:
3859 case RENDERPATH_D3D10:
3860 case RENDERPATH_D3D11:
3862 case RENDERPATH_SOFT:
3867 void R_Mesh_ResetTextureState(void)
3869 unsigned int unitnum;
3873 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3874 R_Mesh_TexBind(unitnum, NULL);
3875 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3876 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3877 switch(vid.renderpath)
3879 case RENDERPATH_GL20:
3880 case RENDERPATH_GLES2:
3881 case RENDERPATH_D3D9:
3882 case RENDERPATH_D3D10:
3883 case RENDERPATH_D3D11:
3884 case RENDERPATH_SOFT:
3886 case RENDERPATH_GL11:
3887 case RENDERPATH_GL13:
3888 case RENDERPATH_GLES1:
3889 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3891 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3892 R_Mesh_TexMatrix(unitnum, NULL);
3901 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3902 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3903 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3905 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3907 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3911 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3913 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3914 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3915 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3919 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3921 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3922 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3923 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3924 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3925 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3926 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3927 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3931 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
3932 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3933 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3936 static void R_Mesh_InitVertexDeclarations(void)
3939 r_vertex3f_d3d9decl = NULL;
3940 r_vertexgeneric_d3d9decl = NULL;
3941 r_vertexmesh_d3d9decl = NULL;
3942 switch(vid.renderpath)
3944 case RENDERPATH_GL20:
3945 case RENDERPATH_GL13:
3946 case RENDERPATH_GL11:
3947 case RENDERPATH_GLES1:
3948 case RENDERPATH_GLES2:
3950 case RENDERPATH_D3D9:
3951 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
3952 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3953 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3955 case RENDERPATH_D3D10:
3956 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3958 case RENDERPATH_D3D11:
3959 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3961 case RENDERPATH_SOFT:
3967 static void R_Mesh_DestroyVertexDeclarations(void)
3970 if (r_vertex3f_d3d9decl)
3971 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
3972 r_vertex3f_d3d9decl = NULL;
3973 if (r_vertexgeneric_d3d9decl)
3974 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3975 r_vertexgeneric_d3d9decl = NULL;
3976 if (r_vertexmesh_d3d9decl)
3977 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3978 r_vertexmesh_d3d9decl = NULL;
3982 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
3984 // upload temporary vertexbuffer for this rendering
3985 if (!gl_state.usevbo_staticvertex)
3986 vertexbuffer = NULL;
3987 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3989 if (gl_state.preparevertices_dynamicvertexbuffer)
3990 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
3992 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
3993 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3995 switch(vid.renderpath)
3997 case RENDERPATH_GL20:
3998 case RENDERPATH_GLES2:
4001 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4002 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4003 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4004 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4005 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4006 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4007 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4011 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4012 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4013 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4014 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4015 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4016 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4017 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4020 case RENDERPATH_GL13:
4021 case RENDERPATH_GLES1:
4024 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4025 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4026 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4027 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4031 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4032 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4033 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4034 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4037 case RENDERPATH_GL11:
4040 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4041 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4042 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4046 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4047 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4048 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4051 case RENDERPATH_D3D9:
4053 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4055 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4057 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4058 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4059 gl_state.d3dvertexdata = (void *)vertex3f;
4060 gl_state.d3dvertexsize = sizeof(float[3]);
4063 case RENDERPATH_D3D10:
4064 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4066 case RENDERPATH_D3D11:
4067 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4069 case RENDERPATH_SOFT:
4070 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4071 DPSOFTRAST_SetColorPointer(NULL, 0);
4072 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4073 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4074 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4075 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4076 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4083 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4086 size = sizeof(r_vertexgeneric_t) * numvertices;
4087 if (gl_state.preparevertices_tempdatamaxsize < size)
4089 gl_state.preparevertices_tempdatamaxsize = size;
4090 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4092 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4093 gl_state.preparevertices_numvertices = numvertices;
4094 return gl_state.preparevertices_vertexgeneric;
4097 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4099 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4100 gl_state.preparevertices_vertexgeneric = NULL;
4101 gl_state.preparevertices_numvertices = 0;
4105 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4108 r_vertexgeneric_t *vertex;
4109 switch(vid.renderpath)
4111 case RENDERPATH_GL20:
4112 case RENDERPATH_GLES2:
4113 if (!vid.useinterleavedarrays)
4115 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4116 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4117 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4118 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4119 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4120 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4121 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4125 case RENDERPATH_GL11:
4126 case RENDERPATH_GL13:
4127 case RENDERPATH_GLES1:
4128 if (!vid.useinterleavedarrays)
4130 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4131 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4132 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4133 if (vid.texunits >= 2)
4134 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4135 if (vid.texunits >= 3)
4136 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4140 case RENDERPATH_D3D9:
4141 case RENDERPATH_D3D10:
4142 case RENDERPATH_D3D11:
4144 case RENDERPATH_SOFT:
4145 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4146 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4147 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4148 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4149 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4150 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4151 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4155 // no quick path for this case, convert to vertex structs
4156 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4157 for (i = 0;i < numvertices;i++)
4158 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4161 for (i = 0;i < numvertices;i++)
4162 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4166 for (i = 0;i < numvertices;i++)
4167 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4170 for (i = 0;i < numvertices;i++)
4171 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4172 R_Mesh_PrepareVertices_Generic_Unlock();
4173 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4176 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4178 // upload temporary vertexbuffer for this rendering
4179 if (!gl_state.usevbo_staticvertex)
4180 vertexbuffer = NULL;
4181 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4183 if (gl_state.preparevertices_dynamicvertexbuffer)
4184 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4186 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4187 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4189 switch(vid.renderpath)
4191 case RENDERPATH_GL20:
4192 case RENDERPATH_GLES2:
4195 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4196 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4197 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4198 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4199 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4200 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4201 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4205 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4206 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4207 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4208 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4209 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4210 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4211 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4214 case RENDERPATH_GL13:
4215 case RENDERPATH_GLES1:
4218 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4219 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4220 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4221 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4225 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4226 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4227 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4228 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4231 case RENDERPATH_GL11:
4234 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4235 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4236 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4240 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4241 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4242 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4245 case RENDERPATH_D3D9:
4247 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4249 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4251 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4252 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4253 gl_state.d3dvertexdata = (void *)vertex;
4254 gl_state.d3dvertexsize = sizeof(*vertex);
4257 case RENDERPATH_D3D10:
4258 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4260 case RENDERPATH_D3D11:
4261 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4263 case RENDERPATH_SOFT:
4264 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4265 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4266 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4267 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4268 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4269 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4270 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4277 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4280 size = sizeof(r_vertexmesh_t) * numvertices;
4281 if (gl_state.preparevertices_tempdatamaxsize < size)
4283 gl_state.preparevertices_tempdatamaxsize = size;
4284 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4286 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4287 gl_state.preparevertices_numvertices = numvertices;
4288 return gl_state.preparevertices_vertexmesh;
4291 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4293 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4294 gl_state.preparevertices_vertexmesh = NULL;
4295 gl_state.preparevertices_numvertices = 0;
4299 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)
4302 r_vertexmesh_t *vertex;
4303 switch(vid.renderpath)
4305 case RENDERPATH_GL20:
4306 case RENDERPATH_GLES2:
4307 if (!vid.useinterleavedarrays)
4309 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4310 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4311 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4312 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4313 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4314 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4315 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4319 case RENDERPATH_GL11:
4320 case RENDERPATH_GL13:
4321 case RENDERPATH_GLES1:
4322 if (!vid.useinterleavedarrays)
4324 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4325 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4326 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4327 if (vid.texunits >= 2)
4328 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4329 if (vid.texunits >= 3)
4330 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4334 case RENDERPATH_D3D9:
4335 case RENDERPATH_D3D10:
4336 case RENDERPATH_D3D11:
4338 case RENDERPATH_SOFT:
4339 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4340 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4341 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4342 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4343 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4344 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4345 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4349 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4350 for (i = 0;i < numvertices;i++)
4351 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4353 for (i = 0;i < numvertices;i++)
4354 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4356 for (i = 0;i < numvertices;i++)
4357 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4359 for (i = 0;i < numvertices;i++)
4360 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4363 for (i = 0;i < numvertices;i++)
4364 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4368 for (i = 0;i < numvertices;i++)
4369 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4371 if (texcoordtexture2f)
4372 for (i = 0;i < numvertices;i++)
4373 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4374 if (texcoordlightmap2f)
4375 for (i = 0;i < numvertices;i++)
4376 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4377 R_Mesh_PrepareVertices_Mesh_Unlock();
4378 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4381 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4383 // upload temporary vertexbuffer for this rendering
4384 if (!gl_state.usevbo_staticvertex)
4385 vertexbuffer = NULL;
4386 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4388 if (gl_state.preparevertices_dynamicvertexbuffer)
4389 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4391 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4392 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4394 switch(vid.renderpath)
4396 case RENDERPATH_GL20:
4397 case RENDERPATH_GLES2:
4400 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4401 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4402 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4403 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4404 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4405 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4406 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4410 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4411 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4412 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4413 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4414 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4415 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4416 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4419 case RENDERPATH_GL13:
4420 case RENDERPATH_GLES1:
4423 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4424 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4425 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4426 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4430 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4431 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4432 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4433 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4436 case RENDERPATH_GL11:
4439 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4440 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4441 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4445 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4446 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4447 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4450 case RENDERPATH_D3D9:
4452 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4454 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4456 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4457 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4458 gl_state.d3dvertexdata = (void *)vertex;
4459 gl_state.d3dvertexsize = sizeof(*vertex);
4462 case RENDERPATH_D3D10:
4463 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4465 case RENDERPATH_D3D11:
4466 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4468 case RENDERPATH_SOFT:
4469 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4470 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4471 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4472 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4473 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4474 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4475 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4480 void GL_BlendEquationSubtract(qboolean negated)
4484 switch(vid.renderpath)
4486 case RENDERPATH_GL11:
4487 case RENDERPATH_GL13:
4488 case RENDERPATH_GL20:
4489 case RENDERPATH_GLES1:
4490 case RENDERPATH_GLES2:
4491 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
4493 case RENDERPATH_D3D9:
4495 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4498 case RENDERPATH_D3D10:
4499 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4501 case RENDERPATH_D3D11:
4502 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4504 case RENDERPATH_SOFT:
4505 DPSOFTRAST_BlendSubtract(true);
4511 switch(vid.renderpath)
4513 case RENDERPATH_GL11:
4514 case RENDERPATH_GL13:
4515 case RENDERPATH_GL20:
4516 case RENDERPATH_GLES1:
4517 case RENDERPATH_GLES2:
4518 qglBlendEquationEXT(GL_FUNC_ADD_EXT);
4520 case RENDERPATH_D3D9:
4522 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4525 case RENDERPATH_D3D10:
4526 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4528 case RENDERPATH_D3D11:
4529 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4531 case RENDERPATH_SOFT:
4532 DPSOFTRAST_BlendSubtract(false);