6 static int max_verts; // always max_meshs * 3
7 #define TRANSDEPTHRES 4096
9 static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "21760"};
10 static cvar_t gl_mesh_batchtriangles = {0, "gl_mesh_batchtriangles", "1024"};
11 static cvar_t gl_mesh_merge = {0, "gl_mesh_merge", "1"};
12 static cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
14 typedef struct buf_mesh_s
16 struct buf_mesh_s *next;
18 int blendfunc1, blendfunc2;
19 int textures[MAX_TEXTUREUNITS];
20 float texturergbscale[MAX_TEXTUREUNITS];
26 typedef struct buf_transtri_s
28 struct buf_transtri_s *next;
34 typedef struct buf_tri_s
64 static float meshfarclip;
65 static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, meshmerge, floatcolors, transranout;
66 static buf_mesh_t *buf_mesh;
67 static buf_tri_t *buf_tri;
68 static buf_vertex_t *buf_vertex;
69 static buf_fcolor_t *buf_fcolor;
70 static buf_bcolor_t *buf_bcolor;
71 static buf_texcoord_t *buf_texcoord[MAX_TEXTUREUNITS];
73 static int currenttransmesh, currenttransvertex, currenttranstriangle;
74 static buf_mesh_t *buf_transmesh;
75 static buf_transtri_t *buf_transtri;
76 static buf_transtri_t **buf_transtri_list;
77 static buf_vertex_t *buf_transvertex;
78 static buf_fcolor_t *buf_transfcolor;
79 static buf_bcolor_t *buf_transbcolor;
80 static buf_texcoord_t *buf_transtexcoord[MAX_TEXTUREUNITS];
82 static mempool_t *gl_backend_mempool;
84 static void gl_backend_start(void)
88 max_verts = max_meshs * 3;
90 gl_backend_mempool = Mem_AllocPool("GL_Backend");
92 #define BACKENDALLOC(var, count, sizeofstruct)\
94 var = Mem_Alloc(gl_backend_mempool, count * sizeof(sizeofstruct));\
96 Sys_Error("gl_backend_start: unable to allocate memory\n");\
97 memset(var, 0, count * sizeof(sizeofstruct));\
100 BACKENDALLOC(buf_mesh, max_meshs, buf_mesh_t)
101 BACKENDALLOC(buf_tri, max_meshs, buf_tri_t)
102 BACKENDALLOC(buf_vertex, max_verts, buf_vertex_t)
103 BACKENDALLOC(buf_fcolor, max_verts, buf_fcolor_t)
104 BACKENDALLOC(buf_bcolor, max_verts, buf_bcolor_t)
106 BACKENDALLOC(buf_transmesh, max_meshs, buf_mesh_t)
107 BACKENDALLOC(buf_transtri, max_meshs, buf_transtri_t)
108 BACKENDALLOC(buf_transtri_list, TRANSDEPTHRES, buf_transtri_t *)
109 BACKENDALLOC(buf_transvertex, max_verts, buf_vertex_t)
110 BACKENDALLOC(buf_transfcolor, max_verts, buf_fcolor_t)
111 BACKENDALLOC(buf_transbcolor, max_verts, buf_bcolor_t)
113 for (i = 0;i < MAX_TEXTUREUNITS;i++)
115 // only allocate as many texcoord arrays as we need
116 if (i < gl_textureunits)
118 BACKENDALLOC(buf_texcoord[i], max_verts, buf_texcoord_t)
119 BACKENDALLOC(buf_transtexcoord[i], max_verts, buf_texcoord_t)
123 buf_texcoord[i] = NULL;
124 buf_transtexcoord[i] = NULL;
127 backendunits = min(MAX_TEXTUREUNITS, gl_textureunits);
128 backendactive = true;
131 static void gl_backend_shutdown(void)
135 #define BACKENDFREE(var)\
142 #define BACKENDFREE(var) var = NULL;
144 BACKENDFREE(buf_mesh)
146 BACKENDFREE(buf_vertex)
147 BACKENDFREE(buf_fcolor)
148 BACKENDFREE(buf_bcolor)
150 BACKENDFREE(buf_transmesh)
151 BACKENDFREE(buf_transtri)
152 BACKENDFREE(buf_transtri_list)
153 BACKENDFREE(buf_transvertex)
154 BACKENDFREE(buf_transfcolor)
155 BACKENDFREE(buf_transbcolor)
157 for (i = 0;i < MAX_TEXTUREUNITS;i++)
159 BACKENDFREE(buf_texcoord[i])
160 BACKENDFREE(buf_transtexcoord[i])
163 Mem_FreePool(&gl_backend_mempool);
166 backendactive = false;
169 static void gl_backend_bufferchanges(int init)
171 // 21760 is (65536 / 3) rounded off to a multiple of 128
172 if (gl_mesh_maxtriangles.integer < 256)
173 Cvar_SetValue("gl_mesh_maxtriangles", 256);
174 if (gl_mesh_maxtriangles.integer > 21760)
175 Cvar_SetValue("gl_mesh_maxtriangles", 21760);
177 if (gl_mesh_batchtriangles.integer < 0)
178 Cvar_SetValue("gl_mesh_batchtriangles", 0);
179 if (gl_mesh_batchtriangles.integer > gl_mesh_maxtriangles.integer)
180 Cvar_SetValue("gl_mesh_batchtriangles", gl_mesh_maxtriangles.integer);
182 max_batch = gl_mesh_batchtriangles.integer;
184 if (max_meshs != gl_mesh_maxtriangles.integer)
186 max_meshs = gl_mesh_maxtriangles.integer;
190 gl_backend_shutdown();
196 float r_farclip, r_newfarclip;
198 static void gl_backend_newmap(void)
200 r_farclip = r_newfarclip = 2048.0f;
203 int polyindexarray[768];
205 void gl_backend_init(void)
208 Cvar_RegisterVariable(&gl_mesh_maxtriangles);
209 Cvar_RegisterVariable(&gl_mesh_batchtriangles);
210 Cvar_RegisterVariable(&gl_mesh_merge);
211 Cvar_RegisterVariable(&gl_mesh_floatcolors);
212 R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
213 gl_backend_bufferchanges(true);
214 for (i = 0;i < 256;i++)
216 polyindexarray[i*3+0] = 0;
217 polyindexarray[i*3+1] = i + 1;
218 polyindexarray[i*3+2] = i + 2;
222 static float viewdist;
226 // called at beginning of frame
227 void R_Mesh_Clear(void)
230 Sys_Error("R_Mesh_Clear: called when backend is not active\n");
232 gl_backend_bufferchanges(false);
237 currenttransmesh = 0;
238 currenttranstriangle = 0;
239 currenttransvertex = 0;
241 meshmerge = gl_mesh_merge.integer;
242 floatcolors = gl_mesh_floatcolors.integer;
244 viewdist = DotProduct(r_origin, vpn);
250 void GL_PrintError(int errornumber, char *filename, int linenumber)
254 case GL_INVALID_ENUM:
255 Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
257 case GL_INVALID_VALUE:
258 Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
260 case GL_INVALID_OPERATION:
261 Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
263 case GL_STACK_OVERFLOW:
264 Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
266 case GL_STACK_UNDERFLOW:
267 Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
269 case GL_OUT_OF_MEMORY:
270 Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
272 case GL_TABLE_TOO_LARGE:
273 Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
276 Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
284 // renders mesh buffers, called to flush buffers when full
285 void R_Mesh_Render(void)
287 int i, k, blendfunc1, blendfunc2, blend, depthmask, unit = 0, clientunit = 0, firsttriangle, triangles, texture[MAX_TEXTUREUNITS];
288 float farclip, texturergbscale[MAX_TEXTUREUNITS];
291 Sys_Error("R_Mesh_Render: called when backend is not active\n");
297 farclip = meshfarclip + 256.0f - viewdist; // + 256 just to be safe
299 // push out farclip for next frame
300 if (farclip > r_newfarclip)
301 r_newfarclip = ceil((farclip + 255) / 256) * 256 + 256;
303 for (i = 0;i < backendunits;i++)
304 texturergbscale[i] = 1;
306 glEnable(GL_CULL_FACE);
308 glCullFace(GL_FRONT);
310 glEnable(GL_DEPTH_TEST);
313 blendfunc2 = GL_ZERO;
314 glBlendFunc(blendfunc1, blendfunc2);
320 glDepthMask((GLuint) depthmask);
324 glVertexPointer(3, GL_FLOAT, sizeof(buf_vertex_t), buf_vertex);
326 glEnableClientState(GL_VERTEX_ARRAY);
330 glColorPointer(4, GL_FLOAT, sizeof(buf_fcolor_t), buf_fcolor);
335 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(buf_bcolor_t), buf_bcolor);
338 glEnableClientState(GL_COLOR_ARRAY);
341 if (backendunits > 1)
343 for (i = 0;i < backendunits;i++)
345 qglActiveTexture(GL_TEXTURE0_ARB + (unit = i));
347 glBindTexture(GL_TEXTURE_2D, (texture[i] = 0));
349 glDisable(GL_TEXTURE_2D);
351 if (gl_combine.integer)
353 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
355 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
357 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
359 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
361 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
363 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
365 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
367 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
369 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
371 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
373 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
375 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);
377 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
379 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
381 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
383 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f);
385 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);
390 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
394 qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i));
396 glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[i]);
398 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
404 glBindTexture(GL_TEXTURE_2D, (texture[0] = 0));
406 glDisable(GL_TEXTURE_2D);
408 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
411 glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[0]);
413 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
417 // lock as early as possible
418 GL_LockArray(0, currentvertex);
421 for (k = 0;k < currentmesh;)
425 if (backendunits > 1)
428 for (i = 0;i < backendunits;i++)
430 if (texture[i] != mesh->textures[i])
434 qglActiveTexture(GL_TEXTURE0_ARB + (unit = i));
439 glEnable(GL_TEXTURE_2D);
441 // have to disable texcoord array on disabled texture
442 // units due to NVIDIA driver bug with
443 // compiled_vertex_array
446 qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i));
449 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
452 glBindTexture(GL_TEXTURE_2D, (texture[i] = mesh->textures[i]));
456 glDisable(GL_TEXTURE_2D);
458 // have to disable texcoord array on disabled texture
459 // units due to NVIDIA driver bug with
460 // compiled_vertex_array
463 qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i));
466 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
470 if (texturergbscale[i] != mesh->texturergbscale[i])
474 qglActiveTexture(GL_TEXTURE0_ARB + (unit = i));
477 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (texturergbscale[i] = mesh->texturergbscale[i]));
483 // if (unit != topunit)
485 // qglActiveTexture(GL_TEXTURE0_ARB + (unit = topunit));
491 if (texture[0] != mesh->textures[0])
495 glEnable(GL_TEXTURE_2D);
497 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
500 glBindTexture(GL_TEXTURE_2D, (texture[0] = mesh->textures[0]));
504 glDisable(GL_TEXTURE_2D);
506 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
511 if (blendfunc1 != mesh->blendfunc1 || blendfunc2 != mesh->blendfunc2)
513 blendfunc1 = mesh->blendfunc1;
514 blendfunc2 = mesh->blendfunc2;
515 glBlendFunc(blendfunc1, blendfunc2);
517 if (blendfunc2 == GL_ZERO)
519 if (blendfunc1 == GL_ONE)
548 if (depthmask != mesh->depthmask)
550 depthmask = mesh->depthmask;
551 glDepthMask((GLuint) depthmask);
555 firsttriangle = mesh->firsttriangle;
556 triangles = mesh->triangles;
557 mesh = &buf_mesh[++k];
561 #if MAX_TEXTUREUNITS != 4
562 #error update this code
564 while (k < currentmesh
565 && mesh->blendfunc1 == blendfunc1
566 && mesh->blendfunc2 == blendfunc2
567 && mesh->depthmask == depthmask
568 && mesh->textures[0] == texture[0]
569 && mesh->textures[1] == texture[1]
570 && mesh->textures[2] == texture[2]
571 && mesh->textures[3] == texture[3]
572 && mesh->texturergbscale[0] == texturergbscale[0]
573 && mesh->texturergbscale[1] == texturergbscale[1]
574 && mesh->texturergbscale[2] == texturergbscale[2]
575 && mesh->texturergbscale[3] == texturergbscale[3])
577 triangles += mesh->triangles;
578 mesh = &buf_mesh[++k];
582 glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[firsttriangle]);
593 if (backendunits > 1)
595 for (i = backendunits - 1;i >= 0;i--)
597 qglActiveTexture(GL_TEXTURE0_ARB + (unit = i));
599 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
601 if (gl_combine.integer)
603 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f);
608 glDisable(GL_TEXTURE_2D);
613 glEnable(GL_TEXTURE_2D);
616 glBindTexture(GL_TEXTURE_2D, 0);
619 qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i));
621 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
627 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
629 glEnable(GL_TEXTURE_2D);
631 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
634 glDisableClientState(GL_COLOR_ARRAY);
636 glDisableClientState(GL_VERTEX_ARRAY);
643 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
647 void R_Mesh_AddTransparent(void)
650 float viewdistcompare, centerscaler, dist1, dist2, dist3, center, maxdist;
651 buf_vertex_t *vert1, *vert2, *vert3;
655 // process and add transparent mesh triangles
656 if (!currenttranstriangle)
659 // map farclip to 0-4095 list range
660 centerscaler = (TRANSDEPTHRES / r_farclip) * (1.0f / 3.0f);
661 viewdistcompare = viewdist + 4.0f;
663 memset(buf_transtri_list, 0, TRANSDEPTHRES * sizeof(buf_transtri_t *));
665 // process in reverse because transtri_list adding code is in reverse as well
667 for (j = currenttranstriangle - 1;j >= 0;j--)
669 tri = &buf_transtri[j];
671 vert1 = &buf_transvertex[tri->index[0]];
672 vert2 = &buf_transvertex[tri->index[1]];
673 vert3 = &buf_transvertex[tri->index[2]];
675 dist1 = DotProduct(vert1->v, vpn);
676 dist2 = DotProduct(vert2->v, vpn);
677 dist3 = DotProduct(vert3->v, vpn);
679 maxdist = max(dist1, max(dist2, dist3));
680 if (maxdist < viewdistcompare)
683 center = (dist1 + dist2 + dist3) * centerscaler - viewdist;
686 i = bound(0, i, (TRANSDEPTHRES - 1));
690 center += 8388608.0f;
691 i = *((long *)¢er) & 0x7FFFFF;
692 i = min(i, (TRANSDEPTHRES - 1));
694 tri->next = buf_transtri_list[i];
695 buf_transtri_list[i] = tri;
699 if (currentmesh + k > max_meshs || currenttriangle + k > max_batch || currentvertex + currenttransvertex > max_verts)
702 // note: can't batch these because they can be rendered in any order
703 // there can never be more transparent triangles than fit in main buffers
704 memcpy(&buf_vertex[currentvertex], &buf_transvertex[0], currenttransvertex * sizeof(buf_vertex_t));
706 memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[0], currenttransvertex * sizeof(buf_fcolor_t));
708 memcpy(&buf_fcolor[currentvertex], &buf_transbcolor[0], currenttransvertex * sizeof(buf_bcolor_t));
709 for (i = 0;i < backendunits;i++)
710 memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][0], currenttransvertex * sizeof(buf_texcoord_t));
712 for (j = TRANSDEPTHRES - 1;j >= 0;j--)
714 if ((tri = buf_transtri_list[j]))
718 mesh = &buf_mesh[currentmesh++];
719 *mesh = *tri->mesh; // copy mesh properties
720 buf_tri[currenttriangle].index[0] = tri->index[0] + currentvertex;
721 buf_tri[currenttriangle].index[1] = tri->index[1] + currentvertex;
722 buf_tri[currenttriangle].index[2] = tri->index[2] + currentvertex;
723 mesh->firsttriangle = currenttriangle++;
729 currentvertex += currenttransvertex;
730 currenttransmesh = 0;
731 currenttranstriangle = 0;
732 currenttransvertex = 0;
735 void R_Mesh_Draw(const rmeshinfo_t *m)
737 static int i, j, *index, overbright;
738 static float c, *in, scaler, cr, cg, cb, ca;
739 static buf_mesh_t *mesh;
740 static buf_vertex_t *vert;
741 static buf_fcolor_t *fcolor;
742 static buf_bcolor_t *bcolor;
743 static buf_texcoord_t *texcoord[MAX_TEXTUREUNITS];
744 static buf_transtri_t *tri;
745 static byte br, bg, bb, ba;
754 Sys_Error("R_DrawMesh: called when backend is not active\n");
758 if (currenttransmesh >= max_meshs || (currenttranstriangle + m->numtriangles) > max_meshs || (currenttransvertex + m->numverts) > max_verts)
762 Con_Printf("R_DrawMesh: ran out of room for transparent meshs\n");
768 vert = &buf_transvertex[currenttransvertex];
769 fcolor = &buf_transfcolor[currenttransvertex];
770 bcolor = &buf_transbcolor[currenttransvertex];
771 for (i = 0;i < backendunits;i++)
772 texcoord[i] = &buf_transtexcoord[i][currenttransvertex];
776 if (m->numtriangles > max_meshs || m->numverts > max_verts)
778 Con_Printf("R_DrawMesh: mesh too big for buffers\n");
782 if (currentmesh >= max_meshs || (currenttriangle + m->numtriangles) > max_batch || (currentvertex + m->numverts) > max_verts)
785 vert = &buf_vertex[currentvertex];
786 fcolor = &buf_fcolor[currentvertex];
787 bcolor = &buf_bcolor[currentvertex];
788 for (i = 0;i < backendunits;i++)
789 texcoord[i] = &buf_texcoord[i][currentvertex];
792 // vertex array code is shared for transparent and opaque meshs
794 for (i = 0, in = m->vertex;i < m->numverts;i++, (int)in += m->vertexstep)
796 vert[i].v[0] = in[0];
797 vert[i].v[1] = in[1];
798 vert[i].v[2] = in[2];
799 // push out farclip based on vertices encountered
800 c = DotProduct(vert[i].v, vpn);
806 if (m->blendfunc2 == GL_SRC_COLOR)
808 if (m->blendfunc1 == GL_DST_COLOR) // 2x modulate with framebuffer
815 overbright = gl_combine.integer;
827 for (i = 0, in = m->color;i < m->numverts;i++, (int)in += m->colorstep)
829 fcolor[i].c[0] = in[0] * scaler;
830 fcolor[i].c[1] = in[1] * scaler;
831 fcolor[i].c[2] = in[2] * scaler;
832 fcolor[i].c[3] = in[3];
841 for (i = 0;i < m->numverts;i++)
854 for (i = 0, in = m->color;i < m->numverts;i++, (int)in += m->colorstep)
856 // shift float to have 8bit fraction at base of number,
857 // then read as integer and kill float bits...
858 c = in[0] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bcolor[i].c[0] = (byte) j;
859 c = in[1] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bcolor[i].c[1] = (byte) j;
860 c = in[2] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bcolor[i].c[2] = (byte) j;
861 c = in[3] + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bcolor[i].c[3] = (byte) j;
866 c = in[0] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;br = (byte) j;
867 c = in[1] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bg = (byte) j;
868 c = in[2] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bb = (byte) j;
869 c = in[3] + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;ba = (byte) j;
870 for (i = 0;i < m->numverts;i++)
880 for (j = 0;j < MAX_TEXTUREUNITS && m->tex[j];j++)
882 if (j >= backendunits)
883 Sys_Error("R_DrawMesh: texture %i supplied when there are only %i texture units\n", j + 1, backendunits);
884 for (i = 0, in = m->texcoords[j];i < m->numverts;i++, (int)in += m->texcoordstep[j])
886 texcoord[j][i].t[0] = in[0];
887 texcoord[j][i].t[1] = in[1];
890 for (;j < backendunits;j++)
892 for (i = 0;i < m->numverts;i++)
894 texcoord[j][i].t[0] = 0;
895 texcoord[j][i].t[1] = 0;
901 // transmesh is only for storage of tranparent meshs until they
902 // are inserted into the main mesh array
903 mesh = &buf_transmesh[currenttransmesh++];
904 mesh->blendfunc1 = m->blendfunc1;
905 mesh->blendfunc2 = m->blendfunc2;
906 mesh->depthmask = false;
908 for (i = 0;i < backendunits;i++)
910 if ((mesh->textures[i] = m->tex[i]))
912 mesh->texturergbscale[i] = m->texrgbscale[i];
913 if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
914 mesh->texturergbscale[i] = 1;
916 if (overbright && j >= 0)
917 mesh->texturergbscale[j] = 4;
919 // transparent meshs are broken up into individual triangles which can
920 // be sorted by depth
922 for (i = 0;i < m->numtriangles;i++)
924 tri = &buf_transtri[currenttranstriangle++];
926 tri->index[0] = *index++ + currenttransvertex;
927 tri->index[1] = *index++ + currenttransvertex;
928 tri->index[2] = *index++ + currenttransvertex;
930 currenttransvertex += m->numverts;
934 mesh = &buf_mesh[currentmesh++];
935 mesh->blendfunc1 = m->blendfunc1;
936 mesh->blendfunc2 = m->blendfunc2;
937 mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
938 mesh->firsttriangle = currenttriangle;
939 mesh->triangles = m->numtriangles;
941 for (i = 0;i < backendunits;i++)
943 if ((mesh->textures[i] = m->tex[i]))
945 mesh->texturergbscale[i] = m->texrgbscale[i];
946 if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
947 mesh->texturergbscale[i] = 1;
949 if (overbright && j >= 0)
950 mesh->texturergbscale[j] = 4;
952 // opaque meshs are rendered directly
953 index = (int *)&buf_tri[currenttriangle];
954 for (i = 0;i < m->numtriangles * 3;i++)
955 index[i] = m->index[i] + currentvertex;
956 currenttriangle += m->numtriangles;
957 currentvertex += m->numverts;
960 c_meshtris += m->numtriangles;
963 void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts)
965 m->index = polyindexarray;
966 m->numverts = numverts;
967 m->numtriangles = numverts - 2;
968 if (m->numtriangles < 1)
970 Con_Printf("R_Mesh_DrawPolygon: invalid vertex count\n");
973 if (m->numtriangles >= 256)
975 Con_Printf("R_Mesh_DrawPolygon: only up to 256 triangles (258 verts) supported\n");