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_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1343 rtexture_t *textures[5];
1344 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1345 textures[4] = depthtexture;
1346 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1347 for (j = 0;j < 5;j++)
1349 for (i = 0;i < vid.teximageunits;i++)
1350 if (gl_state.units[i].texture == textures[j])
1351 R_Mesh_TexBind(i, NULL);
1352 // set up framebuffer object or render targets for the active rendering API
1353 switch(vid.renderpath)
1355 case RENDERPATH_GL11:
1356 case RENDERPATH_GL13:
1357 case RENDERPATH_GL20:
1358 case RENDERPATH_GLES1:
1359 case RENDERPATH_GLES2:
1360 if (gl_state.framebufferobject != fbo)
1362 gl_state.framebufferobject = fbo;
1363 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1366 case RENDERPATH_D3D9:
1368 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1369 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1372 IDirect3DSurface9 *colorsurfaces[4];
1373 for (i = 0;i < 4;i++)
1375 colorsurfaces[i] = NULL;
1377 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1379 // set the render targets for real
1380 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1381 // release the texture surface levels (they won't be lost while bound...)
1382 for (i = 0;i < 4;i++)
1384 IDirect3DSurface9_Release(colorsurfaces[i]);
1387 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1390 case RENDERPATH_D3D10:
1391 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1393 case RENDERPATH_D3D11:
1394 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1396 case RENDERPATH_SOFT:
1400 unsigned int *pointers[5];
1401 memset(pointers, 0, sizeof(pointers));
1402 for (i = 0;i < 5;i++)
1403 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1404 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1405 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1406 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1409 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1415 static int d3dcmpforglfunc(int f)
1419 case GL_NEVER: return D3DCMP_NEVER;
1420 case GL_LESS: return D3DCMP_LESS;
1421 case GL_EQUAL: return D3DCMP_EQUAL;
1422 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1423 case GL_GREATER: return D3DCMP_GREATER;
1424 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1425 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1426 case GL_ALWAYS: return D3DCMP_ALWAYS;
1427 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1431 static int d3dstencilopforglfunc(int f)
1435 case GL_KEEP: return D3DSTENCILOP_KEEP;
1436 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1437 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1438 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1443 extern cvar_t r_transparent_alphatocoverage;
1445 static void GL_Backend_ResetState(void)
1448 gl_state.active = true;
1449 gl_state.depthtest = true;
1450 gl_state.alphatest = false;
1451 gl_state.alphafunc = GL_GEQUAL;
1452 gl_state.alphafuncvalue = 0.5f;
1453 gl_state.alphatocoverage = false;
1454 gl_state.blendfunc1 = GL_ONE;
1455 gl_state.blendfunc2 = GL_ZERO;
1456 gl_state.blend = false;
1457 gl_state.depthmask = GL_TRUE;
1458 gl_state.colormask = 15;
1459 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1460 gl_state.lockrange_first = 0;
1461 gl_state.lockrange_count = 0;
1462 gl_state.cullface = GL_FRONT;
1463 gl_state.cullfaceenable = false;
1464 gl_state.polygonoffset[0] = 0;
1465 gl_state.polygonoffset[1] = 0;
1466 gl_state.framebufferobject = 0;
1467 gl_state.depthfunc = GL_LEQUAL;
1469 switch(vid.renderpath)
1471 case RENDERPATH_D3D9:
1474 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1475 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1476 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1477 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1478 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1479 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1480 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1484 case RENDERPATH_D3D10:
1485 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1487 case RENDERPATH_D3D11:
1488 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1490 case RENDERPATH_GL11:
1491 case RENDERPATH_GL13:
1492 case RENDERPATH_GLES1:
1493 #ifdef GL_ALPHA_TEST
1496 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1497 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1498 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1499 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1500 qglDisable(GL_BLEND);CHECKGLERROR
1501 qglCullFace(gl_state.cullface);CHECKGLERROR
1502 qglDisable(GL_CULL_FACE);CHECKGLERROR
1503 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1504 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1505 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1506 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1508 if (vid.support.arb_vertex_buffer_object)
1510 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1511 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1514 if (vid.support.ext_framebuffer_object)
1516 //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
1517 qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
1520 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1521 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1523 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1524 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1525 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1527 if (vid.support.ext_framebuffer_object)
1528 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
1530 gl_state.unit = MAX_TEXTUREUNITS;
1531 gl_state.clientunit = MAX_TEXTUREUNITS;
1532 for (i = 0;i < vid.texunits;i++)
1534 GL_ActiveTexture(i);
1535 GL_ClientActiveTexture(i);
1536 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1537 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1538 if (vid.support.ext_texture_3d)
1540 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1541 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1543 if (vid.support.arb_texture_cube_map)
1545 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
1546 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1549 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1550 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1551 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1552 qglLoadIdentity();CHECKGLERROR
1553 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1554 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1559 case RENDERPATH_SOFT:
1560 DPSOFTRAST_ColorMask(1,1,1,1);
1561 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1562 DPSOFTRAST_CullFace(gl_state.cullface);
1563 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1564 DPSOFTRAST_DepthMask(gl_state.depthmask);
1565 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1566 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1567 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1569 case RENDERPATH_GL20:
1570 case RENDERPATH_GLES2:
1572 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1573 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1574 qglDisable(GL_BLEND);CHECKGLERROR
1575 qglCullFace(gl_state.cullface);CHECKGLERROR
1576 qglDisable(GL_CULL_FACE);CHECKGLERROR
1577 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1578 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1579 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1580 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1581 if (vid.support.arb_vertex_buffer_object)
1583 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1584 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1586 if (vid.support.ext_framebuffer_object)
1587 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1588 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1589 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1590 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1591 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1592 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1593 gl_state.unit = MAX_TEXTUREUNITS;
1594 gl_state.clientunit = MAX_TEXTUREUNITS;
1595 for (i = 0;i < vid.teximageunits;i++)
1597 GL_ActiveTexture(i);
1598 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1599 if (vid.support.ext_texture_3d)
1601 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1603 if (vid.support.arb_texture_cube_map)
1605 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1608 for (i = 0;i < vid.texarrayunits;i++)
1611 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1612 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1619 void GL_ActiveTexture(unsigned int num)
1621 if (gl_state.unit != num)
1623 gl_state.unit = num;
1624 switch(vid.renderpath)
1626 case RENDERPATH_GL11:
1627 case RENDERPATH_GL13:
1628 case RENDERPATH_GL20:
1629 case RENDERPATH_GLES1:
1630 case RENDERPATH_GLES2:
1631 if (qglActiveTexture)
1634 qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
1638 case RENDERPATH_D3D9:
1639 case RENDERPATH_D3D10:
1640 case RENDERPATH_D3D11:
1642 case RENDERPATH_SOFT:
1648 void GL_ClientActiveTexture(unsigned int num)
1650 if (gl_state.clientunit != num)
1652 gl_state.clientunit = num;
1653 switch(vid.renderpath)
1655 case RENDERPATH_GL11:
1656 case RENDERPATH_GL13:
1657 case RENDERPATH_GLES1:
1658 if (qglActiveTexture)
1661 qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit);
1665 case RENDERPATH_D3D9:
1666 case RENDERPATH_D3D10:
1667 case RENDERPATH_D3D11:
1669 case RENDERPATH_SOFT:
1671 case RENDERPATH_GL20:
1672 case RENDERPATH_GLES2:
1678 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1680 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1682 qboolean blendenable;
1683 gl_state.blendfunc1 = blendfunc1;
1684 gl_state.blendfunc2 = blendfunc2;
1685 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1686 switch(vid.renderpath)
1688 case RENDERPATH_GL11:
1689 case RENDERPATH_GL13:
1690 case RENDERPATH_GL20:
1691 case RENDERPATH_GLES1:
1692 case RENDERPATH_GLES2:
1694 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1695 if (gl_state.blend != blendenable)
1697 gl_state.blend = blendenable;
1698 if (!gl_state.blend)
1700 qglDisable(GL_BLEND);CHECKGLERROR
1704 qglEnable(GL_BLEND);CHECKGLERROR
1708 case RENDERPATH_D3D9:
1713 D3DBLEND d3dblendfunc[2];
1714 glblendfunc[0] = gl_state.blendfunc1;
1715 glblendfunc[1] = gl_state.blendfunc2;
1716 for (i = 0;i < 2;i++)
1718 switch(glblendfunc[i])
1720 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1721 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1722 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1723 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1724 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1725 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1726 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1727 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1728 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1729 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1732 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1733 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1734 if (gl_state.blend != blendenable)
1736 gl_state.blend = blendenable;
1737 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1742 case RENDERPATH_D3D10:
1743 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1745 case RENDERPATH_D3D11:
1746 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1748 case RENDERPATH_SOFT:
1749 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1755 void GL_DepthMask(int state)
1757 if (gl_state.depthmask != state)
1759 gl_state.depthmask = state;
1760 switch(vid.renderpath)
1762 case RENDERPATH_GL11:
1763 case RENDERPATH_GL13:
1764 case RENDERPATH_GL20:
1765 case RENDERPATH_GLES1:
1766 case RENDERPATH_GLES2:
1768 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1770 case RENDERPATH_D3D9:
1772 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1775 case RENDERPATH_D3D10:
1776 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1778 case RENDERPATH_D3D11:
1779 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1781 case RENDERPATH_SOFT:
1782 DPSOFTRAST_DepthMask(gl_state.depthmask);
1788 void GL_DepthTest(int state)
1790 if (gl_state.depthtest != state)
1792 gl_state.depthtest = state;
1793 switch(vid.renderpath)
1795 case RENDERPATH_GL11:
1796 case RENDERPATH_GL13:
1797 case RENDERPATH_GL20:
1798 case RENDERPATH_GLES1:
1799 case RENDERPATH_GLES2:
1801 if (gl_state.depthtest)
1803 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1807 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1810 case RENDERPATH_D3D9:
1812 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1815 case RENDERPATH_D3D10:
1816 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1818 case RENDERPATH_D3D11:
1819 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1821 case RENDERPATH_SOFT:
1822 DPSOFTRAST_DepthTest(gl_state.depthtest);
1828 void GL_DepthFunc(int state)
1830 if (gl_state.depthfunc != state)
1832 gl_state.depthfunc = state;
1833 switch(vid.renderpath)
1835 case RENDERPATH_GL11:
1836 case RENDERPATH_GL13:
1837 case RENDERPATH_GL20:
1838 case RENDERPATH_GLES1:
1839 case RENDERPATH_GLES2:
1841 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1843 case RENDERPATH_D3D9:
1845 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1848 case RENDERPATH_D3D10:
1849 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1851 case RENDERPATH_D3D11:
1852 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1854 case RENDERPATH_SOFT:
1855 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1861 void GL_DepthRange(float nearfrac, float farfrac)
1863 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1865 gl_state.depthrange[0] = nearfrac;
1866 gl_state.depthrange[1] = farfrac;
1867 switch(vid.renderpath)
1869 case RENDERPATH_GL11:
1870 case RENDERPATH_GL13:
1871 case RENDERPATH_GL20:
1872 case RENDERPATH_GLES1:
1873 case RENDERPATH_GLES2:
1875 qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
1877 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1880 case RENDERPATH_D3D9:
1883 D3DVIEWPORT9 d3dviewport;
1884 d3dviewport.X = gl_viewport.x;
1885 d3dviewport.Y = gl_viewport.y;
1886 d3dviewport.Width = gl_viewport.width;
1887 d3dviewport.Height = gl_viewport.height;
1888 d3dviewport.MinZ = gl_state.depthrange[0];
1889 d3dviewport.MaxZ = gl_state.depthrange[1];
1890 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1894 case RENDERPATH_D3D10:
1895 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1897 case RENDERPATH_D3D11:
1898 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1900 case RENDERPATH_SOFT:
1901 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1907 void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask)
1909 switch (vid.renderpath)
1911 case RENDERPATH_GL11:
1912 case RENDERPATH_GL13:
1913 case RENDERPATH_GL20:
1914 case RENDERPATH_GLES1:
1915 case RENDERPATH_GLES2:
1919 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1923 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1925 if (vid.support.ati_separate_stencil)
1927 qglStencilMask(writemask);CHECKGLERROR
1928 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1929 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1930 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1932 else if (vid.support.ext_stencil_two_side)
1934 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1935 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1936 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1937 qglStencilMask(writemask);CHECKGLERROR
1938 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1939 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1940 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1941 qglStencilMask(writemask);CHECKGLERROR
1942 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1943 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1947 case RENDERPATH_D3D9:
1949 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1950 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1951 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1952 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1953 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1954 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1955 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1956 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1957 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1958 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1960 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1961 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1964 case RENDERPATH_D3D10:
1965 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1967 case RENDERPATH_D3D11:
1968 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1970 case RENDERPATH_SOFT:
1971 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1976 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1978 switch (vid.renderpath)
1980 case RENDERPATH_GL11:
1981 case RENDERPATH_GL13:
1982 case RENDERPATH_GL20:
1983 case RENDERPATH_GLES1:
1984 case RENDERPATH_GLES2:
1988 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1992 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1994 if (vid.support.ext_stencil_two_side)
1996 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1997 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2000 qglStencilMask(writemask);CHECKGLERROR
2001 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2002 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2005 case RENDERPATH_D3D9:
2007 if (vid.support.ati_separate_stencil)
2008 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2009 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2011 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2012 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2013 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2014 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2015 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2016 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2019 case RENDERPATH_D3D10:
2020 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2022 case RENDERPATH_D3D11:
2023 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2025 case RENDERPATH_SOFT:
2026 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2031 void GL_PolygonOffset(float planeoffset, float depthoffset)
2033 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2035 gl_state.polygonoffset[0] = planeoffset;
2036 gl_state.polygonoffset[1] = depthoffset;
2037 switch(vid.renderpath)
2039 case RENDERPATH_GL11:
2040 case RENDERPATH_GL13:
2041 case RENDERPATH_GL20:
2042 case RENDERPATH_GLES1:
2043 case RENDERPATH_GLES2:
2044 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2046 case RENDERPATH_D3D9:
2048 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2049 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2052 case RENDERPATH_D3D10:
2053 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2055 case RENDERPATH_D3D11:
2056 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2058 case RENDERPATH_SOFT:
2059 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2065 void GL_SetMirrorState(qboolean state)
2067 if (v_flipped_state != state)
2069 v_flipped_state = state;
2070 if (gl_state.cullface == GL_BACK)
2071 gl_state.cullface = GL_FRONT;
2072 else if (gl_state.cullface == GL_FRONT)
2073 gl_state.cullface = GL_BACK;
2076 switch(vid.renderpath)
2078 case RENDERPATH_GL11:
2079 case RENDERPATH_GL13:
2080 case RENDERPATH_GL20:
2081 case RENDERPATH_GLES1:
2082 case RENDERPATH_GLES2:
2083 qglCullFace(gl_state.cullface);CHECKGLERROR
2085 case RENDERPATH_D3D9:
2087 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2090 case RENDERPATH_D3D10:
2091 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2093 case RENDERPATH_D3D11:
2094 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2096 case RENDERPATH_SOFT:
2097 DPSOFTRAST_CullFace(gl_state.cullface);
2103 void GL_CullFace(int state)
2107 if(state == GL_FRONT)
2109 else if(state == GL_BACK)
2113 switch(vid.renderpath)
2115 case RENDERPATH_GL11:
2116 case RENDERPATH_GL13:
2117 case RENDERPATH_GL20:
2118 case RENDERPATH_GLES1:
2119 case RENDERPATH_GLES2:
2122 if (state != GL_NONE)
2124 if (!gl_state.cullfaceenable)
2126 gl_state.cullfaceenable = true;
2127 qglEnable(GL_CULL_FACE);CHECKGLERROR
2129 if (gl_state.cullface != state)
2131 gl_state.cullface = state;
2132 qglCullFace(gl_state.cullface);CHECKGLERROR
2137 if (gl_state.cullfaceenable)
2139 gl_state.cullfaceenable = false;
2140 qglDisable(GL_CULL_FACE);CHECKGLERROR
2144 case RENDERPATH_D3D9:
2146 if (gl_state.cullface != state)
2148 gl_state.cullface = state;
2149 switch(gl_state.cullface)
2152 gl_state.cullfaceenable = false;
2153 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2156 gl_state.cullfaceenable = true;
2157 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2160 gl_state.cullfaceenable = true;
2161 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2167 case RENDERPATH_D3D10:
2168 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2170 case RENDERPATH_D3D11:
2171 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2173 case RENDERPATH_SOFT:
2174 if (gl_state.cullface != state)
2176 gl_state.cullface = state;
2177 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2178 DPSOFTRAST_CullFace(gl_state.cullface);
2184 void GL_AlphaTest(int state)
2186 if (gl_state.alphatest != state)
2188 gl_state.alphatest = state;
2189 switch(vid.renderpath)
2191 case RENDERPATH_GL11:
2192 case RENDERPATH_GL13:
2193 case RENDERPATH_GLES1:
2194 #ifdef GL_ALPHA_TEST
2195 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2197 if (gl_state.alphatest)
2199 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2203 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2207 case RENDERPATH_D3D9:
2208 case RENDERPATH_D3D10:
2209 case RENDERPATH_D3D11:
2210 case RENDERPATH_SOFT:
2211 case RENDERPATH_GL20:
2212 case RENDERPATH_GLES2:
2218 void GL_AlphaToCoverage(qboolean state)
2220 if (gl_state.alphatocoverage != state)
2222 gl_state.alphatocoverage = state;
2223 switch(vid.renderpath)
2225 case RENDERPATH_GL11:
2226 case RENDERPATH_GL13:
2227 case RENDERPATH_GLES1:
2228 case RENDERPATH_GLES2:
2229 case RENDERPATH_D3D9:
2230 case RENDERPATH_D3D10:
2231 case RENDERPATH_D3D11:
2232 case RENDERPATH_SOFT:
2234 case RENDERPATH_GL20:
2235 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2236 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2238 if (gl_state.alphatocoverage)
2240 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2241 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2245 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2246 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2254 void GL_ColorMask(int r, int g, int b, int a)
2256 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2257 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2258 if (gl_state.colormask != state)
2260 gl_state.colormask = state;
2261 switch(vid.renderpath)
2263 case RENDERPATH_GL11:
2264 case RENDERPATH_GL13:
2265 case RENDERPATH_GL20:
2266 case RENDERPATH_GLES1:
2267 case RENDERPATH_GLES2:
2269 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2271 case RENDERPATH_D3D9:
2273 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2276 case RENDERPATH_D3D10:
2277 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2279 case RENDERPATH_D3D11:
2280 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2282 case RENDERPATH_SOFT:
2283 DPSOFTRAST_ColorMask(r, g, b, a);
2289 void GL_Color(float cr, float cg, float cb, float ca)
2291 if (gl_state.pointer_color_enabled || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
2293 gl_state.color4f[0] = cr;
2294 gl_state.color4f[1] = cg;
2295 gl_state.color4f[2] = cb;
2296 gl_state.color4f[3] = ca;
2297 switch(vid.renderpath)
2299 case RENDERPATH_GL11:
2300 case RENDERPATH_GL13:
2301 case RENDERPATH_GLES1:
2303 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2306 case RENDERPATH_D3D9:
2307 case RENDERPATH_D3D10:
2308 case RENDERPATH_D3D11:
2309 // no equivalent in D3D
2311 case RENDERPATH_SOFT:
2312 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2314 case RENDERPATH_GL20:
2315 case RENDERPATH_GLES2:
2316 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2322 void GL_Scissor (int x, int y, int width, int height)
2324 switch(vid.renderpath)
2326 case RENDERPATH_GL11:
2327 case RENDERPATH_GL13:
2328 case RENDERPATH_GL20:
2329 case RENDERPATH_GLES1:
2330 case RENDERPATH_GLES2:
2332 qglScissor(x, y,width,height);
2335 case RENDERPATH_D3D9:
2341 d3drect.right = x + width;
2342 d3drect.bottom = y + height;
2343 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2347 case RENDERPATH_D3D10:
2348 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2350 case RENDERPATH_D3D11:
2351 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2353 case RENDERPATH_SOFT:
2354 DPSOFTRAST_Scissor(x, y, width, height);
2359 void GL_ScissorTest(int state)
2361 if (gl_state.scissortest != state)
2363 gl_state.scissortest = state;
2364 switch(vid.renderpath)
2366 case RENDERPATH_GL11:
2367 case RENDERPATH_GL13:
2368 case RENDERPATH_GL20:
2369 case RENDERPATH_GLES1:
2370 case RENDERPATH_GLES2:
2372 if(gl_state.scissortest)
2373 qglEnable(GL_SCISSOR_TEST);
2375 qglDisable(GL_SCISSOR_TEST);
2378 case RENDERPATH_D3D9:
2380 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2383 case RENDERPATH_D3D10:
2384 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2386 case RENDERPATH_D3D11:
2387 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2389 case RENDERPATH_SOFT:
2390 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2396 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2398 static const float blackcolor[4] = {0, 0, 0, 0};
2399 // prevent warnings when trying to clear a buffer that does not exist
2401 colorvalue = blackcolor;
2404 mask &= ~GL_STENCIL_BUFFER_BIT;
2407 switch(vid.renderpath)
2409 case RENDERPATH_GL11:
2410 case RENDERPATH_GL13:
2411 case RENDERPATH_GL20:
2412 case RENDERPATH_GLES1:
2413 case RENDERPATH_GLES2:
2415 if (mask & GL_COLOR_BUFFER_BIT)
2417 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2419 if (mask & GL_DEPTH_BUFFER_BIT)
2422 qglClearDepthf(depthvalue);CHECKGLERROR
2424 qglClearDepth(depthvalue);CHECKGLERROR
2427 if (mask & GL_STENCIL_BUFFER_BIT)
2429 qglClearStencil(stencilvalue);CHECKGLERROR
2431 qglClear(mask);CHECKGLERROR
2433 case RENDERPATH_D3D9:
2435 IDirect3DDevice9_Clear(vid_d3d9dev, 0, NULL, ((mask & GL_COLOR_BUFFER_BIT) ? D3DCLEAR_TARGET : 0) | ((mask & GL_STENCIL_BUFFER_BIT) ? D3DCLEAR_STENCIL : 0) | ((mask & GL_DEPTH_BUFFER_BIT) ? D3DCLEAR_ZBUFFER : 0), D3DCOLOR_COLORVALUE(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]), depthvalue, stencilvalue);
2438 case RENDERPATH_D3D10:
2439 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2441 case RENDERPATH_D3D11:
2442 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2444 case RENDERPATH_SOFT:
2445 if (mask & GL_COLOR_BUFFER_BIT)
2446 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2447 if (mask & GL_DEPTH_BUFFER_BIT)
2448 DPSOFTRAST_ClearDepth(depthvalue);
2453 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2455 switch(vid.renderpath)
2457 case RENDERPATH_GL11:
2458 case RENDERPATH_GL13:
2459 case RENDERPATH_GL20:
2460 case RENDERPATH_GLES1:
2461 case RENDERPATH_GLES2:
2463 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2465 case RENDERPATH_D3D9:
2468 // LordHavoc: we can't directly download the backbuffer because it may be
2469 // multisampled, and it may not be lockable, so we blit it to a lockable
2470 // surface of the same dimensions (but without multisample) to resolve the
2471 // multisample buffer to a normal image, and then lock that...
2472 IDirect3DSurface9 *stretchsurface = NULL;
2473 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2475 D3DLOCKED_RECT lockedrect;
2476 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2478 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2481 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2482 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2483 memcpy(outpixels + line * width * 4, row, width * 4);
2484 IDirect3DSurface9_UnlockRect(stretchsurface);
2487 IDirect3DSurface9_Release(stretchsurface);
2490 //IDirect3DSurface9 *syssurface = NULL;
2491 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2492 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2493 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2494 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2495 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2496 //IDirect3DSurface9_UnlockRect(syssurface);
2497 //IDirect3DSurface9_Release(syssurface);
2501 case RENDERPATH_D3D10:
2502 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2504 case RENDERPATH_D3D11:
2505 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2507 case RENDERPATH_SOFT:
2508 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2513 // called at beginning of frame
2514 void R_Mesh_Start(void)
2517 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
2519 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2521 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2522 Cvar_SetValueQuick(&gl_paranoid, 1);
2526 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2530 char compilelog[MAX_INPUTLINE];
2531 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2534 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2535 qglCompileShader(shaderobject);CHECKGLERROR
2536 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2537 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2538 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2540 int i, j, pretextlines = 0;
2541 for (i = 0;i < numstrings - 1;i++)
2542 for (j = 0;strings[i][j];j++)
2543 if (strings[i][j] == '\n')
2545 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2547 if (!shadercompiled)
2549 qglDeleteShader(shaderobject);CHECKGLERROR
2552 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2553 qglDeleteShader(shaderobject);CHECKGLERROR
2557 unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list)
2559 GLint programlinked;
2560 GLuint programobject = 0;
2561 char linklog[MAX_INPUTLINE];
2564 programobject = qglCreateProgram();CHECKGLERROR
2568 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2569 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2570 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2571 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2572 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2573 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2574 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2575 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2576 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2577 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2579 if(vid.support.gl20shaders130)
2580 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2583 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2586 #ifdef GL_GEOMETRY_SHADER
2587 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2591 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2594 qglLinkProgram(programobject);CHECKGLERROR
2595 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2596 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2599 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2600 Con_DPrintf("program link log:\n%s\n", linklog);
2601 // software vertex shader is ok but software fragment shader is WAY
2602 // too slow, fail program if so.
2603 // NOTE: this string might be ATI specific, but that's ok because the
2604 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2605 // software fragment shader due to low instruction and dependent
2607 if (strstr(linklog, "fragment shader will run in software"))
2608 programlinked = false;
2612 return programobject;
2614 qglDeleteProgram(programobject);CHECKGLERROR
2618 void GL_Backend_FreeProgram(unsigned int prog)
2621 qglDeleteProgram(prog);
2625 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2630 for (i = 0;i < count;i++)
2631 *out++ = *in++ + offset;
2634 memcpy(out, in, sizeof(*out) * count);
2637 // renders triangles using vertices from the active arrays
2638 int paranoidblah = 0;
2639 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)
2641 unsigned int numelements = numtriangles * 3;
2643 size_t bufferoffset3i;
2645 size_t bufferoffset3s;
2646 if (numvertices < 3 || numtriangles < 1)
2648 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2649 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);
2652 if (!gl_mesh_prefer_short_elements.integer)
2656 if (element3i_indexbuffer)
2657 element3i_indexbuffer = NULL;
2659 // adjust the pointers for firsttriangle
2661 element3i += firsttriangle * 3;
2662 if (element3i_indexbuffer)
2663 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2665 element3s += firsttriangle * 3;
2666 if (element3s_indexbuffer)
2667 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2668 switch(vid.renderpath)
2670 case RENDERPATH_GL11:
2671 case RENDERPATH_GL13:
2672 case RENDERPATH_GL20:
2673 case RENDERPATH_GLES1:
2674 case RENDERPATH_GLES2:
2675 // check if the user specified to ignore static index buffers
2676 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2678 element3i_indexbuffer = NULL;
2679 element3s_indexbuffer = NULL;
2682 case RENDERPATH_D3D9:
2683 case RENDERPATH_D3D10:
2684 case RENDERPATH_D3D11:
2686 case RENDERPATH_SOFT:
2689 // upload a dynamic index buffer if needed
2692 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2694 if (gl_state.draw_dynamicindexbuffer)
2695 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2697 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2698 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2699 element3s_bufferoffset = 0;
2704 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2706 if (gl_state.draw_dynamicindexbuffer)
2707 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2709 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2710 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2711 element3i_bufferoffset = 0;
2714 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2715 bufferoffset3i = element3i_bufferoffset;
2716 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2717 bufferoffset3s = element3s_bufferoffset;
2718 r_refdef.stats.draws++;
2719 r_refdef.stats.draws_vertices += numvertices;
2720 r_refdef.stats.draws_elements += numelements;
2721 if (gl_paranoid.integer)
2724 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2726 unsigned int j, size;
2728 // note: there's no validation done here on buffer objects because it
2729 // is somewhat difficult to get at the data, and gl_paranoid can be
2730 // used without buffer objects if the need arises
2731 // (the data could be gotten using glMapBuffer but it would be very
2732 // slow due to uncachable video memory reads)
2733 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2734 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2736 if (gl_state.pointer_vertex_pointer)
2737 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2739 if (gl_state.pointer_color_enabled)
2741 if (!qglIsEnabled(GL_COLOR_ARRAY))
2742 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2744 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2745 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2748 for (i = 0;i < vid.texarrayunits;i++)
2750 if (gl_state.units[i].arrayenabled)
2752 GL_ClientActiveTexture(i);
2753 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2754 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2756 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2757 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++)
2764 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2766 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2768 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2775 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2777 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2779 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2785 if (r_render.integer || r_refdef.draw2dstage)
2787 switch(vid.renderpath)
2789 case RENDERPATH_GL11:
2790 case RENDERPATH_GL13:
2791 case RENDERPATH_GL20:
2793 if (gl_mesh_testmanualfeeding.integer)
2796 unsigned int i, j, element;
2798 qglBegin(GL_TRIANGLES);
2799 if(vid.renderpath == RENDERPATH_GL20)
2801 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2804 element = element3i[i];
2806 element = element3s[i];
2808 element = firstvertex + i;
2809 for (j = 0;j < vid.texarrayunits;j++)
2811 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2813 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2815 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2816 if (gl_state.units[j].pointer_texcoord_components == 4)
2817 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2818 else if (gl_state.units[j].pointer_texcoord_components == 3)
2819 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2820 else if (gl_state.units[j].pointer_texcoord_components == 2)
2821 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2823 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2825 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2827 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2828 if (gl_state.units[j].pointer_texcoord_components == 4)
2829 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2830 else if (gl_state.units[j].pointer_texcoord_components == 3)
2831 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2832 else if (gl_state.units[j].pointer_texcoord_components == 2)
2833 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2834 else if (gl_state.units[j].pointer_texcoord_components == 1)
2835 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2837 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2839 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2840 if (gl_state.units[j].pointer_texcoord_components == 4)
2841 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2842 else if (gl_state.units[j].pointer_texcoord_components == 3)
2843 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2844 else if (gl_state.units[j].pointer_texcoord_components == 2)
2845 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2846 else if (gl_state.units[j].pointer_texcoord_components == 1)
2847 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2851 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2853 if (gl_state.pointer_color_gltype == GL_FLOAT)
2855 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2856 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2858 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2860 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2861 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2864 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2866 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2867 if (gl_state.pointer_vertex_components == 4)
2868 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2869 else if (gl_state.pointer_vertex_components == 3)
2870 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2872 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2878 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2881 element = element3i[i];
2883 element = element3s[i];
2885 element = firstvertex + i;
2886 for (j = 0;j < vid.texarrayunits;j++)
2888 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2890 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2892 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2893 if (vid.texarrayunits > 1)
2895 if (gl_state.units[j].pointer_texcoord_components == 4)
2896 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2897 else if (gl_state.units[j].pointer_texcoord_components == 3)
2898 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2899 else if (gl_state.units[j].pointer_texcoord_components == 2)
2900 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2902 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2906 if (gl_state.units[j].pointer_texcoord_components == 4)
2907 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2908 else if (gl_state.units[j].pointer_texcoord_components == 3)
2909 qglTexCoord3f(p[0], p[1], p[2]);
2910 else if (gl_state.units[j].pointer_texcoord_components == 2)
2911 qglTexCoord2f(p[0], p[1]);
2913 qglTexCoord1f(p[0]);
2916 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2918 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2919 if (vid.texarrayunits > 1)
2921 if (gl_state.units[j].pointer_texcoord_components == 4)
2922 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2923 else if (gl_state.units[j].pointer_texcoord_components == 3)
2924 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2925 else if (gl_state.units[j].pointer_texcoord_components == 2)
2926 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2927 else if (gl_state.units[j].pointer_texcoord_components == 1)
2928 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2932 if (gl_state.units[j].pointer_texcoord_components == 4)
2933 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2934 else if (gl_state.units[j].pointer_texcoord_components == 3)
2935 qglTexCoord3f(s[0], s[1], s[2]);
2936 else if (gl_state.units[j].pointer_texcoord_components == 2)
2937 qglTexCoord2f(s[0], s[1]);
2938 else if (gl_state.units[j].pointer_texcoord_components == 1)
2939 qglTexCoord1f(s[0]);
2942 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2944 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2945 if (vid.texarrayunits > 1)
2947 if (gl_state.units[j].pointer_texcoord_components == 4)
2948 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2949 else if (gl_state.units[j].pointer_texcoord_components == 3)
2950 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2951 else if (gl_state.units[j].pointer_texcoord_components == 2)
2952 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2953 else if (gl_state.units[j].pointer_texcoord_components == 1)
2954 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2958 if (gl_state.units[j].pointer_texcoord_components == 4)
2959 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2960 else if (gl_state.units[j].pointer_texcoord_components == 3)
2961 qglTexCoord3f(sb[0], sb[1], sb[2]);
2962 else if (gl_state.units[j].pointer_texcoord_components == 2)
2963 qglTexCoord2f(sb[0], sb[1]);
2964 else if (gl_state.units[j].pointer_texcoord_components == 1)
2965 qglTexCoord1f(sb[0]);
2970 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2972 if (gl_state.pointer_color_gltype == GL_FLOAT)
2974 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2975 qglColor4f(p[0], p[1], p[2], p[3]);
2977 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2979 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2980 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2983 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2985 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2986 if (gl_state.pointer_vertex_components == 4)
2987 qglVertex4f(p[0], p[1], p[2], p[3]);
2988 else if (gl_state.pointer_vertex_components == 3)
2989 qglVertex3f(p[0], p[1], p[2]);
2991 qglVertex2f(p[0], p[1]);
2999 else if (bufferobject3s)
3001 GL_BindEBO(bufferobject3s);
3003 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3005 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
3011 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3015 else if (bufferobject3i)
3017 GL_BindEBO(bufferobject3i);
3019 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3021 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3027 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3035 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3037 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3043 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3051 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3053 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3059 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3065 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3069 case RENDERPATH_D3D9:
3071 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3073 if (element3s_indexbuffer)
3075 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3076 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3078 else if (element3i_indexbuffer)
3080 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3081 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3084 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3089 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3091 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3093 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3097 case RENDERPATH_D3D10:
3098 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3100 case RENDERPATH_D3D11:
3101 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3103 case RENDERPATH_SOFT:
3104 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3106 case RENDERPATH_GLES1:
3107 case RENDERPATH_GLES2:
3108 // GLES does not have glDrawRangeElements, and generally
3109 // underperforms with index buffers, so this code path is
3110 // relatively straightforward...
3112 if (gl_paranoid.integer)
3114 int r, prog, enabled, i;
3115 GLsizei attriblength;
3118 GLchar attribname[1024];
3119 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3120 if (r != GL_FRAMEBUFFER_COMPLETE)
3121 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3122 #ifndef GL_CURRENT_PROGRAM
3123 #define GL_CURRENT_PROGRAM 0x8B8D
3125 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3126 if (r < 0 || r > 10000)
3127 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3129 for (i = 0;i < 8;i++)
3131 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3134 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3135 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);
3141 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3146 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3151 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3159 // restores backend state, used when done with 3D rendering
3160 void R_Mesh_Finish(void)
3162 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
3165 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3167 r_meshbuffer_t *buffer;
3168 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3170 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3171 memset(buffer, 0, sizeof(*buffer));
3172 buffer->bufferobject = 0;
3173 buffer->devicebuffer = NULL;
3175 buffer->isindexbuffer = isindexbuffer;
3176 buffer->isdynamic = isdynamic;
3177 buffer->isindex16 = isindex16;
3178 strlcpy(buffer->name, name, sizeof(buffer->name));
3179 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3183 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3187 if (buffer->isindexbuffer)
3189 r_refdef.stats.indexbufferuploadcount++;
3190 r_refdef.stats.indexbufferuploadsize += size;
3194 r_refdef.stats.vertexbufferuploadcount++;
3195 r_refdef.stats.vertexbufferuploadsize += size;
3197 switch(vid.renderpath)
3199 case RENDERPATH_GL11:
3200 case RENDERPATH_GL13:
3201 case RENDERPATH_GL20:
3202 case RENDERPATH_GLES1:
3203 case RENDERPATH_GLES2:
3204 if (!buffer->bufferobject)
3205 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3206 if (buffer->isindexbuffer)
3207 GL_BindEBO(buffer->bufferobject);
3209 GL_BindVBO(buffer->bufferobject);
3210 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3212 case RENDERPATH_D3D9:
3216 void *datapointer = NULL;
3217 if (buffer->isindexbuffer)
3219 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3220 if (size > buffer->size || !buffer->devicebuffer)
3222 if (buffer->devicebuffer)
3223 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3224 buffer->devicebuffer = NULL;
3225 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)))
3226 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);
3227 buffer->devicebuffer = (void *)d3d9indexbuffer;
3228 buffer->size = size;
3230 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3233 memcpy(datapointer, data, size);
3235 memset(datapointer, 0, size);
3236 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3241 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3242 if (size > buffer->size || !buffer->devicebuffer)
3244 if (buffer->devicebuffer)
3245 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3246 buffer->devicebuffer = NULL;
3247 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3248 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);
3249 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3250 buffer->size = size;
3252 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3255 memcpy(datapointer, data, size);
3257 memset(datapointer, 0, size);
3258 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3264 case RENDERPATH_D3D10:
3265 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3267 case RENDERPATH_D3D11:
3268 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3270 case RENDERPATH_SOFT:
3275 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3279 switch(vid.renderpath)
3281 case RENDERPATH_GL11:
3282 case RENDERPATH_GL13:
3283 case RENDERPATH_GL20:
3284 case RENDERPATH_GLES1:
3285 case RENDERPATH_GLES2:
3286 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3288 case RENDERPATH_D3D9:
3290 if (gl_state.d3dvertexbuffer == (void *)buffer)
3291 gl_state.d3dvertexbuffer = NULL;
3292 if (buffer->devicebuffer)
3294 if (buffer->isindexbuffer)
3295 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3297 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3298 buffer->devicebuffer = NULL;
3302 case RENDERPATH_D3D10:
3303 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3305 case RENDERPATH_D3D11:
3306 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3308 case RENDERPATH_SOFT:
3311 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3314 void GL_Mesh_ListVBOs(qboolean printeach)
3317 size_t ebocount = 0, ebomemory = 0;
3318 size_t vbocount = 0, vbomemory = 0;
3319 r_meshbuffer_t *buffer;
3320 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3321 for (i = 0;i < endindex;i++)
3323 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3326 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)");}
3327 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)");}
3329 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);
3334 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3336 switch(vid.renderpath)
3338 case RENDERPATH_GL11:
3339 case RENDERPATH_GL13:
3340 case RENDERPATH_GLES1:
3341 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)
3343 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3344 gl_state.pointer_vertex_components = components;
3345 gl_state.pointer_vertex_gltype = gltype;
3346 gl_state.pointer_vertex_stride = stride;
3347 gl_state.pointer_vertex_pointer = pointer;
3348 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3349 gl_state.pointer_vertex_offset = bufferoffset;
3351 GL_BindVBO(bufferobject);
3352 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3355 case RENDERPATH_GL20:
3356 case RENDERPATH_GLES2:
3357 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)
3359 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3360 gl_state.pointer_vertex_components = components;
3361 gl_state.pointer_vertex_gltype = gltype;
3362 gl_state.pointer_vertex_stride = stride;
3363 gl_state.pointer_vertex_pointer = pointer;
3364 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3365 gl_state.pointer_vertex_offset = bufferoffset;
3367 GL_BindVBO(bufferobject);
3368 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3371 case RENDERPATH_D3D9:
3372 case RENDERPATH_D3D10:
3373 case RENDERPATH_D3D11:
3374 case RENDERPATH_SOFT:
3379 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3381 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3382 // the pointer only.
3383 switch(vid.renderpath)
3385 case RENDERPATH_GL11:
3386 case RENDERPATH_GL13:
3387 case RENDERPATH_GLES1:
3392 // caller wants color array enabled
3393 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3394 if (!gl_state.pointer_color_enabled)
3396 gl_state.pointer_color_enabled = true;
3398 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3400 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)
3402 gl_state.pointer_color_components = components;
3403 gl_state.pointer_color_gltype = gltype;
3404 gl_state.pointer_color_stride = stride;
3405 gl_state.pointer_color_pointer = pointer;
3406 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3407 gl_state.pointer_color_offset = bufferoffset;
3409 GL_BindVBO(bufferobject);
3410 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3415 // caller wants color array disabled
3416 if (gl_state.pointer_color_enabled)
3418 gl_state.pointer_color_enabled = false;
3420 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3421 // when color array is on the glColor gets trashed, set it again
3422 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3427 case RENDERPATH_GL20:
3428 case RENDERPATH_GLES2:
3432 // caller wants color array enabled
3433 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3434 if (!gl_state.pointer_color_enabled)
3436 gl_state.pointer_color_enabled = true;
3438 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3440 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)
3442 gl_state.pointer_color_components = components;
3443 gl_state.pointer_color_gltype = gltype;
3444 gl_state.pointer_color_stride = stride;
3445 gl_state.pointer_color_pointer = pointer;
3446 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3447 gl_state.pointer_color_offset = bufferoffset;
3449 GL_BindVBO(bufferobject);
3450 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3455 // caller wants color array disabled
3456 if (gl_state.pointer_color_enabled)
3458 gl_state.pointer_color_enabled = false;
3460 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3461 // when color array is on the glColor gets trashed, set it again
3462 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3466 case RENDERPATH_D3D9:
3467 case RENDERPATH_D3D10:
3468 case RENDERPATH_D3D11:
3469 case RENDERPATH_SOFT:
3474 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)
3476 gltextureunit_t *unit = gl_state.units + unitnum;
3477 // update array settings
3478 // note: there is no need to check bufferobject here because all cases
3479 // that involve a valid bufferobject also supply a texcoord array
3480 switch(vid.renderpath)
3482 case RENDERPATH_GL11:
3483 case RENDERPATH_GL13:
3484 case RENDERPATH_GLES1:
3489 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3490 // texture array unit is enabled, enable the array
3491 if (!unit->arrayenabled)
3493 unit->arrayenabled = true;
3494 GL_ClientActiveTexture(unitnum);
3495 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3498 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)
3500 unit->pointer_texcoord_components = components;
3501 unit->pointer_texcoord_gltype = gltype;
3502 unit->pointer_texcoord_stride = stride;
3503 unit->pointer_texcoord_pointer = pointer;
3504 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3505 unit->pointer_texcoord_offset = bufferoffset;
3506 GL_ClientActiveTexture(unitnum);
3507 GL_BindVBO(bufferobject);
3508 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3513 // texture array unit is disabled, disable the array
3514 if (unit->arrayenabled)
3516 unit->arrayenabled = false;
3517 GL_ClientActiveTexture(unitnum);
3518 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3523 case RENDERPATH_GL20:
3524 case RENDERPATH_GLES2:
3528 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3529 // texture array unit is enabled, enable the array
3530 if (!unit->arrayenabled)
3532 unit->arrayenabled = true;
3533 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3536 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)
3538 unit->pointer_texcoord_components = components;
3539 unit->pointer_texcoord_gltype = gltype;
3540 unit->pointer_texcoord_stride = stride;
3541 unit->pointer_texcoord_pointer = pointer;
3542 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3543 unit->pointer_texcoord_offset = bufferoffset;
3544 GL_BindVBO(bufferobject);
3545 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3550 // texture array unit is disabled, disable the array
3551 if (unit->arrayenabled)
3553 unit->arrayenabled = false;
3554 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3558 case RENDERPATH_D3D9:
3559 case RENDERPATH_D3D10:
3560 case RENDERPATH_D3D11:
3561 case RENDERPATH_SOFT:
3566 int R_Mesh_TexBound(unsigned int unitnum, int id)
3568 gltextureunit_t *unit = gl_state.units + unitnum;
3569 if (unitnum >= vid.teximageunits)
3571 if (id == GL_TEXTURE_2D)
3573 if (id == GL_TEXTURE_3D)
3575 if (id == GL_TEXTURE_CUBE_MAP)
3576 return unit->tcubemap;
3580 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3582 switch(vid.renderpath)
3584 case RENDERPATH_GL11:
3585 case RENDERPATH_GL13:
3586 case RENDERPATH_GL20:
3587 case RENDERPATH_GLES1:
3588 case RENDERPATH_GLES2:
3589 R_Mesh_TexBind(0, tex);
3590 GL_ActiveTexture(0);CHECKGLERROR
3591 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3593 case RENDERPATH_D3D9:
3596 IDirect3DSurface9 *currentsurface = NULL;
3597 IDirect3DSurface9 *texturesurface = NULL;
3600 sourcerect.left = sx;
3601 sourcerect.top = sy;
3602 sourcerect.right = sx + width;
3603 sourcerect.bottom = sy + height;
3606 destrect.right = tx + width;
3607 destrect.bottom = ty + height;
3608 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3610 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3612 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3613 IDirect3DSurface9_Release(currentsurface);
3615 IDirect3DSurface9_Release(texturesurface);
3620 case RENDERPATH_D3D10:
3621 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3623 case RENDERPATH_D3D11:
3624 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3626 case RENDERPATH_SOFT:
3627 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3633 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};
3636 void R_Mesh_ClearBindingsForTexture(int texnum)
3638 gltextureunit_t *unit;
3639 unsigned int unitnum;
3640 // 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)
3641 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3643 unit = gl_state.units + unitnum;
3644 if (unit->t2d == texnum)
3646 if (unit->t3d == texnum)
3648 if (unit->tcubemap == texnum)
3649 unit->tcubemap = -1;
3653 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3655 gltextureunit_t *unit = gl_state.units + unitnum;
3656 int tex2d, tex3d, texcubemap, texnum;
3657 if (unitnum >= vid.teximageunits)
3659 // if (unit->texture == tex)
3661 switch(vid.renderpath)
3663 case RENDERPATH_GL20:
3664 case RENDERPATH_GLES2:
3667 tex = r_texture_white;
3668 // not initialized enough yet...
3672 unit->texture = tex;
3673 texnum = R_GetTexture(tex);
3674 switch(tex->gltexturetypeenum)
3676 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3677 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3678 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3681 case RENDERPATH_GL11:
3682 case RENDERPATH_GL13:
3683 case RENDERPATH_GLES1:
3684 unit->texture = tex;
3690 texnum = R_GetTexture(tex);
3691 switch(tex->gltexturetypeenum)
3699 case GL_TEXTURE_CUBE_MAP:
3700 texcubemap = texnum;
3704 // update 2d texture binding
3705 if (unit->t2d != tex2d)
3707 GL_ActiveTexture(unitnum);
3712 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3719 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3723 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3725 // update 3d texture binding
3726 if (unit->t3d != tex3d)
3728 GL_ActiveTexture(unitnum);
3733 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3740 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3744 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3746 // update cubemap texture binding
3747 if (unit->tcubemap != texcubemap)
3749 GL_ActiveTexture(unitnum);
3752 if (unit->tcubemap == 0)
3754 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3761 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3764 unit->tcubemap = texcubemap;
3765 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3768 case RENDERPATH_D3D9:
3771 extern cvar_t gl_texture_anisotropy;
3774 tex = r_texture_white;
3775 // not initialized enough yet...
3779 // upload texture if needed
3781 if (unit->texture == tex)
3783 unit->texture = tex;
3784 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3785 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3786 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3787 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3788 if (tex->d3daddressw)
3789 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3790 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3791 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3792 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3793 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3794 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3795 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3799 case RENDERPATH_D3D10:
3800 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3802 case RENDERPATH_D3D11:
3803 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3805 case RENDERPATH_SOFT:
3808 tex = r_texture_white;
3809 // not initialized enough yet...
3813 texnum = R_GetTexture(tex);
3814 if (unit->texture == tex)
3816 unit->texture = tex;
3817 DPSOFTRAST_SetTexture(unitnum, texnum);
3822 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3824 gltextureunit_t *unit = gl_state.units + unitnum;
3825 switch(vid.renderpath)
3827 case RENDERPATH_GL11:
3828 case RENDERPATH_GL13:
3829 case RENDERPATH_GL20:
3830 case RENDERPATH_GLES1:
3831 case RENDERPATH_GLES2:
3833 if (matrix && matrix->m[3][3])
3835 // texmatrix specified, check if it is different
3836 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3839 unit->texmatrixenabled = true;
3840 unit->matrix = *matrix;
3842 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3843 GL_ActiveTexture(unitnum);
3844 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3845 qglLoadMatrixf(glmatrix);CHECKGLERROR
3846 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3851 // no texmatrix specified, revert to identity
3852 if (unit->texmatrixenabled)
3854 unit->texmatrixenabled = false;
3855 unit->matrix = identitymatrix;
3857 GL_ActiveTexture(unitnum);
3858 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3859 qglLoadIdentity();CHECKGLERROR
3860 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3865 case RENDERPATH_D3D9:
3866 case RENDERPATH_D3D10:
3867 case RENDERPATH_D3D11:
3869 case RENDERPATH_SOFT:
3874 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3876 gltextureunit_t *unit = gl_state.units + unitnum;
3878 switch(vid.renderpath)
3880 case RENDERPATH_GL20:
3881 case RENDERPATH_GLES2:
3884 case RENDERPATH_GL13:
3885 case RENDERPATH_GLES1:
3886 #ifdef GL_TEXTURE_ENV
3887 // GL_ARB_texture_env_combine
3889 combinergb = GL_MODULATE;
3891 combinealpha = GL_MODULATE;
3896 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3898 if (combinergb == GL_DECAL)
3899 combinergb = GL_INTERPOLATE;
3900 if (unit->combine != GL_COMBINE)
3902 unit->combine = GL_COMBINE;
3903 GL_ActiveTexture(unitnum);
3904 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3905 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3907 if (unit->combinergb != combinergb)
3909 unit->combinergb = combinergb;
3910 GL_ActiveTexture(unitnum);
3911 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3913 if (unit->combinealpha != combinealpha)
3915 unit->combinealpha = combinealpha;
3916 GL_ActiveTexture(unitnum);
3917 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3919 if (unit->rgbscale != rgbscale)
3921 unit->rgbscale = rgbscale;
3922 GL_ActiveTexture(unitnum);
3923 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3925 if (unit->alphascale != alphascale)
3927 unit->alphascale = alphascale;
3928 GL_ActiveTexture(unitnum);
3929 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3934 if (unit->combine != combinergb)
3936 unit->combine = combinergb;
3937 GL_ActiveTexture(unitnum);
3938 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3943 case RENDERPATH_GL11:
3945 #ifdef GL_TEXTURE_ENV
3947 combinergb = GL_MODULATE;
3948 if (unit->combine != combinergb)
3950 unit->combine = combinergb;
3951 GL_ActiveTexture(unitnum);
3952 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3956 case RENDERPATH_D3D9:
3957 case RENDERPATH_D3D10:
3958 case RENDERPATH_D3D11:
3960 case RENDERPATH_SOFT:
3965 void R_Mesh_ResetTextureState(void)
3967 unsigned int unitnum;
3971 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3972 R_Mesh_TexBind(unitnum, NULL);
3973 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3974 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3975 switch(vid.renderpath)
3977 case RENDERPATH_GL20:
3978 case RENDERPATH_GLES2:
3979 case RENDERPATH_D3D9:
3980 case RENDERPATH_D3D10:
3981 case RENDERPATH_D3D11:
3982 case RENDERPATH_SOFT:
3984 case RENDERPATH_GL11:
3985 case RENDERPATH_GL13:
3986 case RENDERPATH_GLES1:
3987 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3989 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3990 R_Mesh_TexMatrix(unitnum, NULL);
3999 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
4000 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
4001 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
4003 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
4005 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4009 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
4011 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4012 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4013 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4017 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4019 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4020 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4021 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4022 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4023 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4024 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4025 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4029 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4030 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4031 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4034 static void R_Mesh_InitVertexDeclarations(void)
4037 r_vertex3f_d3d9decl = NULL;
4038 r_vertexgeneric_d3d9decl = NULL;
4039 r_vertexmesh_d3d9decl = NULL;
4040 switch(vid.renderpath)
4042 case RENDERPATH_GL20:
4043 case RENDERPATH_GL13:
4044 case RENDERPATH_GL11:
4045 case RENDERPATH_GLES1:
4046 case RENDERPATH_GLES2:
4048 case RENDERPATH_D3D9:
4049 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4050 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4051 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4053 case RENDERPATH_D3D10:
4054 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4056 case RENDERPATH_D3D11:
4057 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4059 case RENDERPATH_SOFT:
4065 static void R_Mesh_DestroyVertexDeclarations(void)
4068 if (r_vertex3f_d3d9decl)
4069 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4070 r_vertex3f_d3d9decl = NULL;
4071 if (r_vertexgeneric_d3d9decl)
4072 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4073 r_vertexgeneric_d3d9decl = NULL;
4074 if (r_vertexmesh_d3d9decl)
4075 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4076 r_vertexmesh_d3d9decl = NULL;
4080 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4082 // upload temporary vertexbuffer for this rendering
4083 if (!gl_state.usevbo_staticvertex)
4084 vertexbuffer = NULL;
4085 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4087 if (gl_state.preparevertices_dynamicvertexbuffer)
4088 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4090 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4091 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4093 switch(vid.renderpath)
4095 case RENDERPATH_GL20:
4096 case RENDERPATH_GLES2:
4099 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4100 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4101 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4102 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4103 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4104 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4105 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4109 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4110 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4111 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4112 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4113 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4114 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4115 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4118 case RENDERPATH_GL13:
4119 case RENDERPATH_GLES1:
4122 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4123 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4124 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4125 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4129 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4130 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4131 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4132 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4135 case RENDERPATH_GL11:
4138 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4139 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4140 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4144 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4145 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4146 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4149 case RENDERPATH_D3D9:
4151 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4153 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4155 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4156 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4157 gl_state.d3dvertexdata = (void *)vertex3f;
4158 gl_state.d3dvertexsize = sizeof(float[3]);
4161 case RENDERPATH_D3D10:
4162 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4164 case RENDERPATH_D3D11:
4165 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4167 case RENDERPATH_SOFT:
4168 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4169 DPSOFTRAST_SetColorPointer(NULL, 0);
4170 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4171 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4172 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4173 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4174 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4181 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4184 size = sizeof(r_vertexgeneric_t) * numvertices;
4185 if (gl_state.preparevertices_tempdatamaxsize < size)
4187 gl_state.preparevertices_tempdatamaxsize = size;
4188 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4190 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4191 gl_state.preparevertices_numvertices = numvertices;
4192 return gl_state.preparevertices_vertexgeneric;
4195 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4197 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4198 gl_state.preparevertices_vertexgeneric = NULL;
4199 gl_state.preparevertices_numvertices = 0;
4203 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4206 r_vertexgeneric_t *vertex;
4207 switch(vid.renderpath)
4209 case RENDERPATH_GL20:
4210 case RENDERPATH_GLES2:
4211 if (!vid.useinterleavedarrays)
4213 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4214 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4215 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4216 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4217 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4218 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4219 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4223 case RENDERPATH_GL11:
4224 case RENDERPATH_GL13:
4225 case RENDERPATH_GLES1:
4226 if (!vid.useinterleavedarrays)
4228 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4229 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4230 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4231 if (vid.texunits >= 2)
4232 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4233 if (vid.texunits >= 3)
4234 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4238 case RENDERPATH_D3D9:
4239 case RENDERPATH_D3D10:
4240 case RENDERPATH_D3D11:
4242 case RENDERPATH_SOFT:
4243 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4244 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4245 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4246 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4247 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4248 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4249 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4253 // no quick path for this case, convert to vertex structs
4254 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4255 for (i = 0;i < numvertices;i++)
4256 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4259 for (i = 0;i < numvertices;i++)
4260 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4264 for (i = 0;i < numvertices;i++)
4265 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4268 for (i = 0;i < numvertices;i++)
4269 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4270 R_Mesh_PrepareVertices_Generic_Unlock();
4271 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4274 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4276 // upload temporary vertexbuffer for this rendering
4277 if (!gl_state.usevbo_staticvertex)
4278 vertexbuffer = NULL;
4279 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4281 if (gl_state.preparevertices_dynamicvertexbuffer)
4282 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4284 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4285 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4287 switch(vid.renderpath)
4289 case RENDERPATH_GL20:
4290 case RENDERPATH_GLES2:
4293 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4294 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4295 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4296 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4297 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4298 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4299 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4303 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4304 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4305 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4306 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4307 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4308 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4309 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4312 case RENDERPATH_GL13:
4313 case RENDERPATH_GLES1:
4316 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4317 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4318 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4319 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4323 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4324 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4325 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4326 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4329 case RENDERPATH_GL11:
4332 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4333 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4334 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4338 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4339 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4340 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4343 case RENDERPATH_D3D9:
4345 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4347 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4349 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4350 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4351 gl_state.d3dvertexdata = (void *)vertex;
4352 gl_state.d3dvertexsize = sizeof(*vertex);
4355 case RENDERPATH_D3D10:
4356 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4358 case RENDERPATH_D3D11:
4359 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4361 case RENDERPATH_SOFT:
4362 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4363 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4364 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4365 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4366 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4367 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4368 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4375 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4378 size = sizeof(r_vertexmesh_t) * numvertices;
4379 if (gl_state.preparevertices_tempdatamaxsize < size)
4381 gl_state.preparevertices_tempdatamaxsize = size;
4382 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4384 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4385 gl_state.preparevertices_numvertices = numvertices;
4386 return gl_state.preparevertices_vertexmesh;
4389 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4391 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4392 gl_state.preparevertices_vertexmesh = NULL;
4393 gl_state.preparevertices_numvertices = 0;
4397 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)
4400 r_vertexmesh_t *vertex;
4401 switch(vid.renderpath)
4403 case RENDERPATH_GL20:
4404 case RENDERPATH_GLES2:
4405 if (!vid.useinterleavedarrays)
4407 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4408 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4409 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4410 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4411 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4412 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4413 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4417 case RENDERPATH_GL11:
4418 case RENDERPATH_GL13:
4419 case RENDERPATH_GLES1:
4420 if (!vid.useinterleavedarrays)
4422 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4423 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4424 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4425 if (vid.texunits >= 2)
4426 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4427 if (vid.texunits >= 3)
4428 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4432 case RENDERPATH_D3D9:
4433 case RENDERPATH_D3D10:
4434 case RENDERPATH_D3D11:
4436 case RENDERPATH_SOFT:
4437 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4438 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4439 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4440 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4441 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4442 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4443 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4447 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4448 for (i = 0;i < numvertices;i++)
4449 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4451 for (i = 0;i < numvertices;i++)
4452 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4454 for (i = 0;i < numvertices;i++)
4455 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4457 for (i = 0;i < numvertices;i++)
4458 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4461 for (i = 0;i < numvertices;i++)
4462 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4466 for (i = 0;i < numvertices;i++)
4467 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4469 if (texcoordtexture2f)
4470 for (i = 0;i < numvertices;i++)
4471 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4472 if (texcoordlightmap2f)
4473 for (i = 0;i < numvertices;i++)
4474 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4475 R_Mesh_PrepareVertices_Mesh_Unlock();
4476 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4479 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4481 // upload temporary vertexbuffer for this rendering
4482 if (!gl_state.usevbo_staticvertex)
4483 vertexbuffer = NULL;
4484 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4486 if (gl_state.preparevertices_dynamicvertexbuffer)
4487 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4489 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4490 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4492 switch(vid.renderpath)
4494 case RENDERPATH_GL20:
4495 case RENDERPATH_GLES2:
4498 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4499 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4500 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4501 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4502 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4503 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4504 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4508 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4509 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4510 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4511 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4512 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4513 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4514 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4517 case RENDERPATH_GL13:
4518 case RENDERPATH_GLES1:
4521 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4522 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4523 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4524 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4528 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4529 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4530 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4531 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4534 case RENDERPATH_GL11:
4537 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4538 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4539 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4543 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4544 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4545 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4548 case RENDERPATH_D3D9:
4550 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4552 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4554 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4555 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4556 gl_state.d3dvertexdata = (void *)vertex;
4557 gl_state.d3dvertexsize = sizeof(*vertex);
4560 case RENDERPATH_D3D10:
4561 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4563 case RENDERPATH_D3D11:
4564 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4566 case RENDERPATH_SOFT:
4567 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4568 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4569 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4570 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4571 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4572 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4573 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4578 void GL_BlendEquationSubtract(qboolean negated)
4582 switch(vid.renderpath)
4584 case RENDERPATH_GL11:
4585 case RENDERPATH_GL13:
4586 case RENDERPATH_GL20:
4587 case RENDERPATH_GLES1:
4588 case RENDERPATH_GLES2:
4589 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4591 case RENDERPATH_D3D9:
4593 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4596 case RENDERPATH_D3D10:
4597 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4599 case RENDERPATH_D3D11:
4600 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4602 case RENDERPATH_SOFT:
4603 DPSOFTRAST_BlendSubtract(true);
4609 switch(vid.renderpath)
4611 case RENDERPATH_GL11:
4612 case RENDERPATH_GL13:
4613 case RENDERPATH_GL20:
4614 case RENDERPATH_GLES1:
4615 case RENDERPATH_GLES2:
4616 qglBlendEquationEXT(GL_FUNC_ADD);
4618 case RENDERPATH_D3D9:
4620 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4623 case RENDERPATH_D3D10:
4624 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4626 case RENDERPATH_D3D11:
4627 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4629 case RENDERPATH_SOFT:
4630 DPSOFTRAST_BlendSubtract(false);