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 (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1268 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1269 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1270 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1271 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1273 case RENDERPATH_D3D9:
1274 case RENDERPATH_D3D10:
1275 case RENDERPATH_D3D11:
1277 case RENDERPATH_SOFT:
1283 void R_Mesh_DestroyFramebufferObject(int fbo)
1285 switch(vid.renderpath)
1287 case RENDERPATH_GL11:
1288 case RENDERPATH_GL13:
1289 case RENDERPATH_GL20:
1290 case RENDERPATH_GLES1:
1291 case RENDERPATH_GLES2:
1293 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1295 case RENDERPATH_D3D9:
1296 case RENDERPATH_D3D10:
1297 case RENDERPATH_D3D11:
1299 case RENDERPATH_SOFT:
1305 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1307 // 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)
1308 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)
1311 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1312 if (gl_state.d3drt_depthsurface != depthsurface)
1314 gl_state.d3drt_depthsurface = depthsurface;
1315 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1317 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1319 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1320 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1322 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1324 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1325 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1327 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1329 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1330 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1332 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1334 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1335 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1340 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1344 rtexture_t *textures[5];
1345 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1346 textures[4] = depthtexture;
1347 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1348 for (j = 0;j < 5;j++)
1350 for (i = 0;i < vid.teximageunits;i++)
1351 if (gl_state.units[i].texture == textures[j])
1352 R_Mesh_TexBind(i, NULL);
1353 // set up framebuffer object or render targets for the active rendering API
1354 switch(vid.renderpath)
1356 case RENDERPATH_GL11:
1357 case RENDERPATH_GL13:
1358 case RENDERPATH_GL20:
1359 case RENDERPATH_GLES1:
1360 case RENDERPATH_GLES2:
1361 if (gl_state.framebufferobject != fbo)
1363 gl_state.framebufferobject = fbo;
1364 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1367 case RENDERPATH_D3D9:
1369 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1370 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1373 IDirect3DSurface9 *colorsurfaces[4];
1374 for (i = 0;i < 4;i++)
1376 colorsurfaces[i] = NULL;
1378 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1380 // set the render targets for real
1381 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1382 // release the texture surface levels (they won't be lost while bound...)
1383 for (i = 0;i < 4;i++)
1385 IDirect3DSurface9_Release(colorsurfaces[i]);
1388 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1391 case RENDERPATH_D3D10:
1392 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1394 case RENDERPATH_D3D11:
1395 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1397 case RENDERPATH_SOFT:
1401 unsigned int *pointers[5];
1402 memset(pointers, 0, sizeof(pointers));
1403 for (i = 0;i < 5;i++)
1404 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1405 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1406 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1407 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1410 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1416 static int d3dcmpforglfunc(int f)
1420 case GL_NEVER: return D3DCMP_NEVER;
1421 case GL_LESS: return D3DCMP_LESS;
1422 case GL_EQUAL: return D3DCMP_EQUAL;
1423 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1424 case GL_GREATER: return D3DCMP_GREATER;
1425 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1426 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1427 case GL_ALWAYS: return D3DCMP_ALWAYS;
1428 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1432 static int d3dstencilopforglfunc(int f)
1436 case GL_KEEP: return D3DSTENCILOP_KEEP;
1437 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1438 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1439 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1444 extern cvar_t r_transparent_alphatocoverage;
1446 static void GL_Backend_ResetState(void)
1449 gl_state.active = true;
1450 gl_state.depthtest = true;
1451 gl_state.alphatest = false;
1452 gl_state.alphafunc = GL_GEQUAL;
1453 gl_state.alphafuncvalue = 0.5f;
1454 gl_state.alphatocoverage = false;
1455 gl_state.blendfunc1 = GL_ONE;
1456 gl_state.blendfunc2 = GL_ZERO;
1457 gl_state.blend = false;
1458 gl_state.depthmask = GL_TRUE;
1459 gl_state.colormask = 15;
1460 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1461 gl_state.lockrange_first = 0;
1462 gl_state.lockrange_count = 0;
1463 gl_state.cullface = GL_FRONT;
1464 gl_state.cullfaceenable = false;
1465 gl_state.polygonoffset[0] = 0;
1466 gl_state.polygonoffset[1] = 0;
1467 gl_state.framebufferobject = 0;
1468 gl_state.depthfunc = GL_LEQUAL;
1470 switch(vid.renderpath)
1472 case RENDERPATH_D3D9:
1475 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1476 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1477 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1478 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1479 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1480 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1481 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1485 case RENDERPATH_D3D10:
1486 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1488 case RENDERPATH_D3D11:
1489 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1491 case RENDERPATH_GL11:
1492 case RENDERPATH_GL13:
1493 case RENDERPATH_GLES1:
1494 #ifdef GL_ALPHA_TEST
1497 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1498 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1499 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1500 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1501 qglDisable(GL_BLEND);CHECKGLERROR
1502 qglCullFace(gl_state.cullface);CHECKGLERROR
1503 qglDisable(GL_CULL_FACE);CHECKGLERROR
1504 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1505 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1506 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1507 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1509 if (vid.support.arb_vertex_buffer_object)
1511 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1512 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1515 if (vid.support.ext_framebuffer_object)
1517 //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
1518 qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
1521 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1522 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1524 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1525 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1526 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1528 if (vid.support.ext_framebuffer_object)
1529 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
1531 gl_state.unit = MAX_TEXTUREUNITS;
1532 gl_state.clientunit = MAX_TEXTUREUNITS;
1533 for (i = 0;i < vid.texunits;i++)
1535 GL_ActiveTexture(i);
1536 GL_ClientActiveTexture(i);
1537 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1538 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1539 if (vid.support.ext_texture_3d)
1541 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1542 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1544 if (vid.support.arb_texture_cube_map)
1546 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
1547 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1550 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1551 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1552 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1553 qglLoadIdentity();CHECKGLERROR
1554 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1555 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1560 case RENDERPATH_SOFT:
1561 DPSOFTRAST_ColorMask(1,1,1,1);
1562 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1563 DPSOFTRAST_CullFace(gl_state.cullface);
1564 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1565 DPSOFTRAST_DepthMask(gl_state.depthmask);
1566 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1567 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1568 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1570 case RENDERPATH_GL20:
1571 case RENDERPATH_GLES2:
1573 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1574 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1575 qglDisable(GL_BLEND);CHECKGLERROR
1576 qglCullFace(gl_state.cullface);CHECKGLERROR
1577 qglDisable(GL_CULL_FACE);CHECKGLERROR
1578 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1579 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1580 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1581 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1582 if (vid.support.arb_vertex_buffer_object)
1584 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1585 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1587 if (vid.support.ext_framebuffer_object)
1588 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1589 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1590 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1591 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1592 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1593 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1594 gl_state.unit = MAX_TEXTUREUNITS;
1595 gl_state.clientunit = MAX_TEXTUREUNITS;
1596 for (i = 0;i < vid.teximageunits;i++)
1598 GL_ActiveTexture(i);
1599 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1600 if (vid.support.ext_texture_3d)
1602 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1604 if (vid.support.arb_texture_cube_map)
1606 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1609 for (i = 0;i < vid.texarrayunits;i++)
1612 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1613 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1620 void GL_ActiveTexture(unsigned int num)
1622 if (gl_state.unit != num)
1624 gl_state.unit = num;
1625 switch(vid.renderpath)
1627 case RENDERPATH_GL11:
1628 case RENDERPATH_GL13:
1629 case RENDERPATH_GL20:
1630 case RENDERPATH_GLES1:
1631 case RENDERPATH_GLES2:
1632 if (qglActiveTexture)
1635 qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
1639 case RENDERPATH_D3D9:
1640 case RENDERPATH_D3D10:
1641 case RENDERPATH_D3D11:
1643 case RENDERPATH_SOFT:
1649 void GL_ClientActiveTexture(unsigned int num)
1651 if (gl_state.clientunit != num)
1653 gl_state.clientunit = num;
1654 switch(vid.renderpath)
1656 case RENDERPATH_GL11:
1657 case RENDERPATH_GL13:
1658 case RENDERPATH_GLES1:
1659 if (qglActiveTexture)
1662 qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit);
1666 case RENDERPATH_D3D9:
1667 case RENDERPATH_D3D10:
1668 case RENDERPATH_D3D11:
1670 case RENDERPATH_SOFT:
1672 case RENDERPATH_GL20:
1673 case RENDERPATH_GLES2:
1679 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1681 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1683 qboolean blendenable;
1684 gl_state.blendfunc1 = blendfunc1;
1685 gl_state.blendfunc2 = blendfunc2;
1686 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1687 switch(vid.renderpath)
1689 case RENDERPATH_GL11:
1690 case RENDERPATH_GL13:
1691 case RENDERPATH_GL20:
1692 case RENDERPATH_GLES1:
1693 case RENDERPATH_GLES2:
1695 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1696 if (gl_state.blend != blendenable)
1698 gl_state.blend = blendenable;
1699 if (!gl_state.blend)
1701 qglDisable(GL_BLEND);CHECKGLERROR
1705 qglEnable(GL_BLEND);CHECKGLERROR
1709 case RENDERPATH_D3D9:
1714 D3DBLEND d3dblendfunc[2];
1715 glblendfunc[0] = gl_state.blendfunc1;
1716 glblendfunc[1] = gl_state.blendfunc2;
1717 for (i = 0;i < 2;i++)
1719 switch(glblendfunc[i])
1721 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1722 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1723 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1724 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1725 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1726 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1727 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1728 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1729 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1730 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1733 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1734 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1735 if (gl_state.blend != blendenable)
1737 gl_state.blend = blendenable;
1738 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1743 case RENDERPATH_D3D10:
1744 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1746 case RENDERPATH_D3D11:
1747 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1749 case RENDERPATH_SOFT:
1750 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1756 void GL_DepthMask(int state)
1758 if (gl_state.depthmask != state)
1760 gl_state.depthmask = state;
1761 switch(vid.renderpath)
1763 case RENDERPATH_GL11:
1764 case RENDERPATH_GL13:
1765 case RENDERPATH_GL20:
1766 case RENDERPATH_GLES1:
1767 case RENDERPATH_GLES2:
1769 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1771 case RENDERPATH_D3D9:
1773 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1776 case RENDERPATH_D3D10:
1777 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1779 case RENDERPATH_D3D11:
1780 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1782 case RENDERPATH_SOFT:
1783 DPSOFTRAST_DepthMask(gl_state.depthmask);
1789 void GL_DepthTest(int state)
1791 if (gl_state.depthtest != state)
1793 gl_state.depthtest = state;
1794 switch(vid.renderpath)
1796 case RENDERPATH_GL11:
1797 case RENDERPATH_GL13:
1798 case RENDERPATH_GL20:
1799 case RENDERPATH_GLES1:
1800 case RENDERPATH_GLES2:
1802 if (gl_state.depthtest)
1804 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1808 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1811 case RENDERPATH_D3D9:
1813 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1816 case RENDERPATH_D3D10:
1817 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1819 case RENDERPATH_D3D11:
1820 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1822 case RENDERPATH_SOFT:
1823 DPSOFTRAST_DepthTest(gl_state.depthtest);
1829 void GL_DepthFunc(int state)
1831 if (gl_state.depthfunc != state)
1833 gl_state.depthfunc = state;
1834 switch(vid.renderpath)
1836 case RENDERPATH_GL11:
1837 case RENDERPATH_GL13:
1838 case RENDERPATH_GL20:
1839 case RENDERPATH_GLES1:
1840 case RENDERPATH_GLES2:
1842 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1844 case RENDERPATH_D3D9:
1846 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1849 case RENDERPATH_D3D10:
1850 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1852 case RENDERPATH_D3D11:
1853 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1855 case RENDERPATH_SOFT:
1856 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1862 void GL_DepthRange(float nearfrac, float farfrac)
1864 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1866 gl_state.depthrange[0] = nearfrac;
1867 gl_state.depthrange[1] = farfrac;
1868 switch(vid.renderpath)
1870 case RENDERPATH_GL11:
1871 case RENDERPATH_GL13:
1872 case RENDERPATH_GL20:
1873 case RENDERPATH_GLES1:
1874 case RENDERPATH_GLES2:
1876 qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
1878 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1881 case RENDERPATH_D3D9:
1884 D3DVIEWPORT9 d3dviewport;
1885 d3dviewport.X = gl_viewport.x;
1886 d3dviewport.Y = gl_viewport.y;
1887 d3dviewport.Width = gl_viewport.width;
1888 d3dviewport.Height = gl_viewport.height;
1889 d3dviewport.MinZ = gl_state.depthrange[0];
1890 d3dviewport.MaxZ = gl_state.depthrange[1];
1891 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1895 case RENDERPATH_D3D10:
1896 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1898 case RENDERPATH_D3D11:
1899 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1901 case RENDERPATH_SOFT:
1902 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1908 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)
1910 switch (vid.renderpath)
1912 case RENDERPATH_GL11:
1913 case RENDERPATH_GL13:
1914 case RENDERPATH_GL20:
1915 case RENDERPATH_GLES1:
1916 case RENDERPATH_GLES2:
1920 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1924 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1926 if (vid.support.ati_separate_stencil)
1928 qglStencilMask(writemask);CHECKGLERROR
1929 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1930 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1931 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1933 else if (vid.support.ext_stencil_two_side)
1935 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1936 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1937 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1938 qglStencilMask(writemask);CHECKGLERROR
1939 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1940 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1941 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1942 qglStencilMask(writemask);CHECKGLERROR
1943 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1944 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1948 case RENDERPATH_D3D9:
1950 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1951 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1952 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1953 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1954 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1955 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1956 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1957 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1958 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1960 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1961 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1962 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1965 case RENDERPATH_D3D10:
1966 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1968 case RENDERPATH_D3D11:
1969 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1971 case RENDERPATH_SOFT:
1972 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1977 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1979 switch (vid.renderpath)
1981 case RENDERPATH_GL11:
1982 case RENDERPATH_GL13:
1983 case RENDERPATH_GL20:
1984 case RENDERPATH_GLES1:
1985 case RENDERPATH_GLES2:
1989 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1993 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1995 if (vid.support.ext_stencil_two_side)
1997 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1998 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2001 qglStencilMask(writemask);CHECKGLERROR
2002 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2003 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2006 case RENDERPATH_D3D9:
2008 if (vid.support.ati_separate_stencil)
2009 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2011 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2012 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2013 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2014 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2015 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2016 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2017 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2020 case RENDERPATH_D3D10:
2021 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2023 case RENDERPATH_D3D11:
2024 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2026 case RENDERPATH_SOFT:
2027 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2032 void GL_PolygonOffset(float planeoffset, float depthoffset)
2034 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2036 gl_state.polygonoffset[0] = planeoffset;
2037 gl_state.polygonoffset[1] = depthoffset;
2038 switch(vid.renderpath)
2040 case RENDERPATH_GL11:
2041 case RENDERPATH_GL13:
2042 case RENDERPATH_GL20:
2043 case RENDERPATH_GLES1:
2044 case RENDERPATH_GLES2:
2045 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2047 case RENDERPATH_D3D9:
2049 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2050 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2053 case RENDERPATH_D3D10:
2054 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2056 case RENDERPATH_D3D11:
2057 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2059 case RENDERPATH_SOFT:
2060 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2066 void GL_SetMirrorState(qboolean state)
2068 if (v_flipped_state != state)
2070 v_flipped_state = state;
2071 if (gl_state.cullface == GL_BACK)
2072 gl_state.cullface = GL_FRONT;
2073 else if (gl_state.cullface == GL_FRONT)
2074 gl_state.cullface = GL_BACK;
2077 switch(vid.renderpath)
2079 case RENDERPATH_GL11:
2080 case RENDERPATH_GL13:
2081 case RENDERPATH_GL20:
2082 case RENDERPATH_GLES1:
2083 case RENDERPATH_GLES2:
2084 qglCullFace(gl_state.cullface);CHECKGLERROR
2086 case RENDERPATH_D3D9:
2088 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2091 case RENDERPATH_D3D10:
2092 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2094 case RENDERPATH_D3D11:
2095 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2097 case RENDERPATH_SOFT:
2098 DPSOFTRAST_CullFace(gl_state.cullface);
2104 void GL_CullFace(int state)
2108 if(state == GL_FRONT)
2110 else if(state == GL_BACK)
2114 switch(vid.renderpath)
2116 case RENDERPATH_GL11:
2117 case RENDERPATH_GL13:
2118 case RENDERPATH_GL20:
2119 case RENDERPATH_GLES1:
2120 case RENDERPATH_GLES2:
2123 if (state != GL_NONE)
2125 if (!gl_state.cullfaceenable)
2127 gl_state.cullfaceenable = true;
2128 qglEnable(GL_CULL_FACE);CHECKGLERROR
2130 if (gl_state.cullface != state)
2132 gl_state.cullface = state;
2133 qglCullFace(gl_state.cullface);CHECKGLERROR
2138 if (gl_state.cullfaceenable)
2140 gl_state.cullfaceenable = false;
2141 qglDisable(GL_CULL_FACE);CHECKGLERROR
2145 case RENDERPATH_D3D9:
2147 if (gl_state.cullface != state)
2149 gl_state.cullface = state;
2150 switch(gl_state.cullface)
2153 gl_state.cullfaceenable = false;
2154 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2157 gl_state.cullfaceenable = true;
2158 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2161 gl_state.cullfaceenable = true;
2162 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2168 case RENDERPATH_D3D10:
2169 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2171 case RENDERPATH_D3D11:
2172 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2174 case RENDERPATH_SOFT:
2175 if (gl_state.cullface != state)
2177 gl_state.cullface = state;
2178 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2179 DPSOFTRAST_CullFace(gl_state.cullface);
2185 void GL_AlphaTest(int state)
2187 if (gl_state.alphatest != state)
2189 gl_state.alphatest = state;
2190 switch(vid.renderpath)
2192 case RENDERPATH_GL11:
2193 case RENDERPATH_GL13:
2194 case RENDERPATH_GLES1:
2195 #ifdef GL_ALPHA_TEST
2196 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2198 if (gl_state.alphatest)
2200 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2204 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2208 case RENDERPATH_D3D9:
2209 case RENDERPATH_D3D10:
2210 case RENDERPATH_D3D11:
2211 case RENDERPATH_SOFT:
2212 case RENDERPATH_GL20:
2213 case RENDERPATH_GLES2:
2219 void GL_AlphaToCoverage(qboolean state)
2221 if (gl_state.alphatocoverage != state)
2223 gl_state.alphatocoverage = state;
2224 switch(vid.renderpath)
2226 case RENDERPATH_GL11:
2227 case RENDERPATH_GL13:
2228 case RENDERPATH_GLES1:
2229 case RENDERPATH_GLES2:
2230 case RENDERPATH_D3D9:
2231 case RENDERPATH_D3D10:
2232 case RENDERPATH_D3D11:
2233 case RENDERPATH_SOFT:
2235 case RENDERPATH_GL20:
2236 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2237 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2239 if (gl_state.alphatocoverage)
2241 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2242 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2246 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2247 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2255 void GL_ColorMask(int r, int g, int b, int a)
2257 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2258 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2259 if (gl_state.colormask != state)
2261 gl_state.colormask = state;
2262 switch(vid.renderpath)
2264 case RENDERPATH_GL11:
2265 case RENDERPATH_GL13:
2266 case RENDERPATH_GL20:
2267 case RENDERPATH_GLES1:
2268 case RENDERPATH_GLES2:
2270 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2272 case RENDERPATH_D3D9:
2274 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2277 case RENDERPATH_D3D10:
2278 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2280 case RENDERPATH_D3D11:
2281 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2283 case RENDERPATH_SOFT:
2284 DPSOFTRAST_ColorMask(r, g, b, a);
2290 void GL_Color(float cr, float cg, float cb, float ca)
2292 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)
2294 gl_state.color4f[0] = cr;
2295 gl_state.color4f[1] = cg;
2296 gl_state.color4f[2] = cb;
2297 gl_state.color4f[3] = ca;
2298 switch(vid.renderpath)
2300 case RENDERPATH_GL11:
2301 case RENDERPATH_GL13:
2302 case RENDERPATH_GLES1:
2304 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2307 case RENDERPATH_D3D9:
2308 case RENDERPATH_D3D10:
2309 case RENDERPATH_D3D11:
2310 // no equivalent in D3D
2312 case RENDERPATH_SOFT:
2313 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2315 case RENDERPATH_GL20:
2316 case RENDERPATH_GLES2:
2317 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2323 void GL_Scissor (int x, int y, int width, int height)
2325 switch(vid.renderpath)
2327 case RENDERPATH_GL11:
2328 case RENDERPATH_GL13:
2329 case RENDERPATH_GL20:
2330 case RENDERPATH_GLES1:
2331 case RENDERPATH_GLES2:
2333 qglScissor(x, y,width,height);
2336 case RENDERPATH_D3D9:
2342 d3drect.right = x + width;
2343 d3drect.bottom = y + height;
2344 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2348 case RENDERPATH_D3D10:
2349 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2351 case RENDERPATH_D3D11:
2352 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2354 case RENDERPATH_SOFT:
2355 DPSOFTRAST_Scissor(x, y, width, height);
2360 void GL_ScissorTest(int state)
2362 if (gl_state.scissortest != state)
2364 gl_state.scissortest = state;
2365 switch(vid.renderpath)
2367 case RENDERPATH_GL11:
2368 case RENDERPATH_GL13:
2369 case RENDERPATH_GL20:
2370 case RENDERPATH_GLES1:
2371 case RENDERPATH_GLES2:
2373 if(gl_state.scissortest)
2374 qglEnable(GL_SCISSOR_TEST);
2376 qglDisable(GL_SCISSOR_TEST);
2379 case RENDERPATH_D3D9:
2381 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2384 case RENDERPATH_D3D10:
2385 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2387 case RENDERPATH_D3D11:
2388 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2390 case RENDERPATH_SOFT:
2391 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2397 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2399 static const float blackcolor[4] = {0, 0, 0, 0};
2400 // prevent warnings when trying to clear a buffer that does not exist
2402 colorvalue = blackcolor;
2405 mask &= ~GL_STENCIL_BUFFER_BIT;
2408 switch(vid.renderpath)
2410 case RENDERPATH_GL11:
2411 case RENDERPATH_GL13:
2412 case RENDERPATH_GL20:
2413 case RENDERPATH_GLES1:
2414 case RENDERPATH_GLES2:
2416 if (mask & GL_COLOR_BUFFER_BIT)
2418 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2420 if (mask & GL_DEPTH_BUFFER_BIT)
2423 qglClearDepthf(depthvalue);CHECKGLERROR
2425 qglClearDepth(depthvalue);CHECKGLERROR
2428 if (mask & GL_STENCIL_BUFFER_BIT)
2430 qglClearStencil(stencilvalue);CHECKGLERROR
2432 qglClear(mask);CHECKGLERROR
2434 case RENDERPATH_D3D9:
2436 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);
2439 case RENDERPATH_D3D10:
2440 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2442 case RENDERPATH_D3D11:
2443 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2445 case RENDERPATH_SOFT:
2446 if (mask & GL_COLOR_BUFFER_BIT)
2447 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2448 if (mask & GL_DEPTH_BUFFER_BIT)
2449 DPSOFTRAST_ClearDepth(depthvalue);
2454 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2456 switch(vid.renderpath)
2458 case RENDERPATH_GL11:
2459 case RENDERPATH_GL13:
2460 case RENDERPATH_GL20:
2461 case RENDERPATH_GLES1:
2462 case RENDERPATH_GLES2:
2464 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2466 case RENDERPATH_D3D9:
2469 // LordHavoc: we can't directly download the backbuffer because it may be
2470 // multisampled, and it may not be lockable, so we blit it to a lockable
2471 // surface of the same dimensions (but without multisample) to resolve the
2472 // multisample buffer to a normal image, and then lock that...
2473 IDirect3DSurface9 *stretchsurface = NULL;
2474 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2476 D3DLOCKED_RECT lockedrect;
2477 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2479 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2482 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2483 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2484 memcpy(outpixels + line * width * 4, row, width * 4);
2485 IDirect3DSurface9_UnlockRect(stretchsurface);
2488 IDirect3DSurface9_Release(stretchsurface);
2491 //IDirect3DSurface9 *syssurface = NULL;
2492 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2493 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2494 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2495 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2496 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2497 //IDirect3DSurface9_UnlockRect(syssurface);
2498 //IDirect3DSurface9_Release(syssurface);
2502 case RENDERPATH_D3D10:
2503 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2505 case RENDERPATH_D3D11:
2506 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2508 case RENDERPATH_SOFT:
2509 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2514 // called at beginning of frame
2515 void R_Mesh_Start(void)
2518 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
2520 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2522 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2523 Cvar_SetValueQuick(&gl_paranoid, 1);
2527 static qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2531 char compilelog[MAX_INPUTLINE];
2532 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2535 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2536 qglCompileShader(shaderobject);CHECKGLERROR
2537 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2538 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2539 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2541 int i, j, pretextlines = 0;
2542 for (i = 0;i < numstrings - 1;i++)
2543 for (j = 0;strings[i][j];j++)
2544 if (strings[i][j] == '\n')
2546 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2548 if (!shadercompiled)
2550 qglDeleteShader(shaderobject);CHECKGLERROR
2553 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2554 qglDeleteShader(shaderobject);CHECKGLERROR
2558 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)
2560 GLint programlinked;
2561 GLuint programobject = 0;
2562 char linklog[MAX_INPUTLINE];
2565 programobject = qglCreateProgram();CHECKGLERROR
2569 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2570 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2571 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2572 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2573 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2574 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2575 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2576 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2577 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2578 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2580 if(vid.support.gl20shaders130)
2581 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2584 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2587 #ifdef GL_GEOMETRY_SHADER
2588 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2592 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2595 qglLinkProgram(programobject);CHECKGLERROR
2596 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2597 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2600 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2601 Con_DPrintf("program link log:\n%s\n", linklog);
2602 // software vertex shader is ok but software fragment shader is WAY
2603 // too slow, fail program if so.
2604 // NOTE: this string might be ATI specific, but that's ok because the
2605 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2606 // software fragment shader due to low instruction and dependent
2608 if (strstr(linklog, "fragment shader will run in software"))
2609 programlinked = false;
2613 return programobject;
2615 qglDeleteProgram(programobject);CHECKGLERROR
2619 void GL_Backend_FreeProgram(unsigned int prog)
2622 qglDeleteProgram(prog);
2626 // renders triangles using vertices from the active arrays
2627 int paranoidblah = 0;
2628 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)
2630 unsigned int numelements = numtriangles * 3;
2632 size_t bufferoffset3i;
2634 size_t bufferoffset3s;
2635 if (numvertices < 3 || numtriangles < 1)
2637 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2638 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);
2641 if (!gl_mesh_prefer_short_elements.integer)
2645 if (element3i_indexbuffer)
2646 element3i_indexbuffer = NULL;
2648 // adjust the pointers for firsttriangle
2650 element3i += firsttriangle * 3;
2651 if (element3i_indexbuffer)
2652 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2654 element3s += firsttriangle * 3;
2655 if (element3s_indexbuffer)
2656 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2657 switch(vid.renderpath)
2659 case RENDERPATH_GL11:
2660 case RENDERPATH_GL13:
2661 case RENDERPATH_GL20:
2662 case RENDERPATH_GLES1:
2663 case RENDERPATH_GLES2:
2664 // check if the user specified to ignore static index buffers
2665 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2667 element3i_indexbuffer = NULL;
2668 element3s_indexbuffer = NULL;
2671 case RENDERPATH_D3D9:
2672 case RENDERPATH_D3D10:
2673 case RENDERPATH_D3D11:
2675 case RENDERPATH_SOFT:
2678 // upload a dynamic index buffer if needed
2681 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2683 if (gl_state.draw_dynamicindexbuffer)
2684 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2686 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2687 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2688 element3s_bufferoffset = 0;
2693 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2695 if (gl_state.draw_dynamicindexbuffer)
2696 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2698 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2699 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2700 element3i_bufferoffset = 0;
2703 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2704 bufferoffset3i = element3i_bufferoffset;
2705 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2706 bufferoffset3s = element3s_bufferoffset;
2707 r_refdef.stats.draws++;
2708 r_refdef.stats.draws_vertices += numvertices;
2709 r_refdef.stats.draws_elements += numelements;
2710 if (gl_paranoid.integer)
2713 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2715 unsigned int j, size;
2717 // note: there's no validation done here on buffer objects because it
2718 // is somewhat difficult to get at the data, and gl_paranoid can be
2719 // used without buffer objects if the need arises
2720 // (the data could be gotten using glMapBuffer but it would be very
2721 // slow due to uncachable video memory reads)
2722 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2723 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2725 if (gl_state.pointer_vertex_pointer)
2726 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2728 if (gl_state.pointer_color_enabled)
2730 if (!qglIsEnabled(GL_COLOR_ARRAY))
2731 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2733 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2734 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2737 for (i = 0;i < vid.texarrayunits;i++)
2739 if (gl_state.units[i].arrayenabled)
2741 GL_ClientActiveTexture(i);
2742 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2743 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2745 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2746 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++)
2753 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2755 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2757 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2764 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2766 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2768 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2774 if (r_render.integer || r_refdef.draw2dstage)
2776 switch(vid.renderpath)
2778 case RENDERPATH_GL11:
2779 case RENDERPATH_GL13:
2780 case RENDERPATH_GL20:
2782 if (gl_mesh_testmanualfeeding.integer)
2785 unsigned int i, j, element;
2787 qglBegin(GL_TRIANGLES);
2788 if(vid.renderpath == RENDERPATH_GL20)
2790 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2793 element = element3i[i];
2795 element = element3s[i];
2797 element = firstvertex + i;
2798 for (j = 0;j < vid.texarrayunits;j++)
2800 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2802 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2804 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2805 if (gl_state.units[j].pointer_texcoord_components == 4)
2806 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2807 else if (gl_state.units[j].pointer_texcoord_components == 3)
2808 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2809 else if (gl_state.units[j].pointer_texcoord_components == 2)
2810 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2812 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2814 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2816 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2817 if (gl_state.units[j].pointer_texcoord_components == 4)
2818 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2819 else if (gl_state.units[j].pointer_texcoord_components == 3)
2820 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2821 else if (gl_state.units[j].pointer_texcoord_components == 2)
2822 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2823 else if (gl_state.units[j].pointer_texcoord_components == 1)
2824 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2826 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2828 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2829 if (gl_state.units[j].pointer_texcoord_components == 4)
2830 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2831 else if (gl_state.units[j].pointer_texcoord_components == 3)
2832 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2833 else if (gl_state.units[j].pointer_texcoord_components == 2)
2834 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2835 else if (gl_state.units[j].pointer_texcoord_components == 1)
2836 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2840 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2842 if (gl_state.pointer_color_gltype == GL_FLOAT)
2844 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2845 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2847 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2849 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2850 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2853 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2855 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2856 if (gl_state.pointer_vertex_components == 4)
2857 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2858 else if (gl_state.pointer_vertex_components == 3)
2859 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2861 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2867 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2870 element = element3i[i];
2872 element = element3s[i];
2874 element = firstvertex + i;
2875 for (j = 0;j < vid.texarrayunits;j++)
2877 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2879 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2881 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2882 if (vid.texarrayunits > 1)
2884 if (gl_state.units[j].pointer_texcoord_components == 4)
2885 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2886 else if (gl_state.units[j].pointer_texcoord_components == 3)
2887 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2888 else if (gl_state.units[j].pointer_texcoord_components == 2)
2889 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2891 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2895 if (gl_state.units[j].pointer_texcoord_components == 4)
2896 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2897 else if (gl_state.units[j].pointer_texcoord_components == 3)
2898 qglTexCoord3f(p[0], p[1], p[2]);
2899 else if (gl_state.units[j].pointer_texcoord_components == 2)
2900 qglTexCoord2f(p[0], p[1]);
2902 qglTexCoord1f(p[0]);
2905 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2907 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2908 if (vid.texarrayunits > 1)
2910 if (gl_state.units[j].pointer_texcoord_components == 4)
2911 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2912 else if (gl_state.units[j].pointer_texcoord_components == 3)
2913 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2914 else if (gl_state.units[j].pointer_texcoord_components == 2)
2915 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2916 else if (gl_state.units[j].pointer_texcoord_components == 1)
2917 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2921 if (gl_state.units[j].pointer_texcoord_components == 4)
2922 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2923 else if (gl_state.units[j].pointer_texcoord_components == 3)
2924 qglTexCoord3f(s[0], s[1], s[2]);
2925 else if (gl_state.units[j].pointer_texcoord_components == 2)
2926 qglTexCoord2f(s[0], s[1]);
2927 else if (gl_state.units[j].pointer_texcoord_components == 1)
2928 qglTexCoord1f(s[0]);
2931 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2933 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2934 if (vid.texarrayunits > 1)
2936 if (gl_state.units[j].pointer_texcoord_components == 4)
2937 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2938 else if (gl_state.units[j].pointer_texcoord_components == 3)
2939 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2940 else if (gl_state.units[j].pointer_texcoord_components == 2)
2941 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2942 else if (gl_state.units[j].pointer_texcoord_components == 1)
2943 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2947 if (gl_state.units[j].pointer_texcoord_components == 4)
2948 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2949 else if (gl_state.units[j].pointer_texcoord_components == 3)
2950 qglTexCoord3f(sb[0], sb[1], sb[2]);
2951 else if (gl_state.units[j].pointer_texcoord_components == 2)
2952 qglTexCoord2f(sb[0], sb[1]);
2953 else if (gl_state.units[j].pointer_texcoord_components == 1)
2954 qglTexCoord1f(sb[0]);
2959 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2961 if (gl_state.pointer_color_gltype == GL_FLOAT)
2963 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2964 qglColor4f(p[0], p[1], p[2], p[3]);
2966 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2968 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2969 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2972 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2974 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2975 if (gl_state.pointer_vertex_components == 4)
2976 qglVertex4f(p[0], p[1], p[2], p[3]);
2977 else if (gl_state.pointer_vertex_components == 3)
2978 qglVertex3f(p[0], p[1], p[2]);
2980 qglVertex2f(p[0], p[1]);
2988 else if (bufferobject3s)
2990 GL_BindEBO(bufferobject3s);
2992 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2994 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
3000 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3004 else if (bufferobject3i)
3006 GL_BindEBO(bufferobject3i);
3008 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3010 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3016 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3024 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3026 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3032 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3040 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3042 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3048 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3054 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3058 case RENDERPATH_D3D9:
3060 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3062 if (element3s_indexbuffer)
3064 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3065 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3067 else if (element3i_indexbuffer)
3069 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3070 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3073 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3078 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3080 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3082 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3086 case RENDERPATH_D3D10:
3087 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3089 case RENDERPATH_D3D11:
3090 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3092 case RENDERPATH_SOFT:
3093 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3095 case RENDERPATH_GLES1:
3096 case RENDERPATH_GLES2:
3097 // GLES does not have glDrawRangeElements, and generally
3098 // underperforms with index buffers, so this code path is
3099 // relatively straightforward...
3101 if (gl_paranoid.integer)
3103 int r, prog, enabled, i;
3104 GLsizei attriblength;
3107 GLchar attribname[1024];
3108 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3109 if (r != GL_FRAMEBUFFER_COMPLETE)
3110 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3111 #ifndef GL_CURRENT_PROGRAM
3112 #define GL_CURRENT_PROGRAM 0x8B8D
3114 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3115 if (r < 0 || r > 10000)
3116 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3118 for (i = 0;i < 8;i++)
3120 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3123 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3124 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);
3130 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3135 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3140 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3148 // restores backend state, used when done with 3D rendering
3149 void R_Mesh_Finish(void)
3151 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
3154 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3156 r_meshbuffer_t *buffer;
3157 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3159 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3160 memset(buffer, 0, sizeof(*buffer));
3161 buffer->bufferobject = 0;
3162 buffer->devicebuffer = NULL;
3164 buffer->isindexbuffer = isindexbuffer;
3165 buffer->isdynamic = isdynamic;
3166 buffer->isindex16 = isindex16;
3167 strlcpy(buffer->name, name, sizeof(buffer->name));
3168 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3172 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3176 if (buffer->isindexbuffer)
3178 r_refdef.stats.indexbufferuploadcount++;
3179 r_refdef.stats.indexbufferuploadsize += size;
3183 r_refdef.stats.vertexbufferuploadcount++;
3184 r_refdef.stats.vertexbufferuploadsize += size;
3186 switch(vid.renderpath)
3188 case RENDERPATH_GL11:
3189 case RENDERPATH_GL13:
3190 case RENDERPATH_GL20:
3191 case RENDERPATH_GLES1:
3192 case RENDERPATH_GLES2:
3193 if (!buffer->bufferobject)
3194 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3195 if (buffer->isindexbuffer)
3196 GL_BindEBO(buffer->bufferobject);
3198 GL_BindVBO(buffer->bufferobject);
3199 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3201 case RENDERPATH_D3D9:
3205 void *datapointer = NULL;
3206 if (buffer->isindexbuffer)
3208 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3209 if (size > buffer->size || !buffer->devicebuffer)
3211 if (buffer->devicebuffer)
3212 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3213 buffer->devicebuffer = NULL;
3214 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)))
3215 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);
3216 buffer->devicebuffer = (void *)d3d9indexbuffer;
3217 buffer->size = size;
3219 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3222 memcpy(datapointer, data, size);
3224 memset(datapointer, 0, size);
3225 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3230 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3231 if (size > buffer->size || !buffer->devicebuffer)
3233 if (buffer->devicebuffer)
3234 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3235 buffer->devicebuffer = NULL;
3236 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3237 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);
3238 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3239 buffer->size = size;
3241 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3244 memcpy(datapointer, data, size);
3246 memset(datapointer, 0, size);
3247 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3253 case RENDERPATH_D3D10:
3254 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3256 case RENDERPATH_D3D11:
3257 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3259 case RENDERPATH_SOFT:
3264 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3268 switch(vid.renderpath)
3270 case RENDERPATH_GL11:
3271 case RENDERPATH_GL13:
3272 case RENDERPATH_GL20:
3273 case RENDERPATH_GLES1:
3274 case RENDERPATH_GLES2:
3275 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3277 case RENDERPATH_D3D9:
3279 if (gl_state.d3dvertexbuffer == (void *)buffer)
3280 gl_state.d3dvertexbuffer = NULL;
3281 if (buffer->devicebuffer)
3283 if (buffer->isindexbuffer)
3284 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3286 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3287 buffer->devicebuffer = NULL;
3291 case RENDERPATH_D3D10:
3292 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3294 case RENDERPATH_D3D11:
3295 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3297 case RENDERPATH_SOFT:
3300 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3303 void GL_Mesh_ListVBOs(qboolean printeach)
3306 size_t ebocount = 0, ebomemory = 0;
3307 size_t vbocount = 0, vbomemory = 0;
3308 r_meshbuffer_t *buffer;
3309 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3310 for (i = 0;i < endindex;i++)
3312 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3315 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)");}
3316 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)");}
3318 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);
3323 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3325 switch(vid.renderpath)
3327 case RENDERPATH_GL11:
3328 case RENDERPATH_GL13:
3329 case RENDERPATH_GLES1:
3330 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)
3332 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3333 gl_state.pointer_vertex_components = components;
3334 gl_state.pointer_vertex_gltype = gltype;
3335 gl_state.pointer_vertex_stride = stride;
3336 gl_state.pointer_vertex_pointer = pointer;
3337 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3338 gl_state.pointer_vertex_offset = bufferoffset;
3340 GL_BindVBO(bufferobject);
3341 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3344 case RENDERPATH_GL20:
3345 case RENDERPATH_GLES2:
3346 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)
3348 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3349 gl_state.pointer_vertex_components = components;
3350 gl_state.pointer_vertex_gltype = gltype;
3351 gl_state.pointer_vertex_stride = stride;
3352 gl_state.pointer_vertex_pointer = pointer;
3353 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3354 gl_state.pointer_vertex_offset = bufferoffset;
3356 GL_BindVBO(bufferobject);
3357 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3360 case RENDERPATH_D3D9:
3361 case RENDERPATH_D3D10:
3362 case RENDERPATH_D3D11:
3363 case RENDERPATH_SOFT:
3368 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3370 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3371 // the pointer only.
3372 switch(vid.renderpath)
3374 case RENDERPATH_GL11:
3375 case RENDERPATH_GL13:
3376 case RENDERPATH_GLES1:
3381 // caller wants color array enabled
3382 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3383 if (!gl_state.pointer_color_enabled)
3385 gl_state.pointer_color_enabled = true;
3387 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3389 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)
3391 gl_state.pointer_color_components = components;
3392 gl_state.pointer_color_gltype = gltype;
3393 gl_state.pointer_color_stride = stride;
3394 gl_state.pointer_color_pointer = pointer;
3395 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3396 gl_state.pointer_color_offset = bufferoffset;
3398 GL_BindVBO(bufferobject);
3399 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3404 // caller wants color array disabled
3405 if (gl_state.pointer_color_enabled)
3407 gl_state.pointer_color_enabled = false;
3409 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3410 // when color array is on the glColor gets trashed, set it again
3411 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3416 case RENDERPATH_GL20:
3417 case RENDERPATH_GLES2:
3421 // caller wants color array enabled
3422 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3423 if (!gl_state.pointer_color_enabled)
3425 gl_state.pointer_color_enabled = true;
3427 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3429 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)
3431 gl_state.pointer_color_components = components;
3432 gl_state.pointer_color_gltype = gltype;
3433 gl_state.pointer_color_stride = stride;
3434 gl_state.pointer_color_pointer = pointer;
3435 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3436 gl_state.pointer_color_offset = bufferoffset;
3438 GL_BindVBO(bufferobject);
3439 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3444 // caller wants color array disabled
3445 if (gl_state.pointer_color_enabled)
3447 gl_state.pointer_color_enabled = false;
3449 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3450 // when color array is on the glColor gets trashed, set it again
3451 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3455 case RENDERPATH_D3D9:
3456 case RENDERPATH_D3D10:
3457 case RENDERPATH_D3D11:
3458 case RENDERPATH_SOFT:
3463 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)
3465 gltextureunit_t *unit = gl_state.units + unitnum;
3466 // update array settings
3467 // note: there is no need to check bufferobject here because all cases
3468 // that involve a valid bufferobject also supply a texcoord array
3469 switch(vid.renderpath)
3471 case RENDERPATH_GL11:
3472 case RENDERPATH_GL13:
3473 case RENDERPATH_GLES1:
3478 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3479 // texture array unit is enabled, enable the array
3480 if (!unit->arrayenabled)
3482 unit->arrayenabled = true;
3483 GL_ClientActiveTexture(unitnum);
3484 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3487 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)
3489 unit->pointer_texcoord_components = components;
3490 unit->pointer_texcoord_gltype = gltype;
3491 unit->pointer_texcoord_stride = stride;
3492 unit->pointer_texcoord_pointer = pointer;
3493 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3494 unit->pointer_texcoord_offset = bufferoffset;
3495 GL_ClientActiveTexture(unitnum);
3496 GL_BindVBO(bufferobject);
3497 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3502 // texture array unit is disabled, disable the array
3503 if (unit->arrayenabled)
3505 unit->arrayenabled = false;
3506 GL_ClientActiveTexture(unitnum);
3507 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3512 case RENDERPATH_GL20:
3513 case RENDERPATH_GLES2:
3517 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3518 // texture array unit is enabled, enable the array
3519 if (!unit->arrayenabled)
3521 unit->arrayenabled = true;
3522 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3525 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)
3527 unit->pointer_texcoord_components = components;
3528 unit->pointer_texcoord_gltype = gltype;
3529 unit->pointer_texcoord_stride = stride;
3530 unit->pointer_texcoord_pointer = pointer;
3531 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3532 unit->pointer_texcoord_offset = bufferoffset;
3533 GL_BindVBO(bufferobject);
3534 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3539 // texture array unit is disabled, disable the array
3540 if (unit->arrayenabled)
3542 unit->arrayenabled = false;
3543 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3547 case RENDERPATH_D3D9:
3548 case RENDERPATH_D3D10:
3549 case RENDERPATH_D3D11:
3550 case RENDERPATH_SOFT:
3555 int R_Mesh_TexBound(unsigned int unitnum, int id)
3557 gltextureunit_t *unit = gl_state.units + unitnum;
3558 if (unitnum >= vid.teximageunits)
3560 if (id == GL_TEXTURE_2D)
3562 if (id == GL_TEXTURE_3D)
3564 if (id == GL_TEXTURE_CUBE_MAP)
3565 return unit->tcubemap;
3569 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3571 switch(vid.renderpath)
3573 case RENDERPATH_GL11:
3574 case RENDERPATH_GL13:
3575 case RENDERPATH_GL20:
3576 case RENDERPATH_GLES1:
3577 case RENDERPATH_GLES2:
3578 R_Mesh_TexBind(0, tex);
3579 GL_ActiveTexture(0);CHECKGLERROR
3580 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3582 case RENDERPATH_D3D9:
3585 IDirect3DSurface9 *currentsurface = NULL;
3586 IDirect3DSurface9 *texturesurface = NULL;
3589 sourcerect.left = sx;
3590 sourcerect.top = sy;
3591 sourcerect.right = sx + width;
3592 sourcerect.bottom = sy + height;
3595 destrect.right = tx + width;
3596 destrect.bottom = ty + height;
3597 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3599 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3601 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3602 IDirect3DSurface9_Release(currentsurface);
3604 IDirect3DSurface9_Release(texturesurface);
3609 case RENDERPATH_D3D10:
3610 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3612 case RENDERPATH_D3D11:
3613 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3615 case RENDERPATH_SOFT:
3616 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3622 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};
3625 void R_Mesh_ClearBindingsForTexture(int texnum)
3627 gltextureunit_t *unit;
3628 unsigned int unitnum;
3629 // 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)
3630 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3632 unit = gl_state.units + unitnum;
3633 if (unit->t2d == texnum)
3635 if (unit->t3d == texnum)
3637 if (unit->tcubemap == texnum)
3638 unit->tcubemap = -1;
3642 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3644 gltextureunit_t *unit = gl_state.units + unitnum;
3645 int tex2d, tex3d, texcubemap, texnum;
3646 if (unitnum >= vid.teximageunits)
3648 // if (unit->texture == tex)
3650 switch(vid.renderpath)
3652 case RENDERPATH_GL20:
3653 case RENDERPATH_GLES2:
3656 tex = r_texture_white;
3657 // not initialized enough yet...
3661 unit->texture = tex;
3662 texnum = R_GetTexture(tex);
3663 switch(tex->gltexturetypeenum)
3665 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3666 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3667 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3670 case RENDERPATH_GL11:
3671 case RENDERPATH_GL13:
3672 case RENDERPATH_GLES1:
3673 unit->texture = tex;
3679 texnum = R_GetTexture(tex);
3680 switch(tex->gltexturetypeenum)
3688 case GL_TEXTURE_CUBE_MAP:
3689 texcubemap = texnum;
3693 // update 2d texture binding
3694 if (unit->t2d != tex2d)
3696 GL_ActiveTexture(unitnum);
3701 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3708 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3712 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3714 // update 3d texture binding
3715 if (unit->t3d != tex3d)
3717 GL_ActiveTexture(unitnum);
3722 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3729 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3733 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3735 // update cubemap texture binding
3736 if (unit->tcubemap != texcubemap)
3738 GL_ActiveTexture(unitnum);
3741 if (unit->tcubemap == 0)
3743 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3750 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3753 unit->tcubemap = texcubemap;
3754 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3757 case RENDERPATH_D3D9:
3760 extern cvar_t gl_texture_anisotropy;
3763 tex = r_texture_white;
3764 // not initialized enough yet...
3768 // upload texture if needed
3770 if (unit->texture == tex)
3772 unit->texture = tex;
3773 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3774 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3775 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3776 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3777 if (tex->d3daddressw)
3778 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3779 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3780 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3781 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3782 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3783 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3784 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3788 case RENDERPATH_D3D10:
3789 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3791 case RENDERPATH_D3D11:
3792 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3794 case RENDERPATH_SOFT:
3797 tex = r_texture_white;
3798 // not initialized enough yet...
3802 texnum = R_GetTexture(tex);
3803 if (unit->texture == tex)
3805 unit->texture = tex;
3806 DPSOFTRAST_SetTexture(unitnum, texnum);
3811 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3813 gltextureunit_t *unit = gl_state.units + unitnum;
3814 switch(vid.renderpath)
3816 case RENDERPATH_GL11:
3817 case RENDERPATH_GL13:
3818 case RENDERPATH_GL20:
3819 case RENDERPATH_GLES1:
3820 case RENDERPATH_GLES2:
3822 if (matrix && matrix->m[3][3])
3824 // texmatrix specified, check if it is different
3825 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3828 unit->texmatrixenabled = true;
3829 unit->matrix = *matrix;
3831 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3832 GL_ActiveTexture(unitnum);
3833 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3834 qglLoadMatrixf(glmatrix);CHECKGLERROR
3835 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3840 // no texmatrix specified, revert to identity
3841 if (unit->texmatrixenabled)
3843 unit->texmatrixenabled = false;
3844 unit->matrix = identitymatrix;
3846 GL_ActiveTexture(unitnum);
3847 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3848 qglLoadIdentity();CHECKGLERROR
3849 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3854 case RENDERPATH_D3D9:
3855 case RENDERPATH_D3D10:
3856 case RENDERPATH_D3D11:
3858 case RENDERPATH_SOFT:
3863 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3865 gltextureunit_t *unit = gl_state.units + unitnum;
3867 switch(vid.renderpath)
3869 case RENDERPATH_GL20:
3870 case RENDERPATH_GLES2:
3873 case RENDERPATH_GL13:
3874 case RENDERPATH_GLES1:
3875 #ifdef GL_TEXTURE_ENV
3876 // GL_ARB_texture_env_combine
3878 combinergb = GL_MODULATE;
3880 combinealpha = GL_MODULATE;
3885 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3887 if (combinergb == GL_DECAL)
3888 combinergb = GL_INTERPOLATE;
3889 if (unit->combine != GL_COMBINE)
3891 unit->combine = GL_COMBINE;
3892 GL_ActiveTexture(unitnum);
3893 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3894 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3896 if (unit->combinergb != combinergb)
3898 unit->combinergb = combinergb;
3899 GL_ActiveTexture(unitnum);
3900 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3902 if (unit->combinealpha != combinealpha)
3904 unit->combinealpha = combinealpha;
3905 GL_ActiveTexture(unitnum);
3906 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3908 if (unit->rgbscale != rgbscale)
3910 unit->rgbscale = rgbscale;
3911 GL_ActiveTexture(unitnum);
3912 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3914 if (unit->alphascale != alphascale)
3916 unit->alphascale = alphascale;
3917 GL_ActiveTexture(unitnum);
3918 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3923 if (unit->combine != combinergb)
3925 unit->combine = combinergb;
3926 GL_ActiveTexture(unitnum);
3927 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3932 case RENDERPATH_GL11:
3934 #ifdef GL_TEXTURE_ENV
3936 combinergb = GL_MODULATE;
3937 if (unit->combine != combinergb)
3939 unit->combine = combinergb;
3940 GL_ActiveTexture(unitnum);
3941 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3945 case RENDERPATH_D3D9:
3946 case RENDERPATH_D3D10:
3947 case RENDERPATH_D3D11:
3949 case RENDERPATH_SOFT:
3954 void R_Mesh_ResetTextureState(void)
3956 unsigned int unitnum;
3960 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3961 R_Mesh_TexBind(unitnum, NULL);
3962 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3963 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3964 switch(vid.renderpath)
3966 case RENDERPATH_GL20:
3967 case RENDERPATH_GLES2:
3968 case RENDERPATH_D3D9:
3969 case RENDERPATH_D3D10:
3970 case RENDERPATH_D3D11:
3971 case RENDERPATH_SOFT:
3973 case RENDERPATH_GL11:
3974 case RENDERPATH_GL13:
3975 case RENDERPATH_GLES1:
3976 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3978 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3979 R_Mesh_TexMatrix(unitnum, NULL);
3988 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3989 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3990 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3992 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3994 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3998 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
4000 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4001 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4002 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4006 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4008 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4009 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4010 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4011 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4012 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4013 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4014 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4018 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4019 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4020 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4023 static void R_Mesh_InitVertexDeclarations(void)
4026 r_vertex3f_d3d9decl = NULL;
4027 r_vertexgeneric_d3d9decl = NULL;
4028 r_vertexmesh_d3d9decl = NULL;
4029 switch(vid.renderpath)
4031 case RENDERPATH_GL20:
4032 case RENDERPATH_GL13:
4033 case RENDERPATH_GL11:
4034 case RENDERPATH_GLES1:
4035 case RENDERPATH_GLES2:
4037 case RENDERPATH_D3D9:
4038 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4039 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4040 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4042 case RENDERPATH_D3D10:
4043 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4045 case RENDERPATH_D3D11:
4046 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4048 case RENDERPATH_SOFT:
4054 static void R_Mesh_DestroyVertexDeclarations(void)
4057 if (r_vertex3f_d3d9decl)
4058 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4059 r_vertex3f_d3d9decl = NULL;
4060 if (r_vertexgeneric_d3d9decl)
4061 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4062 r_vertexgeneric_d3d9decl = NULL;
4063 if (r_vertexmesh_d3d9decl)
4064 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4065 r_vertexmesh_d3d9decl = NULL;
4069 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4071 // upload temporary vertexbuffer for this rendering
4072 if (!gl_state.usevbo_staticvertex)
4073 vertexbuffer = NULL;
4074 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4076 if (gl_state.preparevertices_dynamicvertexbuffer)
4077 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4079 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4080 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4082 switch(vid.renderpath)
4084 case RENDERPATH_GL20:
4085 case RENDERPATH_GLES2:
4088 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4089 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4090 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4091 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4092 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4093 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4094 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4098 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4099 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4100 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4101 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4102 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4103 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4104 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4107 case RENDERPATH_GL13:
4108 case RENDERPATH_GLES1:
4111 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4112 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4113 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4114 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4118 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4119 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4120 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4121 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4124 case RENDERPATH_GL11:
4127 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4128 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4129 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4133 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4134 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4135 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4138 case RENDERPATH_D3D9:
4140 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4142 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4144 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4145 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4146 gl_state.d3dvertexdata = (void *)vertex3f;
4147 gl_state.d3dvertexsize = sizeof(float[3]);
4150 case RENDERPATH_D3D10:
4151 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4153 case RENDERPATH_D3D11:
4154 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4156 case RENDERPATH_SOFT:
4157 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4158 DPSOFTRAST_SetColorPointer(NULL, 0);
4159 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4160 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4161 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4162 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4163 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4170 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4173 size = sizeof(r_vertexgeneric_t) * numvertices;
4174 if (gl_state.preparevertices_tempdatamaxsize < size)
4176 gl_state.preparevertices_tempdatamaxsize = size;
4177 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4179 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4180 gl_state.preparevertices_numvertices = numvertices;
4181 return gl_state.preparevertices_vertexgeneric;
4184 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4186 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4187 gl_state.preparevertices_vertexgeneric = NULL;
4188 gl_state.preparevertices_numvertices = 0;
4192 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4195 r_vertexgeneric_t *vertex;
4196 switch(vid.renderpath)
4198 case RENDERPATH_GL20:
4199 case RENDERPATH_GLES2:
4200 if (!vid.useinterleavedarrays)
4202 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4203 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4204 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4205 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4206 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4207 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4208 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4212 case RENDERPATH_GL11:
4213 case RENDERPATH_GL13:
4214 case RENDERPATH_GLES1:
4215 if (!vid.useinterleavedarrays)
4217 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4218 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4219 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4220 if (vid.texunits >= 2)
4221 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4222 if (vid.texunits >= 3)
4223 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4227 case RENDERPATH_D3D9:
4228 case RENDERPATH_D3D10:
4229 case RENDERPATH_D3D11:
4231 case RENDERPATH_SOFT:
4232 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4233 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4234 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4235 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4236 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4237 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4238 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4242 // no quick path for this case, convert to vertex structs
4243 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4244 for (i = 0;i < numvertices;i++)
4245 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4248 for (i = 0;i < numvertices;i++)
4249 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4253 for (i = 0;i < numvertices;i++)
4254 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4257 for (i = 0;i < numvertices;i++)
4258 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4259 R_Mesh_PrepareVertices_Generic_Unlock();
4260 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4263 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4265 // upload temporary vertexbuffer for this rendering
4266 if (!gl_state.usevbo_staticvertex)
4267 vertexbuffer = NULL;
4268 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4270 if (gl_state.preparevertices_dynamicvertexbuffer)
4271 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4273 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4274 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4276 switch(vid.renderpath)
4278 case RENDERPATH_GL20:
4279 case RENDERPATH_GLES2:
4282 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4283 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4284 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4285 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4286 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4287 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4288 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4292 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4293 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4294 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4295 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4296 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4297 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4298 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4301 case RENDERPATH_GL13:
4302 case RENDERPATH_GLES1:
4305 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4306 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4307 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4308 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4312 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4313 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4314 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4315 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4318 case RENDERPATH_GL11:
4321 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4322 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4323 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4327 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4328 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4329 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4332 case RENDERPATH_D3D9:
4334 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4336 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4338 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4339 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4340 gl_state.d3dvertexdata = (void *)vertex;
4341 gl_state.d3dvertexsize = sizeof(*vertex);
4344 case RENDERPATH_D3D10:
4345 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4347 case RENDERPATH_D3D11:
4348 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4350 case RENDERPATH_SOFT:
4351 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4352 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4353 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4354 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4355 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4356 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4357 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4364 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4367 size = sizeof(r_vertexmesh_t) * numvertices;
4368 if (gl_state.preparevertices_tempdatamaxsize < size)
4370 gl_state.preparevertices_tempdatamaxsize = size;
4371 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4373 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4374 gl_state.preparevertices_numvertices = numvertices;
4375 return gl_state.preparevertices_vertexmesh;
4378 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4380 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4381 gl_state.preparevertices_vertexmesh = NULL;
4382 gl_state.preparevertices_numvertices = 0;
4386 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)
4389 r_vertexmesh_t *vertex;
4390 switch(vid.renderpath)
4392 case RENDERPATH_GL20:
4393 case RENDERPATH_GLES2:
4394 if (!vid.useinterleavedarrays)
4396 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4397 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4398 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4399 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4400 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4401 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4402 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4406 case RENDERPATH_GL11:
4407 case RENDERPATH_GL13:
4408 case RENDERPATH_GLES1:
4409 if (!vid.useinterleavedarrays)
4411 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4412 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4413 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4414 if (vid.texunits >= 2)
4415 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4416 if (vid.texunits >= 3)
4417 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4421 case RENDERPATH_D3D9:
4422 case RENDERPATH_D3D10:
4423 case RENDERPATH_D3D11:
4425 case RENDERPATH_SOFT:
4426 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4427 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4428 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4429 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4430 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4431 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4432 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4436 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4437 for (i = 0;i < numvertices;i++)
4438 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4440 for (i = 0;i < numvertices;i++)
4441 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4443 for (i = 0;i < numvertices;i++)
4444 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4446 for (i = 0;i < numvertices;i++)
4447 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4450 for (i = 0;i < numvertices;i++)
4451 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4455 for (i = 0;i < numvertices;i++)
4456 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4458 if (texcoordtexture2f)
4459 for (i = 0;i < numvertices;i++)
4460 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4461 if (texcoordlightmap2f)
4462 for (i = 0;i < numvertices;i++)
4463 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4464 R_Mesh_PrepareVertices_Mesh_Unlock();
4465 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4468 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4470 // upload temporary vertexbuffer for this rendering
4471 if (!gl_state.usevbo_staticvertex)
4472 vertexbuffer = NULL;
4473 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4475 if (gl_state.preparevertices_dynamicvertexbuffer)
4476 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4478 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4479 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4481 switch(vid.renderpath)
4483 case RENDERPATH_GL20:
4484 case RENDERPATH_GLES2:
4487 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4488 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4489 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4490 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4491 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4492 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4493 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4497 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4498 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4499 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4500 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4501 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4502 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4503 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4506 case RENDERPATH_GL13:
4507 case RENDERPATH_GLES1:
4510 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4511 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4512 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4513 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4517 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4518 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4519 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4520 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4523 case RENDERPATH_GL11:
4526 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4527 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4528 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4532 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4533 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4534 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4537 case RENDERPATH_D3D9:
4539 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4541 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4543 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4544 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4545 gl_state.d3dvertexdata = (void *)vertex;
4546 gl_state.d3dvertexsize = sizeof(*vertex);
4549 case RENDERPATH_D3D10:
4550 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4552 case RENDERPATH_D3D11:
4553 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4555 case RENDERPATH_SOFT:
4556 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4557 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4558 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4559 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4560 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4561 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4562 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4567 void GL_BlendEquationSubtract(qboolean negated)
4571 switch(vid.renderpath)
4573 case RENDERPATH_GL11:
4574 case RENDERPATH_GL13:
4575 case RENDERPATH_GL20:
4576 case RENDERPATH_GLES1:
4577 case RENDERPATH_GLES2:
4578 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4580 case RENDERPATH_D3D9:
4582 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4585 case RENDERPATH_D3D10:
4586 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4588 case RENDERPATH_D3D11:
4589 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4591 case RENDERPATH_SOFT:
4592 DPSOFTRAST_BlendSubtract(true);
4598 switch(vid.renderpath)
4600 case RENDERPATH_GL11:
4601 case RENDERPATH_GL13:
4602 case RENDERPATH_GL20:
4603 case RENDERPATH_GLES1:
4604 case RENDERPATH_GLES2:
4605 qglBlendEquationEXT(GL_FUNC_ADD);
4607 case RENDERPATH_D3D9:
4609 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4612 case RENDERPATH_D3D10:
4613 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4615 case RENDERPATH_D3D11:
4616 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4618 case RENDERPATH_SOFT:
4619 DPSOFTRAST_BlendSubtract(false);