3 #include "cl_collision.h"
4 #include "dpsoftrast.h"
7 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
8 extern D3DCAPS9 vid_d3d9caps;
11 #define MAX_RENDERTARGETS 4
13 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
14 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)"};
15 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"};
16 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
17 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
19 cvar_t r_render = {0, "r_render", "1", "enables rendering 3D views (you want this on!)"};
20 cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
21 cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
22 cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
23 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
24 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)"};
25 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"};
26 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"};
27 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"};
29 cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
30 qboolean v_flipped_state = false;
32 r_viewport_t gl_viewport;
33 matrix4x4_t gl_modelmatrix;
34 matrix4x4_t gl_viewmatrix;
35 matrix4x4_t gl_modelviewmatrix;
36 matrix4x4_t gl_projectionmatrix;
37 matrix4x4_t gl_modelviewprojectionmatrix;
38 float gl_modelview16f[16];
39 float gl_modelviewprojection16f[16];
40 qboolean gl_modelmatrixchanged;
42 int gl_maxdrawrangeelementsvertices;
43 int gl_maxdrawrangeelementsindices;
48 void GL_PrintError(int errornumber, const char *filename, int linenumber)
52 #ifdef GL_INVALID_ENUM
54 Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
57 #ifdef GL_INVALID_VALUE
58 case GL_INVALID_VALUE:
59 Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
62 #ifdef GL_INVALID_OPERATION
63 case GL_INVALID_OPERATION:
64 Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
67 #ifdef GL_STACK_OVERFLOW
68 case GL_STACK_OVERFLOW:
69 Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
72 #ifdef GL_STACK_UNDERFLOW
73 case GL_STACK_UNDERFLOW:
74 Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
77 #ifdef GL_OUT_OF_MEMORY
78 case GL_OUT_OF_MEMORY:
79 Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
82 #ifdef GL_TABLE_TOO_LARGE
83 case GL_TABLE_TOO_LARGE:
84 Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
87 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
88 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
89 Con_Printf("GL_INVALID_FRAMEBUFFER_OPERATION at %s:%i\n", filename, linenumber);
93 Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
99 #define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
101 void SCR_ScreenShot_f (void);
103 typedef struct gltextureunit_s
105 int pointer_texcoord_components;
106 int pointer_texcoord_gltype;
107 size_t pointer_texcoord_stride;
108 const void *pointer_texcoord_pointer;
109 const r_meshbuffer_t *pointer_texcoord_vertexbuffer;
110 size_t pointer_texcoord_offset;
113 int t2d, t3d, tcubemap;
115 int rgbscale, alphascale;
117 int combinergb, combinealpha;
118 // texmatrixenabled exists only to avoid unnecessary texmatrix compares
119 int texmatrixenabled;
124 typedef struct gl_state_s
132 int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order)
136 float polygonoffset[2];
139 float alphafuncvalue;
142 unsigned int clientunit;
143 gltextureunit_t units[MAX_TEXTUREUNITS];
147 int vertexbufferobject;
148 int elementbufferobject;
149 int framebufferobject;
150 int defaultframebufferobject; // RENDERPATH_GLES2 has a non-zero fbo provided by the OS
151 qboolean pointer_color_enabled;
153 int pointer_vertex_components;
154 int pointer_vertex_gltype;
155 size_t pointer_vertex_stride;
156 const void *pointer_vertex_pointer;
157 const r_meshbuffer_t *pointer_vertex_vertexbuffer;
158 size_t pointer_vertex_offset;
160 int pointer_color_components;
161 int pointer_color_gltype;
162 size_t pointer_color_stride;
163 const void *pointer_color_pointer;
164 const r_meshbuffer_t *pointer_color_vertexbuffer;
165 size_t pointer_color_offset;
167 void *preparevertices_tempdata;
168 size_t preparevertices_tempdatamaxsize;
169 r_meshbuffer_t *preparevertices_dynamicvertexbuffer;
170 r_vertexgeneric_t *preparevertices_vertexgeneric;
171 r_vertexmesh_t *preparevertices_vertexmesh;
172 int preparevertices_numvertices;
174 r_meshbuffer_t *draw_dynamicindexbuffer;
176 qboolean usevbo_staticvertex;
177 qboolean usevbo_staticindex;
178 qboolean usevbo_dynamicvertex;
179 qboolean usevbo_dynamicindex;
181 memexpandablearray_t meshbufferarray;
186 // rtexture_t *d3drt_depthtexture;
187 // rtexture_t *d3drt_colortextures[MAX_RENDERTARGETS];
188 IDirect3DSurface9 *d3drt_depthsurface;
189 IDirect3DSurface9 *d3drt_colorsurfaces[MAX_RENDERTARGETS];
190 IDirect3DSurface9 *d3drt_backbufferdepthsurface;
191 IDirect3DSurface9 *d3drt_backbuffercolorsurface;
192 void *d3dvertexbuffer;
194 size_t d3dvertexsize;
199 static gl_state_t gl_state;
203 note: here's strip order for a terrain row:
210 A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E
212 *elements++ = i + row;
214 *elements++ = i + row + 1;
217 *elements++ = i + row + 1;
220 for (y = 0;y < rows - 1;y++)
222 for (x = 0;x < columns - 1;x++)
225 *elements++ = i + columns;
227 *elements++ = i + columns + 1;
230 *elements++ = i + columns + 1;
241 for (y = 0;y < rows - 1;y++)
243 for (x = 0;x < columns - 1;x++)
247 *elements++ = i + columns;
248 *elements++ = i + columns + 1;
249 *elements++ = i + columns;
250 *elements++ = i + columns + 1;
256 int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
257 unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
258 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
259 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
261 void GL_VBOStats_f(void)
263 GL_Mesh_ListVBOs(true);
266 static void GL_Backend_ResetState(void);
268 static void R_Mesh_InitVertexDeclarations(void);
269 static void R_Mesh_DestroyVertexDeclarations(void);
271 static void R_Mesh_SetUseVBO(void)
273 switch(vid.renderpath)
275 case RENDERPATH_GL11:
276 case RENDERPATH_GL13:
277 case RENDERPATH_GL20:
278 case RENDERPATH_CGGL:
279 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
280 gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
281 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
282 gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer) || vid.forcevbo;
284 case RENDERPATH_D3D9:
285 gl_state.usevbo_staticvertex = gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
286 gl_state.usevbo_dynamicvertex = gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo_dynamicindex.integer) || vid.forcevbo;
288 case RENDERPATH_D3D10:
289 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
291 case RENDERPATH_D3D11:
292 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
294 case RENDERPATH_SOFT:
295 gl_state.usevbo_staticvertex = false;
296 gl_state.usevbo_staticindex = false;
297 gl_state.usevbo_dynamicvertex = false;
298 gl_state.usevbo_dynamicindex = false;
300 case RENDERPATH_GLES2:
301 gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
302 gl_state.usevbo_staticindex = false;
303 gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer) || vid.forcevbo;
304 gl_state.usevbo_dynamicindex = false;
309 static void gl_backend_start(void)
311 memset(&gl_state, 0, sizeof(gl_state));
313 R_Mesh_InitVertexDeclarations();
316 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
318 Con_DPrintf("OpenGL backend started.\n");
322 GL_Backend_ResetState();
324 switch(vid.renderpath)
326 case RENDERPATH_GL11:
327 case RENDERPATH_GL13:
328 case RENDERPATH_GL20:
329 case RENDERPATH_CGGL:
330 case RENDERPATH_GLES2:
331 // fetch current fbo here (default fbo is not 0 on some GLES devices)
332 if (vid.support.ext_framebuffer_object)
333 qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &gl_state.defaultframebufferobject);
335 case RENDERPATH_D3D9:
337 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
338 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
341 case RENDERPATH_D3D10:
342 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
344 case RENDERPATH_D3D11:
345 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
347 case RENDERPATH_SOFT:
352 static void gl_backend_shutdown(void)
354 Con_DPrint("OpenGL Backend shutting down\n");
356 switch(vid.renderpath)
358 case RENDERPATH_GL11:
359 case RENDERPATH_GL13:
360 case RENDERPATH_GL20:
361 case RENDERPATH_CGGL:
362 case RENDERPATH_SOFT:
363 case RENDERPATH_GLES2:
365 case RENDERPATH_D3D9:
367 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
368 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
371 case RENDERPATH_D3D10:
372 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
374 case RENDERPATH_D3D11:
375 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
379 if (gl_state.preparevertices_tempdata)
380 Mem_Free(gl_state.preparevertices_tempdata);
381 if (gl_state.preparevertices_dynamicvertexbuffer)
382 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
384 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
386 R_Mesh_DestroyVertexDeclarations();
388 memset(&gl_state, 0, sizeof(gl_state));
391 static void gl_backend_newmap(void)
395 static void gl_backend_devicelost(void)
398 r_meshbuffer_t *buffer;
400 gl_state.d3dvertexbuffer = NULL;
402 switch(vid.renderpath)
404 case RENDERPATH_GL11:
405 case RENDERPATH_GL13:
406 case RENDERPATH_GL20:
407 case RENDERPATH_CGGL:
408 case RENDERPATH_SOFT:
409 case RENDERPATH_GLES2:
411 case RENDERPATH_D3D9:
413 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
414 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
417 case RENDERPATH_D3D10:
418 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
420 case RENDERPATH_D3D11:
421 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
424 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
425 for (i = 0;i < endindex;i++)
427 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
428 if (!buffer || !buffer->isdynamic)
430 switch(vid.renderpath)
432 case RENDERPATH_GL11:
433 case RENDERPATH_GL13:
434 case RENDERPATH_GL20:
435 case RENDERPATH_CGGL:
436 case RENDERPATH_SOFT:
437 case RENDERPATH_GLES2:
439 case RENDERPATH_D3D9:
441 if (buffer->devicebuffer)
443 if (buffer->isindexbuffer)
444 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
446 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
447 buffer->devicebuffer = NULL;
451 case RENDERPATH_D3D10:
452 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
454 case RENDERPATH_D3D11:
455 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
461 static void gl_backend_devicerestored(void)
463 switch(vid.renderpath)
465 case RENDERPATH_GL11:
466 case RENDERPATH_GL13:
467 case RENDERPATH_GL20:
468 case RENDERPATH_CGGL:
469 case RENDERPATH_SOFT:
470 case RENDERPATH_GLES2:
472 case RENDERPATH_D3D9:
474 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
475 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
478 case RENDERPATH_D3D10:
479 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
481 case RENDERPATH_D3D11:
482 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
487 void gl_backend_init(void)
491 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
493 polygonelement3s[i * 3 + 0] = 0;
494 polygonelement3s[i * 3 + 1] = i + 1;
495 polygonelement3s[i * 3 + 2] = i + 2;
497 // elements for rendering a series of quads as triangles
498 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
500 quadelement3s[i * 6 + 0] = i * 4;
501 quadelement3s[i * 6 + 1] = i * 4 + 1;
502 quadelement3s[i * 6 + 2] = i * 4 + 2;
503 quadelement3s[i * 6 + 3] = i * 4;
504 quadelement3s[i * 6 + 4] = i * 4 + 2;
505 quadelement3s[i * 6 + 5] = i * 4 + 3;
508 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
509 polygonelement3i[i] = polygonelement3s[i];
510 for (i = 0;i < QUADELEMENTS_MAXQUADS*6;i++)
511 quadelement3i[i] = quadelement3s[i];
513 Cvar_RegisterVariable(&r_render);
514 Cvar_RegisterVariable(&r_renderview);
515 Cvar_RegisterVariable(&r_waterwarp);
516 Cvar_RegisterVariable(&gl_polyblend);
517 Cvar_RegisterVariable(&v_flipped);
518 Cvar_RegisterVariable(&gl_dither);
519 Cvar_RegisterVariable(&gl_vbo);
520 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
521 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
522 Cvar_RegisterVariable(&gl_paranoid);
523 Cvar_RegisterVariable(&gl_printcheckerror);
525 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
526 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
527 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
529 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");
531 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
534 void GL_SetMirrorState(qboolean state);
536 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
540 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
541 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
543 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
545 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
546 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
547 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
549 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
552 static int bboxedges[12][2] =
571 qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
573 int i, ix1, iy1, ix2, iy2;
574 float x1, y1, x2, y2;
585 scissor[0] = r_refdef.view.viewport.x;
586 scissor[1] = r_refdef.view.viewport.y;
587 scissor[2] = r_refdef.view.viewport.width;
588 scissor[3] = r_refdef.view.viewport.height;
590 // if view is inside the box, just say yes it's visible
591 if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
594 x1 = y1 = x2 = y2 = 0;
596 // transform all corners that are infront of the nearclip plane
597 VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
598 plane4f[3] = r_refdef.view.frustum[4].dist;
600 for (i = 0;i < 8;i++)
602 Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
603 dist[i] = DotProduct4(corner[i], plane4f);
604 sign[i] = dist[i] > 0;
607 VectorCopy(corner[i], vertex[numvertices]);
611 // if some points are behind the nearclip, add clipped edge points to make
612 // sure that the scissor boundary is complete
613 if (numvertices > 0 && numvertices < 8)
615 // add clipped edge points
616 for (i = 0;i < 12;i++)
620 if (sign[j] != sign[k])
622 f = dist[j] / (dist[j] - dist[k]);
623 VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
629 // if we have no points to check, it is behind the view plane
633 // if we have some points to transform, check what screen area is covered
634 x1 = y1 = x2 = y2 = 0;
636 //Con_Printf("%i vertices to transform...\n", numvertices);
637 for (i = 0;i < numvertices;i++)
639 VectorCopy(vertex[i], v);
640 R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
641 //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]);
644 if (x1 > v2[0]) x1 = v2[0];
645 if (x2 < v2[0]) x2 = v2[0];
646 if (y1 > v2[1]) y1 = v2[1];
647 if (y2 < v2[1]) y2 = v2[1];
656 // now convert the scissor rectangle to integer screen coordinates
657 ix1 = (int)(x1 - 1.0f);
658 //iy1 = vid.height - (int)(y2 - 1.0f);
659 //iy1 = r_refdef.view.viewport.width + 2 * r_refdef.view.viewport.x - (int)(y2 - 1.0f);
660 iy1 = (int)(y1 - 1.0f);
661 ix2 = (int)(x2 + 1.0f);
662 //iy2 = vid.height - (int)(y1 + 1.0f);
663 //iy2 = r_refdef.view.viewport.height + 2 * r_refdef.view.viewport.y - (int)(y1 + 1.0f);
664 iy2 = (int)(y2 + 1.0f);
665 //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
667 // clamp it to the screen
668 if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
669 if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
670 if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
671 if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
673 // if it is inside out, it's not visible
674 if (ix2 <= ix1 || iy2 <= iy1)
677 // the light area is visible, set up the scissor rectangle
680 scissor[2] = ix2 - ix1;
681 scissor[3] = iy2 - iy1;
683 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
684 switch(vid.renderpath)
686 case RENDERPATH_D3D9:
687 case RENDERPATH_D3D10:
688 case RENDERPATH_D3D11:
689 scissor[1] = vid.height - scissor[1] - scissor[3];
691 case RENDERPATH_GL11:
692 case RENDERPATH_GL13:
693 case RENDERPATH_GL20:
694 case RENDERPATH_CGGL:
695 case RENDERPATH_SOFT:
696 case RENDERPATH_GLES2:
704 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
708 float clipPlane[4], v3[3], v4[3];
711 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
713 VectorSet(normal, normalx, normaly, normalz);
714 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
715 VectorScale(normal, dist, v3);
716 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
717 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
718 clipPlane[3] = -DotProduct(v4, clipPlane);
722 // testing code for comparing results
724 VectorCopy4(clipPlane, clipPlane2);
725 R_EntityMatrix(&identitymatrix);
726 VectorSet(q, normal[0], normal[1], normal[2], -dist);
727 qglClipPlane(GL_CLIP_PLANE0, q);
728 qglGetClipPlane(GL_CLIP_PLANE0, q);
729 VectorCopy4(q, clipPlane);
733 // Calculate the clip-space corner point opposite the clipping plane
734 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
735 // transform it into camera space by multiplying it
736 // by the inverse of the projection matrix
737 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
738 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
740 q[3] = (1.0f + m[10]) / m[14];
742 // Calculate the scaled plane vector
743 d = 2.0f / DotProduct4(clipPlane, q);
745 // Replace the third row of the projection matrix
746 m[2] = clipPlane[0] * d;
747 m[6] = clipPlane[1] * d;
748 m[10] = clipPlane[2] * d + 1.0f;
749 m[14] = clipPlane[3] * d;
752 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)
754 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
756 memset(v, 0, sizeof(*v));
757 v->type = R_VIEWPORTTYPE_ORTHO;
758 v->cameramatrix = *cameramatrix;
765 memset(m, 0, sizeof(m));
766 m[0] = 2/(right - left);
767 m[5] = 2/(top - bottom);
768 m[10] = -2/(zFar - zNear);
769 m[12] = - (right + left)/(right - left);
770 m[13] = - (top + bottom)/(top - bottom);
771 m[14] = - (zFar + zNear)/(zFar - zNear);
773 switch(vid.renderpath)
775 case RENDERPATH_GL11:
776 case RENDERPATH_GL13:
777 case RENDERPATH_GL20:
778 case RENDERPATH_CGGL:
779 case RENDERPATH_SOFT:
780 case RENDERPATH_GLES2:
782 case RENDERPATH_D3D9:
783 case RENDERPATH_D3D10:
784 case RENDERPATH_D3D11:
785 m[10] = -1/(zFar - zNear);
786 m[14] = -zNear/(zFar-zNear);
789 v->screentodepth[0] = -farclip / (farclip - nearclip);
790 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
792 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
795 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
797 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
803 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
804 R_Viewport_TransformToScreen(v, test1, test2);
805 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
810 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)
812 matrix4x4_t tempmatrix, basematrix;
814 memset(v, 0, sizeof(*v));
816 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
817 v->cameramatrix = *cameramatrix;
824 memset(m, 0, sizeof(m));
825 m[0] = 1.0 / frustumx;
826 m[5] = 1.0 / frustumy;
827 m[10] = -(farclip + nearclip) / (farclip - nearclip);
829 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
830 v->screentodepth[0] = -farclip / (farclip - nearclip);
831 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
833 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
834 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
835 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
836 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
839 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
841 if(v_flipped.integer)
849 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
852 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)
854 matrix4x4_t tempmatrix, basematrix;
855 const float nudge = 1.0 - 1.0 / (1<<23);
857 memset(v, 0, sizeof(*v));
859 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
860 v->cameramatrix = *cameramatrix;
867 memset(m, 0, sizeof(m));
868 m[ 0] = 1.0 / frustumx;
869 m[ 5] = 1.0 / frustumy;
872 m[14] = -2 * nearclip * nudge;
873 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
874 v->screentodepth[1] = m[14] * -0.5;
876 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
877 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
878 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
879 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
882 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
884 if(v_flipped.integer)
892 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
895 float cubeviewmatrix[6][16] =
897 // standard cubemap projections
935 float rectviewmatrix[6][16] =
937 // sign-preserving cubemap projections
976 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
978 matrix4x4_t tempmatrix, basematrix;
980 memset(v, 0, sizeof(*v));
981 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
982 v->cameramatrix = *cameramatrix;
986 memset(m, 0, sizeof(m));
988 m[10] = -(farclip + nearclip) / (farclip - nearclip);
990 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
992 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
993 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
994 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
997 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
999 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1002 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)
1004 matrix4x4_t tempmatrix, basematrix;
1006 memset(v, 0, sizeof(*v));
1007 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
1008 v->cameramatrix = *cameramatrix;
1009 v->x = (side & 1) * size;
1010 v->y = (side >> 1) * size;
1014 memset(m, 0, sizeof(m));
1015 m[0] = m[5] = 1.0f * ((float)size - border) / size;
1016 m[10] = -(farclip + nearclip) / (farclip - nearclip);
1018 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
1020 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
1021 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
1022 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
1024 switch(vid.renderpath)
1026 case RENDERPATH_GL20:
1027 case RENDERPATH_CGGL:
1028 case RENDERPATH_GL13:
1029 case RENDERPATH_GL11:
1030 case RENDERPATH_SOFT:
1031 case RENDERPATH_GLES2:
1033 case RENDERPATH_D3D9:
1036 case RENDERPATH_D3D10:
1037 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1039 case RENDERPATH_D3D11:
1040 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1045 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
1047 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
1050 void R_SetViewport(const r_viewport_t *v)
1055 // FIXME: v_flipped_state is evil, this probably breaks somewhere
1056 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
1058 // copy over the matrices to our state
1059 gl_viewmatrix = v->viewmatrix;
1060 gl_projectionmatrix = v->projectmatrix;
1062 switch(vid.renderpath)
1064 case RENDERPATH_GL20:
1065 case RENDERPATH_CGGL:
1067 // qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1069 case RENDERPATH_GL13:
1070 case RENDERPATH_GL11:
1072 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1073 // Load the projection matrix into OpenGL
1074 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
1075 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
1076 qglLoadMatrixf(m);CHECKGLERROR
1077 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1079 case RENDERPATH_D3D9:
1082 D3DVIEWPORT9 d3dviewport;
1083 d3dviewport.X = gl_viewport.x;
1084 d3dviewport.Y = gl_viewport.y;
1085 d3dviewport.Width = gl_viewport.width;
1086 d3dviewport.Height = gl_viewport.height;
1087 d3dviewport.MinZ = gl_state.depthrange[0];
1088 d3dviewport.MaxZ = gl_state.depthrange[1];
1089 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1093 case RENDERPATH_D3D10:
1094 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1096 case RENDERPATH_D3D11:
1097 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1099 case RENDERPATH_SOFT:
1100 DPSOFTRAST_Viewport(v->x, v->y, v->width, v->height);
1102 case RENDERPATH_GLES2:
1104 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
1108 // force an update of the derived matrices
1109 gl_modelmatrixchanged = true;
1110 R_EntityMatrix(&gl_modelmatrix);
1113 void R_GetViewport(r_viewport_t *v)
1118 static void GL_BindVBO(int bufferobject)
1120 if (gl_state.vertexbufferobject != bufferobject)
1122 gl_state.vertexbufferobject = bufferobject;
1124 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1128 static void GL_BindEBO(int bufferobject)
1130 if (gl_state.elementbufferobject != bufferobject)
1132 gl_state.elementbufferobject = bufferobject;
1134 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
1138 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1141 switch(vid.renderpath)
1143 case RENDERPATH_GL11:
1144 case RENDERPATH_GL13:
1145 case RENDERPATH_GL20:
1146 case RENDERPATH_CGGL:
1147 case RENDERPATH_GLES2:
1148 if (!vid.support.ext_framebuffer_object)
1150 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
1151 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
1152 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
1153 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
1154 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
1155 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
1156 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
1158 case RENDERPATH_D3D9:
1159 case RENDERPATH_D3D10:
1160 case RENDERPATH_D3D11:
1162 case RENDERPATH_SOFT:
1168 void R_Mesh_DestroyFramebufferObject(int fbo)
1170 switch(vid.renderpath)
1172 case RENDERPATH_GL11:
1173 case RENDERPATH_GL13:
1174 case RENDERPATH_GL20:
1175 case RENDERPATH_CGGL:
1176 case RENDERPATH_GLES2:
1178 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
1180 case RENDERPATH_D3D9:
1181 case RENDERPATH_D3D10:
1182 case RENDERPATH_D3D11:
1184 case RENDERPATH_SOFT:
1190 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
1192 // 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)
1193 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)
1196 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1197 if (gl_state.d3drt_depthsurface != depthsurface)
1199 gl_state.d3drt_depthsurface = depthsurface;
1200 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1202 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1204 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1205 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1207 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1209 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1210 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1212 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1214 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1215 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1217 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1219 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1220 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1225 void R_Mesh_ResetRenderTargets(void)
1227 switch(vid.renderpath)
1229 case RENDERPATH_GL11:
1230 case RENDERPATH_GL13:
1231 case RENDERPATH_GL20:
1232 case RENDERPATH_CGGL:
1233 case RENDERPATH_GLES2:
1234 if (gl_state.framebufferobject)
1236 gl_state.framebufferobject = 0;
1237 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1240 case RENDERPATH_D3D9:
1242 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1245 case RENDERPATH_D3D10:
1246 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1248 case RENDERPATH_D3D11:
1249 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1251 case RENDERPATH_SOFT:
1252 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1257 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1261 rtexture_t *textures[5];
1262 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1263 textures[4] = depthtexture;
1264 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1265 for (j = 0;j < 5;j++)
1267 for (i = 0;i < vid.teximageunits;i++)
1268 if (gl_state.units[i].texture == textures[j])
1269 R_Mesh_TexBind(i, NULL);
1270 // set up framebuffer object or render targets for the active rendering API
1271 switch(vid.renderpath)
1273 case RENDERPATH_GL11:
1274 case RENDERPATH_GL13:
1275 case RENDERPATH_GL20:
1276 case RENDERPATH_CGGL:
1277 case RENDERPATH_GLES2:
1278 if (gl_state.framebufferobject != fbo)
1280 gl_state.framebufferobject = fbo;
1281 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
1284 case RENDERPATH_D3D9:
1286 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1287 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1290 IDirect3DSurface9 *colorsurfaces[4];
1291 for (i = 0;i < 4;i++)
1293 colorsurfaces[i] = NULL;
1295 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1297 // set the render targets for real
1298 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1299 // release the texture surface levels (they won't be lost while bound...)
1300 for (i = 0;i < 4;i++)
1302 IDirect3DSurface9_Release(colorsurfaces[i]);
1305 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1308 case RENDERPATH_D3D10:
1309 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1311 case RENDERPATH_D3D11:
1312 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1314 case RENDERPATH_SOFT:
1318 unsigned int *pointers[5];
1319 memset(pointers, 0, sizeof(pointers));
1320 for (i = 0;i < 5;i++)
1321 pointers[i] = textures[i] ? (unsigned int *)DPSOFTRAST_Texture_GetPixelPointer(textures[i]->texnum, 0) : NULL;
1322 width = DPSOFTRAST_Texture_GetWidth(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1323 height = DPSOFTRAST_Texture_GetHeight(textures[0] ? textures[0]->texnum : textures[4]->texnum, 0);
1324 DPSOFTRAST_SetRenderTargets(width, height, pointers[4], pointers[0], pointers[1], pointers[2], pointers[3]);
1327 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1333 static int d3dcmpforglfunc(int f)
1337 case GL_NEVER: return D3DCMP_NEVER;
1338 case GL_LESS: return D3DCMP_LESS;
1339 case GL_EQUAL: return D3DCMP_EQUAL;
1340 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1341 case GL_GREATER: return D3DCMP_GREATER;
1342 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1343 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1344 case GL_ALWAYS: return D3DCMP_ALWAYS;
1345 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1349 static int d3dstencilopforglfunc(int f)
1353 case GL_KEEP: return D3DSTENCILOP_KEEP;
1354 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1355 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1356 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1362 static void GL_Backend_ResetState(void)
1365 gl_state.active = true;
1366 gl_state.depthtest = true;
1367 gl_state.alphatest = false;
1368 gl_state.alphafunc = GL_GEQUAL;
1369 gl_state.alphafuncvalue = 0.5f;
1370 gl_state.blendfunc1 = GL_ONE;
1371 gl_state.blendfunc2 = GL_ZERO;
1372 gl_state.blend = false;
1373 gl_state.depthmask = GL_TRUE;
1374 gl_state.colormask = 15;
1375 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1376 gl_state.lockrange_first = 0;
1377 gl_state.lockrange_count = 0;
1378 gl_state.cullface = GL_FRONT;
1379 gl_state.cullfaceenable = false;
1380 gl_state.polygonoffset[0] = 0;
1381 gl_state.polygonoffset[1] = 0;
1382 gl_state.framebufferobject = 0;
1383 gl_state.depthfunc = GL_LEQUAL;
1385 switch(vid.renderpath)
1387 case RENDERPATH_D3D9:
1390 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1391 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
1392 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
1393 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, gl_state.alphafuncvalue * 256.0f, 255));
1394 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1395 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1396 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1397 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1398 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1399 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1403 case RENDERPATH_D3D10:
1404 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1406 case RENDERPATH_D3D11:
1407 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1409 case RENDERPATH_GL20:
1410 case RENDERPATH_CGGL:
1413 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1414 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1415 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1416 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1417 qglDisable(GL_BLEND);CHECKGLERROR
1418 qglCullFace(gl_state.cullface);CHECKGLERROR
1419 qglDisable(GL_CULL_FACE);CHECKGLERROR
1420 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1421 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1422 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1423 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1425 if (vid.support.arb_vertex_buffer_object)
1427 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1428 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1431 if (vid.support.ext_framebuffer_object)
1433 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1434 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1437 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1438 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1440 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1441 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1442 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1444 if (vid.support.ext_framebuffer_object)
1445 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1447 gl_state.unit = MAX_TEXTUREUNITS;
1448 gl_state.clientunit = MAX_TEXTUREUNITS;
1449 for (i = 0;i < vid.teximageunits;i++)
1451 GL_ActiveTexture(i);
1452 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1453 if (vid.support.ext_texture_3d)
1455 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1457 if (vid.support.arb_texture_cube_map)
1459 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1463 for (i = 0;i < vid.texarrayunits;i++)
1465 GL_ClientActiveTexture(i);
1467 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1468 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1472 case RENDERPATH_GL13:
1473 case RENDERPATH_GL11:
1476 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1477 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1478 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1479 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1480 qglDisable(GL_BLEND);CHECKGLERROR
1481 qglCullFace(gl_state.cullface);CHECKGLERROR
1482 qglDisable(GL_CULL_FACE);CHECKGLERROR
1483 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1484 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1485 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1486 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1488 if (vid.support.arb_vertex_buffer_object)
1490 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1491 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1494 if (vid.support.ext_framebuffer_object)
1496 //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1497 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1500 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1501 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1503 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1504 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1505 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1507 if (vid.support.ext_framebuffer_object)
1508 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1510 gl_state.unit = MAX_TEXTUREUNITS;
1511 gl_state.clientunit = MAX_TEXTUREUNITS;
1512 for (i = 0;i < vid.texunits;i++)
1514 GL_ActiveTexture(i);
1515 GL_ClientActiveTexture(i);
1516 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1517 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1518 if (vid.support.ext_texture_3d)
1520 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1521 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1523 if (vid.support.arb_texture_cube_map)
1525 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1526 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1529 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1530 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1531 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1532 qglLoadIdentity();CHECKGLERROR
1533 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1534 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1538 case RENDERPATH_SOFT:
1539 DPSOFTRAST_ColorMask(1,1,1,1);
1540 DPSOFTRAST_AlphaTest(gl_state.alphatest);
1541 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1542 DPSOFTRAST_CullFace(gl_state.cullface);
1543 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1544 DPSOFTRAST_DepthMask(gl_state.depthmask);
1545 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1546 DPSOFTRAST_SetRenderTargets(vid.width, vid.height, vid.softdepthpixels, vid.softpixels, NULL, NULL, NULL);
1547 DPSOFTRAST_Viewport(0, 0, vid.width, vid.height);
1549 case RENDERPATH_GLES2:
1551 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1552 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1553 qglDisable(GL_BLEND);CHECKGLERROR
1554 qglCullFace(gl_state.cullface);CHECKGLERROR
1555 qglDisable(GL_CULL_FACE);CHECKGLERROR
1556 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1557 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1558 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1559 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1560 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1561 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1562 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1563 if (vid.support.ext_framebuffer_object)
1564 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1565 qglEnableVertexAttribArray(GLES2ATTRIB_POSITION);
1566 qglVertexAttribPointer(GLES2ATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1567 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);
1568 qglVertexAttribPointer(GLES2ATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1569 qglVertexAttrib4f(GLES2ATTRIB_COLOR, 1, 1, 1, 1);
1570 gl_state.unit = MAX_TEXTUREUNITS;
1571 gl_state.clientunit = MAX_TEXTUREUNITS;
1572 for (i = 0;i < vid.teximageunits;i++)
1574 GL_ActiveTexture(i);
1575 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1576 if (vid.support.ext_texture_3d)
1578 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1580 if (vid.support.arb_texture_cube_map)
1582 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1585 for (i = 0;i < vid.texarrayunits;i++)
1588 qglVertexAttribPointer(i+GLES2ATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1589 qglDisableVertexAttribArray(i+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
1596 void GL_ActiveTexture(unsigned int num)
1598 if (gl_state.unit != num)
1600 gl_state.unit = num;
1601 switch(vid.renderpath)
1603 case RENDERPATH_GL11:
1604 case RENDERPATH_GL13:
1605 case RENDERPATH_GL20:
1606 case RENDERPATH_CGGL:
1607 case RENDERPATH_GLES2:
1608 if (qglActiveTexture)
1611 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1615 case RENDERPATH_D3D9:
1616 case RENDERPATH_D3D10:
1617 case RENDERPATH_D3D11:
1619 case RENDERPATH_SOFT:
1625 void GL_ClientActiveTexture(unsigned int num)
1627 if (gl_state.clientunit != num)
1629 gl_state.clientunit = num;
1630 switch(vid.renderpath)
1632 case RENDERPATH_GL11:
1633 case RENDERPATH_GL13:
1634 case RENDERPATH_GL20:
1635 case RENDERPATH_CGGL:
1636 if (qglActiveTexture)
1639 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1643 case RENDERPATH_D3D9:
1644 case RENDERPATH_D3D10:
1645 case RENDERPATH_D3D11:
1647 case RENDERPATH_SOFT:
1649 case RENDERPATH_GLES2:
1655 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1657 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1659 qboolean blendenable;
1660 gl_state.blendfunc1 = blendfunc1;
1661 gl_state.blendfunc2 = blendfunc2;
1662 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1663 switch(vid.renderpath)
1665 case RENDERPATH_GL11:
1666 case RENDERPATH_GL13:
1667 case RENDERPATH_GL20:
1668 case RENDERPATH_CGGL:
1669 case RENDERPATH_GLES2:
1671 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1672 if (gl_state.blend != blendenable)
1674 gl_state.blend = blendenable;
1675 if (!gl_state.blend)
1677 qglDisable(GL_BLEND);CHECKGLERROR
1681 qglEnable(GL_BLEND);CHECKGLERROR
1685 case RENDERPATH_D3D9:
1690 D3DBLEND d3dblendfunc[2];
1691 glblendfunc[0] = gl_state.blendfunc1;
1692 glblendfunc[1] = gl_state.blendfunc2;
1693 for (i = 0;i < 2;i++)
1695 switch(glblendfunc[i])
1697 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1698 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1699 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1700 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1701 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1702 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1703 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1704 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1705 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1706 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1709 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1710 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1711 if (gl_state.blend != blendenable)
1713 gl_state.blend = blendenable;
1714 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1719 case RENDERPATH_D3D10:
1720 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1722 case RENDERPATH_D3D11:
1723 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1725 case RENDERPATH_SOFT:
1726 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1732 void GL_DepthMask(int state)
1734 if (gl_state.depthmask != state)
1736 gl_state.depthmask = state;
1737 switch(vid.renderpath)
1739 case RENDERPATH_GL11:
1740 case RENDERPATH_GL13:
1741 case RENDERPATH_GL20:
1742 case RENDERPATH_CGGL:
1743 case RENDERPATH_GLES2:
1745 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1747 case RENDERPATH_D3D9:
1749 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1752 case RENDERPATH_D3D10:
1753 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1755 case RENDERPATH_D3D11:
1756 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1758 case RENDERPATH_SOFT:
1759 DPSOFTRAST_DepthMask(gl_state.depthmask);
1765 void GL_DepthTest(int state)
1767 if (gl_state.depthtest != state)
1769 gl_state.depthtest = state;
1770 switch(vid.renderpath)
1772 case RENDERPATH_GL11:
1773 case RENDERPATH_GL13:
1774 case RENDERPATH_GL20:
1775 case RENDERPATH_CGGL:
1776 case RENDERPATH_GLES2:
1778 if (gl_state.depthtest)
1780 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1784 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1787 case RENDERPATH_D3D9:
1789 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1792 case RENDERPATH_D3D10:
1793 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1795 case RENDERPATH_D3D11:
1796 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1798 case RENDERPATH_SOFT:
1799 DPSOFTRAST_DepthTest(gl_state.depthtest);
1805 void GL_DepthFunc(int state)
1807 if (gl_state.depthfunc != state)
1809 gl_state.depthfunc = state;
1810 switch(vid.renderpath)
1812 case RENDERPATH_GL11:
1813 case RENDERPATH_GL13:
1814 case RENDERPATH_GL20:
1815 case RENDERPATH_CGGL:
1816 case RENDERPATH_GLES2:
1818 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1820 case RENDERPATH_D3D9:
1822 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1825 case RENDERPATH_D3D10:
1826 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1828 case RENDERPATH_D3D11:
1829 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1831 case RENDERPATH_SOFT:
1832 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1838 void GL_DepthRange(float nearfrac, float farfrac)
1840 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1842 gl_state.depthrange[0] = nearfrac;
1843 gl_state.depthrange[1] = farfrac;
1844 switch(vid.renderpath)
1846 case RENDERPATH_GL11:
1847 case RENDERPATH_GL13:
1848 case RENDERPATH_GL20:
1849 case RENDERPATH_CGGL:
1850 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1852 case RENDERPATH_D3D9:
1855 D3DVIEWPORT9 d3dviewport;
1856 d3dviewport.X = gl_viewport.x;
1857 d3dviewport.Y = gl_viewport.y;
1858 d3dviewport.Width = gl_viewport.width;
1859 d3dviewport.Height = gl_viewport.height;
1860 d3dviewport.MinZ = gl_state.depthrange[0];
1861 d3dviewport.MaxZ = gl_state.depthrange[1];
1862 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1866 case RENDERPATH_D3D10:
1867 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1869 case RENDERPATH_D3D11:
1870 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1872 case RENDERPATH_SOFT:
1873 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1875 case RENDERPATH_GLES2:
1876 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1877 // FIXME: qglDepthRangef instead... faster...
1878 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1884 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)
1886 switch (vid.renderpath)
1888 case RENDERPATH_GL11:
1889 case RENDERPATH_GL13:
1890 case RENDERPATH_GL20:
1891 case RENDERPATH_CGGL:
1895 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1899 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1901 if (vid.support.ati_separate_stencil)
1903 qglStencilMask(writemask);CHECKGLERROR
1904 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1905 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1906 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1908 else if (vid.support.ext_stencil_two_side)
1910 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1911 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1912 qglStencilMask(writemask);CHECKGLERROR
1913 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1914 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1915 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1916 qglStencilMask(writemask);CHECKGLERROR
1917 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1918 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1921 case RENDERPATH_D3D9:
1923 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1924 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1925 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1926 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1927 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1928 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1929 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1930 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1931 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1932 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1933 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1934 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1935 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1938 case RENDERPATH_D3D10:
1939 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1941 case RENDERPATH_D3D11:
1942 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1944 case RENDERPATH_SOFT:
1945 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1947 case RENDERPATH_GLES2:
1948 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1953 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1955 switch (vid.renderpath)
1957 case RENDERPATH_GL11:
1958 case RENDERPATH_GL13:
1959 case RENDERPATH_GL20:
1960 case RENDERPATH_CGGL:
1961 case RENDERPATH_GLES2:
1965 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1969 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1971 if (vid.support.ext_stencil_two_side)
1973 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1975 qglStencilMask(writemask);CHECKGLERROR
1976 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1977 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1980 case RENDERPATH_D3D9:
1982 if (vid.support.ati_separate_stencil)
1983 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1984 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1985 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1986 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1987 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1988 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1989 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1990 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1991 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1994 case RENDERPATH_D3D10:
1995 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1997 case RENDERPATH_D3D11:
1998 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2000 case RENDERPATH_SOFT:
2001 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2006 void GL_PolygonOffset(float planeoffset, float depthoffset)
2008 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2010 gl_state.polygonoffset[0] = planeoffset;
2011 gl_state.polygonoffset[1] = depthoffset;
2012 switch(vid.renderpath)
2014 case RENDERPATH_GL11:
2015 case RENDERPATH_GL13:
2016 case RENDERPATH_GL20:
2017 case RENDERPATH_CGGL:
2018 case RENDERPATH_GLES2:
2019 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2021 case RENDERPATH_D3D9:
2023 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2024 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2027 case RENDERPATH_D3D10:
2028 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2030 case RENDERPATH_D3D11:
2031 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2033 case RENDERPATH_SOFT:
2034 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2040 void GL_SetMirrorState(qboolean state)
2042 if (v_flipped_state != state)
2044 v_flipped_state = state;
2045 if (gl_state.cullface == GL_BACK)
2046 gl_state.cullface = GL_FRONT;
2047 else if (gl_state.cullface == GL_FRONT)
2048 gl_state.cullface = GL_BACK;
2051 switch(vid.renderpath)
2053 case RENDERPATH_GL11:
2054 case RENDERPATH_GL13:
2055 case RENDERPATH_GL20:
2056 case RENDERPATH_CGGL:
2057 case RENDERPATH_GLES2:
2058 qglCullFace(gl_state.cullface);CHECKGLERROR
2060 case RENDERPATH_D3D9:
2062 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2065 case RENDERPATH_D3D10:
2066 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2068 case RENDERPATH_D3D11:
2069 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2071 case RENDERPATH_SOFT:
2072 DPSOFTRAST_CullFace(gl_state.cullface);
2078 void GL_CullFace(int state)
2082 if(state == GL_FRONT)
2084 else if(state == GL_BACK)
2088 switch(vid.renderpath)
2090 case RENDERPATH_GL11:
2091 case RENDERPATH_GL13:
2092 case RENDERPATH_GL20:
2093 case RENDERPATH_CGGL:
2094 case RENDERPATH_GLES2:
2097 if (state != GL_NONE)
2099 if (!gl_state.cullfaceenable)
2101 gl_state.cullfaceenable = true;
2102 qglEnable(GL_CULL_FACE);CHECKGLERROR
2104 if (gl_state.cullface != state)
2106 gl_state.cullface = state;
2107 qglCullFace(gl_state.cullface);CHECKGLERROR
2112 if (gl_state.cullfaceenable)
2114 gl_state.cullfaceenable = false;
2115 qglDisable(GL_CULL_FACE);CHECKGLERROR
2119 case RENDERPATH_D3D9:
2121 if (gl_state.cullface != state)
2123 gl_state.cullface = state;
2124 switch(gl_state.cullface)
2127 gl_state.cullfaceenable = false;
2128 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2131 gl_state.cullfaceenable = true;
2132 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2135 gl_state.cullfaceenable = true;
2136 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2142 case RENDERPATH_D3D10:
2143 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2145 case RENDERPATH_D3D11:
2146 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2148 case RENDERPATH_SOFT:
2149 if (gl_state.cullface != state)
2151 gl_state.cullface = state;
2152 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2153 DPSOFTRAST_CullFace(gl_state.cullface);
2159 void GL_AlphaTest(int state)
2161 if (gl_state.alphatest != state)
2163 gl_state.alphatest = state;
2164 switch(vid.renderpath)
2166 case RENDERPATH_GL11:
2167 case RENDERPATH_GL13:
2168 case RENDERPATH_GL20:
2169 case RENDERPATH_CGGL:
2171 if (gl_state.alphatest)
2173 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2177 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2180 case RENDERPATH_D3D9:
2182 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
2185 case RENDERPATH_D3D10:
2186 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2188 case RENDERPATH_D3D11:
2189 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2191 case RENDERPATH_SOFT:
2192 DPSOFTRAST_AlphaTest(gl_state.alphatest);
2194 case RENDERPATH_GLES2:
2200 void GL_AlphaFunc(int state, float value)
2202 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
2204 gl_state.alphafunc = state;
2205 gl_state.alphafuncvalue = value;
2206 switch(vid.renderpath)
2208 case RENDERPATH_GL11:
2209 case RENDERPATH_GL13:
2210 case RENDERPATH_GL20:
2211 case RENDERPATH_CGGL:
2213 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
2215 case RENDERPATH_D3D9:
2217 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
2218 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
2221 case RENDERPATH_D3D10:
2222 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2224 case RENDERPATH_D3D11:
2225 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2227 case RENDERPATH_SOFT:
2228 DPSOFTRAST_AlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);
2230 case RENDERPATH_GLES2:
2236 void GL_ColorMask(int r, int g, int b, int a)
2238 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2239 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2240 if (gl_state.colormask != state)
2242 gl_state.colormask = state;
2243 switch(vid.renderpath)
2245 case RENDERPATH_GL11:
2246 case RENDERPATH_GL13:
2247 case RENDERPATH_GL20:
2248 case RENDERPATH_CGGL:
2249 case RENDERPATH_GLES2:
2251 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2253 case RENDERPATH_D3D9:
2255 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2258 case RENDERPATH_D3D10:
2259 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2261 case RENDERPATH_D3D11:
2262 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2264 case RENDERPATH_SOFT:
2265 DPSOFTRAST_ColorMask(r, g, b, a);
2271 void GL_Color(float cr, float cg, float cb, float ca)
2273 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)
2275 gl_state.color4f[0] = cr;
2276 gl_state.color4f[1] = cg;
2277 gl_state.color4f[2] = cb;
2278 gl_state.color4f[3] = ca;
2279 switch(vid.renderpath)
2281 case RENDERPATH_GL11:
2282 case RENDERPATH_GL13:
2283 case RENDERPATH_GL20:
2284 case RENDERPATH_CGGL:
2286 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2289 case RENDERPATH_D3D9:
2290 case RENDERPATH_D3D10:
2291 case RENDERPATH_D3D11:
2292 // no equivalent in D3D
2294 case RENDERPATH_SOFT:
2295 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2297 case RENDERPATH_GLES2:
2298 qglVertexAttrib4f(GLES2ATTRIB_COLOR, cr, cg, cb, ca);
2304 void GL_Scissor (int x, int y, int width, int height)
2306 switch(vid.renderpath)
2308 case RENDERPATH_GL11:
2309 case RENDERPATH_GL13:
2310 case RENDERPATH_GL20:
2311 case RENDERPATH_CGGL:
2312 case RENDERPATH_GLES2:
2314 qglScissor(x, y,width,height);
2317 case RENDERPATH_D3D9:
2323 d3drect.right = x + width;
2324 d3drect.bottom = y + height;
2325 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2329 case RENDERPATH_D3D10:
2330 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2332 case RENDERPATH_D3D11:
2333 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2335 case RENDERPATH_SOFT:
2336 DPSOFTRAST_Scissor(x, y, width, height);
2341 void GL_ScissorTest(int state)
2343 if (gl_state.scissortest != state)
2345 gl_state.scissortest = state;
2346 switch(vid.renderpath)
2348 case RENDERPATH_GL11:
2349 case RENDERPATH_GL13:
2350 case RENDERPATH_GL20:
2351 case RENDERPATH_CGGL:
2352 case RENDERPATH_GLES2:
2354 if(gl_state.scissortest)
2355 qglEnable(GL_SCISSOR_TEST);
2357 qglDisable(GL_SCISSOR_TEST);
2360 case RENDERPATH_D3D9:
2362 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2365 case RENDERPATH_D3D10:
2366 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2368 case RENDERPATH_D3D11:
2369 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2371 case RENDERPATH_SOFT:
2372 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2378 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2380 static const float blackcolor[4] = {0, 0, 0, 0};
2381 // prevent warnings when trying to clear a buffer that does not exist
2383 colorvalue = blackcolor;
2386 mask &= ~GL_STENCIL_BUFFER_BIT;
2389 switch(vid.renderpath)
2391 case RENDERPATH_GL11:
2392 case RENDERPATH_GL13:
2393 case RENDERPATH_GL20:
2394 case RENDERPATH_CGGL:
2395 case RENDERPATH_GLES2:
2397 if (mask & GL_COLOR_BUFFER_BIT)
2399 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2401 if (mask & GL_DEPTH_BUFFER_BIT)
2403 qglClearDepth(depthvalue);CHECKGLERROR
2405 if (mask & GL_STENCIL_BUFFER_BIT)
2407 qglClearStencil(stencilvalue);CHECKGLERROR
2409 qglClear(mask);CHECKGLERROR
2411 case RENDERPATH_D3D9:
2413 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);
2416 case RENDERPATH_D3D10:
2417 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2419 case RENDERPATH_D3D11:
2420 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2422 case RENDERPATH_SOFT:
2423 if (mask & GL_COLOR_BUFFER_BIT)
2424 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2425 if (mask & GL_DEPTH_BUFFER_BIT)
2426 DPSOFTRAST_ClearDepth(depthvalue);
2431 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2433 switch(vid.renderpath)
2435 case RENDERPATH_GL11:
2436 case RENDERPATH_GL13:
2437 case RENDERPATH_GL20:
2438 case RENDERPATH_CGGL:
2439 case RENDERPATH_GLES2:
2441 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2443 case RENDERPATH_D3D9:
2446 // LordHavoc: we can't directly download the backbuffer because it may be
2447 // multisampled, and it may not be lockable, so we blit it to a lockable
2448 // surface of the same dimensions (but without multisample) to resolve the
2449 // multisample buffer to a normal image, and then lock that...
2450 IDirect3DSurface9 *stretchsurface = NULL;
2451 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2453 D3DLOCKED_RECT lockedrect;
2454 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2456 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2459 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2460 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2461 memcpy(outpixels + line * width * 4, row, width * 4);
2462 IDirect3DSurface9_UnlockRect(stretchsurface);
2465 IDirect3DSurface9_Release(stretchsurface);
2468 //IDirect3DSurface9 *syssurface = NULL;
2469 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2470 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2471 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2472 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2473 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2474 //IDirect3DSurface9_UnlockRect(syssurface);
2475 //IDirect3DSurface9_Release(syssurface);
2479 case RENDERPATH_D3D10:
2480 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2482 case RENDERPATH_D3D11:
2483 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2485 case RENDERPATH_SOFT:
2486 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2491 // called at beginning of frame
2492 void R_Mesh_Start(void)
2495 R_Mesh_ResetRenderTargets();
2497 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2499 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2500 Cvar_SetValueQuick(&gl_paranoid, 1);
2504 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2508 char compilelog[MAX_INPUTLINE];
2509 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2512 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2513 qglCompileShader(shaderobject);CHECKGLERROR
2514 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2515 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2516 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2518 int i, j, pretextlines = 0;
2519 for (i = 0;i < numstrings - 1;i++)
2520 for (j = 0;strings[i][j];j++)
2521 if (strings[i][j] == '\n')
2523 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2525 if (!shadercompiled)
2527 qglDeleteShader(shaderobject);CHECKGLERROR
2530 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2531 qglDeleteShader(shaderobject);CHECKGLERROR
2535 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)
2537 GLint programlinked;
2538 GLuint programobject = 0;
2539 char linklog[MAX_INPUTLINE];
2542 programobject = qglCreateProgram();CHECKGLERROR
2546 if (vid.renderpath == RENDERPATH_GLES2)
2548 qglBindAttribLocation(programobject, GLES2ATTRIB_POSITION , "Attrib_Position" );
2549 qglBindAttribLocation(programobject, GLES2ATTRIB_COLOR , "Attrib_Color" );
2550 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD0, "Attrib_TexCoord0");
2551 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD1, "Attrib_TexCoord1");
2552 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD2, "Attrib_TexCoord2");
2553 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD3, "Attrib_TexCoord3");
2554 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD4, "Attrib_TexCoord4");
2555 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD5, "Attrib_TexCoord5");
2556 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD6, "Attrib_TexCoord6");
2557 qglBindAttribLocation(programobject, GLES2ATTRIB_TEXCOORD7, "Attrib_TexCoord7");
2560 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2563 #ifdef GL_GEOMETRY_SHADER
2564 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2568 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2571 qglLinkProgram(programobject);CHECKGLERROR
2572 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2573 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2576 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2577 Con_DPrintf("program link log:\n%s\n", linklog);
2578 // software vertex shader is ok but software fragment shader is WAY
2579 // too slow, fail program if so.
2580 // NOTE: this string might be ATI specific, but that's ok because the
2581 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2582 // software fragment shader due to low instruction and dependent
2584 if (strstr(linklog, "fragment shader will run in software"))
2585 programlinked = false;
2589 return programobject;
2591 qglDeleteProgram(programobject);CHECKGLERROR
2595 void GL_Backend_FreeProgram(unsigned int prog)
2598 qglDeleteProgram(prog);
2602 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2607 for (i = 0;i < count;i++)
2608 *out++ = *in++ + offset;
2611 memcpy(out, in, sizeof(*out) * count);
2614 // renders triangles using vertices from the active arrays
2615 int paranoidblah = 0;
2616 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)
2618 unsigned int numelements = numtriangles * 3;
2620 size_t bufferoffset3i;
2622 size_t bufferoffset3s;
2623 if (numvertices < 3 || numtriangles < 1)
2625 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2626 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);
2629 if (!gl_mesh_prefer_short_elements.integer)
2633 if (element3i_indexbuffer)
2634 element3i_indexbuffer = NULL;
2636 // adjust the pointers for firsttriangle
2638 element3i += firsttriangle * 3;
2639 if (element3i_indexbuffer)
2640 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2642 element3s += firsttriangle * 3;
2643 if (element3s_indexbuffer)
2644 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2645 switch(vid.renderpath)
2647 case RENDERPATH_GL11:
2648 case RENDERPATH_GL13:
2649 case RENDERPATH_GL20:
2650 case RENDERPATH_CGGL:
2651 case RENDERPATH_GLES2:
2652 // check if the user specified to ignore static index buffers
2653 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2655 element3i_indexbuffer = NULL;
2656 element3s_indexbuffer = NULL;
2659 case RENDERPATH_D3D9:
2660 case RENDERPATH_D3D10:
2661 case RENDERPATH_D3D11:
2663 case RENDERPATH_SOFT:
2666 // upload a dynamic index buffer if needed
2669 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2671 if (gl_state.draw_dynamicindexbuffer)
2672 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2674 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2675 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2676 element3s_bufferoffset = 0;
2681 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2683 if (gl_state.draw_dynamicindexbuffer)
2684 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2686 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2687 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2688 element3i_bufferoffset = 0;
2691 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2692 bufferoffset3i = element3i_bufferoffset;
2693 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2694 bufferoffset3s = element3s_bufferoffset;
2695 r_refdef.stats.draws++;
2696 r_refdef.stats.draws_vertices += numvertices;
2697 r_refdef.stats.draws_elements += numelements;
2698 if (gl_paranoid.integer)
2701 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2703 unsigned int j, size;
2705 // note: there's no validation done here on buffer objects because it
2706 // is somewhat difficult to get at the data, and gl_paranoid can be
2707 // used without buffer objects if the need arises
2708 // (the data could be gotten using glMapBuffer but it would be very
2709 // slow due to uncachable video memory reads)
2710 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2711 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2713 if (gl_state.pointer_vertex_pointer)
2714 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2716 if (gl_state.pointer_color_enabled)
2718 if (!qglIsEnabled(GL_COLOR_ARRAY))
2719 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2721 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2722 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2725 for (i = 0;i < vid.texarrayunits;i++)
2727 if (gl_state.units[i].arrayenabled)
2729 GL_ClientActiveTexture(i);
2730 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2731 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2733 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2734 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++)
2741 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2743 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2745 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2752 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2754 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2756 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2762 if (r_render.integer || r_refdef.draw2dstage)
2764 switch(vid.renderpath)
2766 case RENDERPATH_GL11:
2767 case RENDERPATH_GL13:
2768 case RENDERPATH_GL20:
2769 case RENDERPATH_CGGL:
2771 if (gl_mesh_testmanualfeeding.integer)
2773 unsigned int i, j, element;
2775 qglBegin(GL_TRIANGLES);
2776 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2779 element = element3i[i];
2781 element = element3s[i];
2783 element = firstvertex + i;
2784 for (j = 0;j < vid.texarrayunits;j++)
2786 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2788 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2790 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2791 if (vid.texarrayunits > 1)
2793 if (gl_state.units[j].pointer_texcoord_components == 4)
2794 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2795 else if (gl_state.units[j].pointer_texcoord_components == 3)
2796 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2797 else if (gl_state.units[j].pointer_texcoord_components == 2)
2798 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2800 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2804 if (gl_state.units[j].pointer_texcoord_components == 4)
2805 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2806 else if (gl_state.units[j].pointer_texcoord_components == 3)
2807 qglTexCoord3f(p[0], p[1], p[2]);
2808 else if (gl_state.units[j].pointer_texcoord_components == 2)
2809 qglTexCoord2f(p[0], p[1]);
2811 qglTexCoord1f(p[0]);
2814 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2816 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2817 if (vid.texarrayunits > 1)
2819 if (gl_state.units[j].pointer_texcoord_components == 4)
2820 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2821 else if (gl_state.units[j].pointer_texcoord_components == 3)
2822 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2823 else if (gl_state.units[j].pointer_texcoord_components == 2)
2824 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2825 else if (gl_state.units[j].pointer_texcoord_components == 1)
2826 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2830 if (gl_state.units[j].pointer_texcoord_components == 4)
2831 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2832 else if (gl_state.units[j].pointer_texcoord_components == 3)
2833 qglTexCoord3f(s[0], s[1], s[2]);
2834 else if (gl_state.units[j].pointer_texcoord_components == 2)
2835 qglTexCoord2f(s[0], s[1]);
2836 else if (gl_state.units[j].pointer_texcoord_components == 1)
2837 qglTexCoord1f(s[0]);
2840 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2842 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2843 if (vid.texarrayunits > 1)
2845 if (gl_state.units[j].pointer_texcoord_components == 4)
2846 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2847 else if (gl_state.units[j].pointer_texcoord_components == 3)
2848 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2849 else if (gl_state.units[j].pointer_texcoord_components == 2)
2850 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2851 else if (gl_state.units[j].pointer_texcoord_components == 1)
2852 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2856 if (gl_state.units[j].pointer_texcoord_components == 4)
2857 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2858 else if (gl_state.units[j].pointer_texcoord_components == 3)
2859 qglTexCoord3f(sb[0], sb[1], sb[2]);
2860 else if (gl_state.units[j].pointer_texcoord_components == 2)
2861 qglTexCoord2f(sb[0], sb[1]);
2862 else if (gl_state.units[j].pointer_texcoord_components == 1)
2863 qglTexCoord1f(sb[0]);
2868 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2870 if (gl_state.pointer_color_gltype == GL_FLOAT)
2872 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2873 qglColor4f(p[0], p[1], p[2], p[3]);
2875 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2877 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2878 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2881 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2883 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2884 if (gl_state.pointer_vertex_components == 4)
2885 qglVertex4f(p[0], p[1], p[2], p[3]);
2886 else if (gl_state.pointer_vertex_components == 3)
2887 qglVertex3f(p[0], p[1], p[2]);
2889 qglVertex2f(p[0], p[1]);
2895 else if (bufferobject3s)
2897 GL_BindEBO(bufferobject3s);
2898 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2900 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2905 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2909 else if (bufferobject3i)
2911 GL_BindEBO(bufferobject3i);
2912 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2914 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2919 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2926 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2928 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2933 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2940 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2942 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2947 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2953 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2957 case RENDERPATH_D3D9:
2959 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2961 if (element3s_indexbuffer)
2963 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2964 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2966 else if (element3i_indexbuffer)
2968 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2969 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2972 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2977 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2979 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2981 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2985 case RENDERPATH_D3D10:
2986 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2988 case RENDERPATH_D3D11:
2989 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2991 case RENDERPATH_SOFT:
2992 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
2994 case RENDERPATH_GLES2:
2995 // GLES does not have glDrawRangeElements, and generally
2996 // underperforms with index buffers, so this code path is
2997 // relatively straightforward...
2999 if (gl_paranoid.integer)
3001 int r, prog, enabled, i;
3002 GLsizei attriblength;
3005 GLchar attribname[1024];
3006 r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
3007 if (r != GL_FRAMEBUFFER_COMPLETE_EXT)
3008 Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
3009 #ifndef GL_CURRENT_PROGRAM
3010 #define GL_CURRENT_PROGRAM 0x8B8D
3012 qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR
3013 if (r < 0 || r > 10000)
3014 Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r);
3016 for (i = 0;i < 8;i++)
3018 qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR
3021 qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR
3022 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);
3028 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
3033 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
3038 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3046 // restores backend state, used when done with 3D rendering
3047 void R_Mesh_Finish(void)
3049 R_Mesh_ResetRenderTargets();
3052 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3054 r_meshbuffer_t *buffer;
3055 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3057 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3058 memset(buffer, 0, sizeof(*buffer));
3059 buffer->bufferobject = 0;
3060 buffer->devicebuffer = NULL;
3062 buffer->isindexbuffer = isindexbuffer;
3063 buffer->isdynamic = isdynamic;
3064 buffer->isindex16 = isindex16;
3065 strlcpy(buffer->name, name, sizeof(buffer->name));
3066 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3070 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3074 if (buffer->isindexbuffer)
3076 r_refdef.stats.indexbufferuploadcount++;
3077 r_refdef.stats.indexbufferuploadsize += size;
3081 r_refdef.stats.vertexbufferuploadcount++;
3082 r_refdef.stats.vertexbufferuploadsize += size;
3084 switch(vid.renderpath)
3086 case RENDERPATH_GL11:
3087 case RENDERPATH_GL13:
3088 case RENDERPATH_GL20:
3089 case RENDERPATH_CGGL:
3090 case RENDERPATH_GLES2:
3091 if (!buffer->bufferobject)
3092 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3093 if (buffer->isindexbuffer)
3094 GL_BindEBO(buffer->bufferobject);
3096 GL_BindVBO(buffer->bufferobject);
3097 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
3099 case RENDERPATH_D3D9:
3103 void *datapointer = NULL;
3104 if (buffer->isindexbuffer)
3106 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3107 if (size > buffer->size || !buffer->devicebuffer)
3109 if (buffer->devicebuffer)
3110 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3111 buffer->devicebuffer = NULL;
3112 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)))
3113 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);
3114 buffer->devicebuffer = (void *)d3d9indexbuffer;
3115 buffer->size = size;
3117 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3120 memcpy(datapointer, data, size);
3122 memset(datapointer, 0, size);
3123 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3128 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3129 if (size > buffer->size || !buffer->devicebuffer)
3131 if (buffer->devicebuffer)
3132 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3133 buffer->devicebuffer = NULL;
3134 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3135 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);
3136 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3137 buffer->size = size;
3139 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3142 memcpy(datapointer, data, size);
3144 memset(datapointer, 0, size);
3145 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3151 case RENDERPATH_D3D10:
3152 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3154 case RENDERPATH_D3D11:
3155 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3157 case RENDERPATH_SOFT:
3162 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3166 switch(vid.renderpath)
3168 case RENDERPATH_GL11:
3169 case RENDERPATH_GL13:
3170 case RENDERPATH_GL20:
3171 case RENDERPATH_CGGL:
3172 case RENDERPATH_GLES2:
3173 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3175 case RENDERPATH_D3D9:
3177 if (gl_state.d3dvertexbuffer == (void *)buffer)
3178 gl_state.d3dvertexbuffer = NULL;
3179 if (buffer->devicebuffer)
3181 if (buffer->isindexbuffer)
3182 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3184 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3185 buffer->devicebuffer = NULL;
3189 case RENDERPATH_D3D10:
3190 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3192 case RENDERPATH_D3D11:
3193 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3195 case RENDERPATH_SOFT:
3198 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3201 void GL_Mesh_ListVBOs(qboolean printeach)
3204 size_t ebocount = 0, ebomemory = 0;
3205 size_t vbocount = 0, vbomemory = 0;
3206 r_meshbuffer_t *buffer;
3207 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3208 for (i = 0;i < endindex;i++)
3210 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3213 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)");}
3214 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)");}
3216 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);
3221 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3223 switch(vid.renderpath)
3225 case RENDERPATH_GL11:
3226 case RENDERPATH_GL13:
3227 case RENDERPATH_GL20:
3228 case RENDERPATH_CGGL:
3229 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)
3231 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3232 gl_state.pointer_vertex_components = components;
3233 gl_state.pointer_vertex_gltype = gltype;
3234 gl_state.pointer_vertex_stride = stride;
3235 gl_state.pointer_vertex_pointer = pointer;
3236 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3237 gl_state.pointer_vertex_offset = bufferoffset;
3239 GL_BindVBO(bufferobject);
3240 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3243 case RENDERPATH_GLES2:
3244 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)
3246 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3247 gl_state.pointer_vertex_components = components;
3248 gl_state.pointer_vertex_gltype = gltype;
3249 gl_state.pointer_vertex_stride = stride;
3250 gl_state.pointer_vertex_pointer = pointer;
3251 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3252 gl_state.pointer_vertex_offset = bufferoffset;
3254 GL_BindVBO(bufferobject);
3255 qglVertexAttribPointer(GLES2ATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3258 case RENDERPATH_D3D9:
3259 case RENDERPATH_D3D10:
3260 case RENDERPATH_D3D11:
3261 case RENDERPATH_SOFT:
3266 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3268 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3269 // the pointer only.
3270 switch(vid.renderpath)
3272 case RENDERPATH_GL11:
3273 case RENDERPATH_GL13:
3274 case RENDERPATH_GL20:
3275 case RENDERPATH_CGGL:
3279 // caller wants color array enabled
3280 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3281 if (!gl_state.pointer_color_enabled)
3283 gl_state.pointer_color_enabled = true;
3285 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3287 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)
3289 gl_state.pointer_color_components = components;
3290 gl_state.pointer_color_gltype = gltype;
3291 gl_state.pointer_color_stride = stride;
3292 gl_state.pointer_color_pointer = pointer;
3293 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3294 gl_state.pointer_color_offset = bufferoffset;
3296 GL_BindVBO(bufferobject);
3297 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3302 // caller wants color array disabled
3303 if (gl_state.pointer_color_enabled)
3305 gl_state.pointer_color_enabled = false;
3307 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3308 // when color array is on the glColor gets trashed, set it again
3309 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3313 case RENDERPATH_GLES2:
3317 // caller wants color array enabled
3318 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3319 if (!gl_state.pointer_color_enabled)
3321 gl_state.pointer_color_enabled = true;
3323 qglEnableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3325 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)
3327 gl_state.pointer_color_components = components;
3328 gl_state.pointer_color_gltype = gltype;
3329 gl_state.pointer_color_stride = stride;
3330 gl_state.pointer_color_pointer = pointer;
3331 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3332 gl_state.pointer_color_offset = bufferoffset;
3334 GL_BindVBO(bufferobject);
3335 qglVertexAttribPointer(GLES2ATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3340 // caller wants color array disabled
3341 if (gl_state.pointer_color_enabled)
3343 gl_state.pointer_color_enabled = false;
3345 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3346 // when color array is on the glColor gets trashed, set it again
3347 qglVertexAttrib4f(GLES2ATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3351 case RENDERPATH_D3D9:
3352 case RENDERPATH_D3D10:
3353 case RENDERPATH_D3D11:
3354 case RENDERPATH_SOFT:
3359 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)
3361 gltextureunit_t *unit = gl_state.units + unitnum;
3362 // update array settings
3363 // note: there is no need to check bufferobject here because all cases
3364 // that involve a valid bufferobject also supply a texcoord array
3365 switch(vid.renderpath)
3367 case RENDERPATH_GL11:
3368 case RENDERPATH_GL13:
3369 case RENDERPATH_GL20:
3370 case RENDERPATH_CGGL:
3374 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3375 // texture array unit is enabled, enable the array
3376 if (!unit->arrayenabled)
3378 unit->arrayenabled = true;
3379 GL_ClientActiveTexture(unitnum);
3380 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3383 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)
3385 unit->pointer_texcoord_components = components;
3386 unit->pointer_texcoord_gltype = gltype;
3387 unit->pointer_texcoord_stride = stride;
3388 unit->pointer_texcoord_pointer = pointer;
3389 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3390 unit->pointer_texcoord_offset = bufferoffset;
3391 GL_ClientActiveTexture(unitnum);
3392 GL_BindVBO(bufferobject);
3393 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3398 // texture array unit is disabled, disable the array
3399 if (unit->arrayenabled)
3401 unit->arrayenabled = false;
3402 GL_ClientActiveTexture(unitnum);
3403 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3407 case RENDERPATH_GLES2:
3411 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3412 // texture array unit is enabled, enable the array
3413 if (!unit->arrayenabled)
3415 unit->arrayenabled = true;
3416 qglEnableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3419 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)
3421 unit->pointer_texcoord_components = components;
3422 unit->pointer_texcoord_gltype = gltype;
3423 unit->pointer_texcoord_stride = stride;
3424 unit->pointer_texcoord_pointer = pointer;
3425 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3426 unit->pointer_texcoord_offset = bufferoffset;
3427 GL_BindVBO(bufferobject);
3428 qglVertexAttribPointer(unitnum+GLES2ATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3433 // texture array unit is disabled, disable the array
3434 if (unit->arrayenabled)
3436 unit->arrayenabled = false;
3437 qglDisableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3441 case RENDERPATH_D3D9:
3442 case RENDERPATH_D3D10:
3443 case RENDERPATH_D3D11:
3444 case RENDERPATH_SOFT:
3449 int R_Mesh_TexBound(unsigned int unitnum, int id)
3451 gltextureunit_t *unit = gl_state.units + unitnum;
3452 if (unitnum >= vid.teximageunits)
3454 if (id == GL_TEXTURE_2D)
3456 if (id == GL_TEXTURE_3D)
3458 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3459 return unit->tcubemap;
3463 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3465 switch(vid.renderpath)
3467 case RENDERPATH_GL11:
3468 case RENDERPATH_GL13:
3469 case RENDERPATH_GL20:
3470 case RENDERPATH_CGGL:
3471 case RENDERPATH_GLES2:
3472 R_Mesh_TexBind(0, tex);
3473 GL_ActiveTexture(0);CHECKGLERROR
3474 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3476 case RENDERPATH_D3D9:
3479 IDirect3DSurface9 *currentsurface = NULL;
3480 IDirect3DSurface9 *texturesurface = NULL;
3483 sourcerect.left = sx;
3484 sourcerect.top = sy;
3485 sourcerect.right = sx + width;
3486 sourcerect.bottom = sy + height;
3489 destrect.right = tx + width;
3490 destrect.bottom = ty + height;
3491 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3493 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3495 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3496 IDirect3DSurface9_Release(currentsurface);
3498 IDirect3DSurface9_Release(texturesurface);
3503 case RENDERPATH_D3D10:
3504 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3506 case RENDERPATH_D3D11:
3507 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3509 case RENDERPATH_SOFT:
3510 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3516 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};
3519 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3521 gltextureunit_t *unit = gl_state.units + unitnum;
3522 int tex2d, tex3d, texcubemap, texnum;
3523 if (unitnum >= vid.teximageunits)
3525 // if (unit->texture == tex)
3527 switch(vid.renderpath)
3529 case RENDERPATH_GL20:
3530 case RENDERPATH_CGGL:
3531 case RENDERPATH_GLES2:
3534 tex = r_texture_white;
3535 // not initialized enough yet...
3539 unit->texture = tex;
3540 texnum = R_GetTexture(tex);
3541 switch(tex->gltexturetypeenum)
3543 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3544 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3545 case GL_TEXTURE_CUBE_MAP_ARB: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR}break;
3548 case RENDERPATH_GL13:
3549 case RENDERPATH_GL11:
3550 unit->texture = tex;
3556 texnum = R_GetTexture(tex);
3557 switch(tex->gltexturetypeenum)
3565 case GL_TEXTURE_CUBE_MAP_ARB:
3566 texcubemap = texnum;
3570 // update 2d texture binding
3571 if (unit->t2d != tex2d)
3573 GL_ActiveTexture(unitnum);
3578 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3585 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3589 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3591 // update 3d texture binding
3592 if (unit->t3d != tex3d)
3594 GL_ActiveTexture(unitnum);
3599 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3606 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3610 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3612 // update cubemap texture binding
3613 if (unit->tcubemap != texcubemap)
3615 GL_ActiveTexture(unitnum);
3618 if (unit->tcubemap == 0)
3620 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3627 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3630 unit->tcubemap = texcubemap;
3631 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3634 case RENDERPATH_D3D9:
3637 extern cvar_t gl_texture_anisotropy;
3640 tex = r_texture_white;
3641 // not initialized enough yet...
3645 // upload texture if needed
3647 if (unit->texture == tex)
3649 unit->texture = tex;
3650 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3651 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3652 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3653 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3654 if (tex->d3daddressw)
3655 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3656 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3657 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3658 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3659 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3660 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3661 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3665 case RENDERPATH_D3D10:
3666 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3668 case RENDERPATH_D3D11:
3669 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3671 case RENDERPATH_SOFT:
3674 tex = r_texture_white;
3675 // not initialized enough yet...
3679 texnum = R_GetTexture(tex);
3680 if (unit->texture == tex)
3682 unit->texture = tex;
3683 DPSOFTRAST_SetTexture(unitnum, texnum);
3688 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3690 gltextureunit_t *unit = gl_state.units + unitnum;
3691 switch(vid.renderpath)
3693 case RENDERPATH_GL11:
3694 case RENDERPATH_GL13:
3695 case RENDERPATH_GL20:
3696 case RENDERPATH_CGGL:
3697 if (matrix && matrix->m[3][3])
3699 // texmatrix specified, check if it is different
3700 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3703 unit->texmatrixenabled = true;
3704 unit->matrix = *matrix;
3706 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3707 GL_ActiveTexture(unitnum);
3708 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3709 qglLoadMatrixf(glmatrix);CHECKGLERROR
3710 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3715 // no texmatrix specified, revert to identity
3716 if (unit->texmatrixenabled)
3718 unit->texmatrixenabled = false;
3719 unit->matrix = identitymatrix;
3721 GL_ActiveTexture(unitnum);
3722 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3723 qglLoadIdentity();CHECKGLERROR
3724 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3728 case RENDERPATH_D3D9:
3729 case RENDERPATH_D3D10:
3730 case RENDERPATH_D3D11:
3732 case RENDERPATH_SOFT:
3734 case RENDERPATH_GLES2:
3739 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3741 gltextureunit_t *unit = gl_state.units + unitnum;
3743 switch(vid.renderpath)
3745 case RENDERPATH_GL20:
3746 case RENDERPATH_CGGL:
3747 case RENDERPATH_GLES2:
3750 case RENDERPATH_GL13:
3751 // GL_ARB_texture_env_combine
3753 combinergb = GL_MODULATE;
3755 combinealpha = GL_MODULATE;
3760 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3762 if (combinergb == GL_DECAL)
3763 combinergb = GL_INTERPOLATE_ARB;
3764 if (unit->combine != GL_COMBINE_ARB)
3766 unit->combine = GL_COMBINE_ARB;
3767 GL_ActiveTexture(unitnum);
3768 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3769 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3771 if (unit->combinergb != combinergb)
3773 unit->combinergb = combinergb;
3774 GL_ActiveTexture(unitnum);
3775 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3777 if (unit->combinealpha != combinealpha)
3779 unit->combinealpha = combinealpha;
3780 GL_ActiveTexture(unitnum);
3781 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3783 if (unit->rgbscale != rgbscale)
3785 unit->rgbscale = rgbscale;
3786 GL_ActiveTexture(unitnum);
3787 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3789 if (unit->alphascale != alphascale)
3791 unit->alphascale = alphascale;
3792 GL_ActiveTexture(unitnum);
3793 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3798 if (unit->combine != combinergb)
3800 unit->combine = combinergb;
3801 GL_ActiveTexture(unitnum);
3802 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3806 case RENDERPATH_GL11:
3809 combinergb = GL_MODULATE;
3810 if (unit->combine != combinergb)
3812 unit->combine = combinergb;
3813 GL_ActiveTexture(unitnum);
3814 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3817 case RENDERPATH_D3D9:
3818 case RENDERPATH_D3D10:
3819 case RENDERPATH_D3D11:
3821 case RENDERPATH_SOFT:
3826 void R_Mesh_ResetTextureState(void)
3828 unsigned int unitnum;
3833 switch(vid.renderpath)
3835 case RENDERPATH_GL20:
3836 case RENDERPATH_CGGL:
3837 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3839 gltextureunit_t *unit = gl_state.units + unitnum;
3843 GL_ActiveTexture(unitnum);
3844 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3849 GL_ActiveTexture(unitnum);
3850 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3855 GL_ActiveTexture(unitnum);
3856 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3859 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3861 gltextureunit_t *unit = gl_state.units + unitnum;
3862 if (unit->arrayenabled)
3864 unit->arrayenabled = false;
3865 GL_ClientActiveTexture(unitnum);
3866 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3869 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3871 gltextureunit_t *unit = gl_state.units + unitnum;
3872 if (unit->texmatrixenabled)
3874 unit->texmatrixenabled = false;
3875 unit->matrix = identitymatrix;
3877 GL_ActiveTexture(unitnum);
3878 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3879 qglLoadIdentity();CHECKGLERROR
3880 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3884 case RENDERPATH_GL13:
3885 case RENDERPATH_GL11:
3886 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3888 gltextureunit_t *unit = gl_state.units + unitnum;
3892 GL_ActiveTexture(unitnum);
3893 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3894 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3899 GL_ActiveTexture(unitnum);
3900 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3901 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3906 GL_ActiveTexture(unitnum);
3907 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3908 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3910 if (unit->arrayenabled)
3912 unit->arrayenabled = false;
3913 GL_ClientActiveTexture(unitnum);
3914 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3916 if (unit->texmatrixenabled)
3918 unit->texmatrixenabled = false;
3919 unit->matrix = identitymatrix;
3921 GL_ActiveTexture(unitnum);
3922 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3923 qglLoadIdentity();CHECKGLERROR
3924 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3926 if (unit->combine != GL_MODULATE)
3928 unit->combine = GL_MODULATE;
3929 GL_ActiveTexture(unitnum);
3930 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3934 case RENDERPATH_D3D9:
3935 case RENDERPATH_D3D10:
3936 case RENDERPATH_D3D11:
3938 case RENDERPATH_SOFT:
3940 case RENDERPATH_GLES2:
3948 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3949 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3950 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3952 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3954 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3958 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3960 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3961 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3962 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3966 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3968 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3969 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3970 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3971 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3972 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3973 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3974 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3978 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
3979 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3980 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3983 static void R_Mesh_InitVertexDeclarations(void)
3986 r_vertex3f_d3d9decl = NULL;
3987 r_vertexgeneric_d3d9decl = NULL;
3988 r_vertexmesh_d3d9decl = NULL;
3989 switch(vid.renderpath)
3991 case RENDERPATH_GL20:
3992 case RENDERPATH_CGGL:
3993 case RENDERPATH_GL13:
3994 case RENDERPATH_GL11:
3995 case RENDERPATH_GLES2:
3997 case RENDERPATH_D3D9:
3998 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
3999 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
4000 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
4002 case RENDERPATH_D3D10:
4003 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4005 case RENDERPATH_D3D11:
4006 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4008 case RENDERPATH_SOFT:
4014 static void R_Mesh_DestroyVertexDeclarations(void)
4017 if (r_vertex3f_d3d9decl)
4018 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
4019 r_vertex3f_d3d9decl = NULL;
4020 if (r_vertexgeneric_d3d9decl)
4021 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
4022 r_vertexgeneric_d3d9decl = NULL;
4023 if (r_vertexmesh_d3d9decl)
4024 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
4025 r_vertexmesh_d3d9decl = NULL;
4029 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
4031 // upload temporary vertexbuffer for this rendering
4032 if (!gl_state.usevbo_staticvertex)
4033 vertexbuffer = NULL;
4034 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4036 if (gl_state.preparevertices_dynamicvertexbuffer)
4037 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
4039 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4040 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4042 switch(vid.renderpath)
4044 case RENDERPATH_GL20:
4045 case RENDERPATH_CGGL:
4046 case RENDERPATH_GLES2:
4049 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4050 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4051 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4052 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4053 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4054 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4055 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4059 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4060 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4061 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4062 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4063 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4064 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4065 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4068 case RENDERPATH_GL13:
4071 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4072 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4073 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4074 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4078 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4079 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4080 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4081 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4084 case RENDERPATH_GL11:
4087 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4088 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4089 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4093 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4094 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4095 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4098 case RENDERPATH_D3D9:
4100 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4102 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4104 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4105 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4106 gl_state.d3dvertexdata = (void *)vertex3f;
4107 gl_state.d3dvertexsize = sizeof(float[3]);
4110 case RENDERPATH_D3D10:
4111 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4113 case RENDERPATH_D3D11:
4114 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4116 case RENDERPATH_SOFT:
4117 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4118 DPSOFTRAST_SetColorPointer(NULL, 0);
4119 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4120 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4121 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4122 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4123 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4130 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4133 size = sizeof(r_vertexgeneric_t) * numvertices;
4134 if (gl_state.preparevertices_tempdatamaxsize < size)
4136 gl_state.preparevertices_tempdatamaxsize = size;
4137 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4139 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4140 gl_state.preparevertices_numvertices = numvertices;
4141 return gl_state.preparevertices_vertexgeneric;
4144 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4146 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4147 gl_state.preparevertices_vertexgeneric = NULL;
4148 gl_state.preparevertices_numvertices = 0;
4152 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4155 r_vertexgeneric_t *vertex;
4156 switch(vid.renderpath)
4158 case RENDERPATH_GL20:
4159 case RENDERPATH_CGGL:
4160 case RENDERPATH_GLES2:
4161 if (!vid.useinterleavedarrays)
4163 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4164 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4165 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4166 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4167 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4168 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4169 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4173 case RENDERPATH_GL13:
4174 case RENDERPATH_GL11:
4175 if (!vid.useinterleavedarrays)
4177 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4178 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4179 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4180 if (vid.texunits >= 2)
4181 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4182 if (vid.texunits >= 3)
4183 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4187 case RENDERPATH_D3D9:
4188 case RENDERPATH_D3D10:
4189 case RENDERPATH_D3D11:
4191 case RENDERPATH_SOFT:
4192 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4193 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4194 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4195 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4196 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4197 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4198 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4202 // no quick path for this case, convert to vertex structs
4203 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4204 for (i = 0;i < numvertices;i++)
4205 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4208 for (i = 0;i < numvertices;i++)
4209 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4213 float tempcolor4f[4];
4214 unsigned char tempcolor4ub[4];
4215 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4216 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4217 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4218 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4219 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4220 for (i = 0;i < numvertices;i++)
4221 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4224 for (i = 0;i < numvertices;i++)
4225 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4226 R_Mesh_PrepareVertices_Generic_Unlock();
4227 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4230 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4232 // upload temporary vertexbuffer for this rendering
4233 if (!gl_state.usevbo_staticvertex)
4234 vertexbuffer = NULL;
4235 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4237 if (gl_state.preparevertices_dynamicvertexbuffer)
4238 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4240 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4241 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4243 switch(vid.renderpath)
4245 case RENDERPATH_GL20:
4246 case RENDERPATH_CGGL:
4247 case RENDERPATH_GLES2:
4250 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4251 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4252 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4253 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4254 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4255 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4256 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4260 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4261 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4262 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4263 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4264 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4265 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4266 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4269 case RENDERPATH_GL13:
4272 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4273 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4274 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4275 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4279 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4280 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4281 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4282 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4285 case RENDERPATH_GL11:
4288 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4289 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4290 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4294 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4295 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4296 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4299 case RENDERPATH_D3D9:
4301 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4303 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4305 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4306 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4307 gl_state.d3dvertexdata = (void *)vertex;
4308 gl_state.d3dvertexsize = sizeof(*vertex);
4311 case RENDERPATH_D3D10:
4312 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4314 case RENDERPATH_D3D11:
4315 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4317 case RENDERPATH_SOFT:
4318 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4319 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4320 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4321 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4322 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4323 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4324 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4331 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4334 size = sizeof(r_vertexmesh_t) * numvertices;
4335 if (gl_state.preparevertices_tempdatamaxsize < size)
4337 gl_state.preparevertices_tempdatamaxsize = size;
4338 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4340 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4341 gl_state.preparevertices_numvertices = numvertices;
4342 return gl_state.preparevertices_vertexmesh;
4345 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4347 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4348 gl_state.preparevertices_vertexmesh = NULL;
4349 gl_state.preparevertices_numvertices = 0;
4353 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)
4356 r_vertexmesh_t *vertex;
4357 switch(vid.renderpath)
4359 case RENDERPATH_GL20:
4360 case RENDERPATH_CGGL:
4361 case RENDERPATH_GLES2:
4362 if (!vid.useinterleavedarrays)
4364 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4365 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4366 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4367 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4368 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4369 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4370 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4374 case RENDERPATH_GL13:
4375 case RENDERPATH_GL11:
4376 if (!vid.useinterleavedarrays)
4378 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4379 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4380 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4381 if (vid.texunits >= 2)
4382 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4383 if (vid.texunits >= 3)
4384 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4388 case RENDERPATH_D3D9:
4389 case RENDERPATH_D3D10:
4390 case RENDERPATH_D3D11:
4392 case RENDERPATH_SOFT:
4393 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4394 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4395 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4396 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4397 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4398 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4399 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4403 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4404 for (i = 0;i < numvertices;i++)
4405 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4407 for (i = 0;i < numvertices;i++)
4408 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4410 for (i = 0;i < numvertices;i++)
4411 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4413 for (i = 0;i < numvertices;i++)
4414 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4417 for (i = 0;i < numvertices;i++)
4418 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4422 float tempcolor4f[4];
4423 unsigned char tempcolor4ub[4];
4424 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4425 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4426 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4427 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4428 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4429 for (i = 0;i < numvertices;i++)
4430 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4432 if (texcoordtexture2f)
4433 for (i = 0;i < numvertices;i++)
4434 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4435 if (texcoordlightmap2f)
4436 for (i = 0;i < numvertices;i++)
4437 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4438 R_Mesh_PrepareVertices_Mesh_Unlock();
4439 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4442 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4444 // upload temporary vertexbuffer for this rendering
4445 if (!gl_state.usevbo_staticvertex)
4446 vertexbuffer = NULL;
4447 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4449 if (gl_state.preparevertices_dynamicvertexbuffer)
4450 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4452 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4453 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4455 switch(vid.renderpath)
4457 case RENDERPATH_GL20:
4458 case RENDERPATH_CGGL:
4459 case RENDERPATH_GLES2:
4462 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4463 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4464 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4465 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4466 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4467 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4468 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4472 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4473 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4474 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4475 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4476 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4477 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4478 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4481 case RENDERPATH_GL13:
4484 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4485 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4486 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4487 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4491 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4492 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4493 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4494 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4497 case RENDERPATH_GL11:
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_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4502 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4506 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4507 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4508 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4511 case RENDERPATH_D3D9:
4513 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4515 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4517 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4518 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4519 gl_state.d3dvertexdata = (void *)vertex;
4520 gl_state.d3dvertexsize = sizeof(*vertex);
4523 case RENDERPATH_D3D10:
4524 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4526 case RENDERPATH_D3D11:
4527 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4529 case RENDERPATH_SOFT:
4530 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4531 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4532 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4533 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4534 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4535 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4536 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);