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 void GL_VBOStats_f(void)
352 GL_Mesh_ListVBOs(true);
355 static void GL_Backend_ResetState(void);
357 static void R_Mesh_InitVertexDeclarations(void);
358 static void R_Mesh_DestroyVertexDeclarations(void);
360 static void R_Mesh_SetUseVBO(void)
362 switch(vid.renderpath)
364 case RENDERPATH_GL11:
365 case RENDERPATH_GL13:
366 case RENDERPATH_GL20:
367 case RENDERPATH_GLES1:
368 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
369 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
370 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
371 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
373 case RENDERPATH_D3D9:
374 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
375 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
377 case RENDERPATH_D3D10:
378 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
380 case RENDERPATH_D3D11:
381 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
383 case RENDERPATH_SOFT:
384 gl_state.usevbo_staticvertex = false;
385 gl_state.usevbo_staticindex = false;
386 gl_state.usevbo_dynamicvertex = false;
387 gl_state.usevbo_dynamicindex = false;
389 case RENDERPATH_GLES2:
390 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
391 gl_state.usevbo_staticindex = false;
392 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
393 gl_state.usevbo_dynamicindex = false;
398 static void gl_backend_start(void)
400 memset(&gl_state, 0, sizeof(gl_state));
402 R_Mesh_InitVertexDeclarations();
405 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
407 Con_DPrintf("OpenGL backend started.\n");
411 GL_Backend_ResetState();
413 switch(vid.renderpath)
415 case RENDERPATH_GL11:
416 case RENDERPATH_GL13:
417 case RENDERPATH_GL20:
418 case RENDERPATH_GLES1:
419 case RENDERPATH_GLES2:
420 // fetch current fbo here (default fbo is not 0 on some GLES devices)
421 if (vid.support.ext_framebuffer_object)
422 qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);
424 case RENDERPATH_D3D9:
426 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
427 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
430 case RENDERPATH_D3D10:
431 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
433 case RENDERPATH_D3D11:
434 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
436 case RENDERPATH_SOFT:
441 static void gl_backend_shutdown(void)
443 Con_DPrint("OpenGL Backend shutting down\n");
445 switch(vid.renderpath)
447 case RENDERPATH_GL11:
448 case RENDERPATH_GL13:
449 case RENDERPATH_GL20:
450 case RENDERPATH_SOFT:
451 case RENDERPATH_GLES1:
452 case RENDERPATH_GLES2:
454 case RENDERPATH_D3D9:
456 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
457 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
460 case RENDERPATH_D3D10:
461 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
463 case RENDERPATH_D3D11:
464 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
468 if (gl_state.preparevertices_tempdata)
469 Mem_Free(gl_state.preparevertices_tempdata);
470 if (gl_state.preparevertices_dynamicvertexbuffer)
471 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
473 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
475 R_Mesh_DestroyVertexDeclarations();
477 memset(&gl_state, 0, sizeof(gl_state));
480 static void gl_backend_newmap(void)
484 static void gl_backend_devicelost(void)
487 r_meshbuffer_t *buffer;
489 gl_state.d3dvertexbuffer = NULL;
491 switch(vid.renderpath)
493 case RENDERPATH_GL11:
494 case RENDERPATH_GL13:
495 case RENDERPATH_GL20:
496 case RENDERPATH_SOFT:
497 case RENDERPATH_GLES1:
498 case RENDERPATH_GLES2:
500 case RENDERPATH_D3D9:
502 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
503 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
506 case RENDERPATH_D3D10:
507 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
509 case RENDERPATH_D3D11:
510 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
513 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
514 for (i = 0;i < endindex;i++)
516 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
517 if (!buffer || !buffer->isdynamic)
519 switch(vid.renderpath)
521 case RENDERPATH_GL11:
522 case RENDERPATH_GL13:
523 case RENDERPATH_GL20:
524 case RENDERPATH_SOFT:
525 case RENDERPATH_GLES1:
526 case RENDERPATH_GLES2:
528 case RENDERPATH_D3D9:
530 if (buffer->devicebuffer)
532 if (buffer->isindexbuffer)
533 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
535 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
536 buffer->devicebuffer = NULL;
540 case RENDERPATH_D3D10:
541 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
543 case RENDERPATH_D3D11:
544 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
550 static void gl_backend_devicerestored(void)
552 switch(vid.renderpath)
554 case RENDERPATH_GL11:
555 case RENDERPATH_GL13:
556 case RENDERPATH_GL20:
557 case RENDERPATH_SOFT:
558 case RENDERPATH_GLES1:
559 case RENDERPATH_GLES2:
561 case RENDERPATH_D3D9:
563 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
564 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
567 case RENDERPATH_D3D10:
568 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
570 case RENDERPATH_D3D11:
571 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
576 void gl_backend_init(void)
580 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
582 polygonelement3s[i * 3 + 0] = 0;
583 polygonelement3s[i * 3 + 1] = i + 1;
584 polygonelement3s[i * 3 + 2] = i + 2;
586 // elements for rendering a series of quads as triangles
587 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
589 quadelement3s[i * 6 + 0] = i * 4;
590 quadelement3s[i * 6 + 1] = i * 4 + 1;
591 quadelement3s[i * 6 + 2] = i * 4 + 2;
592 quadelement3s[i * 6 + 3] = i * 4;
593 quadelement3s[i * 6 + 4] = i * 4 + 2;
594 quadelement3s[i * 6 + 5] = i * 4 + 3;
597 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
598 polygonelement3i[i] = polygonelement3s[i];
599 for (i = 0;i < QUADELEMENTS_MAXQUADS*6;i++)
600 quadelement3i[i] = quadelement3s[i];
602 Cvar_RegisterVariable(&r_render);
603 Cvar_RegisterVariable(&r_renderview);
604 Cvar_RegisterVariable(&r_waterwarp);
605 Cvar_RegisterVariable(&gl_polyblend);
606 Cvar_RegisterVariable(&v_flipped);
607 Cvar_RegisterVariable(&gl_dither);
608 Cvar_RegisterVariable(&gl_vbo);
609 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
610 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
611 Cvar_RegisterVariable(&gl_paranoid);
612 Cvar_RegisterVariable(&gl_printcheckerror);
614 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
615 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
616 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
618 Cmd_AddCommand("gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
620 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
623 void GL_SetMirrorState(qboolean state);
625 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
629 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
630 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
632 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
634 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
635 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
636 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
638 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
643 switch(vid.renderpath)
645 case RENDERPATH_GL11:
646 case RENDERPATH_GL13:
647 case RENDERPATH_GL20:
648 case RENDERPATH_GLES1:
649 case RENDERPATH_GLES2:
652 case RENDERPATH_D3D9:
653 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
655 case RENDERPATH_D3D10:
656 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
658 case RENDERPATH_D3D11:
659 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
661 case RENDERPATH_SOFT:
667 static int bboxedges[12][2] =
686 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
688 int i, ix1, iy1, ix2, iy2;
689 float x1, y1, x2, y2;
700 scissor[0] = r_refdef.view.viewport.x;
701 scissor[1] = r_refdef.view.viewport.y;
702 scissor[2] = r_refdef.view.viewport.width;
703 scissor[3] = r_refdef.view.viewport.height;
705 // if view is inside the box, just say yes it's visible
706 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
709 x1 = y1 = x2 = y2 = 0;
711 // transform all corners that are infront of the nearclip plane
712 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
713 plane4f[3] = r_refdef.view.frustum[4].dist;
715 for (i = 0;i < 8;i++)
717 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
718 dist[i] = DotProduct4(corner[i], plane4f);
719 sign[i] = dist[i] > 0;
722 VectorCopy(corner[i], vertex[numvertices]);
726 // if some points are behind the nearclip, add clipped edge points to make
727 // sure that the scissor boundary is complete
728 if (numvertices > 0 && numvertices < 8)
730 // add clipped edge points
731 for (i = 0;i < 12;i++)
735 if (sign[j] != sign[k])
737 f = dist[j] / (dist[j] - dist[k]);
738 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
744 // if we have no points to check, it is behind the view plane
748 // if we have some points to transform, check what screen area is covered
749 x1 = y1 = x2 = y2 = 0;
751 //Con_Printf("%i vertices to transform...\n", numvertices);
752 for (i = 0;i < numvertices;i++)
754 VectorCopy(vertex[i], v);
755 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
756 //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
759 if (x1 > v2[0]) x1 = v2[0];
760 if (x2 < v2[0]) x2 = v2[0];
761 if (y1 > v2[1]) y1 = v2[1];
762 if (y2 < v2[1]) y2 = v2[1];
771 // now convert the scissor rectangle to integer screen coordinates
772 ix1 = (int)(x1 - 1.0f);
773 //iy1 = vid.height - (int)(y2 - 1.0f);
774 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
775 iy1 = (int)(y1 - 1.0f);
776 ix2 = (int)(x2 + 1.0f);
777 //iy2 = vid.height - (int)(y1 + 1.0f);
778 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
779 iy2 = (int)(y2 + 1.0f);
780 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
782 // clamp it to the screen
783 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
784 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
785 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
786 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
788 // if it is inside out, it's not visible
789 if (ix2 <= ix1 || iy2 <= iy1)
792 // the light area is visible, set up the scissor rectangle
795 scissor[2] = ix2 - ix1;
796 scissor[3] = iy2 - iy1;
798 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
799 switch(vid.renderpath)
801 case RENDERPATH_D3D9:
802 case RENDERPATH_D3D10:
803 case RENDERPATH_D3D11:
804 scissor[1] = vid.height - scissor[1] - scissor[3];
806 case RENDERPATH_GL11:
807 case RENDERPATH_GL13:
808 case RENDERPATH_GL20:
809 case RENDERPATH_SOFT:
810 case RENDERPATH_GLES1:
811 case RENDERPATH_GLES2:
819 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
823 float clipPlane[4], v3[3], v4[3];
826 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
828 VectorSet(normal, normalx, normaly, normalz);
829 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
830 VectorScale(normal, -dist, v3);
831 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
832 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
833 clipPlane[3] = -DotProduct(v4, clipPlane);
837 // testing code for comparing results
839 VectorCopy4(clipPlane, clipPlane2);
840 R_EntityMatrix(&identitymatrix);
841 VectorSet(q, normal[0], normal[1], normal[2], -dist);
842 qglClipPlane(GL_CLIP_PLANE0, q);
843 qglGetClipPlane(GL_CLIP_PLANE0, q);
844 VectorCopy4(q, clipPlane);
848 // Calculate the clip-space corner point opposite the clipping plane
849 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
850 // transform it into camera space by multiplying it
851 // by the inverse of the projection matrix
852 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
853 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
855 q[3] = (1.0f + m[10]) / m[14];
857 // Calculate the scaled plane vector
858 d = 2.0f / DotProduct4(clipPlane, q);
860 // Replace the third row of the projection matrix
861 m[2] = clipPlane[0] * d;
862 m[6] = clipPlane[1] * d;
863 m[10] = clipPlane[2] * d + 1.0f;
864 m[14] = clipPlane[3] * d;
867 void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float nearclip, float farclip, const float *nearplane)
869 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
871 memset(v, 0, sizeof(*v));
872 v->type = R_VIEWPORTTYPE_ORTHO;
873 v->cameramatrix = *cameramatrix;
880 memset(m, 0, sizeof(m));
881 m[0] = 2/(right - left);
882 m[5] = 2/(top - bottom);
883 m[10] = -2/(zFar - zNear);
884 m[12] = - (right + left)/(right - left);
885 m[13] = - (top + bottom)/(top - bottom);
886 m[14] = - (zFar + zNear)/(zFar - zNear);
888 switch(vid.renderpath)
890 case RENDERPATH_GL11:
891 case RENDERPATH_GL13:
892 case RENDERPATH_GL20:
893 case RENDERPATH_SOFT:
894 case RENDERPATH_GLES1:
895 case RENDERPATH_GLES2:
897 case RENDERPATH_D3D9:
898 case RENDERPATH_D3D10:
899 case RENDERPATH_D3D11:
900 m[10] = -1/(zFar - zNear);
901 m[14] = -zNear/(zFar-zNear);
904 v->screentodepth[0] = -farclip / (farclip - nearclip);
905 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
907 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
910 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
912 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
918 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
919 R_Viewport_TransformToScreen(v, test1, test2);
920 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
925 void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
927 matrix4x4_t tempmatrix, basematrix;
929 memset(v, 0, sizeof(*v));
931 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
932 v->cameramatrix = *cameramatrix;
939 memset(m, 0, sizeof(m));
940 m[0] = 1.0 / frustumx;
941 m[5] = 1.0 / frustumy;
942 m[10] = -(farclip + nearclip) / (farclip - nearclip);
944 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
945 v->screentodepth[0] = -farclip / (farclip - nearclip);
946 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
948 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
949 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
950 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
951 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
954 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
956 if(v_flipped.integer)
964 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
967 void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, const float *nearplane)
969 matrix4x4_t tempmatrix, basematrix;
970 const float nudge = 1.0 - 1.0 / (1<<23);
972 memset(v, 0, sizeof(*v));
974 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
975 v->cameramatrix = *cameramatrix;
982 memset(m, 0, sizeof(m));
983 m[ 0] = 1.0 / frustumx;
984 m[ 5] = 1.0 / frustumy;
987 m[14] = -2 * nearclip * nudge;
988 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
989 v->screentodepth[1] = m[14] * -0.5;
991 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
992 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
993 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
994 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
997 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
999 if(v_flipped.integer)
1007 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1010 float cubeviewmatrix[6][16] =
1012 // standard cubemap projections
1050 float rectviewmatrix[6][16] =
1052 // sign-preserving cubemap projections
1091 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
1093 matrix4x4_t tempmatrix, basematrix;
1095 memset(v, 0, sizeof(*v));
1096 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1097 v->cameramatrix = *cameramatrix;
1101 memset(m, 0, sizeof(m));
1103 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1105 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1107 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
1108 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1109 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1112 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1114 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1117 void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane)
1119 matrix4x4_t tempmatrix, basematrix;
1121 memset(v, 0, sizeof(*v));
1122 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1123 v->cameramatrix = *cameramatrix;
1124 v->x = (side & 1) * size;
1125 v->y = (side >> 1) * size;
1129 memset(m, 0, sizeof(m));
1130 m[0] = m[5] = 1.0f * ((float)size - border) / size;
1131 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1133 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1135 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
1136 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1137 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1139 switch(vid.renderpath)
1141 case RENDERPATH_GL20:
1142 case RENDERPATH_GL13:
1143 case RENDERPATH_GL11:
1144 case RENDERPATH_SOFT:
1145 case RENDERPATH_GLES1:
1146 case RENDERPATH_GLES2:
1148 case RENDERPATH_D3D9:
1151 case RENDERPATH_D3D10:
1152 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1154 case RENDERPATH_D3D11:
1155 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1160 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1162 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1165 void R_SetViewport(const r_viewport_t *v)
1170 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1171 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1173 // copy over the matrices to our state
1174 gl_viewmatrix = v->viewmatrix;
1175 gl_projectionmatrix = v->projectmatrix;
1177 switch(vid.renderpath)
1179 case RENDERPATH_GL13:
1180 case RENDERPATH_GL11:
1181 case RENDERPATH_GLES1:
1182 #ifdef GL_PROJECTION
1184 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1185 // Load the projection matrix into OpenGL
1186 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1187 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1188 qglLoadMatrixf(m);CHECKGLERROR
1189 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1192 case RENDERPATH_D3D9:
1195 D3DVIEWPORT9 d3dviewport;
1196 d3dviewport.X = gl_viewport.x;
1197 d3dviewport.Y = gl_viewport.y;
1198 d3dviewport.Width = gl_viewport.width;
1199 d3dviewport.Height = gl_viewport.height;
1200 d3dviewport.MinZ = gl_state.depthrange[0];
1201 d3dviewport.MaxZ = gl_state.depthrange[1];
1202 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1206 case RENDERPATH_D3D10:
1207 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1209 case RENDERPATH_D3D11:
1210 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1212 case RENDERPATH_SOFT:
1213 DPSOFTRAST_Viewport(v->x, v->y, v->width, v->height);
1215 case RENDERPATH_GL20:
1216 case RENDERPATH_GLES2:
1218 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1222 // force an update of the derived matrices
1223 gl_modelmatrixchanged = true;
1224 R_EntityMatrix(&gl_modelmatrix);
1227 void R_GetViewport(r_viewport_t *v)
1232 static void GL_BindVBO(int bufferobject)
1234 if (gl_state.vertexbufferobject != bufferobject)
1236 gl_state.vertexbufferobject = bufferobject;
1238 qglBindBufferARB(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
1242 static void GL_BindEBO(int bufferobject)
1244 if (gl_state.elementbufferobject != bufferobject)
1246 gl_state.elementbufferobject = bufferobject;
1248 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
1252 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1255 switch(vid.renderpath)
1257 case RENDERPATH_GL11:
1258 case RENDERPATH_GL13:
1259 case RENDERPATH_GL20:
1260 case RENDERPATH_GLES1:
1261 case RENDERPATH_GLES2:
1262 if (!vid.support.ext_framebuffer_object)
1264 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1265 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1266 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1267 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1268 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1269 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1270 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1272 case RENDERPATH_D3D9:
1273 case RENDERPATH_D3D10:
1274 case RENDERPATH_D3D11:
1276 case RENDERPATH_SOFT:
1282 void R_Mesh_DestroyFramebufferObject(int fbo)
1284 switch(vid.renderpath)
1286 case RENDERPATH_GL11:
1287 case RENDERPATH_GL13:
1288 case RENDERPATH_GL20:
1289 case RENDERPATH_GLES1:
1290 case RENDERPATH_GLES2:
1292 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1294 case RENDERPATH_D3D9:
1295 case RENDERPATH_D3D10:
1296 case RENDERPATH_D3D11:
1298 case RENDERPATH_SOFT:
1304 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1306 // LordHavoc: for some weird reason the redundant SetDepthStencilSurface calls are necessary (otherwise the lights fail depth test, as if they were using the shadowmap depth surface and render target still)
1307 if (gl_state.d3drt_depthsurface == depthsurface && gl_state.d3drt_colorsurfaces[0] == colorsurface0 && gl_state.d3drt_colorsurfaces[1] == colorsurface1 && gl_state.d3drt_colorsurfaces[2] == colorsurface2 && gl_state.d3drt_colorsurfaces[3] == colorsurface3)
1310 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1311 if (gl_state.d3drt_depthsurface != depthsurface)
1313 gl_state.d3drt_depthsurface = depthsurface;
1314 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1316 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1318 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1319 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1321 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1323 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1324 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1326 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1328 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1329 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1331 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1333 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1334 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1339 void R_Mesh_ResetRenderTargets(void)
1341 switch(vid.renderpath)
1343 case RENDERPATH_GL11:
1344 case RENDERPATH_GL13:
1345 case RENDERPATH_GL20:
1346 case RENDERPATH_GLES1:
1347 case RENDERPATH_GLES2:
1348 if (gl_state.framebufferobject)
1350 gl_state.framebufferobject = 0;
1351 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1354 case RENDERPATH_D3D9:
1356 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1359 case RENDERPATH_D3D10:
1360 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1362 case RENDERPATH_D3D11:
1363 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1365 case RENDERPATH_SOFT:
1366 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1371 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1375 rtexture_t *textures[5];
1376 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1377 textures[4] = depthtexture;
1378 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1379 for (j = 0;j < 5;j++)
1381 for (i = 0;i < vid.teximageunits;i++)
1382 if (gl_state.units[i].texture == textures[j])
1383 R_Mesh_TexBind(i, NULL);
1384 // set up framebuffer object or render targets for the active rendering API
1385 switch(vid.renderpath)
1387 case RENDERPATH_GL11:
1388 case RENDERPATH_GL13:
1389 case RENDERPATH_GL20:
1390 case RENDERPATH_GLES1:
1391 case RENDERPATH_GLES2:
1392 if (gl_state.framebufferobject != fbo)
1394 gl_state.framebufferobject = fbo;
1395 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1398 case RENDERPATH_D3D9:
1400 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1401 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1404 IDirect3DSurface9 *colorsurfaces[4];
1405 for (i = 0;i < 4;i++)
1407 colorsurfaces[i] = NULL;
1409 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1411 // set the render targets for real
1412 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1413 // release the texture surface levels (they won't be lost while bound...)
1414 for (i = 0;i < 4;i++)
1416 IDirect3DSurface9_Release(colorsurfaces[i]);
1419 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1422 case RENDERPATH_D3D10:
1423 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1425 case RENDERPATH_D3D11:
1426 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1428 case RENDERPATH_SOFT:
1432 unsigned int *pointers[5];
1433 memset(pointers, 0, sizeof(pointers));
1434 for (i = 0;i < 5;i++)
1435 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1436 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1437 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1438 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1441 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1447 static int d3dcmpforglfunc(int f)
1451 case GL_NEVER: return D3DCMP_NEVER;
1452 case GL_LESS: return D3DCMP_LESS;
1453 case GL_EQUAL: return D3DCMP_EQUAL;
1454 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1455 case GL_GREATER: return D3DCMP_GREATER;
1456 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1457 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1458 case GL_ALWAYS: return D3DCMP_ALWAYS;
1459 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1463 static int d3dstencilopforglfunc(int f)
1467 case GL_KEEP: return D3DSTENCILOP_KEEP;
1468 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1469 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1470 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1475 extern cvar_t r_transparent_alphatocoverage;
1477 static void GL_Backend_ResetState(void)
1480 gl_state.active = true;
1481 gl_state.depthtest = true;
1482 gl_state.alphatest = false;
1483 gl_state.alphafunc = GL_GEQUAL;
1484 gl_state.alphafuncvalue = 0.5f;
1485 gl_state.alphatocoverage = false;
1486 gl_state.blendfunc1 = GL_ONE;
1487 gl_state.blendfunc2 = GL_ZERO;
1488 gl_state.blend = false;
1489 gl_state.depthmask = GL_TRUE;
1490 gl_state.colormask = 15;
1491 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1492 gl_state.lockrange_first = 0;
1493 gl_state.lockrange_count = 0;
1494 gl_state.cullface = GL_FRONT;
1495 gl_state.cullfaceenable = false;
1496 gl_state.polygonoffset[0] = 0;
1497 gl_state.polygonoffset[1] = 0;
1498 gl_state.framebufferobject = 0;
1499 gl_state.depthfunc = GL_LEQUAL;
1501 switch(vid.renderpath)
1503 case RENDERPATH_D3D9:
1506 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1507 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1508 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1509 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1510 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1511 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1512 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1516 case RENDERPATH_D3D10:
1517 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1519 case RENDERPATH_D3D11:
1520 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1522 case RENDERPATH_GL11:
1523 case RENDERPATH_GL13:
1524 case RENDERPATH_GLES1:
1525 #ifdef GL_ALPHA_TEST
1528 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1529 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1530 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1531 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1532 qglDisable(GL_BLEND);CHECKGLERROR
1533 qglCullFace(gl_state.cullface);CHECKGLERROR
1534 qglDisable(GL_CULL_FACE);CHECKGLERROR
1535 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1536 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1537 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1538 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1540 if (vid.support.arb_vertex_buffer_object)
1542 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1543 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1546 if (vid.support.ext_framebuffer_object)
1548 //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
1549 qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
1552 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1553 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1555 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1556 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1557 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1559 if (vid.support.ext_framebuffer_object)
1560 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
1562 gl_state.unit = MAX_TEXTUREUNITS;
1563 gl_state.clientunit = MAX_TEXTUREUNITS;
1564 for (i = 0;i < vid.texunits;i++)
1566 GL_ActiveTexture(i);
1567 GL_ClientActiveTexture(i);
1568 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1569 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1570 if (vid.support.ext_texture_3d)
1572 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1573 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1575 if (vid.support.arb_texture_cube_map)
1577 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
1578 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1581 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1582 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1583 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1584 qglLoadIdentity();CHECKGLERROR
1585 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1586 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1591 case RENDERPATH_SOFT:
1592 DPSOFTRAST_ColorMask(1,1,1,1);
1593 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1594 DPSOFTRAST_CullFace(gl_state.cullface);
1595 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1596 DPSOFTRAST_DepthMask(gl_state.depthmask);
1597 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1598 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1599 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1601 case RENDERPATH_GL20:
1602 case RENDERPATH_GLES2:
1604 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1605 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1606 qglDisable(GL_BLEND);CHECKGLERROR
1607 qglCullFace(gl_state.cullface);CHECKGLERROR
1608 qglDisable(GL_CULL_FACE);CHECKGLERROR
1609 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1610 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1611 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1612 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1613 if (vid.support.arb_vertex_buffer_object)
1615 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1616 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1618 if (vid.support.ext_framebuffer_object)
1619 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1620 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1621 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1622 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1623 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1624 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1625 gl_state.unit = MAX_TEXTUREUNITS;
1626 gl_state.clientunit = MAX_TEXTUREUNITS;
1627 for (i = 0;i < vid.teximageunits;i++)
1629 GL_ActiveTexture(i);
1630 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1631 if (vid.support.ext_texture_3d)
1633 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1635 if (vid.support.arb_texture_cube_map)
1637 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1640 for (i = 0;i < vid.texarrayunits;i++)
1643 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1644 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1651 void GL_ActiveTexture(unsigned int num)
1653 if (gl_state.unit != num)
1655 gl_state.unit = num;
1656 switch(vid.renderpath)
1658 case RENDERPATH_GL11:
1659 case RENDERPATH_GL13:
1660 case RENDERPATH_GL20:
1661 case RENDERPATH_GLES1:
1662 case RENDERPATH_GLES2:
1663 if (qglActiveTexture)
1666 qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
1670 case RENDERPATH_D3D9:
1671 case RENDERPATH_D3D10:
1672 case RENDERPATH_D3D11:
1674 case RENDERPATH_SOFT:
1680 void GL_ClientActiveTexture(unsigned int num)
1682 if (gl_state.clientunit != num)
1684 gl_state.clientunit = num;
1685 switch(vid.renderpath)
1687 case RENDERPATH_GL11:
1688 case RENDERPATH_GL13:
1689 case RENDERPATH_GLES1:
1690 if (qglActiveTexture)
1693 qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit);
1697 case RENDERPATH_D3D9:
1698 case RENDERPATH_D3D10:
1699 case RENDERPATH_D3D11:
1701 case RENDERPATH_SOFT:
1703 case RENDERPATH_GL20:
1704 case RENDERPATH_GLES2:
1710 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1712 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1714 qboolean blendenable;
1715 gl_state.blendfunc1 = blendfunc1;
1716 gl_state.blendfunc2 = blendfunc2;
1717 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1718 switch(vid.renderpath)
1720 case RENDERPATH_GL11:
1721 case RENDERPATH_GL13:
1722 case RENDERPATH_GL20:
1723 case RENDERPATH_GLES1:
1724 case RENDERPATH_GLES2:
1726 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1727 if (gl_state.blend != blendenable)
1729 gl_state.blend = blendenable;
1730 if (!gl_state.blend)
1732 qglDisable(GL_BLEND);CHECKGLERROR
1736 qglEnable(GL_BLEND);CHECKGLERROR
1740 case RENDERPATH_D3D9:
1745 D3DBLEND d3dblendfunc[2];
1746 glblendfunc[0] = gl_state.blendfunc1;
1747 glblendfunc[1] = gl_state.blendfunc2;
1748 for (i = 0;i < 2;i++)
1750 switch(glblendfunc[i])
1752 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1753 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1754 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1755 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1756 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1757 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1758 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1759 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1760 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1761 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1764 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1765 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1766 if (gl_state.blend != blendenable)
1768 gl_state.blend = blendenable;
1769 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1774 case RENDERPATH_D3D10:
1775 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1777 case RENDERPATH_D3D11:
1778 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1780 case RENDERPATH_SOFT:
1781 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1787 void GL_DepthMask(int state)
1789 if (gl_state.depthmask != state)
1791 gl_state.depthmask = state;
1792 switch(vid.renderpath)
1794 case RENDERPATH_GL11:
1795 case RENDERPATH_GL13:
1796 case RENDERPATH_GL20:
1797 case RENDERPATH_GLES1:
1798 case RENDERPATH_GLES2:
1800 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1802 case RENDERPATH_D3D9:
1804 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1807 case RENDERPATH_D3D10:
1808 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1810 case RENDERPATH_D3D11:
1811 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1813 case RENDERPATH_SOFT:
1814 DPSOFTRAST_DepthMask(gl_state.depthmask);
1820 void GL_DepthTest(int state)
1822 if (gl_state.depthtest != state)
1824 gl_state.depthtest = state;
1825 switch(vid.renderpath)
1827 case RENDERPATH_GL11:
1828 case RENDERPATH_GL13:
1829 case RENDERPATH_GL20:
1830 case RENDERPATH_GLES1:
1831 case RENDERPATH_GLES2:
1833 if (gl_state.depthtest)
1835 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1839 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1842 case RENDERPATH_D3D9:
1844 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1847 case RENDERPATH_D3D10:
1848 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1850 case RENDERPATH_D3D11:
1851 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1853 case RENDERPATH_SOFT:
1854 DPSOFTRAST_DepthTest(gl_state.depthtest);
1860 void GL_DepthFunc(int state)
1862 if (gl_state.depthfunc != state)
1864 gl_state.depthfunc = state;
1865 switch(vid.renderpath)
1867 case RENDERPATH_GL11:
1868 case RENDERPATH_GL13:
1869 case RENDERPATH_GL20:
1870 case RENDERPATH_GLES1:
1871 case RENDERPATH_GLES2:
1873 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1875 case RENDERPATH_D3D9:
1877 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1880 case RENDERPATH_D3D10:
1881 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1883 case RENDERPATH_D3D11:
1884 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1886 case RENDERPATH_SOFT:
1887 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1893 void GL_DepthRange(float nearfrac, float farfrac)
1895 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1897 gl_state.depthrange[0] = nearfrac;
1898 gl_state.depthrange[1] = farfrac;
1899 switch(vid.renderpath)
1901 case RENDERPATH_GL11:
1902 case RENDERPATH_GL13:
1903 case RENDERPATH_GL20:
1904 case RENDERPATH_GLES1:
1905 case RENDERPATH_GLES2:
1907 qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
1909 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1912 case RENDERPATH_D3D9:
1915 D3DVIEWPORT9 d3dviewport;
1916 d3dviewport.X = gl_viewport.x;
1917 d3dviewport.Y = gl_viewport.y;
1918 d3dviewport.Width = gl_viewport.width;
1919 d3dviewport.Height = gl_viewport.height;
1920 d3dviewport.MinZ = gl_state.depthrange[0];
1921 d3dviewport.MaxZ = gl_state.depthrange[1];
1922 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1926 case RENDERPATH_D3D10:
1927 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1929 case RENDERPATH_D3D11:
1930 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1932 case RENDERPATH_SOFT:
1933 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1939 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)
1941 switch (vid.renderpath)
1943 case RENDERPATH_GL11:
1944 case RENDERPATH_GL13:
1945 case RENDERPATH_GL20:
1946 case RENDERPATH_GLES1:
1947 case RENDERPATH_GLES2:
1951 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1955 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1957 if (vid.support.ati_separate_stencil)
1959 qglStencilMask(writemask);CHECKGLERROR
1960 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1961 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1962 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1964 else if (vid.support.ext_stencil_two_side)
1966 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1967 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1968 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1969 qglStencilMask(writemask);CHECKGLERROR
1970 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1971 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1972 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1973 qglStencilMask(writemask);CHECKGLERROR
1974 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1975 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1979 case RENDERPATH_D3D9:
1981 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1982 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1983 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1984 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1985 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1986 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1987 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1988 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1989 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1990 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1991 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1992 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1993 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1996 case RENDERPATH_D3D10:
1997 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1999 case RENDERPATH_D3D11:
2000 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2002 case RENDERPATH_SOFT:
2003 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2008 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
2010 switch (vid.renderpath)
2012 case RENDERPATH_GL11:
2013 case RENDERPATH_GL13:
2014 case RENDERPATH_GL20:
2015 case RENDERPATH_GLES1:
2016 case RENDERPATH_GLES2:
2020 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
2024 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
2026 if (vid.support.ext_stencil_two_side)
2028 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
2029 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2032 qglStencilMask(writemask);CHECKGLERROR
2033 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2034 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2037 case RENDERPATH_D3D9:
2039 if (vid.support.ati_separate_stencil)
2040 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2041 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2042 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2043 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2044 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2045 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2046 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2047 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2048 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2051 case RENDERPATH_D3D10:
2052 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2054 case RENDERPATH_D3D11:
2055 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2057 case RENDERPATH_SOFT:
2058 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2063 void GL_PolygonOffset(float planeoffset, float depthoffset)
2065 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2067 gl_state.polygonoffset[0] = planeoffset;
2068 gl_state.polygonoffset[1] = depthoffset;
2069 switch(vid.renderpath)
2071 case RENDERPATH_GL11:
2072 case RENDERPATH_GL13:
2073 case RENDERPATH_GL20:
2074 case RENDERPATH_GLES1:
2075 case RENDERPATH_GLES2:
2076 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2078 case RENDERPATH_D3D9:
2080 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2081 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2084 case RENDERPATH_D3D10:
2085 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2087 case RENDERPATH_D3D11:
2088 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2090 case RENDERPATH_SOFT:
2091 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2097 void GL_SetMirrorState(qboolean state)
2099 if (v_flipped_state != state)
2101 v_flipped_state = state;
2102 if (gl_state.cullface == GL_BACK)
2103 gl_state.cullface = GL_FRONT;
2104 else if (gl_state.cullface == GL_FRONT)
2105 gl_state.cullface = GL_BACK;
2108 switch(vid.renderpath)
2110 case RENDERPATH_GL11:
2111 case RENDERPATH_GL13:
2112 case RENDERPATH_GL20:
2113 case RENDERPATH_GLES1:
2114 case RENDERPATH_GLES2:
2115 qglCullFace(gl_state.cullface);CHECKGLERROR
2117 case RENDERPATH_D3D9:
2119 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2122 case RENDERPATH_D3D10:
2123 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2125 case RENDERPATH_D3D11:
2126 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2128 case RENDERPATH_SOFT:
2129 DPSOFTRAST_CullFace(gl_state.cullface);
2135 void GL_CullFace(int state)
2139 if(state == GL_FRONT)
2141 else if(state == GL_BACK)
2145 switch(vid.renderpath)
2147 case RENDERPATH_GL11:
2148 case RENDERPATH_GL13:
2149 case RENDERPATH_GL20:
2150 case RENDERPATH_GLES1:
2151 case RENDERPATH_GLES2:
2154 if (state != GL_NONE)
2156 if (!gl_state.cullfaceenable)
2158 gl_state.cullfaceenable = true;
2159 qglEnable(GL_CULL_FACE);CHECKGLERROR
2161 if (gl_state.cullface != state)
2163 gl_state.cullface = state;
2164 qglCullFace(gl_state.cullface);CHECKGLERROR
2169 if (gl_state.cullfaceenable)
2171 gl_state.cullfaceenable = false;
2172 qglDisable(GL_CULL_FACE);CHECKGLERROR
2176 case RENDERPATH_D3D9:
2178 if (gl_state.cullface != state)
2180 gl_state.cullface = state;
2181 switch(gl_state.cullface)
2184 gl_state.cullfaceenable = false;
2185 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2188 gl_state.cullfaceenable = true;
2189 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2192 gl_state.cullfaceenable = true;
2193 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2199 case RENDERPATH_D3D10:
2200 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2202 case RENDERPATH_D3D11:
2203 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2205 case RENDERPATH_SOFT:
2206 if (gl_state.cullface != state)
2208 gl_state.cullface = state;
2209 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2210 DPSOFTRAST_CullFace(gl_state.cullface);
2216 void GL_AlphaTest(int state)
2218 if (gl_state.alphatest != state)
2220 gl_state.alphatest = state;
2221 switch(vid.renderpath)
2223 case RENDERPATH_GL11:
2224 case RENDERPATH_GL13:
2225 case RENDERPATH_GLES1:
2226 #ifdef GL_ALPHA_TEST
2227 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2229 if (gl_state.alphatest)
2231 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2235 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2239 case RENDERPATH_D3D9:
2240 case RENDERPATH_D3D10:
2241 case RENDERPATH_D3D11:
2242 case RENDERPATH_SOFT:
2243 case RENDERPATH_GL20:
2244 case RENDERPATH_GLES2:
2250 void GL_AlphaToCoverage(qboolean state)
2252 if (gl_state.alphatocoverage != state)
2254 gl_state.alphatocoverage = state;
2255 switch(vid.renderpath)
2257 case RENDERPATH_GL11:
2258 case RENDERPATH_GL13:
2259 case RENDERPATH_GLES1:
2260 case RENDERPATH_GLES2:
2261 case RENDERPATH_D3D9:
2262 case RENDERPATH_D3D10:
2263 case RENDERPATH_D3D11:
2264 case RENDERPATH_SOFT:
2266 case RENDERPATH_GL20:
2267 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2268 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2270 if (gl_state.alphatocoverage)
2272 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2273 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2277 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2278 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2286 void GL_ColorMask(int r, int g, int b, int a)
2288 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2289 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2290 if (gl_state.colormask != state)
2292 gl_state.colormask = state;
2293 switch(vid.renderpath)
2295 case RENDERPATH_GL11:
2296 case RENDERPATH_GL13:
2297 case RENDERPATH_GL20:
2298 case RENDERPATH_GLES1:
2299 case RENDERPATH_GLES2:
2301 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2303 case RENDERPATH_D3D9:
2305 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2308 case RENDERPATH_D3D10:
2309 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2311 case RENDERPATH_D3D11:
2312 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2314 case RENDERPATH_SOFT:
2315 DPSOFTRAST_ColorMask(r, g, b, a);
2321 void GL_Color(float cr, float cg, float cb, float ca)
2323 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)
2325 gl_state.color4f[0] = cr;
2326 gl_state.color4f[1] = cg;
2327 gl_state.color4f[2] = cb;
2328 gl_state.color4f[3] = ca;
2329 switch(vid.renderpath)
2331 case RENDERPATH_GL11:
2332 case RENDERPATH_GL13:
2333 case RENDERPATH_GLES1:
2335 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2338 case RENDERPATH_D3D9:
2339 case RENDERPATH_D3D10:
2340 case RENDERPATH_D3D11:
2341 // no equivalent in D3D
2343 case RENDERPATH_SOFT:
2344 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2346 case RENDERPATH_GL20:
2347 case RENDERPATH_GLES2:
2348 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2354 void GL_Scissor (int x, int y, int width, int height)
2356 switch(vid.renderpath)
2358 case RENDERPATH_GL11:
2359 case RENDERPATH_GL13:
2360 case RENDERPATH_GL20:
2361 case RENDERPATH_GLES1:
2362 case RENDERPATH_GLES2:
2364 qglScissor(x, y,width,height);
2367 case RENDERPATH_D3D9:
2373 d3drect.right = x + width;
2374 d3drect.bottom = y + height;
2375 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2379 case RENDERPATH_D3D10:
2380 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2382 case RENDERPATH_D3D11:
2383 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2385 case RENDERPATH_SOFT:
2386 DPSOFTRAST_Scissor(x, y, width, height);
2391 void GL_ScissorTest(int state)
2393 if (gl_state.scissortest != state)
2395 gl_state.scissortest = state;
2396 switch(vid.renderpath)
2398 case RENDERPATH_GL11:
2399 case RENDERPATH_GL13:
2400 case RENDERPATH_GL20:
2401 case RENDERPATH_GLES1:
2402 case RENDERPATH_GLES2:
2404 if(gl_state.scissortest)
2405 qglEnable(GL_SCISSOR_TEST);
2407 qglDisable(GL_SCISSOR_TEST);
2410 case RENDERPATH_D3D9:
2412 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2415 case RENDERPATH_D3D10:
2416 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2418 case RENDERPATH_D3D11:
2419 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2421 case RENDERPATH_SOFT:
2422 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2428 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2430 static const float blackcolor[4] = {0, 0, 0, 0};
2431 // prevent warnings when trying to clear a buffer that does not exist
2433 colorvalue = blackcolor;
2436 mask &= ~GL_STENCIL_BUFFER_BIT;
2439 switch(vid.renderpath)
2441 case RENDERPATH_GL11:
2442 case RENDERPATH_GL13:
2443 case RENDERPATH_GL20:
2444 case RENDERPATH_GLES1:
2445 case RENDERPATH_GLES2:
2447 if (mask & GL_COLOR_BUFFER_BIT)
2449 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2451 if (mask & GL_DEPTH_BUFFER_BIT)
2454 qglClearDepthf(depthvalue);CHECKGLERROR
2456 qglClearDepth(depthvalue);CHECKGLERROR
2459 if (mask & GL_STENCIL_BUFFER_BIT)
2461 qglClearStencil(stencilvalue);CHECKGLERROR
2463 qglClear(mask);CHECKGLERROR
2465 case RENDERPATH_D3D9:
2467 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);
2470 case RENDERPATH_D3D10:
2471 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2473 case RENDERPATH_D3D11:
2474 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2476 case RENDERPATH_SOFT:
2477 if (mask & GL_COLOR_BUFFER_BIT)
2478 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2479 if (mask & GL_DEPTH_BUFFER_BIT)
2480 DPSOFTRAST_ClearDepth(depthvalue);
2485 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2487 switch(vid.renderpath)
2489 case RENDERPATH_GL11:
2490 case RENDERPATH_GL13:
2491 case RENDERPATH_GL20:
2492 case RENDERPATH_GLES1:
2493 case RENDERPATH_GLES2:
2495 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2497 case RENDERPATH_D3D9:
2500 // LordHavoc: we can't directly download the backbuffer because it may be
2501 // multisampled, and it may not be lockable, so we blit it to a lockable
2502 // surface of the same dimensions (but without multisample) to resolve the
2503 // multisample buffer to a normal image, and then lock that...
2504 IDirect3DSurface9 *stretchsurface = NULL;
2505 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2507 D3DLOCKED_RECT lockedrect;
2508 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2510 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2513 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2514 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2515 memcpy(outpixels + line * width * 4, row, width * 4);
2516 IDirect3DSurface9_UnlockRect(stretchsurface);
2519 IDirect3DSurface9_Release(stretchsurface);
2522 //IDirect3DSurface9 *syssurface = NULL;
2523 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2524 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2525 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2526 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2527 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2528 //IDirect3DSurface9_UnlockRect(syssurface);
2529 //IDirect3DSurface9_Release(syssurface);
2533 case RENDERPATH_D3D10:
2534 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2536 case RENDERPATH_D3D11:
2537 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2539 case RENDERPATH_SOFT:
2540 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2545 // called at beginning of frame
2546 void R_Mesh_Start(void)
2549 R_Mesh_ResetRenderTargets();
2551 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2553 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2554 Cvar_SetValueQuick(&gl_paranoid, 1);
2558 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2562 char compilelog[MAX_INPUTLINE];
2563 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2566 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2567 qglCompileShader(shaderobject);CHECKGLERROR
2568 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2569 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2570 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2572 int i, j, pretextlines = 0;
2573 for (i = 0;i < numstrings - 1;i++)
2574 for (j = 0;strings[i][j];j++)
2575 if (strings[i][j] == '\n')
2577 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2579 if (!shadercompiled)
2581 qglDeleteShader(shaderobject);CHECKGLERROR
2584 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2585 qglDeleteShader(shaderobject);CHECKGLERROR
2589 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)
2591 GLint programlinked;
2592 GLuint programobject = 0;
2593 char linklog[MAX_INPUTLINE];
2596 programobject = qglCreateProgram();CHECKGLERROR
2600 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2601 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2602 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2603 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2604 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2605 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2606 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2607 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2608 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2609 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2611 if(vid.support.gl20shaders130)
2612 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2615 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2618 #ifdef GL_GEOMETRY_SHADER
2619 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2623 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2626 qglLinkProgram(programobject);CHECKGLERROR
2627 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2628 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2631 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2632 Con_DPrintf("program link log:\n%s\n", linklog);
2633 // software vertex shader is ok but software fragment shader is WAY
2634 // too slow, fail program if so.
2635 // NOTE: this string might be ATI specific, but that's ok because the
2636 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2637 // software fragment shader due to low instruction and dependent
2639 if (strstr(linklog, "fragment shader will run in software"))
2640 programlinked = false;
2644 return programobject;
2646 qglDeleteProgram(programobject);CHECKGLERROR
2650 void GL_Backend_FreeProgram(unsigned int prog)
2653 qglDeleteProgram(prog);
2657 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2662 for (i = 0;i < count;i++)
2663 *out++ = *in++ + offset;
2666 memcpy(out, in, sizeof(*out) * count);
2669 // renders triangles using vertices from the active arrays
2670 int paranoidblah = 0;
2671 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)
2673 unsigned int numelements = numtriangles * 3;
2675 size_t bufferoffset3i;
2677 size_t bufferoffset3s;
2678 if (numvertices < 3 || numtriangles < 1)
2680 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2681 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);
2684 if (!gl_mesh_prefer_short_elements.integer)
2688 if (element3i_indexbuffer)
2689 element3i_indexbuffer = NULL;
2691 // adjust the pointers for firsttriangle
2693 element3i += firsttriangle * 3;
2694 if (element3i_indexbuffer)
2695 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2697 element3s += firsttriangle * 3;
2698 if (element3s_indexbuffer)
2699 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2700 switch(vid.renderpath)
2702 case RENDERPATH_GL11:
2703 case RENDERPATH_GL13:
2704 case RENDERPATH_GL20:
2705 case RENDERPATH_GLES1:
2706 case RENDERPATH_GLES2:
2707 // check if the user specified to ignore static index buffers
2708 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2710 element3i_indexbuffer = NULL;
2711 element3s_indexbuffer = NULL;
2714 case RENDERPATH_D3D9:
2715 case RENDERPATH_D3D10:
2716 case RENDERPATH_D3D11:
2718 case RENDERPATH_SOFT:
2721 // upload a dynamic index buffer if needed
2724 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2726 if (gl_state.draw_dynamicindexbuffer)
2727 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2729 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2730 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2731 element3s_bufferoffset = 0;
2736 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2738 if (gl_state.draw_dynamicindexbuffer)
2739 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2741 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2742 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2743 element3i_bufferoffset = 0;
2746 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2747 bufferoffset3i = element3i_bufferoffset;
2748 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2749 bufferoffset3s = element3s_bufferoffset;
2750 r_refdef.stats.draws++;
2751 r_refdef.stats.draws_vertices += numvertices;
2752 r_refdef.stats.draws_elements += numelements;
2753 if (gl_paranoid.integer)
2756 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2758 unsigned int j, size;
2760 // note: there's no validation done here on buffer objects because it
2761 // is somewhat difficult to get at the data, and gl_paranoid can be
2762 // used without buffer objects if the need arises
2763 // (the data could be gotten using glMapBuffer but it would be very
2764 // slow due to uncachable video memory reads)
2765 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2766 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2768 if (gl_state.pointer_vertex_pointer)
2769 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2771 if (gl_state.pointer_color_enabled)
2773 if (!qglIsEnabled(GL_COLOR_ARRAY))
2774 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2776 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2777 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2780 for (i = 0;i < vid.texarrayunits;i++)
2782 if (gl_state.units[i].arrayenabled)
2784 GL_ClientActiveTexture(i);
2785 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2786 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2788 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2789 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++)
2796 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2798 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2800 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2807 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2809 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2811 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2817 if (r_render.integer || r_refdef.draw2dstage)
2819 switch(vid.renderpath)
2821 case RENDERPATH_GL11:
2822 case RENDERPATH_GL13:
2823 case RENDERPATH_GL20:
2825 if (gl_mesh_testmanualfeeding.integer)
2828 unsigned int i, j, element;
2830 qglBegin(GL_TRIANGLES);
2831 if(vid.renderpath == RENDERPATH_GL20)
2833 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2836 element = element3i[i];
2838 element = element3s[i];
2840 element = firstvertex + i;
2841 for (j = 0;j < vid.texarrayunits;j++)
2843 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2845 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2847 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2848 if (gl_state.units[j].pointer_texcoord_components == 4)
2849 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2850 else if (gl_state.units[j].pointer_texcoord_components == 3)
2851 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2852 else if (gl_state.units[j].pointer_texcoord_components == 2)
2853 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2855 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2857 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2859 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2860 if (gl_state.units[j].pointer_texcoord_components == 4)
2861 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2862 else if (gl_state.units[j].pointer_texcoord_components == 3)
2863 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2864 else if (gl_state.units[j].pointer_texcoord_components == 2)
2865 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2866 else if (gl_state.units[j].pointer_texcoord_components == 1)
2867 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2869 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2871 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2872 if (gl_state.units[j].pointer_texcoord_components == 4)
2873 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2874 else if (gl_state.units[j].pointer_texcoord_components == 3)
2875 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2876 else if (gl_state.units[j].pointer_texcoord_components == 2)
2877 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2878 else if (gl_state.units[j].pointer_texcoord_components == 1)
2879 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2883 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2885 if (gl_state.pointer_color_gltype == GL_FLOAT)
2887 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2888 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2890 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2892 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2893 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2896 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2898 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2899 if (gl_state.pointer_vertex_components == 4)
2900 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2901 else if (gl_state.pointer_vertex_components == 3)
2902 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2904 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2910 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2913 element = element3i[i];
2915 element = element3s[i];
2917 element = firstvertex + i;
2918 for (j = 0;j < vid.texarrayunits;j++)
2920 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2922 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2924 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2925 if (vid.texarrayunits > 1)
2927 if (gl_state.units[j].pointer_texcoord_components == 4)
2928 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2929 else if (gl_state.units[j].pointer_texcoord_components == 3)
2930 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2931 else if (gl_state.units[j].pointer_texcoord_components == 2)
2932 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2934 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2938 if (gl_state.units[j].pointer_texcoord_components == 4)
2939 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2940 else if (gl_state.units[j].pointer_texcoord_components == 3)
2941 qglTexCoord3f(p[0], p[1], p[2]);
2942 else if (gl_state.units[j].pointer_texcoord_components == 2)
2943 qglTexCoord2f(p[0], p[1]);
2945 qglTexCoord1f(p[0]);
2948 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2950 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2951 if (vid.texarrayunits > 1)
2953 if (gl_state.units[j].pointer_texcoord_components == 4)
2954 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2955 else if (gl_state.units[j].pointer_texcoord_components == 3)
2956 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2957 else if (gl_state.units[j].pointer_texcoord_components == 2)
2958 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2959 else if (gl_state.units[j].pointer_texcoord_components == 1)
2960 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2964 if (gl_state.units[j].pointer_texcoord_components == 4)
2965 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2966 else if (gl_state.units[j].pointer_texcoord_components == 3)
2967 qglTexCoord3f(s[0], s[1], s[2]);
2968 else if (gl_state.units[j].pointer_texcoord_components == 2)
2969 qglTexCoord2f(s[0], s[1]);
2970 else if (gl_state.units[j].pointer_texcoord_components == 1)
2971 qglTexCoord1f(s[0]);
2974 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2976 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2977 if (vid.texarrayunits > 1)
2979 if (gl_state.units[j].pointer_texcoord_components == 4)
2980 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2981 else if (gl_state.units[j].pointer_texcoord_components == 3)
2982 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2983 else if (gl_state.units[j].pointer_texcoord_components == 2)
2984 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2985 else if (gl_state.units[j].pointer_texcoord_components == 1)
2986 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2990 if (gl_state.units[j].pointer_texcoord_components == 4)
2991 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2992 else if (gl_state.units[j].pointer_texcoord_components == 3)
2993 qglTexCoord3f(sb[0], sb[1], sb[2]);
2994 else if (gl_state.units[j].pointer_texcoord_components == 2)
2995 qglTexCoord2f(sb[0], sb[1]);
2996 else if (gl_state.units[j].pointer_texcoord_components == 1)
2997 qglTexCoord1f(sb[0]);
3002 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
3004 if (gl_state.pointer_color_gltype == GL_FLOAT)
3006 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
3007 qglColor4f(p[0], p[1], p[2], p[3]);
3009 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
3011 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
3012 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
3015 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
3017 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
3018 if (gl_state.pointer_vertex_components == 4)
3019 qglVertex4f(p[0], p[1], p[2], p[3]);
3020 else if (gl_state.pointer_vertex_components == 3)
3021 qglVertex3f(p[0], p[1], p[2]);
3023 qglVertex2f(p[0], p[1]);
3031 else if (bufferobject3s)
3033 GL_BindEBO(bufferobject3s);
3035 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3037 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
3043 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3047 else if (bufferobject3i)
3049 GL_BindEBO(bufferobject3i);
3051 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3053 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3059 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3067 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3069 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3075 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3083 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3085 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3091 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3097 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3101 case RENDERPATH_D3D9:
3103 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3105 if (element3s_indexbuffer)
3107 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3108 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3110 else if (element3i_indexbuffer)
3112 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3113 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3116 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3121 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3123 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3125 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3129 case RENDERPATH_D3D10:
3130 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3132 case RENDERPATH_D3D11:
3133 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3135 case RENDERPATH_SOFT:
3136 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3138 case RENDERPATH_GLES1:
3139 case RENDERPATH_GLES2:
3140 // GLES does not have glDrawRangeElements, and generally
3141 // underperforms with index buffers, so this code path is
3142 // relatively straightforward...
3144 if (gl_paranoid.integer)
3146 int r, prog, enabled, i;
3147 GLsizei attriblength;
3150 GLchar attribname[1024];
3151 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3152 if (r != GL_FRAMEBUFFER_COMPLETE)
3153 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3154 #ifndef GL_CURRENT_PROGRAM
3155 #define GL_CURRENT_PROGRAM 0x8B8D
3157 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3158 if (r < 0 || r > 10000)
3159 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3161 for (i = 0;i < 8;i++)
3163 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3166 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3167 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);
3173 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3178 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3183 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3191 // restores backend state, used when done with 3D rendering
3192 void R_Mesh_Finish(void)
3194 R_Mesh_ResetRenderTargets();
3197 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3199 r_meshbuffer_t *buffer;
3200 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3202 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3203 memset(buffer, 0, sizeof(*buffer));
3204 buffer->bufferobject = 0;
3205 buffer->devicebuffer = NULL;
3207 buffer->isindexbuffer = isindexbuffer;
3208 buffer->isdynamic = isdynamic;
3209 buffer->isindex16 = isindex16;
3210 strlcpy(buffer->name, name, sizeof(buffer->name));
3211 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3215 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3219 if (buffer->isindexbuffer)
3221 r_refdef.stats.indexbufferuploadcount++;
3222 r_refdef.stats.indexbufferuploadsize += size;
3226 r_refdef.stats.vertexbufferuploadcount++;
3227 r_refdef.stats.vertexbufferuploadsize += size;
3229 switch(vid.renderpath)
3231 case RENDERPATH_GL11:
3232 case RENDERPATH_GL13:
3233 case RENDERPATH_GL20:
3234 case RENDERPATH_GLES1:
3235 case RENDERPATH_GLES2:
3236 if (!buffer->bufferobject)
3237 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3238 if (buffer->isindexbuffer)
3239 GL_BindEBO(buffer->bufferobject);
3241 GL_BindVBO(buffer->bufferobject);
3242 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3244 case RENDERPATH_D3D9:
3248 void *datapointer = NULL;
3249 if (buffer->isindexbuffer)
3251 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3252 if (size > buffer->size || !buffer->devicebuffer)
3254 if (buffer->devicebuffer)
3255 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3256 buffer->devicebuffer = NULL;
3257 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)))
3258 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);
3259 buffer->devicebuffer = (void *)d3d9indexbuffer;
3260 buffer->size = size;
3262 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3265 memcpy(datapointer, data, size);
3267 memset(datapointer, 0, size);
3268 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3273 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3274 if (size > buffer->size || !buffer->devicebuffer)
3276 if (buffer->devicebuffer)
3277 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3278 buffer->devicebuffer = NULL;
3279 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3280 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);
3281 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3282 buffer->size = size;
3284 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3287 memcpy(datapointer, data, size);
3289 memset(datapointer, 0, size);
3290 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3296 case RENDERPATH_D3D10:
3297 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3299 case RENDERPATH_D3D11:
3300 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3302 case RENDERPATH_SOFT:
3307 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3311 switch(vid.renderpath)
3313 case RENDERPATH_GL11:
3314 case RENDERPATH_GL13:
3315 case RENDERPATH_GL20:
3316 case RENDERPATH_GLES1:
3317 case RENDERPATH_GLES2:
3318 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3320 case RENDERPATH_D3D9:
3322 if (gl_state.d3dvertexbuffer == (void *)buffer)
3323 gl_state.d3dvertexbuffer = NULL;
3324 if (buffer->devicebuffer)
3326 if (buffer->isindexbuffer)
3327 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3329 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3330 buffer->devicebuffer = NULL;
3334 case RENDERPATH_D3D10:
3335 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3337 case RENDERPATH_D3D11:
3338 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3340 case RENDERPATH_SOFT:
3343 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3346 void GL_Mesh_ListVBOs(qboolean printeach)
3349 size_t ebocount = 0, ebomemory = 0;
3350 size_t vbocount = 0, vbomemory = 0;
3351 r_meshbuffer_t *buffer;
3352 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3353 for (i = 0;i < endindex;i++)
3355 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3358 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)");}
3359 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)");}
3361 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);
3366 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3368 switch(vid.renderpath)
3370 case RENDERPATH_GL11:
3371 case RENDERPATH_GL13:
3372 case RENDERPATH_GLES1:
3373 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)
3375 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3376 gl_state.pointer_vertex_components = components;
3377 gl_state.pointer_vertex_gltype = gltype;
3378 gl_state.pointer_vertex_stride = stride;
3379 gl_state.pointer_vertex_pointer = pointer;
3380 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3381 gl_state.pointer_vertex_offset = bufferoffset;
3383 GL_BindVBO(bufferobject);
3384 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3387 case RENDERPATH_GL20:
3388 case RENDERPATH_GLES2:
3389 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)
3391 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3392 gl_state.pointer_vertex_components = components;
3393 gl_state.pointer_vertex_gltype = gltype;
3394 gl_state.pointer_vertex_stride = stride;
3395 gl_state.pointer_vertex_pointer = pointer;
3396 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3397 gl_state.pointer_vertex_offset = bufferoffset;
3399 GL_BindVBO(bufferobject);
3400 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3403 case RENDERPATH_D3D9:
3404 case RENDERPATH_D3D10:
3405 case RENDERPATH_D3D11:
3406 case RENDERPATH_SOFT:
3411 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3413 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3414 // the pointer only.
3415 switch(vid.renderpath)
3417 case RENDERPATH_GL11:
3418 case RENDERPATH_GL13:
3419 case RENDERPATH_GLES1:
3424 // caller wants color array enabled
3425 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3426 if (!gl_state.pointer_color_enabled)
3428 gl_state.pointer_color_enabled = true;
3430 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3432 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)
3434 gl_state.pointer_color_components = components;
3435 gl_state.pointer_color_gltype = gltype;
3436 gl_state.pointer_color_stride = stride;
3437 gl_state.pointer_color_pointer = pointer;
3438 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3439 gl_state.pointer_color_offset = bufferoffset;
3441 GL_BindVBO(bufferobject);
3442 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3447 // caller wants color array disabled
3448 if (gl_state.pointer_color_enabled)
3450 gl_state.pointer_color_enabled = false;
3452 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3453 // when color array is on the glColor gets trashed, set it again
3454 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3459 case RENDERPATH_GL20:
3460 case RENDERPATH_GLES2:
3464 // caller wants color array enabled
3465 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3466 if (!gl_state.pointer_color_enabled)
3468 gl_state.pointer_color_enabled = true;
3470 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3472 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)
3474 gl_state.pointer_color_components = components;
3475 gl_state.pointer_color_gltype = gltype;
3476 gl_state.pointer_color_stride = stride;
3477 gl_state.pointer_color_pointer = pointer;
3478 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3479 gl_state.pointer_color_offset = bufferoffset;
3481 GL_BindVBO(bufferobject);
3482 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3487 // caller wants color array disabled
3488 if (gl_state.pointer_color_enabled)
3490 gl_state.pointer_color_enabled = false;
3492 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3493 // when color array is on the glColor gets trashed, set it again
3494 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3498 case RENDERPATH_D3D9:
3499 case RENDERPATH_D3D10:
3500 case RENDERPATH_D3D11:
3501 case RENDERPATH_SOFT:
3506 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)
3508 gltextureunit_t *unit = gl_state.units + unitnum;
3509 // update array settings
3510 // note: there is no need to check bufferobject here because all cases
3511 // that involve a valid bufferobject also supply a texcoord array
3512 switch(vid.renderpath)
3514 case RENDERPATH_GL11:
3515 case RENDERPATH_GL13:
3516 case RENDERPATH_GLES1:
3521 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3522 // texture array unit is enabled, enable the array
3523 if (!unit->arrayenabled)
3525 unit->arrayenabled = true;
3526 GL_ClientActiveTexture(unitnum);
3527 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3530 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)
3532 unit->pointer_texcoord_components = components;
3533 unit->pointer_texcoord_gltype = gltype;
3534 unit->pointer_texcoord_stride = stride;
3535 unit->pointer_texcoord_pointer = pointer;
3536 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3537 unit->pointer_texcoord_offset = bufferoffset;
3538 GL_ClientActiveTexture(unitnum);
3539 GL_BindVBO(bufferobject);
3540 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3545 // texture array unit is disabled, disable the array
3546 if (unit->arrayenabled)
3548 unit->arrayenabled = false;
3549 GL_ClientActiveTexture(unitnum);
3550 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3555 case RENDERPATH_GL20:
3556 case RENDERPATH_GLES2:
3560 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3561 // texture array unit is enabled, enable the array
3562 if (!unit->arrayenabled)
3564 unit->arrayenabled = true;
3565 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3568 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)
3570 unit->pointer_texcoord_components = components;
3571 unit->pointer_texcoord_gltype = gltype;
3572 unit->pointer_texcoord_stride = stride;
3573 unit->pointer_texcoord_pointer = pointer;
3574 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3575 unit->pointer_texcoord_offset = bufferoffset;
3576 GL_BindVBO(bufferobject);
3577 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3582 // texture array unit is disabled, disable the array
3583 if (unit->arrayenabled)
3585 unit->arrayenabled = false;
3586 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3590 case RENDERPATH_D3D9:
3591 case RENDERPATH_D3D10:
3592 case RENDERPATH_D3D11:
3593 case RENDERPATH_SOFT:
3598 int R_Mesh_TexBound(unsigned int unitnum, int id)
3600 gltextureunit_t *unit = gl_state.units + unitnum;
3601 if (unitnum >= vid.teximageunits)
3603 if (id == GL_TEXTURE_2D)
3605 if (id == GL_TEXTURE_3D)
3607 if (id == GL_TEXTURE_CUBE_MAP)
3608 return unit->tcubemap;
3612 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3614 switch(vid.renderpath)
3616 case RENDERPATH_GL11:
3617 case RENDERPATH_GL13:
3618 case RENDERPATH_GL20:
3619 case RENDERPATH_GLES1:
3620 case RENDERPATH_GLES2:
3621 R_Mesh_TexBind(0, tex);
3622 GL_ActiveTexture(0);CHECKGLERROR
3623 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3625 case RENDERPATH_D3D9:
3628 IDirect3DSurface9 *currentsurface = NULL;
3629 IDirect3DSurface9 *texturesurface = NULL;
3632 sourcerect.left = sx;
3633 sourcerect.top = sy;
3634 sourcerect.right = sx + width;
3635 sourcerect.bottom = sy + height;
3638 destrect.right = tx + width;
3639 destrect.bottom = ty + height;
3640 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3642 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3644 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3645 IDirect3DSurface9_Release(currentsurface);
3647 IDirect3DSurface9_Release(texturesurface);
3652 case RENDERPATH_D3D10:
3653 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3655 case RENDERPATH_D3D11:
3656 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3658 case RENDERPATH_SOFT:
3659 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3665 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};
3668 void R_Mesh_ClearBindingsForTexture(int texnum)
3670 gltextureunit_t *unit;
3671 unsigned int unitnum;
3672 // 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)
3673 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3675 unit = gl_state.units + unitnum;
3676 if (unit->t2d == texnum)
3678 if (unit->t3d == texnum)
3680 if (unit->tcubemap == texnum)
3681 unit->tcubemap = -1;
3685 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3687 gltextureunit_t *unit = gl_state.units + unitnum;
3688 int tex2d, tex3d, texcubemap, texnum;
3689 if (unitnum >= vid.teximageunits)
3691 // if (unit->texture == tex)
3693 switch(vid.renderpath)
3695 case RENDERPATH_GL20:
3696 case RENDERPATH_GLES2:
3699 tex = r_texture_white;
3700 // not initialized enough yet...
3704 unit->texture = tex;
3705 texnum = R_GetTexture(tex);
3706 switch(tex->gltexturetypeenum)
3708 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3709 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3710 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3713 case RENDERPATH_GL11:
3714 case RENDERPATH_GL13:
3715 case RENDERPATH_GLES1:
3716 unit->texture = tex;
3722 texnum = R_GetTexture(tex);
3723 switch(tex->gltexturetypeenum)
3731 case GL_TEXTURE_CUBE_MAP:
3732 texcubemap = texnum;
3736 // update 2d texture binding
3737 if (unit->t2d != tex2d)
3739 GL_ActiveTexture(unitnum);
3744 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3751 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3755 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3757 // update 3d texture binding
3758 if (unit->t3d != tex3d)
3760 GL_ActiveTexture(unitnum);
3765 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3772 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3776 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3778 // update cubemap texture binding
3779 if (unit->tcubemap != texcubemap)
3781 GL_ActiveTexture(unitnum);
3784 if (unit->tcubemap == 0)
3786 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3793 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3796 unit->tcubemap = texcubemap;
3797 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3800 case RENDERPATH_D3D9:
3803 extern cvar_t gl_texture_anisotropy;
3806 tex = r_texture_white;
3807 // not initialized enough yet...
3811 // upload texture if needed
3813 if (unit->texture == tex)
3815 unit->texture = tex;
3816 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3817 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3818 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3819 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3820 if (tex->d3daddressw)
3821 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3822 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3823 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3824 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3825 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3826 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3827 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3831 case RENDERPATH_D3D10:
3832 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3834 case RENDERPATH_D3D11:
3835 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3837 case RENDERPATH_SOFT:
3840 tex = r_texture_white;
3841 // not initialized enough yet...
3845 texnum = R_GetTexture(tex);
3846 if (unit->texture == tex)
3848 unit->texture = tex;
3849 DPSOFTRAST_SetTexture(unitnum, texnum);
3854 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3856 gltextureunit_t *unit = gl_state.units + unitnum;
3857 switch(vid.renderpath)
3859 case RENDERPATH_GL11:
3860 case RENDERPATH_GL13:
3861 case RENDERPATH_GL20:
3862 case RENDERPATH_GLES1:
3863 case RENDERPATH_GLES2:
3865 if (matrix && matrix->m[3][3])
3867 // texmatrix specified, check if it is different
3868 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3871 unit->texmatrixenabled = true;
3872 unit->matrix = *matrix;
3874 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3875 GL_ActiveTexture(unitnum);
3876 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3877 qglLoadMatrixf(glmatrix);CHECKGLERROR
3878 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3883 // no texmatrix specified, revert to identity
3884 if (unit->texmatrixenabled)
3886 unit->texmatrixenabled = false;
3887 unit->matrix = identitymatrix;
3889 GL_ActiveTexture(unitnum);
3890 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3891 qglLoadIdentity();CHECKGLERROR
3892 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3897 case RENDERPATH_D3D9:
3898 case RENDERPATH_D3D10:
3899 case RENDERPATH_D3D11:
3901 case RENDERPATH_SOFT:
3906 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3908 gltextureunit_t *unit = gl_state.units + unitnum;
3910 switch(vid.renderpath)
3912 case RENDERPATH_GL20:
3913 case RENDERPATH_GLES2:
3916 case RENDERPATH_GL13:
3917 case RENDERPATH_GLES1:
3918 #ifdef GL_TEXTURE_ENV
3919 // GL_ARB_texture_env_combine
3921 combinergb = GL_MODULATE;
3923 combinealpha = GL_MODULATE;
3928 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3930 if (combinergb == GL_DECAL)
3931 combinergb = GL_INTERPOLATE;
3932 if (unit->combine != GL_COMBINE)
3934 unit->combine = GL_COMBINE;
3935 GL_ActiveTexture(unitnum);
3936 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3937 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3939 if (unit->combinergb != combinergb)
3941 unit->combinergb = combinergb;
3942 GL_ActiveTexture(unitnum);
3943 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3945 if (unit->combinealpha != combinealpha)
3947 unit->combinealpha = combinealpha;
3948 GL_ActiveTexture(unitnum);
3949 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3951 if (unit->rgbscale != rgbscale)
3953 unit->rgbscale = rgbscale;
3954 GL_ActiveTexture(unitnum);
3955 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3957 if (unit->alphascale != alphascale)
3959 unit->alphascale = alphascale;
3960 GL_ActiveTexture(unitnum);
3961 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3966 if (unit->combine != combinergb)
3968 unit->combine = combinergb;
3969 GL_ActiveTexture(unitnum);
3970 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3975 case RENDERPATH_GL11:
3977 #ifdef GL_TEXTURE_ENV
3979 combinergb = GL_MODULATE;
3980 if (unit->combine != combinergb)
3982 unit->combine = combinergb;
3983 GL_ActiveTexture(unitnum);
3984 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3988 case RENDERPATH_D3D9:
3989 case RENDERPATH_D3D10:
3990 case RENDERPATH_D3D11:
3992 case RENDERPATH_SOFT:
3997 void R_Mesh_ResetTextureState(void)
3999 unsigned int unitnum;
4003 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
4004 R_Mesh_TexBind(unitnum, NULL);
4005 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
4006 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4007 switch(vid.renderpath)
4009 case RENDERPATH_GL20:
4010 case RENDERPATH_GLES2:
4011 case RENDERPATH_D3D9:
4012 case RENDERPATH_D3D10:
4013 case RENDERPATH_D3D11:
4014 case RENDERPATH_SOFT:
4016 case RENDERPATH_GL11:
4017 case RENDERPATH_GL13:
4018 case RENDERPATH_GLES1:
4019 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
4021 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
4022 R_Mesh_TexMatrix(unitnum, NULL);
4031 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
4032 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
4033 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
4035 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
4037 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4041 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
4043 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4044 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4045 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4049 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4051 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4052 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4053 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4054 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4055 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4056 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4057 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4061 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4062 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4063 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4066 static void R_Mesh_InitVertexDeclarations(void)
4069 r_vertex3f_d3d9decl = NULL;
4070 r_vertexgeneric_d3d9decl = NULL;
4071 r_vertexmesh_d3d9decl = NULL;
4072 switch(vid.renderpath)
4074 case RENDERPATH_GL20:
4075 case RENDERPATH_GL13:
4076 case RENDERPATH_GL11:
4077 case RENDERPATH_GLES1:
4078 case RENDERPATH_GLES2:
4080 case RENDERPATH_D3D9:
4081 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4082 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4083 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4085 case RENDERPATH_D3D10:
4086 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4088 case RENDERPATH_D3D11:
4089 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4091 case RENDERPATH_SOFT:
4097 static void R_Mesh_DestroyVertexDeclarations(void)
4100 if (r_vertex3f_d3d9decl)
4101 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4102 r_vertex3f_d3d9decl = NULL;
4103 if (r_vertexgeneric_d3d9decl)
4104 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4105 r_vertexgeneric_d3d9decl = NULL;
4106 if (r_vertexmesh_d3d9decl)
4107 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4108 r_vertexmesh_d3d9decl = NULL;
4112 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4114 // upload temporary vertexbuffer for this rendering
4115 if (!gl_state.usevbo_staticvertex)
4116 vertexbuffer = NULL;
4117 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4119 if (gl_state.preparevertices_dynamicvertexbuffer)
4120 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4122 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4123 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4125 switch(vid.renderpath)
4127 case RENDERPATH_GL20:
4128 case RENDERPATH_GLES2:
4131 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4132 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4133 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4134 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4135 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4136 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4137 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4141 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4142 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4143 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4144 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4145 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4146 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4147 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4150 case RENDERPATH_GL13:
4151 case RENDERPATH_GLES1:
4154 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4155 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4156 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4157 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4161 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4162 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4163 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4164 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4167 case RENDERPATH_GL11:
4170 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4171 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4172 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4176 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4177 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4178 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4181 case RENDERPATH_D3D9:
4183 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4185 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4187 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4188 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4189 gl_state.d3dvertexdata = (void *)vertex3f;
4190 gl_state.d3dvertexsize = sizeof(float[3]);
4193 case RENDERPATH_D3D10:
4194 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4196 case RENDERPATH_D3D11:
4197 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4199 case RENDERPATH_SOFT:
4200 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4201 DPSOFTRAST_SetColorPointer(NULL, 0);
4202 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4203 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4204 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4205 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4206 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4213 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4216 size = sizeof(r_vertexgeneric_t) * numvertices;
4217 if (gl_state.preparevertices_tempdatamaxsize < size)
4219 gl_state.preparevertices_tempdatamaxsize = size;
4220 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4222 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4223 gl_state.preparevertices_numvertices = numvertices;
4224 return gl_state.preparevertices_vertexgeneric;
4227 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4229 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4230 gl_state.preparevertices_vertexgeneric = NULL;
4231 gl_state.preparevertices_numvertices = 0;
4235 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4238 r_vertexgeneric_t *vertex;
4239 switch(vid.renderpath)
4241 case RENDERPATH_GL20:
4242 case RENDERPATH_GLES2:
4243 if (!vid.useinterleavedarrays)
4245 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4246 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4247 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4248 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4249 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4250 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4251 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4255 case RENDERPATH_GL11:
4256 case RENDERPATH_GL13:
4257 case RENDERPATH_GLES1:
4258 if (!vid.useinterleavedarrays)
4260 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4261 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4262 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4263 if (vid.texunits >= 2)
4264 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4265 if (vid.texunits >= 3)
4266 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4270 case RENDERPATH_D3D9:
4271 case RENDERPATH_D3D10:
4272 case RENDERPATH_D3D11:
4274 case RENDERPATH_SOFT:
4275 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4276 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4277 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4278 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4279 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4280 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4281 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4285 // no quick path for this case, convert to vertex structs
4286 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4287 for (i = 0;i < numvertices;i++)
4288 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4291 for (i = 0;i < numvertices;i++)
4292 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4296 for (i = 0;i < numvertices;i++)
4297 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4300 for (i = 0;i < numvertices;i++)
4301 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4302 R_Mesh_PrepareVertices_Generic_Unlock();
4303 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4306 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4308 // upload temporary vertexbuffer for this rendering
4309 if (!gl_state.usevbo_staticvertex)
4310 vertexbuffer = NULL;
4311 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4313 if (gl_state.preparevertices_dynamicvertexbuffer)
4314 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4316 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4317 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4319 switch(vid.renderpath)
4321 case RENDERPATH_GL20:
4322 case RENDERPATH_GLES2:
4325 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4326 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4327 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4328 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4329 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4330 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4331 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4335 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4336 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4337 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4338 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4339 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4340 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4341 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4344 case RENDERPATH_GL13:
4345 case RENDERPATH_GLES1:
4348 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4349 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4350 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4351 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4355 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4356 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4357 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4358 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4361 case RENDERPATH_GL11:
4364 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4365 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4366 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4370 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4371 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4372 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4375 case RENDERPATH_D3D9:
4377 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4379 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4381 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4382 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4383 gl_state.d3dvertexdata = (void *)vertex;
4384 gl_state.d3dvertexsize = sizeof(*vertex);
4387 case RENDERPATH_D3D10:
4388 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4390 case RENDERPATH_D3D11:
4391 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4393 case RENDERPATH_SOFT:
4394 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4395 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4396 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4397 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4398 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4399 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4400 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4407 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4410 size = sizeof(r_vertexmesh_t) * numvertices;
4411 if (gl_state.preparevertices_tempdatamaxsize < size)
4413 gl_state.preparevertices_tempdatamaxsize = size;
4414 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4416 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4417 gl_state.preparevertices_numvertices = numvertices;
4418 return gl_state.preparevertices_vertexmesh;
4421 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4423 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4424 gl_state.preparevertices_vertexmesh = NULL;
4425 gl_state.preparevertices_numvertices = 0;
4429 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)
4432 r_vertexmesh_t *vertex;
4433 switch(vid.renderpath)
4435 case RENDERPATH_GL20:
4436 case RENDERPATH_GLES2:
4437 if (!vid.useinterleavedarrays)
4439 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4440 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4441 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4442 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4443 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4444 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4445 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4449 case RENDERPATH_GL11:
4450 case RENDERPATH_GL13:
4451 case RENDERPATH_GLES1:
4452 if (!vid.useinterleavedarrays)
4454 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4455 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4456 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4457 if (vid.texunits >= 2)
4458 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4459 if (vid.texunits >= 3)
4460 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4464 case RENDERPATH_D3D9:
4465 case RENDERPATH_D3D10:
4466 case RENDERPATH_D3D11:
4468 case RENDERPATH_SOFT:
4469 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4470 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4471 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4472 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4473 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4474 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4475 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4479 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4480 for (i = 0;i < numvertices;i++)
4481 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4483 for (i = 0;i < numvertices;i++)
4484 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4486 for (i = 0;i < numvertices;i++)
4487 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4489 for (i = 0;i < numvertices;i++)
4490 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4493 for (i = 0;i < numvertices;i++)
4494 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4498 for (i = 0;i < numvertices;i++)
4499 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4501 if (texcoordtexture2f)
4502 for (i = 0;i < numvertices;i++)
4503 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4504 if (texcoordlightmap2f)
4505 for (i = 0;i < numvertices;i++)
4506 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4507 R_Mesh_PrepareVertices_Mesh_Unlock();
4508 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4511 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4513 // upload temporary vertexbuffer for this rendering
4514 if (!gl_state.usevbo_staticvertex)
4515 vertexbuffer = NULL;
4516 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4518 if (gl_state.preparevertices_dynamicvertexbuffer)
4519 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4521 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4522 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4524 switch(vid.renderpath)
4526 case RENDERPATH_GL20:
4527 case RENDERPATH_GLES2:
4530 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4531 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4532 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4533 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4534 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4535 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4536 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4540 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4541 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4542 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4543 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4544 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4545 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4546 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4549 case RENDERPATH_GL13:
4550 case RENDERPATH_GLES1:
4553 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4554 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4555 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4556 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4560 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4561 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4562 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4563 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4566 case RENDERPATH_GL11:
4569 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4570 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4571 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4575 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4576 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4577 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4580 case RENDERPATH_D3D9:
4582 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4584 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4586 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4587 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4588 gl_state.d3dvertexdata = (void *)vertex;
4589 gl_state.d3dvertexsize = sizeof(*vertex);
4592 case RENDERPATH_D3D10:
4593 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4595 case RENDERPATH_D3D11:
4596 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4598 case RENDERPATH_SOFT:
4599 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4600 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4601 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4602 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4603 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4604 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4605 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4610 void GL_BlendEquationSubtract(qboolean negated)
4614 switch(vid.renderpath)
4616 case RENDERPATH_GL11:
4617 case RENDERPATH_GL13:
4618 case RENDERPATH_GL20:
4619 case RENDERPATH_GLES1:
4620 case RENDERPATH_GLES2:
4621 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4623 case RENDERPATH_D3D9:
4625 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4628 case RENDERPATH_D3D10:
4629 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4631 case RENDERPATH_D3D11:
4632 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4634 case RENDERPATH_SOFT:
4635 DPSOFTRAST_BlendSubtract(true);
4641 switch(vid.renderpath)
4643 case RENDERPATH_GL11:
4644 case RENDERPATH_GL13:
4645 case RENDERPATH_GL20:
4646 case RENDERPATH_GLES1:
4647 case RENDERPATH_GLES2:
4648 qglBlendEquationEXT(GL_FUNC_ADD);
4650 case RENDERPATH_D3D9:
4652 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4655 case RENDERPATH_D3D10:
4656 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4658 case RENDERPATH_D3D11:
4659 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4661 case RENDERPATH_SOFT:
4662 DPSOFTRAST_BlendSubtract(false);