3 #include "cl_collision.h"
6 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
7 extern D3DCAPS9 vid_d3d9caps;
10 #define MAX_RENDERTARGETS 4
12 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
13 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)"};
14 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"};
15 cvar_t gl_mesh_separatearrays = {0, "gl_mesh_separatearrays", "1", "use several separate vertex arrays rather than one combined stream"};
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 qboolean pointer_color_enabled;
152 int pointer_vertex_components;
153 int pointer_vertex_gltype;
154 size_t pointer_vertex_stride;
155 const void *pointer_vertex_pointer;
156 const r_meshbuffer_t *pointer_vertex_vertexbuffer;
157 size_t pointer_vertex_offset;
159 int pointer_color_components;
160 int pointer_color_gltype;
161 size_t pointer_color_stride;
162 const void *pointer_color_pointer;
163 const r_meshbuffer_t *pointer_color_vertexbuffer;
164 size_t pointer_color_offset;
166 void *preparevertices_tempdata;
167 size_t preparevertices_tempdatamaxsize;
168 r_meshbuffer_t *preparevertices_dynamicvertexbuffer;
169 r_vertexposition_t *preparevertices_vertexposition;
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__);
297 static void gl_backend_start(void)
299 memset(&gl_state, 0, sizeof(gl_state));
301 R_Mesh_InitVertexDeclarations();
304 Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
306 Con_DPrintf("OpenGL backend started.\n");
310 GL_Backend_ResetState();
312 switch(vid.renderpath)
314 case RENDERPATH_GL11:
315 case RENDERPATH_GL13:
316 case RENDERPATH_GL20:
317 case RENDERPATH_CGGL:
319 case RENDERPATH_D3D9:
321 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
322 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
325 case RENDERPATH_D3D10:
326 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
328 case RENDERPATH_D3D11:
329 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
334 static void gl_backend_shutdown(void)
336 Con_DPrint("OpenGL Backend shutting down\n");
338 switch(vid.renderpath)
340 case RENDERPATH_GL11:
341 case RENDERPATH_GL13:
342 case RENDERPATH_GL20:
343 case RENDERPATH_CGGL:
345 case RENDERPATH_D3D9:
347 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
348 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
351 case RENDERPATH_D3D10:
352 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
354 case RENDERPATH_D3D11:
355 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
359 if (gl_state.preparevertices_tempdata)
360 Mem_Free(gl_state.preparevertices_tempdata);
361 if (gl_state.preparevertices_dynamicvertexbuffer)
362 R_Mesh_DestroyMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer);
364 Mem_ExpandableArray_FreeArray(&gl_state.meshbufferarray);
366 R_Mesh_DestroyVertexDeclarations();
368 memset(&gl_state, 0, sizeof(gl_state));
371 static void gl_backend_newmap(void)
375 static void gl_backend_devicelost(void)
378 r_meshbuffer_t *buffer;
380 gl_state.d3dvertexbuffer = NULL;
382 switch(vid.renderpath)
384 case RENDERPATH_GL11:
385 case RENDERPATH_GL13:
386 case RENDERPATH_GL20:
387 case RENDERPATH_CGGL:
389 case RENDERPATH_D3D9:
391 IDirect3DSurface9_Release(gl_state.d3drt_backbufferdepthsurface);
392 IDirect3DSurface9_Release(gl_state.d3drt_backbuffercolorsurface);
395 case RENDERPATH_D3D10:
396 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
398 case RENDERPATH_D3D11:
399 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
402 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
403 for (i = 0;i < endindex;i++)
405 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
406 if (!buffer || !buffer->isdynamic)
408 switch(vid.renderpath)
410 case RENDERPATH_GL11:
411 case RENDERPATH_GL13:
412 case RENDERPATH_GL20:
413 case RENDERPATH_CGGL:
415 case RENDERPATH_D3D9:
417 if (buffer->devicebuffer)
419 if (buffer->isindexbuffer)
420 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
422 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
423 buffer->devicebuffer = NULL;
427 case RENDERPATH_D3D10:
428 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
430 case RENDERPATH_D3D11:
431 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
437 static void gl_backend_devicerestored(void)
439 switch(vid.renderpath)
441 case RENDERPATH_GL11:
442 case RENDERPATH_GL13:
443 case RENDERPATH_GL20:
444 case RENDERPATH_CGGL:
446 case RENDERPATH_D3D9:
448 IDirect3DDevice9_GetDepthStencilSurface(vid_d3d9dev, &gl_state.d3drt_backbufferdepthsurface);
449 IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, &gl_state.d3drt_backbuffercolorsurface);
452 case RENDERPATH_D3D10:
453 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
455 case RENDERPATH_D3D11:
456 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
461 void gl_backend_init(void)
465 for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++)
467 polygonelement3s[i * 3 + 0] = 0;
468 polygonelement3s[i * 3 + 1] = i + 1;
469 polygonelement3s[i * 3 + 2] = i + 2;
471 // elements for rendering a series of quads as triangles
472 for (i = 0;i < QUADELEMENTS_MAXQUADS;i++)
474 quadelement3s[i * 6 + 0] = i * 4;
475 quadelement3s[i * 6 + 1] = i * 4 + 1;
476 quadelement3s[i * 6 + 2] = i * 4 + 2;
477 quadelement3s[i * 6 + 3] = i * 4;
478 quadelement3s[i * 6 + 4] = i * 4 + 2;
479 quadelement3s[i * 6 + 5] = i * 4 + 3;
482 for (i = 0;i < (POLYGONELEMENTS_MAXPOINTS - 2)*3;i++)
483 polygonelement3i[i] = polygonelement3s[i];
484 for (i = 0;i < QUADELEMENTS_MAXQUADS*3;i++)
485 quadelement3i[i] = quadelement3s[i];
487 Cvar_RegisterVariable(&r_render);
488 Cvar_RegisterVariable(&r_renderview);
489 Cvar_RegisterVariable(&r_waterwarp);
490 Cvar_RegisterVariable(&gl_polyblend);
491 Cvar_RegisterVariable(&v_flipped);
492 Cvar_RegisterVariable(&gl_dither);
493 Cvar_RegisterVariable(&gl_vbo);
494 Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
495 Cvar_RegisterVariable(&gl_vbo_dynamicindex);
496 Cvar_RegisterVariable(&gl_paranoid);
497 Cvar_RegisterVariable(&gl_printcheckerror);
499 Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
500 Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
501 Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
502 Cvar_RegisterVariable(&gl_mesh_separatearrays);
504 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");
506 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
509 void GL_SetMirrorState(qboolean state);
511 void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
515 Matrix4x4_Transform4 (&v->viewmatrix, in, temp);
516 Matrix4x4_Transform4 (&v->projectmatrix, temp, out);
518 out[0] = v->x + (out[0] * iw + 1.0f) * v->width * 0.5f;
520 // for an odd reason, inverting this is wrong for R_Shadow_ScissorForBBox (we then get badly scissored lights)
521 //out[1] = v->y + v->height - (out[1] * iw + 1.0f) * v->height * 0.5f;
522 out[1] = v->y + (out[1] * iw + 1.0f) * v->height * 0.5f;
524 out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
527 static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
531 float clipPlane[4], v3[3], v4[3];
534 // This is inspired by Oblique Depth Projection from http://www.terathon.com/code/oblique.php
536 VectorSet(normal, normalx, normaly, normalz);
537 Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
538 VectorScale(normal, dist, v3);
539 Matrix4x4_Transform(&v->viewmatrix, v3, v4);
540 // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
541 clipPlane[3] = -DotProduct(v4, clipPlane);
545 // testing code for comparing results
547 VectorCopy4(clipPlane, clipPlane2);
548 R_EntityMatrix(&identitymatrix);
549 VectorSet(q, normal[0], normal[1], normal[2], -dist);
550 qglClipPlane(GL_CLIP_PLANE0, q);
551 qglGetClipPlane(GL_CLIP_PLANE0, q);
552 VectorCopy4(q, clipPlane);
556 // Calculate the clip-space corner point opposite the clipping plane
557 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
558 // transform it into camera space by multiplying it
559 // by the inverse of the projection matrix
560 q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
561 q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
563 q[3] = (1.0f + m[10]) / m[14];
565 // Calculate the scaled plane vector
566 d = 2.0f / DotProduct4(clipPlane, q);
568 // Replace the third row of the projection matrix
569 m[2] = clipPlane[0] * d;
570 m[6] = clipPlane[1] * d;
571 m[10] = clipPlane[2] * d + 1.0f;
572 m[14] = clipPlane[3] * d;
575 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)
577 float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
579 memset(v, 0, sizeof(*v));
580 v->type = R_VIEWPORTTYPE_ORTHO;
581 v->cameramatrix = *cameramatrix;
588 memset(m, 0, sizeof(m));
589 m[0] = 2/(right - left);
590 m[5] = 2/(top - bottom);
591 m[10] = -2/(zFar - zNear);
592 m[12] = - (right + left)/(right - left);
593 m[13] = - (top + bottom)/(top - bottom);
594 m[14] = - (zFar + zNear)/(zFar - zNear);
596 switch(vid.renderpath)
598 case RENDERPATH_GL11:
599 case RENDERPATH_GL13:
600 case RENDERPATH_GL20:
601 case RENDERPATH_CGGL:
603 case RENDERPATH_D3D9:
604 case RENDERPATH_D3D10:
605 case RENDERPATH_D3D11:
606 m[10] = -1/(zFar - zNear);
607 m[14] = -zNear/(zFar-zNear);
610 v->screentodepth[0] = -farclip / (farclip - nearclip);
611 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
613 Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
616 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
618 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
624 Vector4Set(test1, (x1+x2)*0.5f, (y1+y2)*0.5f, 0.0f, 1.0f);
625 R_Viewport_TransformToScreen(v, test1, test2);
626 Con_Printf("%f %f %f -> %f %f %f\n", test1[0], test1[1], test1[2], test2[0], test2[1], test2[2]);
631 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)
633 matrix4x4_t tempmatrix, basematrix;
635 memset(v, 0, sizeof(*v));
637 v->type = R_VIEWPORTTYPE_PERSPECTIVE;
638 v->cameramatrix = *cameramatrix;
645 memset(m, 0, sizeof(m));
646 m[0] = 1.0 / frustumx;
647 m[5] = 1.0 / frustumy;
648 m[10] = -(farclip + nearclip) / (farclip - nearclip);
650 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
651 v->screentodepth[0] = -farclip / (farclip - nearclip);
652 v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
654 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
655 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
656 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
657 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
660 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
662 if(v_flipped.integer)
670 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
673 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)
675 matrix4x4_t tempmatrix, basematrix;
676 const float nudge = 1.0 - 1.0 / (1<<23);
678 memset(v, 0, sizeof(*v));
680 v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
681 v->cameramatrix = *cameramatrix;
688 memset(m, 0, sizeof(m));
689 m[ 0] = 1.0 / frustumx;
690 m[ 5] = 1.0 / frustumy;
693 m[14] = -2 * nearclip * nudge;
694 v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
695 v->screentodepth[1] = m[14] * -0.5;
697 Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
698 Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
699 Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
700 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
703 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
705 if(v_flipped.integer)
713 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
716 float cubeviewmatrix[6][16] =
718 // standard cubemap projections
756 float rectviewmatrix[6][16] =
758 // sign-preserving cubemap projections
797 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
799 matrix4x4_t tempmatrix, basematrix;
801 memset(v, 0, sizeof(*v));
802 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
803 v->cameramatrix = *cameramatrix;
807 memset(m, 0, sizeof(m));
809 m[10] = -(farclip + nearclip) / (farclip - nearclip);
811 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
813 Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
814 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
815 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
818 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
820 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
823 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)
825 matrix4x4_t tempmatrix, basematrix;
827 memset(v, 0, sizeof(*v));
828 v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
829 v->cameramatrix = *cameramatrix;
830 v->x = (side & 1) * size;
831 v->y = (side >> 1) * size;
835 memset(m, 0, sizeof(m));
836 m[0] = m[5] = 1.0f * ((float)size - border) / size;
837 m[10] = -(farclip + nearclip) / (farclip - nearclip);
839 m[14] = -2 * nearclip * farclip / (farclip - nearclip);
841 Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
842 Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
843 Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
845 switch(vid.renderpath)
847 case RENDERPATH_GL20:
848 case RENDERPATH_CGGL:
849 case RENDERPATH_GL13:
850 case RENDERPATH_GL11:
852 case RENDERPATH_D3D9:
855 case RENDERPATH_D3D10:
856 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
858 case RENDERPATH_D3D11:
859 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
864 R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
866 Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
869 void R_SetViewport(const r_viewport_t *v)
874 // FIXME: v_flipped_state is evil, this probably breaks somewhere
875 GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
877 // copy over the matrices to our state
878 gl_viewmatrix = v->viewmatrix;
879 gl_projectionmatrix = v->projectmatrix;
881 switch(vid.renderpath)
883 case RENDERPATH_GL20:
884 case RENDERPATH_CGGL:
886 // qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
888 case RENDERPATH_GL13:
889 case RENDERPATH_GL11:
891 qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
892 // Load the projection matrix into OpenGL
893 qglMatrixMode(GL_PROJECTION);CHECKGLERROR
894 Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
895 qglLoadMatrixf(m);CHECKGLERROR
896 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
898 case RENDERPATH_D3D9:
901 D3DVIEWPORT9 d3dviewport;
902 d3dviewport.X = gl_viewport.x;
903 d3dviewport.Y = gl_viewport.y;
904 d3dviewport.Width = gl_viewport.width;
905 d3dviewport.Height = gl_viewport.height;
906 d3dviewport.MinZ = gl_state.depthrange[0];
907 d3dviewport.MaxZ = gl_state.depthrange[1];
908 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
912 case RENDERPATH_D3D10:
913 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
915 case RENDERPATH_D3D11:
916 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
920 // force an update of the derived matrices
921 gl_modelmatrixchanged = true;
922 R_EntityMatrix(&gl_modelmatrix);
925 void R_GetViewport(r_viewport_t *v)
930 static void GL_BindVBO(int bufferobject)
932 if (gl_state.vertexbufferobject != bufferobject)
934 gl_state.vertexbufferobject = bufferobject;
936 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
940 static void GL_BindEBO(int bufferobject)
942 if (gl_state.elementbufferobject != bufferobject)
944 gl_state.elementbufferobject = bufferobject;
946 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobject);CHECKGLERROR
950 int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
953 switch(vid.renderpath)
955 case RENDERPATH_GL11:
956 case RENDERPATH_GL13:
957 case RENDERPATH_GL20:
958 case RENDERPATH_CGGL:
959 if (!vid.support.ext_framebuffer_object)
961 qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR
962 R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
963 if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR
964 if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR
965 if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR
966 if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR
967 if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR
969 case RENDERPATH_D3D9:
970 case RENDERPATH_D3D10:
971 case RENDERPATH_D3D11:
977 void R_Mesh_DestroyFramebufferObject(int fbo)
979 switch(vid.renderpath)
981 case RENDERPATH_GL11:
982 case RENDERPATH_GL13:
983 case RENDERPATH_GL20:
984 case RENDERPATH_CGGL:
986 qglDeleteFramebuffersEXT(1, (GLuint*)&fbo);
988 case RENDERPATH_D3D9:
989 case RENDERPATH_D3D10:
990 case RENDERPATH_D3D11:
996 void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3)
998 // 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)
999 // 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)
1002 gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface;
1003 // if (gl_state.d3drt_depthsurface != depthsurface)
1005 gl_state.d3drt_depthsurface = depthsurface;
1006 IDirect3DDevice9_SetDepthStencilSurface(vid_d3d9dev, gl_state.d3drt_depthsurface);
1008 if (gl_state.d3drt_colorsurfaces[0] != colorsurface0)
1010 gl_state.d3drt_colorsurfaces[0] = colorsurface0;
1011 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 0, gl_state.d3drt_colorsurfaces[0]);
1013 if (gl_state.d3drt_colorsurfaces[1] != colorsurface1)
1015 gl_state.d3drt_colorsurfaces[1] = colorsurface1;
1016 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 1, gl_state.d3drt_colorsurfaces[1]);
1018 if (gl_state.d3drt_colorsurfaces[2] != colorsurface2)
1020 gl_state.d3drt_colorsurfaces[2] = colorsurface2;
1021 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 2, gl_state.d3drt_colorsurfaces[2]);
1023 if (gl_state.d3drt_colorsurfaces[3] != colorsurface3)
1025 gl_state.d3drt_colorsurfaces[3] = colorsurface3;
1026 IDirect3DDevice9_SetRenderTarget(vid_d3d9dev, 3, gl_state.d3drt_colorsurfaces[3]);
1031 void R_Mesh_ResetRenderTargets(void)
1033 switch(vid.renderpath)
1035 case RENDERPATH_GL11:
1036 case RENDERPATH_GL13:
1037 case RENDERPATH_GL20:
1038 case RENDERPATH_CGGL:
1039 if (gl_state.framebufferobject)
1041 gl_state.framebufferobject = 0;
1042 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1045 case RENDERPATH_D3D9:
1047 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1050 case RENDERPATH_D3D10:
1051 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1053 case RENDERPATH_D3D11:
1054 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1059 void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
1063 rtexture_t *textures[5];
1064 Vector4Set(textures, colortexture, colortexture2, colortexture3, colortexture4);
1065 textures[4] = depthtexture;
1066 // unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
1067 for (j = 0;j < 5;j++)
1069 for (i = 0;i < vid.teximageunits;i++)
1070 if (gl_state.units[i].texture == textures[j])
1071 R_Mesh_TexBind(i, NULL);
1072 // set up framebuffer object or render targets for the active rendering API
1073 switch(vid.renderpath)
1075 case RENDERPATH_GL11:
1076 case RENDERPATH_GL13:
1077 case RENDERPATH_GL20:
1078 case RENDERPATH_CGGL:
1079 if (gl_state.framebufferobject != fbo)
1081 gl_state.framebufferobject = fbo;
1082 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1085 case RENDERPATH_D3D9:
1087 // set up the new render targets, a NULL depthtexture intentionally binds nothing
1088 // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost
1091 IDirect3DSurface9 *colorsurfaces[4];
1092 for (i = 0;i < 4;i++)
1094 colorsurfaces[i] = NULL;
1096 IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]);
1098 // set the render targets for real
1099 R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]);
1100 // release the texture surface levels (they won't be lost while bound...)
1101 for (i = 0;i < 4;i++)
1103 IDirect3DSurface9_Release(colorsurfaces[i]);
1106 R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL);
1109 case RENDERPATH_D3D10:
1110 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1112 case RENDERPATH_D3D11:
1113 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1119 static int d3dcmpforglfunc(int f)
1123 case GL_NEVER: return D3DCMP_NEVER;
1124 case GL_LESS: return D3DCMP_LESS;
1125 case GL_EQUAL: return D3DCMP_EQUAL;
1126 case GL_LEQUAL: return D3DCMP_LESSEQUAL;
1127 case GL_GREATER: return D3DCMP_GREATER;
1128 case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
1129 case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
1130 case GL_ALWAYS: return D3DCMP_ALWAYS;
1131 default: Con_DPrintf("Unknown GL_DepthFunc\n");return D3DCMP_ALWAYS;
1135 static int d3dstencilopforglfunc(int f)
1139 case GL_KEEP: return D3DSTENCILOP_KEEP;
1140 case GL_INCR: return D3DSTENCILOP_INCR; // note: GL_INCR is clamped, D3DSTENCILOP_INCR wraps
1141 case GL_DECR: return D3DSTENCILOP_DECR; // note: GL_DECR is clamped, D3DSTENCILOP_DECR wraps
1142 default: Con_DPrintf("Unknown GL_StencilFunc\n");return D3DSTENCILOP_KEEP;
1148 static void GL_Backend_ResetState(void)
1151 gl_state.active = true;
1152 gl_state.depthtest = true;
1153 gl_state.alphatest = false;
1154 gl_state.alphafunc = GL_GEQUAL;
1155 gl_state.alphafuncvalue = 0.5f;
1156 gl_state.blendfunc1 = GL_ONE;
1157 gl_state.blendfunc2 = GL_ZERO;
1158 gl_state.blend = false;
1159 gl_state.depthmask = GL_TRUE;
1160 gl_state.colormask = 15;
1161 gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1;
1162 gl_state.lockrange_first = 0;
1163 gl_state.lockrange_count = 0;
1164 gl_state.cullface = GL_NONE;
1165 gl_state.cullfaceenable = false;
1166 gl_state.polygonoffset[0] = 0;
1167 gl_state.polygonoffset[1] = 0;
1168 gl_state.framebufferobject = 0;
1169 gl_state.depthfunc = GL_LEQUAL;
1171 switch(vid.renderpath)
1173 case RENDERPATH_D3D9:
1176 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, gl_state.colormask);
1177 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
1178 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
1179 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, gl_state.alphafuncvalue * 256.0f, 255));
1180 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1181 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1182 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1183 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1184 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1185 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1189 case RENDERPATH_D3D10:
1190 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1192 case RENDERPATH_D3D11:
1193 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1195 case RENDERPATH_GL20:
1196 case RENDERPATH_CGGL:
1199 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1200 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1201 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1202 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1203 qglDisable(GL_BLEND);CHECKGLERROR
1204 qglCullFace(gl_state.cullface);CHECKGLERROR
1205 qglDisable(GL_CULL_FACE);CHECKGLERROR
1206 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1207 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1208 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1209 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1211 if (vid.support.arb_vertex_buffer_object)
1213 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1214 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1217 if (vid.support.ext_framebuffer_object)
1219 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1220 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1223 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1224 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1226 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1227 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1228 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1230 if (vid.support.ext_framebuffer_object)
1231 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1233 gl_state.unit = MAX_TEXTUREUNITS;
1234 gl_state.clientunit = MAX_TEXTUREUNITS;
1235 for (i = 0;i < vid.teximageunits;i++)
1237 GL_ActiveTexture(i);
1238 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1239 if (vid.support.ext_texture_3d)
1241 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1243 if (vid.support.arb_texture_cube_map)
1245 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1249 for (i = 0;i < vid.texarrayunits;i++)
1251 GL_ClientActiveTexture(i);
1253 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1254 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1258 case RENDERPATH_GL13:
1259 case RENDERPATH_GL11:
1262 qglColorMask(1, 1, 1, 1);CHECKGLERROR
1263 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1264 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1265 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1266 qglDisable(GL_BLEND);CHECKGLERROR
1267 qglCullFace(gl_state.cullface);CHECKGLERROR
1268 qglDisable(GL_CULL_FACE);CHECKGLERROR
1269 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1270 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1271 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1272 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1274 if (vid.support.arb_vertex_buffer_object)
1276 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1277 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1280 if (vid.support.ext_framebuffer_object)
1282 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
1283 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1286 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), NULL);CHECKGLERROR
1287 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
1289 qglColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL);CHECKGLERROR
1290 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
1291 qglColor4f(1, 1, 1, 1);CHECKGLERROR
1293 if (vid.support.ext_framebuffer_object)
1294 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, gl_state.framebufferobject);
1296 gl_state.unit = MAX_TEXTUREUNITS;
1297 gl_state.clientunit = MAX_TEXTUREUNITS;
1298 for (i = 0;i < vid.texunits;i++)
1300 GL_ActiveTexture(i);
1301 GL_ClientActiveTexture(i);
1302 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
1303 qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
1304 if (vid.support.ext_texture_3d)
1306 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
1307 qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
1309 if (vid.support.arb_texture_cube_map)
1311 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
1312 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
1315 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
1316 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
1317 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
1318 qglLoadIdentity();CHECKGLERROR
1319 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
1320 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
1327 void GL_ActiveTexture(unsigned int num)
1329 if (gl_state.unit != num)
1331 gl_state.unit = num;
1332 switch(vid.renderpath)
1334 case RENDERPATH_GL11:
1335 case RENDERPATH_GL13:
1336 case RENDERPATH_GL20:
1337 case RENDERPATH_CGGL:
1338 if (qglActiveTexture)
1341 qglActiveTexture(GL_TEXTURE0_ARB + gl_state.unit);
1345 case RENDERPATH_D3D9:
1346 case RENDERPATH_D3D10:
1347 case RENDERPATH_D3D11:
1353 void GL_ClientActiveTexture(unsigned int num)
1355 if (gl_state.clientunit != num)
1357 gl_state.clientunit = num;
1358 switch(vid.renderpath)
1360 case RENDERPATH_GL11:
1361 case RENDERPATH_GL13:
1362 case RENDERPATH_GL20:
1363 case RENDERPATH_CGGL:
1364 if (qglActiveTexture)
1367 qglClientActiveTexture(GL_TEXTURE0_ARB + gl_state.clientunit);
1371 case RENDERPATH_D3D9:
1372 case RENDERPATH_D3D10:
1373 case RENDERPATH_D3D11:
1379 void GL_BlendFunc(int blendfunc1, int blendfunc2)
1381 if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2)
1383 qboolean blendenable;
1384 gl_state.blendfunc1 = blendfunc1;
1385 gl_state.blendfunc2 = blendfunc2;
1386 blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
1387 switch(vid.renderpath)
1389 case RENDERPATH_GL11:
1390 case RENDERPATH_GL13:
1391 case RENDERPATH_GL20:
1392 case RENDERPATH_CGGL:
1394 qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
1395 if (gl_state.blend != blendenable)
1397 gl_state.blend = blendenable;
1398 if (!gl_state.blend)
1400 qglDisable(GL_BLEND);CHECKGLERROR
1404 qglEnable(GL_BLEND);CHECKGLERROR
1408 case RENDERPATH_D3D9:
1413 D3DBLEND d3dblendfunc[2];
1414 glblendfunc[0] = gl_state.blendfunc1;
1415 glblendfunc[1] = gl_state.blendfunc2;
1416 for (i = 0;i < 2;i++)
1418 switch(glblendfunc[i])
1420 case GL_ZERO: d3dblendfunc[i] = D3DBLEND_ZERO;break;
1421 case GL_ONE: d3dblendfunc[i] = D3DBLEND_ONE;break;
1422 case GL_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_SRCCOLOR;break;
1423 case GL_ONE_MINUS_SRC_COLOR: d3dblendfunc[i] = D3DBLEND_INVSRCCOLOR;break;
1424 case GL_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_SRCALPHA;break;
1425 case GL_ONE_MINUS_SRC_ALPHA: d3dblendfunc[i] = D3DBLEND_INVSRCALPHA;break;
1426 case GL_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_DESTALPHA;break;
1427 case GL_ONE_MINUS_DST_ALPHA: d3dblendfunc[i] = D3DBLEND_INVDESTALPHA;break;
1428 case GL_DST_COLOR: d3dblendfunc[i] = D3DBLEND_DESTCOLOR;break;
1429 case GL_ONE_MINUS_DST_COLOR: d3dblendfunc[i] = D3DBLEND_INVDESTCOLOR;break;
1432 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SRCBLEND, d3dblendfunc[0]);
1433 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DESTBLEND, d3dblendfunc[1]);
1434 if (gl_state.blend != blendenable)
1436 gl_state.blend = blendenable;
1437 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHABLENDENABLE, gl_state.blend);
1442 case RENDERPATH_D3D10:
1443 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1445 case RENDERPATH_D3D11:
1446 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1452 void GL_DepthMask(int state)
1454 if (gl_state.depthmask != state)
1456 gl_state.depthmask = state;
1457 switch(vid.renderpath)
1459 case RENDERPATH_GL11:
1460 case RENDERPATH_GL13:
1461 case RENDERPATH_GL20:
1462 case RENDERPATH_CGGL:
1464 qglDepthMask(gl_state.depthmask);CHECKGLERROR
1466 case RENDERPATH_D3D9:
1468 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZWRITEENABLE, gl_state.depthmask);
1471 case RENDERPATH_D3D10:
1472 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1474 case RENDERPATH_D3D11:
1475 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1481 void GL_DepthTest(int state)
1483 if (gl_state.depthtest != state)
1485 gl_state.depthtest = state;
1486 switch(vid.renderpath)
1488 case RENDERPATH_GL11:
1489 case RENDERPATH_GL13:
1490 case RENDERPATH_GL20:
1491 case RENDERPATH_CGGL:
1493 if (gl_state.depthtest)
1495 qglEnable(GL_DEPTH_TEST);CHECKGLERROR
1499 qglDisable(GL_DEPTH_TEST);CHECKGLERROR
1502 case RENDERPATH_D3D9:
1504 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZENABLE, gl_state.depthtest);
1507 case RENDERPATH_D3D10:
1508 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1510 case RENDERPATH_D3D11:
1511 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1517 void GL_DepthFunc(int state)
1519 if (gl_state.depthfunc != state)
1521 gl_state.depthfunc = state;
1522 switch(vid.renderpath)
1524 case RENDERPATH_GL11:
1525 case RENDERPATH_GL13:
1526 case RENDERPATH_GL20:
1527 case RENDERPATH_CGGL:
1529 qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
1531 case RENDERPATH_D3D9:
1533 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ZFUNC, d3dcmpforglfunc(gl_state.depthfunc));
1536 case RENDERPATH_D3D10:
1537 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1539 case RENDERPATH_D3D11:
1540 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1546 void GL_DepthRange(float nearfrac, float farfrac)
1548 if (gl_state.depthrange[0] != nearfrac || gl_state.depthrange[1] != farfrac)
1550 gl_state.depthrange[0] = nearfrac;
1551 gl_state.depthrange[1] = farfrac;
1552 switch(vid.renderpath)
1554 case RENDERPATH_GL11:
1555 case RENDERPATH_GL13:
1556 case RENDERPATH_GL20:
1557 case RENDERPATH_CGGL:
1558 qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
1560 case RENDERPATH_D3D9:
1563 D3DVIEWPORT9 d3dviewport;
1564 d3dviewport.X = gl_viewport.x;
1565 d3dviewport.Y = gl_viewport.y;
1566 d3dviewport.Width = gl_viewport.width;
1567 d3dviewport.Height = gl_viewport.height;
1568 d3dviewport.MinZ = gl_state.depthrange[0];
1569 d3dviewport.MaxZ = gl_state.depthrange[1];
1570 IDirect3DDevice9_SetViewport(vid_d3d9dev, &d3dviewport);
1574 case RENDERPATH_D3D10:
1575 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1577 case RENDERPATH_D3D11:
1578 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1584 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)
1586 switch (vid.renderpath)
1588 case RENDERPATH_GL11:
1589 case RENDERPATH_GL13:
1590 case RENDERPATH_GL20:
1591 case RENDERPATH_CGGL:
1595 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1599 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1601 if (vid.support.ati_separate_stencil)
1603 qglStencilMask(writemask);CHECKGLERROR
1604 qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR
1605 qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR
1606 qglStencilFuncSeparate(frontcompare, backcompare, comparereference, comparereference);CHECKGLERROR
1608 else if (vid.support.ext_stencil_two_side)
1610 qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1611 qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR
1612 qglStencilMask(writemask);CHECKGLERROR
1613 qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR
1614 qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR
1615 qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR
1616 qglStencilMask(writemask);CHECKGLERROR
1617 qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR
1618 qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR
1621 case RENDERPATH_D3D9:
1623 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1624 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1625 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1626 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(frontfail));
1627 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(frontzfail));
1628 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(frontzpass));
1629 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(frontcompare));
1630 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFAIL, d3dstencilopforglfunc(backfail));
1631 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILZFAIL, d3dstencilopforglfunc(backzfail));
1632 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILPASS, d3dstencilopforglfunc(backzpass));
1633 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CCW_STENCILFUNC, d3dcmpforglfunc(backcompare));
1634 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1635 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1638 case RENDERPATH_D3D10:
1639 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1641 case RENDERPATH_D3D11:
1642 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1647 void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask)
1649 switch (vid.renderpath)
1651 case RENDERPATH_GL11:
1652 case RENDERPATH_GL13:
1653 case RENDERPATH_GL20:
1654 case RENDERPATH_CGGL:
1658 qglEnable(GL_STENCIL_TEST);CHECKGLERROR
1662 qglDisable(GL_STENCIL_TEST);CHECKGLERROR
1664 if (vid.support.ext_stencil_two_side)
1666 qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
1668 qglStencilMask(writemask);CHECKGLERROR
1669 qglStencilOp(fail, zfail, zpass);CHECKGLERROR
1670 qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR
1673 case RENDERPATH_D3D9:
1675 if (vid.support.ati_separate_stencil)
1676 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_TWOSIDEDSTENCILMODE, true);
1677 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILENABLE, enable);
1678 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILWRITEMASK, writemask);
1679 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFAIL, d3dstencilopforglfunc(fail));
1680 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILZFAIL, d3dstencilopforglfunc(zfail));
1681 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILPASS, d3dstencilopforglfunc(zpass));
1682 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILFUNC, d3dcmpforglfunc(compare));
1683 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILREF, comparereference);
1684 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_STENCILMASK, comparemask);
1687 case RENDERPATH_D3D10:
1688 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1690 case RENDERPATH_D3D11:
1691 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1696 void GL_PolygonOffset(float planeoffset, float depthoffset)
1698 if (gl_state.polygonoffset[0] != planeoffset || gl_state.polygonoffset[1] != depthoffset)
1700 gl_state.polygonoffset[0] = planeoffset;
1701 gl_state.polygonoffset[1] = depthoffset;
1702 switch(vid.renderpath)
1704 case RENDERPATH_GL11:
1705 case RENDERPATH_GL13:
1706 case RENDERPATH_GL20:
1707 case RENDERPATH_CGGL:
1708 qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
1710 case RENDERPATH_D3D9:
1712 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SLOPESCALEDEPTHBIAS, gl_state.polygonoffset[0]);
1713 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_DEPTHBIAS, gl_state.polygonoffset[1] * (1.0f / 16777216.0f));
1716 case RENDERPATH_D3D10:
1717 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1719 case RENDERPATH_D3D11:
1720 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1726 void GL_SetMirrorState(qboolean state)
1728 if (v_flipped_state != state)
1730 v_flipped_state = state;
1731 if (gl_state.cullface == GL_BACK)
1732 gl_state.cullface = GL_FRONT;
1733 else if (gl_state.cullface == GL_FRONT)
1734 gl_state.cullface = GL_BACK;
1737 switch(vid.renderpath)
1739 case RENDERPATH_GL11:
1740 case RENDERPATH_GL13:
1741 case RENDERPATH_GL20:
1742 case RENDERPATH_CGGL:
1743 qglCullFace(gl_state.cullface);
1745 case RENDERPATH_D3D9:
1747 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, gl_state.cullface == GL_FRONT ? D3DCULL_CCW : D3DCULL_CW);
1750 case RENDERPATH_D3D10:
1751 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1753 case RENDERPATH_D3D11:
1754 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1760 void GL_CullFace(int state)
1764 if(state == GL_FRONT)
1766 else if(state == GL_BACK)
1770 switch(vid.renderpath)
1772 case RENDERPATH_GL11:
1773 case RENDERPATH_GL13:
1774 case RENDERPATH_GL20:
1775 case RENDERPATH_CGGL:
1778 if (state != GL_NONE)
1780 if (!gl_state.cullfaceenable)
1782 gl_state.cullfaceenable = true;
1783 qglEnable(GL_CULL_FACE);CHECKGLERROR
1785 if (gl_state.cullface != state)
1787 gl_state.cullface = state;
1788 qglCullFace(gl_state.cullface);CHECKGLERROR
1793 if (gl_state.cullfaceenable)
1795 gl_state.cullfaceenable = false;
1796 qglDisable(GL_CULL_FACE);CHECKGLERROR
1800 case RENDERPATH_D3D9:
1802 if (gl_state.cullface != state)
1804 gl_state.cullface = state;
1805 switch(gl_state.cullface)
1808 gl_state.cullfaceenable = false;
1809 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_NONE);
1812 gl_state.cullfaceenable = true;
1813 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CCW);
1816 gl_state.cullfaceenable = true;
1817 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_CULLMODE, D3DCULL_CW);
1823 case RENDERPATH_D3D10:
1824 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1826 case RENDERPATH_D3D11:
1827 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1832 void GL_AlphaTest(int state)
1834 if (gl_state.alphatest != state)
1836 gl_state.alphatest = state;
1837 switch(vid.renderpath)
1839 case RENDERPATH_GL11:
1840 case RENDERPATH_GL13:
1841 case RENDERPATH_GL20:
1842 case RENDERPATH_CGGL:
1844 if (gl_state.alphatest)
1846 qglEnable(GL_ALPHA_TEST);CHECKGLERROR
1850 qglDisable(GL_ALPHA_TEST);CHECKGLERROR
1853 case RENDERPATH_D3D9:
1855 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHATESTENABLE, gl_state.alphatest);
1858 case RENDERPATH_D3D10:
1859 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1861 case RENDERPATH_D3D11:
1862 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1868 void GL_AlphaFunc(int state, float value)
1870 if (gl_state.alphafunc != state || gl_state.alphafuncvalue != value)
1872 gl_state.alphafunc = state;
1873 gl_state.alphafuncvalue = value;
1874 switch(vid.renderpath)
1876 case RENDERPATH_GL11:
1877 case RENDERPATH_GL13:
1878 case RENDERPATH_GL20:
1879 case RENDERPATH_CGGL:
1881 qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR
1883 case RENDERPATH_D3D9:
1885 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAFUNC, d3dcmpforglfunc(gl_state.alphafunc));
1886 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_ALPHAREF, (int)bound(0, value * 256.0f, 255));
1889 case RENDERPATH_D3D10:
1890 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1892 case RENDERPATH_D3D11:
1893 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1899 void GL_ColorMask(int r, int g, int b, int a)
1901 // NOTE: this matches D3DCOLORWRITEENABLE_RED, GREEN, BLUE, ALPHA
1902 int state = (r ? 1 : 0) | (g ? 2 : 0) | (b ? 4 : 0) | (a ? 8 : 0);
1903 if (gl_state.colormask != state)
1905 gl_state.colormask = state;
1906 switch(vid.renderpath)
1908 case RENDERPATH_GL11:
1909 case RENDERPATH_GL13:
1910 case RENDERPATH_GL20:
1911 case RENDERPATH_CGGL:
1913 qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
1915 case RENDERPATH_D3D9:
1917 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_COLORWRITEENABLE, state);
1920 case RENDERPATH_D3D10:
1921 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1923 case RENDERPATH_D3D11:
1924 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1930 void GL_Color(float cr, float cg, float cb, float ca)
1932 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)
1934 gl_state.color4f[0] = cr;
1935 gl_state.color4f[1] = cg;
1936 gl_state.color4f[2] = cb;
1937 gl_state.color4f[3] = ca;
1938 switch(vid.renderpath)
1940 case RENDERPATH_GL11:
1941 case RENDERPATH_GL13:
1942 case RENDERPATH_GL20:
1943 case RENDERPATH_CGGL:
1945 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);
1948 case RENDERPATH_D3D9:
1949 case RENDERPATH_D3D10:
1950 case RENDERPATH_D3D11:
1951 // no equivalent in D3D
1957 void GL_Scissor (int x, int y, int width, int height)
1959 switch(vid.renderpath)
1961 case RENDERPATH_GL11:
1962 case RENDERPATH_GL13:
1963 case RENDERPATH_GL20:
1964 case RENDERPATH_CGGL:
1966 qglScissor(x, y,width,height);
1969 case RENDERPATH_D3D9:
1975 d3drect.right = x + width;
1976 d3drect.bottom = y + height;
1977 IDirect3DDevice9_SetScissorRect(vid_d3d9dev, &d3drect);
1981 case RENDERPATH_D3D10:
1982 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1984 case RENDERPATH_D3D11:
1985 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1990 void GL_ScissorTest(int state)
1992 if (gl_state.scissortest != state)
1994 gl_state.scissortest = state;
1995 switch(vid.renderpath)
1997 case RENDERPATH_GL11:
1998 case RENDERPATH_GL13:
1999 case RENDERPATH_GL20:
2000 case RENDERPATH_CGGL:
2002 if(gl_state.scissortest)
2003 qglEnable(GL_SCISSOR_TEST);
2005 qglDisable(GL_SCISSOR_TEST);
2008 case RENDERPATH_D3D9:
2010 IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_SCISSORTESTENABLE, gl_state.scissortest);
2013 case RENDERPATH_D3D10:
2014 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2016 case RENDERPATH_D3D11:
2017 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2023 void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
2025 static const float blackcolor[4] = {0, 0, 0, 0};
2026 // prevent warnings when trying to clear a buffer that does not exist
2028 colorvalue = blackcolor;
2031 mask &= ~GL_STENCIL_BUFFER_BIT;
2034 switch(vid.renderpath)
2036 case RENDERPATH_GL11:
2037 case RENDERPATH_GL13:
2038 case RENDERPATH_GL20:
2039 case RENDERPATH_CGGL:
2041 if (mask & GL_COLOR_BUFFER_BIT)
2043 qglClearColor(colorvalue[0], colorvalue[1], colorvalue[2], colorvalue[3]);CHECKGLERROR
2045 if (mask & GL_DEPTH_BUFFER_BIT)
2047 qglClearDepth(depthvalue);CHECKGLERROR
2049 if (mask & GL_STENCIL_BUFFER_BIT)
2051 qglClearStencil(stencilvalue);CHECKGLERROR
2053 qglClear(mask);CHECKGLERROR
2055 case RENDERPATH_D3D9:
2057 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);
2060 case RENDERPATH_D3D10:
2061 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2063 case RENDERPATH_D3D11:
2064 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2069 void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels)
2071 switch(vid.renderpath)
2073 case RENDERPATH_GL11:
2074 case RENDERPATH_GL13:
2075 case RENDERPATH_GL20:
2076 case RENDERPATH_CGGL:
2078 qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR
2080 case RENDERPATH_D3D9:
2083 // LordHavoc: we can't directly download the backbuffer because it may be
2084 // multisampled, and it may not be lockable, so we blit it to a lockable
2085 // surface of the same dimensions (but without multisample) to resolve the
2086 // multisample buffer to a normal image, and then lock that...
2087 IDirect3DSurface9 *stretchsurface = NULL;
2088 if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &stretchsurface, NULL)))
2090 D3DLOCKED_RECT lockedrect;
2091 if (!FAILED(IDirect3DDevice9_StretchRect(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, NULL, stretchsurface, NULL, D3DTEXF_POINT)))
2093 if (!FAILED(IDirect3DSurface9_LockRect(stretchsurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2096 unsigned char *row = (unsigned char *)lockedrect.pBits + x * 4 + lockedrect.Pitch * (vid.height - 1 - y);
2097 for (line = 0;line < height;line++, row -= lockedrect.Pitch)
2098 memcpy(outpixels + line * width * 4, row, width * 4);
2099 IDirect3DSurface9_UnlockRect(stretchsurface);
2102 IDirect3DSurface9_Release(stretchsurface);
2105 //IDirect3DSurface9 *syssurface = NULL;
2106 //if (!FAILED(IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &stretchsurface, NULL)))
2107 //if (!FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(vid_d3d9dev, vid.width, vid.height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &syssurface, NULL)))
2108 //IDirect3DDevice9_GetRenderTargetData(vid_d3d9dev, gl_state.d3drt_backbuffercolorsurface, syssurface);
2109 //if (!FAILED(IDirect3DDevice9_GetFrontBufferData(vid_d3d9dev, 0, syssurface)))
2110 //if (!FAILED(IDirect3DSurface9_LockRect(syssurface, &lockedrect, NULL, D3DLOCK_READONLY)))
2111 //IDirect3DSurface9_UnlockRect(syssurface);
2112 //IDirect3DSurface9_Release(syssurface);
2116 case RENDERPATH_D3D10:
2117 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2119 case RENDERPATH_D3D11:
2120 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2125 // called at beginning of frame
2126 void R_Mesh_Start(void)
2129 R_Mesh_ResetRenderTargets();
2131 if (gl_printcheckerror.integer && !gl_paranoid.integer)
2133 Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
2134 Cvar_SetValueQuick(&gl_paranoid, 1);
2138 qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
2142 char compilelog[MAX_INPUTLINE];
2143 shaderobject = qglCreateShaderObjectARB(shadertypeenum);CHECKGLERROR
2146 qglShaderSourceARB(shaderobject, numstrings, strings, NULL);CHECKGLERROR
2147 qglCompileShaderARB(shaderobject);CHECKGLERROR
2148 qglGetObjectParameterivARB(shaderobject, GL_OBJECT_COMPILE_STATUS_ARB, &shadercompiled);CHECKGLERROR
2149 qglGetInfoLogARB(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
2150 if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
2152 int i, j, pretextlines = 0;
2153 for (i = 0;i < numstrings - 1;i++)
2154 for (j = 0;strings[i][j];j++)
2155 if (strings[i][j] == '\n')
2157 Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
2159 if (!shadercompiled)
2161 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2164 qglAttachObjectARB(programobject, shaderobject);CHECKGLERROR
2165 qglDeleteObjectARB(shaderobject);CHECKGLERROR
2169 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)
2171 GLint programlinked;
2172 GLuint programobject = 0;
2173 char linklog[MAX_INPUTLINE];
2176 programobject = qglCreateProgramObjectARB();CHECKGLERROR
2180 if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER_ARB, "vertex", vertexstrings_count, vertexstrings_list))
2183 #ifdef GL_GEOMETRY_SHADER_ARB
2184 if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER_ARB, "geometry", geometrystrings_count, geometrystrings_list))
2188 if (fragmentstrings_count && !GL_Backend_CompileShader(programobject, GL_FRAGMENT_SHADER_ARB, "fragment", fragmentstrings_count, fragmentstrings_list))
2191 qglLinkProgramARB(programobject);CHECKGLERROR
2192 qglGetObjectParameterivARB(programobject, GL_OBJECT_LINK_STATUS_ARB, &programlinked);CHECKGLERROR
2193 qglGetInfoLogARB(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
2196 if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
2197 Con_DPrintf("program link log:\n%s\n", linklog);
2198 // software vertex shader is ok but software fragment shader is WAY
2199 // too slow, fail program if so.
2200 // NOTE: this string might be ATI specific, but that's ok because the
2201 // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a
2202 // software fragment shader due to low instruction and dependent
2204 if (strstr(linklog, "fragment shader will run in software"))
2205 programlinked = false;
2209 return programobject;
2211 qglDeleteObjectARB(programobject);CHECKGLERROR
2215 void GL_Backend_FreeProgram(unsigned int prog)
2218 qglDeleteObjectARB(prog);
2222 void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
2227 for (i = 0;i < count;i++)
2228 *out++ = *in++ + offset;
2231 memcpy(out, in, sizeof(*out) * count);
2234 // renders triangles using vertices from the active arrays
2235 int paranoidblah = 0;
2236 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)
2238 unsigned int numelements = numtriangles * 3;
2240 size_t bufferoffset3i;
2242 size_t bufferoffset3s;
2243 if (numvertices < 3 || numtriangles < 1)
2245 if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
2246 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);
2249 if (!gl_mesh_prefer_short_elements.integer)
2253 if (element3i_indexbuffer)
2254 element3i_indexbuffer = NULL;
2256 // adjust the pointers for firsttriangle
2258 element3i += firsttriangle * 3;
2259 if (element3i_indexbuffer)
2260 element3i_bufferoffset += firsttriangle * 3 * sizeof(*element3i);
2262 element3s += firsttriangle * 3;
2263 if (element3s_indexbuffer)
2264 element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
2265 switch(vid.renderpath)
2267 case RENDERPATH_GL11:
2268 case RENDERPATH_GL13:
2269 case RENDERPATH_GL20:
2270 case RENDERPATH_CGGL:
2271 // check if the user specified to ignore static index buffers
2272 if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
2274 element3i_indexbuffer = NULL;
2275 element3s_indexbuffer = NULL;
2278 case RENDERPATH_D3D9:
2279 case RENDERPATH_D3D10:
2280 case RENDERPATH_D3D11:
2283 // upload a dynamic index buffer if needed
2286 if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
2288 if (gl_state.draw_dynamicindexbuffer)
2289 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3s, numelements * sizeof(*element3s));
2291 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3s, numelements * sizeof(*element3s), "temporary", true, true, true);
2292 element3s_indexbuffer = gl_state.draw_dynamicindexbuffer;
2293 element3s_bufferoffset = 0;
2298 if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
2300 if (gl_state.draw_dynamicindexbuffer)
2301 R_Mesh_UpdateMeshBuffer(gl_state.draw_dynamicindexbuffer, (void *)element3i, numelements * sizeof(*element3i));
2303 gl_state.draw_dynamicindexbuffer = R_Mesh_CreateMeshBuffer((void *)element3i, numelements * sizeof(*element3i), "temporary", true, true, false);
2304 element3i_indexbuffer = gl_state.draw_dynamicindexbuffer;
2305 element3i_bufferoffset = 0;
2308 bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
2309 bufferoffset3i = element3i_bufferoffset;
2310 bufferobject3s = element3s_indexbuffer ? element3s_indexbuffer->bufferobject : 0;
2311 bufferoffset3s = element3s_bufferoffset;
2312 r_refdef.stats.meshes++;
2313 r_refdef.stats.meshes_elements += numelements;
2314 if (gl_paranoid.integer)
2317 // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
2319 unsigned int j, size;
2321 // note: there's no validation done here on buffer objects because it
2322 // is somewhat difficult to get at the data, and gl_paranoid can be
2323 // used without buffer objects if the need arises
2324 // (the data could be gotten using glMapBuffer but it would be very
2325 // slow due to uncachable video memory reads)
2326 if (!qglIsEnabled(GL_VERTEX_ARRAY))
2327 Con_Print("R_Mesh_Draw: vertex array not enabled\n");
2329 if (gl_state.pointer_vertex_pointer)
2330 for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
2332 if (gl_state.pointer_color_enabled)
2334 if (!qglIsEnabled(GL_COLOR_ARRAY))
2335 Con_Print("R_Mesh_Draw: color array set but not enabled\n");
2337 if (gl_state.pointer_color && gl_state.pointer_color_enabled)
2338 for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
2341 for (i = 0;i < vid.texarrayunits;i++)
2343 if (gl_state.units[i].arrayenabled)
2345 GL_ClientActiveTexture(i);
2346 if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
2347 Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
2349 if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
2350 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++)
2357 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2359 if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
2361 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
2368 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2370 if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
2372 Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
2378 if (r_render.integer || r_refdef.draw2dstage)
2380 switch(vid.renderpath)
2382 case RENDERPATH_GL11:
2383 case RENDERPATH_GL13:
2384 case RENDERPATH_GL20:
2385 case RENDERPATH_CGGL:
2387 if (gl_mesh_testmanualfeeding.integer)
2389 unsigned int i, j, element;
2391 qglBegin(GL_TRIANGLES);
2392 for (i = 0;i < (unsigned int) numtriangles * 3;i++)
2395 element = element3i[i];
2397 element = element3s[i];
2399 element = firstvertex + i;
2400 for (j = 0;j < vid.texarrayunits;j++)
2402 if (gl_state.units[j].pointer_texcoord_pointer && gl_state.units[j].arrayenabled)
2404 if (gl_state.units[j].pointer_texcoord_gltype == GL_FLOAT)
2406 p = (const GLfloat *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2407 if (vid.texarrayunits > 1)
2409 if (gl_state.units[j].pointer_texcoord_components == 4)
2410 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
2411 else if (gl_state.units[j].pointer_texcoord_components == 3)
2412 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
2413 else if (gl_state.units[j].pointer_texcoord_components == 2)
2414 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
2416 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
2420 if (gl_state.units[j].pointer_texcoord_components == 4)
2421 qglTexCoord4f(p[0], p[1], p[2], p[3]);
2422 else if (gl_state.units[j].pointer_texcoord_components == 3)
2423 qglTexCoord3f(p[0], p[1], p[2]);
2424 else if (gl_state.units[j].pointer_texcoord_components == 2)
2425 qglTexCoord2f(p[0], p[1]);
2427 qglTexCoord1f(p[0]);
2430 else if (gl_state.units[j].pointer_texcoord_gltype == GL_SHORT)
2432 const GLshort *s = (const GLshort *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2433 if (vid.texarrayunits > 1)
2435 if (gl_state.units[j].pointer_texcoord_components == 4)
2436 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2], s[3]);
2437 else if (gl_state.units[j].pointer_texcoord_components == 3)
2438 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, s[0], s[1], s[2]);
2439 else if (gl_state.units[j].pointer_texcoord_components == 2)
2440 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, s[0], s[1]);
2441 else if (gl_state.units[j].pointer_texcoord_components == 1)
2442 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, s[0]);
2446 if (gl_state.units[j].pointer_texcoord_components == 4)
2447 qglTexCoord4f(s[0], s[1], s[2], s[3]);
2448 else if (gl_state.units[j].pointer_texcoord_components == 3)
2449 qglTexCoord3f(s[0], s[1], s[2]);
2450 else if (gl_state.units[j].pointer_texcoord_components == 2)
2451 qglTexCoord2f(s[0], s[1]);
2452 else if (gl_state.units[j].pointer_texcoord_components == 1)
2453 qglTexCoord1f(s[0]);
2456 else if (gl_state.units[j].pointer_texcoord_gltype == GL_BYTE)
2458 const GLbyte *sb = (const GLbyte *)((const unsigned char *)gl_state.units[j].pointer_texcoord_pointer + element * gl_state.units[j].pointer_texcoord_stride);
2459 if (vid.texarrayunits > 1)
2461 if (gl_state.units[j].pointer_texcoord_components == 4)
2462 qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2], sb[3]);
2463 else if (gl_state.units[j].pointer_texcoord_components == 3)
2464 qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, sb[0], sb[1], sb[2]);
2465 else if (gl_state.units[j].pointer_texcoord_components == 2)
2466 qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, sb[0], sb[1]);
2467 else if (gl_state.units[j].pointer_texcoord_components == 1)
2468 qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, sb[0]);
2472 if (gl_state.units[j].pointer_texcoord_components == 4)
2473 qglTexCoord4f(sb[0], sb[1], sb[2], sb[3]);
2474 else if (gl_state.units[j].pointer_texcoord_components == 3)
2475 qglTexCoord3f(sb[0], sb[1], sb[2]);
2476 else if (gl_state.units[j].pointer_texcoord_components == 2)
2477 qglTexCoord2f(sb[0], sb[1]);
2478 else if (gl_state.units[j].pointer_texcoord_components == 1)
2479 qglTexCoord1f(sb[0]);
2484 if (gl_state.pointer_color_pointer && gl_state.pointer_color_enabled && gl_state.pointer_color_components == 4)
2486 if (gl_state.pointer_color_gltype == GL_FLOAT)
2488 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2489 qglColor4f(p[0], p[1], p[2], p[3]);
2491 else if (gl_state.pointer_color_gltype == GL_UNSIGNED_BYTE)
2493 const GLubyte *ub = (const GLubyte *)((const unsigned char *)gl_state.pointer_color_pointer + element * gl_state.pointer_color_stride);
2494 qglColor4ub(ub[0], ub[1], ub[2], ub[3]);
2497 if (gl_state.pointer_vertex_gltype == GL_FLOAT)
2499 p = (const GLfloat *)((const unsigned char *)gl_state.pointer_vertex_pointer + element * gl_state.pointer_vertex_stride);
2500 if (gl_state.pointer_vertex_components == 4)
2501 qglVertex4f(p[0], p[1], p[2], p[3]);
2502 else if (gl_state.pointer_vertex_components == 3)
2503 qglVertex3f(p[0], p[1], p[2]);
2505 qglVertex2f(p[0], p[1]);
2511 else if (bufferobject3s)
2513 GL_BindEBO(bufferobject3s);
2514 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2516 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
2521 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
2525 else if (bufferobject3i)
2527 GL_BindEBO(bufferobject3i);
2528 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2530 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
2535 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
2542 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2544 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
2549 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
2556 if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
2558 qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
2563 qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
2569 qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
2573 case RENDERPATH_D3D9:
2575 if (gl_state.d3dvertexbuffer && ((element3s && element3s_indexbuffer) || (element3i && element3i_indexbuffer)))
2577 if (element3s_indexbuffer)
2579 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3s_indexbuffer->devicebuffer);
2580 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3s_bufferoffset>>1, numtriangles);
2582 else if (element3i_indexbuffer)
2584 IDirect3DDevice9_SetIndices(vid_d3d9dev, (IDirect3DIndexBuffer9 *)element3i_indexbuffer->devicebuffer);
2585 IDirect3DDevice9_DrawIndexedPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, 0, firstvertex, numvertices, element3i_bufferoffset>>2, numtriangles);
2588 IDirect3DDevice9_DrawPrimitive(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices);
2593 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3s + firsttriangle*3, D3DFMT_INDEX16, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2595 IDirect3DDevice9_DrawIndexedPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, firstvertex, numvertices, numtriangles, element3i + firsttriangle*3, D3DFMT_INDEX32, gl_state.d3dvertexdata, gl_state.d3dvertexsize);
2597 IDirect3DDevice9_DrawPrimitiveUP(vid_d3d9dev, D3DPT_TRIANGLELIST, numvertices, (void *) ((byte *) gl_state.d3dvertexdata + (numvertices * gl_state.d3dvertexsize)), gl_state.d3dvertexsize);
2601 case RENDERPATH_D3D10:
2602 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2604 case RENDERPATH_D3D11:
2605 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2611 // restores backend state, used when done with 3D rendering
2612 void R_Mesh_Finish(void)
2614 R_Mesh_ResetRenderTargets();
2617 r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isdynamic, qboolean isindex16)
2619 r_meshbuffer_t *buffer;
2620 if (!(isdynamic ? (isindexbuffer ? gl_state.usevbo_dynamicindex : gl_state.usevbo_dynamicvertex) : (isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex)))
2622 buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
2623 memset(buffer, 0, sizeof(*buffer));
2624 buffer->bufferobject = 0;
2625 buffer->devicebuffer = NULL;
2627 buffer->isindexbuffer = isindexbuffer;
2628 buffer->isdynamic = isdynamic;
2629 buffer->isindex16 = isindex16;
2630 strlcpy(buffer->name, name, sizeof(buffer->name));
2631 R_Mesh_UpdateMeshBuffer(buffer, data, size);
2635 void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size)
2639 if (buffer->isindexbuffer)
2641 r_refdef.stats.indexbufferuploadcount++;
2642 r_refdef.stats.indexbufferuploadsize += size;
2646 r_refdef.stats.vertexbufferuploadcount++;
2647 r_refdef.stats.vertexbufferuploadsize += size;
2649 switch(vid.renderpath)
2651 case RENDERPATH_GL11:
2652 case RENDERPATH_GL13:
2653 case RENDERPATH_GL20:
2654 case RENDERPATH_CGGL:
2655 if (!buffer->bufferobject)
2656 qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
2657 if (buffer->isindexbuffer)
2658 GL_BindEBO(buffer->bufferobject);
2660 GL_BindVBO(buffer->bufferobject);
2661 qglBufferDataARB(buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER_ARB : GL_ARRAY_BUFFER_ARB, size, data, buffer->isdynamic ? GL_STREAM_DRAW_ARB : GL_STATIC_DRAW_ARB);
2663 case RENDERPATH_D3D9:
2667 void *datapointer = NULL;
2668 if (buffer->isindexbuffer)
2670 IDirect3DIndexBuffer9 *d3d9indexbuffer = (IDirect3DIndexBuffer9 *)buffer->devicebuffer;
2671 if (size > buffer->size || !buffer->devicebuffer)
2673 if (buffer->devicebuffer)
2674 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9*)buffer->devicebuffer);
2675 buffer->devicebuffer = NULL;
2676 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)))
2677 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);
2678 buffer->devicebuffer = (void *)d3d9indexbuffer;
2679 buffer->size = size;
2681 if (!FAILED(IDirect3DIndexBuffer9_Lock(d3d9indexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2684 memcpy(datapointer, data, size);
2686 memset(datapointer, 0, size);
2687 IDirect3DIndexBuffer9_Unlock(d3d9indexbuffer);
2692 IDirect3DVertexBuffer9 *d3d9vertexbuffer = (IDirect3DVertexBuffer9 *)buffer->devicebuffer;
2693 if (size > buffer->size || !buffer->devicebuffer)
2695 if (buffer->devicebuffer)
2696 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9*)buffer->devicebuffer);
2697 buffer->devicebuffer = NULL;
2698 if (FAILED(result = IDirect3DDevice9_CreateVertexBuffer(vid_d3d9dev, size, buffer->isdynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0, 0, buffer->isdynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &d3d9vertexbuffer, NULL)))
2699 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);
2700 buffer->devicebuffer = (void *)d3d9vertexbuffer;
2701 buffer->size = size;
2703 if (!FAILED(IDirect3DVertexBuffer9_Lock(d3d9vertexbuffer, 0, 0, &datapointer, buffer->isdynamic ? D3DLOCK_DISCARD : 0)))
2706 memcpy(datapointer, data, size);
2708 memset(datapointer, 0, size);
2709 IDirect3DVertexBuffer9_Unlock(d3d9vertexbuffer);
2715 case RENDERPATH_D3D10:
2716 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2718 case RENDERPATH_D3D11:
2719 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2724 void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
2728 switch(vid.renderpath)
2730 case RENDERPATH_GL11:
2731 case RENDERPATH_GL13:
2732 case RENDERPATH_GL20:
2733 case RENDERPATH_CGGL:
2734 qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
2736 case RENDERPATH_D3D9:
2738 if (gl_state.d3dvertexbuffer == (void *)buffer)
2739 gl_state.d3dvertexbuffer = NULL;
2740 if (buffer->devicebuffer)
2742 if (buffer->isindexbuffer)
2743 IDirect3DIndexBuffer9_Release((IDirect3DIndexBuffer9 *)buffer->devicebuffer);
2745 IDirect3DVertexBuffer9_Release((IDirect3DVertexBuffer9 *)buffer->devicebuffer);
2746 buffer->devicebuffer = NULL;
2750 case RENDERPATH_D3D10:
2751 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2753 case RENDERPATH_D3D11:
2754 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2757 Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
2760 void GL_Mesh_ListVBOs(qboolean printeach)
2763 size_t ebocount = 0, ebomemory = 0;
2764 size_t vbocount = 0, vbomemory = 0;
2765 r_meshbuffer_t *buffer;
2766 endindex = Mem_ExpandableArray_IndexRange(&gl_state.meshbufferarray);
2767 for (i = 0;i < endindex;i++)
2769 buffer = (r_meshbuffer_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.meshbufferarray, i);
2772 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)");}
2773 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)");}
2775 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);
2780 void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
2782 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2783 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)
2785 gl_state.pointer_vertex_components = components;
2786 gl_state.pointer_vertex_gltype = gltype;
2787 gl_state.pointer_vertex_stride = stride;
2788 gl_state.pointer_vertex_pointer = pointer;
2789 gl_state.pointer_vertex_vertexbuffer = vertexbuffer;
2790 gl_state.pointer_vertex_offset = bufferoffset;
2792 GL_BindVBO(bufferobject);
2793 qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
2797 void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
2799 // note: vertexbuffer may be non-NULL even if pointer is NULL, so check
2800 // the pointer only.
2803 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2804 // caller wants color array enabled
2805 if (!gl_state.pointer_color_enabled)
2807 gl_state.pointer_color_enabled = true;
2809 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
2811 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)
2813 gl_state.pointer_color_components = components;
2814 gl_state.pointer_color_gltype = gltype;
2815 gl_state.pointer_color_stride = stride;
2816 gl_state.pointer_color_pointer = pointer;
2817 gl_state.pointer_color_vertexbuffer = vertexbuffer;
2818 gl_state.pointer_color_offset = bufferoffset;
2820 GL_BindVBO(bufferobject);
2821 qglColorPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
2826 // caller wants color array disabled
2827 if (gl_state.pointer_color_enabled)
2829 gl_state.pointer_color_enabled = false;
2831 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
2832 // when color array is on the glColor gets trashed, set it again
2833 qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]);CHECKGLERROR
2838 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)
2840 gltextureunit_t *unit = gl_state.units + unitnum;
2841 // update array settings
2843 // note: there is no need to check bufferobject here because all cases
2844 // that involve a valid bufferobject also supply a texcoord array
2847 int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
2848 // texture array unit is enabled, enable the array
2849 if (!unit->arrayenabled)
2851 unit->arrayenabled = true;
2852 GL_ClientActiveTexture(unitnum);
2853 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
2856 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)
2858 unit->pointer_texcoord_components = components;
2859 unit->pointer_texcoord_gltype = gltype;
2860 unit->pointer_texcoord_stride = stride;
2861 unit->pointer_texcoord_pointer = pointer;
2862 unit->pointer_texcoord_vertexbuffer = vertexbuffer;
2863 unit->pointer_texcoord_offset = bufferoffset;
2864 GL_ClientActiveTexture(unitnum);
2865 GL_BindVBO(bufferobject);
2866 qglTexCoordPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
2871 // texture array unit is disabled, disable the array
2872 if (unit->arrayenabled)
2874 unit->arrayenabled = false;
2875 GL_ClientActiveTexture(unitnum);
2876 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
2881 int R_Mesh_TexBound(unsigned int unitnum, int id)
2883 gltextureunit_t *unit = gl_state.units + unitnum;
2884 if (unitnum >= vid.teximageunits)
2886 if (id == GL_TEXTURE_2D)
2888 if (id == GL_TEXTURE_3D)
2890 if (id == GL_TEXTURE_CUBE_MAP_ARB)
2891 return unit->tcubemap;
2895 void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
2897 switch(vid.renderpath)
2899 case RENDERPATH_GL11:
2900 case RENDERPATH_GL13:
2901 case RENDERPATH_GL20:
2902 case RENDERPATH_CGGL:
2903 R_Mesh_TexBind(0, tex);
2904 GL_ActiveTexture(0);CHECKGLERROR
2905 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
2907 case RENDERPATH_D3D9:
2910 IDirect3DSurface9 *currentsurface = NULL;
2911 IDirect3DSurface9 *texturesurface = NULL;
2914 sourcerect.left = sx;
2915 sourcerect.top = sy;
2916 sourcerect.right = sx + width;
2917 sourcerect.bottom = sy + height;
2920 destrect.right = tx + width;
2921 destrect.bottom = ty + height;
2922 if (!FAILED(IDirect3DTexture9_GetSurfaceLevel(((IDirect3DTexture9 *)tex->d3dtexture), 0, &texturesurface)))
2924 if (!FAILED(IDirect3DDevice9_GetRenderTarget(vid_d3d9dev, 0, ¤tsurface)))
2926 IDirect3DDevice9_StretchRect(vid_d3d9dev, currentsurface, &sourcerect, texturesurface, &destrect, D3DTEXF_NONE);
2927 IDirect3DSurface9_Release(currentsurface);
2929 IDirect3DSurface9_Release(texturesurface);
2934 case RENDERPATH_D3D10:
2935 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2937 case RENDERPATH_D3D11:
2938 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2944 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};
2947 void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
2949 gltextureunit_t *unit = gl_state.units + unitnum;
2950 int tex2d, tex3d, texcubemap, texnum;
2951 if (unitnum >= vid.teximageunits)
2953 // if (unit->texture == tex)
2955 switch(vid.renderpath)
2957 case RENDERPATH_GL20:
2958 case RENDERPATH_CGGL:
2961 tex = r_texture_white;
2962 // not initialized enough yet...
2966 unit->texture = tex;
2967 texnum = R_GetTexture(tex);
2968 switch(tex->gltexturetypeenum)
2970 case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
2971 case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
2972 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;
2975 case RENDERPATH_GL13:
2976 case RENDERPATH_GL11:
2977 unit->texture = tex;
2983 texnum = R_GetTexture(tex);
2984 switch(tex->gltexturetypeenum)
2992 case GL_TEXTURE_CUBE_MAP_ARB:
2993 texcubemap = texnum;
2997 // update 2d texture binding
2998 if (unit->t2d != tex2d)
3000 GL_ActiveTexture(unitnum);
3005 qglEnable(GL_TEXTURE_2D);CHECKGLERROR
3012 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3016 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3018 // update 3d texture binding
3019 if (unit->t3d != tex3d)
3021 GL_ActiveTexture(unitnum);
3026 qglEnable(GL_TEXTURE_3D);CHECKGLERROR
3033 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3037 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3039 // update cubemap texture binding
3040 if (unit->tcubemap != texcubemap)
3042 GL_ActiveTexture(unitnum);
3045 if (unit->tcubemap == 0)
3047 qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3054 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3057 unit->tcubemap = texcubemap;
3058 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3061 case RENDERPATH_D3D9:
3064 extern cvar_t gl_texture_anisotropy;
3067 tex = r_texture_white;
3068 // not initialized enough yet...
3072 if (unit->texture == tex)
3074 unit->texture = tex;
3075 // upload texture if needed
3077 R_RealGetTexture(tex);
3078 IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
3079 //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
3080 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
3081 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
3082 if (tex->d3daddressw)
3083 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
3084 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
3085 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
3086 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
3087 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
3088 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
3089 IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
3093 case RENDERPATH_D3D10:
3094 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3096 case RENDERPATH_D3D11:
3097 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3102 void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
3104 gltextureunit_t *unit = gl_state.units + unitnum;
3105 switch(vid.renderpath)
3107 case RENDERPATH_GL11:
3108 case RENDERPATH_GL13:
3109 case RENDERPATH_GL20:
3110 case RENDERPATH_CGGL:
3111 if (matrix && matrix->m[3][3])
3113 // texmatrix specified, check if it is different
3114 if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
3117 unit->texmatrixenabled = true;
3118 unit->matrix = *matrix;
3120 Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
3121 GL_ActiveTexture(unitnum);
3122 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3123 qglLoadMatrixf(glmatrix);CHECKGLERROR
3124 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3129 // no texmatrix specified, revert to identity
3130 if (unit->texmatrixenabled)
3132 unit->texmatrixenabled = false;
3133 unit->matrix = identitymatrix;
3135 GL_ActiveTexture(unitnum);
3136 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3137 qglLoadIdentity();CHECKGLERROR
3138 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3142 case RENDERPATH_D3D9:
3143 case RENDERPATH_D3D10:
3144 case RENDERPATH_D3D11:
3149 void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
3151 gltextureunit_t *unit = gl_state.units + unitnum;
3153 switch(vid.renderpath)
3155 case RENDERPATH_GL20:
3156 case RENDERPATH_CGGL:
3159 case RENDERPATH_GL13:
3160 // GL_ARB_texture_env_combine
3162 combinergb = GL_MODULATE;
3164 combinealpha = GL_MODULATE;
3169 if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
3171 if (combinergb == GL_DECAL)
3172 combinergb = GL_INTERPOLATE_ARB;
3173 if (unit->combine != GL_COMBINE_ARB)
3175 unit->combine = GL_COMBINE_ARB;
3176 GL_ActiveTexture(unitnum);
3177 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
3178 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
3180 if (unit->combinergb != combinergb)
3182 unit->combinergb = combinergb;
3183 GL_ActiveTexture(unitnum);
3184 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
3186 if (unit->combinealpha != combinealpha)
3188 unit->combinealpha = combinealpha;
3189 GL_ActiveTexture(unitnum);
3190 qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
3192 if (unit->rgbscale != rgbscale)
3194 unit->rgbscale = rgbscale;
3195 GL_ActiveTexture(unitnum);
3196 qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
3198 if (unit->alphascale != alphascale)
3200 unit->alphascale = alphascale;
3201 GL_ActiveTexture(unitnum);
3202 qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
3207 if (unit->combine != combinergb)
3209 unit->combine = combinergb;
3210 GL_ActiveTexture(unitnum);
3211 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3215 case RENDERPATH_GL11:
3218 combinergb = GL_MODULATE;
3219 if (unit->combine != combinergb)
3221 unit->combine = combinergb;
3222 GL_ActiveTexture(unitnum);
3223 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3226 case RENDERPATH_D3D9:
3227 case RENDERPATH_D3D10:
3228 case RENDERPATH_D3D11:
3233 void R_Mesh_ResetTextureState(void)
3235 unsigned int unitnum;
3240 switch(vid.renderpath)
3242 case RENDERPATH_GL20:
3243 case RENDERPATH_CGGL:
3244 for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
3246 gltextureunit_t *unit = gl_state.units + unitnum;
3250 GL_ActiveTexture(unitnum);
3251 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3256 GL_ActiveTexture(unitnum);
3257 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3262 GL_ActiveTexture(unitnum);
3263 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3266 for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
3268 gltextureunit_t *unit = gl_state.units + unitnum;
3269 if (unit->arrayenabled)
3271 unit->arrayenabled = false;
3272 GL_ClientActiveTexture(unitnum);
3273 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3276 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3278 gltextureunit_t *unit = gl_state.units + unitnum;
3279 if (unit->texmatrixenabled)
3281 unit->texmatrixenabled = false;
3282 unit->matrix = identitymatrix;
3284 GL_ActiveTexture(unitnum);
3285 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3286 qglLoadIdentity();CHECKGLERROR
3287 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3291 case RENDERPATH_GL13:
3292 case RENDERPATH_GL11:
3293 for (unitnum = 0;unitnum < vid.texunits;unitnum++)
3295 gltextureunit_t *unit = gl_state.units + unitnum;
3299 GL_ActiveTexture(unitnum);
3300 qglDisable(GL_TEXTURE_2D);CHECKGLERROR
3301 qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
3306 GL_ActiveTexture(unitnum);
3307 qglDisable(GL_TEXTURE_3D);CHECKGLERROR
3308 qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
3313 GL_ActiveTexture(unitnum);
3314 qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
3315 qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
3317 if (unit->arrayenabled)
3319 unit->arrayenabled = false;
3320 GL_ClientActiveTexture(unitnum);
3321 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
3323 if (unit->texmatrixenabled)
3325 unit->texmatrixenabled = false;
3326 unit->matrix = identitymatrix;
3328 GL_ActiveTexture(unitnum);
3329 qglMatrixMode(GL_TEXTURE);CHECKGLERROR
3330 qglLoadIdentity();CHECKGLERROR
3331 qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
3333 if (unit->combine != GL_MODULATE)
3335 unit->combine = GL_MODULATE;
3336 GL_ActiveTexture(unitnum);
3337 qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
3341 case RENDERPATH_D3D9:
3342 case RENDERPATH_D3D10:
3343 case RENDERPATH_D3D11:
3351 //#define r_vertexposition_d3d9fvf (D3DFVF_XYZ)
3352 //#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
3353 //#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
3355 D3DVERTEXELEMENT9 r_vertexposition_d3d9elements[] =
3357 {0, (int)((size_t)&((r_vertexposition_t *)0)->vertex3f), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3361 D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
3363 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3364 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3365 {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3369 D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
3371 {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3372 {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4ub ), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3373 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3374 {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3375 {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
3376 {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
3377 {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
3381 IDirect3DVertexDeclaration9 *r_vertexposition_d3d9decl;
3382 IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
3383 IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
3386 static void R_Mesh_InitVertexDeclarations(void)
3389 r_vertexposition_d3d9decl = NULL;
3390 r_vertexgeneric_d3d9decl = NULL;
3391 r_vertexmesh_d3d9decl = NULL;
3392 switch(vid.renderpath)
3394 case RENDERPATH_GL20:
3395 case RENDERPATH_CGGL:
3396 case RENDERPATH_GL13:
3397 case RENDERPATH_GL11:
3399 case RENDERPATH_D3D9:
3400 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexposition_d3d9elements, &r_vertexposition_d3d9decl);
3401 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
3402 IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
3404 case RENDERPATH_D3D10:
3405 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3407 case RENDERPATH_D3D11:
3408 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3414 static void R_Mesh_DestroyVertexDeclarations(void)
3417 if (r_vertexposition_d3d9decl)
3418 IDirect3DVertexDeclaration9_Release(r_vertexposition_d3d9decl);
3419 r_vertexposition_d3d9decl = NULL;
3420 if (r_vertexgeneric_d3d9decl)
3421 IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
3422 r_vertexgeneric_d3d9decl = NULL;
3423 if (r_vertexmesh_d3d9decl)
3424 IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
3425 r_vertexmesh_d3d9decl = NULL;
3429 r_vertexposition_t *R_Mesh_PrepareVertices_Position_Lock(int numvertices)
3432 size = sizeof(r_vertexposition_t) * numvertices;
3433 if (gl_state.preparevertices_tempdatamaxsize < size)
3435 gl_state.preparevertices_tempdatamaxsize = size;
3436 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3438 gl_state.preparevertices_vertexposition = (r_vertexposition_t *)gl_state.preparevertices_tempdata;
3439 gl_state.preparevertices_numvertices = numvertices;
3440 return gl_state.preparevertices_vertexposition;
3443 qboolean R_Mesh_PrepareVertices_Position_Unlock(void)
3445 R_Mesh_PrepareVertices_Position(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexposition, NULL);
3446 gl_state.preparevertices_vertexposition = NULL;
3447 gl_state.preparevertices_numvertices = 0;
3451 void R_Mesh_PrepareVertices_Position_Arrays(int numvertices, const float *vertex3f)
3454 r_vertexposition_t *vertex;
3455 switch(vid.renderpath)
3457 case RENDERPATH_GL20:
3458 case RENDERPATH_CGGL:
3459 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3460 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3461 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3462 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3463 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3464 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3465 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3467 case RENDERPATH_GL13:
3468 case RENDERPATH_GL11:
3469 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3470 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3471 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3472 if (vid.texunits >= 2)
3473 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3474 if (vid.texunits >= 3)
3475 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3477 case RENDERPATH_D3D9:
3479 gl_state.d3dvertexbuffer = NULL;
3480 gl_state.d3dvertexdata = (void *)vertex3f;
3481 gl_state.d3dvertexsize = sizeof(float[3]);
3484 case RENDERPATH_D3D10:
3485 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3487 case RENDERPATH_D3D11:
3488 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3492 // no quick path for this case, convert to vertex structs
3493 vertex = R_Mesh_PrepareVertices_Position_Lock(numvertices);
3494 for (i = 0;i < numvertices;i++)
3495 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3496 R_Mesh_PrepareVertices_Position_Unlock();
3497 R_Mesh_PrepareVertices_Position(numvertices, vertex, NULL);
3500 void R_Mesh_PrepareVertices_Position(int numvertices, const r_vertexposition_t *vertex, const r_meshbuffer_t *vertexbuffer)
3502 // upload temporary vertexbuffer for this rendering
3503 if (!gl_state.usevbo_staticvertex)
3504 vertexbuffer = NULL;
3505 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3507 if (gl_state.preparevertices_dynamicvertexbuffer)
3508 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3510 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3511 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3513 switch(vid.renderpath)
3515 case RENDERPATH_GL20:
3516 case RENDERPATH_CGGL:
3519 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3520 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3521 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3522 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3523 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3524 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3525 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3529 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3530 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3531 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3532 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3533 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3534 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3535 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3538 case RENDERPATH_GL13:
3541 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3542 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3543 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3544 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3548 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3549 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3550 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3551 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3554 case RENDERPATH_GL11:
3557 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3558 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3559 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3563 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3564 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
3565 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3568 case RENDERPATH_D3D9:
3570 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexposition_d3d9decl);
3572 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
3574 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3575 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3576 gl_state.d3dvertexdata = (void *)vertex;
3577 gl_state.d3dvertexsize = sizeof(*vertex);
3580 case RENDERPATH_D3D10:
3581 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3583 case RENDERPATH_D3D11:
3584 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3591 r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices)
3594 size = sizeof(r_vertexgeneric_t) * numvertices;
3595 if (gl_state.preparevertices_tempdatamaxsize < size)
3597 gl_state.preparevertices_tempdatamaxsize = size;
3598 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3600 gl_state.preparevertices_vertexgeneric = (r_vertexgeneric_t *)gl_state.preparevertices_tempdata;
3601 gl_state.preparevertices_numvertices = numvertices;
3602 return gl_state.preparevertices_vertexgeneric;
3605 qboolean R_Mesh_PrepareVertices_Generic_Unlock(void)
3607 R_Mesh_PrepareVertices_Generic(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexgeneric, NULL);
3608 gl_state.preparevertices_vertexgeneric = NULL;
3609 gl_state.preparevertices_numvertices = 0;
3613 void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
3616 r_vertexgeneric_t *vertex;
3617 switch(vid.renderpath)
3619 case RENDERPATH_GL20:
3620 case RENDERPATH_CGGL:
3621 if (gl_mesh_separatearrays.integer)
3623 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3624 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3625 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3626 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3627 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3628 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3629 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3633 case RENDERPATH_GL13:
3634 case RENDERPATH_GL11:
3635 if (gl_mesh_separatearrays.integer)
3637 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3638 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3639 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
3640 if (vid.texunits >= 2)
3641 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3642 if (vid.texunits >= 3)
3643 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3647 case RENDERPATH_D3D9:
3648 case RENDERPATH_D3D10:
3649 case RENDERPATH_D3D11:
3653 // no quick path for this case, convert to vertex structs
3654 vertex = R_Mesh_PrepareVertices_Generic_Lock(numvertices);
3655 for (i = 0;i < numvertices;i++)
3656 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3659 for (i = 0;i < numvertices;i++)
3660 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
3664 float tempcolor4f[4];
3665 unsigned char tempcolor4ub[4];
3666 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
3667 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
3668 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
3669 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
3670 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
3671 for (i = 0;i < numvertices;i++)
3672 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
3675 for (i = 0;i < numvertices;i++)
3676 Vector2Copy(texcoord2f + 2*i, vertex[i].texcoord2f);
3677 R_Mesh_PrepareVertices_Generic_Unlock();
3678 R_Mesh_PrepareVertices_Generic(numvertices, vertex, NULL);
3681 void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer)
3683 // upload temporary vertexbuffer for this rendering
3684 if (!gl_state.usevbo_staticvertex)
3685 vertexbuffer = NULL;
3686 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3688 if (gl_state.preparevertices_dynamicvertexbuffer)
3689 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3691 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3692 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3694 switch(vid.renderpath)
3696 case RENDERPATH_GL20:
3697 case RENDERPATH_CGGL:
3700 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3701 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3702 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3703 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3704 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3705 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3706 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3710 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3711 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3712 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3713 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3714 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3715 R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3716 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3719 case RENDERPATH_GL13:
3722 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3723 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3724 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3725 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3729 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3730 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3731 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3732 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3735 case RENDERPATH_GL11:
3738 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3739 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3740 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , vertexbuffer, (int)((unsigned char *)vertex->texcoord2f - (unsigned char *)vertex));
3744 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3745 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3746 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoord2f , NULL, 0);
3749 case RENDERPATH_D3D9:
3751 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9decl);
3753 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
3755 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3756 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3757 gl_state.d3dvertexdata = (void *)vertex;
3758 gl_state.d3dvertexsize = sizeof(*vertex);
3761 case RENDERPATH_D3D10:
3762 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3764 case RENDERPATH_D3D11:
3765 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3772 r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices)
3775 size = sizeof(r_vertexmesh_t) * numvertices;
3776 if (gl_state.preparevertices_tempdatamaxsize < size)
3778 gl_state.preparevertices_tempdatamaxsize = size;
3779 gl_state.preparevertices_tempdata = Mem_Realloc(r_main_mempool, gl_state.preparevertices_tempdata, gl_state.preparevertices_tempdatamaxsize);
3781 gl_state.preparevertices_vertexmesh = (r_vertexmesh_t *)gl_state.preparevertices_tempdata;
3782 gl_state.preparevertices_numvertices = numvertices;
3783 return gl_state.preparevertices_vertexmesh;
3786 qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void)
3788 R_Mesh_PrepareVertices_Mesh(gl_state.preparevertices_numvertices, gl_state.preparevertices_vertexmesh, NULL);
3789 gl_state.preparevertices_vertexmesh = NULL;
3790 gl_state.preparevertices_numvertices = 0;
3794 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)
3797 r_vertexmesh_t *vertex;
3798 switch(vid.renderpath)
3800 case RENDERPATH_GL20:
3801 case RENDERPATH_CGGL:
3802 if (gl_mesh_separatearrays.integer)
3804 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3805 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3806 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
3807 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
3808 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
3809 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
3810 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
3814 case RENDERPATH_GL13:
3815 case RENDERPATH_GL11:
3816 if (gl_mesh_separatearrays.integer)
3818 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
3819 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
3820 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
3821 if (vid.texunits >= 2)
3822 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
3823 if (vid.texunits >= 3)
3824 R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
3828 case RENDERPATH_D3D9:
3829 case RENDERPATH_D3D10:
3830 case RENDERPATH_D3D11:
3834 vertex = R_Mesh_PrepareVertices_Mesh_Lock(numvertices);
3835 for (i = 0;i < numvertices;i++)
3836 VectorCopy(vertex3f + 3*i, vertex[i].vertex3f);
3838 for (i = 0;i < numvertices;i++)
3839 VectorCopy(svector3f + 3*i, vertex[i].svector3f);
3841 for (i = 0;i < numvertices;i++)
3842 VectorCopy(tvector3f + 3*i, vertex[i].tvector3f);
3844 for (i = 0;i < numvertices;i++)
3845 VectorCopy(normal3f + 3*i, vertex[i].normal3f);
3848 for (i = 0;i < numvertices;i++)
3849 Vector4Scale(color4f + 4*i, 255.0f, vertex[i].color4ub);
3853 float tempcolor4f[4];
3854 unsigned char tempcolor4ub[4];
3855 Vector4Scale(gl_state.color4f, 255.0f, tempcolor4f);
3856 tempcolor4ub[0] = (unsigned char)bound(0.0f, tempcolor4f[0], 255.0f);
3857 tempcolor4ub[1] = (unsigned char)bound(0.0f, tempcolor4f[1], 255.0f);
3858 tempcolor4ub[2] = (unsigned char)bound(0.0f, tempcolor4f[2], 255.0f);
3859 tempcolor4ub[3] = (unsigned char)bound(0.0f, tempcolor4f[3], 255.0f);
3860 for (i = 0;i < numvertices;i++)
3861 Vector4Copy(tempcolor4ub, vertex[i].color4ub);
3863 if (texcoordtexture2f)
3864 for (i = 0;i < numvertices;i++)
3865 Vector2Copy(texcoordtexture2f + 2*i, vertex[i].texcoordtexture2f);
3866 if (texcoordlightmap2f)
3867 for (i = 0;i < numvertices;i++)
3868 Vector2Copy(texcoordlightmap2f + 2*i, vertex[i].texcoordlightmap2f);
3869 R_Mesh_PrepareVertices_Mesh_Unlock();
3870 R_Mesh_PrepareVertices_Mesh(numvertices, vertex, NULL);
3873 void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *vertexbuffer)
3875 // upload temporary vertexbuffer for this rendering
3876 if (!gl_state.usevbo_staticvertex)
3877 vertexbuffer = NULL;
3878 if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
3880 if (gl_state.preparevertices_dynamicvertexbuffer)
3881 R_Mesh_UpdateMeshBuffer(gl_state.preparevertices_dynamicvertexbuffer, vertex, numvertices * sizeof(*vertex));
3883 gl_state.preparevertices_dynamicvertexbuffer = R_Mesh_CreateMeshBuffer(vertex, numvertices * sizeof(*vertex), "temporary", false, true, false);
3884 vertexbuffer = gl_state.preparevertices_dynamicvertexbuffer;
3886 switch(vid.renderpath)
3888 case RENDERPATH_GL20:
3889 case RENDERPATH_CGGL:
3892 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3893 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3894 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
3895 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , vertexbuffer, (int)((unsigned char *)vertex->svector3f - (unsigned char *)vertex));
3896 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , vertexbuffer, (int)((unsigned char *)vertex->tvector3f - (unsigned char *)vertex));
3897 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , vertexbuffer, (int)((unsigned char *)vertex->normal3f - (unsigned char *)vertex));
3898 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
3902 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3903 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3904 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
3905 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(*vertex), vertex->svector3f , NULL, 0);
3906 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(*vertex), vertex->tvector3f , NULL, 0);
3907 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(*vertex), vertex->normal3f , NULL, 0);
3908 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
3911 case RENDERPATH_GL13:
3914 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3915 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3916 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
3917 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, vertexbuffer, (int)((unsigned char *)vertex->texcoordlightmap2f - (unsigned char *)vertex));
3921 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3922 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3923 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
3924 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordlightmap2f, NULL, 0);
3927 case RENDERPATH_GL11:
3930 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , vertexbuffer, (int)((unsigned char *)vertex->vertex3f - (unsigned char *)vertex));
3931 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , vertexbuffer, (int)((unsigned char *)vertex->color4ub - (unsigned char *)vertex));
3932 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , vertexbuffer, (int)((unsigned char *)vertex->texcoordtexture2f - (unsigned char *)vertex));
3936 R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(*vertex), vertex->vertex3f , NULL, 0);
3937 R_Mesh_ColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(*vertex), vertex->color4ub , NULL, 0);
3938 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(*vertex), vertex->texcoordtexture2f , NULL, 0);
3941 case RENDERPATH_D3D9:
3943 IDirect3DDevice9_SetVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9decl);
3945 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, (IDirect3DVertexBuffer9*)vertexbuffer->devicebuffer, 0, sizeof(*vertex));
3947 IDirect3DDevice9_SetStreamSource(vid_d3d9dev, 0, NULL, 0, 0);
3948 gl_state.d3dvertexbuffer = (void *)vertexbuffer;
3949 gl_state.d3dvertexdata = (void *)vertex;
3950 gl_state.d3dvertexsize = sizeof(*vertex);
3953 case RENDERPATH_D3D10:
3954 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3956 case RENDERPATH_D3D11:
3957 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);