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(GL_FRONT, frontcompare, comparereference, comparereference);CHECKGLERROR
1932 qglStencilFuncSeparate(GL_BACK, backcompare, comparereference, comparereference);CHECKGLERROR
1934 else if (vid.support.ext_stencil_two_side)
1936 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1937 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1938 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1939 qglStencilMask(writemask);CHECKGLERROR
1940 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1941 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1942 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1943 qglStencilMask(writemask);CHECKGLERROR
1944 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1945 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1949 case RENDERPATH_D3D9:
1951 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1952 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1953 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1954 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1955 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1956 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1957 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1958 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1959 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1960 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1961 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1962 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1963 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1966 case RENDERPATH_D3D10:
1967 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1969 case RENDERPATH_D3D11:
1970 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1972 case RENDERPATH_SOFT:
1973 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1978 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1980 switch (vid.renderpath)
1982 case RENDERPATH_GL11:
1983 case RENDERPATH_GL13:
1984 case RENDERPATH_GL20:
1985 case RENDERPATH_GLES1:
1986 case RENDERPATH_GLES2:
1990 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1994 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1996 if (vid.support.ext_stencil_two_side)
1998 #ifdef GL_STENCIL_TEST_TWO_SIDE_EXT
1999 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
2002 qglStencilMask(writemask);CHECKGLERROR
2003 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
2004 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
2007 case RENDERPATH_D3D9:
2009 if (vid.support.ati_separate_stencil)
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
2011 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
2012 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
2013 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
2014 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
2015 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
2016 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
2017 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
2018 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
2021 case RENDERPATH_D3D10:
2022 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2024 case RENDERPATH_D3D11:
2025 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2027 case RENDERPATH_SOFT:
2028 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2033 void GL_PolygonOffset(float planeoffset, float depthoffset)
2035 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2037 gl_state.polygonoffset[0] = planeoffset;
2038 gl_state.polygonoffset[1] = depthoffset;
2039 switch(vid.renderpath)
2041 case RENDERPATH_GL11:
2042 case RENDERPATH_GL13:
2043 case RENDERPATH_GL20:
2044 case RENDERPATH_GLES1:
2045 case RENDERPATH_GLES2:
2046 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2048 case RENDERPATH_D3D9:
2050 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2051 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2054 case RENDERPATH_D3D10:
2055 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2057 case RENDERPATH_D3D11:
2058 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2060 case RENDERPATH_SOFT:
2061 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2067 void GL_SetMirrorState(qboolean state)
2069 if (v_flipped_state != state)
2071 v_flipped_state = state;
2072 if (gl_state.cullface == GL_BACK)
2073 gl_state.cullface = GL_FRONT;
2074 else if (gl_state.cullface == GL_FRONT)
2075 gl_state.cullface = GL_BACK;
2078 switch(vid.renderpath)
2080 case RENDERPATH_GL11:
2081 case RENDERPATH_GL13:
2082 case RENDERPATH_GL20:
2083 case RENDERPATH_GLES1:
2084 case RENDERPATH_GLES2:
2085 qglCullFace(gl_state.cullface);CHECKGLERROR
2087 case RENDERPATH_D3D9:
2089 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2092 case RENDERPATH_D3D10:
2093 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2095 case RENDERPATH_D3D11:
2096 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2098 case RENDERPATH_SOFT:
2099 DPSOFTRAST_CullFace(gl_state.cullface);
2105 void GL_CullFace(int state)
2109 if(state == GL_FRONT)
2111 else if(state == GL_BACK)
2115 switch(vid.renderpath)
2117 case RENDERPATH_GL11:
2118 case RENDERPATH_GL13:
2119 case RENDERPATH_GL20:
2120 case RENDERPATH_GLES1:
2121 case RENDERPATH_GLES2:
2124 if (state != GL_NONE)
2126 if (!gl_state.cullfaceenable)
2128 gl_state.cullfaceenable = true;
2129 qglEnable(GL_CULL_FACE);CHECKGLERROR
2131 if (gl_state.cullface != state)
2133 gl_state.cullface = state;
2134 qglCullFace(gl_state.cullface);CHECKGLERROR
2139 if (gl_state.cullfaceenable)
2141 gl_state.cullfaceenable = false;
2142 qglDisable(GL_CULL_FACE);CHECKGLERROR
2146 case RENDERPATH_D3D9:
2148 if (gl_state.cullface != state)
2150 gl_state.cullface = state;
2151 switch(gl_state.cullface)
2154 gl_state.cullfaceenable = false;
2155 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2158 gl_state.cullfaceenable = true;
2159 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2162 gl_state.cullfaceenable = true;
2163 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2169 case RENDERPATH_D3D10:
2170 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2172 case RENDERPATH_D3D11:
2173 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2175 case RENDERPATH_SOFT:
2176 if (gl_state.cullface != state)
2178 gl_state.cullface = state;
2179 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2180 DPSOFTRAST_CullFace(gl_state.cullface);
2186 void GL_AlphaTest(int state)
2188 if (gl_state.alphatest != state)
2190 gl_state.alphatest = state;
2191 switch(vid.renderpath)
2193 case RENDERPATH_GL11:
2194 case RENDERPATH_GL13:
2195 case RENDERPATH_GLES1:
2196 #ifdef GL_ALPHA_TEST
2197 // only fixed function uses alpha test, other paths use pixel kill capability in shaders
2199 if (gl_state.alphatest)
2201 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2205 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2209 case RENDERPATH_D3D9:
2210 case RENDERPATH_D3D10:
2211 case RENDERPATH_D3D11:
2212 case RENDERPATH_SOFT:
2213 case RENDERPATH_GL20:
2214 case RENDERPATH_GLES2:
2220 void GL_AlphaToCoverage(qboolean state)
2222 if (gl_state.alphatocoverage != state)
2224 gl_state.alphatocoverage = state;
2225 switch(vid.renderpath)
2227 case RENDERPATH_GL11:
2228 case RENDERPATH_GL13:
2229 case RENDERPATH_GLES1:
2230 case RENDERPATH_GLES2:
2231 case RENDERPATH_D3D9:
2232 case RENDERPATH_D3D10:
2233 case RENDERPATH_D3D11:
2234 case RENDERPATH_SOFT:
2236 case RENDERPATH_GL20:
2237 #ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
2238 // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
2240 if (gl_state.alphatocoverage)
2242 qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2243 // qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2247 qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
2248 // qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
2256 void GL_ColorMask(int r, int g, int b, int a)
2258 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2259 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2260 if (gl_state.colormask != state)
2262 gl_state.colormask = state;
2263 switch(vid.renderpath)
2265 case RENDERPATH_GL11:
2266 case RENDERPATH_GL13:
2267 case RENDERPATH_GL20:
2268 case RENDERPATH_GLES1:
2269 case RENDERPATH_GLES2:
2271 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2273 case RENDERPATH_D3D9:
2275 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2278 case RENDERPATH_D3D10:
2279 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2281 case RENDERPATH_D3D11:
2282 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2284 case RENDERPATH_SOFT:
2285 DPSOFTRAST_ColorMask(r, g, b, a);
2291 void GL_Color(float cr, float cg, float cb, float ca)
2293 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)
2295 gl_state.color4f[0] = cr;
2296 gl_state.color4f[1] = cg;
2297 gl_state.color4f[2] = cb;
2298 gl_state.color4f[3] = ca;
2299 switch(vid.renderpath)
2301 case RENDERPATH_GL11:
2302 case RENDERPATH_GL13:
2303 case RENDERPATH_GLES1:
2305 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2308 case RENDERPATH_D3D9:
2309 case RENDERPATH_D3D10:
2310 case RENDERPATH_D3D11:
2311 // no equivalent in D3D
2313 case RENDERPATH_SOFT:
2314 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2316 case RENDERPATH_GL20:
2317 case RENDERPATH_GLES2:
2318 qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
2324 void GL_Scissor (int x, int y, int width, int height)
2326 switch(vid.renderpath)
2328 case RENDERPATH_GL11:
2329 case RENDERPATH_GL13:
2330 case RENDERPATH_GL20:
2331 case RENDERPATH_GLES1:
2332 case RENDERPATH_GLES2:
2334 qglScissor(x, y,width,height);
2337 case RENDERPATH_D3D9:
2343 d3drect.right = x + width;
2344 d3drect.bottom = y + height;
2345 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2349 case RENDERPATH_D3D10:
2350 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2352 case RENDERPATH_D3D11:
2353 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2355 case RENDERPATH_SOFT:
2356 DPSOFTRAST_Scissor(x, y, width, height);
2361 void GL_ScissorTest(int state)
2363 if (gl_state.scissortest != state)
2365 gl_state.scissortest = state;
2366 switch(vid.renderpath)
2368 case RENDERPATH_GL11:
2369 case RENDERPATH_GL13:
2370 case RENDERPATH_GL20:
2371 case RENDERPATH_GLES1:
2372 case RENDERPATH_GLES2:
2374 if(gl_state.scissortest)
2375 qglEnable(GL_SCISSOR_TEST);
2377 qglDisable(GL_SCISSOR_TEST);
2380 case RENDERPATH_D3D9:
2382 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2385 case RENDERPATH_D3D10:
2386 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2388 case RENDERPATH_D3D11:
2389 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2391 case RENDERPATH_SOFT:
2392 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2398 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2400 static const float blackcolor[4] = {0, 0, 0, 0};
2401 // prevent warnings when trying to clear a buffer that does not exist
2403 colorvalue = blackcolor;
2406 mask &= ~GL_STENCIL_BUFFER_BIT;
2409 switch(vid.renderpath)
2411 case RENDERPATH_GL11:
2412 case RENDERPATH_GL13:
2413 case RENDERPATH_GL20:
2414 case RENDERPATH_GLES1:
2415 case RENDERPATH_GLES2:
2417 if (mask & GL_COLOR_BUFFER_BIT)
2419 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2421 if (mask & GL_DEPTH_BUFFER_BIT)
2424 qglClearDepthf(depthvalue);CHECKGLERROR
2426 qglClearDepth(depthvalue);CHECKGLERROR
2429 if (mask & GL_STENCIL_BUFFER_BIT)
2431 qglClearStencil(stencilvalue);CHECKGLERROR
2433 qglClear(mask);CHECKGLERROR
2435 case RENDERPATH_D3D9:
2437 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);
2440 case RENDERPATH_D3D10:
2441 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2443 case RENDERPATH_D3D11:
2444 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2446 case RENDERPATH_SOFT:
2447 if (mask & GL_COLOR_BUFFER_BIT)
2448 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2449 if (mask & GL_DEPTH_BUFFER_BIT)
2450 DPSOFTRAST_ClearDepth(depthvalue);
2455 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2457 switch(vid.renderpath)
2459 case RENDERPATH_GL11:
2460 case RENDERPATH_GL13:
2461 case RENDERPATH_GL20:
2462 case RENDERPATH_GLES1:
2463 case RENDERPATH_GLES2:
2465 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2467 case RENDERPATH_D3D9:
2470 // LordHavoc: we can't directly download the backbuffer because it may be
2471 // multisampled, and it may not be lockable, so we blit it to a lockable
2472 // surface of the same dimensions (but without multisample) to resolve the
2473 // multisample buffer to a normal image, and then lock that...
2474 IDirect3DSurface9 *stretchsurface = NULL;
2475 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2477 D3DLOCKED_RECT lockedrect;
2478 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2480 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2483 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2484 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2485 memcpy(outpixels + line * width * 4, row, width * 4);
2486 IDirect3DSurface9_UnlockRect(stretchsurface);
2489 IDirect3DSurface9_Release(stretchsurface);
2492 //IDirect3DSurface9 *syssurface = NULL;
2493 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2494 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2495 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2496 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2497 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2498 //IDirect3DSurface9_UnlockRect(syssurface);
2499 //IDirect3DSurface9_Release(syssurface);
2503 case RENDERPATH_D3D10:
2504 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2506 case RENDERPATH_D3D11:
2507 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2509 case RENDERPATH_SOFT:
2510 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2515 // called at beginning of frame
2516 void R_Mesh_Start(void)
2519 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
2521 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2523 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2524 Cvar_SetValueQuick(&gl_paranoid, 1);
2528 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2532 char compilelog[MAX_INPUTLINE];
2533 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2536 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2537 qglCompileShader(shaderobject);CHECKGLERROR
2538 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2539 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2540 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning") || developer_extra.integer))
2542 int i, j, pretextlines = 0;
2543 for (i = 0;i < numstrings - 1;i++)
2544 for (j = 0;strings[i][j];j++)
2545 if (strings[i][j] == '\n')
2547 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2549 if (!shadercompiled)
2551 qglDeleteShader(shaderobject);CHECKGLERROR
2554 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2555 qglDeleteShader(shaderobject);CHECKGLERROR
2559 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)
2561 GLint programlinked;
2562 GLuint programobject = 0;
2563 char linklog[MAX_INPUTLINE];
2566 programobject = qglCreateProgram();CHECKGLERROR
2570 qglBindAttribLocation(programobject, GLSLATTRIB_POSITION , "Attrib_Position" );
2571 qglBindAttribLocation(programobject, GLSLATTRIB_COLOR , "Attrib_Color" );
2572 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2573 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2574 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2575 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2576 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2577 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2578 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2579 qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2581 if(vid.support.gl20shaders130)
2582 qglBindFragDataLocation(programobject, 0, "dp_FragColor");
2585 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2588 #ifdef GL_GEOMETRY_SHADER
2589 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2593 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2596 qglLinkProgram(programobject);CHECKGLERROR
2597 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2598 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2601 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer)
2602 Con_DPrintf("program link log:\n%s\n", linklog);
2603 // software vertex shader is ok but software fragment shader is WAY
2604 // too slow, fail program if so.
2605 // NOTE: this string might be ATI specific, but that's ok because the
2606 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2607 // software fragment shader due to low instruction and dependent
2609 if (strstr(linklog, "fragment shader will run in software"))
2610 programlinked = false;
2614 return programobject;
2616 qglDeleteProgram(programobject);CHECKGLERROR
2620 void GL_Backend_FreeProgram(unsigned int prog)
2623 qglDeleteProgram(prog);
2627 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2632 for (i = 0;i < count;i++)
2633 *out++ = *in++ + offset;
2636 memcpy(out, in, sizeof(*out) * count);
2639 // renders triangles using vertices from the active arrays
2640 int paranoidblah = 0;
2641 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)
2643 unsigned int numelements = numtriangles * 3;
2645 size_t bufferoffset3i;
2647 size_t bufferoffset3s;
2648 if (numvertices < 3 || numtriangles < 1)
2650 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2651 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);
2654 if (!gl_mesh_prefer_short_elements.integer)
2658 if (element3i_indexbuffer)
2659 element3i_indexbuffer = NULL;
2661 // adjust the pointers for firsttriangle
2663 element3i += firsttriangle * 3;
2664 if (element3i_indexbuffer)
2665 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2667 element3s += firsttriangle * 3;
2668 if (element3s_indexbuffer)
2669 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2670 switch(vid.renderpath)
2672 case RENDERPATH_GL11:
2673 case RENDERPATH_GL13:
2674 case RENDERPATH_GL20:
2675 case RENDERPATH_GLES1:
2676 case RENDERPATH_GLES2:
2677 // check if the user specified to ignore static index buffers
2678 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2680 element3i_indexbuffer = NULL;
2681 element3s_indexbuffer = NULL;
2684 case RENDERPATH_D3D9:
2685 case RENDERPATH_D3D10:
2686 case RENDERPATH_D3D11:
2688 case RENDERPATH_SOFT:
2691 // upload a dynamic index buffer if needed
2694 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2696 if (gl_state.draw_dynamicindexbuffer)
2697 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2699 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2700 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2701 element3s_bufferoffset = 0;
2706 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2708 if (gl_state.draw_dynamicindexbuffer)
2709 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2711 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2712 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2713 element3i_bufferoffset = 0;
2716 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2717 bufferoffset3i = element3i_bufferoffset;
2718 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2719 bufferoffset3s = element3s_bufferoffset;
2720 r_refdef.stats.draws++;
2721 r_refdef.stats.draws_vertices += numvertices;
2722 r_refdef.stats.draws_elements += numelements;
2723 if (gl_paranoid.integer)
2726 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2728 unsigned int j, size;
2730 // note: there's no validation done here on buffer objects because it
2731 // is somewhat difficult to get at the data, and gl_paranoid can be
2732 // used without buffer objects if the need arises
2733 // (the data could be gotten using glMapBuffer but it would be very
2734 // slow due to uncachable video memory reads)
2735 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2736 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2738 if (gl_state.pointer_vertex_pointer)
2739 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2741 if (gl_state.pointer_color_enabled)
2743 if (!qglIsEnabled(GL_COLOR_ARRAY))
2744 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2746 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2747 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2750 for (i = 0;i < vid.texarrayunits;i++)
2752 if (gl_state.units[i].arrayenabled)
2754 GL_ClientActiveTexture(i);
2755 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2756 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2758 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2759 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++)
2766 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2768 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2770 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2777 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2779 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2781 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2787 if (r_render.integer || r_refdef.draw2dstage)
2789 switch(vid.renderpath)
2791 case RENDERPATH_GL11:
2792 case RENDERPATH_GL13:
2793 case RENDERPATH_GL20:
2795 if (gl_mesh_testmanualfeeding.integer)
2798 unsigned int i, j, element;
2800 qglBegin(GL_TRIANGLES);
2801 if(vid.renderpath == RENDERPATH_GL20)
2803 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2806 element = element3i[i];
2808 element = element3s[i];
2810 element = firstvertex + i;
2811 for (j = 0;j < vid.texarrayunits;j++)
2813 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2815 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2817 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2818 if (gl_state.units[j].pointer_texcoord_components == 4)
2819 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2], p[3]);
2820 else if (gl_state.units[j].pointer_texcoord_components == 3)
2821 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1], p[2]);
2822 else if (gl_state.units[j].pointer_texcoord_components == 2)
2823 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, p[0], p[1]);
2825 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, p[0]);
2827 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2829 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2830 if (gl_state.units[j].pointer_texcoord_components == 4)
2831 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2], s[3]);
2832 else if (gl_state.units[j].pointer_texcoord_components == 3)
2833 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1], s[2]);
2834 else if (gl_state.units[j].pointer_texcoord_components == 2)
2835 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, s[0], s[1]);
2836 else if (gl_state.units[j].pointer_texcoord_components == 1)
2837 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, s[0]);
2839 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2841 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2842 if (gl_state.units[j].pointer_texcoord_components == 4)
2843 qglVertexAttrib4f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2], sb[3]);
2844 else if (gl_state.units[j].pointer_texcoord_components == 3)
2845 qglVertexAttrib3f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1], sb[2]);
2846 else if (gl_state.units[j].pointer_texcoord_components == 2)
2847 qglVertexAttrib2f(GLSLATTRIB_TEXCOORD0 + j, sb[0], sb[1]);
2848 else if (gl_state.units[j].pointer_texcoord_components == 1)
2849 qglVertexAttrib1f(GLSLATTRIB_TEXCOORD0 + j, sb[0]);
2853 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2855 if (gl_state.pointer_color_gltype == GL_FLOAT)
2857 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2858 qglVertexAttrib4f(GLSLATTRIB_COLOR, p[0], p[1], p[2], p[3]);
2860 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2862 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2863 qglVertexAttrib4Nub(GLSLATTRIB_COLOR, ub[0], ub[1], ub[2], ub[3]);
2866 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2868 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2869 if (gl_state.pointer_vertex_components == 4)
2870 qglVertexAttrib4f(GLSLATTRIB_POSITION, p[0], p[1], p[2], p[3]);
2871 else if (gl_state.pointer_vertex_components == 3)
2872 qglVertexAttrib3f(GLSLATTRIB_POSITION, p[0], p[1], p[2]);
2874 qglVertexAttrib2f(GLSLATTRIB_POSITION, p[0], p[1]);
2880 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2883 element = element3i[i];
2885 element = element3s[i];
2887 element = firstvertex + i;
2888 for (j = 0;j < vid.texarrayunits;j++)
2890 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2892 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2894 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2895 if (vid.texarrayunits > 1)
2897 if (gl_state.units[j].pointer_texcoord_components == 4)
2898 qglMultiTexCoord4f(GL_TEXTURE0 + j, p[0], p[1], p[2], p[3]);
2899 else if (gl_state.units[j].pointer_texcoord_components == 3)
2900 qglMultiTexCoord3f(GL_TEXTURE0 + j, p[0], p[1], p[2]);
2901 else if (gl_state.units[j].pointer_texcoord_components == 2)
2902 qglMultiTexCoord2f(GL_TEXTURE0 + j, p[0], p[1]);
2904 qglMultiTexCoord1f(GL_TEXTURE0 + j, p[0]);
2908 if (gl_state.units[j].pointer_texcoord_components == 4)
2909 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2910 else if (gl_state.units[j].pointer_texcoord_components == 3)
2911 qglTexCoord3f(p[0], p[1], p[2]);
2912 else if (gl_state.units[j].pointer_texcoord_components == 2)
2913 qglTexCoord2f(p[0], p[1]);
2915 qglTexCoord1f(p[0]);
2918 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2920 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2921 if (vid.texarrayunits > 1)
2923 if (gl_state.units[j].pointer_texcoord_components == 4)
2924 qglMultiTexCoord4f(GL_TEXTURE0 + j, s[0], s[1], s[2], s[3]);
2925 else if (gl_state.units[j].pointer_texcoord_components == 3)
2926 qglMultiTexCoord3f(GL_TEXTURE0 + j, s[0], s[1], s[2]);
2927 else if (gl_state.units[j].pointer_texcoord_components == 2)
2928 qglMultiTexCoord2f(GL_TEXTURE0 + j, s[0], s[1]);
2929 else if (gl_state.units[j].pointer_texcoord_components == 1)
2930 qglMultiTexCoord1f(GL_TEXTURE0 + j, s[0]);
2934 if (gl_state.units[j].pointer_texcoord_components == 4)
2935 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2936 else if (gl_state.units[j].pointer_texcoord_components == 3)
2937 qglTexCoord3f(s[0], s[1], s[2]);
2938 else if (gl_state.units[j].pointer_texcoord_components == 2)
2939 qglTexCoord2f(s[0], s[1]);
2940 else if (gl_state.units[j].pointer_texcoord_components == 1)
2941 qglTexCoord1f(s[0]);
2944 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2946 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2947 if (vid.texarrayunits > 1)
2949 if (gl_state.units[j].pointer_texcoord_components == 4)
2950 qglMultiTexCoord4f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2], sb[3]);
2951 else if (gl_state.units[j].pointer_texcoord_components == 3)
2952 qglMultiTexCoord3f(GL_TEXTURE0 + j, sb[0], sb[1], sb[2]);
2953 else if (gl_state.units[j].pointer_texcoord_components == 2)
2954 qglMultiTexCoord2f(GL_TEXTURE0 + j, sb[0], sb[1]);
2955 else if (gl_state.units[j].pointer_texcoord_components == 1)
2956 qglMultiTexCoord1f(GL_TEXTURE0 + j, sb[0]);
2960 if (gl_state.units[j].pointer_texcoord_components == 4)
2961 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2962 else if (gl_state.units[j].pointer_texcoord_components == 3)
2963 qglTexCoord3f(sb[0], sb[1], sb[2]);
2964 else if (gl_state.units[j].pointer_texcoord_components == 2)
2965 qglTexCoord2f(sb[0], sb[1]);
2966 else if (gl_state.units[j].pointer_texcoord_components == 1)
2967 qglTexCoord1f(sb[0]);
2972 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2974 if (gl_state.pointer_color_gltype == GL_FLOAT)
2976 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2977 qglColor4f(p[0], p[1], p[2], p[3]);
2979 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2981 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2982 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2985 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2987 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2988 if (gl_state.pointer_vertex_components == 4)
2989 qglVertex4f(p[0], p[1], p[2], p[3]);
2990 else if (gl_state.pointer_vertex_components == 3)
2991 qglVertex3f(p[0], p[1], p[2]);
2993 qglVertex2f(p[0], p[1]);
3001 else if (bufferobject3s)
3003 GL_BindEBO(bufferobject3s);
3005 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3007 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
3013 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
3017 else if (bufferobject3i)
3019 GL_BindEBO(bufferobject3i);
3021 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3023 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
3029 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
3037 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3039 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
3045 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3053 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
3055 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
3061 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3067 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3071 case RENDERPATH_D3D9:
3073 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
3075 if (element3s_indexbuffer)
3077 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
3078 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
3080 else if (element3i_indexbuffer)
3082 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
3083 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
3086 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
3091 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3093 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3095 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
3099 case RENDERPATH_D3D10:
3100 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3102 case RENDERPATH_D3D11:
3103 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3105 case RENDERPATH_SOFT:
3106 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
3108 case RENDERPATH_GLES1:
3109 case RENDERPATH_GLES2:
3110 // GLES does not have glDrawRangeElements, and generally
3111 // underperforms with index buffers, so this code path is
3112 // relatively straightforward...
3114 if (gl_paranoid.integer)
3116 int r, prog, enabled, i;
3117 GLsizei attriblength;
3120 GLchar attribname[1024];
3121 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
3122 if (r != GL_FRAMEBUFFER_COMPLETE)
3123 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3124 #ifndef GL_CURRENT_PROGRAM
3125 #define GL_CURRENT_PROGRAM 0x8B8D
3127 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3128 if (r < 0 || r > 10000)
3129 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3131 for (i = 0;i < 8;i++)
3133 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3136 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3137 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);
3143 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3148 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3153 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3161 // restores backend state, used when done with 3D rendering
3162 void R_Mesh_Finish(void)
3164 R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
3167 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3169 r_meshbuffer_t *buffer;
3170 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3172 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3173 memset(buffer, 0, sizeof(*buffer));
3174 buffer->bufferobject = 0;
3175 buffer->devicebuffer = NULL;
3177 buffer->isindexbuffer = isindexbuffer;
3178 buffer->isdynamic = isdynamic;
3179 buffer->isindex16 = isindex16;
3180 strlcpy(buffer->name, name, sizeof(buffer->name));
3181 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3185 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3189 if (buffer->isindexbuffer)
3191 r_refdef.stats.indexbufferuploadcount++;
3192 r_refdef.stats.indexbufferuploadsize += size;
3196 r_refdef.stats.vertexbufferuploadcount++;
3197 r_refdef.stats.vertexbufferuploadsize += size;
3199 switch(vid.renderpath)
3201 case RENDERPATH_GL11:
3202 case RENDERPATH_GL13:
3203 case RENDERPATH_GL20:
3204 case RENDERPATH_GLES1:
3205 case RENDERPATH_GLES2:
3206 if (!buffer->bufferobject)
3207 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3208 if (buffer->isindexbuffer)
3209 GL_BindEBO(buffer->bufferobject);
3211 GL_BindVBO(buffer->bufferobject);
3212 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
3214 case RENDERPATH_D3D9:
3218 void *datapointer = NULL;
3219 if (buffer->isindexbuffer)
3221 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3222 if (size > buffer->size || !buffer->devicebuffer)
3224 if (buffer->devicebuffer)
3225 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3226 buffer->devicebuffer = NULL;
3227 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)))
3228 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);
3229 buffer->devicebuffer = (void *)d3d9indexbuffer;
3230 buffer->size = size;
3232 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3235 memcpy(datapointer, data, size);
3237 memset(datapointer, 0, size);
3238 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3243 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3244 if (size > buffer->size || !buffer->devicebuffer)
3246 if (buffer->devicebuffer)
3247 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3248 buffer->devicebuffer = NULL;
3249 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3250 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);
3251 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3252 buffer->size = size;
3254 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3257 memcpy(datapointer, data, size);
3259 memset(datapointer, 0, size);
3260 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3266 case RENDERPATH_D3D10:
3267 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3269 case RENDERPATH_D3D11:
3270 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3272 case RENDERPATH_SOFT:
3277 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3281 switch(vid.renderpath)
3283 case RENDERPATH_GL11:
3284 case RENDERPATH_GL13:
3285 case RENDERPATH_GL20:
3286 case RENDERPATH_GLES1:
3287 case RENDERPATH_GLES2:
3288 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3290 case RENDERPATH_D3D9:
3292 if (gl_state.d3dvertexbuffer == (void *)buffer)
3293 gl_state.d3dvertexbuffer = NULL;
3294 if (buffer->devicebuffer)
3296 if (buffer->isindexbuffer)
3297 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3299 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3300 buffer->devicebuffer = NULL;
3304 case RENDERPATH_D3D10:
3305 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3307 case RENDERPATH_D3D11:
3308 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3310 case RENDERPATH_SOFT:
3313 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3316 void GL_Mesh_ListVBOs(qboolean printeach)
3319 size_t ebocount = 0, ebomemory = 0;
3320 size_t vbocount = 0, vbomemory = 0;
3321 r_meshbuffer_t *buffer;
3322 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3323 for (i = 0;i < endindex;i++)
3325 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3328 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)");}
3329 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)");}
3331 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);
3336 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3338 switch(vid.renderpath)
3340 case RENDERPATH_GL11:
3341 case RENDERPATH_GL13:
3342 case RENDERPATH_GLES1:
3343 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)
3345 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3346 gl_state.pointer_vertex_components = components;
3347 gl_state.pointer_vertex_gltype = gltype;
3348 gl_state.pointer_vertex_stride = stride;
3349 gl_state.pointer_vertex_pointer = pointer;
3350 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3351 gl_state.pointer_vertex_offset = bufferoffset;
3353 GL_BindVBO(bufferobject);
3354 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3357 case RENDERPATH_GL20:
3358 case RENDERPATH_GLES2:
3359 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)
3361 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3362 gl_state.pointer_vertex_components = components;
3363 gl_state.pointer_vertex_gltype = gltype;
3364 gl_state.pointer_vertex_stride = stride;
3365 gl_state.pointer_vertex_pointer = pointer;
3366 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3367 gl_state.pointer_vertex_offset = bufferoffset;
3369 GL_BindVBO(bufferobject);
3370 qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3373 case RENDERPATH_D3D9:
3374 case RENDERPATH_D3D10:
3375 case RENDERPATH_D3D11:
3376 case RENDERPATH_SOFT:
3381 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3383 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3384 // the pointer only.
3385 switch(vid.renderpath)
3387 case RENDERPATH_GL11:
3388 case RENDERPATH_GL13:
3389 case RENDERPATH_GLES1:
3394 // caller wants color array enabled
3395 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3396 if (!gl_state.pointer_color_enabled)
3398 gl_state.pointer_color_enabled = true;
3400 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3402 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)
3404 gl_state.pointer_color_components = components;
3405 gl_state.pointer_color_gltype = gltype;
3406 gl_state.pointer_color_stride = stride;
3407 gl_state.pointer_color_pointer = pointer;
3408 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3409 gl_state.pointer_color_offset = bufferoffset;
3411 GL_BindVBO(bufferobject);
3412 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3417 // caller wants color array disabled
3418 if (gl_state.pointer_color_enabled)
3420 gl_state.pointer_color_enabled = false;
3422 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3423 // when color array is on the glColor gets trashed, set it again
3424 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3429 case RENDERPATH_GL20:
3430 case RENDERPATH_GLES2:
3434 // caller wants color array enabled
3435 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3436 if (!gl_state.pointer_color_enabled)
3438 gl_state.pointer_color_enabled = true;
3440 qglEnableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3442 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)
3444 gl_state.pointer_color_components = components;
3445 gl_state.pointer_color_gltype = gltype;
3446 gl_state.pointer_color_stride = stride;
3447 gl_state.pointer_color_pointer = pointer;
3448 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3449 gl_state.pointer_color_offset = bufferoffset;
3451 GL_BindVBO(bufferobject);
3452 qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3457 // caller wants color array disabled
3458 if (gl_state.pointer_color_enabled)
3460 gl_state.pointer_color_enabled = false;
3462 qglDisableVertexAttribArray(GLSLATTRIB_COLOR);CHECKGLERROR
3463 // when color array is on the glColor gets trashed, set it again
3464 qglVertexAttrib4f(GLSLATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3468 case RENDERPATH_D3D9:
3469 case RENDERPATH_D3D10:
3470 case RENDERPATH_D3D11:
3471 case RENDERPATH_SOFT:
3476 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)
3478 gltextureunit_t *unit = gl_state.units + unitnum;
3479 // update array settings
3480 // note: there is no need to check bufferobject here because all cases
3481 // that involve a valid bufferobject also supply a texcoord array
3482 switch(vid.renderpath)
3484 case RENDERPATH_GL11:
3485 case RENDERPATH_GL13:
3486 case RENDERPATH_GLES1:
3491 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3492 // texture array unit is enabled, enable the array
3493 if (!unit->arrayenabled)
3495 unit->arrayenabled = true;
3496 GL_ClientActiveTexture(unitnum);
3497 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3500 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)
3502 unit->pointer_texcoord_components = components;
3503 unit->pointer_texcoord_gltype = gltype;
3504 unit->pointer_texcoord_stride = stride;
3505 unit->pointer_texcoord_pointer = pointer;
3506 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3507 unit->pointer_texcoord_offset = bufferoffset;
3508 GL_ClientActiveTexture(unitnum);
3509 GL_BindVBO(bufferobject);
3510 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3515 // texture array unit is disabled, disable the array
3516 if (unit->arrayenabled)
3518 unit->arrayenabled = false;
3519 GL_ClientActiveTexture(unitnum);
3520 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3525 case RENDERPATH_GL20:
3526 case RENDERPATH_GLES2:
3530 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3531 // texture array unit is enabled, enable the array
3532 if (!unit->arrayenabled)
3534 unit->arrayenabled = true;
3535 qglEnableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3538 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)
3540 unit->pointer_texcoord_components = components;
3541 unit->pointer_texcoord_gltype = gltype;
3542 unit->pointer_texcoord_stride = stride;
3543 unit->pointer_texcoord_pointer = pointer;
3544 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3545 unit->pointer_texcoord_offset = bufferoffset;
3546 GL_BindVBO(bufferobject);
3547 qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3552 // texture array unit is disabled, disable the array
3553 if (unit->arrayenabled)
3555 unit->arrayenabled = false;
3556 qglDisableVertexAttribArray(unitnum+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
3560 case RENDERPATH_D3D9:
3561 case RENDERPATH_D3D10:
3562 case RENDERPATH_D3D11:
3563 case RENDERPATH_SOFT:
3568 int R_Mesh_TexBound(unsigned int unitnum, int id)
3570 gltextureunit_t *unit = gl_state.units + unitnum;
3571 if (unitnum >= vid.teximageunits)
3573 if (id == GL_TEXTURE_2D)
3575 if (id == GL_TEXTURE_3D)
3577 if (id == GL_TEXTURE_CUBE_MAP)
3578 return unit->tcubemap;
3582 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3584 switch(vid.renderpath)
3586 case RENDERPATH_GL11:
3587 case RENDERPATH_GL13:
3588 case RENDERPATH_GL20:
3589 case RENDERPATH_GLES1:
3590 case RENDERPATH_GLES2:
3591 R_Mesh_TexBind(0, tex);
3592 GL_ActiveTexture(0);CHECKGLERROR
3593 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3595 case RENDERPATH_D3D9:
3598 IDirect3DSurface9 *currentsurface = NULL;
3599 IDirect3DSurface9 *texturesurface = NULL;
3602 sourcerect.left = sx;
3603 sourcerect.top = sy;
3604 sourcerect.right = sx + width;
3605 sourcerect.bottom = sy + height;
3608 destrect.right = tx + width;
3609 destrect.bottom = ty + height;
3610 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3612 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3614 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3615 IDirect3DSurface9_Release(currentsurface);
3617 IDirect3DSurface9_Release(texturesurface);
3622 case RENDERPATH_D3D10:
3623 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3625 case RENDERPATH_D3D11:
3626 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3628 case RENDERPATH_SOFT:
3629 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3635 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};
3638 void R_Mesh_ClearBindingsForTexture(int texnum)
3640 gltextureunit_t *unit;
3641 unsigned int unitnum;
3642 // 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)
3643 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3645 unit = gl_state.units + unitnum;
3646 if (unit->t2d == texnum)
3648 if (unit->t3d == texnum)
3650 if (unit->tcubemap == texnum)
3651 unit->tcubemap = -1;
3655 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3657 gltextureunit_t *unit = gl_state.units + unitnum;
3658 int tex2d, tex3d, texcubemap, texnum;
3659 if (unitnum >= vid.teximageunits)
3661 // if (unit->texture == tex)
3663 switch(vid.renderpath)
3665 case RENDERPATH_GL20:
3666 case RENDERPATH_GLES2:
3669 tex = r_texture_white;
3670 // not initialized enough yet...
3674 unit->texture = tex;
3675 texnum = R_GetTexture(tex);
3676 switch(tex->gltexturetypeenum)
3678 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3679 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3680 case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
3683 case RENDERPATH_GL11:
3684 case RENDERPATH_GL13:
3685 case RENDERPATH_GLES1:
3686 unit->texture = tex;
3692 texnum = R_GetTexture(tex);
3693 switch(tex->gltexturetypeenum)
3701 case GL_TEXTURE_CUBE_MAP:
3702 texcubemap = texnum;
3706 // update 2d texture binding
3707 if (unit->t2d != tex2d)
3709 GL_ActiveTexture(unitnum);
3714 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3721 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3725 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3727 // update 3d texture binding
3728 if (unit->t3d != tex3d)
3730 GL_ActiveTexture(unitnum);
3735 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3742 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3746 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3748 // update cubemap texture binding
3749 if (unit->tcubemap != texcubemap)
3751 GL_ActiveTexture(unitnum);
3754 if (unit->tcubemap == 0)
3756 qglEnable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3763 qglDisable(GL_TEXTURE_CUBE_MAP);CHECKGLERROR
3766 unit->tcubemap = texcubemap;
3767 qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
3770 case RENDERPATH_D3D9:
3773 extern cvar_t gl_texture_anisotropy;
3776 tex = r_texture_white;
3777 // not initialized enough yet...
3781 // upload texture if needed
3783 if (unit->texture == tex)
3785 unit->texture = tex;
3786 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3787 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3788 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3789 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3790 if (tex->d3daddressw)
3791 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3792 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3793 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3794 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3795 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3796 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3797 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3801 case RENDERPATH_D3D10:
3802 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3804 case RENDERPATH_D3D11:
3805 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3807 case RENDERPATH_SOFT:
3810 tex = r_texture_white;
3811 // not initialized enough yet...
3815 texnum = R_GetTexture(tex);
3816 if (unit->texture == tex)
3818 unit->texture = tex;
3819 DPSOFTRAST_SetTexture(unitnum, texnum);
3824 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3826 gltextureunit_t *unit = gl_state.units + unitnum;
3827 switch(vid.renderpath)
3829 case RENDERPATH_GL11:
3830 case RENDERPATH_GL13:
3831 case RENDERPATH_GL20:
3832 case RENDERPATH_GLES1:
3833 case RENDERPATH_GLES2:
3835 if (matrix && matrix->m[3][3])
3837 // texmatrix specified, check if it is different
3838 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3841 unit->texmatrixenabled = true;
3842 unit->matrix = *matrix;
3844 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3845 GL_ActiveTexture(unitnum);
3846 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3847 qglLoadMatrixf(glmatrix);CHECKGLERROR
3848 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3853 // no texmatrix specified, revert to identity
3854 if (unit->texmatrixenabled)
3856 unit->texmatrixenabled = false;
3857 unit->matrix = identitymatrix;
3859 GL_ActiveTexture(unitnum);
3860 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3861 qglLoadIdentity();CHECKGLERROR
3862 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3867 case RENDERPATH_D3D9:
3868 case RENDERPATH_D3D10:
3869 case RENDERPATH_D3D11:
3871 case RENDERPATH_SOFT:
3876 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3878 gltextureunit_t *unit = gl_state.units + unitnum;
3880 switch(vid.renderpath)
3882 case RENDERPATH_GL20:
3883 case RENDERPATH_GLES2:
3886 case RENDERPATH_GL13:
3887 case RENDERPATH_GLES1:
3888 #ifdef GL_TEXTURE_ENV
3889 // GL_ARB_texture_env_combine
3891 combinergb = GL_MODULATE;
3893 combinealpha = GL_MODULATE;
3898 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3900 if (combinergb == GL_DECAL)
3901 combinergb = GL_INTERPOLATE;
3902 if (unit->combine != GL_COMBINE)
3904 unit->combine = GL_COMBINE;
3905 GL_ActiveTexture(unitnum);
3906 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
3907 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
3909 if (unit->combinergb != combinergb)
3911 unit->combinergb = combinergb;
3912 GL_ActiveTexture(unitnum);
3913 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
3915 if (unit->combinealpha != combinealpha)
3917 unit->combinealpha = combinealpha;
3918 GL_ActiveTexture(unitnum);
3919 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
3921 if (unit->rgbscale != rgbscale)
3923 unit->rgbscale = rgbscale;
3924 GL_ActiveTexture(unitnum);
3925 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
3927 if (unit->alphascale != alphascale)
3929 unit->alphascale = alphascale;
3930 GL_ActiveTexture(unitnum);
3931 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3936 if (unit->combine != combinergb)
3938 unit->combine = combinergb;
3939 GL_ActiveTexture(unitnum);
3940 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3945 case RENDERPATH_GL11:
3947 #ifdef GL_TEXTURE_ENV
3949 combinergb = GL_MODULATE;
3950 if (unit->combine != combinergb)
3952 unit->combine = combinergb;
3953 GL_ActiveTexture(unitnum);
3954 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3958 case RENDERPATH_D3D9:
3959 case RENDERPATH_D3D10:
3960 case RENDERPATH_D3D11:
3962 case RENDERPATH_SOFT:
3967 void R_Mesh_ResetTextureState(void)
3969 unsigned int unitnum;
3973 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3974 R_Mesh_TexBind(unitnum, NULL);
3975 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3976 R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3977 switch(vid.renderpath)
3979 case RENDERPATH_GL20:
3980 case RENDERPATH_GLES2:
3981 case RENDERPATH_D3D9:
3982 case RENDERPATH_D3D10:
3983 case RENDERPATH_D3D11:
3984 case RENDERPATH_SOFT:
3986 case RENDERPATH_GL11:
3987 case RENDERPATH_GL13:
3988 case RENDERPATH_GLES1:
3989 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3991 R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
3992 R_Mesh_TexMatrix(unitnum, NULL);
4001 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
4002 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
4003 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
4005 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
4007 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4011 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
4013 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4014 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4015 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4019 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
4021 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4022 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4023 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4024 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4025 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4026 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
4027 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
4031 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
4032 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
4033 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
4036 static void R_Mesh_InitVertexDeclarations(void)
4039 r_vertex3f_d3d9decl = NULL;
4040 r_vertexgeneric_d3d9decl = NULL;
4041 r_vertexmesh_d3d9decl = NULL;
4042 switch(vid.renderpath)
4044 case RENDERPATH_GL20:
4045 case RENDERPATH_GL13:
4046 case RENDERPATH_GL11:
4047 case RENDERPATH_GLES1:
4048 case RENDERPATH_GLES2:
4050 case RENDERPATH_D3D9:
4051 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
4052 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4053 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4055 case RENDERPATH_D3D10:
4056 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4058 case RENDERPATH_D3D11:
4059 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4061 case RENDERPATH_SOFT:
4067 static void R_Mesh_DestroyVertexDeclarations(void)
4070 if (r_vertex3f_d3d9decl)
4071 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4072 r_vertex3f_d3d9decl = NULL;
4073 if (r_vertexgeneric_d3d9decl)
4074 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4075 r_vertexgeneric_d3d9decl = NULL;
4076 if (r_vertexmesh_d3d9decl)
4077 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4078 r_vertexmesh_d3d9decl = NULL;
4082 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4084 // upload temporary vertexbuffer for this rendering
4085 if (!gl_state.usevbo_staticvertex)
4086 vertexbuffer = NULL;
4087 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4089 if (gl_state.preparevertices_dynamicvertexbuffer)
4090 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4092 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4093 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4095 switch(vid.renderpath)
4097 case RENDERPATH_GL20:
4098 case RENDERPATH_GLES2:
4101 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4102 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4103 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4104 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4105 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4106 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4107 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4111 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4112 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4113 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4114 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4115 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4116 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4117 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4120 case RENDERPATH_GL13:
4121 case RENDERPATH_GLES1:
4124 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4125 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4126 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4127 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4131 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4132 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4133 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4134 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4137 case RENDERPATH_GL11:
4140 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4141 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4142 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4146 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4147 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4148 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4151 case RENDERPATH_D3D9:
4153 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4155 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4157 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4158 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4159 gl_state.d3dvertexdata = (void *)vertex3f;
4160 gl_state.d3dvertexsize = sizeof(float[3]);
4163 case RENDERPATH_D3D10:
4164 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4166 case RENDERPATH_D3D11:
4167 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4169 case RENDERPATH_SOFT:
4170 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4171 DPSOFTRAST_SetColorPointer(NULL, 0);
4172 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4173 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4174 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4175 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4176 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4183 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4186 size = sizeof(r_vertexgeneric_t) * numvertices;
4187 if (gl_state.preparevertices_tempdatamaxsize < size)
4189 gl_state.preparevertices_tempdatamaxsize = size;
4190 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4192 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4193 gl_state.preparevertices_numvertices = numvertices;
4194 return gl_state.preparevertices_vertexgeneric;
4197 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4199 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4200 gl_state.preparevertices_vertexgeneric = NULL;
4201 gl_state.preparevertices_numvertices = 0;
4205 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4208 r_vertexgeneric_t *vertex;
4209 switch(vid.renderpath)
4211 case RENDERPATH_GL20:
4212 case RENDERPATH_GLES2:
4213 if (!vid.useinterleavedarrays)
4215 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4216 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4217 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4218 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4219 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4220 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4221 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4225 case RENDERPATH_GL11:
4226 case RENDERPATH_GL13:
4227 case RENDERPATH_GLES1:
4228 if (!vid.useinterleavedarrays)
4230 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4231 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4232 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4233 if (vid.texunits >= 2)
4234 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4235 if (vid.texunits >= 3)
4236 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4240 case RENDERPATH_D3D9:
4241 case RENDERPATH_D3D10:
4242 case RENDERPATH_D3D11:
4244 case RENDERPATH_SOFT:
4245 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4246 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4247 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4248 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4249 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4250 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4251 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4255 // no quick path for this case, convert to vertex structs
4256 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4257 for (i = 0;i < numvertices;i++)
4258 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4261 for (i = 0;i < numvertices;i++)
4262 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4266 for (i = 0;i < numvertices;i++)
4267 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4270 for (i = 0;i < numvertices;i++)
4271 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4272 R_Mesh_PrepareVertices_Generic_Unlock();
4273 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4276 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4278 // upload temporary vertexbuffer for this rendering
4279 if (!gl_state.usevbo_staticvertex)
4280 vertexbuffer = NULL;
4281 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4283 if (gl_state.preparevertices_dynamicvertexbuffer)
4284 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4286 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4287 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4289 switch(vid.renderpath)
4291 case RENDERPATH_GL20:
4292 case RENDERPATH_GLES2:
4295 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4296 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4297 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4298 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4299 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4300 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4301 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4305 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4306 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4307 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4308 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4309 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4310 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4311 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4314 case RENDERPATH_GL13:
4315 case RENDERPATH_GLES1:
4318 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4319 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4320 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4321 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4325 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4326 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4327 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4328 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4331 case RENDERPATH_GL11:
4334 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4335 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4336 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4340 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4341 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4342 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4345 case RENDERPATH_D3D9:
4347 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4349 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4351 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4352 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4353 gl_state.d3dvertexdata = (void *)vertex;
4354 gl_state.d3dvertexsize = sizeof(*vertex);
4357 case RENDERPATH_D3D10:
4358 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4360 case RENDERPATH_D3D11:
4361 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4363 case RENDERPATH_SOFT:
4364 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4365 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4366 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4367 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4368 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4369 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4370 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4377 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4380 size = sizeof(r_vertexmesh_t) * numvertices;
4381 if (gl_state.preparevertices_tempdatamaxsize < size)
4383 gl_state.preparevertices_tempdatamaxsize = size;
4384 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4386 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4387 gl_state.preparevertices_numvertices = numvertices;
4388 return gl_state.preparevertices_vertexmesh;
4391 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4393 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4394 gl_state.preparevertices_vertexmesh = NULL;
4395 gl_state.preparevertices_numvertices = 0;
4399 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)
4402 r_vertexmesh_t *vertex;
4403 switch(vid.renderpath)
4405 case RENDERPATH_GL20:
4406 case RENDERPATH_GLES2:
4407 if (!vid.useinterleavedarrays)
4409 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4410 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4411 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4412 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4413 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4414 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4415 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4419 case RENDERPATH_GL11:
4420 case RENDERPATH_GL13:
4421 case RENDERPATH_GLES1:
4422 if (!vid.useinterleavedarrays)
4424 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4425 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4426 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4427 if (vid.texunits >= 2)
4428 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4429 if (vid.texunits >= 3)
4430 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4434 case RENDERPATH_D3D9:
4435 case RENDERPATH_D3D10:
4436 case RENDERPATH_D3D11:
4438 case RENDERPATH_SOFT:
4439 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4440 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4441 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4442 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4443 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4444 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4445 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4449 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4450 for (i = 0;i < numvertices;i++)
4451 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4453 for (i = 0;i < numvertices;i++)
4454 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4456 for (i = 0;i < numvertices;i++)
4457 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4459 for (i = 0;i < numvertices;i++)
4460 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4463 for (i = 0;i < numvertices;i++)
4464 Vector4Copy(color4f + 4*i, vertex[i].color4f);
4468 for (i = 0;i < numvertices;i++)
4469 Vector4Copy(gl_state.color4f, vertex[i].color4f);
4471 if (texcoordtexture2f)
4472 for (i = 0;i < numvertices;i++)
4473 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4474 if (texcoordlightmap2f)
4475 for (i = 0;i < numvertices;i++)
4476 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4477 R_Mesh_PrepareVertices_Mesh_Unlock();
4478 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4481 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4483 // upload temporary vertexbuffer for this rendering
4484 if (!gl_state.usevbo_staticvertex)
4485 vertexbuffer = NULL;
4486 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4488 if (gl_state.preparevertices_dynamicvertexbuffer)
4489 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4491 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4492 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4494 switch(vid.renderpath)
4496 case RENDERPATH_GL20:
4497 case RENDERPATH_GLES2:
4500 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4501 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4502 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4503 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4504 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4505 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4506 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4510 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4511 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4512 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4513 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4514 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4515 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4516 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4519 case RENDERPATH_GL13:
4520 case RENDERPATH_GLES1:
4523 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4524 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4525 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4526 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4530 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4531 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4532 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4533 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4536 case RENDERPATH_GL11:
4539 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4540 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , vertexbuffer, (int)((unsigned char *)vertex->color4f - (unsigned char *)vertex));
4541 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4545 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4546 R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(*vertex), vertex->color4f , NULL, 0);
4547 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4550 case RENDERPATH_D3D9:
4552 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4554 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4556 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4557 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4558 gl_state.d3dvertexdata = (void *)vertex;
4559 gl_state.d3dvertexsize = sizeof(*vertex);
4562 case RENDERPATH_D3D10:
4563 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4565 case RENDERPATH_D3D11:
4566 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4568 case RENDERPATH_SOFT:
4569 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4570 DPSOFTRAST_SetColorPointer(vertex->color4f, sizeof(*vertex));
4571 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4572 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4573 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4574 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4575 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);
4580 void GL_BlendEquationSubtract(qboolean negated)
4584 switch(vid.renderpath)
4586 case RENDERPATH_GL11:
4587 case RENDERPATH_GL13:
4588 case RENDERPATH_GL20:
4589 case RENDERPATH_GLES1:
4590 case RENDERPATH_GLES2:
4591 qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
4593 case RENDERPATH_D3D9:
4595 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
4598 case RENDERPATH_D3D10:
4599 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4601 case RENDERPATH_D3D11:
4602 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4604 case RENDERPATH_SOFT:
4605 DPSOFTRAST_BlendSubtract(true);
4611 switch(vid.renderpath)
4613 case RENDERPATH_GL11:
4614 case RENDERPATH_GL13:
4615 case RENDERPATH_GL20:
4616 case RENDERPATH_GLES1:
4617 case RENDERPATH_GLES2:
4618 qglBlendEquationEXT(GL_FUNC_ADD);
4620 case RENDERPATH_D3D9:
4622 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4625 case RENDERPATH_D3D10:
4626 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4628 case RENDERPATH_D3D11:
4629 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4631 case RENDERPATH_SOFT:
4632 DPSOFTRAST_BlendSubtract(false);