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_NONE;
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 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1564 qglEnableVertexAttribArray(GLES2ATTRIB_POSITION);
1565 qglVertexAttribPointer(GLES2ATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1566 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);
1567 qglVertexAttribPointer(GLES2ATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1568 qglVertexAttrib4f(GLES2ATTRIB_COLOR, 1, 1, 1, 1);
1569 gl_state.unit = MAX_TEXTUREUNITS;
1570 gl_state.clientunit = MAX_TEXTUREUNITS;
1571 for (i = 0;i < vid.teximageunits;i++)
1573 GL_ActiveTexture(i);
1574 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1575 if (vid.support.ext_texture_3d)
1577 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1579 if (vid.support.arb_texture_cube_map)
1581 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1584 for (i = 0;i < vid.texarrayunits;i++)
1587 qglVertexAttribPointer(i+GLES2ATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1588 qglDisableVertexAttribArray(i+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
1595 void GL_ActiveTexture(unsigned int num)
1597 if (gl_state.unit != num)
1599 gl_state.unit = num;
1600 switch(vid.renderpath)
1602 case RENDERPATH_GL11:
1603 case RENDERPATH_GL13:
1604 case RENDERPATH_GL20:
1605 case RENDERPATH_CGGL:
1606 case RENDERPATH_GLES2:
1607 if (qglActiveTexture)
1610 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1614 case RENDERPATH_D3D9:
1615 case RENDERPATH_D3D10:
1616 case RENDERPATH_D3D11:
1618 case RENDERPATH_SOFT:
1624 void GL_ClientActiveTexture(unsigned int num)
1626 if (gl_state.clientunit != num)
1628 gl_state.clientunit = num;
1629 switch(vid.renderpath)
1631 case RENDERPATH_GL11:
1632 case RENDERPATH_GL13:
1633 case RENDERPATH_GL20:
1634 case RENDERPATH_CGGL:
1635 if (qglActiveTexture)
1638 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1642 case RENDERPATH_D3D9:
1643 case RENDERPATH_D3D10:
1644 case RENDERPATH_D3D11:
1646 case RENDERPATH_SOFT:
1648 case RENDERPATH_GLES2:
1654 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1656 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1658 qboolean blendenable;
1659 gl_state.blendfunc1 = blendfunc1;
1660 gl_state.blendfunc2 = blendfunc2;
1661 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1662 switch(vid.renderpath)
1664 case RENDERPATH_GL11:
1665 case RENDERPATH_GL13:
1666 case RENDERPATH_GL20:
1667 case RENDERPATH_CGGL:
1668 case RENDERPATH_GLES2:
1670 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1671 if (gl_state.blend != blendenable)
1673 gl_state.blend = blendenable;
1674 if (!gl_state.blend)
1676 qglDisable(GL_BLEND);CHECKGLERROR
1680 qglEnable(GL_BLEND);CHECKGLERROR
1684 case RENDERPATH_D3D9:
1689 D3DBLEND d3dblendfunc[2];
1690 glblendfunc[0] = gl_state.blendfunc1;
1691 glblendfunc[1] = gl_state.blendfunc2;
1692 for (i = 0;i < 2;i++)
1694 switch(glblendfunc[i])
1696 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1697 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1698 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1699 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1700 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1701 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1702 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1703 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1704 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1705 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1708 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1709 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1710 if (gl_state.blend != blendenable)
1712 gl_state.blend = blendenable;
1713 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1718 case RENDERPATH_D3D10:
1719 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1721 case RENDERPATH_D3D11:
1722 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1724 case RENDERPATH_SOFT:
1725 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1731 void GL_DepthMask(int state)
1733 if (gl_state.depthmask != state)
1735 gl_state.depthmask = state;
1736 switch(vid.renderpath)
1738 case RENDERPATH_GL11:
1739 case RENDERPATH_GL13:
1740 case RENDERPATH_GL20:
1741 case RENDERPATH_CGGL:
1742 case RENDERPATH_GLES2:
1744 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1746 case RENDERPATH_D3D9:
1748 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1751 case RENDERPATH_D3D10:
1752 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1754 case RENDERPATH_D3D11:
1755 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1757 case RENDERPATH_SOFT:
1758 DPSOFTRAST_DepthMask(gl_state.depthmask);
1764 void GL_DepthTest(int state)
1766 if (gl_state.depthtest != state)
1768 gl_state.depthtest = state;
1769 switch(vid.renderpath)
1771 case RENDERPATH_GL11:
1772 case RENDERPATH_GL13:
1773 case RENDERPATH_GL20:
1774 case RENDERPATH_CGGL:
1775 case RENDERPATH_GLES2:
1777 if (gl_state.depthtest)
1779 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1783 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1786 case RENDERPATH_D3D9:
1788 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1791 case RENDERPATH_D3D10:
1792 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1794 case RENDERPATH_D3D11:
1795 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1797 case RENDERPATH_SOFT:
1798 DPSOFTRAST_DepthTest(gl_state.depthtest);
1804 void GL_DepthFunc(int state)
1806 if (gl_state.depthfunc != state)
1808 gl_state.depthfunc = state;
1809 switch(vid.renderpath)
1811 case RENDERPATH_GL11:
1812 case RENDERPATH_GL13:
1813 case RENDERPATH_GL20:
1814 case RENDERPATH_CGGL:
1815 case RENDERPATH_GLES2:
1817 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1819 case RENDERPATH_D3D9:
1821 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1824 case RENDERPATH_D3D10:
1825 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1827 case RENDERPATH_D3D11:
1828 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1830 case RENDERPATH_SOFT:
1831 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1837 void GL_DepthRange(float nearfrac, float farfrac)
1839 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1841 gl_state.depthrange[0] = nearfrac;
1842 gl_state.depthrange[1] = farfrac;
1843 switch(vid.renderpath)
1845 case RENDERPATH_GL11:
1846 case RENDERPATH_GL13:
1847 case RENDERPATH_GL20:
1848 case RENDERPATH_CGGL:
1849 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1851 case RENDERPATH_D3D9:
1854 D3DVIEWPORT9 d3dviewport;
1855 d3dviewport.X = gl_viewport.x;
1856 d3dviewport.Y = gl_viewport.y;
1857 d3dviewport.Width = gl_viewport.width;
1858 d3dviewport.Height = gl_viewport.height;
1859 d3dviewport.MinZ = gl_state.depthrange[0];
1860 d3dviewport.MaxZ = gl_state.depthrange[1];
1861 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1865 case RENDERPATH_D3D10:
1866 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1868 case RENDERPATH_D3D11:
1869 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1871 case RENDERPATH_SOFT:
1872 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1874 case RENDERPATH_GLES2:
1875 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1876 // FIXME: qglDepthRangef instead... faster...
1877 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1883 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)
1885 switch (vid.renderpath)
1887 case RENDERPATH_GL11:
1888 case RENDERPATH_GL13:
1889 case RENDERPATH_GL20:
1890 case RENDERPATH_CGGL:
1894 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1898 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1900 if (vid.support.ati_separate_stencil)
1902 qglStencilMask(writemask);CHECKGLERROR
1903 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1904 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1905 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1907 else if (vid.support.ext_stencil_two_side)
1909 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1910 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1911 qglStencilMask(writemask);CHECKGLERROR
1912 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1913 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1914 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1915 qglStencilMask(writemask);CHECKGLERROR
1916 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1917 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1920 case RENDERPATH_D3D9:
1922 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1923 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1924 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1925 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1926 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1927 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1928 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1929 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1930 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1931 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1932 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1933 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1934 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1937 case RENDERPATH_D3D10:
1938 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1940 case RENDERPATH_D3D11:
1941 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1943 case RENDERPATH_SOFT:
1944 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1946 case RENDERPATH_GLES2:
1947 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1952 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1954 switch (vid.renderpath)
1956 case RENDERPATH_GL11:
1957 case RENDERPATH_GL13:
1958 case RENDERPATH_GL20:
1959 case RENDERPATH_CGGL:
1960 case RENDERPATH_GLES2:
1964 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1968 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1970 if (vid.support.ext_stencil_two_side)
1972 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1974 qglStencilMask(writemask);CHECKGLERROR
1975 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1976 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1979 case RENDERPATH_D3D9:
1981 if (vid.support.ati_separate_stencil)
1982 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1983 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1984 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1985 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1986 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1987 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1988 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1989 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1990 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1993 case RENDERPATH_D3D10:
1994 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1996 case RENDERPATH_D3D11:
1997 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1999 case RENDERPATH_SOFT:
2000 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2005 void GL_PolygonOffset(float planeoffset, float depthoffset)
2007 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2009 gl_state.polygonoffset[0] = planeoffset;
2010 gl_state.polygonoffset[1] = depthoffset;
2011 switch(vid.renderpath)
2013 case RENDERPATH_GL11:
2014 case RENDERPATH_GL13:
2015 case RENDERPATH_GL20:
2016 case RENDERPATH_CGGL:
2017 case RENDERPATH_GLES2:
2018 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2020 case RENDERPATH_D3D9:
2022 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2023 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2026 case RENDERPATH_D3D10:
2027 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2029 case RENDERPATH_D3D11:
2030 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2032 case RENDERPATH_SOFT:
2033 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2039 void GL_SetMirrorState(qboolean state)
2041 if (v_flipped_state != state)
2043 v_flipped_state = state;
2044 if (gl_state.cullface == GL_BACK)
2045 gl_state.cullface = GL_FRONT;
2046 else if (gl_state.cullface == GL_FRONT)
2047 gl_state.cullface = GL_BACK;
2050 switch(vid.renderpath)
2052 case RENDERPATH_GL11:
2053 case RENDERPATH_GL13:
2054 case RENDERPATH_GL20:
2055 case RENDERPATH_CGGL:
2056 case RENDERPATH_GLES2:
2057 qglCullFace(gl_state.cullface);
2059 case RENDERPATH_D3D9:
2061 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2064 case RENDERPATH_D3D10:
2065 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2067 case RENDERPATH_D3D11:
2068 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2070 case RENDERPATH_SOFT:
2071 DPSOFTRAST_CullFace(gl_state.cullface);
2077 void GL_CullFace(int state)
2081 if(state == GL_FRONT)
2083 else if(state == GL_BACK)
2087 switch(vid.renderpath)
2089 case RENDERPATH_GL11:
2090 case RENDERPATH_GL13:
2091 case RENDERPATH_GL20:
2092 case RENDERPATH_CGGL:
2093 case RENDERPATH_GLES2:
2096 if (state != GL_NONE)
2098 if (!gl_state.cullfaceenable)
2100 gl_state.cullfaceenable = true;
2101 qglEnable(GL_CULL_FACE);CHECKGLERROR
2103 if (gl_state.cullface != state)
2105 gl_state.cullface = state;
2106 qglCullFace(gl_state.cullface);CHECKGLERROR
2111 if (gl_state.cullfaceenable)
2113 gl_state.cullfaceenable = false;
2114 qglDisable(GL_CULL_FACE);CHECKGLERROR
2118 case RENDERPATH_D3D9:
2120 if (gl_state.cullface != state)
2122 gl_state.cullface = state;
2123 switch(gl_state.cullface)
2126 gl_state.cullfaceenable = false;
2127 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2130 gl_state.cullfaceenable = true;
2131 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2134 gl_state.cullfaceenable = true;
2135 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2141 case RENDERPATH_D3D10:
2142 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2144 case RENDERPATH_D3D11:
2145 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2147 case RENDERPATH_SOFT:
2148 if (gl_state.cullface != state)
2150 gl_state.cullface = state;
2151 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2152 DPSOFTRAST_CullFace(gl_state.cullface);
2158 void GL_AlphaTest(int state)
2160 if (gl_state.alphatest != state)
2162 gl_state.alphatest = state;
2163 switch(vid.renderpath)
2165 case RENDERPATH_GL11:
2166 case RENDERPATH_GL13:
2167 case RENDERPATH_GL20:
2168 case RENDERPATH_CGGL:
2170 if (gl_state.alphatest)
2172 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2176 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2179 case RENDERPATH_D3D9:
2181 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
2184 case RENDERPATH_D3D10:
2185 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2187 case RENDERPATH_D3D11:
2188 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2190 case RENDERPATH_SOFT:
2191 DPSOFTRAST_AlphaTest(gl_state.alphatest);
2193 case RENDERPATH_GLES2:
2199 void GL_AlphaFunc(int state, float value)
2201 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
2203 gl_state.alphafunc = state;
2204 gl_state.alphafuncvalue = value;
2205 switch(vid.renderpath)
2207 case RENDERPATH_GL11:
2208 case RENDERPATH_GL13:
2209 case RENDERPATH_GL20:
2210 case RENDERPATH_CGGL:
2212 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
2214 case RENDERPATH_D3D9:
2216 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
2217 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
2220 case RENDERPATH_D3D10:
2221 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2223 case RENDERPATH_D3D11:
2224 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2226 case RENDERPATH_SOFT:
2227 DPSOFTRAST_AlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);
2229 case RENDERPATH_GLES2:
2235 void GL_ColorMask(int r, int g, int b, int a)
2237 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2238 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2239 if (gl_state.colormask != state)
2241 gl_state.colormask = state;
2242 switch(vid.renderpath)
2244 case RENDERPATH_GL11:
2245 case RENDERPATH_GL13:
2246 case RENDERPATH_GL20:
2247 case RENDERPATH_CGGL:
2248 case RENDERPATH_GLES2:
2250 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2252 case RENDERPATH_D3D9:
2254 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2257 case RENDERPATH_D3D10:
2258 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2260 case RENDERPATH_D3D11:
2261 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2263 case RENDERPATH_SOFT:
2264 DPSOFTRAST_ColorMask(r, g, b, a);
2270 void GL_Color(float cr, float cg, float cb, float ca)
2272 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)
2274 gl_state.color4f[0] = cr;
2275 gl_state.color4f[1] = cg;
2276 gl_state.color4f[2] = cb;
2277 gl_state.color4f[3] = ca;
2278 switch(vid.renderpath)
2280 case RENDERPATH_GL11:
2281 case RENDERPATH_GL13:
2282 case RENDERPATH_GL20:
2283 case RENDERPATH_CGGL:
2285 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2288 case RENDERPATH_D3D9:
2289 case RENDERPATH_D3D10:
2290 case RENDERPATH_D3D11:
2291 // no equivalent in D3D
2293 case RENDERPATH_SOFT:
2294 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2296 case RENDERPATH_GLES2:
2297 qglVertexAttrib4f(GLES2ATTRIB_COLOR, cr, cg, cb, ca);
2303 void GL_Scissor (int x, int y, int width, int height)
2305 switch(vid.renderpath)
2307 case RENDERPATH_GL11:
2308 case RENDERPATH_GL13:
2309 case RENDERPATH_GL20:
2310 case RENDERPATH_CGGL:
2311 case RENDERPATH_GLES2:
2313 qglScissor(x, y,width,height);
2316 case RENDERPATH_D3D9:
2322 d3drect.right = x + width;
2323 d3drect.bottom = y + height;
2324 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2328 case RENDERPATH_D3D10:
2329 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2331 case RENDERPATH_D3D11:
2332 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2334 case RENDERPATH_SOFT:
2335 DPSOFTRAST_Scissor(x, y, width, height);
2340 void GL_ScissorTest(int state)
2342 if (gl_state.scissortest != state)
2344 gl_state.scissortest = state;
2345 switch(vid.renderpath)
2347 case RENDERPATH_GL11:
2348 case RENDERPATH_GL13:
2349 case RENDERPATH_GL20:
2350 case RENDERPATH_CGGL:
2351 case RENDERPATH_GLES2:
2353 if(gl_state.scissortest)
2354 qglEnable(GL_SCISSOR_TEST);
2356 qglDisable(GL_SCISSOR_TEST);
2359 case RENDERPATH_D3D9:
2361 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2364 case RENDERPATH_D3D10:
2365 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2367 case RENDERPATH_D3D11:
2368 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2370 case RENDERPATH_SOFT:
2371 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2377 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2379 static const float blackcolor[4] = {0, 0, 0, 0};
2380 // prevent warnings when trying to clear a buffer that does not exist
2382 colorvalue = blackcolor;
2385 mask &= ~GL_STENCIL_BUFFER_BIT;
2388 switch(vid.renderpath)
2390 case RENDERPATH_GL11:
2391 case RENDERPATH_GL13:
2392 case RENDERPATH_GL20:
2393 case RENDERPATH_CGGL:
2394 case RENDERPATH_GLES2:
2396 if (mask & GL_COLOR_BUFFER_BIT)
2398 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2400 if (mask & GL_DEPTH_BUFFER_BIT)
2402 qglClearDepth(depthvalue);CHECKGLERROR
2404 if (mask & GL_STENCIL_BUFFER_BIT)
2406 qglClearStencil(stencilvalue);CHECKGLERROR
2408 qglClear(mask);CHECKGLERROR
2410 case RENDERPATH_D3D9:
2412 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);
2415 case RENDERPATH_D3D10:
2416 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2418 case RENDERPATH_D3D11:
2419 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2421 case RENDERPATH_SOFT:
2422 if (mask & GL_COLOR_BUFFER_BIT)
2423 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2424 if (mask & GL_DEPTH_BUFFER_BIT)
2425 DPSOFTRAST_ClearDepth(depthvalue);
2430 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2432 switch(vid.renderpath)
2434 case RENDERPATH_GL11:
2435 case RENDERPATH_GL13:
2436 case RENDERPATH_GL20:
2437 case RENDERPATH_CGGL:
2438 case RENDERPATH_GLES2:
2440 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2442 case RENDERPATH_D3D9:
2445 // LordHavoc: we can't directly download the backbuffer because it may be
2446 // multisampled, and it may not be lockable, so we blit it to a lockable
2447 // surface of the same dimensions (but without multisample) to resolve the
2448 // multisample buffer to a normal image, and then lock that...
2449 IDirect3DSurface9 *stretchsurface = NULL;
2450 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2452 D3DLOCKED_RECT lockedrect;
2453 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2455 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2458 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2459 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2460 memcpy(outpixels + line * width * 4, row, width * 4);
2461 IDirect3DSurface9_UnlockRect(stretchsurface);
2464 IDirect3DSurface9_Release(stretchsurface);
2467 //IDirect3DSurface9 *syssurface = NULL;
2468 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2469 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2470 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2471 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2472 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2473 //IDirect3DSurface9_UnlockRect(syssurface);
2474 //IDirect3DSurface9_Release(syssurface);
2478 case RENDERPATH_D3D10:
2479 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2481 case RENDERPATH_D3D11:
2482 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2484 case RENDERPATH_SOFT:
2485 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2490 // called at beginning of frame
2491 void R_Mesh_Start(void)
2494 R_Mesh_ResetRenderTargets();
2496 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2498 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2499 Cvar_SetValueQuick(&gl_paranoid, 1);
2503 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2507 char compilelog[MAX_INPUTLINE];
2508 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2511 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2512 qglCompileShader(shaderobject);CHECKGLERROR
2513 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2514 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2515 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2517 int i, j, pretextlines = 0;
2518 for (i = 0;i < numstrings - 1;i++)
2519 for (j = 0;strings[i][j];j++)
2520 if (strings[i][j] == '\n')
2522 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2524 if (!shadercompiled)
2526 qglDeleteShader(shaderobject);CHECKGLERROR
2529 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2530 qglDeleteShader(shaderobject);CHECKGLERROR
2534 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)
2536 GLint programlinked;
2537 GLuint programobject = 0;
2538 char linklog[MAX_INPUTLINE];
2541 programobject = qglCreateProgram();CHECKGLERROR
2545 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2548 #ifdef GL_GEOMETRY_SHADER
2549 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2553 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2556 qglLinkProgram(programobject);CHECKGLERROR
2557 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2558 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2561 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2562 Con_DPrintf("program link log:\n%s\n", linklog);
2563 // software vertex shader is ok but software fragment shader is WAY
2564 // too slow, fail program if so.
2565 // NOTE: this string might be ATI specific, but that's ok because the
2566 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2567 // software fragment shader due to low instruction and dependent
2569 if (strstr(linklog, "fragment shader will run in software"))
2570 programlinked = false;
2574 return programobject;
2576 qglDeleteProgram(programobject);CHECKGLERROR
2580 void GL_Backend_FreeProgram(unsigned int prog)
2583 qglDeleteProgram(prog);
2587 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2592 for (i = 0;i < count;i++)
2593 *out++ = *in++ + offset;
2596 memcpy(out, in, sizeof(*out) * count);
2599 // renders triangles using vertices from the active arrays
2600 int paranoidblah = 0;
2601 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)
2603 unsigned int numelements = numtriangles * 3;
2605 size_t bufferoffset3i;
2607 size_t bufferoffset3s;
2608 if (numvertices < 3 || numtriangles < 1)
2610 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2611 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);
2614 if (!gl_mesh_prefer_short_elements.integer)
2618 if (element3i_indexbuffer)
2619 element3i_indexbuffer = NULL;
2621 // adjust the pointers for firsttriangle
2623 element3i += firsttriangle * 3;
2624 if (element3i_indexbuffer)
2625 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2627 element3s += firsttriangle * 3;
2628 if (element3s_indexbuffer)
2629 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2630 switch(vid.renderpath)
2632 case RENDERPATH_GL11:
2633 case RENDERPATH_GL13:
2634 case RENDERPATH_GL20:
2635 case RENDERPATH_CGGL:
2636 case RENDERPATH_GLES2:
2637 // check if the user specified to ignore static index buffers
2638 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2640 element3i_indexbuffer = NULL;
2641 element3s_indexbuffer = NULL;
2644 case RENDERPATH_D3D9:
2645 case RENDERPATH_D3D10:
2646 case RENDERPATH_D3D11:
2648 case RENDERPATH_SOFT:
2651 // upload a dynamic index buffer if needed
2654 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2656 if (gl_state.draw_dynamicindexbuffer)
2657 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2659 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2660 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2661 element3s_bufferoffset = 0;
2666 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2668 if (gl_state.draw_dynamicindexbuffer)
2669 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2671 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2672 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2673 element3i_bufferoffset = 0;
2676 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2677 bufferoffset3i = element3i_bufferoffset;
2678 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2679 bufferoffset3s = element3s_bufferoffset;
2680 r_refdef.stats.draws++;
2681 r_refdef.stats.draws_vertices += numvertices;
2682 r_refdef.stats.draws_elements += numelements;
2683 if (gl_paranoid.integer)
2686 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2688 unsigned int j, size;
2690 // note: there's no validation done here on buffer objects because it
2691 // is somewhat difficult to get at the data, and gl_paranoid can be
2692 // used without buffer objects if the need arises
2693 // (the data could be gotten using glMapBuffer but it would be very
2694 // slow due to uncachable video memory reads)
2695 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2696 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2698 if (gl_state.pointer_vertex_pointer)
2699 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2701 if (gl_state.pointer_color_enabled)
2703 if (!qglIsEnabled(GL_COLOR_ARRAY))
2704 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2706 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2707 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2710 for (i = 0;i < vid.texarrayunits;i++)
2712 if (gl_state.units[i].arrayenabled)
2714 GL_ClientActiveTexture(i);
2715 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2716 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2718 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2719 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++)
2726 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2728 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2730 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2737 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2739 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2741 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2747 if (r_render.integer || r_refdef.draw2dstage)
2749 switch(vid.renderpath)
2751 case RENDERPATH_GL11:
2752 case RENDERPATH_GL13:
2753 case RENDERPATH_GL20:
2754 case RENDERPATH_CGGL:
2756 if (gl_mesh_testmanualfeeding.integer)
2758 unsigned int i, j, element;
2760 qglBegin(GL_TRIANGLES);
2761 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2764 element = element3i[i];
2766 element = element3s[i];
2768 element = firstvertex + i;
2769 for (j = 0;j < vid.texarrayunits;j++)
2771 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2773 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2775 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2776 if (vid.texarrayunits > 1)
2778 if (gl_state.units[j].pointer_texcoord_components == 4)
2779 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2780 else if (gl_state.units[j].pointer_texcoord_components == 3)
2781 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2782 else if (gl_state.units[j].pointer_texcoord_components == 2)
2783 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2785 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2789 if (gl_state.units[j].pointer_texcoord_components == 4)
2790 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2791 else if (gl_state.units[j].pointer_texcoord_components == 3)
2792 qglTexCoord3f(p[0], p[1], p[2]);
2793 else if (gl_state.units[j].pointer_texcoord_components == 2)
2794 qglTexCoord2f(p[0], p[1]);
2796 qglTexCoord1f(p[0]);
2799 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2801 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2802 if (vid.texarrayunits > 1)
2804 if (gl_state.units[j].pointer_texcoord_components == 4)
2805 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2806 else if (gl_state.units[j].pointer_texcoord_components == 3)
2807 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2808 else if (gl_state.units[j].pointer_texcoord_components == 2)
2809 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2810 else if (gl_state.units[j].pointer_texcoord_components == 1)
2811 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2815 if (gl_state.units[j].pointer_texcoord_components == 4)
2816 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2817 else if (gl_state.units[j].pointer_texcoord_components == 3)
2818 qglTexCoord3f(s[0], s[1], s[2]);
2819 else if (gl_state.units[j].pointer_texcoord_components == 2)
2820 qglTexCoord2f(s[0], s[1]);
2821 else if (gl_state.units[j].pointer_texcoord_components == 1)
2822 qglTexCoord1f(s[0]);
2825 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2827 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2828 if (vid.texarrayunits > 1)
2830 if (gl_state.units[j].pointer_texcoord_components == 4)
2831 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2832 else if (gl_state.units[j].pointer_texcoord_components == 3)
2833 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2834 else if (gl_state.units[j].pointer_texcoord_components == 2)
2835 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2836 else if (gl_state.units[j].pointer_texcoord_components == 1)
2837 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2841 if (gl_state.units[j].pointer_texcoord_components == 4)
2842 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2843 else if (gl_state.units[j].pointer_texcoord_components == 3)
2844 qglTexCoord3f(sb[0], sb[1], sb[2]);
2845 else if (gl_state.units[j].pointer_texcoord_components == 2)
2846 qglTexCoord2f(sb[0], sb[1]);
2847 else if (gl_state.units[j].pointer_texcoord_components == 1)
2848 qglTexCoord1f(sb[0]);
2853 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2855 if (gl_state.pointer_color_gltype == GL_FLOAT)
2857 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2858 qglColor4f(p[0], p[1], p[2], p[3]);
2860 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2862 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2863 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2866 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2868 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2869 if (gl_state.pointer_vertex_components == 4)
2870 qglVertex4f(p[0], p[1], p[2], p[3]);
2871 else if (gl_state.pointer_vertex_components == 3)
2872 qglVertex3f(p[0], p[1], p[2]);
2874 qglVertex2f(p[0], p[1]);
2880 else if (bufferobject3s)
2882 GL_BindEBO(bufferobject3s);
2883 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2885 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2890 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2894 else if (bufferobject3i)
2896 GL_BindEBO(bufferobject3i);
2897 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2899 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2904 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2911 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2913 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2918 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2925 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2927 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2932 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2938 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2942 case RENDERPATH_D3D9:
2944 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2946 if (element3s_indexbuffer)
2948 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2949 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2951 else if (element3i_indexbuffer)
2953 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2954 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2957 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2962 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2964 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2966 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2970 case RENDERPATH_D3D10:
2971 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2973 case RENDERPATH_D3D11:
2974 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2976 case RENDERPATH_SOFT:
2977 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
2979 case RENDERPATH_GLES2:
2980 // GLES does not have glDrawRangeElements, and generally
2981 // underperforms with index buffers, so this code path is
2982 // relatively straightforward...
2985 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2990 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2995 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3003 // restores backend state, used when done with 3D rendering
3004 void R_Mesh_Finish(void)
3006 R_Mesh_ResetRenderTargets();
3009 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3011 r_meshbuffer_t *buffer;
3012 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3014 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3015 memset(buffer, 0, sizeof(*buffer));
3016 buffer->bufferobject = 0;
3017 buffer->devicebuffer = NULL;
3019 buffer->isindexbuffer = isindexbuffer;
3020 buffer->isdynamic = isdynamic;
3021 buffer->isindex16 = isindex16;
3022 strlcpy(buffer->name, name, sizeof(buffer->name));
3023 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3027 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3031 if (buffer->isindexbuffer)
3033 r_refdef.stats.indexbufferuploadcount++;
3034 r_refdef.stats.indexbufferuploadsize += size;
3038 r_refdef.stats.vertexbufferuploadcount++;
3039 r_refdef.stats.vertexbufferuploadsize += size;
3041 switch(vid.renderpath)
3043 case RENDERPATH_GL11:
3044 case RENDERPATH_GL13:
3045 case RENDERPATH_GL20:
3046 case RENDERPATH_CGGL:
3047 case RENDERPATH_GLES2:
3048 if (!buffer->bufferobject)
3049 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3050 if (buffer->isindexbuffer)
3051 GL_BindEBO(buffer->bufferobject);
3053 GL_BindVBO(buffer->bufferobject);
3054 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
3056 case RENDERPATH_D3D9:
3060 void *datapointer = NULL;
3061 if (buffer->isindexbuffer)
3063 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3064 if (size > buffer->size || !buffer->devicebuffer)
3066 if (buffer->devicebuffer)
3067 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3068 buffer->devicebuffer = NULL;
3069 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)))
3070 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);
3071 buffer->devicebuffer = (void *)d3d9indexbuffer;
3072 buffer->size = size;
3074 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3077 memcpy(datapointer, data, size);
3079 memset(datapointer, 0, size);
3080 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3085 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3086 if (size > buffer->size || !buffer->devicebuffer)
3088 if (buffer->devicebuffer)
3089 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3090 buffer->devicebuffer = NULL;
3091 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3092 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);
3093 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3094 buffer->size = size;
3096 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3099 memcpy(datapointer, data, size);
3101 memset(datapointer, 0, size);
3102 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3108 case RENDERPATH_D3D10:
3109 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3111 case RENDERPATH_D3D11:
3112 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3114 case RENDERPATH_SOFT:
3119 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3123 switch(vid.renderpath)
3125 case RENDERPATH_GL11:
3126 case RENDERPATH_GL13:
3127 case RENDERPATH_GL20:
3128 case RENDERPATH_CGGL:
3129 case RENDERPATH_GLES2:
3130 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3132 case RENDERPATH_D3D9:
3134 if (gl_state.d3dvertexbuffer == (void *)buffer)
3135 gl_state.d3dvertexbuffer = NULL;
3136 if (buffer->devicebuffer)
3138 if (buffer->isindexbuffer)
3139 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3141 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3142 buffer->devicebuffer = NULL;
3146 case RENDERPATH_D3D10:
3147 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3149 case RENDERPATH_D3D11:
3150 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3152 case RENDERPATH_SOFT:
3155 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3158 void GL_Mesh_ListVBOs(qboolean printeach)
3161 size_t ebocount = 0, ebomemory = 0;
3162 size_t vbocount = 0, vbomemory = 0;
3163 r_meshbuffer_t *buffer;
3164 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3165 for (i = 0;i < endindex;i++)
3167 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3170 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)");}
3171 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)");}
3173 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);
3178 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3180 switch(vid.renderpath)
3182 case RENDERPATH_GL11:
3183 case RENDERPATH_GL13:
3184 case RENDERPATH_GL20:
3185 case RENDERPATH_CGGL:
3186 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)
3188 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3189 gl_state.pointer_vertex_components = components;
3190 gl_state.pointer_vertex_gltype = gltype;
3191 gl_state.pointer_vertex_stride = stride;
3192 gl_state.pointer_vertex_pointer = pointer;
3193 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3194 gl_state.pointer_vertex_offset = bufferoffset;
3196 GL_BindVBO(bufferobject);
3197 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3200 case RENDERPATH_GLES2:
3201 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)
3203 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3204 gl_state.pointer_vertex_components = components;
3205 gl_state.pointer_vertex_gltype = gltype;
3206 gl_state.pointer_vertex_stride = stride;
3207 gl_state.pointer_vertex_pointer = pointer;
3208 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3209 gl_state.pointer_vertex_offset = bufferoffset;
3211 GL_BindVBO(bufferobject);
3212 qglVertexAttribPointer(GLES2ATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3215 case RENDERPATH_D3D9:
3216 case RENDERPATH_D3D10:
3217 case RENDERPATH_D3D11:
3218 case RENDERPATH_SOFT:
3223 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3225 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3226 // the pointer only.
3227 switch(vid.renderpath)
3229 case RENDERPATH_GL11:
3230 case RENDERPATH_GL13:
3231 case RENDERPATH_GL20:
3232 case RENDERPATH_CGGL:
3236 // caller wants color array enabled
3237 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3238 if (!gl_state.pointer_color_enabled)
3240 gl_state.pointer_color_enabled = true;
3242 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3244 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)
3246 gl_state.pointer_color_components = components;
3247 gl_state.pointer_color_gltype = gltype;
3248 gl_state.pointer_color_stride = stride;
3249 gl_state.pointer_color_pointer = pointer;
3250 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3251 gl_state.pointer_color_offset = bufferoffset;
3253 GL_BindVBO(bufferobject);
3254 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3259 // caller wants color array disabled
3260 if (gl_state.pointer_color_enabled)
3262 gl_state.pointer_color_enabled = false;
3264 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3265 // when color array is on the glColor gets trashed, set it again
3266 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3270 case RENDERPATH_GLES2:
3274 // caller wants color array enabled
3275 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3276 if (!gl_state.pointer_color_enabled)
3278 gl_state.pointer_color_enabled = true;
3280 qglEnableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3282 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)
3284 gl_state.pointer_color_components = components;
3285 gl_state.pointer_color_gltype = gltype;
3286 gl_state.pointer_color_stride = stride;
3287 gl_state.pointer_color_pointer = pointer;
3288 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3289 gl_state.pointer_color_offset = bufferoffset;
3291 GL_BindVBO(bufferobject);
3292 qglVertexAttribPointer(GLES2ATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3297 // caller wants color array disabled
3298 if (gl_state.pointer_color_enabled)
3300 gl_state.pointer_color_enabled = false;
3302 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3303 // when color array is on the glColor gets trashed, set it again
3304 qglVertexAttrib4f(GLES2ATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3308 case RENDERPATH_D3D9:
3309 case RENDERPATH_D3D10:
3310 case RENDERPATH_D3D11:
3311 case RENDERPATH_SOFT:
3316 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)
3318 gltextureunit_t *unit = gl_state.units + unitnum;
3319 // update array settings
3320 // note: there is no need to check bufferobject here because all cases
3321 // that involve a valid bufferobject also supply a texcoord array
3322 switch(vid.renderpath)
3324 case RENDERPATH_GL11:
3325 case RENDERPATH_GL13:
3326 case RENDERPATH_GL20:
3327 case RENDERPATH_CGGL:
3331 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3332 // texture array unit is enabled, enable the array
3333 if (!unit->arrayenabled)
3335 unit->arrayenabled = true;
3336 GL_ClientActiveTexture(unitnum);
3337 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3340 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)
3342 unit->pointer_texcoord_components = components;
3343 unit->pointer_texcoord_gltype = gltype;
3344 unit->pointer_texcoord_stride = stride;
3345 unit->pointer_texcoord_pointer = pointer;
3346 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3347 unit->pointer_texcoord_offset = bufferoffset;
3348 GL_ClientActiveTexture(unitnum);
3349 GL_BindVBO(bufferobject);
3350 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3355 // texture array unit is disabled, disable the array
3356 if (unit->arrayenabled)
3358 unit->arrayenabled = false;
3359 GL_ClientActiveTexture(unitnum);
3360 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3364 case RENDERPATH_GLES2:
3368 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3369 // texture array unit is enabled, enable the array
3370 if (!unit->arrayenabled)
3372 unit->arrayenabled = true;
3373 qglEnableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3376 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)
3378 unit->pointer_texcoord_components = components;
3379 unit->pointer_texcoord_gltype = gltype;
3380 unit->pointer_texcoord_stride = stride;
3381 unit->pointer_texcoord_pointer = pointer;
3382 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3383 unit->pointer_texcoord_offset = bufferoffset;
3384 GL_BindVBO(bufferobject);
3385 qglVertexAttribPointer(unitnum+GLES2ATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3390 // texture array unit is disabled, disable the array
3391 if (unit->arrayenabled)
3393 unit->arrayenabled = false;
3394 qglDisableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3398 case RENDERPATH_D3D9:
3399 case RENDERPATH_D3D10:
3400 case RENDERPATH_D3D11:
3401 case RENDERPATH_SOFT:
3406 int R_Mesh_TexBound(unsigned int unitnum, int id)
3408 gltextureunit_t *unit = gl_state.units + unitnum;
3409 if (unitnum >= vid.teximageunits)
3411 if (id == GL_TEXTURE_2D)
3413 if (id == GL_TEXTURE_3D)
3415 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3416 return unit->tcubemap;
3420 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3422 switch(vid.renderpath)
3424 case RENDERPATH_GL11:
3425 case RENDERPATH_GL13:
3426 case RENDERPATH_GL20:
3427 case RENDERPATH_CGGL:
3428 case RENDERPATH_GLES2:
3429 R_Mesh_TexBind(0, tex);
3430 GL_ActiveTexture(0);CHECKGLERROR
3431 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3433 case RENDERPATH_D3D9:
3436 IDirect3DSurface9 *currentsurface = NULL;
3437 IDirect3DSurface9 *texturesurface = NULL;
3440 sourcerect.left = sx;
3441 sourcerect.top = sy;
3442 sourcerect.right = sx + width;
3443 sourcerect.bottom = sy + height;
3446 destrect.right = tx + width;
3447 destrect.bottom = ty + height;
3448 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3450 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3452 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3453 IDirect3DSurface9_Release(currentsurface);
3455 IDirect3DSurface9_Release(texturesurface);
3460 case RENDERPATH_D3D10:
3461 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3463 case RENDERPATH_D3D11:
3464 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3466 case RENDERPATH_SOFT:
3467 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3473 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};
3476 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3478 gltextureunit_t *unit = gl_state.units + unitnum;
3479 int tex2d, tex3d, texcubemap, texnum;
3480 if (unitnum >= vid.teximageunits)
3482 // if (unit->texture == tex)
3484 switch(vid.renderpath)
3486 case RENDERPATH_GL20:
3487 case RENDERPATH_CGGL:
3488 case RENDERPATH_GLES2:
3491 tex = r_texture_white;
3492 // not initialized enough yet...
3496 unit->texture = tex;
3497 texnum = R_GetTexture(tex);
3498 switch(tex->gltexturetypeenum)
3500 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3501 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3502 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;
3505 case RENDERPATH_GL13:
3506 case RENDERPATH_GL11:
3507 unit->texture = tex;
3513 texnum = R_GetTexture(tex);
3514 switch(tex->gltexturetypeenum)
3522 case GL_TEXTURE_CUBE_MAP_ARB:
3523 texcubemap = texnum;
3527 // update 2d texture binding
3528 if (unit->t2d != tex2d)
3530 GL_ActiveTexture(unitnum);
3535 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3542 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3546 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3548 // update 3d texture binding
3549 if (unit->t3d != tex3d)
3551 GL_ActiveTexture(unitnum);
3556 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3563 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3567 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3569 // update cubemap texture binding
3570 if (unit->tcubemap != texcubemap)
3572 GL_ActiveTexture(unitnum);
3575 if (unit->tcubemap == 0)
3577 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3584 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3587 unit->tcubemap = texcubemap;
3588 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3591 case RENDERPATH_D3D9:
3594 extern cvar_t gl_texture_anisotropy;
3597 tex = r_texture_white;
3598 // not initialized enough yet...
3602 if (unit->texture == tex)
3604 unit->texture = tex;
3605 // upload texture if needed
3607 R_RealGetTexture(tex);
3608 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3609 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3610 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3611 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3612 if (tex->d3daddressw)
3613 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3614 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3615 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3616 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3617 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3618 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3619 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3623 case RENDERPATH_D3D10:
3624 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3626 case RENDERPATH_D3D11:
3627 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3629 case RENDERPATH_SOFT:
3632 tex = r_texture_white;
3633 // not initialized enough yet...
3637 if (unit->texture == tex)
3639 unit->texture = tex;
3640 DPSOFTRAST_SetTexture(unitnum, R_GetTexture(tex));
3645 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3647 gltextureunit_t *unit = gl_state.units + unitnum;
3648 switch(vid.renderpath)
3650 case RENDERPATH_GL11:
3651 case RENDERPATH_GL13:
3652 case RENDERPATH_GL20:
3653 case RENDERPATH_CGGL:
3654 if (matrix && matrix->m[3][3])
3656 // texmatrix specified, check if it is different
3657 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3660 unit->texmatrixenabled = true;
3661 unit->matrix = *matrix;
3663 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3664 GL_ActiveTexture(unitnum);
3665 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3666 qglLoadMatrixf(glmatrix);CHECKGLERROR
3667 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3672 // no texmatrix specified, revert to identity
3673 if (unit->texmatrixenabled)
3675 unit->texmatrixenabled = false;
3676 unit->matrix = identitymatrix;
3678 GL_ActiveTexture(unitnum);
3679 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3680 qglLoadIdentity();CHECKGLERROR
3681 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3685 case RENDERPATH_D3D9:
3686 case RENDERPATH_D3D10:
3687 case RENDERPATH_D3D11:
3689 case RENDERPATH_SOFT:
3691 case RENDERPATH_GLES2:
3696 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3698 gltextureunit_t *unit = gl_state.units + unitnum;
3700 switch(vid.renderpath)
3702 case RENDERPATH_GL20:
3703 case RENDERPATH_CGGL:
3704 case RENDERPATH_GLES2:
3707 case RENDERPATH_GL13:
3708 // GL_ARB_texture_env_combine
3710 combinergb = GL_MODULATE;
3712 combinealpha = GL_MODULATE;
3717 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3719 if (combinergb == GL_DECAL)
3720 combinergb = GL_INTERPOLATE_ARB;
3721 if (unit->combine != GL_COMBINE_ARB)
3723 unit->combine = GL_COMBINE_ARB;
3724 GL_ActiveTexture(unitnum);
3725 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3726 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3728 if (unit->combinergb != combinergb)
3730 unit->combinergb = combinergb;
3731 GL_ActiveTexture(unitnum);
3732 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3734 if (unit->combinealpha != combinealpha)
3736 unit->combinealpha = combinealpha;
3737 GL_ActiveTexture(unitnum);
3738 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3740 if (unit->rgbscale != rgbscale)
3742 unit->rgbscale = rgbscale;
3743 GL_ActiveTexture(unitnum);
3744 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3746 if (unit->alphascale != alphascale)
3748 unit->alphascale = alphascale;
3749 GL_ActiveTexture(unitnum);
3750 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3755 if (unit->combine != combinergb)
3757 unit->combine = combinergb;
3758 GL_ActiveTexture(unitnum);
3759 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3763 case RENDERPATH_GL11:
3766 combinergb = GL_MODULATE;
3767 if (unit->combine != combinergb)
3769 unit->combine = combinergb;
3770 GL_ActiveTexture(unitnum);
3771 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3774 case RENDERPATH_D3D9:
3775 case RENDERPATH_D3D10:
3776 case RENDERPATH_D3D11:
3778 case RENDERPATH_SOFT:
3783 void R_Mesh_ResetTextureState(void)
3785 unsigned int unitnum;
3790 switch(vid.renderpath)
3792 case RENDERPATH_GL20:
3793 case RENDERPATH_CGGL:
3794 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3796 gltextureunit_t *unit = gl_state.units + unitnum;
3800 GL_ActiveTexture(unitnum);
3801 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3806 GL_ActiveTexture(unitnum);
3807 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3812 GL_ActiveTexture(unitnum);
3813 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3816 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3818 gltextureunit_t *unit = gl_state.units + unitnum;
3819 if (unit->arrayenabled)
3821 unit->arrayenabled = false;
3822 GL_ClientActiveTexture(unitnum);
3823 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3826 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3828 gltextureunit_t *unit = gl_state.units + unitnum;
3829 if (unit->texmatrixenabled)
3831 unit->texmatrixenabled = false;
3832 unit->matrix = identitymatrix;
3834 GL_ActiveTexture(unitnum);
3835 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3836 qglLoadIdentity();CHECKGLERROR
3837 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3841 case RENDERPATH_GL13:
3842 case RENDERPATH_GL11:
3843 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3845 gltextureunit_t *unit = gl_state.units + unitnum;
3849 GL_ActiveTexture(unitnum);
3850 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3851 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3856 GL_ActiveTexture(unitnum);
3857 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3858 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3863 GL_ActiveTexture(unitnum);
3864 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3865 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3867 if (unit->arrayenabled)
3869 unit->arrayenabled = false;
3870 GL_ClientActiveTexture(unitnum);
3871 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3873 if (unit->texmatrixenabled)
3875 unit->texmatrixenabled = false;
3876 unit->matrix = identitymatrix;
3878 GL_ActiveTexture(unitnum);
3879 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3880 qglLoadIdentity();CHECKGLERROR
3881 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3883 if (unit->combine != GL_MODULATE)
3885 unit->combine = GL_MODULATE;
3886 GL_ActiveTexture(unitnum);
3887 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3891 case RENDERPATH_D3D9:
3892 case RENDERPATH_D3D10:
3893 case RENDERPATH_D3D11:
3895 case RENDERPATH_SOFT:
3897 case RENDERPATH_GLES2:
3905 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3906 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3907 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3909 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3911 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3915 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3917 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3918 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3919 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3923 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3925 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3926 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3927 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3928 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3929 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3930 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3931 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3935 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
3936 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3937 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3940 static void R_Mesh_InitVertexDeclarations(void)
3943 r_vertex3f_d3d9decl = NULL;
3944 r_vertexgeneric_d3d9decl = NULL;
3945 r_vertexmesh_d3d9decl = NULL;
3946 switch(vid.renderpath)
3948 case RENDERPATH_GL20:
3949 case RENDERPATH_CGGL:
3950 case RENDERPATH_GL13:
3951 case RENDERPATH_GL11:
3952 case RENDERPATH_GLES2:
3954 case RENDERPATH_D3D9:
3955 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
3956 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3957 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3959 case RENDERPATH_D3D10:
3960 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3962 case RENDERPATH_D3D11:
3963 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3965 case RENDERPATH_SOFT:
3971 static void R_Mesh_DestroyVertexDeclarations(void)
3974 if (r_vertex3f_d3d9decl)
3975 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
3976 r_vertex3f_d3d9decl = NULL;
3977 if (r_vertexgeneric_d3d9decl)
3978 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3979 r_vertexgeneric_d3d9decl = NULL;
3980 if (r_vertexmesh_d3d9decl)
3981 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3982 r_vertexmesh_d3d9decl = NULL;
3986 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
3988 // upload temporary vertexbuffer for this rendering
3989 if (!gl_state.usevbo_staticvertex)
3990 vertexbuffer = NULL;
3991 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3993 if (gl_state.preparevertices_dynamicvertexbuffer)
3994 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
3996 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
3997 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3999 switch(vid.renderpath)
4001 case RENDERPATH_GL20:
4002 case RENDERPATH_CGGL:
4003 case RENDERPATH_GLES2:
4006 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4007 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4008 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4009 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4010 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4011 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4012 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4016 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4017 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4018 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4019 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4020 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4021 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4022 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4025 case RENDERPATH_GL13:
4028 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4029 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4030 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4031 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4035 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4036 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4037 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4038 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4041 case RENDERPATH_GL11:
4044 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4045 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4046 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4050 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4051 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4052 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4055 case RENDERPATH_D3D9:
4057 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4059 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4061 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4062 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4063 gl_state.d3dvertexdata = (void *)vertex3f;
4064 gl_state.d3dvertexsize = sizeof(float[3]);
4067 case RENDERPATH_D3D10:
4068 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4070 case RENDERPATH_D3D11:
4071 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4073 case RENDERPATH_SOFT:
4074 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4075 DPSOFTRAST_SetColorPointer(NULL, 0);
4076 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4077 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4078 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4079 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4080 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4087 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4090 size = sizeof(r_vertexgeneric_t) * numvertices;
4091 if (gl_state.preparevertices_tempdatamaxsize < size)
4093 gl_state.preparevertices_tempdatamaxsize = size;
4094 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4096 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4097 gl_state.preparevertices_numvertices = numvertices;
4098 return gl_state.preparevertices_vertexgeneric;
4101 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4103 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4104 gl_state.preparevertices_vertexgeneric = NULL;
4105 gl_state.preparevertices_numvertices = 0;
4109 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4112 r_vertexgeneric_t *vertex;
4113 switch(vid.renderpath)
4115 case RENDERPATH_GL20:
4116 case RENDERPATH_CGGL:
4117 case RENDERPATH_GLES2:
4118 if (!vid.useinterleavedarrays)
4120 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4121 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4122 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4123 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4124 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4125 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4126 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4130 case RENDERPATH_GL13:
4131 case RENDERPATH_GL11:
4132 if (!vid.useinterleavedarrays)
4134 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4135 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4136 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4137 if (vid.texunits >= 2)
4138 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4139 if (vid.texunits >= 3)
4140 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4144 case RENDERPATH_D3D9:
4145 case RENDERPATH_D3D10:
4146 case RENDERPATH_D3D11:
4148 case RENDERPATH_SOFT:
4149 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4150 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4151 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4152 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4153 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4154 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4155 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4159 // no quick path for this case, convert to vertex structs
4160 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4161 for (i = 0;i < numvertices;i++)
4162 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4165 for (i = 0;i < numvertices;i++)
4166 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4170 float tempcolor4f[4];
4171 unsigned char tempcolor4ub[4];
4172 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4173 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4174 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4175 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4176 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4177 for (i = 0;i < numvertices;i++)
4178 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4181 for (i = 0;i < numvertices;i++)
4182 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4183 R_Mesh_PrepareVertices_Generic_Unlock();
4184 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4187 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4189 // upload temporary vertexbuffer for this rendering
4190 if (!gl_state.usevbo_staticvertex)
4191 vertexbuffer = NULL;
4192 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4194 if (gl_state.preparevertices_dynamicvertexbuffer)
4195 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4197 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4198 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4200 switch(vid.renderpath)
4202 case RENDERPATH_GL20:
4203 case RENDERPATH_CGGL:
4204 case RENDERPATH_GLES2:
4207 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4208 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4209 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4210 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4211 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4212 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4213 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4217 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4218 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4219 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4220 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4221 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4222 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4223 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4226 case RENDERPATH_GL13:
4229 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4230 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4231 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4232 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4236 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4237 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4238 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4239 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4242 case RENDERPATH_GL11:
4245 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4246 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4247 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4251 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4252 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4253 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4256 case RENDERPATH_D3D9:
4258 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4260 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4262 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4263 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4264 gl_state.d3dvertexdata = (void *)vertex;
4265 gl_state.d3dvertexsize = sizeof(*vertex);
4268 case RENDERPATH_D3D10:
4269 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4271 case RENDERPATH_D3D11:
4272 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4274 case RENDERPATH_SOFT:
4275 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4276 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4277 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4278 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4279 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4280 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4281 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4288 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4291 size = sizeof(r_vertexmesh_t) * numvertices;
4292 if (gl_state.preparevertices_tempdatamaxsize < size)
4294 gl_state.preparevertices_tempdatamaxsize = size;
4295 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4297 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4298 gl_state.preparevertices_numvertices = numvertices;
4299 return gl_state.preparevertices_vertexmesh;
4302 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4304 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4305 gl_state.preparevertices_vertexmesh = NULL;
4306 gl_state.preparevertices_numvertices = 0;
4310 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)
4313 r_vertexmesh_t *vertex;
4314 switch(vid.renderpath)
4316 case RENDERPATH_GL20:
4317 case RENDERPATH_CGGL:
4318 case RENDERPATH_GLES2:
4319 if (!vid.useinterleavedarrays)
4321 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4322 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4323 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4324 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4325 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4326 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4327 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4331 case RENDERPATH_GL13:
4332 case RENDERPATH_GL11:
4333 if (!vid.useinterleavedarrays)
4335 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4336 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4337 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4338 if (vid.texunits >= 2)
4339 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4340 if (vid.texunits >= 3)
4341 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4345 case RENDERPATH_D3D9:
4346 case RENDERPATH_D3D10:
4347 case RENDERPATH_D3D11:
4349 case RENDERPATH_SOFT:
4350 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4351 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4352 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4353 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4354 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4355 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4356 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4360 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4361 for (i = 0;i < numvertices;i++)
4362 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4364 for (i = 0;i < numvertices;i++)
4365 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4367 for (i = 0;i < numvertices;i++)
4368 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4370 for (i = 0;i < numvertices;i++)
4371 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4374 for (i = 0;i < numvertices;i++)
4375 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4379 float tempcolor4f[4];
4380 unsigned char tempcolor4ub[4];
4381 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4382 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4383 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4384 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4385 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4386 for (i = 0;i < numvertices;i++)
4387 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4389 if (texcoordtexture2f)
4390 for (i = 0;i < numvertices;i++)
4391 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4392 if (texcoordlightmap2f)
4393 for (i = 0;i < numvertices;i++)
4394 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4395 R_Mesh_PrepareVertices_Mesh_Unlock();
4396 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4399 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4401 // upload temporary vertexbuffer for this rendering
4402 if (!gl_state.usevbo_staticvertex)
4403 vertexbuffer = NULL;
4404 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4406 if (gl_state.preparevertices_dynamicvertexbuffer)
4407 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4409 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4410 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4412 switch(vid.renderpath)
4414 case RENDERPATH_GL20:
4415 case RENDERPATH_CGGL:
4416 case RENDERPATH_GLES2:
4419 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4420 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4421 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4422 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4423 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4424 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4425 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4429 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4430 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4431 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4432 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4433 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4434 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4435 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4438 case RENDERPATH_GL13:
4441 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4442 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4443 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4444 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4448 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4449 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4450 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4451 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4454 case RENDERPATH_GL11:
4457 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4458 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4459 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4463 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4464 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4465 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4468 case RENDERPATH_D3D9:
4470 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4472 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4474 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4475 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4476 gl_state.d3dvertexdata = (void *)vertex;
4477 gl_state.d3dvertexsize = sizeof(*vertex);
4480 case RENDERPATH_D3D10:
4481 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4483 case RENDERPATH_D3D11:
4484 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4486 case RENDERPATH_SOFT:
4487 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4488 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4489 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4490 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4491 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4492 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4493 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);