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 (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1268 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1269 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1270 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1271 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1273 case RENDERPATH_D3D9:
1274 case RENDERPATH_D3D10:
1275 case RENDERPATH_D3D11:
1277 case RENDERPATH_SOFT:
1283 void R_Mesh_DestroyFramebufferObject(int fbo)
1285 switch(vid.renderpath)
1287 case RENDERPATH_GL11:
1288 case RENDERPATH_GL13:
1289 case RENDERPATH_GL20:
1290 case RENDERPATH_GLES1:
1291 case RENDERPATH_GLES2:
1293 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1295 case RENDERPATH_D3D9:
1296 case RENDERPATH_D3D10:
1297 case RENDERPATH_D3D11:
1299 case RENDERPATH_SOFT:
1305 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1307 // LordHavoc: for some weird reason the redundant SetDepthStencilSurface calls are necessary (otherwise the lights fail depth test, as if they were using the shadowmap depth surface and render target still)
1308 if (gl_state.d3drt_depthsurface == depthsurface && gl_state.d3drt_colorsurfaces[0] == colorsurface0 && gl_state.d3drt_colorsurfaces[1] == colorsurface1 && gl_state.d3drt_colorsurfaces[2] == colorsurface2 && gl_state.d3drt_colorsurfaces[3] == colorsurface3)
1311 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1312 if (gl_state.d3drt_depthsurface != depthsurface)
1314 gl_state.d3drt_depthsurface = depthsurface;
1315 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1317 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1319 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1320 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1322 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1324 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1325 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1327 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1329 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1330 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1332 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1334 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1335 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1340 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1344 rtexture_t *textures[5];
1345 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1346 textures[4] = depthtexture;
1347 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1348 for (j = 0;j < 5;j++)
1350 for (i = 0;i < vid.teximageunits;i++)
1351 if (gl_state.units[i].texture == textures[j])
1352 R_Mesh_TexBind(i, NULL);
1353 // set up framebuffer object or render targets for the active rendering API
1354 switch(vid.renderpath)
1356 case RENDERPATH_GL11:
1357 case RENDERPATH_GL13:
1358 case RENDERPATH_GL20:
1359 case RENDERPATH_GLES1:
1360 case RENDERPATH_GLES2:
1361 if (gl_state.framebufferobject != fbo)
1363 gl_state.framebufferobject = fbo;
1364 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1367 case RENDERPATH_D3D9:
1369 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1370 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1373 IDirect3DSurface9 *colorsurfaces[4];
1374 for (i = 0;i < 4;i++)
1376 colorsurfaces[i] = NULL;
1378 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1380 // set the render targets for real
1381 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1382 // release the texture surface levels (they won't be lost while bound...)
1383 for (i = 0;i < 4;i++)
1385 IDirect3DSurface9_Release(colorsurfaces[i]);
1388 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1391 case RENDERPATH_D3D10:
1392 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1394 case RENDERPATH_D3D11:
1395 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1397 case RENDERPATH_SOFT:
1401 unsigned int *pointers[5];
1402 memset(pointers, 0, sizeof(pointers));
1403 for (i = 0;i < 5;i++)
1404 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1405 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1406 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1407 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1410 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1416 static int d3dcmpforglfunc(int f)
1420 case GL_NEVER: return D3DCMP_NEVER;
1421 case GL_LESS: return D3DCMP_LESS;
1422 case GL_EQUAL: return D3DCMP_EQUAL;
1423 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1424 case GL_GREATER: return D3DCMP_GREATER;
1425 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1426 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1427 case GL_ALWAYS: return D3DCMP_ALWAYS;
1428 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1432 static int d3dstencilopforglfunc(int f)
1436 case GL_KEEP: return D3DSTENCILOP_KEEP;
1437 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1438 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1439 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1444 extern cvar_t r_transparent_alphatocoverage;
1446 static void GL_Backend_ResetState(void)
1449 gl_state.active = true;
1450 gl_state.depthtest = true;
1451 gl_state.alphatest = false;
1452 gl_state.alphafunc = GL_GEQUAL;
1453 gl_state.alphafuncvalue = 0.5f;
1454 gl_state.alphatocoverage = false;
1455 gl_state.blendfunc1 = GL_ONE;
1456 gl_state.blendfunc2 = GL_ZERO;
1457 gl_state.blend = false;
1458 gl_state.depthmask = GL_TRUE;
1459 gl_state.colormask = 15;
1460 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1461 gl_state.lockrange_first = 0;
1462 gl_state.lockrange_count = 0;
1463 gl_state.cullface = GL_FRONT;
1464 gl_state.cullfaceenable = false;
1465 gl_state.polygonoffset[0] = 0;
1466 gl_state.polygonoffset[1] = 0;
1467 gl_state.framebufferobject = 0;
1468 gl_state.depthfunc = GL_LEQUAL;
1470 switch(vid.renderpath)
1472 case RENDERPATH_D3D9:
1475 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1476 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1477 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1478 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1479 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1480 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1481 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1485 case RENDERPATH_D3D10:
1486 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1488 case RENDERPATH_D3D11:
1489 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1491 case RENDERPATH_GL11:
1492 case RENDERPATH_GL13:
1493 case RENDERPATH_GLES1:
1494 #ifdef GL_ALPHA_TEST
1497 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1498 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1499 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1500 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1501 qglDisable(GL_BLEND);CHECKGLERROR
1502 qglCullFace(gl_state.cullface);CHECKGLERROR
1503 qglDisable(GL_CULL_FACE);CHECKGLERROR
1504 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1505 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1506 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1507 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1509 if (vid.support.arb_vertex_buffer_object)
1511 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1512 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1515 if (vid.support.ext_framebuffer_object)
1517 //qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);
1518 qglBindFramebufferEXT(GL_FRAMEBUFFER, 0);
1521 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1522 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1524 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1525 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1526 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1528 if (vid.support.ext_framebuffer_object)
1529 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.framebufferobject);
1531 gl_state.unit = MAX_TEXTUREUNITS;
1532 gl_state.clientunit = MAX_TEXTUREUNITS;
1533 for (i = 0;i < vid.texunits;i++)
1535 GL_ActiveTexture(i);
1536 GL_ClientActiveTexture(i);
1537 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1538 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1539 if (vid.support.ext_texture_3d)
1541 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1542 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1544 if (vid.support.arb_texture_cube_map)
1546 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
1547 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1550 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1551 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1552 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1553 qglLoadIdentity();CHECKGLERROR
1554 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1555 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1560 case RENDERPATH_SOFT:
1561 DPSOFTRAST_ColorMask(1,1,1,1);
1562 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1563 DPSOFTRAST_CullFace(gl_state.cullface);
1564 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1565 DPSOFTRAST_DepthMask(gl_state.depthmask);
1566 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1567 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1568 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1570 case RENDERPATH_GL20:
1571 case RENDERPATH_GLES2:
1573 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1574 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1575 qglDisable(GL_BLEND);CHECKGLERROR
1576 qglCullFace(gl_state.cullface);CHECKGLERROR
1577 qglDisable(GL_CULL_FACE);CHECKGLERROR
1578 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1579 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1580 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1581 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1582 if (vid.support.arb_vertex_buffer_object)
1584 qglBindBufferARB(GL_ARRAY_BUFFER, 0);
1585 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
1587 if (vid.support.ext_framebuffer_object)
1588 qglBindFramebufferEXT(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
1589 qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
1590 qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1591 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
1592 qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1593 qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
1594 gl_state.unit = MAX_TEXTUREUNITS;
1595 gl_state.clientunit = MAX_TEXTUREUNITS;
1596 for (i = 0;i < vid.teximageunits;i++)
1598 GL_ActiveTexture(i);
1599 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1600 if (vid.support.ext_texture_3d)
1602 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1604 if (vid.support.arb_texture_cube_map)
1606 qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
1609 for (i = 0;i < vid.texarrayunits;i++)
1612 qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1613 qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
1620 void GL_ActiveTexture(unsigned int num)
1622 if (gl_state.unit != num)
1624 gl_state.unit = num;
1625 switch(vid.renderpath)
1627 case RENDERPATH_GL11:
1628 case RENDERPATH_GL13:
1629 case RENDERPATH_GL20:
1630 case RENDERPATH_GLES1:
1631 case RENDERPATH_GLES2:
1632 if (qglActiveTexture)
1635 qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
1639 case RENDERPATH_D3D9:
1640 case RENDERPATH_D3D10:
1641 case RENDERPATH_D3D11:
1643 case RENDERPATH_SOFT:
1649 void GL_ClientActiveTexture(unsigned int num)
1651 if (gl_state.clientunit != num)
1653 gl_state.clientunit = num;
1654 switch(vid.renderpath)
1656 case RENDERPATH_GL11:
1657 case RENDERPATH_GL13:
1658 case RENDERPATH_GLES1:
1659 if (qglActiveTexture)
1662 qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit);
1666 case RENDERPATH_D3D9:
1667 case RENDERPATH_D3D10:
1668 case RENDERPATH_D3D11:
1670 case RENDERPATH_SOFT:
1672 case RENDERPATH_GL20:
1673 case RENDERPATH_GLES2:
1679 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1681 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1683 qboolean blendenable;
1684 gl_state.blendfunc1 = blendfunc1;
1685 gl_state.blendfunc2 = blendfunc2;
1686 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1687 switch(vid.renderpath)
1689 case RENDERPATH_GL11:
1690 case RENDERPATH_GL13:
1691 case RENDERPATH_GL20:
1692 case RENDERPATH_GLES1:
1693 case RENDERPATH_GLES2:
1695 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1696 if (gl_state.blend != blendenable)
1698 gl_state.blend = blendenable;
1699 if (!gl_state.blend)
1701 qglDisable(GL_BLEND);CHECKGLERROR
1705 qglEnable(GL_BLEND);CHECKGLERROR
1709 case RENDERPATH_D3D9:
1714 D3DBLEND d3dblendfunc[2];
1715 glblendfunc[0] = gl_state.blendfunc1;
1716 glblendfunc[1] = gl_state.blendfunc2;
1717 for (i = 0;i < 2;i++)
1719 switch(glblendfunc[i])
1721 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1722 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1723 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1724 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1725 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1726 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1727 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1728 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1729 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1730 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1733 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1734 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1735 if (gl_state.blend != blendenable)
1737 gl_state.blend = blendenable;
1738 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1743 case RENDERPATH_D3D10:
1744 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1746 case RENDERPATH_D3D11:
1747 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1749 case RENDERPATH_SOFT:
1750 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1756 void GL_DepthMask(int state)
1758 if (gl_state.depthmask != state)
1760 gl_state.depthmask = state;
1761 switch(vid.renderpath)
1763 case RENDERPATH_GL11:
1764 case RENDERPATH_GL13:
1765 case RENDERPATH_GL20:
1766 case RENDERPATH_GLES1:
1767 case RENDERPATH_GLES2:
1769 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1771 case RENDERPATH_D3D9:
1773 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1776 case RENDERPATH_D3D10:
1777 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1779 case RENDERPATH_D3D11:
1780 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1782 case RENDERPATH_SOFT:
1783 DPSOFTRAST_DepthMask(gl_state.depthmask);
1789 void GL_DepthTest(int state)
1791 if (gl_state.depthtest != state)
1793 gl_state.depthtest = state;
1794 switch(vid.renderpath)
1796 case RENDERPATH_GL11:
1797 case RENDERPATH_GL13:
1798 case RENDERPATH_GL20:
1799 case RENDERPATH_GLES1:
1800 case RENDERPATH_GLES2:
1802 if (gl_state.depthtest)
1804 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1808 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1811 case RENDERPATH_D3D9:
1813 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1816 case RENDERPATH_D3D10:
1817 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1819 case RENDERPATH_D3D11:
1820 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1822 case RENDERPATH_SOFT:
1823 DPSOFTRAST_DepthTest(gl_state.depthtest);
1829 void GL_DepthFunc(int state)
1831 if (gl_state.depthfunc != state)
1833 gl_state.depthfunc = state;
1834 switch(vid.renderpath)
1836 case RENDERPATH_GL11:
1837 case RENDERPATH_GL13:
1838 case RENDERPATH_GL20:
1839 case RENDERPATH_GLES1:
1840 case RENDERPATH_GLES2:
1842 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1844 case RENDERPATH_D3D9:
1846 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1849 case RENDERPATH_D3D10:
1850 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1852 case RENDERPATH_D3D11:
1853 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1855 case RENDERPATH_SOFT:
1856 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1862 void GL_DepthRange(float nearfrac, float farfrac)
1864 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1866 gl_state.depthrange[0] = nearfrac;
1867 gl_state.depthrange[1] = farfrac;
1868 switch(vid.renderpath)
1870 case RENDERPATH_GL11:
1871 case RENDERPATH_GL13:
1872 case RENDERPATH_GL20:
1873 case RENDERPATH_GLES1:
1874 case RENDERPATH_GLES2:
1876 qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
1878 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1881 case RENDERPATH_D3D9:
1884 D3DVIEWPORT9 d3dviewport;
1885 d3dviewport.X = gl_viewport.x;
1886 d3dviewport.Y = gl_viewport.y;
1887 d3dviewport.Width = gl_viewport.width;
1888 d3dviewport.Height = gl_viewport.height;
1889 d3dviewport.MinZ = gl_state.depthrange[0];
1890 d3dviewport.MaxZ = gl_state.depthrange[1];
1891 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1895 case RENDERPATH_D3D10:
1896 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1898 case RENDERPATH_D3D11:
1899 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1901 case RENDERPATH_SOFT:
1902 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1908 void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask)
1910 switch (vid.renderpath)
1912 case RENDERPATH_GL11:
1913 case RENDERPATH_GL13:
1914 case RENDERPATH_GL20:
1915 case RENDERPATH_GLES1:
1916 case RENDERPATH_GLES2:
1920 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1924 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1926 if (vid.support.ati_separate_stencil)
1928 qglStencilMask(writemask);CHECKGLERROR
1929 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1930 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1931 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1933 else if (vid.support.ext_stencil_two_side)
1935 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1936 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1937 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1938 qglStencilMask(writemask);CHECKGLERROR
1939 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1940 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1941 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1942 qglStencilMask(writemask);CHECKGLERROR
1943 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1944 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1948 case RENDERPATH_D3D9:
1950 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1951 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1952 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1953 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1954 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1955 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1956 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1957 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1958 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1960 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1961 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1962 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1965 case RENDERPATH_D3D10:
1966 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1968 case RENDERPATH_D3D11:
1969 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1971 case RENDERPATH_SOFT:
1972 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1977 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1979 switch (vid.renderpath)
1981 case RENDERPATH_GL11:
1982 case RENDERPATH_GL13:
1983 case RENDERPATH_GL20:
1984 case RENDERPATH_GLES1:
1985 case RENDERPATH_GLES2:
1989 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1993 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1995 if (vid.support.ext_stencil_two_side)
1997 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1998 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2001 qglStencilMask(writemask);CHECKGLERROR
2002 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2003 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2006 case RENDERPATH_D3D9:
2008 if (vid.support.ati_separate_stencil)
2009 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2011 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2012 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2013 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2014 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2015 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2016 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2017 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2020 case RENDERPATH_D3D10:
2021 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2023 case RENDERPATH_D3D11:
2024 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2026 case RENDERPATH_SOFT:
2027 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2032 void GL_PolygonOffset(float planeoffset, float depthoffset)
2034 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2036 gl_state.polygonoffset[0] = planeoffset;
2037 gl_state.polygonoffset[1] = depthoffset;
2038 switch(vid.renderpath)
2040 case RENDERPATH_GL11:
2041 case RENDERPATH_GL13:
2042 case RENDERPATH_GL20:
2043 case RENDERPATH_GLES1:
2044 case RENDERPATH_GLES2:
2045 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2047 case RENDERPATH_D3D9:
2049 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2050 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2053 case RENDERPATH_D3D10:
2054 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2056 case RENDERPATH_D3D11:
2057 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2059 case RENDERPATH_SOFT:
2060 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2066 void GL_SetMirrorState(qboolean state)
2068 if (v_flipped_state != state)
2070 v_flipped_state = state;
2071 if (gl_state.cullface == GL_BACK)
2072 gl_state.cullface = GL_FRONT;
2073 else if (gl_state.cullface == GL_FRONT)
2074 gl_state.cullface = GL_BACK;
2077 switch(vid.renderpath)
2079 case RENDERPATH_GL11:
2080 case RENDERPATH_GL13:
2081 case RENDERPATH_GL20:
2082 case RENDERPATH_GLES1:
2083 case RENDERPATH_GLES2:
2084 qglCullFace(gl_state.cullface);CHECKGLERROR
2086 case RENDERPATH_D3D9:
2088 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2091 case RENDERPATH_D3D10:
2092 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2094 case RENDERPATH_D3D11:
2095 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2097 case RENDERPATH_SOFT:
2098 DPSOFTRAST_CullFace(gl_state.cullface);
2104 void GL_CullFace(int state)
2108 if(state == GL_FRONT)
2110 else if(state == GL_BACK)
2114 switch(vid.renderpath)
2116 case RENDERPATH_GL11:
2117 case RENDERPATH_GL13:
2118 case RENDERPATH_GL20:
2119 case RENDERPATH_GLES1:
2120 case RENDERPATH_GLES2:
2123 if (state != GL_NONE)
2125 if (!gl_state.cullfaceenable)
2127 gl_state.cullfaceenable = true;
2128 qglEnable(GL_CULL_FACE);CHECKGLERROR
2130 if (gl_state.cullface != state)
2132 gl_state.cullface = state;
2133 qglCullFace(gl_state.cullface);CHECKGLERROR
2138 if (gl_state.cullfaceenable)
2140 gl_state.cullfaceenable = false;
2141 qglDisable(GL_CULL_FACE);CHECKGLERROR
2145 case RENDERPATH_D3D9:
2147 if (gl_state.cullface != state)
2149 gl_state.cullface = state;
2150 switch(gl_state.cullface)
2153 gl_state.cullfaceenable = false;
2154 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2157 gl_state.cullfaceenable = true;
2158 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2161 gl_state.cullfaceenable = true;
2162 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2168 case RENDERPATH_D3D10:
2169 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2171 case RENDERPATH_D3D11:
2172 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2174 case RENDERPATH_SOFT:
2175 if (gl_state.cullface != state)
2177 gl_state.cullface = state;
2178 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2179 DPSOFTRAST_CullFace(gl_state.cullface);
2185 void GL_AlphaTest(int state)
2187 if (gl_state.alphatest != state)
2189 gl_state.alphatest = state;
2190 switch(vid.renderpath)
2192 case RENDERPATH_GL11:
2193 case RENDERPATH_GL13:
2194 case RENDERPATH_GLES1:
2195 #ifdef GL_ALPHA_TEST
2196 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2198 if (gl_state.alphatest)
2200 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2204 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2208 case RENDERPATH_D3D9:
2209 case RENDERPATH_D3D10:
2210 case RENDERPATH_D3D11:
2211 case RENDERPATH_SOFT:
2212 case RENDERPATH_GL20:
2213 case RENDERPATH_GLES2:
2219 void GL_AlphaToCoverage(qboolean state)
2221 if (gl_state.alphatocoverage != state)
2223 gl_state.alphatocoverage = state;
2224 switch(vid.renderpath)
2226 case RENDERPATH_GL11:
2227 case RENDERPATH_GL13:
2228 case RENDERPATH_GLES1:
2229 case RENDERPATH_GLES2:
2230 case RENDERPATH_D3D9:
2231 case RENDERPATH_D3D10:
2232 case RENDERPATH_D3D11:
2233 case RENDERPATH_SOFT:
2235 case RENDERPATH_GL20:
2236 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2237 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2239 if (gl_state.alphatocoverage)
2241 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2242 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2246 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2247 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2255 void GL_ColorMask(int r, int g, int b, int a)
2257 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2258 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2259 if (gl_state.colormask != state)
2261 gl_state.colormask = state;
2262 switch(vid.renderpath)
2264 case RENDERPATH_GL11:
2265 case RENDERPATH_GL13:
2266 case RENDERPATH_GL20:
2267 case RENDERPATH_GLES1:
2268 case RENDERPATH_GLES2:
2270 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2272 case RENDERPATH_D3D9:
2274 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2277 case RENDERPATH_D3D10:
2278 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2280 case RENDERPATH_D3D11:
2281 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2283 case RENDERPATH_SOFT:
2284 DPSOFTRAST_ColorMask(r, g, b, a);
2290 void GL_Color(float cr, float cg, float cb, float ca)
2292 if (gl_state.pointer_color_enabled || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
2294 gl_state.color4f[0] = cr;
2295 gl_state.color4f[1] = cg;
2296 gl_state.color4f[2] = cb;
2297 gl_state.color4f[3] = ca;
2298 switch(vid.renderpath)
2300 case RENDERPATH_GL11:
2301 case RENDERPATH_GL13:
2302 case RENDERPATH_GLES1:
2304 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2307 case RENDERPATH_D3D9:
2308 case RENDERPATH_D3D10:
2309 case RENDERPATH_D3D11:
2310 // no equivalent in D3D
2312 case RENDERPATH_SOFT:
2313 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2315 case RENDERPATH_GL20:
2316 case RENDERPATH_GLES2:
2317 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2323 void GL_Scissor (int x, int y, int width, int height)
2325 switch(vid.renderpath)
2327 case RENDERPATH_GL11:
2328 case RENDERPATH_GL13:
2329 case RENDERPATH_GL20:
2330 case RENDERPATH_GLES1:
2331 case RENDERPATH_GLES2:
2333 qglScissor(x, y,width,height);
2336 case RENDERPATH_D3D9:
2342 d3drect.right = x + width;
2343 d3drect.bottom = y + height;
2344 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2348 case RENDERPATH_D3D10:
2349 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2351 case RENDERPATH_D3D11:
2352 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2354 case RENDERPATH_SOFT:
2355 DPSOFTRAST_Scissor(x, y, width, height);
2360 void GL_ScissorTest(int state)
2362 if (gl_state.scissortest != state)
2364 gl_state.scissortest = state;
2365 switch(vid.renderpath)
2367 case RENDERPATH_GL11:
2368 case RENDERPATH_GL13:
2369 case RENDERPATH_GL20:
2370 case RENDERPATH_GLES1:
2371 case RENDERPATH_GLES2:
2373 if(gl_state.scissortest)
2374 qglEnable(GL_SCISSOR_TEST);
2376 qglDisable(GL_SCISSOR_TEST);
2379 case RENDERPATH_D3D9:
2381 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2384 case RENDERPATH_D3D10:
2385 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2387 case RENDERPATH_D3D11:
2388 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2390 case RENDERPATH_SOFT:
2391 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2397 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2399 static const float blackcolor[4] = {0, 0, 0, 0};
2400 // prevent warnings when trying to clear a buffer that does not exist
2402 colorvalue = blackcolor;
2405 mask &= ~GL_STENCIL_BUFFER_BIT;
2408 switch(vid.renderpath)
2410 case RENDERPATH_GL11:
2411 case RENDERPATH_GL13:
2412 case RENDERPATH_GL20:
2413 case RENDERPATH_GLES1:
2414 case RENDERPATH_GLES2:
2416 if (mask & GL_COLOR_BUFFER_BIT)
2418 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2420 if (mask & GL_DEPTH_BUFFER_BIT)
2423 qglClearDepthf(depthvalue);CHECKGLERROR
2425 qglClearDepth(depthvalue);CHECKGLERROR
2428 if (mask & GL_STENCIL_BUFFER_BIT)
2430 qglClearStencil(stencilvalue);CHECKGLERROR
2432 qglClear(mask);CHECKGLERROR
2434 case RENDERPATH_D3D9:
2436 IDirect3DDevice9_Clear(vid_d3d9dev, 0, NULL, ((mask & GL_COLOR_BUFFER_BIT) ? D3DCLEAR_TARGET : 0) | ((mask & GL_STENCIL_BUFFER_BIT) ? D3DCLEAR_STENCIL : 0) | ((mask & GL_DEPTH_BUFFER_BIT) ? D3DCLEAR_ZBUFFER : 0), D3DCOLOR_COLORVALUE(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]), depthvalue, stencilvalue);
2439 case RENDERPATH_D3D10:
2440 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2442 case RENDERPATH_D3D11:
2443 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2445 case RENDERPATH_SOFT:
2446 if (mask & GL_COLOR_BUFFER_BIT)
2447 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2448 if (mask & GL_DEPTH_BUFFER_BIT)
2449 DPSOFTRAST_ClearDepth(depthvalue);
2454 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2456 switch(vid.renderpath)
2458 case RENDERPATH_GL11:
2459 case RENDERPATH_GL13:
2460 case RENDERPATH_GL20:
2461 case RENDERPATH_GLES1:
2462 case RENDERPATH_GLES2:
2464 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2466 case RENDERPATH_D3D9:
2469 // LordHavoc: we can't directly download the backbuffer because it may be
2470 // multisampled, and it may not be lockable, so we blit it to a lockable
2471 // surface of the same dimensions (but without multisample) to resolve the
2472 // multisample buffer to a normal image, and then lock that...
2473 IDirect3DSurface9 *stretchsurface = NULL;
2474 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2476 D3DLOCKED_RECT lockedrect;
2477 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2479 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2482 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2483 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2484 memcpy(outpixels + line * width * 4, row, width * 4);
2485 IDirect3DSurface9_UnlockRect(stretchsurface);
2488 IDirect3DSurface9_Release(stretchsurface);
2491 //IDirect3DSurface9 *syssurface = NULL;
2492 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2493 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2494 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2495 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2496 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2497 //IDirect3DSurface9_UnlockRect(syssurface);
2498 //IDirect3DSurface9_Release(syssurface);
2502 case RENDERPATH_D3D10:
2503 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2505 case RENDERPATH_D3D11:
2506 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2508 case RENDERPATH_SOFT:
2509 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2514 // called at beginning of frame
2515 void R_Mesh_Start(void)
2518 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
2520 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2522 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2523 Cvar_SetValueQuick(&gl_paranoid, 1);
2527 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2531 char compilelog[MAX_INPUTLINE];
2532 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2535 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2536 qglCompileShader(shaderobject);CHECKGLERROR
2537 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2538 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2539 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2541 int i, j, pretextlines = 0;
2542 for (i = 0;i < numstrings - 1;i++)
2543 for (j = 0;strings[i][j];j++)
2544 if (strings[i][j] == '\n')
2546 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2548 if (!shadercompiled)
2550 qglDeleteShader(shaderobject);CHECKGLERROR
2553 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2554 qglDeleteShader(shaderobject);CHECKGLERROR
2558 unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list)
2560 GLint programlinked;
2561 GLuint programobject = 0;
2562 char linklog[MAX_INPUTLINE];
2565 programobject = qglCreateProgram();CHECKGLERROR
2569 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2570 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2571 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2572 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2573 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2574 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2575 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2576 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2577 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2578 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2580 if(vid.support.gl20shaders130)
2581 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2584 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2587 #ifdef GL_GEOMETRY_SHADER
2588 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2592 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2595 qglLinkProgram(programobject);CHECKGLERROR
2596 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2597 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2600 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2601 Con_DPrintf("program link log:\n%s\n", linklog);
2602 // software vertex shader is ok but software fragment shader is WAY
2603 // too slow, fail program if so.
2604 // NOTE: this string might be ATI specific, but that's ok because the
2605 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2606 // software fragment shader due to low instruction and dependent
2608 if (strstr(linklog, "fragment shader will run in software"))
2609 programlinked = false;
2613 return programobject;
2615 qglDeleteProgram(programobject);CHECKGLERROR
2619 void GL_Backend_FreeProgram(unsigned int prog)
2622 qglDeleteProgram(prog);
2626 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2631 for (i = 0;i < count;i++)
2632 *out++ = *in++ + offset;
2635 memcpy(out, in, sizeof(*out) * count);
2638 // renders triangles using vertices from the active arrays
2639 int paranoidblah = 0;
2640 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)
2642 unsigned int numelements = numtriangles * 3;
2644 size_t bufferoffset3i;
2646 size_t bufferoffset3s;
2647 if (numvertices < 3 || numtriangles < 1)
2649 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2650 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);
2653 if (!gl_mesh_prefer_short_elements.integer)
2657 if (element3i_indexbuffer)
2658 element3i_indexbuffer = NULL;
2660 // adjust the pointers for firsttriangle
2662 element3i += firsttriangle * 3;
2663 if (element3i_indexbuffer)
2664 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2666 element3s += firsttriangle * 3;
2667 if (element3s_indexbuffer)
2668 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2669 switch(vid.renderpath)
2671 case RENDERPATH_GL11:
2672 case RENDERPATH_GL13:
2673 case RENDERPATH_GL20:
2674 case RENDERPATH_GLES1:
2675 case RENDERPATH_GLES2:
2676 // check if the user specified to ignore static index buffers
2677 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2679 element3i_indexbuffer = NULL;
2680 element3s_indexbuffer = NULL;
2683 case RENDERPATH_D3D9:
2684 case RENDERPATH_D3D10:
2685 case RENDERPATH_D3D11:
2687 case RENDERPATH_SOFT:
2690 // upload a dynamic index buffer if needed
2693 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2695 if (gl_state.draw_dynamicindexbuffer)
2696 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2698 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2699 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2700 element3s_bufferoffset = 0;
2705 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2707 if (gl_state.draw_dynamicindexbuffer)
2708 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2710 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2711 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2712 element3i_bufferoffset = 0;
2715 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2716 bufferoffset3i = element3i_bufferoffset;
2717 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2718 bufferoffset3s = element3s_bufferoffset;
2719 r_refdef.stats.draws++;
2720 r_refdef.stats.draws_vertices += numvertices;
2721 r_refdef.stats.draws_elements += numelements;
2722 if (gl_paranoid.integer)
2725 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2727 unsigned int j, size;
2729 // note: there's no validation done here on buffer objects because it
2730 // is somewhat difficult to get at the data, and gl_paranoid can be
2731 // used without buffer objects if the need arises
2732 // (the data could be gotten using glMapBuffer but it would be very
2733 // slow due to uncachable video memory reads)
2734 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2735 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2737 if (gl_state.pointer_vertex_pointer)
2738 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2740 if (gl_state.pointer_color_enabled)
2742 if (!qglIsEnabled(GL_COLOR_ARRAY))
2743 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2745 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2746 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2749 for (i = 0;i < vid.texarrayunits;i++)
2751 if (gl_state.units[i].arrayenabled)
2753 GL_ClientActiveTexture(i);
2754 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2755 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2757 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2758 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++)
2765 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2767 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2769 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2776 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2778 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2780 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2786 if (r_render.integer || r_refdef.draw2dstage)
2788 switch(vid.renderpath)
2790 case RENDERPATH_GL11:
2791 case RENDERPATH_GL13:
2792 case RENDERPATH_GL20:
2794 if (gl_mesh_testmanualfeeding.integer)
2797 unsigned int i, j, element;
2799 qglBegin(GL_TRIANGLES);
2800 if(vid.renderpath == RENDERPATH_GL20)
2802 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2805 element = element3i[i];
2807 element = element3s[i];
2809 element = firstvertex + i;
2810 for (j = 0;j < vid.texarrayunits;j++)
2812 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2814 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2816 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2817 if (gl_state.units[j].pointer_texcoord_components == 4)
2818 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2819 else if (gl_state.units[j].pointer_texcoord_components == 3)
2820 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2821 else if (gl_state.units[j].pointer_texcoord_components == 2)
2822 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2824 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2826 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2828 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2829 if (gl_state.units[j].pointer_texcoord_components == 4)
2830 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2831 else if (gl_state.units[j].pointer_texcoord_components == 3)
2832 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2833 else if (gl_state.units[j].pointer_texcoord_components == 2)
2834 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2835 else if (gl_state.units[j].pointer_texcoord_components == 1)
2836 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2838 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2840 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2841 if (gl_state.units[j].pointer_texcoord_components == 4)
2842 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2843 else if (gl_state.units[j].pointer_texcoord_components == 3)
2844 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2845 else if (gl_state.units[j].pointer_texcoord_components == 2)
2846 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2847 else if (gl_state.units[j].pointer_texcoord_components == 1)
2848 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2852 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2854 if (gl_state.pointer_color_gltype == GL_FLOAT)
2856 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2857 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2859 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2861 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2862 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2865 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2867 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2868 if (gl_state.pointer_vertex_components == 4)
2869 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2870 else if (gl_state.pointer_vertex_components == 3)
2871 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2873 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2879 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2882 element = element3i[i];
2884 element = element3s[i];
2886 element = firstvertex + i;
2887 for (j = 0;j < vid.texarrayunits;j++)
2889 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2891 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2893 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2894 if (vid.texarrayunits > 1)
2896 if (gl_state.units[j].pointer_texcoord_components == 4)
2897 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2898 else if (gl_state.units[j].pointer_texcoord_components == 3)
2899 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2900 else if (gl_state.units[j].pointer_texcoord_components == 2)
2901 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2903 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2907 if (gl_state.units[j].pointer_texcoord_components == 4)
2908 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2909 else if (gl_state.units[j].pointer_texcoord_components == 3)
2910 qglTexCoord3f(p[0], p[1], p[2]);
2911 else if (gl_state.units[j].pointer_texcoord_components == 2)
2912 qglTexCoord2f(p[0], p[1]);
2914 qglTexCoord1f(p[0]);
2917 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2919 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2920 if (vid.texarrayunits > 1)
2922 if (gl_state.units[j].pointer_texcoord_components == 4)
2923 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2924 else if (gl_state.units[j].pointer_texcoord_components == 3)
2925 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2926 else if (gl_state.units[j].pointer_texcoord_components == 2)
2927 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2928 else if (gl_state.units[j].pointer_texcoord_components == 1)
2929 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2933 if (gl_state.units[j].pointer_texcoord_components == 4)
2934 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2935 else if (gl_state.units[j].pointer_texcoord_components == 3)
2936 qglTexCoord3f(s[0], s[1], s[2]);
2937 else if (gl_state.units[j].pointer_texcoord_components == 2)
2938 qglTexCoord2f(s[0], s[1]);
2939 else if (gl_state.units[j].pointer_texcoord_components == 1)
2940 qglTexCoord1f(s[0]);
2943 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2945 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2946 if (vid.texarrayunits > 1)
2948 if (gl_state.units[j].pointer_texcoord_components == 4)
2949 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2950 else if (gl_state.units[j].pointer_texcoord_components == 3)
2951 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2952 else if (gl_state.units[j].pointer_texcoord_components == 2)
2953 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2954 else if (gl_state.units[j].pointer_texcoord_components == 1)
2955 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2959 if (gl_state.units[j].pointer_texcoord_components == 4)
2960 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2961 else if (gl_state.units[j].pointer_texcoord_components == 3)
2962 qglTexCoord3f(sb[0], sb[1], sb[2]);
2963 else if (gl_state.units[j].pointer_texcoord_components == 2)
2964 qglTexCoord2f(sb[0], sb[1]);
2965 else if (gl_state.units[j].pointer_texcoord_components == 1)
2966 qglTexCoord1f(sb[0]);
2971 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2973 if (gl_state.pointer_color_gltype == GL_FLOAT)
2975 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2976 qglColor4f(p[0], p[1], p[2], p[3]);
2978 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2980 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2981 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2984 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2986 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2987 if (gl_state.pointer_vertex_components == 4)
2988 qglVertex4f(p[0], p[1], p[2], p[3]);
2989 else if (gl_state.pointer_vertex_components == 3)
2990 qglVertex3f(p[0], p[1], p[2]);
2992 qglVertex2f(p[0], p[1]);
3000 else if (bufferobject3s)
3002 GL_BindEBO(bufferobject3s);
3004 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3006 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
3012 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3016 else if (bufferobject3i)
3018 GL_BindEBO(bufferobject3i);
3020 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3022 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3028 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3036 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3038 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3044 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3052 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3054 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3060 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3066 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3070 case RENDERPATH_D3D9:
3072 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3074 if (element3s_indexbuffer)
3076 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3077 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3079 else if (element3i_indexbuffer)
3081 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3082 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3085 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3090 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3092 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3094 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3098 case RENDERPATH_D3D10:
3099 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3101 case RENDERPATH_D3D11:
3102 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3104 case RENDERPATH_SOFT:
3105 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3107 case RENDERPATH_GLES1:
3108 case RENDERPATH_GLES2:
3109 // GLES does not have glDrawRangeElements, and generally
3110 // underperforms with index buffers, so this code path is
3111 // relatively straightforward...
3113 if (gl_paranoid.integer)
3115 int r, prog, enabled, i;
3116 GLsizei attriblength;
3119 GLchar attribname[1024];
3120 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3121 if (r != GL_FRAMEBUFFER_COMPLETE)
3122 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3123 #ifndef GL_CURRENT_PROGRAM
3124 #define GL_CURRENT_PROGRAM 0x8B8D
3126 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3127 if (r < 0 || r > 10000)
3128 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3130 for (i = 0;i < 8;i++)
3132 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3135 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3136 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);
3142 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3147 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3152 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3160 // restores backend state, used when done with 3D rendering
3161 void R_Mesh_Finish(void)
3163 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
3166 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3168 r_meshbuffer_t *buffer;
3169 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3171 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3172 memset(buffer, 0, sizeof(*buffer));
3173 buffer->bufferobject = 0;
3174 buffer->devicebuffer = NULL;
3176 buffer->isindexbuffer = isindexbuffer;
3177 buffer->isdynamic = isdynamic;
3178 buffer->isindex16 = isindex16;
3179 strlcpy(buffer->name, name, sizeof(buffer->name));
3180 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3184 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3188 if (buffer->isindexbuffer)
3190 r_refdef.stats.indexbufferuploadcount++;
3191 r_refdef.stats.indexbufferuploadsize += size;
3195 r_refdef.stats.vertexbufferuploadcount++;
3196 r_refdef.stats.vertexbufferuploadsize += size;
3198 switch(vid.renderpath)
3200 case RENDERPATH_GL11:
3201 case RENDERPATH_GL13:
3202 case RENDERPATH_GL20:
3203 case RENDERPATH_GLES1:
3204 case RENDERPATH_GLES2:
3205 if (!buffer->bufferobject)
3206 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3207 if (buffer->isindexbuffer)
3208 GL_BindEBO(buffer->bufferobject);
3210 GL_BindVBO(buffer->bufferobject);
3211 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3213 case RENDERPATH_D3D9:
3217 void *datapointer = NULL;
3218 if (buffer->isindexbuffer)
3220 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3221 if (size > buffer->size || !buffer->devicebuffer)
3223 if (buffer->devicebuffer)
3224 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3225 buffer->devicebuffer = NULL;
3226 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)))
3227 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);
3228 buffer->devicebuffer = (void *)d3d9indexbuffer;
3229 buffer->size = size;
3231 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3234 memcpy(datapointer, data, size);
3236 memset(datapointer, 0, size);
3237 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3242 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3243 if (size > buffer->size || !buffer->devicebuffer)
3245 if (buffer->devicebuffer)
3246 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3247 buffer->devicebuffer = NULL;
3248 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3249 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);
3250 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3251 buffer->size = size;
3253 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3256 memcpy(datapointer, data, size);
3258 memset(datapointer, 0, size);
3259 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3265 case RENDERPATH_D3D10:
3266 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3268 case RENDERPATH_D3D11:
3269 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3271 case RENDERPATH_SOFT:
3276 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3280 switch(vid.renderpath)
3282 case RENDERPATH_GL11:
3283 case RENDERPATH_GL13:
3284 case RENDERPATH_GL20:
3285 case RENDERPATH_GLES1:
3286 case RENDERPATH_GLES2:
3287 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3289 case RENDERPATH_D3D9:
3291 if (gl_state.d3dvertexbuffer == (void *)buffer)
3292 gl_state.d3dvertexbuffer = NULL;
3293 if (buffer->devicebuffer)
3295 if (buffer->isindexbuffer)
3296 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3298 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3299 buffer->devicebuffer = NULL;
3303 case RENDERPATH_D3D10:
3304 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3306 case RENDERPATH_D3D11:
3307 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3309 case RENDERPATH_SOFT:
3312 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3315 void GL_Mesh_ListVBOs(qboolean printeach)
3318 size_t ebocount = 0, ebomemory = 0;
3319 size_t vbocount = 0, vbomemory = 0;
3320 r_meshbuffer_t *buffer;
3321 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3322 for (i = 0;i < endindex;i++)
3324 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3327 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)");}
3328 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)");}
3330 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);
3335 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3337 switch(vid.renderpath)
3339 case RENDERPATH_GL11:
3340 case RENDERPATH_GL13:
3341 case RENDERPATH_GLES1:
3342 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)
3344 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3345 gl_state.pointer_vertex_components = components;
3346 gl_state.pointer_vertex_gltype = gltype;
3347 gl_state.pointer_vertex_stride = stride;
3348 gl_state.pointer_vertex_pointer = pointer;
3349 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3350 gl_state.pointer_vertex_offset = bufferoffset;
3352 GL_BindVBO(bufferobject);
3353 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3356 case RENDERPATH_GL20:
3357 case RENDERPATH_GLES2:
3358 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)
3360 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3361 gl_state.pointer_vertex_components = components;
3362 gl_state.pointer_vertex_gltype = gltype;
3363 gl_state.pointer_vertex_stride = stride;
3364 gl_state.pointer_vertex_pointer = pointer;
3365 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3366 gl_state.pointer_vertex_offset = bufferoffset;
3368 GL_BindVBO(bufferobject);
3369 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3372 case RENDERPATH_D3D9:
3373 case RENDERPATH_D3D10:
3374 case RENDERPATH_D3D11:
3375 case RENDERPATH_SOFT:
3380 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3382 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3383 // the pointer only.
3384 switch(vid.renderpath)
3386 case RENDERPATH_GL11:
3387 case RENDERPATH_GL13:
3388 case RENDERPATH_GLES1:
3393 // caller wants color array enabled
3394 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3395 if (!gl_state.pointer_color_enabled)
3397 gl_state.pointer_color_enabled = true;
3399 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3401 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)
3403 gl_state.pointer_color_components = components;
3404 gl_state.pointer_color_gltype = gltype;
3405 gl_state.pointer_color_stride = stride;
3406 gl_state.pointer_color_pointer = pointer;
3407 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3408 gl_state.pointer_color_offset = bufferoffset;
3410 GL_BindVBO(bufferobject);
3411 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3416 // caller wants color array disabled
3417 if (gl_state.pointer_color_enabled)
3419 gl_state.pointer_color_enabled = false;
3421 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3422 // when color array is on the glColor gets trashed, set it again
3423 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3428 case RENDERPATH_GL20:
3429 case RENDERPATH_GLES2:
3433 // caller wants color array enabled
3434 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3435 if (!gl_state.pointer_color_enabled)
3437 gl_state.pointer_color_enabled = true;
3439 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3441 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)
3443 gl_state.pointer_color_components = components;
3444 gl_state.pointer_color_gltype = gltype;
3445 gl_state.pointer_color_stride = stride;
3446 gl_state.pointer_color_pointer = pointer;
3447 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3448 gl_state.pointer_color_offset = bufferoffset;
3450 GL_BindVBO(bufferobject);
3451 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3456 // caller wants color array disabled
3457 if (gl_state.pointer_color_enabled)
3459 gl_state.pointer_color_enabled = false;
3461 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3462 // when color array is on the glColor gets trashed, set it again
3463 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3467 case RENDERPATH_D3D9:
3468 case RENDERPATH_D3D10:
3469 case RENDERPATH_D3D11:
3470 case RENDERPATH_SOFT:
3475 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)
3477 gltextureunit_t *unit = gl_state.units + unitnum;
3478 // update array settings
3479 // note: there is no need to check bufferobject here because all cases
3480 // that involve a valid bufferobject also supply a texcoord array
3481 switch(vid.renderpath)
3483 case RENDERPATH_GL11:
3484 case RENDERPATH_GL13:
3485 case RENDERPATH_GLES1:
3490 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3491 // texture array unit is enabled, enable the array
3492 if (!unit->arrayenabled)
3494 unit->arrayenabled = true;
3495 GL_ClientActiveTexture(unitnum);
3496 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3499 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)
3501 unit->pointer_texcoord_components = components;
3502 unit->pointer_texcoord_gltype = gltype;
3503 unit->pointer_texcoord_stride = stride;
3504 unit->pointer_texcoord_pointer = pointer;
3505 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3506 unit->pointer_texcoord_offset = bufferoffset;
3507 GL_ClientActiveTexture(unitnum);
3508 GL_BindVBO(bufferobject);
3509 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3514 // texture array unit is disabled, disable the array
3515 if (unit->arrayenabled)
3517 unit->arrayenabled = false;
3518 GL_ClientActiveTexture(unitnum);
3519 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3524 case RENDERPATH_GL20:
3525 case RENDERPATH_GLES2:
3529 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3530 // texture array unit is enabled, enable the array
3531 if (!unit->arrayenabled)
3533 unit->arrayenabled = true;
3534 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3537 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)
3539 unit->pointer_texcoord_components = components;
3540 unit->pointer_texcoord_gltype = gltype;
3541 unit->pointer_texcoord_stride = stride;
3542 unit->pointer_texcoord_pointer = pointer;
3543 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3544 unit->pointer_texcoord_offset = bufferoffset;
3545 GL_BindVBO(bufferobject);
3546 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3551 // texture array unit is disabled, disable the array
3552 if (unit->arrayenabled)
3554 unit->arrayenabled = false;
3555 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3559 case RENDERPATH_D3D9:
3560 case RENDERPATH_D3D10:
3561 case RENDERPATH_D3D11:
3562 case RENDERPATH_SOFT:
3567 int R_Mesh_TexBound(unsigned int unitnum, int id)
3569 gltextureunit_t *unit = gl_state.units + unitnum;
3570 if (unitnum >= vid.teximageunits)
3572 if (id == GL_TEXTURE_2D)
3574 if (id == GL_TEXTURE_3D)
3576 if (id == GL_TEXTURE_CUBE_MAP)
3577 return unit->tcubemap;
3581 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3583 switch(vid.renderpath)
3585 case RENDERPATH_GL11:
3586 case RENDERPATH_GL13:
3587 case RENDERPATH_GL20:
3588 case RENDERPATH_GLES1:
3589 case RENDERPATH_GLES2:
3590 R_Mesh_TexBind(0, tex);
3591 GL_ActiveTexture(0);CHECKGLERROR
3592 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3594 case RENDERPATH_D3D9:
3597 IDirect3DSurface9 *currentsurface = NULL;
3598 IDirect3DSurface9 *texturesurface = NULL;
3601 sourcerect.left = sx;
3602 sourcerect.top = sy;
3603 sourcerect.right = sx + width;
3604 sourcerect.bottom = sy + height;
3607 destrect.right = tx + width;
3608 destrect.bottom = ty + height;
3609 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3611 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3613 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3614 IDirect3DSurface9_Release(currentsurface);
3616 IDirect3DSurface9_Release(texturesurface);
3621 case RENDERPATH_D3D10:
3622 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3624 case RENDERPATH_D3D11:
3625 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3627 case RENDERPATH_SOFT:
3628 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3634 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};
3637 void R_Mesh_ClearBindingsForTexture(int texnum)
3639 gltextureunit_t *unit;
3640 unsigned int unitnum;
3641 // 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)
3642 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3644 unit = gl_state.units + unitnum;
3645 if (unit->t2d == texnum)
3647 if (unit->t3d == texnum)
3649 if (unit->tcubemap == texnum)
3650 unit->tcubemap = -1;
3654 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3656 gltextureunit_t *unit = gl_state.units + unitnum;
3657 int tex2d, tex3d, texcubemap, texnum;
3658 if (unitnum >= vid.teximageunits)
3660 // if (unit->texture == tex)
3662 switch(vid.renderpath)
3664 case RENDERPATH_GL20:
3665 case RENDERPATH_GLES2:
3668 tex = r_texture_white;
3669 // not initialized enough yet...
3673 unit->texture = tex;
3674 texnum = R_GetTexture(tex);
3675 switch(tex->gltexturetypeenum)
3677 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3678 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3679 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3682 case RENDERPATH_GL11:
3683 case RENDERPATH_GL13:
3684 case RENDERPATH_GLES1:
3685 unit->texture = tex;
3691 texnum = R_GetTexture(tex);
3692 switch(tex->gltexturetypeenum)
3700 case GL_TEXTURE_CUBE_MAP:
3701 texcubemap = texnum;
3705 // update 2d texture binding
3706 if (unit->t2d != tex2d)
3708 GL_ActiveTexture(unitnum);
3713 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3720 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3724 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3726 // update 3d texture binding
3727 if (unit->t3d != tex3d)
3729 GL_ActiveTexture(unitnum);
3734 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3741 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3745 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3747 // update cubemap texture binding
3748 if (unit->tcubemap != texcubemap)
3750 GL_ActiveTexture(unitnum);
3753 if (unit->tcubemap == 0)
3755 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3762 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3765 unit->tcubemap = texcubemap;
3766 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3769 case RENDERPATH_D3D9:
3772 extern cvar_t gl_texture_anisotropy;
3775 tex = r_texture_white;
3776 // not initialized enough yet...
3780 // upload texture if needed
3782 if (unit->texture == tex)
3784 unit->texture = tex;
3785 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3786 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3787 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3788 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3789 if (tex->d3daddressw)
3790 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3791 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3792 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3793 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3794 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3795 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3796 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3800 case RENDERPATH_D3D10:
3801 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3803 case RENDERPATH_D3D11:
3804 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3806 case RENDERPATH_SOFT:
3809 tex = r_texture_white;
3810 // not initialized enough yet...
3814 texnum = R_GetTexture(tex);
3815 if (unit->texture == tex)
3817 unit->texture = tex;
3818 DPSOFTRAST_SetTexture(unitnum, texnum);
3823 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3825 gltextureunit_t *unit = gl_state.units + unitnum;
3826 switch(vid.renderpath)
3828 case RENDERPATH_GL11:
3829 case RENDERPATH_GL13:
3830 case RENDERPATH_GL20:
3831 case RENDERPATH_GLES1:
3832 case RENDERPATH_GLES2:
3834 if (matrix && matrix->m[3][3])
3836 // texmatrix specified, check if it is different
3837 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3840 unit->texmatrixenabled = true;
3841 unit->matrix = *matrix;
3843 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3844 GL_ActiveTexture(unitnum);
3845 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3846 qglLoadMatrixf(glmatrix);CHECKGLERROR
3847 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3852 // no texmatrix specified, revert to identity
3853 if (unit->texmatrixenabled)
3855 unit->texmatrixenabled = false;
3856 unit->matrix = identitymatrix;
3858 GL_ActiveTexture(unitnum);
3859 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3860 qglLoadIdentity();CHECKGLERROR
3861 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3866 case RENDERPATH_D3D9:
3867 case RENDERPATH_D3D10:
3868 case RENDERPATH_D3D11:
3870 case RENDERPATH_SOFT:
3875 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3877 gltextureunit_t *unit = gl_state.units + unitnum;
3879 switch(vid.renderpath)
3881 case RENDERPATH_GL20:
3882 case RENDERPATH_GLES2:
3885 case RENDERPATH_GL13:
3886 case RENDERPATH_GLES1:
3887 #ifdef GL_TEXTURE_ENV
3888 // GL_ARB_texture_env_combine
3890 combinergb = GL_MODULATE;
3892 combinealpha = GL_MODULATE;
3897 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3899 if (combinergb == GL_DECAL)
3900 combinergb = GL_INTERPOLATE;
3901 if (unit->combine != GL_COMBINE)
3903 unit->combine = GL_COMBINE;
3904 GL_ActiveTexture(unitnum);
3905 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3906 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3908 if (unit->combinergb != combinergb)
3910 unit->combinergb = combinergb;
3911 GL_ActiveTexture(unitnum);
3912 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3914 if (unit->combinealpha != combinealpha)
3916 unit->combinealpha = combinealpha;
3917 GL_ActiveTexture(unitnum);
3918 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3920 if (unit->rgbscale != rgbscale)
3922 unit->rgbscale = rgbscale;
3923 GL_ActiveTexture(unitnum);
3924 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3926 if (unit->alphascale != alphascale)
3928 unit->alphascale = alphascale;
3929 GL_ActiveTexture(unitnum);
3930 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3935 if (unit->combine != combinergb)
3937 unit->combine = combinergb;
3938 GL_ActiveTexture(unitnum);
3939 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3944 case RENDERPATH_GL11:
3946 #ifdef GL_TEXTURE_ENV
3948 combinergb = GL_MODULATE;
3949 if (unit->combine != combinergb)
3951 unit->combine = combinergb;
3952 GL_ActiveTexture(unitnum);
3953 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3957 case RENDERPATH_D3D9:
3958 case RENDERPATH_D3D10:
3959 case RENDERPATH_D3D11:
3961 case RENDERPATH_SOFT:
3966 void R_Mesh_ResetTextureState(void)
3968 unsigned int unitnum;
3972 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3973 R_Mesh_TexBind(unitnum, NULL);
3974 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3975 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3976 switch(vid.renderpath)
3978 case RENDERPATH_GL20:
3979 case RENDERPATH_GLES2:
3980 case RENDERPATH_D3D9:
3981 case RENDERPATH_D3D10:
3982 case RENDERPATH_D3D11:
3983 case RENDERPATH_SOFT:
3985 case RENDERPATH_GL11:
3986 case RENDERPATH_GL13:
3987 case RENDERPATH_GLES1:
3988 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3990 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3991 R_Mesh_TexMatrix(unitnum, NULL);
4000 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
4001 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
4002 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
4004 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
4006 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4010 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
4012 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4013 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4014 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4018 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4020 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4021 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4022 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4023 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4024 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4025 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4026 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4030 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4031 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4032 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4035 static void R_Mesh_InitVertexDeclarations(void)
4038 r_vertex3f_d3d9decl = NULL;
4039 r_vertexgeneric_d3d9decl = NULL;
4040 r_vertexmesh_d3d9decl = NULL;
4041 switch(vid.renderpath)
4043 case RENDERPATH_GL20:
4044 case RENDERPATH_GL13:
4045 case RENDERPATH_GL11:
4046 case RENDERPATH_GLES1:
4047 case RENDERPATH_GLES2:
4049 case RENDERPATH_D3D9:
4050 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4051 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4052 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4054 case RENDERPATH_D3D10:
4055 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4057 case RENDERPATH_D3D11:
4058 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4060 case RENDERPATH_SOFT:
4066 static void R_Mesh_DestroyVertexDeclarations(void)
4069 if (r_vertex3f_d3d9decl)
4070 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4071 r_vertex3f_d3d9decl = NULL;
4072 if (r_vertexgeneric_d3d9decl)
4073 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4074 r_vertexgeneric_d3d9decl = NULL;
4075 if (r_vertexmesh_d3d9decl)
4076 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4077 r_vertexmesh_d3d9decl = NULL;
4081 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4083 // upload temporary vertexbuffer for this rendering
4084 if (!gl_state.usevbo_staticvertex)
4085 vertexbuffer = NULL;
4086 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4088 if (gl_state.preparevertices_dynamicvertexbuffer)
4089 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4091 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4092 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4094 switch(vid.renderpath)
4096 case RENDERPATH_GL20:
4097 case RENDERPATH_GLES2:
4100 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4101 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4102 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4103 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4104 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4105 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4106 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4110 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4111 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4112 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4113 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4114 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4115 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4116 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4119 case RENDERPATH_GL13:
4120 case RENDERPATH_GLES1:
4123 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4124 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4125 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4126 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4130 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4131 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4132 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4133 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4136 case RENDERPATH_GL11:
4139 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4140 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4141 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4145 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4146 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4147 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4150 case RENDERPATH_D3D9:
4152 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4154 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4156 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4157 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4158 gl_state.d3dvertexdata = (void *)vertex3f;
4159 gl_state.d3dvertexsize = sizeof(float[3]);
4162 case RENDERPATH_D3D10:
4163 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4165 case RENDERPATH_D3D11:
4166 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4168 case RENDERPATH_SOFT:
4169 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4170 DPSOFTRAST_SetColorPointer(NULL, 0);
4171 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4172 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4173 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4174 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4175 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4182 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4185 size = sizeof(r_vertexgeneric_t) * numvertices;
4186 if (gl_state.preparevertices_tempdatamaxsize < size)
4188 gl_state.preparevertices_tempdatamaxsize = size;
4189 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4191 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4192 gl_state.preparevertices_numvertices = numvertices;
4193 return gl_state.preparevertices_vertexgeneric;
4196 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4198 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4199 gl_state.preparevertices_vertexgeneric = NULL;
4200 gl_state.preparevertices_numvertices = 0;
4204 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4207 r_vertexgeneric_t *vertex;
4208 switch(vid.renderpath)
4210 case RENDERPATH_GL20:
4211 case RENDERPATH_GLES2:
4212 if (!vid.useinterleavedarrays)
4214 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4215 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4216 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4217 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4218 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4219 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4220 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4224 case RENDERPATH_GL11:
4225 case RENDERPATH_GL13:
4226 case RENDERPATH_GLES1:
4227 if (!vid.useinterleavedarrays)
4229 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4230 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4231 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4232 if (vid.texunits >= 2)
4233 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4234 if (vid.texunits >= 3)
4235 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4239 case RENDERPATH_D3D9:
4240 case RENDERPATH_D3D10:
4241 case RENDERPATH_D3D11:
4243 case RENDERPATH_SOFT:
4244 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4245 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4246 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4247 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4248 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4249 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4250 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4254 // no quick path for this case, convert to vertex structs
4255 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4256 for (i = 0;i < numvertices;i++)
4257 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4260 for (i = 0;i < numvertices;i++)
4261 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4265 for (i = 0;i < numvertices;i++)
4266 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4269 for (i = 0;i < numvertices;i++)
4270 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4271 R_Mesh_PrepareVertices_Generic_Unlock();
4272 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4275 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4277 // upload temporary vertexbuffer for this rendering
4278 if (!gl_state.usevbo_staticvertex)
4279 vertexbuffer = NULL;
4280 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4282 if (gl_state.preparevertices_dynamicvertexbuffer)
4283 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4285 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4286 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4288 switch(vid.renderpath)
4290 case RENDERPATH_GL20:
4291 case RENDERPATH_GLES2:
4294 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4295 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4296 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4297 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4298 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4299 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4300 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4304 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4305 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4306 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4307 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4308 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4309 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4310 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4313 case RENDERPATH_GL13:
4314 case RENDERPATH_GLES1:
4317 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4318 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4319 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4320 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4324 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4325 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4326 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4327 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4330 case RENDERPATH_GL11:
4333 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4334 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4335 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4339 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4340 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4341 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4344 case RENDERPATH_D3D9:
4346 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4348 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4350 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4351 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4352 gl_state.d3dvertexdata = (void *)vertex;
4353 gl_state.d3dvertexsize = sizeof(*vertex);
4356 case RENDERPATH_D3D10:
4357 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4359 case RENDERPATH_D3D11:
4360 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4362 case RENDERPATH_SOFT:
4363 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4364 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4365 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4366 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4367 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4368 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4369 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4376 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4379 size = sizeof(r_vertexmesh_t) * numvertices;
4380 if (gl_state.preparevertices_tempdatamaxsize < size)
4382 gl_state.preparevertices_tempdatamaxsize = size;
4383 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4385 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4386 gl_state.preparevertices_numvertices = numvertices;
4387 return gl_state.preparevertices_vertexmesh;
4390 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4392 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4393 gl_state.preparevertices_vertexmesh = NULL;
4394 gl_state.preparevertices_numvertices = 0;
4398 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)
4401 r_vertexmesh_t *vertex;
4402 switch(vid.renderpath)
4404 case RENDERPATH_GL20:
4405 case RENDERPATH_GLES2:
4406 if (!vid.useinterleavedarrays)
4408 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4409 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4410 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4411 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4412 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4413 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4414 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4418 case RENDERPATH_GL11:
4419 case RENDERPATH_GL13:
4420 case RENDERPATH_GLES1:
4421 if (!vid.useinterleavedarrays)
4423 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4424 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4425 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4426 if (vid.texunits >= 2)
4427 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4428 if (vid.texunits >= 3)
4429 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4433 case RENDERPATH_D3D9:
4434 case RENDERPATH_D3D10:
4435 case RENDERPATH_D3D11:
4437 case RENDERPATH_SOFT:
4438 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4439 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4440 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4441 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4442 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4443 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4444 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4448 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4449 for (i = 0;i < numvertices;i++)
4450 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4452 for (i = 0;i < numvertices;i++)
4453 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4455 for (i = 0;i < numvertices;i++)
4456 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4458 for (i = 0;i < numvertices;i++)
4459 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4462 for (i = 0;i < numvertices;i++)
4463 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4467 for (i = 0;i < numvertices;i++)
4468 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4470 if (texcoordtexture2f)
4471 for (i = 0;i < numvertices;i++)
4472 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4473 if (texcoordlightmap2f)
4474 for (i = 0;i < numvertices;i++)
4475 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4476 R_Mesh_PrepareVertices_Mesh_Unlock();
4477 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4480 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4482 // upload temporary vertexbuffer for this rendering
4483 if (!gl_state.usevbo_staticvertex)
4484 vertexbuffer = NULL;
4485 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4487 if (gl_state.preparevertices_dynamicvertexbuffer)
4488 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4490 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4491 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4493 switch(vid.renderpath)
4495 case RENDERPATH_GL20:
4496 case RENDERPATH_GLES2:
4499 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4500 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4501 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4502 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4503 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4504 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4505 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4509 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4510 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4511 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4512 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4513 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4514 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4515 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4518 case RENDERPATH_GL13:
4519 case RENDERPATH_GLES1:
4522 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4523 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4524 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4525 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4529 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4530 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4531 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4532 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4535 case RENDERPATH_GL11:
4538 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4539 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4540 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4544 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4545 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4546 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4549 case RENDERPATH_D3D9:
4551 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4553 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4555 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4556 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4557 gl_state.d3dvertexdata = (void *)vertex;
4558 gl_state.d3dvertexsize = sizeof(*vertex);
4561 case RENDERPATH_D3D10:
4562 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4564 case RENDERPATH_D3D11:
4565 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4567 case RENDERPATH_SOFT:
4568 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4569 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4570 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4571 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4572 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4573 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4574 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4579 void GL_BlendEquationSubtract(qboolean negated)
4583 switch(vid.renderpath)
4585 case RENDERPATH_GL11:
4586 case RENDERPATH_GL13:
4587 case RENDERPATH_GL20:
4588 case RENDERPATH_GLES1:
4589 case RENDERPATH_GLES2:
4590 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4592 case RENDERPATH_D3D9:
4594 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4597 case RENDERPATH_D3D10:
4598 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4600 case RENDERPATH_D3D11:
4601 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4603 case RENDERPATH_SOFT:
4604 DPSOFTRAST_BlendSubtract(true);
4610 switch(vid.renderpath)
4612 case RENDERPATH_GL11:
4613 case RENDERPATH_GL13:
4614 case RENDERPATH_GL20:
4615 case RENDERPATH_GLES1:
4616 case RENDERPATH_GLES2:
4617 qglBlendEquationEXT(GL_FUNC_ADD);
4619 case RENDERPATH_D3D9:
4621 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4624 case RENDERPATH_D3D10:
4625 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4627 case RENDERPATH_D3D11:
4628 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4630 case RENDERPATH_SOFT:
4631 DPSOFTRAST_BlendSubtract(false);