3 #include "cl_collision.h"
4 #include "dpsoftrast.h"
7 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
8 extern D3DCAPS9 vid_d3d9caps;
11 // on GLES we have to use some proper #define's
12 #ifndef GL_FRAMEBUFFER
13 #define GL_FRAMEBUFFER 0x8D40
14 #define GL_DEPTH_ATTACHMENT 0x8D00
15 #define GL_COLOR_ATTACHMENT0 0x8CE0
16 #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
18 #ifndef GL_COLOR_ATTACHMENT1
19 #define GL_COLOR_ATTACHMENT1 0x8CE1
20 #define GL_COLOR_ATTACHMENT2 0x8CE2
21 #define GL_COLOR_ATTACHMENT3 0x8CE3
22 #define GL_COLOR_ATTACHMENT4 0x8CE4
23 #define GL_COLOR_ATTACHMENT5 0x8CE5
24 #define GL_COLOR_ATTACHMENT6 0x8CE6
25 #define GL_COLOR_ATTACHMENT7 0x8CE7
26 #define GL_COLOR_ATTACHMENT8 0x8CE8
27 #define GL_COLOR_ATTACHMENT9 0x8CE9
28 #define GL_COLOR_ATTACHMENT10 0x8CEA
29 #define GL_COLOR_ATTACHMENT11 0x8CEB
30 #define GL_COLOR_ATTACHMENT12 0x8CEC
31 #define GL_COLOR_ATTACHMENT13 0x8CED
32 #define GL_COLOR_ATTACHMENT14 0x8CEE
33 #define GL_COLOR_ATTACHMENT15 0x8CEF
35 #ifndef GL_ARRAY_BUFFER
36 #define GL_ARRAY_BUFFER 0x8892
37 #define GL_ELEMENT_ARRAY_BUFFER 0x8893
39 //#ifndef GL_VERTEX_ARRAY
40 //#define GL_VERTEX_ARRAY 0x8074
41 //#define GL_COLOR_ARRAY 0x8076
42 //#define GL_TEXTURE_COORD_ARRAY 0x8078
45 #define GL_TEXTURE0 0x84C0
46 #define GL_TEXTURE1 0x84C1
47 #define GL_TEXTURE2 0x84C2
48 #define GL_TEXTURE3 0x84C3
49 #define GL_TEXTURE4 0x84C4
50 #define GL_TEXTURE5 0x84C5
51 #define GL_TEXTURE6 0x84C6
52 #define GL_TEXTURE7 0x84C7
53 #define GL_TEXTURE8 0x84C8
54 #define GL_TEXTURE9 0x84C9
55 #define GL_TEXTURE10 0x84CA
56 #define GL_TEXTURE11 0x84CB
57 #define GL_TEXTURE12 0x84CC
58 #define GL_TEXTURE13 0x84CD
59 #define GL_TEXTURE14 0x84CE
60 #define GL_TEXTURE15 0x84CF
61 #define GL_TEXTURE16 0x84D0
62 #define GL_TEXTURE17 0x84D1
63 #define GL_TEXTURE18 0x84D2
64 #define GL_TEXTURE19 0x84D3
65 #define GL_TEXTURE20 0x84D4
66 #define GL_TEXTURE21 0x84D5
67 #define GL_TEXTURE22 0x84D6
68 #define GL_TEXTURE23 0x84D7
69 #define GL_TEXTURE24 0x84D8
70 #define GL_TEXTURE25 0x84D9
71 #define GL_TEXTURE26 0x84DA
72 #define GL_TEXTURE27 0x84DB
73 #define GL_TEXTURE28 0x84DC
74 #define GL_TEXTURE29 0x84DD
75 #define GL_TEXTURE30 0x84DE
76 #define GL_TEXTURE31 0x84DF
80 #define GL_TEXTURE_3D 0x806F
82 #ifndef GL_TEXTURE_CUBE_MAP
83 #define GL_TEXTURE_CUBE_MAP 0x8513
85 //#ifndef GL_MODELVIEW
86 //#define GL_MODELVIEW 0x1700
88 //#ifndef GL_PROJECTION
89 //#define GL_PROJECTION 0x1701
92 //#define GL_DECAL 0x2101
94 //#ifndef GL_INTERPOLATE
95 //#define GL_INTERPOLATE 0x8575
99 #define MAX_RENDERTARGETS 4
101 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
102 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)"};
103 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"};
104 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
105 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
107 cvar_t r_render = {0, "r_render", "1", "enables rendering 3D views (you want this on!)"};
108 cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
109 cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
110 cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
111 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
112 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)"};
113 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"};
114 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"};
115 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"};
117 cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
118 qboolean v_flipped_state = false;
120 r_viewport_t gl_viewport;
121 matrix4x4_t gl_modelmatrix;
122 matrix4x4_t gl_viewmatrix;
123 matrix4x4_t gl_modelviewmatrix;
124 matrix4x4_t gl_projectionmatrix;
125 matrix4x4_t gl_modelviewprojectionmatrix;
126 float gl_modelview16f[16];
127 float gl_modelviewprojection16f[16];
128 qboolean gl_modelmatrixchanged;
130 int gl_maxdrawrangeelementsvertices;
131 int gl_maxdrawrangeelementsindices;
136 void GL_PrintError(int errornumber, const char *filename, int linenumber)
140 #ifdef GL_INVALID_ENUM
141 case GL_INVALID_ENUM:
142 Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
145 #ifdef GL_INVALID_VALUE
146 case GL_INVALID_VALUE:
147 Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
150 #ifdef GL_INVALID_OPERATION
151 case GL_INVALID_OPERATION:
152 Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
155 #ifdef GL_STACK_OVERFLOW
156 case GL_STACK_OVERFLOW:
157 Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
160 #ifdef GL_STACK_UNDERFLOW
161 case GL_STACK_UNDERFLOW:
162 Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
165 #ifdef GL_OUT_OF_MEMORY
166 case GL_OUT_OF_MEMORY:
167 Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
170 #ifdef GL_TABLE_TOO_LARGE
171 case GL_TABLE_TOO_LARGE:
172 Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
175 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION
176 case GL_INVALID_FRAMEBUFFER_OPERATION:
177 Con_Printf("GL_INVALID_FRAMEBUFFER_OPERATION at %s:%i\n", filename, linenumber);
181 Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
187 #define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
189 void SCR_ScreenShot_f (void);
191 typedef struct gltextureunit_s
193 int pointer_texcoord_components;
194 int pointer_texcoord_gltype;
195 size_t pointer_texcoord_stride;
196 const void *pointer_texcoord_pointer;
197 const r_meshbuffer_t *pointer_texcoord_vertexbuffer;
198 size_t pointer_texcoord_offset;
201 int t2d, t3d, tcubemap;
203 int rgbscale, alphascale;
205 int combinergb, combinealpha;
206 // texmatrixenabled exists only to avoid unnecessary texmatrix compares
207 int texmatrixenabled;
212 typedef struct gl_state_s
220 int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order)
224 float polygonoffset[2];
227 float alphafuncvalue;
228 qboolean alphatocoverage;
231 unsigned int clientunit;
232 gltextureunit_t units[MAX_TEXTUREUNITS];
236 int vertexbufferobject;
237 int elementbufferobject;
238 int framebufferobject;
239 int defaultframebufferobject; // deal with platforms that use a non-zero default fbo
240 qboolean pointer_color_enabled;
242 int pointer_vertex_components;
243 int pointer_vertex_gltype;
244 size_t pointer_vertex_stride;
245 const void *pointer_vertex_pointer;
246 const r_meshbuffer_t *pointer_vertex_vertexbuffer;
247 size_t pointer_vertex_offset;
249 int pointer_color_components;
250 int pointer_color_gltype;
251 size_t pointer_color_stride;
252 const void *pointer_color_pointer;
253 const r_meshbuffer_t *pointer_color_vertexbuffer;
254 size_t pointer_color_offset;
256 void *preparevertices_tempdata;
257 size_t preparevertices_tempdatamaxsize;
258 r_meshbuffer_t *preparevertices_dynamicvertexbuffer;
259 r_vertexgeneric_t *preparevertices_vertexgeneric;
260 r_vertexmesh_t *preparevertices_vertexmesh;
261 int preparevertices_numvertices;
263 r_meshbuffer_t *draw_dynamicindexbuffer;
265 qboolean usevbo_staticvertex;
266 qboolean usevbo_staticindex;
267 qboolean usevbo_dynamicvertex;
268 qboolean usevbo_dynamicindex;
270 memexpandablearray_t meshbufferarray;
275 // rtexture_t *d3drt_depthtexture;
276 // rtexture_t *d3drt_colortextures[MAX_RENDERTARGETS];
277 IDirect3DSurface9 *d3drt_depthsurface;
278 IDirect3DSurface9 *d3drt_colorsurfaces[MAX_RENDERTARGETS];
279 IDirect3DSurface9 *d3drt_backbufferdepthsurface;
280 IDirect3DSurface9 *d3drt_backbuffercolorsurface;
281 void *d3dvertexbuffer;
283 size_t d3dvertexsize;
288 static gl_state_t gl_state;
292 note: here's strip order for a terrain row:
299 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
301 *elements++ = i + row;
303 *elements++ = i + row + 1;
306 *elements++ = i + row + 1;
309 for (y = 0;y < rows - 1;y++)
311 for (x = 0;x < columns - 1;x++)
314 *elements++ = i + columns;
316 *elements++ = i + columns + 1;
319 *elements++ = i + columns + 1;
330 for (y = 0;y < rows - 1;y++)
332 for (x = 0;x < columns - 1;x++)
336 *elements++ = i + columns;
337 *elements++ = i + columns + 1;
338 *elements++ = i + columns;
339 *elements++ = i + columns + 1;
345 int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
346 unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
347 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
348 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
350 static void GL_VBOStats_f(void)
352 GL_Mesh_ListVBOs(true);
355 static void GL_Backend_ResetState(void);
357 static void R_Mesh_InitVertexDeclarations(void);
358 static void R_Mesh_DestroyVertexDeclarations(void);
360 static void R_Mesh_SetUseVBO(void)
362 switch(vid.renderpath)
364 case RENDERPATH_GL11:
365 case RENDERPATH_GL13:
366 case RENDERPATH_GL20:
367 case RENDERPATH_GLES1:
368 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
369 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
370 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
371 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
373 case RENDERPATH_D3D9:
374 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
375 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
377 case RENDERPATH_D3D10:
378 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
380 case RENDERPATH_D3D11:
381 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
383 case RENDERPATH_SOFT:
384 gl_state.usevbo_staticvertex = false;
385 gl_state.usevbo_staticindex = false;
386 gl_state.usevbo_dynamicvertex = false;
387 gl_state.usevbo_dynamicindex = false;
389 case RENDERPATH_GLES2:
390 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
391 gl_state.usevbo_staticindex = false;
392 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
393 gl_state.usevbo_dynamicindex = false;
398 static void gl_backend_start(void)
400 memset(&gl_state, 0, sizeof(gl_state));
402 R_Mesh_InitVertexDeclarations();
405 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
407 Con_DPrintf("OpenGL backend started.\n");
411 GL_Backend_ResetState();
413 switch(vid.renderpath)
415 case RENDERPATH_GL11:
416 case RENDERPATH_GL13:
417 case RENDERPATH_GL20:
418 case RENDERPATH_GLES1:
419 case RENDERPATH_GLES2:
420 // fetch current fbo here (default fbo is not 0 on some GLES devices)
421 if (vid.support.ext_framebuffer_object)
422 qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);
424 case RENDERPATH_D3D9:
426 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
427 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
430 case RENDERPATH_D3D10:
431 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
433 case RENDERPATH_D3D11:
434 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
436 case RENDERPATH_SOFT:
441 static void gl_backend_shutdown(void)
443 Con_DPrint("OpenGL Backend shutting down\n");
445 switch(vid.renderpath)
447 case RENDERPATH_GL11:
448 case RENDERPATH_GL13:
449 case RENDERPATH_GL20:
450 case RENDERPATH_SOFT:
451 case RENDERPATH_GLES1:
452 case RENDERPATH_GLES2:
454 case RENDERPATH_D3D9:
456 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
457 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
460 case RENDERPATH_D3D10:
461 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
463 case RENDERPATH_D3D11:
464 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
468 if (gl_state.preparevertices_tempdata)
469 Mem_Free(gl_state.preparevertices_tempdata);
470 if (gl_state.preparevertices_dynamicvertexbuffer)
471 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
473 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
475 R_Mesh_DestroyVertexDeclarations();
477 memset(&gl_state, 0, sizeof(gl_state));
480 static void gl_backend_newmap(void)
484 static void gl_backend_devicelost(void)
487 r_meshbuffer_t *buffer;
489 gl_state.d3dvertexbuffer = NULL;
491 switch(vid.renderpath)
493 case RENDERPATH_GL11:
494 case RENDERPATH_GL13:
495 case RENDERPATH_GL20:
496 case RENDERPATH_SOFT:
497 case RENDERPATH_GLES1:
498 case RENDERPATH_GLES2:
500 case RENDERPATH_D3D9:
502 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
503 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
506 case RENDERPATH_D3D10:
507 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
509 case RENDERPATH_D3D11:
510 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
513 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
514 for (i = 0;i < endindex;i++)
516 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
517 if (!buffer || !buffer->isdynamic)
519 switch(vid.renderpath)
521 case RENDERPATH_GL11:
522 case RENDERPATH_GL13:
523 case RENDERPATH_GL20:
524 case RENDERPATH_SOFT:
525 case RENDERPATH_GLES1:
526 case RENDERPATH_GLES2:
528 case RENDERPATH_D3D9:
530 if (buffer->devicebuffer)
532 if (buffer->isindexbuffer)
533 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
535 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
536 buffer->devicebuffer = NULL;
540 case RENDERPATH_D3D10:
541 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
543 case RENDERPATH_D3D11:
544 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
550 static void gl_backend_devicerestored(void)
552 switch(vid.renderpath)
554 case RENDERPATH_GL11:
555 case RENDERPATH_GL13:
556 case RENDERPATH_GL20:
557 case RENDERPATH_SOFT:
558 case RENDERPATH_GLES1:
559 case RENDERPATH_GLES2:
561 case RENDERPATH_D3D9:
563 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
564 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
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__);
576 void gl_backend_init(void)
580 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
582 polygonelement3s[i * 3 + 0] = 0;
583 polygonelement3s[i * 3 + 1] = i + 1;
584 polygonelement3s[i * 3 + 2] = i + 2;
586 // elements for rendering a series of quads as triangles
587 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
589 quadelement3s[i * 6 + 0] = i * 4;
590 quadelement3s[i * 6 + 1] = i * 4 + 1;
591 quadelement3s[i * 6 + 2] = i * 4 + 2;
592 quadelement3s[i * 6 + 3] = i * 4;
593 quadelement3s[i * 6 + 4] = i * 4 + 2;
594 quadelement3s[i * 6 + 5] = i * 4 + 3;
597 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
598 polygonelement3i[i] = polygonelement3s[i];
599 for (i = 0;i < QUADELEMENTS_MAXQUADS*6;i++)
600 quadelement3i[i] = quadelement3s[i];
602 Cvar_RegisterVariable(&r_render);
603 Cvar_RegisterVariable(&r_renderview);
604 Cvar_RegisterVariable(&r_waterwarp);
605 Cvar_RegisterVariable(&gl_polyblend);
606 Cvar_RegisterVariable(&v_flipped);
607 Cvar_RegisterVariable(&gl_dither);
608 Cvar_RegisterVariable(&gl_vbo);
609 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
610 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
611 Cvar_RegisterVariable(&gl_paranoid);
612 Cvar_RegisterVariable(&gl_printcheckerror);
614 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
615 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
616 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
618 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");
620 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
623 void GL_SetMirrorState(qboolean state);
625 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
629 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
630 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
632 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
634 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
635 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
636 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
638 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
643 switch(vid.renderpath)
645 case RENDERPATH_GL11:
646 case RENDERPATH_GL13:
647 case RENDERPATH_GL20:
648 case RENDERPATH_GLES1:
649 case RENDERPATH_GLES2:
652 case RENDERPATH_D3D9:
653 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
655 case RENDERPATH_D3D10:
656 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
658 case RENDERPATH_D3D11:
659 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
661 case RENDERPATH_SOFT:
667 static int bboxedges[12][2] =
686 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
688 int i, ix1, iy1, ix2, iy2;
689 float x1, y1, x2, y2;
700 scissor[0] = r_refdef.view.viewport.x;
701 scissor[1] = r_refdef.view.viewport.y;
702 scissor[2] = r_refdef.view.viewport.width;
703 scissor[3] = r_refdef.view.viewport.height;
705 // if view is inside the box, just say yes it's visible
706 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
709 x1 = y1 = x2 = y2 = 0;
711 // transform all corners that are infront of the nearclip plane
712 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
713 plane4f[3] = r_refdef.view.frustum[4].dist;
715 for (i = 0;i < 8;i++)
717 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
718 dist[i] = DotProduct4(corner[i], plane4f);
719 sign[i] = dist[i] > 0;
722 VectorCopy(corner[i], vertex[numvertices]);
726 // if some points are behind the nearclip, add clipped edge points to make
727 // sure that the scissor boundary is complete
728 if (numvertices > 0 && numvertices < 8)
730 // add clipped edge points
731 for (i = 0;i < 12;i++)
735 if (sign[j] != sign[k])
737 f = dist[j] / (dist[j] - dist[k]);
738 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
744 // if we have no points to check, it is behind the view plane
748 // if we have some points to transform, check what screen area is covered
749 x1 = y1 = x2 = y2 = 0;
751 //Con_Printf("%i vertices to transform...\n", numvertices);
752 for (i = 0;i < numvertices;i++)
754 VectorCopy(vertex[i], v);
755 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
756 //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]);
759 if (x1 > v2[0]) x1 = v2[0];
760 if (x2 < v2[0]) x2 = v2[0];
761 if (y1 > v2[1]) y1 = v2[1];
762 if (y2 < v2[1]) y2 = v2[1];
771 // now convert the scissor rectangle to integer screen coordinates
772 ix1 = (int)(x1 - 1.0f);
773 //iy1 = vid.height - (int)(y2 - 1.0f);
774 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
775 iy1 = (int)(y1 - 1.0f);
776 ix2 = (int)(x2 + 1.0f);
777 //iy2 = vid.height - (int)(y1 + 1.0f);
778 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
779 iy2 = (int)(y2 + 1.0f);
780 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
782 // clamp it to the screen
783 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
784 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
785 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
786 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
788 // if it is inside out, it's not visible
789 if (ix2 <= ix1 || iy2 <= iy1)
792 // the light area is visible, set up the scissor rectangle
795 scissor[2] = ix2 - ix1;
796 scissor[3] = iy2 - iy1;
798 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
799 switch(vid.renderpath)
801 case RENDERPATH_D3D9:
802 case RENDERPATH_D3D10:
803 case RENDERPATH_D3D11:
804 scissor[1] = vid.height - scissor[1] - scissor[3];
806 case RENDERPATH_GL11:
807 case RENDERPATH_GL13:
808 case RENDERPATH_GL20:
809 case RENDERPATH_SOFT:
810 case RENDERPATH_GLES1:
811 case RENDERPATH_GLES2:
819 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
823 float clipPlane[4], v3[3], v4[3];
826 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
828 VectorSet(normal, normalx, normaly, normalz);
829 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
830 VectorScale(normal, -dist, v3);
831 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
832 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
833 clipPlane[3] = -DotProduct(v4, clipPlane);
837 // testing code for comparing results
839 VectorCopy4(clipPlane, clipPlane2);
840 R_EntityMatrix(&identitymatrix);
841 VectorSet(q, normal[0], normal[1], normal[2], -dist);
842 qglClipPlane(GL_CLIP_PLANE0, q);
843 qglGetClipPlane(GL_CLIP_PLANE0, q);
844 VectorCopy4(q, clipPlane);
848 // Calculate the clip-space corner point opposite the clipping plane
849 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
850 // transform it into camera space by multiplying it
851 // by the inverse of the projection matrix
852 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
853 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
855 q[3] = (1.0f + m[10]) / m[14];
857 // Calculate the scaled plane vector
858 d = 2.0f / DotProduct4(clipPlane, q);
860 // Replace the third row of the projection matrix
861 m[2] = clipPlane[0] * d;
862 m[6] = clipPlane[1] * d;
863 m[10] = clipPlane[2] * d + 1.0f;
864 m[14] = clipPlane[3] * d;
867 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)
869 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
871 memset(v, 0, sizeof(*v));
872 v->type = R_VIEWPORTTYPE_ORTHO;
873 v->cameramatrix = *cameramatrix;
880 memset(m, 0, sizeof(m));
881 m[0] = 2/(right - left);
882 m[5] = 2/(top - bottom);
883 m[10] = -2/(zFar - zNear);
884 m[12] = - (right + left)/(right - left);
885 m[13] = - (top + bottom)/(top - bottom);
886 m[14] = - (zFar + zNear)/(zFar - zNear);
888 switch(vid.renderpath)
890 case RENDERPATH_GL11:
891 case RENDERPATH_GL13:
892 case RENDERPATH_GL20:
893 case RENDERPATH_SOFT:
894 case RENDERPATH_GLES1:
895 case RENDERPATH_GLES2:
897 case RENDERPATH_D3D9:
898 case RENDERPATH_D3D10:
899 case RENDERPATH_D3D11:
900 m[10] = -1/(zFar - zNear);
901 m[14] = -zNear/(zFar-zNear);
904 v->screentodepth[0] = -farclip / (farclip - nearclip);
905 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
907 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
910 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
912 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
918 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
919 R_Viewport_TransformToScreen(v, test1, test2);
920 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
925 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)
927 matrix4x4_t tempmatrix, basematrix;
929 memset(v, 0, sizeof(*v));
931 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
932 v->cameramatrix = *cameramatrix;
939 memset(m, 0, sizeof(m));
940 m[0] = 1.0 / frustumx;
941 m[5] = 1.0 / frustumy;
942 m[10] = -(farclip + nearclip) / (farclip - nearclip);
944 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
945 v->screentodepth[0] = -farclip / (farclip - nearclip);
946 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
948 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
949 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
950 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
951 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
954 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
956 if(v_flipped.integer)
964 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
967 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)
969 matrix4x4_t tempmatrix, basematrix;
970 const float nudge = 1.0 - 1.0 / (1<<23);
972 memset(v, 0, sizeof(*v));
974 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
975 v->cameramatrix = *cameramatrix;
982 memset(m, 0, sizeof(m));
983 m[ 0] = 1.0 / frustumx;
984 m[ 5] = 1.0 / frustumy;
987 m[14] = -2 * nearclip * nudge;
988 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
989 v->screentodepth[1] = m[14] * -0.5;
991 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
992 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
993 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
994 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
997 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
999 if(v_flipped.integer)
1007 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1010 float cubeviewmatrix[6][16] =
1012 // standard cubemap projections
1050 float rectviewmatrix[6][16] =
1052 // sign-preserving cubemap projections
1091 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
1093 matrix4x4_t tempmatrix, basematrix;
1095 memset(v, 0, sizeof(*v));
1096 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1097 v->cameramatrix = *cameramatrix;
1101 memset(m, 0, sizeof(m));
1103 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1105 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1107 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
1108 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1109 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1112 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1114 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1117 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)
1119 matrix4x4_t tempmatrix, basematrix;
1121 memset(v, 0, sizeof(*v));
1122 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1123 v->cameramatrix = *cameramatrix;
1124 v->x = (side & 1) * size;
1125 v->y = (side >> 1) * size;
1129 memset(m, 0, sizeof(m));
1130 m[0] = m[5] = 1.0f * ((float)size - border) / size;
1131 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1133 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1135 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
1136 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1137 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1139 switch(vid.renderpath)
1141 case RENDERPATH_GL20:
1142 case RENDERPATH_GL13:
1143 case RENDERPATH_GL11:
1144 case RENDERPATH_SOFT:
1145 case RENDERPATH_GLES1:
1146 case RENDERPATH_GLES2:
1148 case RENDERPATH_D3D9:
1151 case RENDERPATH_D3D10:
1152 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1154 case RENDERPATH_D3D11:
1155 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1160 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1162 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1165 void R_SetViewport(const r_viewport_t *v)
1170 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1171 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1173 // copy over the matrices to our state
1174 gl_viewmatrix = v->viewmatrix;
1175 gl_projectionmatrix = v->projectmatrix;
1177 switch(vid.renderpath)
1179 case RENDERPATH_GL13:
1180 case RENDERPATH_GL11:
1181 case RENDERPATH_GLES1:
1182 #ifdef GL_PROJECTION
1184 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1185 // Load the projection matrix into OpenGL
1186 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1187 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1188 qglLoadMatrixf(m);CHECKGLERROR
1189 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1192 case RENDERPATH_D3D9:
1195 D3DVIEWPORT9 d3dviewport;
1196 d3dviewport.X = gl_viewport.x;
1197 d3dviewport.Y = gl_viewport.y;
1198 d3dviewport.Width = gl_viewport.width;
1199 d3dviewport.Height = gl_viewport.height;
1200 d3dviewport.MinZ = gl_state.depthrange[0];
1201 d3dviewport.MaxZ = gl_state.depthrange[1];
1202 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1206 case RENDERPATH_D3D10:
1207 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1209 case RENDERPATH_D3D11:
1210 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1212 case RENDERPATH_SOFT:
1213 DPSOFTRAST_Viewport(v->x, v->y, v->width, v->height);
1215 case RENDERPATH_GL20:
1216 case RENDERPATH_GLES2:
1218 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1222 // force an update of the derived matrices
1223 gl_modelmatrixchanged = true;
1224 R_EntityMatrix(&gl_modelmatrix);
1227 void R_GetViewport(r_viewport_t *v)
1232 static void GL_BindVBO(int bufferobject)
1234 if (gl_state.vertexbufferobject != bufferobject)
1236 gl_state.vertexbufferobject = bufferobject;
1238 qglBindBufferARB(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
1242 static void GL_BindEBO(int bufferobject)
1244 if (gl_state.elementbufferobject != bufferobject)
1246 gl_state.elementbufferobject = bufferobject;
1248 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
1252 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1255 switch(vid.renderpath)
1257 case RENDERPATH_GL11:
1258 case RENDERPATH_GL13:
1259 case RENDERPATH_GL20:
1260 case RENDERPATH_GLES1:
1261 case RENDERPATH_GLES2:
1262 if (!vid.support.ext_framebuffer_object)
1264 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1265 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1266 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1267 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1268 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1269 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1270 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1272 case RENDERPATH_D3D9:
1273 case RENDERPATH_D3D10:
1274 case RENDERPATH_D3D11:
1276 case RENDERPATH_SOFT:
1282 void R_Mesh_DestroyFramebufferObject(int fbo)
1284 switch(vid.renderpath)
1286 case RENDERPATH_GL11:
1287 case RENDERPATH_GL13:
1288 case RENDERPATH_GL20:
1289 case RENDERPATH_GLES1:
1290 case RENDERPATH_GLES2:
1292 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1294 case RENDERPATH_D3D9:
1295 case RENDERPATH_D3D10:
1296 case RENDERPATH_D3D11:
1298 case RENDERPATH_SOFT:
1304 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1306 // 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)
1307 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)
1310 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1311 if (gl_state.d3drt_depthsurface != depthsurface)
1313 gl_state.d3drt_depthsurface = depthsurface;
1314 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1316 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1318 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1319 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1321 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1323 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1324 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1326 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1328 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1329 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1331 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1333 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1334 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1339 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1343 rtexture_t *textures[5];
1344 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1345 textures[4] = depthtexture;
1346 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1347 for (j = 0;j < 5;j++)
1349 for (i = 0;i < vid.teximageunits;i++)
1350 if (gl_state.units[i].texture == textures[j])
1351 R_Mesh_TexBind(i, NULL);
1352 // set up framebuffer object or render targets for the active rendering API
1353 switch(vid.renderpath)
1355 case RENDERPATH_GL11:
1356 case RENDERPATH_GL13:
1357 case RENDERPATH_GL20:
1358 case RENDERPATH_GLES1:
1359 case RENDERPATH_GLES2:
1360 if (gl_state.framebufferobject != fbo)
1362 gl_state.framebufferobject = fbo;
1363 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1366 case RENDERPATH_D3D9:
1368 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1369 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1372 IDirect3DSurface9 *colorsurfaces[4];
1373 for (i = 0;i < 4;i++)
1375 colorsurfaces[i] = NULL;
1377 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1379 // set the render targets for real
1380 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1381 // release the texture surface levels (they won't be lost while bound...)
1382 for (i = 0;i < 4;i++)
1384 IDirect3DSurface9_Release(colorsurfaces[i]);
1387 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1390 case RENDERPATH_D3D10:
1391 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1393 case RENDERPATH_D3D11:
1394 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1396 case RENDERPATH_SOFT:
1400 unsigned int *pointers[5];
1401 memset(pointers, 0, sizeof(pointers));
1402 for (i = 0;i < 5;i++)
1403 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1404 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1405 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1406 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1409 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1415 static int d3dcmpforglfunc(int f)
1419 case GL_NEVER: return D3DCMP_NEVER;
1420 case GL_LESS: return D3DCMP_LESS;
1421 case GL_EQUAL: return D3DCMP_EQUAL;
1422 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1423 case GL_GREATER: return D3DCMP_GREATER;
1424 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1425 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1426 case GL_ALWAYS: return D3DCMP_ALWAYS;
1427 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1431 static int d3dstencilopforglfunc(int f)
1435 case GL_KEEP: return D3DSTENCILOP_KEEP;
1436 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1437 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1438 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1443 extern cvar_t r_transparent_alphatocoverage;
1445 static void GL_Backend_ResetState(void)
1448 gl_state.active = true;
1449 gl_state.depthtest = true;
1450 gl_state.alphatest = false;
1451 gl_state.alphafunc = GL_GEQUAL;
1452 gl_state.alphafuncvalue = 0.5f;
1453 gl_state.alphatocoverage = false;
1454 gl_state.blendfunc1 = GL_ONE;
1455 gl_state.blendfunc2 = GL_ZERO;
1456 gl_state.blend = false;
1457 gl_state.depthmask = GL_TRUE;
1458 gl_state.colormask = 15;
1459 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1460 gl_state.lockrange_first = 0;
1461 gl_state.lockrange_count = 0;
1462 gl_state.cullface = GL_FRONT;
1463 gl_state.cullfaceenable = false;
1464 gl_state.polygonoffset[0] = 0;
1465 gl_state.polygonoffset[1] = 0;
1466 gl_state.framebufferobject = 0;
1467 gl_state.depthfunc = GL_LEQUAL;
1469 switch(vid.renderpath)
1471 case RENDERPATH_D3D9:
1474 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1475 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1476 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1477 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1478 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1479 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1480 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1484 case RENDERPATH_D3D10:
1485 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1487 case RENDERPATH_D3D11:
1488 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1490 case RENDERPATH_GL11:
1491 case RENDERPATH_GL13:
1492 case RENDERPATH_GLES1:
1493 #ifdef GL_ALPHA_TEST
1496 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1497 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1498 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1499 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1500 qglDisable(GL_BLEND);CHECKGLERROR
1501 qglCullFace(gl_state.cullface);CHECKGLERROR
1502 qglDisable(GL_CULL_FACE);CHECKGLERROR
1503 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1504 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1505 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1506 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1508 if (vid.support.arb_vertex_buffer_object)
1510 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1511 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1514 if (vid.support.ext_framebuffer_object)
1516 //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
1517 qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
1520 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1521 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1523 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1524 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1525 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1527 if (vid.support.ext_framebuffer_object)
1528 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
1530 gl_state.unit = MAX_TEXTUREUNITS;
1531 gl_state.clientunit = MAX_TEXTUREUNITS;
1532 for (i = 0;i < vid.texunits;i++)
1534 GL_ActiveTexture(i);
1535 GL_ClientActiveTexture(i);
1536 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1537 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1538 if (vid.support.ext_texture_3d)
1540 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1541 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1543 if (vid.support.arb_texture_cube_map)
1545 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
1546 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1549 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1550 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1551 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1552 qglLoadIdentity();CHECKGLERROR
1553 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1554 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1559 case RENDERPATH_SOFT:
1560 DPSOFTRAST_ColorMask(1,1,1,1);
1561 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1562 DPSOFTRAST_CullFace(gl_state.cullface);
1563 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1564 DPSOFTRAST_DepthMask(gl_state.depthmask);
1565 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1566 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1567 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1569 case RENDERPATH_GL20:
1570 case RENDERPATH_GLES2:
1572 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1573 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1574 qglDisable(GL_BLEND);CHECKGLERROR
1575 qglCullFace(gl_state.cullface);CHECKGLERROR
1576 qglDisable(GL_CULL_FACE);CHECKGLERROR
1577 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1578 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1579 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1580 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1581 if (vid.support.arb_vertex_buffer_object)
1583 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1584 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1586 if (vid.support.ext_framebuffer_object)
1587 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1588 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1589 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1590 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1591 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1592 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1593 gl_state.unit = MAX_TEXTUREUNITS;
1594 gl_state.clientunit = MAX_TEXTUREUNITS;
1595 for (i = 0;i < vid.teximageunits;i++)
1597 GL_ActiveTexture(i);
1598 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1599 if (vid.support.ext_texture_3d)
1601 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1603 if (vid.support.arb_texture_cube_map)
1605 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1608 for (i = 0;i < vid.texarrayunits;i++)
1611 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1612 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1619 void GL_ActiveTexture(unsigned int num)
1621 if (gl_state.unit != num)
1623 gl_state.unit = num;
1624 switch(vid.renderpath)
1626 case RENDERPATH_GL11:
1627 case RENDERPATH_GL13:
1628 case RENDERPATH_GL20:
1629 case RENDERPATH_GLES1:
1630 case RENDERPATH_GLES2:
1631 if (qglActiveTexture)
1634 qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
1638 case RENDERPATH_D3D9:
1639 case RENDERPATH_D3D10:
1640 case RENDERPATH_D3D11:
1642 case RENDERPATH_SOFT:
1648 void GL_ClientActiveTexture(unsigned int num)
1650 if (gl_state.clientunit != num)
1652 gl_state.clientunit = num;
1653 switch(vid.renderpath)
1655 case RENDERPATH_GL11:
1656 case RENDERPATH_GL13:
1657 case RENDERPATH_GLES1:
1658 if (qglActiveTexture)
1661 qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit);
1665 case RENDERPATH_D3D9:
1666 case RENDERPATH_D3D10:
1667 case RENDERPATH_D3D11:
1669 case RENDERPATH_SOFT:
1671 case RENDERPATH_GL20:
1672 case RENDERPATH_GLES2:
1678 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1680 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1682 qboolean blendenable;
1683 gl_state.blendfunc1 = blendfunc1;
1684 gl_state.blendfunc2 = blendfunc2;
1685 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1686 switch(vid.renderpath)
1688 case RENDERPATH_GL11:
1689 case RENDERPATH_GL13:
1690 case RENDERPATH_GL20:
1691 case RENDERPATH_GLES1:
1692 case RENDERPATH_GLES2:
1694 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1695 if (gl_state.blend != blendenable)
1697 gl_state.blend = blendenable;
1698 if (!gl_state.blend)
1700 qglDisable(GL_BLEND);CHECKGLERROR
1704 qglEnable(GL_BLEND);CHECKGLERROR
1708 case RENDERPATH_D3D9:
1713 D3DBLEND d3dblendfunc[2];
1714 glblendfunc[0] = gl_state.blendfunc1;
1715 glblendfunc[1] = gl_state.blendfunc2;
1716 for (i = 0;i < 2;i++)
1718 switch(glblendfunc[i])
1720 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1721 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1722 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1723 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1724 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1725 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1726 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1727 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1728 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1729 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1732 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1733 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1734 if (gl_state.blend != blendenable)
1736 gl_state.blend = blendenable;
1737 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1742 case RENDERPATH_D3D10:
1743 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1745 case RENDERPATH_D3D11:
1746 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1748 case RENDERPATH_SOFT:
1749 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1755 void GL_DepthMask(int state)
1757 if (gl_state.depthmask != state)
1759 gl_state.depthmask = state;
1760 switch(vid.renderpath)
1762 case RENDERPATH_GL11:
1763 case RENDERPATH_GL13:
1764 case RENDERPATH_GL20:
1765 case RENDERPATH_GLES1:
1766 case RENDERPATH_GLES2:
1768 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1770 case RENDERPATH_D3D9:
1772 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1775 case RENDERPATH_D3D10:
1776 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1778 case RENDERPATH_D3D11:
1779 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1781 case RENDERPATH_SOFT:
1782 DPSOFTRAST_DepthMask(gl_state.depthmask);
1788 void GL_DepthTest(int state)
1790 if (gl_state.depthtest != state)
1792 gl_state.depthtest = state;
1793 switch(vid.renderpath)
1795 case RENDERPATH_GL11:
1796 case RENDERPATH_GL13:
1797 case RENDERPATH_GL20:
1798 case RENDERPATH_GLES1:
1799 case RENDERPATH_GLES2:
1801 if (gl_state.depthtest)
1803 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1807 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1810 case RENDERPATH_D3D9:
1812 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1815 case RENDERPATH_D3D10:
1816 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1818 case RENDERPATH_D3D11:
1819 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1821 case RENDERPATH_SOFT:
1822 DPSOFTRAST_DepthTest(gl_state.depthtest);
1828 void GL_DepthFunc(int state)
1830 if (gl_state.depthfunc != state)
1832 gl_state.depthfunc = state;
1833 switch(vid.renderpath)
1835 case RENDERPATH_GL11:
1836 case RENDERPATH_GL13:
1837 case RENDERPATH_GL20:
1838 case RENDERPATH_GLES1:
1839 case RENDERPATH_GLES2:
1841 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1843 case RENDERPATH_D3D9:
1845 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1848 case RENDERPATH_D3D10:
1849 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1851 case RENDERPATH_D3D11:
1852 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1854 case RENDERPATH_SOFT:
1855 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1861 void GL_DepthRange(float nearfrac, float farfrac)
1863 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1865 gl_state.depthrange[0] = nearfrac;
1866 gl_state.depthrange[1] = farfrac;
1867 switch(vid.renderpath)
1869 case RENDERPATH_GL11:
1870 case RENDERPATH_GL13:
1871 case RENDERPATH_GL20:
1872 case RENDERPATH_GLES1:
1873 case RENDERPATH_GLES2:
1875 qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
1877 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1880 case RENDERPATH_D3D9:
1883 D3DVIEWPORT9 d3dviewport;
1884 d3dviewport.X = gl_viewport.x;
1885 d3dviewport.Y = gl_viewport.y;
1886 d3dviewport.Width = gl_viewport.width;
1887 d3dviewport.Height = gl_viewport.height;
1888 d3dviewport.MinZ = gl_state.depthrange[0];
1889 d3dviewport.MaxZ = gl_state.depthrange[1];
1890 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1894 case RENDERPATH_D3D10:
1895 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1897 case RENDERPATH_D3D11:
1898 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1900 case RENDERPATH_SOFT:
1901 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1907 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)
1909 switch (vid.renderpath)
1911 case RENDERPATH_GL11:
1912 case RENDERPATH_GL13:
1913 case RENDERPATH_GL20:
1914 case RENDERPATH_GLES1:
1915 case RENDERPATH_GLES2:
1919 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1923 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1925 if (vid.support.ati_separate_stencil)
1927 qglStencilMask(writemask);CHECKGLERROR
1928 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1929 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1930 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1932 else if (vid.support.ext_stencil_two_side)
1934 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1935 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1936 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1937 qglStencilMask(writemask);CHECKGLERROR
1938 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1939 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1940 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1941 qglStencilMask(writemask);CHECKGLERROR
1942 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1943 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1947 case RENDERPATH_D3D9:
1949 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1950 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1951 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1952 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1953 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1954 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1955 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1956 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1957 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1958 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1960 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1961 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1964 case RENDERPATH_D3D10:
1965 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1967 case RENDERPATH_D3D11:
1968 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1970 case RENDERPATH_SOFT:
1971 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1976 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1978 switch (vid.renderpath)
1980 case RENDERPATH_GL11:
1981 case RENDERPATH_GL13:
1982 case RENDERPATH_GL20:
1983 case RENDERPATH_GLES1:
1984 case RENDERPATH_GLES2:
1988 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1992 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1994 if (vid.support.ext_stencil_two_side)
1996 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1997 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2000 qglStencilMask(writemask);CHECKGLERROR
2001 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2002 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2005 case RENDERPATH_D3D9:
2007 if (vid.support.ati_separate_stencil)
2008 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2009 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2011 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2012 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2013 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2014 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2015 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2016 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2019 case RENDERPATH_D3D10:
2020 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2022 case RENDERPATH_D3D11:
2023 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2025 case RENDERPATH_SOFT:
2026 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2031 void GL_PolygonOffset(float planeoffset, float depthoffset)
2033 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2035 gl_state.polygonoffset[0] = planeoffset;
2036 gl_state.polygonoffset[1] = depthoffset;
2037 switch(vid.renderpath)
2039 case RENDERPATH_GL11:
2040 case RENDERPATH_GL13:
2041 case RENDERPATH_GL20:
2042 case RENDERPATH_GLES1:
2043 case RENDERPATH_GLES2:
2044 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2046 case RENDERPATH_D3D9:
2048 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2049 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2052 case RENDERPATH_D3D10:
2053 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2055 case RENDERPATH_D3D11:
2056 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2058 case RENDERPATH_SOFT:
2059 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2065 void GL_SetMirrorState(qboolean state)
2067 if (v_flipped_state != state)
2069 v_flipped_state = state;
2070 if (gl_state.cullface == GL_BACK)
2071 gl_state.cullface = GL_FRONT;
2072 else if (gl_state.cullface == GL_FRONT)
2073 gl_state.cullface = GL_BACK;
2076 switch(vid.renderpath)
2078 case RENDERPATH_GL11:
2079 case RENDERPATH_GL13:
2080 case RENDERPATH_GL20:
2081 case RENDERPATH_GLES1:
2082 case RENDERPATH_GLES2:
2083 qglCullFace(gl_state.cullface);CHECKGLERROR
2085 case RENDERPATH_D3D9:
2087 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2090 case RENDERPATH_D3D10:
2091 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2093 case RENDERPATH_D3D11:
2094 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2096 case RENDERPATH_SOFT:
2097 DPSOFTRAST_CullFace(gl_state.cullface);
2103 void GL_CullFace(int state)
2107 if(state == GL_FRONT)
2109 else if(state == GL_BACK)
2113 switch(vid.renderpath)
2115 case RENDERPATH_GL11:
2116 case RENDERPATH_GL13:
2117 case RENDERPATH_GL20:
2118 case RENDERPATH_GLES1:
2119 case RENDERPATH_GLES2:
2122 if (state != GL_NONE)
2124 if (!gl_state.cullfaceenable)
2126 gl_state.cullfaceenable = true;
2127 qglEnable(GL_CULL_FACE);CHECKGLERROR
2129 if (gl_state.cullface != state)
2131 gl_state.cullface = state;
2132 qglCullFace(gl_state.cullface);CHECKGLERROR
2137 if (gl_state.cullfaceenable)
2139 gl_state.cullfaceenable = false;
2140 qglDisable(GL_CULL_FACE);CHECKGLERROR
2144 case RENDERPATH_D3D9:
2146 if (gl_state.cullface != state)
2148 gl_state.cullface = state;
2149 switch(gl_state.cullface)
2152 gl_state.cullfaceenable = false;
2153 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2156 gl_state.cullfaceenable = true;
2157 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2160 gl_state.cullfaceenable = true;
2161 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2167 case RENDERPATH_D3D10:
2168 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2170 case RENDERPATH_D3D11:
2171 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2173 case RENDERPATH_SOFT:
2174 if (gl_state.cullface != state)
2176 gl_state.cullface = state;
2177 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2178 DPSOFTRAST_CullFace(gl_state.cullface);
2184 void GL_AlphaTest(int state)
2186 if (gl_state.alphatest != state)
2188 gl_state.alphatest = state;
2189 switch(vid.renderpath)
2191 case RENDERPATH_GL11:
2192 case RENDERPATH_GL13:
2193 case RENDERPATH_GLES1:
2194 #ifdef GL_ALPHA_TEST
2195 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2197 if (gl_state.alphatest)
2199 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2203 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2207 case RENDERPATH_D3D9:
2208 case RENDERPATH_D3D10:
2209 case RENDERPATH_D3D11:
2210 case RENDERPATH_SOFT:
2211 case RENDERPATH_GL20:
2212 case RENDERPATH_GLES2:
2218 void GL_AlphaToCoverage(qboolean state)
2220 if (gl_state.alphatocoverage != state)
2222 gl_state.alphatocoverage = state;
2223 switch(vid.renderpath)
2225 case RENDERPATH_GL11:
2226 case RENDERPATH_GL13:
2227 case RENDERPATH_GLES1:
2228 case RENDERPATH_GLES2:
2229 case RENDERPATH_D3D9:
2230 case RENDERPATH_D3D10:
2231 case RENDERPATH_D3D11:
2232 case RENDERPATH_SOFT:
2234 case RENDERPATH_GL20:
2235 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2236 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2238 if (gl_state.alphatocoverage)
2240 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2241 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2245 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2246 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2254 void GL_ColorMask(int r, int g, int b, int a)
2256 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2257 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2258 if (gl_state.colormask != state)
2260 gl_state.colormask = state;
2261 switch(vid.renderpath)
2263 case RENDERPATH_GL11:
2264 case RENDERPATH_GL13:
2265 case RENDERPATH_GL20:
2266 case RENDERPATH_GLES1:
2267 case RENDERPATH_GLES2:
2269 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2271 case RENDERPATH_D3D9:
2273 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2276 case RENDERPATH_D3D10:
2277 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2279 case RENDERPATH_D3D11:
2280 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2282 case RENDERPATH_SOFT:
2283 DPSOFTRAST_ColorMask(r, g, b, a);
2289 void GL_Color(float cr, float cg, float cb, float ca)
2291 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)
2293 gl_state.color4f[0] = cr;
2294 gl_state.color4f[1] = cg;
2295 gl_state.color4f[2] = cb;
2296 gl_state.color4f[3] = ca;
2297 switch(vid.renderpath)
2299 case RENDERPATH_GL11:
2300 case RENDERPATH_GL13:
2301 case RENDERPATH_GLES1:
2303 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2306 case RENDERPATH_D3D9:
2307 case RENDERPATH_D3D10:
2308 case RENDERPATH_D3D11:
2309 // no equivalent in D3D
2311 case RENDERPATH_SOFT:
2312 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2314 case RENDERPATH_GL20:
2315 case RENDERPATH_GLES2:
2316 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2322 void GL_Scissor (int x, int y, int width, int height)
2324 switch(vid.renderpath)
2326 case RENDERPATH_GL11:
2327 case RENDERPATH_GL13:
2328 case RENDERPATH_GL20:
2329 case RENDERPATH_GLES1:
2330 case RENDERPATH_GLES2:
2332 qglScissor(x, y,width,height);
2335 case RENDERPATH_D3D9:
2341 d3drect.right = x + width;
2342 d3drect.bottom = y + height;
2343 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2347 case RENDERPATH_D3D10:
2348 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2350 case RENDERPATH_D3D11:
2351 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2353 case RENDERPATH_SOFT:
2354 DPSOFTRAST_Scissor(x, y, width, height);
2359 void GL_ScissorTest(int state)
2361 if (gl_state.scissortest != state)
2363 gl_state.scissortest = state;
2364 switch(vid.renderpath)
2366 case RENDERPATH_GL11:
2367 case RENDERPATH_GL13:
2368 case RENDERPATH_GL20:
2369 case RENDERPATH_GLES1:
2370 case RENDERPATH_GLES2:
2372 if(gl_state.scissortest)
2373 qglEnable(GL_SCISSOR_TEST);
2375 qglDisable(GL_SCISSOR_TEST);
2378 case RENDERPATH_D3D9:
2380 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2383 case RENDERPATH_D3D10:
2384 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2386 case RENDERPATH_D3D11:
2387 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2389 case RENDERPATH_SOFT:
2390 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2396 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2398 static const float blackcolor[4] = {0, 0, 0, 0};
2399 // prevent warnings when trying to clear a buffer that does not exist
2401 colorvalue = blackcolor;
2404 mask &= ~GL_STENCIL_BUFFER_BIT;
2407 switch(vid.renderpath)
2409 case RENDERPATH_GL11:
2410 case RENDERPATH_GL13:
2411 case RENDERPATH_GL20:
2412 case RENDERPATH_GLES1:
2413 case RENDERPATH_GLES2:
2415 if (mask & GL_COLOR_BUFFER_BIT)
2417 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2419 if (mask & GL_DEPTH_BUFFER_BIT)
2422 qglClearDepthf(depthvalue);CHECKGLERROR
2424 qglClearDepth(depthvalue);CHECKGLERROR
2427 if (mask & GL_STENCIL_BUFFER_BIT)
2429 qglClearStencil(stencilvalue);CHECKGLERROR
2431 qglClear(mask);CHECKGLERROR
2433 case RENDERPATH_D3D9:
2435 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);
2438 case RENDERPATH_D3D10:
2439 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2441 case RENDERPATH_D3D11:
2442 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2444 case RENDERPATH_SOFT:
2445 if (mask & GL_COLOR_BUFFER_BIT)
2446 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2447 if (mask & GL_DEPTH_BUFFER_BIT)
2448 DPSOFTRAST_ClearDepth(depthvalue);
2453 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2455 switch(vid.renderpath)
2457 case RENDERPATH_GL11:
2458 case RENDERPATH_GL13:
2459 case RENDERPATH_GL20:
2460 case RENDERPATH_GLES1:
2461 case RENDERPATH_GLES2:
2463 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2465 case RENDERPATH_D3D9:
2468 // LordHavoc: we can't directly download the backbuffer because it may be
2469 // multisampled, and it may not be lockable, so we blit it to a lockable
2470 // surface of the same dimensions (but without multisample) to resolve the
2471 // multisample buffer to a normal image, and then lock that...
2472 IDirect3DSurface9 *stretchsurface = NULL;
2473 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2475 D3DLOCKED_RECT lockedrect;
2476 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2478 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2481 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2482 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2483 memcpy(outpixels + line * width * 4, row, width * 4);
2484 IDirect3DSurface9_UnlockRect(stretchsurface);
2487 IDirect3DSurface9_Release(stretchsurface);
2490 //IDirect3DSurface9 *syssurface = NULL;
2491 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2492 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2493 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2494 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2495 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2496 //IDirect3DSurface9_UnlockRect(syssurface);
2497 //IDirect3DSurface9_Release(syssurface);
2501 case RENDERPATH_D3D10:
2502 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2504 case RENDERPATH_D3D11:
2505 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2507 case RENDERPATH_SOFT:
2508 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2513 // called at beginning of frame
2514 void R_Mesh_Start(void)
2517 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
2519 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2521 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2522 Cvar_SetValueQuick(&gl_paranoid, 1);
2526 static qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2530 char compilelog[MAX_INPUTLINE];
2531 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2534 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2535 qglCompileShader(shaderobject);CHECKGLERROR
2536 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2537 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2538 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2540 int i, j, pretextlines = 0;
2541 for (i = 0;i < numstrings - 1;i++)
2542 for (j = 0;strings[i][j];j++)
2543 if (strings[i][j] == '\n')
2545 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2547 if (!shadercompiled)
2549 qglDeleteShader(shaderobject);CHECKGLERROR
2552 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2553 qglDeleteShader(shaderobject);CHECKGLERROR
2557 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)
2559 GLint programlinked;
2560 GLuint programobject = 0;
2561 char linklog[MAX_INPUTLINE];
2564 programobject = qglCreateProgram();CHECKGLERROR
2568 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2569 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2570 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2571 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2572 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2573 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2574 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2575 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2576 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2577 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2579 if(vid.support.gl20shaders130)
2580 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2583 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2586 #ifdef GL_GEOMETRY_SHADER
2587 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2591 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2594 qglLinkProgram(programobject);CHECKGLERROR
2595 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2596 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2599 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2600 Con_DPrintf("program link log:\n%s\n", linklog);
2601 // software vertex shader is ok but software fragment shader is WAY
2602 // too slow, fail program if so.
2603 // NOTE: this string might be ATI specific, but that's ok because the
2604 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2605 // software fragment shader due to low instruction and dependent
2607 if (strstr(linklog, "fragment shader will run in software"))
2608 programlinked = false;
2612 return programobject;
2614 qglDeleteProgram(programobject);CHECKGLERROR
2618 void GL_Backend_FreeProgram(unsigned int prog)
2621 qglDeleteProgram(prog);
2625 // renders triangles using vertices from the active arrays
2626 int paranoidblah = 0;
2627 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)
2629 unsigned int numelements = numtriangles * 3;
2631 size_t bufferoffset3i;
2633 size_t bufferoffset3s;
2634 if (numvertices < 3 || numtriangles < 1)
2636 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2637 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);
2640 if (!gl_mesh_prefer_short_elements.integer)
2644 if (element3i_indexbuffer)
2645 element3i_indexbuffer = NULL;
2647 // adjust the pointers for firsttriangle
2649 element3i += firsttriangle * 3;
2650 if (element3i_indexbuffer)
2651 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2653 element3s += firsttriangle * 3;
2654 if (element3s_indexbuffer)
2655 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2656 switch(vid.renderpath)
2658 case RENDERPATH_GL11:
2659 case RENDERPATH_GL13:
2660 case RENDERPATH_GL20:
2661 case RENDERPATH_GLES1:
2662 case RENDERPATH_GLES2:
2663 // check if the user specified to ignore static index buffers
2664 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2666 element3i_indexbuffer = NULL;
2667 element3s_indexbuffer = NULL;
2670 case RENDERPATH_D3D9:
2671 case RENDERPATH_D3D10:
2672 case RENDERPATH_D3D11:
2674 case RENDERPATH_SOFT:
2677 // upload a dynamic index buffer if needed
2680 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2682 if (gl_state.draw_dynamicindexbuffer)
2683 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2685 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2686 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2687 element3s_bufferoffset = 0;
2692 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2694 if (gl_state.draw_dynamicindexbuffer)
2695 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2697 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2698 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2699 element3i_bufferoffset = 0;
2702 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2703 bufferoffset3i = element3i_bufferoffset;
2704 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2705 bufferoffset3s = element3s_bufferoffset;
2706 r_refdef.stats.draws++;
2707 r_refdef.stats.draws_vertices += numvertices;
2708 r_refdef.stats.draws_elements += numelements;
2709 if (gl_paranoid.integer)
2712 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2714 unsigned int j, size;
2716 // note: there's no validation done here on buffer objects because it
2717 // is somewhat difficult to get at the data, and gl_paranoid can be
2718 // used without buffer objects if the need arises
2719 // (the data could be gotten using glMapBuffer but it would be very
2720 // slow due to uncachable video memory reads)
2721 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2722 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2724 if (gl_state.pointer_vertex_pointer)
2725 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2727 if (gl_state.pointer_color_enabled)
2729 if (!qglIsEnabled(GL_COLOR_ARRAY))
2730 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2732 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2733 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2736 for (i = 0;i < vid.texarrayunits;i++)
2738 if (gl_state.units[i].arrayenabled)
2740 GL_ClientActiveTexture(i);
2741 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2742 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2744 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2745 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++)
2752 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2754 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2756 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2763 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2765 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2767 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2773 if (r_render.integer || r_refdef.draw2dstage)
2775 switch(vid.renderpath)
2777 case RENDERPATH_GL11:
2778 case RENDERPATH_GL13:
2779 case RENDERPATH_GL20:
2781 if (gl_mesh_testmanualfeeding.integer)
2784 unsigned int i, j, element;
2786 qglBegin(GL_TRIANGLES);
2787 if(vid.renderpath == RENDERPATH_GL20)
2789 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2792 element = element3i[i];
2794 element = element3s[i];
2796 element = firstvertex + i;
2797 for (j = 0;j < vid.texarrayunits;j++)
2799 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2801 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2803 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2804 if (gl_state.units[j].pointer_texcoord_components == 4)
2805 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2806 else if (gl_state.units[j].pointer_texcoord_components == 3)
2807 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2808 else if (gl_state.units[j].pointer_texcoord_components == 2)
2809 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2811 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2813 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2815 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2816 if (gl_state.units[j].pointer_texcoord_components == 4)
2817 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2818 else if (gl_state.units[j].pointer_texcoord_components == 3)
2819 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2820 else if (gl_state.units[j].pointer_texcoord_components == 2)
2821 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2822 else if (gl_state.units[j].pointer_texcoord_components == 1)
2823 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2825 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2827 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2828 if (gl_state.units[j].pointer_texcoord_components == 4)
2829 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2830 else if (gl_state.units[j].pointer_texcoord_components == 3)
2831 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2832 else if (gl_state.units[j].pointer_texcoord_components == 2)
2833 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2834 else if (gl_state.units[j].pointer_texcoord_components == 1)
2835 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2839 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2841 if (gl_state.pointer_color_gltype == GL_FLOAT)
2843 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2844 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2846 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2848 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2849 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2852 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2854 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2855 if (gl_state.pointer_vertex_components == 4)
2856 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2857 else if (gl_state.pointer_vertex_components == 3)
2858 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2860 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2866 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2869 element = element3i[i];
2871 element = element3s[i];
2873 element = firstvertex + i;
2874 for (j = 0;j < vid.texarrayunits;j++)
2876 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2878 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2880 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2881 if (vid.texarrayunits > 1)
2883 if (gl_state.units[j].pointer_texcoord_components == 4)
2884 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2885 else if (gl_state.units[j].pointer_texcoord_components == 3)
2886 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2887 else if (gl_state.units[j].pointer_texcoord_components == 2)
2888 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2890 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2894 if (gl_state.units[j].pointer_texcoord_components == 4)
2895 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2896 else if (gl_state.units[j].pointer_texcoord_components == 3)
2897 qglTexCoord3f(p[0], p[1], p[2]);
2898 else if (gl_state.units[j].pointer_texcoord_components == 2)
2899 qglTexCoord2f(p[0], p[1]);
2901 qglTexCoord1f(p[0]);
2904 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2906 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2907 if (vid.texarrayunits > 1)
2909 if (gl_state.units[j].pointer_texcoord_components == 4)
2910 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2911 else if (gl_state.units[j].pointer_texcoord_components == 3)
2912 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2913 else if (gl_state.units[j].pointer_texcoord_components == 2)
2914 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2915 else if (gl_state.units[j].pointer_texcoord_components == 1)
2916 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2920 if (gl_state.units[j].pointer_texcoord_components == 4)
2921 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2922 else if (gl_state.units[j].pointer_texcoord_components == 3)
2923 qglTexCoord3f(s[0], s[1], s[2]);
2924 else if (gl_state.units[j].pointer_texcoord_components == 2)
2925 qglTexCoord2f(s[0], s[1]);
2926 else if (gl_state.units[j].pointer_texcoord_components == 1)
2927 qglTexCoord1f(s[0]);
2930 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2932 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2933 if (vid.texarrayunits > 1)
2935 if (gl_state.units[j].pointer_texcoord_components == 4)
2936 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2937 else if (gl_state.units[j].pointer_texcoord_components == 3)
2938 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2939 else if (gl_state.units[j].pointer_texcoord_components == 2)
2940 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2941 else if (gl_state.units[j].pointer_texcoord_components == 1)
2942 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2946 if (gl_state.units[j].pointer_texcoord_components == 4)
2947 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2948 else if (gl_state.units[j].pointer_texcoord_components == 3)
2949 qglTexCoord3f(sb[0], sb[1], sb[2]);
2950 else if (gl_state.units[j].pointer_texcoord_components == 2)
2951 qglTexCoord2f(sb[0], sb[1]);
2952 else if (gl_state.units[j].pointer_texcoord_components == 1)
2953 qglTexCoord1f(sb[0]);
2958 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2960 if (gl_state.pointer_color_gltype == GL_FLOAT)
2962 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2963 qglColor4f(p[0], p[1], p[2], p[3]);
2965 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2967 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2968 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2971 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2973 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2974 if (gl_state.pointer_vertex_components == 4)
2975 qglVertex4f(p[0], p[1], p[2], p[3]);
2976 else if (gl_state.pointer_vertex_components == 3)
2977 qglVertex3f(p[0], p[1], p[2]);
2979 qglVertex2f(p[0], p[1]);
2987 else if (bufferobject3s)
2989 GL_BindEBO(bufferobject3s);
2991 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2993 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2999 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3003 else if (bufferobject3i)
3005 GL_BindEBO(bufferobject3i);
3007 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3009 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3015 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3023 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3025 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3031 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3039 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3041 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3047 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3053 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3057 case RENDERPATH_D3D9:
3059 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3061 if (element3s_indexbuffer)
3063 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3064 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3066 else if (element3i_indexbuffer)
3068 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3069 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3072 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3077 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3079 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3081 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3085 case RENDERPATH_D3D10:
3086 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3088 case RENDERPATH_D3D11:
3089 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3091 case RENDERPATH_SOFT:
3092 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3094 case RENDERPATH_GLES1:
3095 case RENDERPATH_GLES2:
3096 // GLES does not have glDrawRangeElements, and generally
3097 // underperforms with index buffers, so this code path is
3098 // relatively straightforward...
3100 if (gl_paranoid.integer)
3102 int r, prog, enabled, i;
3103 GLsizei attriblength;
3106 GLchar attribname[1024];
3107 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3108 if (r != GL_FRAMEBUFFER_COMPLETE)
3109 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3110 #ifndef GL_CURRENT_PROGRAM
3111 #define GL_CURRENT_PROGRAM 0x8B8D
3113 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3114 if (r < 0 || r > 10000)
3115 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3117 for (i = 0;i < 8;i++)
3119 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3122 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3123 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);
3129 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3134 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3139 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3147 // restores backend state, used when done with 3D rendering
3148 void R_Mesh_Finish(void)
3150 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
3153 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3155 r_meshbuffer_t *buffer;
3156 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3158 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3159 memset(buffer, 0, sizeof(*buffer));
3160 buffer->bufferobject = 0;
3161 buffer->devicebuffer = NULL;
3163 buffer->isindexbuffer = isindexbuffer;
3164 buffer->isdynamic = isdynamic;
3165 buffer->isindex16 = isindex16;
3166 strlcpy(buffer->name, name, sizeof(buffer->name));
3167 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3171 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3175 if (buffer->isindexbuffer)
3177 r_refdef.stats.indexbufferuploadcount++;
3178 r_refdef.stats.indexbufferuploadsize += size;
3182 r_refdef.stats.vertexbufferuploadcount++;
3183 r_refdef.stats.vertexbufferuploadsize += size;
3185 switch(vid.renderpath)
3187 case RENDERPATH_GL11:
3188 case RENDERPATH_GL13:
3189 case RENDERPATH_GL20:
3190 case RENDERPATH_GLES1:
3191 case RENDERPATH_GLES2:
3192 if (!buffer->bufferobject)
3193 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3194 if (buffer->isindexbuffer)
3195 GL_BindEBO(buffer->bufferobject);
3197 GL_BindVBO(buffer->bufferobject);
3198 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3200 case RENDERPATH_D3D9:
3204 void *datapointer = NULL;
3205 if (buffer->isindexbuffer)
3207 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3208 if (size > buffer->size || !buffer->devicebuffer)
3210 if (buffer->devicebuffer)
3211 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3212 buffer->devicebuffer = NULL;
3213 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)))
3214 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);
3215 buffer->devicebuffer = (void *)d3d9indexbuffer;
3216 buffer->size = size;
3218 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3221 memcpy(datapointer, data, size);
3223 memset(datapointer, 0, size);
3224 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3229 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3230 if (size > buffer->size || !buffer->devicebuffer)
3232 if (buffer->devicebuffer)
3233 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3234 buffer->devicebuffer = NULL;
3235 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3236 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);
3237 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3238 buffer->size = size;
3240 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3243 memcpy(datapointer, data, size);
3245 memset(datapointer, 0, size);
3246 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3252 case RENDERPATH_D3D10:
3253 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3255 case RENDERPATH_D3D11:
3256 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3258 case RENDERPATH_SOFT:
3263 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3267 switch(vid.renderpath)
3269 case RENDERPATH_GL11:
3270 case RENDERPATH_GL13:
3271 case RENDERPATH_GL20:
3272 case RENDERPATH_GLES1:
3273 case RENDERPATH_GLES2:
3274 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3276 case RENDERPATH_D3D9:
3278 if (gl_state.d3dvertexbuffer == (void *)buffer)
3279 gl_state.d3dvertexbuffer = NULL;
3280 if (buffer->devicebuffer)
3282 if (buffer->isindexbuffer)
3283 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3285 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3286 buffer->devicebuffer = NULL;
3290 case RENDERPATH_D3D10:
3291 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3293 case RENDERPATH_D3D11:
3294 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3296 case RENDERPATH_SOFT:
3299 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3302 void GL_Mesh_ListVBOs(qboolean printeach)
3305 size_t ebocount = 0, ebomemory = 0;
3306 size_t vbocount = 0, vbomemory = 0;
3307 r_meshbuffer_t *buffer;
3308 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3309 for (i = 0;i < endindex;i++)
3311 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3314 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)");}
3315 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)");}
3317 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);
3322 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3324 switch(vid.renderpath)
3326 case RENDERPATH_GL11:
3327 case RENDERPATH_GL13:
3328 case RENDERPATH_GLES1:
3329 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)
3331 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3332 gl_state.pointer_vertex_components = components;
3333 gl_state.pointer_vertex_gltype = gltype;
3334 gl_state.pointer_vertex_stride = stride;
3335 gl_state.pointer_vertex_pointer = pointer;
3336 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3337 gl_state.pointer_vertex_offset = bufferoffset;
3339 GL_BindVBO(bufferobject);
3340 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3343 case RENDERPATH_GL20:
3344 case RENDERPATH_GLES2:
3345 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)
3347 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3348 gl_state.pointer_vertex_components = components;
3349 gl_state.pointer_vertex_gltype = gltype;
3350 gl_state.pointer_vertex_stride = stride;
3351 gl_state.pointer_vertex_pointer = pointer;
3352 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3353 gl_state.pointer_vertex_offset = bufferoffset;
3355 GL_BindVBO(bufferobject);
3356 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3359 case RENDERPATH_D3D9:
3360 case RENDERPATH_D3D10:
3361 case RENDERPATH_D3D11:
3362 case RENDERPATH_SOFT:
3367 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3369 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3370 // the pointer only.
3371 switch(vid.renderpath)
3373 case RENDERPATH_GL11:
3374 case RENDERPATH_GL13:
3375 case RENDERPATH_GLES1:
3380 // caller wants color array enabled
3381 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3382 if (!gl_state.pointer_color_enabled)
3384 gl_state.pointer_color_enabled = true;
3386 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3388 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)
3390 gl_state.pointer_color_components = components;
3391 gl_state.pointer_color_gltype = gltype;
3392 gl_state.pointer_color_stride = stride;
3393 gl_state.pointer_color_pointer = pointer;
3394 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3395 gl_state.pointer_color_offset = bufferoffset;
3397 GL_BindVBO(bufferobject);
3398 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3403 // caller wants color array disabled
3404 if (gl_state.pointer_color_enabled)
3406 gl_state.pointer_color_enabled = false;
3408 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3409 // when color array is on the glColor gets trashed, set it again
3410 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3415 case RENDERPATH_GL20:
3416 case RENDERPATH_GLES2:
3420 // caller wants color array enabled
3421 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3422 if (!gl_state.pointer_color_enabled)
3424 gl_state.pointer_color_enabled = true;
3426 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3428 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)
3430 gl_state.pointer_color_components = components;
3431 gl_state.pointer_color_gltype = gltype;
3432 gl_state.pointer_color_stride = stride;
3433 gl_state.pointer_color_pointer = pointer;
3434 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3435 gl_state.pointer_color_offset = bufferoffset;
3437 GL_BindVBO(bufferobject);
3438 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3443 // caller wants color array disabled
3444 if (gl_state.pointer_color_enabled)
3446 gl_state.pointer_color_enabled = false;
3448 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3449 // when color array is on the glColor gets trashed, set it again
3450 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3454 case RENDERPATH_D3D9:
3455 case RENDERPATH_D3D10:
3456 case RENDERPATH_D3D11:
3457 case RENDERPATH_SOFT:
3462 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)
3464 gltextureunit_t *unit = gl_state.units + unitnum;
3465 // update array settings
3466 // note: there is no need to check bufferobject here because all cases
3467 // that involve a valid bufferobject also supply a texcoord array
3468 switch(vid.renderpath)
3470 case RENDERPATH_GL11:
3471 case RENDERPATH_GL13:
3472 case RENDERPATH_GLES1:
3477 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3478 // texture array unit is enabled, enable the array
3479 if (!unit->arrayenabled)
3481 unit->arrayenabled = true;
3482 GL_ClientActiveTexture(unitnum);
3483 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3486 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)
3488 unit->pointer_texcoord_components = components;
3489 unit->pointer_texcoord_gltype = gltype;
3490 unit->pointer_texcoord_stride = stride;
3491 unit->pointer_texcoord_pointer = pointer;
3492 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3493 unit->pointer_texcoord_offset = bufferoffset;
3494 GL_ClientActiveTexture(unitnum);
3495 GL_BindVBO(bufferobject);
3496 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3501 // texture array unit is disabled, disable the array
3502 if (unit->arrayenabled)
3504 unit->arrayenabled = false;
3505 GL_ClientActiveTexture(unitnum);
3506 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3511 case RENDERPATH_GL20:
3512 case RENDERPATH_GLES2:
3516 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3517 // texture array unit is enabled, enable the array
3518 if (!unit->arrayenabled)
3520 unit->arrayenabled = true;
3521 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3524 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)
3526 unit->pointer_texcoord_components = components;
3527 unit->pointer_texcoord_gltype = gltype;
3528 unit->pointer_texcoord_stride = stride;
3529 unit->pointer_texcoord_pointer = pointer;
3530 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3531 unit->pointer_texcoord_offset = bufferoffset;
3532 GL_BindVBO(bufferobject);
3533 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3538 // texture array unit is disabled, disable the array
3539 if (unit->arrayenabled)
3541 unit->arrayenabled = false;
3542 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3546 case RENDERPATH_D3D9:
3547 case RENDERPATH_D3D10:
3548 case RENDERPATH_D3D11:
3549 case RENDERPATH_SOFT:
3554 int R_Mesh_TexBound(unsigned int unitnum, int id)
3556 gltextureunit_t *unit = gl_state.units + unitnum;
3557 if (unitnum >= vid.teximageunits)
3559 if (id == GL_TEXTURE_2D)
3561 if (id == GL_TEXTURE_3D)
3563 if (id == GL_TEXTURE_CUBE_MAP)
3564 return unit->tcubemap;
3568 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3570 switch(vid.renderpath)
3572 case RENDERPATH_GL11:
3573 case RENDERPATH_GL13:
3574 case RENDERPATH_GL20:
3575 case RENDERPATH_GLES1:
3576 case RENDERPATH_GLES2:
3577 R_Mesh_TexBind(0, tex);
3578 GL_ActiveTexture(0);CHECKGLERROR
3579 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3581 case RENDERPATH_D3D9:
3584 IDirect3DSurface9 *currentsurface = NULL;
3585 IDirect3DSurface9 *texturesurface = NULL;
3588 sourcerect.left = sx;
3589 sourcerect.top = sy;
3590 sourcerect.right = sx + width;
3591 sourcerect.bottom = sy + height;
3594 destrect.right = tx + width;
3595 destrect.bottom = ty + height;
3596 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3598 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3600 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3601 IDirect3DSurface9_Release(currentsurface);
3603 IDirect3DSurface9_Release(texturesurface);
3608 case RENDERPATH_D3D10:
3609 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3611 case RENDERPATH_D3D11:
3612 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3614 case RENDERPATH_SOFT:
3615 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3621 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};
3624 void R_Mesh_ClearBindingsForTexture(int texnum)
3626 gltextureunit_t *unit;
3627 unsigned int unitnum;
3628 // 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)
3629 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3631 unit = gl_state.units + unitnum;
3632 if (unit->t2d == texnum)
3634 if (unit->t3d == texnum)
3636 if (unit->tcubemap == texnum)
3637 unit->tcubemap = -1;
3641 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3643 gltextureunit_t *unit = gl_state.units + unitnum;
3644 int tex2d, tex3d, texcubemap, texnum;
3645 if (unitnum >= vid.teximageunits)
3647 // if (unit->texture == tex)
3649 switch(vid.renderpath)
3651 case RENDERPATH_GL20:
3652 case RENDERPATH_GLES2:
3655 tex = r_texture_white;
3656 // not initialized enough yet...
3660 unit->texture = tex;
3661 texnum = R_GetTexture(tex);
3662 switch(tex->gltexturetypeenum)
3664 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3665 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3666 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3669 case RENDERPATH_GL11:
3670 case RENDERPATH_GL13:
3671 case RENDERPATH_GLES1:
3672 unit->texture = tex;
3678 texnum = R_GetTexture(tex);
3679 switch(tex->gltexturetypeenum)
3687 case GL_TEXTURE_CUBE_MAP:
3688 texcubemap = texnum;
3692 // update 2d texture binding
3693 if (unit->t2d != tex2d)
3695 GL_ActiveTexture(unitnum);
3700 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3707 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3711 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3713 // update 3d texture binding
3714 if (unit->t3d != tex3d)
3716 GL_ActiveTexture(unitnum);
3721 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3728 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3732 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3734 // update cubemap texture binding
3735 if (unit->tcubemap != texcubemap)
3737 GL_ActiveTexture(unitnum);
3740 if (unit->tcubemap == 0)
3742 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3749 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3752 unit->tcubemap = texcubemap;
3753 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3756 case RENDERPATH_D3D9:
3759 extern cvar_t gl_texture_anisotropy;
3762 tex = r_texture_white;
3763 // not initialized enough yet...
3767 // upload texture if needed
3769 if (unit->texture == tex)
3771 unit->texture = tex;
3772 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3773 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3774 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3775 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3776 if (tex->d3daddressw)
3777 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3778 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3779 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3780 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3781 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3782 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3783 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3787 case RENDERPATH_D3D10:
3788 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3790 case RENDERPATH_D3D11:
3791 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3793 case RENDERPATH_SOFT:
3796 tex = r_texture_white;
3797 // not initialized enough yet...
3801 texnum = R_GetTexture(tex);
3802 if (unit->texture == tex)
3804 unit->texture = tex;
3805 DPSOFTRAST_SetTexture(unitnum, texnum);
3810 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3812 gltextureunit_t *unit = gl_state.units + unitnum;
3813 switch(vid.renderpath)
3815 case RENDERPATH_GL11:
3816 case RENDERPATH_GL13:
3817 case RENDERPATH_GL20:
3818 case RENDERPATH_GLES1:
3819 case RENDERPATH_GLES2:
3821 if (matrix && matrix->m[3][3])
3823 // texmatrix specified, check if it is different
3824 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3827 unit->texmatrixenabled = true;
3828 unit->matrix = *matrix;
3830 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3831 GL_ActiveTexture(unitnum);
3832 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3833 qglLoadMatrixf(glmatrix);CHECKGLERROR
3834 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3839 // no texmatrix specified, revert to identity
3840 if (unit->texmatrixenabled)
3842 unit->texmatrixenabled = false;
3843 unit->matrix = identitymatrix;
3845 GL_ActiveTexture(unitnum);
3846 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3847 qglLoadIdentity();CHECKGLERROR
3848 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3853 case RENDERPATH_D3D9:
3854 case RENDERPATH_D3D10:
3855 case RENDERPATH_D3D11:
3857 case RENDERPATH_SOFT:
3862 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3864 gltextureunit_t *unit = gl_state.units + unitnum;
3866 switch(vid.renderpath)
3868 case RENDERPATH_GL20:
3869 case RENDERPATH_GLES2:
3872 case RENDERPATH_GL13:
3873 case RENDERPATH_GLES1:
3874 #ifdef GL_TEXTURE_ENV
3875 // GL_ARB_texture_env_combine
3877 combinergb = GL_MODULATE;
3879 combinealpha = GL_MODULATE;
3884 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3886 if (combinergb == GL_DECAL)
3887 combinergb = GL_INTERPOLATE;
3888 if (unit->combine != GL_COMBINE)
3890 unit->combine = GL_COMBINE;
3891 GL_ActiveTexture(unitnum);
3892 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3893 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3895 if (unit->combinergb != combinergb)
3897 unit->combinergb = combinergb;
3898 GL_ActiveTexture(unitnum);
3899 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3901 if (unit->combinealpha != combinealpha)
3903 unit->combinealpha = combinealpha;
3904 GL_ActiveTexture(unitnum);
3905 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3907 if (unit->rgbscale != rgbscale)
3909 unit->rgbscale = rgbscale;
3910 GL_ActiveTexture(unitnum);
3911 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3913 if (unit->alphascale != alphascale)
3915 unit->alphascale = alphascale;
3916 GL_ActiveTexture(unitnum);
3917 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3922 if (unit->combine != combinergb)
3924 unit->combine = combinergb;
3925 GL_ActiveTexture(unitnum);
3926 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3931 case RENDERPATH_GL11:
3933 #ifdef GL_TEXTURE_ENV
3935 combinergb = GL_MODULATE;
3936 if (unit->combine != combinergb)
3938 unit->combine = combinergb;
3939 GL_ActiveTexture(unitnum);
3940 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3944 case RENDERPATH_D3D9:
3945 case RENDERPATH_D3D10:
3946 case RENDERPATH_D3D11:
3948 case RENDERPATH_SOFT:
3953 void R_Mesh_ResetTextureState(void)
3955 unsigned int unitnum;
3959 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3960 R_Mesh_TexBind(unitnum, NULL);
3961 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3962 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3963 switch(vid.renderpath)
3965 case RENDERPATH_GL20:
3966 case RENDERPATH_GLES2:
3967 case RENDERPATH_D3D9:
3968 case RENDERPATH_D3D10:
3969 case RENDERPATH_D3D11:
3970 case RENDERPATH_SOFT:
3972 case RENDERPATH_GL11:
3973 case RENDERPATH_GL13:
3974 case RENDERPATH_GLES1:
3975 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3977 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3978 R_Mesh_TexMatrix(unitnum, NULL);
3987 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3988 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3989 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3991 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3993 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3997 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3999 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4000 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4001 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4005 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4007 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4008 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4009 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4010 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4011 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4012 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4013 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4017 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4018 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4019 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4022 static void R_Mesh_InitVertexDeclarations(void)
4025 r_vertex3f_d3d9decl = NULL;
4026 r_vertexgeneric_d3d9decl = NULL;
4027 r_vertexmesh_d3d9decl = NULL;
4028 switch(vid.renderpath)
4030 case RENDERPATH_GL20:
4031 case RENDERPATH_GL13:
4032 case RENDERPATH_GL11:
4033 case RENDERPATH_GLES1:
4034 case RENDERPATH_GLES2:
4036 case RENDERPATH_D3D9:
4037 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4038 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4039 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4041 case RENDERPATH_D3D10:
4042 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4044 case RENDERPATH_D3D11:
4045 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4047 case RENDERPATH_SOFT:
4053 static void R_Mesh_DestroyVertexDeclarations(void)
4056 if (r_vertex3f_d3d9decl)
4057 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4058 r_vertex3f_d3d9decl = NULL;
4059 if (r_vertexgeneric_d3d9decl)
4060 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4061 r_vertexgeneric_d3d9decl = NULL;
4062 if (r_vertexmesh_d3d9decl)
4063 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4064 r_vertexmesh_d3d9decl = NULL;
4068 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4070 // upload temporary vertexbuffer for this rendering
4071 if (!gl_state.usevbo_staticvertex)
4072 vertexbuffer = NULL;
4073 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4075 if (gl_state.preparevertices_dynamicvertexbuffer)
4076 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4078 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4079 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4081 switch(vid.renderpath)
4083 case RENDERPATH_GL20:
4084 case RENDERPATH_GLES2:
4087 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4088 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4089 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4090 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4091 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4092 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4093 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4097 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4098 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4099 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4100 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4101 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4102 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4103 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4106 case RENDERPATH_GL13:
4107 case RENDERPATH_GLES1:
4110 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4111 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4112 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4113 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4117 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4118 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4119 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4120 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4123 case RENDERPATH_GL11:
4126 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4127 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4128 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4132 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4133 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4134 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4137 case RENDERPATH_D3D9:
4139 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4141 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4143 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4144 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4145 gl_state.d3dvertexdata = (void *)vertex3f;
4146 gl_state.d3dvertexsize = sizeof(float[3]);
4149 case RENDERPATH_D3D10:
4150 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4152 case RENDERPATH_D3D11:
4153 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4155 case RENDERPATH_SOFT:
4156 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4157 DPSOFTRAST_SetColorPointer(NULL, 0);
4158 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4159 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4160 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4161 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4162 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4169 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4172 size = sizeof(r_vertexgeneric_t) * numvertices;
4173 if (gl_state.preparevertices_tempdatamaxsize < size)
4175 gl_state.preparevertices_tempdatamaxsize = size;
4176 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4178 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4179 gl_state.preparevertices_numvertices = numvertices;
4180 return gl_state.preparevertices_vertexgeneric;
4183 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4185 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4186 gl_state.preparevertices_vertexgeneric = NULL;
4187 gl_state.preparevertices_numvertices = 0;
4191 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4194 r_vertexgeneric_t *vertex;
4195 switch(vid.renderpath)
4197 case RENDERPATH_GL20:
4198 case RENDERPATH_GLES2:
4199 if (!vid.useinterleavedarrays)
4201 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4202 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4203 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4204 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4205 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4206 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4207 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4211 case RENDERPATH_GL11:
4212 case RENDERPATH_GL13:
4213 case RENDERPATH_GLES1:
4214 if (!vid.useinterleavedarrays)
4216 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4217 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4218 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4219 if (vid.texunits >= 2)
4220 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4221 if (vid.texunits >= 3)
4222 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4226 case RENDERPATH_D3D9:
4227 case RENDERPATH_D3D10:
4228 case RENDERPATH_D3D11:
4230 case RENDERPATH_SOFT:
4231 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4232 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4233 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4234 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4235 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4236 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4237 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4241 // no quick path for this case, convert to vertex structs
4242 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4243 for (i = 0;i < numvertices;i++)
4244 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4247 for (i = 0;i < numvertices;i++)
4248 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4252 for (i = 0;i < numvertices;i++)
4253 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4256 for (i = 0;i < numvertices;i++)
4257 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4258 R_Mesh_PrepareVertices_Generic_Unlock();
4259 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4262 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4264 // upload temporary vertexbuffer for this rendering
4265 if (!gl_state.usevbo_staticvertex)
4266 vertexbuffer = NULL;
4267 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4269 if (gl_state.preparevertices_dynamicvertexbuffer)
4270 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4272 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4273 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4275 switch(vid.renderpath)
4277 case RENDERPATH_GL20:
4278 case RENDERPATH_GLES2:
4281 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4282 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4283 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4284 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4285 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4286 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4287 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4291 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4292 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4293 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4294 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4295 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4296 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4297 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4300 case RENDERPATH_GL13:
4301 case RENDERPATH_GLES1:
4304 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4305 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4306 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4307 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4311 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4312 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4313 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4314 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4317 case RENDERPATH_GL11:
4320 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4321 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4322 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4326 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4327 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4328 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4331 case RENDERPATH_D3D9:
4333 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4335 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4337 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4338 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4339 gl_state.d3dvertexdata = (void *)vertex;
4340 gl_state.d3dvertexsize = sizeof(*vertex);
4343 case RENDERPATH_D3D10:
4344 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4346 case RENDERPATH_D3D11:
4347 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4349 case RENDERPATH_SOFT:
4350 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4351 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4352 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4353 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4354 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4355 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4356 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4363 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4366 size = sizeof(r_vertexmesh_t) * numvertices;
4367 if (gl_state.preparevertices_tempdatamaxsize < size)
4369 gl_state.preparevertices_tempdatamaxsize = size;
4370 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4372 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4373 gl_state.preparevertices_numvertices = numvertices;
4374 return gl_state.preparevertices_vertexmesh;
4377 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4379 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4380 gl_state.preparevertices_vertexmesh = NULL;
4381 gl_state.preparevertices_numvertices = 0;
4385 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)
4388 r_vertexmesh_t *vertex;
4389 switch(vid.renderpath)
4391 case RENDERPATH_GL20:
4392 case RENDERPATH_GLES2:
4393 if (!vid.useinterleavedarrays)
4395 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4396 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4397 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4398 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4399 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4400 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4401 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4405 case RENDERPATH_GL11:
4406 case RENDERPATH_GL13:
4407 case RENDERPATH_GLES1:
4408 if (!vid.useinterleavedarrays)
4410 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4411 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4412 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4413 if (vid.texunits >= 2)
4414 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4415 if (vid.texunits >= 3)
4416 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4420 case RENDERPATH_D3D9:
4421 case RENDERPATH_D3D10:
4422 case RENDERPATH_D3D11:
4424 case RENDERPATH_SOFT:
4425 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4426 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4427 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4428 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4429 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4430 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4431 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4435 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4436 for (i = 0;i < numvertices;i++)
4437 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4439 for (i = 0;i < numvertices;i++)
4440 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4442 for (i = 0;i < numvertices;i++)
4443 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4445 for (i = 0;i < numvertices;i++)
4446 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4449 for (i = 0;i < numvertices;i++)
4450 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4454 for (i = 0;i < numvertices;i++)
4455 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4457 if (texcoordtexture2f)
4458 for (i = 0;i < numvertices;i++)
4459 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4460 if (texcoordlightmap2f)
4461 for (i = 0;i < numvertices;i++)
4462 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4463 R_Mesh_PrepareVertices_Mesh_Unlock();
4464 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4467 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4469 // upload temporary vertexbuffer for this rendering
4470 if (!gl_state.usevbo_staticvertex)
4471 vertexbuffer = NULL;
4472 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4474 if (gl_state.preparevertices_dynamicvertexbuffer)
4475 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4477 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4478 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4480 switch(vid.renderpath)
4482 case RENDERPATH_GL20:
4483 case RENDERPATH_GLES2:
4486 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4487 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4488 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4489 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4490 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4491 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4492 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4496 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4497 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4498 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4499 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4500 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4501 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4502 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4505 case RENDERPATH_GL13:
4506 case RENDERPATH_GLES1:
4509 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4510 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4511 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4512 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4516 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4517 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4518 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4519 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4522 case RENDERPATH_GL11:
4525 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4526 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4527 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4531 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4532 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4533 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4536 case RENDERPATH_D3D9:
4538 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4540 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4542 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4543 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4544 gl_state.d3dvertexdata = (void *)vertex;
4545 gl_state.d3dvertexsize = sizeof(*vertex);
4548 case RENDERPATH_D3D10:
4549 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4551 case RENDERPATH_D3D11:
4552 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4554 case RENDERPATH_SOFT:
4555 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4556 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4557 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4558 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4559 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4560 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4561 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4566 void GL_BlendEquationSubtract(qboolean negated)
4570 switch(vid.renderpath)
4572 case RENDERPATH_GL11:
4573 case RENDERPATH_GL13:
4574 case RENDERPATH_GL20:
4575 case RENDERPATH_GLES1:
4576 case RENDERPATH_GLES2:
4577 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4579 case RENDERPATH_D3D9:
4581 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4584 case RENDERPATH_D3D10:
4585 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4587 case RENDERPATH_D3D11:
4588 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4590 case RENDERPATH_SOFT:
4591 DPSOFTRAST_BlendSubtract(true);
4597 switch(vid.renderpath)
4599 case RENDERPATH_GL11:
4600 case RENDERPATH_GL13:
4601 case RENDERPATH_GL20:
4602 case RENDERPATH_GLES1:
4603 case RENDERPATH_GLES2:
4604 qglBlendEquationEXT(GL_FUNC_ADD);
4606 case RENDERPATH_D3D9:
4608 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4611 case RENDERPATH_D3D10:
4612 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4614 case RENDERPATH_D3D11:
4615 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4617 case RENDERPATH_SOFT:
4618 DPSOFTRAST_BlendSubtract(false);