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 if (vid.support.ext_framebuffer_object)
1564 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.defaultframebufferobject);
1565 qglEnableVertexAttribArray(GLES2ATTRIB_POSITION);
1566 qglVertexAttribPointer(GLES2ATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
1567 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);
1568 qglVertexAttribPointer(GLES2ATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
1569 qglVertexAttrib4f(GLES2ATTRIB_COLOR, 1, 1, 1, 1);
1570 gl_state.unit = MAX_TEXTUREUNITS;
1571 gl_state.clientunit = MAX_TEXTUREUNITS;
1572 for (i = 0;i < vid.teximageunits;i++)
1574 GL_ActiveTexture(i);
1575 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1576 if (vid.support.ext_texture_3d)
1578 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1580 if (vid.support.arb_texture_cube_map)
1582 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1585 for (i = 0;i < vid.texarrayunits;i++)
1588 qglVertexAttribPointer(i+GLES2ATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
1589 qglDisableVertexAttribArray(i+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
1596 void GL_ActiveTexture(unsigned int num)
1598 if (gl_state.unit != num)
1600 gl_state.unit = num;
1601 switch(vid.renderpath)
1603 case RENDERPATH_GL11:
1604 case RENDERPATH_GL13:
1605 case RENDERPATH_GL20:
1606 case RENDERPATH_CGGL:
1607 case RENDERPATH_GLES2:
1608 if (qglActiveTexture)
1611 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1615 case RENDERPATH_D3D9:
1616 case RENDERPATH_D3D10:
1617 case RENDERPATH_D3D11:
1619 case RENDERPATH_SOFT:
1625 void GL_ClientActiveTexture(unsigned int num)
1627 if (gl_state.clientunit != num)
1629 gl_state.clientunit = num;
1630 switch(vid.renderpath)
1632 case RENDERPATH_GL11:
1633 case RENDERPATH_GL13:
1634 case RENDERPATH_GL20:
1635 case RENDERPATH_CGGL:
1636 if (qglActiveTexture)
1639 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1643 case RENDERPATH_D3D9:
1644 case RENDERPATH_D3D10:
1645 case RENDERPATH_D3D11:
1647 case RENDERPATH_SOFT:
1649 case RENDERPATH_GLES2:
1655 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1657 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1659 qboolean blendenable;
1660 gl_state.blendfunc1 = blendfunc1;
1661 gl_state.blendfunc2 = blendfunc2;
1662 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1663 switch(vid.renderpath)
1665 case RENDERPATH_GL11:
1666 case RENDERPATH_GL13:
1667 case RENDERPATH_GL20:
1668 case RENDERPATH_CGGL:
1669 case RENDERPATH_GLES2:
1671 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1672 if (gl_state.blend != blendenable)
1674 gl_state.blend = blendenable;
1675 if (!gl_state.blend)
1677 qglDisable(GL_BLEND);CHECKGLERROR
1681 qglEnable(GL_BLEND);CHECKGLERROR
1685 case RENDERPATH_D3D9:
1690 D3DBLEND d3dblendfunc[2];
1691 glblendfunc[0] = gl_state.blendfunc1;
1692 glblendfunc[1] = gl_state.blendfunc2;
1693 for (i = 0;i < 2;i++)
1695 switch(glblendfunc[i])
1697 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1698 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1699 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1700 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1701 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1702 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1703 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1704 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1705 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1706 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1709 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1710 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1711 if (gl_state.blend != blendenable)
1713 gl_state.blend = blendenable;
1714 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1719 case RENDERPATH_D3D10:
1720 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1722 case RENDERPATH_D3D11:
1723 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1725 case RENDERPATH_SOFT:
1726 DPSOFTRAST_BlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);
1732 void GL_DepthMask(int state)
1734 if (gl_state.depthmask != state)
1736 gl_state.depthmask = state;
1737 switch(vid.renderpath)
1739 case RENDERPATH_GL11:
1740 case RENDERPATH_GL13:
1741 case RENDERPATH_GL20:
1742 case RENDERPATH_CGGL:
1743 case RENDERPATH_GLES2:
1745 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1747 case RENDERPATH_D3D9:
1749 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1752 case RENDERPATH_D3D10:
1753 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1755 case RENDERPATH_D3D11:
1756 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1758 case RENDERPATH_SOFT:
1759 DPSOFTRAST_DepthMask(gl_state.depthmask);
1765 void GL_DepthTest(int state)
1767 if (gl_state.depthtest != state)
1769 gl_state.depthtest = state;
1770 switch(vid.renderpath)
1772 case RENDERPATH_GL11:
1773 case RENDERPATH_GL13:
1774 case RENDERPATH_GL20:
1775 case RENDERPATH_CGGL:
1776 case RENDERPATH_GLES2:
1778 if (gl_state.depthtest)
1780 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1784 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1787 case RENDERPATH_D3D9:
1789 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1792 case RENDERPATH_D3D10:
1793 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1795 case RENDERPATH_D3D11:
1796 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1798 case RENDERPATH_SOFT:
1799 DPSOFTRAST_DepthTest(gl_state.depthtest);
1805 void GL_DepthFunc(int state)
1807 if (gl_state.depthfunc != state)
1809 gl_state.depthfunc = state;
1810 switch(vid.renderpath)
1812 case RENDERPATH_GL11:
1813 case RENDERPATH_GL13:
1814 case RENDERPATH_GL20:
1815 case RENDERPATH_CGGL:
1816 case RENDERPATH_GLES2:
1818 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1820 case RENDERPATH_D3D9:
1822 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1825 case RENDERPATH_D3D10:
1826 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1828 case RENDERPATH_D3D11:
1829 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1831 case RENDERPATH_SOFT:
1832 DPSOFTRAST_DepthFunc(gl_state.depthfunc);
1838 void GL_DepthRange(float nearfrac, float farfrac)
1840 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1842 gl_state.depthrange[0] = nearfrac;
1843 gl_state.depthrange[1] = farfrac;
1844 switch(vid.renderpath)
1846 case RENDERPATH_GL11:
1847 case RENDERPATH_GL13:
1848 case RENDERPATH_GL20:
1849 case RENDERPATH_CGGL:
1850 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1852 case RENDERPATH_D3D9:
1855 D3DVIEWPORT9 d3dviewport;
1856 d3dviewport.X = gl_viewport.x;
1857 d3dviewport.Y = gl_viewport.y;
1858 d3dviewport.Width = gl_viewport.width;
1859 d3dviewport.Height = gl_viewport.height;
1860 d3dviewport.MinZ = gl_state.depthrange[0];
1861 d3dviewport.MaxZ = gl_state.depthrange[1];
1862 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1866 case RENDERPATH_D3D10:
1867 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1869 case RENDERPATH_D3D11:
1870 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1872 case RENDERPATH_SOFT:
1873 DPSOFTRAST_DepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1875 case RENDERPATH_GLES2:
1876 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1877 // FIXME: qglDepthRangef instead... faster...
1878 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1884 void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask)
1886 switch (vid.renderpath)
1888 case RENDERPATH_GL11:
1889 case RENDERPATH_GL13:
1890 case RENDERPATH_GL20:
1891 case RENDERPATH_CGGL:
1895 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1899 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1901 if (vid.support.ati_separate_stencil)
1903 qglStencilMask(writemask);CHECKGLERROR
1904 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1905 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1906 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1908 else if (vid.support.ext_stencil_two_side)
1910 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1911 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1912 qglStencilMask(writemask);CHECKGLERROR
1913 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1914 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1915 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1916 qglStencilMask(writemask);CHECKGLERROR
1917 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1918 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1921 case RENDERPATH_D3D9:
1923 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1924 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1925 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1926 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1927 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1928 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1929 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1930 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1931 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1932 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1933 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1934 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1935 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1938 case RENDERPATH_D3D10:
1939 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1941 case RENDERPATH_D3D11:
1942 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1944 case RENDERPATH_SOFT:
1945 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1947 case RENDERPATH_GLES2:
1948 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1953 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1955 switch (vid.renderpath)
1957 case RENDERPATH_GL11:
1958 case RENDERPATH_GL13:
1959 case RENDERPATH_GL20:
1960 case RENDERPATH_CGGL:
1961 case RENDERPATH_GLES2:
1965 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1969 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1971 if (vid.support.ext_stencil_two_side)
1973 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1975 qglStencilMask(writemask);CHECKGLERROR
1976 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1977 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1980 case RENDERPATH_D3D9:
1982 if (vid.support.ati_separate_stencil)
1983 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1984 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1985 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1986 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1987 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1988 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1989 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1990 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1991 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1994 case RENDERPATH_D3D10:
1995 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1997 case RENDERPATH_D3D11:
1998 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2000 case RENDERPATH_SOFT:
2001 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2006 void GL_PolygonOffset(float planeoffset, float depthoffset)
2008 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
2010 gl_state.polygonoffset[0] = planeoffset;
2011 gl_state.polygonoffset[1] = depthoffset;
2012 switch(vid.renderpath)
2014 case RENDERPATH_GL11:
2015 case RENDERPATH_GL13:
2016 case RENDERPATH_GL20:
2017 case RENDERPATH_CGGL:
2018 case RENDERPATH_GLES2:
2019 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2021 case RENDERPATH_D3D9:
2023 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
2024 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
2027 case RENDERPATH_D3D10:
2028 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2030 case RENDERPATH_D3D11:
2031 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2033 case RENDERPATH_SOFT:
2034 DPSOFTRAST_PolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
2040 void GL_SetMirrorState(qboolean state)
2042 if (v_flipped_state != state)
2044 v_flipped_state = state;
2045 if (gl_state.cullface == GL_BACK)
2046 gl_state.cullface = GL_FRONT;
2047 else if (gl_state.cullface == GL_FRONT)
2048 gl_state.cullface = GL_BACK;
2051 switch(vid.renderpath)
2053 case RENDERPATH_GL11:
2054 case RENDERPATH_GL13:
2055 case RENDERPATH_GL20:
2056 case RENDERPATH_CGGL:
2057 case RENDERPATH_GLES2:
2058 qglCullFace(gl_state.cullface);
2060 case RENDERPATH_D3D9:
2062 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
2065 case RENDERPATH_D3D10:
2066 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2068 case RENDERPATH_D3D11:
2069 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2071 case RENDERPATH_SOFT:
2072 DPSOFTRAST_CullFace(gl_state.cullface);
2078 void GL_CullFace(int state)
2082 if(state == GL_FRONT)
2084 else if(state == GL_BACK)
2088 switch(vid.renderpath)
2090 case RENDERPATH_GL11:
2091 case RENDERPATH_GL13:
2092 case RENDERPATH_GL20:
2093 case RENDERPATH_CGGL:
2094 case RENDERPATH_GLES2:
2097 if (state != GL_NONE)
2099 if (!gl_state.cullfaceenable)
2101 gl_state.cullfaceenable = true;
2102 qglEnable(GL_CULL_FACE);CHECKGLERROR
2104 if (gl_state.cullface != state)
2106 gl_state.cullface = state;
2107 qglCullFace(gl_state.cullface);CHECKGLERROR
2112 if (gl_state.cullfaceenable)
2114 gl_state.cullfaceenable = false;
2115 qglDisable(GL_CULL_FACE);CHECKGLERROR
2119 case RENDERPATH_D3D9:
2121 if (gl_state.cullface != state)
2123 gl_state.cullface = state;
2124 switch(gl_state.cullface)
2127 gl_state.cullfaceenable = false;
2128 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
2131 gl_state.cullfaceenable = true;
2132 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
2135 gl_state.cullfaceenable = true;
2136 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
2142 case RENDERPATH_D3D10:
2143 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2145 case RENDERPATH_D3D11:
2146 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2148 case RENDERPATH_SOFT:
2149 if (gl_state.cullface != state)
2151 gl_state.cullface = state;
2152 gl_state.cullfaceenable = state != GL_NONE ? true : false;
2153 DPSOFTRAST_CullFace(gl_state.cullface);
2159 void GL_AlphaTest(int state)
2161 if (gl_state.alphatest != state)
2163 gl_state.alphatest = state;
2164 switch(vid.renderpath)
2166 case RENDERPATH_GL11:
2167 case RENDERPATH_GL13:
2168 case RENDERPATH_GL20:
2169 case RENDERPATH_CGGL:
2171 if (gl_state.alphatest)
2173 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
2177 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
2180 case RENDERPATH_D3D9:
2182 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
2185 case RENDERPATH_D3D10:
2186 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2188 case RENDERPATH_D3D11:
2189 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2191 case RENDERPATH_SOFT:
2192 DPSOFTRAST_AlphaTest(gl_state.alphatest);
2194 case RENDERPATH_GLES2:
2200 void GL_AlphaFunc(int state, float value)
2202 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
2204 gl_state.alphafunc = state;
2205 gl_state.alphafuncvalue = value;
2206 switch(vid.renderpath)
2208 case RENDERPATH_GL11:
2209 case RENDERPATH_GL13:
2210 case RENDERPATH_GL20:
2211 case RENDERPATH_CGGL:
2213 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
2215 case RENDERPATH_D3D9:
2217 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
2218 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
2221 case RENDERPATH_D3D10:
2222 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2224 case RENDERPATH_D3D11:
2225 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2227 case RENDERPATH_SOFT:
2228 DPSOFTRAST_AlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);
2230 case RENDERPATH_GLES2:
2236 void GL_ColorMask(int r, int g, int b, int a)
2238 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
2239 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
2240 if (gl_state.colormask != state)
2242 gl_state.colormask = state;
2243 switch(vid.renderpath)
2245 case RENDERPATH_GL11:
2246 case RENDERPATH_GL13:
2247 case RENDERPATH_GL20:
2248 case RENDERPATH_CGGL:
2249 case RENDERPATH_GLES2:
2251 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
2253 case RENDERPATH_D3D9:
2255 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
2258 case RENDERPATH_D3D10:
2259 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2261 case RENDERPATH_D3D11:
2262 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2264 case RENDERPATH_SOFT:
2265 DPSOFTRAST_ColorMask(r, g, b, a);
2271 void GL_Color(float cr, float cg, float cb, float ca)
2273 if (gl_state.pointer_color_enabled || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca)
2275 gl_state.color4f[0] = cr;
2276 gl_state.color4f[1] = cg;
2277 gl_state.color4f[2] = cb;
2278 gl_state.color4f[3] = ca;
2279 switch(vid.renderpath)
2281 case RENDERPATH_GL11:
2282 case RENDERPATH_GL13:
2283 case RENDERPATH_GL20:
2284 case RENDERPATH_CGGL:
2286 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
2289 case RENDERPATH_D3D9:
2290 case RENDERPATH_D3D10:
2291 case RENDERPATH_D3D11:
2292 // no equivalent in D3D
2294 case RENDERPATH_SOFT:
2295 DPSOFTRAST_Color4f(cr, cg, cb, ca);
2297 case RENDERPATH_GLES2:
2298 qglVertexAttrib4f(GLES2ATTRIB_COLOR, cr, cg, cb, ca);
2304 void GL_Scissor (int x, int y, int width, int height)
2306 switch(vid.renderpath)
2308 case RENDERPATH_GL11:
2309 case RENDERPATH_GL13:
2310 case RENDERPATH_GL20:
2311 case RENDERPATH_CGGL:
2312 case RENDERPATH_GLES2:
2314 qglScissor(x, y,width,height);
2317 case RENDERPATH_D3D9:
2323 d3drect.right = x + width;
2324 d3drect.bottom = y + height;
2325 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
2329 case RENDERPATH_D3D10:
2330 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2332 case RENDERPATH_D3D11:
2333 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2335 case RENDERPATH_SOFT:
2336 DPSOFTRAST_Scissor(x, y, width, height);
2341 void GL_ScissorTest(int state)
2343 if (gl_state.scissortest != state)
2345 gl_state.scissortest = state;
2346 switch(vid.renderpath)
2348 case RENDERPATH_GL11:
2349 case RENDERPATH_GL13:
2350 case RENDERPATH_GL20:
2351 case RENDERPATH_CGGL:
2352 case RENDERPATH_GLES2:
2354 if(gl_state.scissortest)
2355 qglEnable(GL_SCISSOR_TEST);
2357 qglDisable(GL_SCISSOR_TEST);
2360 case RENDERPATH_D3D9:
2362 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2365 case RENDERPATH_D3D10:
2366 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2368 case RENDERPATH_D3D11:
2369 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2371 case RENDERPATH_SOFT:
2372 DPSOFTRAST_ScissorTest(gl_state.scissortest);
2378 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2380 static const float blackcolor[4] = {0, 0, 0, 0};
2381 // prevent warnings when trying to clear a buffer that does not exist
2383 colorvalue = blackcolor;
2386 mask &= ~GL_STENCIL_BUFFER_BIT;
2389 switch(vid.renderpath)
2391 case RENDERPATH_GL11:
2392 case RENDERPATH_GL13:
2393 case RENDERPATH_GL20:
2394 case RENDERPATH_CGGL:
2395 case RENDERPATH_GLES2:
2397 if (mask & GL_COLOR_BUFFER_BIT)
2399 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2401 if (mask & GL_DEPTH_BUFFER_BIT)
2403 qglClearDepth(depthvalue);CHECKGLERROR
2405 if (mask & GL_STENCIL_BUFFER_BIT)
2407 qglClearStencil(stencilvalue);CHECKGLERROR
2409 qglClear(mask);CHECKGLERROR
2411 case RENDERPATH_D3D9:
2413 IDirect3DDevice9_Clear(vid_d3d9dev, 0, NULL, ((mask & GL_COLOR_BUFFER_BIT) ? D3DCLEAR_TARGET : 0) | ((mask & GL_STENCIL_BUFFER_BIT) ? D3DCLEAR_STENCIL : 0) | ((mask & GL_DEPTH_BUFFER_BIT) ? D3DCLEAR_ZBUFFER : 0), D3DCOLOR_COLORVALUE(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]), depthvalue, stencilvalue);
2416 case RENDERPATH_D3D10:
2417 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2419 case RENDERPATH_D3D11:
2420 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2422 case RENDERPATH_SOFT:
2423 if (mask & GL_COLOR_BUFFER_BIT)
2424 DPSOFTRAST_ClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);
2425 if (mask & GL_DEPTH_BUFFER_BIT)
2426 DPSOFTRAST_ClearDepth(depthvalue);
2431 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2433 switch(vid.renderpath)
2435 case RENDERPATH_GL11:
2436 case RENDERPATH_GL13:
2437 case RENDERPATH_GL20:
2438 case RENDERPATH_CGGL:
2439 case RENDERPATH_GLES2:
2441 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2443 case RENDERPATH_D3D9:
2446 // LordHavoc: we can't directly download the backbuffer because it may be
2447 // multisampled, and it may not be lockable, so we blit it to a lockable
2448 // surface of the same dimensions (but without multisample) to resolve the
2449 // multisample buffer to a normal image, and then lock that...
2450 IDirect3DSurface9 *stretchsurface = NULL;
2451 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2453 D3DLOCKED_RECT lockedrect;
2454 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2456 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2459 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2460 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2461 memcpy(outpixels + line * width * 4, row, width * 4);
2462 IDirect3DSurface9_UnlockRect(stretchsurface);
2465 IDirect3DSurface9_Release(stretchsurface);
2468 //IDirect3DSurface9 *syssurface = NULL;
2469 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2470 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2471 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2472 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2473 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2474 //IDirect3DSurface9_UnlockRect(syssurface);
2475 //IDirect3DSurface9_Release(syssurface);
2479 case RENDERPATH_D3D10:
2480 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2482 case RENDERPATH_D3D11:
2483 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2485 case RENDERPATH_SOFT:
2486 DPSOFTRAST_GetPixelsBGRA(x, y, width, height, outpixels);
2491 // called at beginning of frame
2492 void R_Mesh_Start(void)
2495 R_Mesh_ResetRenderTargets();
2497 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2499 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2500 Cvar_SetValueQuick(&gl_paranoid, 1);
2504 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2508 char compilelog[MAX_INPUTLINE];
2509 shaderobject = qglCreateShader(shadertypeenum);CHECKGLERROR
2512 qglShaderSource(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2513 qglCompileShader(shaderobject);CHECKGLERROR
2514 qglGetShaderiv(shaderobject, GL_COMPILE_STATUS, &shadercompiled);CHECKGLERROR
2515 qglGetShaderInfoLog(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2516 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2518 int i, j, pretextlines = 0;
2519 for (i = 0;i < numstrings - 1;i++)
2520 for (j = 0;strings[i][j];j++)
2521 if (strings[i][j] == '\n')
2523 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2525 if (!shadercompiled)
2527 qglDeleteShader(shaderobject);CHECKGLERROR
2530 qglAttachShader(programobject, shaderobject);CHECKGLERROR
2531 qglDeleteShader(shaderobject);CHECKGLERROR
2535 unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list)
2537 GLint programlinked;
2538 GLuint programobject = 0;
2539 char linklog[MAX_INPUTLINE];
2542 programobject = qglCreateProgram();CHECKGLERROR
2546 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
2549 #ifdef GL_GEOMETRY_SHADER
2550 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list))
2554 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER, "fragment", fragmentstrings_count, fragmentstrings_list))
2557 qglLinkProgram(programobject);CHECKGLERROR
2558 qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR
2559 qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2562 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2563 Con_DPrintf("program link log:\n%s\n", linklog);
2564 // software vertex shader is ok but software fragment shader is WAY
2565 // too slow, fail program if so.
2566 // NOTE: this string might be ATI specific, but that's ok because the
2567 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2568 // software fragment shader due to low instruction and dependent
2570 if (strstr(linklog, "fragment shader will run in software"))
2571 programlinked = false;
2575 return programobject;
2577 qglDeleteProgram(programobject);CHECKGLERROR
2581 void GL_Backend_FreeProgram(unsigned int prog)
2584 qglDeleteProgram(prog);
2588 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2593 for (i = 0;i < count;i++)
2594 *out++ = *in++ + offset;
2597 memcpy(out, in, sizeof(*out) * count);
2600 // renders triangles using vertices from the active arrays
2601 int paranoidblah = 0;
2602 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)
2604 unsigned int numelements = numtriangles * 3;
2606 size_t bufferoffset3i;
2608 size_t bufferoffset3s;
2609 if (numvertices < 3 || numtriangles < 1)
2611 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2612 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);
2615 if (!gl_mesh_prefer_short_elements.integer)
2619 if (element3i_indexbuffer)
2620 element3i_indexbuffer = NULL;
2622 // adjust the pointers for firsttriangle
2624 element3i += firsttriangle * 3;
2625 if (element3i_indexbuffer)
2626 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2628 element3s += firsttriangle * 3;
2629 if (element3s_indexbuffer)
2630 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2631 switch(vid.renderpath)
2633 case RENDERPATH_GL11:
2634 case RENDERPATH_GL13:
2635 case RENDERPATH_GL20:
2636 case RENDERPATH_CGGL:
2637 case RENDERPATH_GLES2:
2638 // check if the user specified to ignore static index buffers
2639 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2641 element3i_indexbuffer = NULL;
2642 element3s_indexbuffer = NULL;
2645 case RENDERPATH_D3D9:
2646 case RENDERPATH_D3D10:
2647 case RENDERPATH_D3D11:
2649 case RENDERPATH_SOFT:
2652 // upload a dynamic index buffer if needed
2655 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2657 if (gl_state.draw_dynamicindexbuffer)
2658 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2660 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2661 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2662 element3s_bufferoffset = 0;
2667 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2669 if (gl_state.draw_dynamicindexbuffer)
2670 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2672 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2673 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2674 element3i_bufferoffset = 0;
2677 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2678 bufferoffset3i = element3i_bufferoffset;
2679 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2680 bufferoffset3s = element3s_bufferoffset;
2681 r_refdef.stats.draws++;
2682 r_refdef.stats.draws_vertices += numvertices;
2683 r_refdef.stats.draws_elements += numelements;
2684 if (gl_paranoid.integer)
2687 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2689 unsigned int j, size;
2691 // note: there's no validation done here on buffer objects because it
2692 // is somewhat difficult to get at the data, and gl_paranoid can be
2693 // used without buffer objects if the need arises
2694 // (the data could be gotten using glMapBuffer but it would be very
2695 // slow due to uncachable video memory reads)
2696 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2697 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2699 if (gl_state.pointer_vertex_pointer)
2700 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2702 if (gl_state.pointer_color_enabled)
2704 if (!qglIsEnabled(GL_COLOR_ARRAY))
2705 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2707 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2708 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2711 for (i = 0;i < vid.texarrayunits;i++)
2713 if (gl_state.units[i].arrayenabled)
2715 GL_ClientActiveTexture(i);
2716 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2717 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2719 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2720 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++)
2727 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2729 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2731 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2738 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2740 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2742 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2748 if (r_render.integer || r_refdef.draw2dstage)
2750 switch(vid.renderpath)
2752 case RENDERPATH_GL11:
2753 case RENDERPATH_GL13:
2754 case RENDERPATH_GL20:
2755 case RENDERPATH_CGGL:
2757 if (gl_mesh_testmanualfeeding.integer)
2759 unsigned int i, j, element;
2761 qglBegin(GL_TRIANGLES);
2762 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2765 element = element3i[i];
2767 element = element3s[i];
2769 element = firstvertex + i;
2770 for (j = 0;j < vid.texarrayunits;j++)
2772 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2774 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2776 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2777 if (vid.texarrayunits > 1)
2779 if (gl_state.units[j].pointer_texcoord_components == 4)
2780 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2781 else if (gl_state.units[j].pointer_texcoord_components == 3)
2782 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2783 else if (gl_state.units[j].pointer_texcoord_components == 2)
2784 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2786 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2790 if (gl_state.units[j].pointer_texcoord_components == 4)
2791 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2792 else if (gl_state.units[j].pointer_texcoord_components == 3)
2793 qglTexCoord3f(p[0], p[1], p[2]);
2794 else if (gl_state.units[j].pointer_texcoord_components == 2)
2795 qglTexCoord2f(p[0], p[1]);
2797 qglTexCoord1f(p[0]);
2800 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2802 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2803 if (vid.texarrayunits > 1)
2805 if (gl_state.units[j].pointer_texcoord_components == 4)
2806 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2807 else if (gl_state.units[j].pointer_texcoord_components == 3)
2808 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2809 else if (gl_state.units[j].pointer_texcoord_components == 2)
2810 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2811 else if (gl_state.units[j].pointer_texcoord_components == 1)
2812 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2816 if (gl_state.units[j].pointer_texcoord_components == 4)
2817 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2818 else if (gl_state.units[j].pointer_texcoord_components == 3)
2819 qglTexCoord3f(s[0], s[1], s[2]);
2820 else if (gl_state.units[j].pointer_texcoord_components == 2)
2821 qglTexCoord2f(s[0], s[1]);
2822 else if (gl_state.units[j].pointer_texcoord_components == 1)
2823 qglTexCoord1f(s[0]);
2826 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2828 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2829 if (vid.texarrayunits > 1)
2831 if (gl_state.units[j].pointer_texcoord_components == 4)
2832 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2833 else if (gl_state.units[j].pointer_texcoord_components == 3)
2834 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2835 else if (gl_state.units[j].pointer_texcoord_components == 2)
2836 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2837 else if (gl_state.units[j].pointer_texcoord_components == 1)
2838 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2842 if (gl_state.units[j].pointer_texcoord_components == 4)
2843 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2844 else if (gl_state.units[j].pointer_texcoord_components == 3)
2845 qglTexCoord3f(sb[0], sb[1], sb[2]);
2846 else if (gl_state.units[j].pointer_texcoord_components == 2)
2847 qglTexCoord2f(sb[0], sb[1]);
2848 else if (gl_state.units[j].pointer_texcoord_components == 1)
2849 qglTexCoord1f(sb[0]);
2854 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2856 if (gl_state.pointer_color_gltype == GL_FLOAT)
2858 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2859 qglColor4f(p[0], p[1], p[2], p[3]);
2861 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2863 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2864 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2867 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2869 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2870 if (gl_state.pointer_vertex_components == 4)
2871 qglVertex4f(p[0], p[1], p[2], p[3]);
2872 else if (gl_state.pointer_vertex_components == 3)
2873 qglVertex3f(p[0], p[1], p[2]);
2875 qglVertex2f(p[0], p[1]);
2881 else if (bufferobject3s)
2883 GL_BindEBO(bufferobject3s);
2884 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2886 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2891 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2895 else if (bufferobject3i)
2897 GL_BindEBO(bufferobject3i);
2898 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2900 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2905 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2912 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2914 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2919 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2926 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2928 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2933 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2939 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2943 case RENDERPATH_D3D9:
2945 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2947 if (element3s_indexbuffer)
2949 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2950 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2952 else if (element3i_indexbuffer)
2954 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2955 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2958 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2963 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2965 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2967 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *)gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2971 case RENDERPATH_D3D10:
2972 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2974 case RENDERPATH_D3D11:
2975 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2977 case RENDERPATH_SOFT:
2978 DPSOFTRAST_DrawTriangles(firstvertex, numvertices, numtriangles, element3i, element3s);
2980 case RENDERPATH_GLES2:
2981 // GLES does not have glDrawRangeElements, and generally
2982 // underperforms with index buffers, so this code path is
2983 // relatively straightforward...
2984 //if (qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
2985 // Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject);
2988 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2993 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2998 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
3006 // restores backend state, used when done with 3D rendering
3007 void R_Mesh_Finish(void)
3009 R_Mesh_ResetRenderTargets();
3012 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
3014 r_meshbuffer_t *buffer;
3015 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
3017 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
3018 memset(buffer, 0, sizeof(*buffer));
3019 buffer->bufferobject = 0;
3020 buffer->devicebuffer = NULL;
3022 buffer->isindexbuffer = isindexbuffer;
3023 buffer->isdynamic = isdynamic;
3024 buffer->isindex16 = isindex16;
3025 strlcpy(buffer->name, name, sizeof(buffer->name));
3026 R_Mesh_UpdateMeshBuffer(buffer, data, size);
3030 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
3034 if (buffer->isindexbuffer)
3036 r_refdef.stats.indexbufferuploadcount++;
3037 r_refdef.stats.indexbufferuploadsize += size;
3041 r_refdef.stats.vertexbufferuploadcount++;
3042 r_refdef.stats.vertexbufferuploadsize += size;
3044 switch(vid.renderpath)
3046 case RENDERPATH_GL11:
3047 case RENDERPATH_GL13:
3048 case RENDERPATH_GL20:
3049 case RENDERPATH_CGGL:
3050 case RENDERPATH_GLES2:
3051 if (!buffer->bufferobject)
3052 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
3053 if (buffer->isindexbuffer)
3054 GL_BindEBO(buffer->bufferobject);
3056 GL_BindVBO(buffer->bufferobject);
3057 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
3059 case RENDERPATH_D3D9:
3063 void *datapointer = NULL;
3064 if (buffer->isindexbuffer)
3066 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
3067 if (size > buffer->size || !buffer->devicebuffer)
3069 if (buffer->devicebuffer)
3070 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
3071 buffer->devicebuffer = NULL;
3072 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)))
3073 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);
3074 buffer->devicebuffer = (void *)d3d9indexbuffer;
3075 buffer->size = size;
3077 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3080 memcpy(datapointer, data, size);
3082 memset(datapointer, 0, size);
3083 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
3088 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
3089 if (size > buffer->size || !buffer->devicebuffer)
3091 if (buffer->devicebuffer)
3092 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
3093 buffer->devicebuffer = NULL;
3094 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
3095 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);
3096 buffer->devicebuffer = (void *)d3d9vertexbuffer;
3097 buffer->size = size;
3099 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
3102 memcpy(datapointer, data, size);
3104 memset(datapointer, 0, size);
3105 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
3111 case RENDERPATH_D3D10:
3112 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3114 case RENDERPATH_D3D11:
3115 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3117 case RENDERPATH_SOFT:
3122 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
3126 switch(vid.renderpath)
3128 case RENDERPATH_GL11:
3129 case RENDERPATH_GL13:
3130 case RENDERPATH_GL20:
3131 case RENDERPATH_CGGL:
3132 case RENDERPATH_GLES2:
3133 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
3135 case RENDERPATH_D3D9:
3137 if (gl_state.d3dvertexbuffer == (void *)buffer)
3138 gl_state.d3dvertexbuffer = NULL;
3139 if (buffer->devicebuffer)
3141 if (buffer->isindexbuffer)
3142 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
3144 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
3145 buffer->devicebuffer = NULL;
3149 case RENDERPATH_D3D10:
3150 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3152 case RENDERPATH_D3D11:
3153 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3155 case RENDERPATH_SOFT:
3158 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
3161 void GL_Mesh_ListVBOs(qboolean printeach)
3164 size_t ebocount = 0, ebomemory = 0;
3165 size_t vbocount = 0, vbomemory = 0;
3166 r_meshbuffer_t *buffer;
3167 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
3168 for (i = 0;i < endindex;i++)
3170 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
3173 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)");}
3174 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)");}
3176 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);
3181 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3183 switch(vid.renderpath)
3185 case RENDERPATH_GL11:
3186 case RENDERPATH_GL13:
3187 case RENDERPATH_GL20:
3188 case RENDERPATH_CGGL:
3189 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)
3191 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3192 gl_state.pointer_vertex_components = components;
3193 gl_state.pointer_vertex_gltype = gltype;
3194 gl_state.pointer_vertex_stride = stride;
3195 gl_state.pointer_vertex_pointer = pointer;
3196 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3197 gl_state.pointer_vertex_offset = bufferoffset;
3199 GL_BindVBO(bufferobject);
3200 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3203 case RENDERPATH_GLES2:
3204 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)
3206 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3207 gl_state.pointer_vertex_components = components;
3208 gl_state.pointer_vertex_gltype = gltype;
3209 gl_state.pointer_vertex_stride = stride;
3210 gl_state.pointer_vertex_pointer = pointer;
3211 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
3212 gl_state.pointer_vertex_offset = bufferoffset;
3214 GL_BindVBO(bufferobject);
3215 qglVertexAttribPointer(GLES2ATTRIB_POSITION, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3218 case RENDERPATH_D3D9:
3219 case RENDERPATH_D3D10:
3220 case RENDERPATH_D3D11:
3221 case RENDERPATH_SOFT:
3226 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
3228 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
3229 // the pointer only.
3230 switch(vid.renderpath)
3232 case RENDERPATH_GL11:
3233 case RENDERPATH_GL13:
3234 case RENDERPATH_GL20:
3235 case RENDERPATH_CGGL:
3239 // caller wants color array enabled
3240 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3241 if (!gl_state.pointer_color_enabled)
3243 gl_state.pointer_color_enabled = true;
3245 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3247 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)
3249 gl_state.pointer_color_components = components;
3250 gl_state.pointer_color_gltype = gltype;
3251 gl_state.pointer_color_stride = stride;
3252 gl_state.pointer_color_pointer = pointer;
3253 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3254 gl_state.pointer_color_offset = bufferoffset;
3256 GL_BindVBO(bufferobject);
3257 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3262 // caller wants color array disabled
3263 if (gl_state.pointer_color_enabled)
3265 gl_state.pointer_color_enabled = false;
3267 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
3268 // when color array is on the glColor gets trashed, set it again
3269 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3273 case RENDERPATH_GLES2:
3277 // caller wants color array enabled
3278 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3279 if (!gl_state.pointer_color_enabled)
3281 gl_state.pointer_color_enabled = true;
3283 qglEnableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3285 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)
3287 gl_state.pointer_color_components = components;
3288 gl_state.pointer_color_gltype = gltype;
3289 gl_state.pointer_color_stride = stride;
3290 gl_state.pointer_color_pointer = pointer;
3291 gl_state.pointer_color_vertexbuffer = vertexbuffer;
3292 gl_state.pointer_color_offset = bufferoffset;
3294 GL_BindVBO(bufferobject);
3295 qglVertexAttribPointer(GLES2ATTRIB_COLOR, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3300 // caller wants color array disabled
3301 if (gl_state.pointer_color_enabled)
3303 gl_state.pointer_color_enabled = false;
3305 qglDisableVertexAttribArray(GLES2ATTRIB_COLOR);CHECKGLERROR
3306 // when color array is on the glColor gets trashed, set it again
3307 qglVertexAttrib4f(GLES2ATTRIB_COLOR, gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
3311 case RENDERPATH_D3D9:
3312 case RENDERPATH_D3D10:
3313 case RENDERPATH_D3D11:
3314 case RENDERPATH_SOFT:
3319 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)
3321 gltextureunit_t *unit = gl_state.units + unitnum;
3322 // update array settings
3323 // note: there is no need to check bufferobject here because all cases
3324 // that involve a valid bufferobject also supply a texcoord array
3325 switch(vid.renderpath)
3327 case RENDERPATH_GL11:
3328 case RENDERPATH_GL13:
3329 case RENDERPATH_GL20:
3330 case RENDERPATH_CGGL:
3334 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3335 // texture array unit is enabled, enable the array
3336 if (!unit->arrayenabled)
3338 unit->arrayenabled = true;
3339 GL_ClientActiveTexture(unitnum);
3340 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3343 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)
3345 unit->pointer_texcoord_components = components;
3346 unit->pointer_texcoord_gltype = gltype;
3347 unit->pointer_texcoord_stride = stride;
3348 unit->pointer_texcoord_pointer = pointer;
3349 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3350 unit->pointer_texcoord_offset = bufferoffset;
3351 GL_ClientActiveTexture(unitnum);
3352 GL_BindVBO(bufferobject);
3353 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3358 // texture array unit is disabled, disable the array
3359 if (unit->arrayenabled)
3361 unit->arrayenabled = false;
3362 GL_ClientActiveTexture(unitnum);
3363 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3367 case RENDERPATH_GLES2:
3371 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
3372 // texture array unit is enabled, enable the array
3373 if (!unit->arrayenabled)
3375 unit->arrayenabled = true;
3376 qglEnableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3379 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)
3381 unit->pointer_texcoord_components = components;
3382 unit->pointer_texcoord_gltype = gltype;
3383 unit->pointer_texcoord_stride = stride;
3384 unit->pointer_texcoord_pointer = pointer;
3385 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
3386 unit->pointer_texcoord_offset = bufferoffset;
3387 GL_BindVBO(bufferobject);
3388 qglVertexAttribPointer(unitnum+GLES2ATTRIB_TEXCOORD0, components, gltype, false, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
3393 // texture array unit is disabled, disable the array
3394 if (unit->arrayenabled)
3396 unit->arrayenabled = false;
3397 qglDisableVertexAttribArray(unitnum+GLES2ATTRIB_TEXCOORD0);CHECKGLERROR
3401 case RENDERPATH_D3D9:
3402 case RENDERPATH_D3D10:
3403 case RENDERPATH_D3D11:
3404 case RENDERPATH_SOFT:
3409 int R_Mesh_TexBound(unsigned int unitnum, int id)
3411 gltextureunit_t *unit = gl_state.units + unitnum;
3412 if (unitnum >= vid.teximageunits)
3414 if (id == GL_TEXTURE_2D)
3416 if (id == GL_TEXTURE_3D)
3418 if (id == GL_TEXTURE_CUBE_MAP_ARB)
3419 return unit->tcubemap;
3423 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
3425 switch(vid.renderpath)
3427 case RENDERPATH_GL11:
3428 case RENDERPATH_GL13:
3429 case RENDERPATH_GL20:
3430 case RENDERPATH_CGGL:
3431 case RENDERPATH_GLES2:
3432 R_Mesh_TexBind(0, tex);
3433 GL_ActiveTexture(0);CHECKGLERROR
3434 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
3436 case RENDERPATH_D3D9:
3439 IDirect3DSurface9 *currentsurface = NULL;
3440 IDirect3DSurface9 *texturesurface = NULL;
3443 sourcerect.left = sx;
3444 sourcerect.top = sy;
3445 sourcerect.right = sx + width;
3446 sourcerect.bottom = sy + height;
3449 destrect.right = tx + width;
3450 destrect.bottom = ty + height;
3451 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
3453 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
3455 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
3456 IDirect3DSurface9_Release(currentsurface);
3458 IDirect3DSurface9_Release(texturesurface);
3463 case RENDERPATH_D3D10:
3464 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3466 case RENDERPATH_D3D11:
3467 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3469 case RENDERPATH_SOFT:
3470 DPSOFTRAST_CopyRectangleToTexture(tex->texnum, 0, tx, ty, sx, sy, width, height);
3476 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};
3479 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
3481 gltextureunit_t *unit = gl_state.units + unitnum;
3482 int tex2d, tex3d, texcubemap, texnum;
3483 if (unitnum >= vid.teximageunits)
3485 // if (unit->texture == tex)
3487 switch(vid.renderpath)
3489 case RENDERPATH_GL20:
3490 case RENDERPATH_CGGL:
3491 case RENDERPATH_GLES2:
3494 tex = r_texture_white;
3495 // not initialized enough yet...
3499 unit->texture = tex;
3500 texnum = R_GetTexture(tex);
3501 switch(tex->gltexturetypeenum)
3503 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
3504 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
3505 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;
3508 case RENDERPATH_GL13:
3509 case RENDERPATH_GL11:
3510 unit->texture = tex;
3516 texnum = R_GetTexture(tex);
3517 switch(tex->gltexturetypeenum)
3525 case GL_TEXTURE_CUBE_MAP_ARB:
3526 texcubemap = texnum;
3530 // update 2d texture binding
3531 if (unit->t2d != tex2d)
3533 GL_ActiveTexture(unitnum);
3538 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3545 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3549 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3551 // update 3d texture binding
3552 if (unit->t3d != tex3d)
3554 GL_ActiveTexture(unitnum);
3559 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3566 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3570 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3572 // update cubemap texture binding
3573 if (unit->tcubemap != texcubemap)
3575 GL_ActiveTexture(unitnum);
3578 if (unit->tcubemap == 0)
3580 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3587 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3590 unit->tcubemap = texcubemap;
3591 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3594 case RENDERPATH_D3D9:
3597 extern cvar_t gl_texture_anisotropy;
3600 tex = r_texture_white;
3601 // not initialized enough yet...
3605 // upload texture if needed
3607 if (unit->texture == tex)
3609 unit->texture = tex;
3610 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3611 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3612 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3613 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3614 if (tex->d3daddressw)
3615 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3616 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3617 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3618 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3619 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3620 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3621 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3625 case RENDERPATH_D3D10:
3626 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3628 case RENDERPATH_D3D11:
3629 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3631 case RENDERPATH_SOFT:
3634 tex = r_texture_white;
3635 // not initialized enough yet...
3639 texnum = R_GetTexture(tex);
3640 if (unit->texture == tex)
3642 unit->texture = tex;
3643 DPSOFTRAST_SetTexture(unitnum, texnum);
3648 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3650 gltextureunit_t *unit = gl_state.units + unitnum;
3651 switch(vid.renderpath)
3653 case RENDERPATH_GL11:
3654 case RENDERPATH_GL13:
3655 case RENDERPATH_GL20:
3656 case RENDERPATH_CGGL:
3657 if (matrix && matrix->m[3][3])
3659 // texmatrix specified, check if it is different
3660 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3663 unit->texmatrixenabled = true;
3664 unit->matrix = *matrix;
3666 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3667 GL_ActiveTexture(unitnum);
3668 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3669 qglLoadMatrixf(glmatrix);CHECKGLERROR
3670 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3675 // no texmatrix specified, revert to identity
3676 if (unit->texmatrixenabled)
3678 unit->texmatrixenabled = false;
3679 unit->matrix = identitymatrix;
3681 GL_ActiveTexture(unitnum);
3682 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3683 qglLoadIdentity();CHECKGLERROR
3684 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3688 case RENDERPATH_D3D9:
3689 case RENDERPATH_D3D10:
3690 case RENDERPATH_D3D11:
3692 case RENDERPATH_SOFT:
3694 case RENDERPATH_GLES2:
3699 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3701 gltextureunit_t *unit = gl_state.units + unitnum;
3703 switch(vid.renderpath)
3705 case RENDERPATH_GL20:
3706 case RENDERPATH_CGGL:
3707 case RENDERPATH_GLES2:
3710 case RENDERPATH_GL13:
3711 // GL_ARB_texture_env_combine
3713 combinergb = GL_MODULATE;
3715 combinealpha = GL_MODULATE;
3720 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3722 if (combinergb == GL_DECAL)
3723 combinergb = GL_INTERPOLATE_ARB;
3724 if (unit->combine != GL_COMBINE_ARB)
3726 unit->combine = GL_COMBINE_ARB;
3727 GL_ActiveTexture(unitnum);
3728 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3729 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3731 if (unit->combinergb != combinergb)
3733 unit->combinergb = combinergb;
3734 GL_ActiveTexture(unitnum);
3735 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3737 if (unit->combinealpha != combinealpha)
3739 unit->combinealpha = combinealpha;
3740 GL_ActiveTexture(unitnum);
3741 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3743 if (unit->rgbscale != rgbscale)
3745 unit->rgbscale = rgbscale;
3746 GL_ActiveTexture(unitnum);
3747 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3749 if (unit->alphascale != alphascale)
3751 unit->alphascale = alphascale;
3752 GL_ActiveTexture(unitnum);
3753 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3758 if (unit->combine != combinergb)
3760 unit->combine = combinergb;
3761 GL_ActiveTexture(unitnum);
3762 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3766 case RENDERPATH_GL11:
3769 combinergb = GL_MODULATE;
3770 if (unit->combine != combinergb)
3772 unit->combine = combinergb;
3773 GL_ActiveTexture(unitnum);
3774 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3777 case RENDERPATH_D3D9:
3778 case RENDERPATH_D3D10:
3779 case RENDERPATH_D3D11:
3781 case RENDERPATH_SOFT:
3786 void R_Mesh_ResetTextureState(void)
3788 unsigned int unitnum;
3793 switch(vid.renderpath)
3795 case RENDERPATH_GL20:
3796 case RENDERPATH_CGGL:
3797 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3799 gltextureunit_t *unit = gl_state.units + unitnum;
3803 GL_ActiveTexture(unitnum);
3804 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3809 GL_ActiveTexture(unitnum);
3810 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3815 GL_ActiveTexture(unitnum);
3816 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3819 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3821 gltextureunit_t *unit = gl_state.units + unitnum;
3822 if (unit->arrayenabled)
3824 unit->arrayenabled = false;
3825 GL_ClientActiveTexture(unitnum);
3826 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3829 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3831 gltextureunit_t *unit = gl_state.units + unitnum;
3832 if (unit->texmatrixenabled)
3834 unit->texmatrixenabled = false;
3835 unit->matrix = identitymatrix;
3837 GL_ActiveTexture(unitnum);
3838 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3839 qglLoadIdentity();CHECKGLERROR
3840 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3844 case RENDERPATH_GL13:
3845 case RENDERPATH_GL11:
3846 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3848 gltextureunit_t *unit = gl_state.units + unitnum;
3852 GL_ActiveTexture(unitnum);
3853 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3854 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3859 GL_ActiveTexture(unitnum);
3860 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3861 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3866 GL_ActiveTexture(unitnum);
3867 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3868 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3870 if (unit->arrayenabled)
3872 unit->arrayenabled = false;
3873 GL_ClientActiveTexture(unitnum);
3874 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3876 if (unit->texmatrixenabled)
3878 unit->texmatrixenabled = false;
3879 unit->matrix = identitymatrix;
3881 GL_ActiveTexture(unitnum);
3882 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3883 qglLoadIdentity();CHECKGLERROR
3884 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3886 if (unit->combine != GL_MODULATE)
3888 unit->combine = GL_MODULATE;
3889 GL_ActiveTexture(unitnum);
3890 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3894 case RENDERPATH_D3D9:
3895 case RENDERPATH_D3D10:
3896 case RENDERPATH_D3D11:
3898 case RENDERPATH_SOFT:
3900 case RENDERPATH_GLES2:
3908 //#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
3909 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3910 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3912 D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
3914 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3918 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3920 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3921 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3922 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3926 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3928 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3929 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3930 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3931 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3932 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3933 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3934 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3938 IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
3939 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3940 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3943 static void R_Mesh_InitVertexDeclarations(void)
3946 r_vertex3f_d3d9decl = NULL;
3947 r_vertexgeneric_d3d9decl = NULL;
3948 r_vertexmesh_d3d9decl = NULL;
3949 switch(vid.renderpath)
3951 case RENDERPATH_GL20:
3952 case RENDERPATH_CGGL:
3953 case RENDERPATH_GL13:
3954 case RENDERPATH_GL11:
3955 case RENDERPATH_GLES2:
3957 case RENDERPATH_D3D9:
3958 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
3959 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3960 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3962 case RENDERPATH_D3D10:
3963 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3965 case RENDERPATH_D3D11:
3966 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3968 case RENDERPATH_SOFT:
3974 static void R_Mesh_DestroyVertexDeclarations(void)
3977 if (r_vertex3f_d3d9decl)
3978 IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
3979 r_vertex3f_d3d9decl = NULL;
3980 if (r_vertexgeneric_d3d9decl)
3981 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3982 r_vertexgeneric_d3d9decl = NULL;
3983 if (r_vertexmesh_d3d9decl)
3984 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3985 r_vertexmesh_d3d9decl = NULL;
3989 void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer)
3991 // upload temporary vertexbuffer for this rendering
3992 if (!gl_state.usevbo_staticvertex)
3993 vertexbuffer = NULL;
3994 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3996 if (gl_state.preparevertices_dynamicvertexbuffer)
3997 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex3f, numvertices * sizeof(float[3]));
3999 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex3f, numvertices * sizeof(float[3]), "temporary", false, true, false);
4000 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4002 switch(vid.renderpath)
4004 case RENDERPATH_GL20:
4005 case RENDERPATH_CGGL:
4006 case RENDERPATH_GLES2:
4009 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4010 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4011 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4012 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4013 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4014 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4015 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4019 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4020 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4021 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4022 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4023 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4024 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4025 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4028 case RENDERPATH_GL13:
4031 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4032 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4033 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4034 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4038 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4039 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4040 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4041 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4044 case RENDERPATH_GL11:
4047 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4048 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4049 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4053 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
4054 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
4055 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4058 case RENDERPATH_D3D9:
4060 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9decl);
4062 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(float[3]));
4064 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4065 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4066 gl_state.d3dvertexdata = (void *)vertex3f;
4067 gl_state.d3dvertexsize = sizeof(float[3]);
4070 case RENDERPATH_D3D10:
4071 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4073 case RENDERPATH_D3D11:
4074 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4076 case RENDERPATH_SOFT:
4077 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4078 DPSOFTRAST_SetColorPointer(NULL, 0);
4079 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), NULL);
4080 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4081 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4082 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4083 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4090 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
4093 size = sizeof(r_vertexgeneric_t) * numvertices;
4094 if (gl_state.preparevertices_tempdatamaxsize < size)
4096 gl_state.preparevertices_tempdatamaxsize = size;
4097 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4099 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
4100 gl_state.preparevertices_numvertices = numvertices;
4101 return gl_state.preparevertices_vertexgeneric;
4104 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
4106 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
4107 gl_state.preparevertices_vertexgeneric = NULL;
4108 gl_state.preparevertices_numvertices = 0;
4112 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
4115 r_vertexgeneric_t *vertex;
4116 switch(vid.renderpath)
4118 case RENDERPATH_GL20:
4119 case RENDERPATH_CGGL:
4120 case RENDERPATH_GLES2:
4121 if (!vid.useinterleavedarrays)
4123 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4124 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4125 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4126 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4127 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4128 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4129 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4133 case RENDERPATH_GL13:
4134 case RENDERPATH_GL11:
4135 if (!vid.useinterleavedarrays)
4137 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4138 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4139 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
4140 if (vid.texunits >= 2)
4141 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4142 if (vid.texunits >= 3)
4143 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4147 case RENDERPATH_D3D9:
4148 case RENDERPATH_D3D10:
4149 case RENDERPATH_D3D11:
4151 case RENDERPATH_SOFT:
4152 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4153 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4154 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoord2f);
4155 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(float[2]), NULL);
4156 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(float[2]), NULL);
4157 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(float[2]), NULL);
4158 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), NULL);
4162 // no quick path for this case, convert to vertex structs
4163 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
4164 for (i = 0;i < numvertices;i++)
4165 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4168 for (i = 0;i < numvertices;i++)
4169 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4173 float tempcolor4f[4];
4174 unsigned char tempcolor4ub[4];
4175 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4176 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4177 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4178 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4179 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4180 for (i = 0;i < numvertices;i++)
4181 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4184 for (i = 0;i < numvertices;i++)
4185 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
4186 R_Mesh_PrepareVertices_Generic_Unlock();
4187 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
4190 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
4192 // upload temporary vertexbuffer for this rendering
4193 if (!gl_state.usevbo_staticvertex)
4194 vertexbuffer = NULL;
4195 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4197 if (gl_state.preparevertices_dynamicvertexbuffer)
4198 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4200 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4201 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4203 switch(vid.renderpath)
4205 case RENDERPATH_GL20:
4206 case RENDERPATH_CGGL:
4207 case RENDERPATH_GLES2:
4210 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4211 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4212 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4213 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4214 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4215 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4216 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4220 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4221 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4222 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4223 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4224 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4225 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4226 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4229 case RENDERPATH_GL13:
4232 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4233 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4234 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4235 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4239 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4240 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4241 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4242 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4245 case RENDERPATH_GL11:
4248 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4249 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4250 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
4254 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4255 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4256 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
4259 case RENDERPATH_D3D9:
4261 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
4263 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4265 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4266 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4267 gl_state.d3dvertexdata = (void *)vertex;
4268 gl_state.d3dvertexsize = sizeof(*vertex);
4271 case RENDERPATH_D3D10:
4272 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4274 case RENDERPATH_D3D11:
4275 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4277 case RENDERPATH_SOFT:
4278 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4279 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4280 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoord2f);
4281 DPSOFTRAST_SetTexCoordPointer(1, 2, sizeof(*vertex), NULL);
4282 DPSOFTRAST_SetTexCoordPointer(2, 2, sizeof(*vertex), NULL);
4283 DPSOFTRAST_SetTexCoordPointer(3, 2, sizeof(*vertex), NULL);
4284 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), NULL);
4291 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
4294 size = sizeof(r_vertexmesh_t) * numvertices;
4295 if (gl_state.preparevertices_tempdatamaxsize < size)
4297 gl_state.preparevertices_tempdatamaxsize = size;
4298 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
4300 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
4301 gl_state.preparevertices_numvertices = numvertices;
4302 return gl_state.preparevertices_vertexmesh;
4305 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
4307 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
4308 gl_state.preparevertices_vertexmesh = NULL;
4309 gl_state.preparevertices_numvertices = 0;
4313 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)
4316 r_vertexmesh_t *vertex;
4317 switch(vid.renderpath)
4319 case RENDERPATH_GL20:
4320 case RENDERPATH_CGGL:
4321 case RENDERPATH_GLES2:
4322 if (!vid.useinterleavedarrays)
4324 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4325 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4326 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4327 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
4328 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
4329 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
4330 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4334 case RENDERPATH_GL13:
4335 case RENDERPATH_GL11:
4336 if (!vid.useinterleavedarrays)
4338 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
4339 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
4340 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
4341 if (vid.texunits >= 2)
4342 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
4343 if (vid.texunits >= 3)
4344 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
4348 case RENDERPATH_D3D9:
4349 case RENDERPATH_D3D10:
4350 case RENDERPATH_D3D11:
4352 case RENDERPATH_SOFT:
4353 DPSOFTRAST_SetVertexPointer(vertex3f, sizeof(float[3]));
4354 DPSOFTRAST_SetColorPointer(color4f, sizeof(float[4]));
4355 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(float[2]), texcoordtexture2f);
4356 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(float[3]), svector3f);
4357 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(float[3]), tvector3f);
4358 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(float[3]), normal3f);
4359 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(float[2]), texcoordlightmap2f);
4363 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
4364 for (i = 0;i < numvertices;i++)
4365 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
4367 for (i = 0;i < numvertices;i++)
4368 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
4370 for (i = 0;i < numvertices;i++)
4371 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
4373 for (i = 0;i < numvertices;i++)
4374 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
4377 for (i = 0;i < numvertices;i++)
4378 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
4382 float tempcolor4f[4];
4383 unsigned char tempcolor4ub[4];
4384 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
4385 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
4386 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
4387 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
4388 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
4389 for (i = 0;i < numvertices;i++)
4390 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
4392 if (texcoordtexture2f)
4393 for (i = 0;i < numvertices;i++)
4394 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
4395 if (texcoordlightmap2f)
4396 for (i = 0;i < numvertices;i++)
4397 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
4398 R_Mesh_PrepareVertices_Mesh_Unlock();
4399 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
4402 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
4404 // upload temporary vertexbuffer for this rendering
4405 if (!gl_state.usevbo_staticvertex)
4406 vertexbuffer = NULL;
4407 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
4409 if (gl_state.preparevertices_dynamicvertexbuffer)
4410 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
4412 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
4413 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
4415 switch(vid.renderpath)
4417 case RENDERPATH_GL20:
4418 case RENDERPATH_CGGL:
4419 case RENDERPATH_GLES2:
4422 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4423 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4424 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4425 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
4426 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
4427 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
4428 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4432 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4433 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4434 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4435 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
4436 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
4437 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
4438 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4441 case RENDERPATH_GL13:
4444 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4445 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4446 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4447 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
4451 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4452 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4453 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4454 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
4457 case RENDERPATH_GL11:
4460 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
4461 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
4462 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
4466 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
4467 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
4468 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
4471 case RENDERPATH_D3D9:
4473 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
4475 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
4477 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
4478 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
4479 gl_state.d3dvertexdata = (void *)vertex;
4480 gl_state.d3dvertexsize = sizeof(*vertex);
4483 case RENDERPATH_D3D10:
4484 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4486 case RENDERPATH_D3D11:
4487 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
4489 case RENDERPATH_SOFT:
4490 DPSOFTRAST_SetVertexPointer(vertex->vertex3f, sizeof(*vertex));
4491 DPSOFTRAST_SetColorPointer4ub(vertex->color4ub, sizeof(*vertex));
4492 DPSOFTRAST_SetTexCoordPointer(0, 2, sizeof(*vertex), vertex->texcoordtexture2f);
4493 DPSOFTRAST_SetTexCoordPointer(1, 3, sizeof(*vertex), vertex->svector3f);
4494 DPSOFTRAST_SetTexCoordPointer(2, 3, sizeof(*vertex), vertex->tvector3f);
4495 DPSOFTRAST_SetTexCoordPointer(3, 3, sizeof(*vertex), vertex->normal3f);
4496 DPSOFTRAST_SetTexCoordPointer(4, 2, sizeof(*vertex), vertex->texcoordlightmap2f);