2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // r_surf.c: surface-related refresh code
25 #define MAX_LIGHTMAP_SIZE 256
27 static unsigned int intblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
28 static float floatblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
30 static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4];
32 cvar_t r_ambient = {0, "r_ambient", "0"};
33 cvar_t r_drawportals = {0, "r_drawportals", "0"};
34 cvar_t r_testvis = {0, "r_testvis", "0"};
35 cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
36 cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
37 cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
38 cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"};
39 cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"};
40 cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0"};
41 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
43 // flag arrays used for visibility checking on world model
44 // (all other entities have no per-surface/per-leaf visibility checks)
45 // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
46 qbyte r_pvsbits[(32768+7)>>3];
47 // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
48 qbyte r_worldleafvisible[32768];
49 // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_surfaces
50 qbyte r_worldsurfacevisible[262144];
53 static int dlightdivtable[32768];
55 static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surface)
57 int sdtable[256], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, red, green, blue, lit, dist2, impacts, impactt, subtract, k;
59 float dist, impact[3], local[3], planenormal[3], planedist;
64 smax = (surface->extents[0] >> 4) + 1;
65 tmax = (surface->extents[1] >> 4) + 1;
68 VectorCopy(surface->mesh.data_normal3f, planenormal);
69 planedist = DotProduct(surface->mesh.data_vertex3f, planenormal);
71 for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
73 if (!(surface->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
74 continue; // not lit by this light
76 Matrix4x4_Transform(matrix, light->origin, local);
77 dist = DotProduct(local, planenormal) - planedist;
79 // for comparisons to minimum acceptable light
80 // compensate for LIGHTOFFSET
81 maxdist = (int) light->rtlight.lightmap_cullradius2 + LIGHTOFFSET;
88 VectorMA(local, -dist, planenormal, impact);
90 impacts = DotProduct (impact, surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3] - surface->texturemins[0];
91 impactt = DotProduct (impact, surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3] - surface->texturemins[1];
93 s = bound(0, impacts, smax * 16) - impacts;
94 t = bound(0, impactt, tmax * 16) - impactt;
95 i = s * s + t * t + dist2;
99 // reduce calculations
100 for (s = 0, i = impacts; s < smax; s++, i -= 16)
101 sdtable[s] = i * i + dist2;
103 maxdist3 = maxdist - dist2;
105 // convert to 8.8 blocklights format
106 red = light->rtlight.lightmap_light[0] * (1.0f / 128.0f);
107 green = light->rtlight.lightmap_light[1] * (1.0f / 128.0f);
108 blue = light->rtlight.lightmap_light[2] * (1.0f / 128.0f);
109 subtract = (int) (light->rtlight.lightmap_subtract * 4194304.0f);
113 for (t = 0;t < tmax;t++, i -= 16)
116 // make sure some part of it is visible on this line
119 maxdist2 = maxdist - td;
120 for (s = 0;s < smax;s++)
122 if (sdtable[s] < maxdist2)
124 k = dlightdivtable[(sdtable[s] + td) >> 7] - subtract;
128 bl[1] += (green * k);
143 static int R_FloatAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surface)
145 int lnum, s, t, smax, tmax, smax3, lit, impacts, impactt;
146 float sdtable[256], *bl, k, dist, dist2, maxdist, maxdist2, maxdist3, td1, td, red, green, blue, impact[3], local[3], subtract, planenormal[3], planedist;
151 smax = (surface->extents[0] >> 4) + 1;
152 tmax = (surface->extents[1] >> 4) + 1;
155 VectorCopy(surface->mesh.data_normal3f, planenormal);
156 planedist = DotProduct(surface->mesh.data_vertex3f, planenormal);
158 for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
160 if (!(surface->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
161 continue; // not lit by this light
163 Matrix4x4_Transform(matrix, light->origin, local);
164 dist = DotProduct(local, planenormal) - planedist;
166 // for comparisons to minimum acceptable light
167 // compensate for LIGHTOFFSET
168 maxdist = (int) light->rtlight.lightmap_cullradius2 + LIGHTOFFSET;
171 dist2 += LIGHTOFFSET;
172 if (dist2 >= maxdist)
175 VectorMA(local, -dist, planenormal, impact);
177 impacts = DotProduct (impact, surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3] - surface->texturemins[0];
178 impactt = DotProduct (impact, surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3] - surface->texturemins[1];
180 td = bound(0, impacts, smax * 16) - impacts;
181 td1 = bound(0, impactt, tmax * 16) - impactt;
182 td = td * td + td1 * td1 + dist2;
186 // reduce calculations
187 for (s = 0, td1 = impacts; s < smax; s++, td1 -= 16.0f)
188 sdtable[s] = td1 * td1 + dist2;
190 maxdist3 = maxdist - dist2;
192 // convert to 8.8 blocklights format
193 red = light->rtlight.lightmap_light[0];
194 green = light->rtlight.lightmap_light[1];
195 blue = light->rtlight.lightmap_light[2];
196 subtract = light->rtlight.lightmap_subtract * 32768.0f;
197 bl = floatblocklights;
200 for (t = 0;t < tmax;t++, td1 -= 16.0f)
203 // make sure some part of it is visible on this line
206 maxdist2 = maxdist - td;
207 for (s = 0;s < smax;s++)
209 if (sdtable[s] < maxdist2)
211 k = (32768.0f / (sdtable[s] + td)) - subtract;
232 Combine and scale multiple lightmaps into the 8.8 format in blocklights
235 static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface)
237 if (!r_floatbuildlightmap.integer)
239 int smax, tmax, i, j, size, size3, maps, stride, l;
240 unsigned int *bl, scale;
241 qbyte *lightmap, *out, *stain;
243 // update cached lighting info
244 surface->cached_dlight = 0;
246 smax = (surface->extents[0]>>4)+1;
247 tmax = (surface->extents[1]>>4)+1;
250 lightmap = surface->samples;
252 // set to full bright if no light data
254 if (!ent->model->brushq1.lightdata)
256 for (i = 0;i < size3;i++)
262 memset(bl, 0, size*3*sizeof(unsigned int));
265 if (surface->dlightframe == r_framecount)
267 surface->dlightframe = -1;
268 surface->cached_dlight = R_IntAddDynamicLights(&ent->inversematrix, surface);
269 if (surface->cached_dlight)
274 // add all the lightmaps
278 for (maps = 0;maps < MAXLIGHTMAPS && surface->styles[maps] != 255;maps++, lightmap += size3)
279 for (scale = d_lightstylevalue[surface->styles[maps]], i = 0;i < size3;i++)
280 bl[i] += lightmap[i] * scale;
284 stain = surface->stainsamples;
287 // the >> 16 shift adjusts down 8 bits to account for the stainmap
288 // scaling, and remaps the 0-65536 (2x overbright) to 0-256, it will
289 // be doubled during rendering to achieve 2x overbright
290 // (0 = 0.0, 128 = 1.0, 256 = 2.0)
291 if (ent->model->brushq1.lightmaprgba)
293 stride = (surface->lightmaptexturestride - smax) * 4;
294 for (i = 0;i < tmax;i++, out += stride)
296 for (j = 0;j < smax;j++)
298 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
299 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
300 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
307 stride = (surface->lightmaptexturestride - smax) * 3;
308 for (i = 0;i < tmax;i++, out += stride)
310 for (j = 0;j < smax;j++)
312 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
313 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
314 l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
319 R_UpdateTexture(surface->lightmaptexture, templight);
323 int smax, tmax, i, j, size, size3, maps, stride, l;
325 qbyte *lightmap, *out, *stain;
327 // update cached lighting info
328 surface->cached_dlight = 0;
330 smax = (surface->extents[0]>>4)+1;
331 tmax = (surface->extents[1]>>4)+1;
334 lightmap = surface->samples;
336 // set to full bright if no light data
337 bl = floatblocklights;
338 if (!ent->model->brushq1.lightdata)
340 for (i = 0;i < size3;i++)
345 memset(bl, 0, size*3*sizeof(float));
348 if (surface->dlightframe == r_framecount)
350 surface->dlightframe = -1;
351 surface->cached_dlight = R_FloatAddDynamicLights(&ent->inversematrix, surface);
352 if (surface->cached_dlight)
357 // add all the lightmaps
360 bl = floatblocklights;
361 for (maps = 0;maps < MAXLIGHTMAPS && surface->styles[maps] != 255;maps++, lightmap += size3)
362 for (scale = d_lightstylevalue[surface->styles[maps]], i = 0;i < size3;i++)
363 bl[i] += lightmap[i] * scale;
367 stain = surface->stainsamples;
368 bl = floatblocklights;
370 // this scaling adjusts down 8 bits to account for the stainmap
371 // scaling, and remaps the 0.0-2.0 (2x overbright) to 0-256, it will
372 // be doubled during rendering to achieve 2x overbright
373 // (0 = 0.0, 128 = 1.0, 256 = 2.0)
374 scale = 1.0f / (1 << 16);
375 if (ent->model->brushq1.lightmaprgba)
377 stride = (surface->lightmaptexturestride - smax) * 4;
378 for (i = 0;i < tmax;i++, out += stride)
380 for (j = 0;j < smax;j++)
382 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
383 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
384 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
391 stride = (surface->lightmaptexturestride - smax) * 3;
392 for (i = 0;i < tmax;i++, out += stride)
394 for (j = 0;j < smax;j++)
396 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
397 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
398 l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
403 R_UpdateTexture(surface->lightmaptexture, templight);
407 void R_StainNode (mnode_t *node, model_t *model, const vec3_t origin, float radius, const float fcolor[8])
409 float ndist, a, ratio, maxdist, maxdist2, maxdist3, invradius, sdtable[256], td, dist2;
410 msurface_t *surface, *endsurface;
411 int i, s, t, smax, tmax, smax3, impacts, impactt, stained;
415 maxdist = radius * radius;
416 invradius = 1.0f / radius;
421 ndist = PlaneDiff(origin, node->plane);
424 node = node->children[0];
429 node = node->children[1];
433 dist2 = ndist * ndist;
434 maxdist3 = maxdist - dist2;
436 if (node->plane->type < 3)
438 VectorCopy(origin, impact);
439 impact[node->plane->type] -= ndist;
443 impact[0] = origin[0] - node->plane->normal[0] * ndist;
444 impact[1] = origin[1] - node->plane->normal[1] * ndist;
445 impact[2] = origin[2] - node->plane->normal[2] * ndist;
448 for (surface = model->brush.data_surfaces + node->firstsurface, endsurface = surface + node->numsurfaces;surface < endsurface;surface++)
450 if (surface->stainsamples)
452 smax = (surface->extents[0] >> 4) + 1;
453 tmax = (surface->extents[1] >> 4) + 1;
455 impacts = DotProduct (impact, surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3] - surface->texturemins[0];
456 impactt = DotProduct (impact, surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3] - surface->texturemins[1];
458 s = bound(0, impacts, smax * 16) - impacts;
459 t = bound(0, impactt, tmax * 16) - impactt;
460 i = s * s + t * t + dist2;
464 // reduce calculations
465 for (s = 0, i = impacts; s < smax; s++, i -= 16)
466 sdtable[s] = i * i + dist2;
468 bl = surface->stainsamples;
473 for (t = 0;t < tmax;t++, i -= 16)
476 // make sure some part of it is visible on this line
479 maxdist2 = maxdist - td;
480 for (s = 0;s < smax;s++)
482 if (sdtable[s] < maxdist2)
484 ratio = lhrandom(0.0f, 1.0f);
485 a = (fcolor[3] + ratio * fcolor[7]) * (1.0f - sqrt(sdtable[s] + td) * invradius);
486 if (a >= (1.0f / 64.0f))
490 bl[0] = (qbyte) ((float) bl[0] + a * ((fcolor[0] + ratio * fcolor[4]) - (float) bl[0]));
491 bl[1] = (qbyte) ((float) bl[1] + a * ((fcolor[1] + ratio * fcolor[5]) - (float) bl[1]));
492 bl[2] = (qbyte) ((float) bl[2] + a * ((fcolor[2] + ratio * fcolor[6]) - (float) bl[2]));
502 // force lightmap upload
504 surface->cached_dlight = true;
508 if (node->children[0]->plane)
510 if (node->children[1]->plane)
512 R_StainNode(node->children[0], model, origin, radius, fcolor);
513 node = node->children[1];
518 node = node->children[0];
522 else if (node->children[1]->plane)
524 node = node->children[1];
529 void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
533 entity_render_t *ent;
536 if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes)
541 fcolor[3] = ca1 * (1.0f / 64.0f);
542 fcolor[4] = cr2 - cr1;
543 fcolor[5] = cg2 - cg1;
544 fcolor[6] = cb2 - cb1;
545 fcolor[7] = (ca2 - ca1) * (1.0f / 64.0f);
547 R_StainNode(r_refdef.worldmodel->brush.data_nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
549 // look for embedded bmodels
550 for (n = 0;n < cl_num_brushmodel_entities;n++)
552 ent = cl_brushmodel_entities[n];
554 if (model && model->name[0] == '*')
556 Mod_CheckLoaded(model);
557 if (model->brush.data_nodes)
559 Matrix4x4_Transform(&ent->inversematrix, origin, org);
560 R_StainNode(model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, model, org, radius, fcolor);
568 =============================================================
572 =============================================================
576 static void RSurf_AddLightmapToVertexColors_Color4f(const int *lightmapoffsets, float *c, int numverts, const qbyte *samples, int size3, const qbyte *styles)
581 if (styles[0] != 255)
583 for (i = 0;i < numverts;i++, c += 4)
585 lm = samples + lightmapoffsets[i];
586 scale = d_lightstylevalue[styles[0]] * (1.0f / 32768.0f);
587 VectorMA(c, scale, lm, c);
588 if (styles[1] != 255)
591 scale = d_lightstylevalue[styles[1]] * (1.0f / 32768.0f);
592 VectorMA(c, scale, lm, c);
593 if (styles[2] != 255)
596 scale = d_lightstylevalue[styles[2]] * (1.0f / 32768.0f);
597 VectorMA(c, scale, lm, c);
598 if (styles[3] != 255)
601 scale = d_lightstylevalue[styles[3]] * (1.0f / 32768.0f);
602 VectorMA(c, scale, lm, c);
612 static void RSurf_FogColors_Vertex3f_Color4f(const float *v, float *c, float colorscale, int numverts, const float *modelorg)
618 for (i = 0;i < numverts;i++, v += 3, c += 4)
620 VectorSubtract(v, modelorg, diff);
621 f = colorscale * (1 - exp(fogdensity/DotProduct(diff, diff)));
622 VectorScale(c, f, c);
625 else if (colorscale != 1)
626 for (i = 0;i < numverts;i++, c += 4)
627 VectorScale(c, colorscale, c);
632 static void RSurf_FoggedColors_Vertex3f_Color4f(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg)
641 for (i = 0;i < numverts;i++, v += 3, c += 4)
643 VectorSubtract(v, modelorg, diff);
644 f = 1 - exp(fogdensity/DotProduct(diff, diff));
653 for (i = 0;i < numverts;i++, c += 4)
665 static void RSurf_FogPassColors_Vertex3f_Color4f(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg)
672 for (i = 0;i < numverts;i++, v += 3, c += 4)
674 VectorSubtract(v, modelorg, diff);
675 f = exp(fogdensity/DotProduct(diff, diff));
685 static int RSurf_LightSeparate_Vertex3f_Color4f(const matrix4x4_t *matrix, const int *dlightbits, int numverts, const float *vert, float *color, float scale)
690 int i, l, lit = false;
691 const dlight_t *light;
693 for (l = 0;l < r_numdlights;l++)
695 if (dlightbits[l >> 5] & (1 << (l & 31)))
697 light = &r_dlight[l];
698 Matrix4x4_Transform(matrix, light->origin, lightorigin);
699 for (i = 0, v = vert, c = color;i < numverts;i++, v += 3, c += 4)
701 f = VectorDistance2(v, lightorigin) + LIGHTOFFSET;
702 if (f < light->rtlight.lightmap_cullradius2)
704 f = ((1.0f / f) - light->rtlight.lightmap_subtract) * scale;
705 VectorMA(c, f, light->rtlight.lightmap_light, c);
715 static float *RSurf_GetVertexPointer(const entity_render_t *ent, const msurface_t *surface)
717 if (surface->texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
719 texture_t *texture = surface->texture;
721 float center[3], center2[3], forward[3], right[3], up[3], v[4][3];
722 matrix4x4_t matrix1, imatrix1;
723 R_Mesh_Matrix(&r_identitymatrix);
724 // a single autosprite surface can contain multiple sprites...
725 for (j = 0;j < surface->mesh.num_vertices - 3;j += 4)
728 for (i = 0;i < 4;i++)
729 VectorAdd(center, surface->mesh.data_vertex3f + (j+i) * 3, center);
730 VectorScale(center, 0.25f, center);
731 Matrix4x4_Transform(&ent->matrix, center, center2);
732 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
733 Matrix4x4_FromVectors(&matrix1, surface->mesh.data_normal3f + j*3, surface->mesh.data_svector3f + j*3, surface->mesh.data_tvector3f + j*3, center);
734 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
735 for (i = 0;i < 4;i++)
736 Matrix4x4_Transform(&imatrix1, surface->mesh.data_vertex3f + (j+i)*3, v[i]);
737 if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
739 forward[0] = r_vieworigin[0] - center2[0];
740 forward[1] = r_vieworigin[1] - center2[1];
742 VectorNormalize(forward);
743 right[0] = forward[1];
744 right[1] = -forward[0];
752 VectorCopy(r_viewforward, forward);
753 VectorCopy(r_viewright, right);
754 VectorCopy(r_viewup, up);
756 for (i = 0;i < 4;i++)
757 VectorMAMAMAM(1, center2, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (i+j) * 3);
759 return varray_vertex3f;
762 return surface->mesh.data_vertex3f;
765 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
767 // we don't need to set currentframe if t->animated is false because
768 // it was already set up by the texture loader for non-animating
771 t->currentframe = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0];
774 t->currentmaterialflags = t->basematerialflags;
775 t->currentalpha = ent->alpha;
776 if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
777 t->currentalpha *= r_wateralpha.value;
778 if (!(ent->flags & RENDER_LIGHT))
779 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
780 if (ent->effects & EF_ADDITIVE)
781 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
782 else if (t->currentalpha < 1)
783 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
786 matrix4x4_t r_surf_waterscrollmatrix;
788 void R_UpdateAllTextureInfo(entity_render_t *ent)
791 Matrix4x4_CreateTranslate(&r_surf_waterscrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
793 for (i = 0;i < ent->model->brush.num_textures;i++)
794 R_UpdateTextureInfo(ent, ent->model->brush.data_textures + i);
797 static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
800 int texturesurfaceindex;
804 float f, r, g, b, a, base, colorscale;
805 const msurface_t *surface;
812 qboolean fogallpasses;
813 qboolean waterscrolling;
815 texture = texture->currentframe;
816 if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
818 c_faces += texturenumsurfaces;
819 // gl_lightmaps debugging mode skips normal texturing
820 if (gl_lightmaps.integer)
822 GL_BlendFunc(GL_ONE, GL_ZERO);
825 qglDisable(GL_CULL_FACE);
826 GL_Color(1, 1, 1, 1);
827 memset(&m, 0, sizeof(m));
828 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
830 surface = texturesurfacelist[texturesurfaceindex];
831 m.tex[0] = R_GetTexture(surface->lightmaptexture);
832 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
833 if (surface->lightmaptexture)
835 GL_Color(1, 1, 1, 1);
836 m.pointer_color = NULL;
839 m.pointer_color = surface->mesh.data_lightmapcolor4f;
840 m.pointer_vertex = surface->mesh.data_vertex3f;
842 GL_LockArrays(0, surface->mesh.num_vertices);
843 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
846 qglEnable(GL_CULL_FACE);
849 GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
850 GL_DepthMask(!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT));
851 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
852 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
853 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
854 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
856 GL_BlendFunc(GL_ONE, GL_ZERO);
857 // water waterscrolling in texture matrix
858 waterscrolling = (texture->currentmaterialflags & MATERIALFLAG_WATER) && r_waterscroll.value != 0;
859 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
860 qglDisable(GL_CULL_FACE);
861 if (texture->currentmaterialflags & MATERIALFLAG_SKY)
865 skyrendernow = false;
869 // LordHavoc: HalfLife maps have freaky skypolys...
870 if (!ent->model->brush.ishlbsp)
872 R_Mesh_Matrix(&ent->matrix);
873 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
876 // depth-only (masking)
877 GL_ColorMask(0,0,0,0);
878 // just to make sure that braindead drivers don't draw anything
879 // despite that colormask...
880 GL_BlendFunc(GL_ZERO, GL_ONE);
885 GL_BlendFunc(GL_ONE, GL_ZERO);
889 memset(&m, 0, sizeof(m));
890 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
892 surface = texturesurfacelist[texturesurfaceindex];
893 m.pointer_vertex = surface->mesh.data_vertex3f;
895 GL_LockArrays(0, surface->mesh.num_vertices);
896 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
899 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
902 else if ((texture->currentmaterialflags & MATERIALFLAG_WATER) && r_watershader.value && gl_textureshader && !texture->skin.glow && !fogenabled && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
904 // NVIDIA Geforce3 distortion texture shader on water
905 float args[4] = {0.05f,0,0,0.04f};
906 memset(&m, 0, sizeof(m));
907 m.tex[0] = R_GetTexture(mod_shared_distorttexture[(int)(r_refdef.time * 16)&63]);
908 m.tex[1] = R_GetTexture(texture->skin.base);
909 m.texcombinergb[0] = GL_REPLACE;
910 m.texcombinergb[1] = GL_REPLACE;
911 Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value);
912 m.texmatrix[1] = r_surf_waterscrollmatrix;
915 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
917 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
918 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB);
919 qglTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[0]);
920 qglEnable(GL_TEXTURE_SHADER_NV);
922 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
924 surface = texturesurfacelist[texturesurfaceindex];
925 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
926 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
927 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
929 GL_LockArrays(0, surface->mesh.num_vertices);
930 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
934 qglDisable(GL_TEXTURE_SHADER_NV);
935 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
938 else if (texture->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
940 // normal surface (wall or water)
942 dolightmap = !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
943 doambient = r_ambient.value >= (1/64.0f);
944 dodetail = texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
945 doglow = texture->skin.glow != NULL;
946 dofogpass = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD);
947 fogallpasses = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
948 if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
950 if (dobase && dolightmap && gl_combine.integer)
953 memset(&m, 0, sizeof(m));
954 m.tex[1] = R_GetTexture(texture->skin.base);
956 m.texmatrix[1] = r_surf_waterscrollmatrix;
957 m.texrgbscale[1] = 2;
958 m.pointer_color = varray_color4f;
960 r = ent->colormod[0] * colorscale;
961 g = ent->colormod[1] * colorscale;
962 b = ent->colormod[2] * colorscale;
963 a = texture->currentalpha;
964 base = r_ambient.value * (1.0f / 64.0f);
965 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
967 surface = texturesurfacelist[texturesurfaceindex];
968 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
969 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
970 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
971 if (surface->lightmaptexture)
973 m.tex[0] = R_GetTexture(surface->lightmaptexture);
976 m.pointer_color = varray_color4f;
977 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
979 VectorSubtract(v, modelorg, diff);
980 f = 1 - exp(fogdensity/DotProduct(diff, diff));
989 m.pointer_color = NULL;
990 GL_Color(r, g, b, a);
995 m.tex[0] = R_GetTexture(r_texture_white);
996 m.pointer_color = varray_color4f;
998 if (surface->styles[0] != 255 || surface->dlightframe == r_framecount)
1000 if (surface->styles[0] != 255)
1003 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1008 if (surface->styles[0] != 255)
1010 if (surface->mesh.data_lightmapcolor4f)
1012 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 128.0f);
1013 VectorMA(c, scale, surface->mesh.data_lightmapcolor4f + i*4, c);
1015 else if (surface->mesh.data_lightmapoffsets)
1017 const qbyte *lm = surface->samples + surface->mesh.data_lightmapoffsets[i];
1018 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 32768.0f);
1019 VectorMA(c, scale, lm, c);
1020 if (surface->styles[1] != 255)
1022 int size3 = ((surface->extents[0]>>4)+1)*((surface->extents[1]>>4)+1)*3;
1024 scale = d_lightstylevalue[surface->styles[1]] * (1.0f / 32768.0f);
1025 VectorMA(c, scale, lm, c);
1026 if (surface->styles[2] != 255)
1029 scale = d_lightstylevalue[surface->styles[2]] * (1.0f / 32768.0f);
1030 VectorMA(c, scale, lm, c);
1031 if (surface->styles[3] != 255)
1034 scale = d_lightstylevalue[surface->styles[3]] * (1.0f / 32768.0f);
1035 VectorMA(c, scale, lm, c);
1042 if (surface->dlightframe == r_framecount)
1045 float worldvertex[3];
1046 // TODO: make this work with autosprite which uses identitymatrix
1047 Matrix4x4_Transform(&ent->matrix, v, worldvertex);
1048 for (l = 0;l < r_numdlights;l++)
1050 if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
1053 dlight_t *light = &r_dlight[l];
1054 f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
1055 if (f2 < light->rtlight.lightmap_cullradius2)
1057 f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
1058 VectorMA(c, f2, light->rtlight.lightmap_light, c);
1069 VectorSubtract(v, modelorg, diff);
1070 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1071 VectorScale(c, f, c);
1073 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1074 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1081 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1083 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1088 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1093 m.pointer_color = NULL;
1094 GL_Color(0, 0, 0, a);
1099 GL_LockArrays(0, surface->mesh.num_vertices);
1100 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1101 GL_LockArrays(0, 0);
1107 memset(&m, 0, sizeof(m));
1108 m.tex[0] = R_GetTexture(texture->skin.base);
1110 m.texmatrix[0] = r_surf_waterscrollmatrix;
1111 m.texmatrix[0] = r_surf_waterscrollmatrix;
1112 m.pointer_color = varray_color4f;
1114 if (gl_combine.integer)
1116 m.texrgbscale[0] = 4;
1117 colorscale *= 0.25f;
1119 r = ent->colormod[0] * colorscale;
1120 g = ent->colormod[1] * colorscale;
1121 b = ent->colormod[2] * colorscale;
1122 a = texture->currentalpha;
1125 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1127 surface = texturesurfacelist[texturesurfaceindex];
1128 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1129 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1130 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1135 if (surface->styles[0] != 255)
1137 if (surface->mesh.data_lightmapcolor4f)
1139 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 128.0f);
1140 VectorMA(c, scale, surface->mesh.data_lightmapcolor4f + i*4, c);
1142 else if (surface->mesh.data_lightmapoffsets)
1144 const qbyte *lm = surface->samples + surface->mesh.data_lightmapoffsets[i];
1145 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 32768.0f);
1146 VectorMA(c, scale, lm, c);
1147 if (surface->styles[1] != 255)
1149 int size3 = ((surface->extents[0]>>4)+1)*((surface->extents[1]>>4)+1)*3;
1151 scale = d_lightstylevalue[surface->styles[1]] * (1.0f / 32768.0f);
1152 VectorMA(c, scale, lm, c);
1153 if (surface->styles[2] != 255)
1156 scale = d_lightstylevalue[surface->styles[2]] * (1.0f / 32768.0f);
1157 VectorMA(c, scale, lm, c);
1158 if (surface->styles[3] != 255)
1161 scale = d_lightstylevalue[surface->styles[3]] * (1.0f / 32768.0f);
1162 VectorMA(c, scale, lm, c);
1169 if (surface->dlightframe == r_framecount)
1171 // TODO: make this work with autosprite which uses identitymatrix
1172 Matrix4x4_Transform(&ent->matrix, v, worldvertex);
1173 for (l = 0;l < r_numdlights;l++)
1175 if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
1178 dlight_t *light = &r_dlight[l];
1179 f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
1180 if (f2 < light->rtlight.lightmap_cullradius2)
1182 f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
1183 VectorMA(c, f2, light->rtlight.lightmap_light, c);
1194 VectorSubtract(v, modelorg, diff);
1195 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1196 VectorScale(c, f, c);
1198 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1199 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1204 GL_LockArrays(0, surface->mesh.num_vertices);
1205 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1206 GL_LockArrays(0, 0);
1213 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1215 surface = texturesurfacelist[texturesurfaceindex];
1216 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1217 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1219 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
1220 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1222 m.pointer_color = varray_color4f;
1223 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1225 VectorSubtract(v, modelorg, diff);
1226 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1230 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1235 m.pointer_color = varray_color4f;
1236 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1238 VectorSubtract(v, modelorg, diff);
1239 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1247 GL_LockArrays(0, surface->mesh.num_vertices);
1248 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1249 GL_LockArrays(0, 0);
1254 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1256 surface = texturesurfacelist[texturesurfaceindex];
1257 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1258 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1260 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
1261 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1263 m.pointer_color = varray_color4f;
1264 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1269 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1274 m.pointer_color = NULL;
1275 GL_Color(r, g, b, a);
1278 GL_LockArrays(0, surface->mesh.num_vertices);
1279 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1280 GL_LockArrays(0, 0);
1288 if (!dolightmap && dobase)
1292 GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
1293 memset(&m, 0, sizeof(m));
1294 m.tex[0] = R_GetTexture(texture->skin.base);
1296 m.texmatrix[0] = r_surf_waterscrollmatrix;
1297 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1299 surface = texturesurfacelist[texturesurfaceindex];
1300 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1301 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1303 GL_LockArrays(0, surface->mesh.num_vertices);
1304 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1305 GL_LockArrays(0, 0);
1308 if (r_lightmapintensity <= 0 && dolightmap && dobase)
1312 GL_Color(0, 0, 0, 1);
1313 memset(&m, 0, sizeof(m));
1314 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1316 surface = texturesurfacelist[texturesurfaceindex];
1317 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1319 GL_LockArrays(0, surface->mesh.num_vertices);
1320 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1321 GL_LockArrays(0, 0);
1324 if (r_textureunits.integer >= 2 && gl_combine.integer && dolightmap && dobase)
1326 // dualtexture combine
1327 GL_BlendFunc(GL_ONE, GL_ZERO);
1331 memset(&m, 0, sizeof(m));
1332 m.tex[1] = R_GetTexture(texture->skin.base);
1334 m.texmatrix[1] = r_surf_waterscrollmatrix;
1335 m.texrgbscale[1] = 2;
1336 r = ent->colormod[0] * r_lightmapintensity;
1337 g = ent->colormod[1] * r_lightmapintensity;
1338 b = ent->colormod[2] * r_lightmapintensity;
1339 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1341 surface = texturesurfacelist[texturesurfaceindex];
1342 memset(&m, 0, sizeof(m));
1343 m.tex[1] = R_GetTexture(texture->skin.base);
1345 m.texmatrix[1] = r_surf_waterscrollmatrix;
1346 m.texrgbscale[1] = 2;
1347 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1348 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
1349 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
1350 if (surface->lightmaptexture)
1352 m.tex[0] = R_GetTexture(surface->lightmaptexture);
1353 m.pointer_color = NULL;
1354 GL_Color(r, g, b, 1);
1356 else if (r == 1 && g == 1 && b == 1)
1358 m.tex[0] = R_GetTexture(r_texture_white);
1359 m.pointer_color = surface->mesh.data_lightmapcolor4f;
1363 m.tex[0] = R_GetTexture(r_texture_white);
1364 m.pointer_color = varray_color4f;
1365 for (i = 0;i < surface->mesh.num_vertices;i++)
1367 varray_color4f[i*4+0] = surface->mesh.data_lightmapcolor4f[i*4+0] * r;
1368 varray_color4f[i*4+1] = surface->mesh.data_lightmapcolor4f[i*4+1] * g;
1369 varray_color4f[i*4+2] = surface->mesh.data_lightmapcolor4f[i*4+2] * b;
1370 varray_color4f[i*4+3] = surface->mesh.data_lightmapcolor4f[i*4+3];
1374 GL_LockArrays(0, surface->mesh.num_vertices);
1375 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1376 GL_LockArrays(0, 0);
1382 GL_BlendFunc(GL_ONE, GL_ZERO);
1384 GL_Color(1, 1, 1, 1);
1385 memset(&m, 0, sizeof(m));
1386 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1388 surface = texturesurfacelist[texturesurfaceindex];
1389 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1390 m.tex[0] = R_GetTexture(surface->lightmaptexture);
1391 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
1392 if (surface->lightmaptexture)
1393 m.pointer_color = NULL;
1395 m.pointer_color = surface->mesh.data_lightmapcolor4f;
1397 GL_LockArrays(0, surface->mesh.num_vertices);
1398 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1399 GL_LockArrays(0, 0);
1404 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
1405 GL_DepthMask(false);
1406 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
1407 memset(&m, 0, sizeof(m));
1408 m.tex[0] = R_GetTexture(texture->skin.base);
1410 m.texmatrix[0] = r_surf_waterscrollmatrix;
1411 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1413 surface = texturesurfacelist[texturesurfaceindex];
1414 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1415 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1417 GL_LockArrays(0, surface->mesh.num_vertices);
1418 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1419 GL_LockArrays(0, 0);
1426 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1427 GL_DepthMask(false);
1428 memset(&m, 0, sizeof(m));
1429 m.tex[0] = R_GetTexture(texture->skin.base);
1431 m.texmatrix[0] = r_surf_waterscrollmatrix;
1432 m.pointer_color = varray_color4f;
1434 if (gl_combine.integer)
1436 m.texrgbscale[0] = 4;
1437 colorscale *= 0.25f;
1439 base = r_ambient.value * (1.0f / 64.0f);
1440 r = ent->colormod[0] * colorscale * base;
1441 g = ent->colormod[1] * colorscale * base;
1442 b = ent->colormod[2] * colorscale * base;
1443 a = texture->currentalpha;
1444 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1446 surface = texturesurfacelist[texturesurfaceindex];
1447 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1448 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1449 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1456 VectorSubtract(v, modelorg, diff);
1457 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1458 VectorScale(c, f, c);
1460 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1461 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1466 GL_LockArrays(0, surface->mesh.num_vertices);
1467 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1468 GL_LockArrays(0, 0);
1471 // marklights based vertex dlight rendering... evil and broken
1473 GL_BlendFunc(GL_ONE, GL_ONE);
1474 GL_DepthMask(false);
1475 memset(&m, 0, sizeof(m));
1476 m.tex[0] = R_GetTexture(texture->skin.base);
1478 m.texmatrix[0] = r_surf_waterscrollmatrix;
1479 m.pointer_color = varray_color4f;
1480 r = ent->colormod[0] * r_lightmapintensity;
1481 g = ent->colormod[1] * r_lightmapintensity;
1482 b = ent->colormod[2] * r_lightmapintensity;
1483 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1486 surface = texturesurfacelist[texturesurfaceindex];
1487 if (surface->dlightframe != r_framecount)
1489 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1490 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1492 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1498 // TODO: make this work with autosprite which uses identitymatrix or change autosprite
1499 Matrix4x4_Transform(&ent->matrix, v, worldvertex);
1500 for (l = 0;l < r_numdlights;l++)
1502 if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
1505 dlight_t *light = &r_dlight[l];
1506 f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
1507 if (f2 < light->rtlight.lightmap_cullradius2)
1509 f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
1510 VectorMA(c, f2, light->rtlight.lightmap_light, c);
1520 VectorSubtract(v, modelorg, diff);
1521 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1522 VectorScale(c, f, c);
1524 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1525 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1532 GL_LockArrays(0, surface->mesh.num_vertices);
1533 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1534 GL_LockArrays(0, 0);
1539 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
1540 GL_DepthMask(false);
1541 GL_Color(1, 1, 1, 1);
1542 memset(&m, 0, sizeof(m));
1543 m.tex[0] = R_GetTexture(texture->skin.detail);
1544 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1546 surface = texturesurfacelist[texturesurfaceindex];
1547 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1548 m.pointer_texcoord[0] = surface->mesh.data_texcoorddetail2f;
1550 GL_LockArrays(0, surface->mesh.num_vertices);
1551 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1552 GL_LockArrays(0, 0);
1557 // if glow was not already done using multitexture, do it now.
1558 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1559 GL_DepthMask(false);
1560 memset(&m, 0, sizeof(m));
1561 m.tex[0] = R_GetTexture(texture->skin.glow);
1563 m.texmatrix[0] = r_surf_waterscrollmatrix;
1564 m.pointer_color = varray_color4f;
1566 r = ent->colormod[0] * colorscale;
1567 g = ent->colormod[1] * colorscale;
1568 b = ent->colormod[2] * colorscale;
1569 a = texture->currentalpha;
1572 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1574 surface = texturesurfacelist[texturesurfaceindex];
1575 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1576 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1577 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1579 m.pointer_color = varray_color4f;
1580 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1582 VectorSubtract(v, modelorg, diff);
1583 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1587 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1592 m.pointer_color = varray_color4f;
1593 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1595 VectorSubtract(v, modelorg, diff);
1596 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1604 GL_LockArrays(0, surface->mesh.num_vertices);
1605 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1606 GL_LockArrays(0, 0);
1611 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1613 surface = texturesurfacelist[texturesurfaceindex];
1614 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1615 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1616 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1618 m.pointer_color = varray_color4f;
1619 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1624 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1629 m.pointer_color = NULL;
1630 GL_Color(r, g, b, a);
1633 GL_LockArrays(0, surface->mesh.num_vertices);
1634 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1635 GL_LockArrays(0, 0);
1641 // if this is opaque use alpha blend which will darken the earlier
1644 // if this is an alpha blended material, all the earlier passes
1645 // were darkened by fog already, so we only need to add the fog
1646 // color ontop through the fog mask texture
1648 // if this is an additive blended material, all the earlier passes
1649 // were darkened by fog already, and we should not add fog color
1650 // (because the background was not darkened, there is no fog color
1651 // that was lost behind it).
1653 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1655 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1656 GL_DepthMask(false);
1657 memset(&m, 0, sizeof(m));
1658 m.tex[0] = R_GetTexture(texture->skin.fog);
1660 m.texmatrix[0] = r_surf_waterscrollmatrix;
1664 a = texture->currentalpha;
1665 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1667 surface = texturesurfacelist[texturesurfaceindex];
1668 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1669 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1670 m.pointer_color = varray_color4f;
1671 //RSurf_FogPassColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->mesh.num_vertices, modelorg);
1672 if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1674 m.pointer_color = varray_color4f;
1675 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1677 VectorSubtract(v, modelorg, diff);
1678 f = exp(fogdensity/DotProduct(diff, diff));
1682 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * f * a;
1687 m.pointer_color = varray_color4f;
1688 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1690 VectorSubtract(v, modelorg, diff);
1691 f = exp(fogdensity/DotProduct(diff, diff));
1699 GL_LockArrays(0, surface->mesh.num_vertices);
1700 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1701 GL_LockArrays(0, 0);
1705 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
1706 qglEnable(GL_CULL_FACE);
1709 static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata2)
1711 const entity_render_t *ent = calldata1;
1712 const msurface_t *surface = ent->model->brush.data_surfaces + calldata2;
1717 float base, colorscale;
1718 float args[4] = {0.05f,0,0,0.04f};
1719 matrix4x4_t scrollmatrix;
1722 texture = surface->texture;
1723 if (texture->basematerialflags & MATERIALFLAG_SKY)
1724 return; // transparent sky is too difficult
1725 R_UpdateTextureInfo(ent, texture);
1727 R_Mesh_Matrix(&ent->matrix);
1728 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
1729 R_DrawSurfaceList(ent, texture, 1, &surface, modelorg);
1731 GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
1732 GL_DepthMask(!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT));
1733 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
1734 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1735 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
1736 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1738 GL_BlendFunc(GL_ONE, GL_ZERO);
1740 // water scrolling in texture matrix
1741 if ((texture->currentmaterialflags & MATERIALFLAG_WATER) && r_waterscroll.value != 0)
1742 Matrix4x4_CreateTranslate(&scrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
1744 scrollmatrix = r_identitymatrix;
1746 if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
1747 qglDisable(GL_CULL_FACE);
1748 if ((texture->currentmaterialflags & MATERIALFLAG_WATER) && r_watershader.value && gl_textureshader && !texture->skin.glow && !fogenabled && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
1750 // NVIDIA Geforce3 distortion texture shader on water
1751 GL_Color(1, 1, 1, texture->currentalpha);
1752 memset(&m, 0, sizeof(m));
1753 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1754 m.tex[0] = R_GetTexture(mod_shared_distorttexture[(int)(r_refdef.time * 16)&63]);
1755 m.tex[1] = R_GetTexture(texture->skin.base);
1756 m.texcombinergb[0] = GL_REPLACE;
1757 m.texcombinergb[1] = GL_REPLACE;
1758 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1759 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
1760 Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value);
1761 m.texmatrix[1] = scrollmatrix;
1764 GL_ActiveTexture(0);
1765 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
1766 GL_ActiveTexture(1);
1767 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
1768 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB);
1769 qglTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[0]);
1770 qglEnable(GL_TEXTURE_SHADER_NV);
1772 GL_LockArrays(0, surface->mesh.num_vertices);
1773 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1774 GL_LockArrays(0, 0);
1776 qglDisable(GL_TEXTURE_SHADER_NV);
1777 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
1778 GL_ActiveTexture(0);
1783 float r, g, b, a, f, *c, diff[3];
1785 qboolean dolightmaptexture;
1788 dolightmaptexture = surface->lightmaptexture && gl_combine.integer && !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
1789 dodetail = texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
1790 doglow = texture->skin.glow != NULL;
1791 // TODO: ideally transparent surface rendering should call
1792 // R_RenderLighting instead of using vertex dlights
1793 // (it would need scrolling support added though!)
1794 if (dolightmaptexture)
1797 memset(&m, 0, sizeof(m));
1798 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1799 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1800 m.tex[0] = R_GetTexture(texture->skin.base);
1801 m.texmatrix[0] = scrollmatrix;
1802 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
1803 m.tex[1] = R_GetTexture(surface->lightmaptexture);
1804 m.texrgbscale[1] = 2;
1805 m.pointer_color = varray_color4f;
1806 if (r_textureunits.integer >= 3 && dodetail)
1809 m.pointer_texcoord[2] = surface->mesh.data_texcoorddetail2f;
1810 m.tex[2] = R_GetTexture(texture->skin.detail);
1811 m.texmatrix[2] = scrollmatrix;
1812 if (r_textureunits.integer >= 4 && doglow)
1815 m.pointer_texcoord[3] = surface->mesh.data_texcoordtexture2f;
1816 m.tex[3] = R_GetTexture(texture->skin.glow);
1817 m.texmatrix[3] = scrollmatrix;
1820 else if (r_textureunits.integer >= 3 && doglow && !dodetail)
1823 m.pointer_texcoord[2] = surface->mesh.data_texcoordtexture2f;
1824 m.tex[2] = R_GetTexture(texture->skin.glow);
1825 m.texmatrix[2] = scrollmatrix;
1828 r = ent->colormod[0] * colorscale;
1829 g = ent->colormod[1] * colorscale;
1830 b = ent->colormod[2] * colorscale;
1831 a = texture->currentalpha;
1832 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1839 VectorSubtract(v, modelorg, diff);
1840 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1841 VectorScale(c, f, c);
1843 if (surface->mesh.data_lightmapcolor4f)
1844 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1849 GL_LockArrays(0, surface->mesh.num_vertices);
1850 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1851 GL_LockArrays(0, 0);
1853 if ((r_ambient.value > 0 || surface->dlightframe == r_framecount) && !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
1855 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1856 GL_DepthMask(false);
1857 memset(&m, 0, sizeof(m));
1858 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1859 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1860 m.tex[0] = R_GetTexture(texture->skin.base);
1861 m.texmatrix[0] = scrollmatrix;
1862 m.pointer_color = varray_color4f;
1864 if (gl_combine.integer)
1866 m.texrgbscale[0] = 4;
1867 colorscale *= 0.25f;
1869 r = ent->colormod[0] * colorscale;
1870 g = ent->colormod[1] * colorscale;
1871 b = ent->colormod[2] * colorscale;
1872 a = texture->currentalpha;
1873 base = r_ambient.value * (1.0f / 64.0f);
1874 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1879 if (surface->dlightframe == r_framecount)
1881 // TODO: make this work with autosprite which uses identitymatrix
1882 Matrix4x4_Transform(&ent->matrix, v, worldvertex);
1883 for (l = 0;l < r_numdlights;l++)
1885 if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
1888 dlight_t *light = &r_dlight[l];
1889 f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
1890 if (f2 < light->rtlight.lightmap_cullradius2)
1892 f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
1893 VectorMA(c, f2, light->rtlight.lightmap_light, c);
1903 VectorSubtract(v, modelorg, diff);
1904 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1905 VectorScale(c, f, c);
1907 if (surface->mesh.data_lightmapcolor4f)
1908 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
1913 GL_LockArrays(0, surface->mesh.num_vertices);
1914 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
1915 GL_LockArrays(0, 0);
1920 memset(&m, 0, sizeof(m));
1921 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
1922 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
1923 m.tex[0] = R_GetTexture(texture->skin.base);
1924 m.texmatrix[0] = scrollmatrix;
1925 m.pointer_color = varray_color4f;
1927 if (gl_combine.integer)
1929 m.texrgbscale[0] = 4;
1930 colorscale *= 0.25f;
1935 m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
1936 m.tex[1] = R_GetTexture(texture->skin.glow);
1937 m.texmatrix[1] = scrollmatrix;
1939 r = ent->colormod[0] * colorscale;
1940 g = ent->colormod[1] * colorscale;
1941 b = ent->colormod[2] * colorscale;
1942 a = texture->currentalpha;
1943 base = r_ambient.value * (1.0f / 64.0f);
1944 if ((ent->flags & RENDER_LIGHT) && !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
1946 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
1951 if (surface->styles[0] != 255)
1953 if (surface->mesh.data_lightmapcolor4f)
1955 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 128.0f);
1956 VectorMA(c, scale, surface->mesh.data_lightmapcolor4f + i*4, c);
1958 else if (surface->mesh.data_lightmapoffsets)
1960 const qbyte *lm = surface->samples + surface->mesh.data_lightmapoffsets[i];
1961 float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 32768.0f);
1962 VectorMA(c, scale, lm, c);
1963 if (surface->styles[1] != 255)
1965 int size3 = ((surface->extents[0]>>4)+1)*((surface->extents[1]>>4)+1)*3;
1967 scale = d_lightstylevalue[surface->styles[1]] * (1.0f / 32768.0f);
1968 VectorMA(c, scale, lm, c);
1969 if (surface->styles[2] != 255)
1972 scale = d_lightstylevalue[surface->styles[2]] * (1.0f / 32768.0f);
1973 VectorMA(c, scale, lm, c);
1974 if (surface->styles[3] != 255)
1977 scale = d_lightstylevalue[surface->styles[3]] * (1.0f / 32768.0f);
1978 VectorMA(c, scale, lm, c);
1984 if (surface->dlightframe == r_framecount)
1986 // TODO: make this work with autosprite which uses identitymatrix
1987 Matrix4x4_Transform(&ent->matrix, v, worldvertex);
1988 for (l = 0;l < r_numdlights;l++)
1990 if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
1993 dlight_t *light = &r_dlight[l];
1994 f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
1995 if (f2 < light->rtlight.lightmap_cullradius2)
1997 f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
1998 VectorMA(c, f2, light->rtlight.lightmap_light, c);
2008 VectorSubtract(v, modelorg, diff);
2009 f = 1 - exp(fogdensity/DotProduct(diff, diff));
2010 VectorScale(c, f, c);
2012 if (surface->mesh.data_lightmapcolor4f)
2013 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
2022 if (surface->mesh.data_lightmapcolor4f)
2024 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
2026 VectorSubtract(v, modelorg, diff);
2027 f = 1 - exp(fogdensity/DotProduct(diff, diff));
2031 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
2036 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
2038 VectorSubtract(v, modelorg, diff);
2039 f = 1 - exp(fogdensity/DotProduct(diff, diff));
2049 if (surface->mesh.data_lightmapcolor4f)
2051 for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
2056 c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
2061 m.pointer_color = NULL;
2062 GL_Color(r, g, b, a);
2067 GL_LockArrays(0, surface->mesh.num_vertices);
2068 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2069 GL_LockArrays(0, 0);
2071 // note: dodetail is never set if transparent
2074 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2075 GL_DepthMask(false);
2076 memset(&m, 0, sizeof(m));
2077 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
2078 m.pointer_texcoord[0] = surface->mesh.data_texcoorddetail2f;
2079 m.tex[0] = R_GetTexture(texture->skin.detail);
2080 m.pointer_color = varray_color4f;
2081 RSurf_FoggedColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha, 1, surface->mesh.num_vertices, modelorg);
2083 GL_LockArrays(0, surface->mesh.num_vertices);
2084 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2085 GL_LockArrays(0, 0);
2089 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2090 GL_DepthMask(false);
2091 memset(&m, 0, sizeof(m));
2092 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
2093 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2094 m.tex[0] = R_GetTexture(texture->skin.glow);
2095 m.texmatrix[0] = scrollmatrix;
2096 m.pointer_color = varray_color4f;
2097 RSurf_FoggedColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha, 1, surface->mesh.num_vertices, modelorg);
2099 GL_LockArrays(0, surface->mesh.num_vertices);
2100 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2101 GL_LockArrays(0, 0);
2103 if (fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD))
2105 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2106 GL_DepthMask(false);
2107 memset(&m, 0, sizeof(m));
2108 m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
2109 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2110 m.tex[0] = R_GetTexture(texture->skin.fog);
2111 m.texmatrix[0] = scrollmatrix;
2112 m.pointer_color = varray_color4f;
2113 RSurf_FogPassColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->mesh.num_vertices, modelorg);
2115 GL_LockArrays(0, surface->mesh.num_vertices);
2116 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2117 GL_LockArrays(0, 0);
2120 if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2121 qglEnable(GL_CULL_FACE);
2126 void R_DrawSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, msurface_t **texturesurfacelist)
2128 int texturesurfaceindex;
2129 vec3_t tempcenter, center, modelorg;
2130 msurface_t *surface;
2131 qboolean dolightmap;
2138 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2139 c_faces += texturenumsurfaces;
2140 // gl_lightmaps debugging mode skips normal texturing
2141 if (gl_lightmaps.integer)
2143 GL_BlendFunc(GL_ONE, GL_ZERO);
2146 qglDisable(GL_CULL_FACE);
2147 GL_Color(1, 1, 1, 1);
2148 memset(&m, 0, sizeof(m));
2149 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2151 surface = texturesurfacelist[texturesurfaceindex];
2152 m.tex[0] = R_GetTexture(surface->lightmaptexture);
2153 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
2154 if (surface->lightmaptexture)
2156 GL_Color(1, 1, 1, 1);
2157 m.pointer_color = NULL;
2160 m.pointer_color = surface->mesh.data_lightmapcolor4f;
2161 m.pointer_vertex = surface->mesh.data_vertex3f;
2163 GL_LockArrays(0, surface->mesh.num_vertices);
2164 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2165 GL_LockArrays(0, 0);
2167 qglEnable(GL_CULL_FACE);
2170 if (texture->currentmaterialflags & MATERIALFLAG_WALL)
2172 dolightmap = (ent->flags & RENDER_LIGHT);
2174 doambient = r_ambient.value > 0;
2175 dodetail = texture->skin.detail != NULL && r_detailtextures.integer != 0;
2176 doglow = texture->skin.glow != NULL;
2178 // multitexture cases
2179 if (r_textureunits.integer >= 2 && gl_combine.integer && dobase && dolightmap)
2181 GL_BlendFunc(GL_ONE, GL_ZERO);
2184 GL_Color(1, 1, 1, 1);
2185 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
2186 memset(&m, 0, sizeof(m));
2187 m.tex[0] = R_GetTexture(texture->skin.base);
2189 m.texrgbscale[1] = 2;
2191 if (r_textureunits.integer >= 4 && !doambient && dodetail && doglow)
2193 m.tex[2] = R_GetTexture(texture->skin.detail);
2194 m.texrgbscale[2] = 2;
2196 m.tex[3] = R_GetTexture(texture->skin.glow);
2197 m.texcombinergb[3] = GL_ADD;
2199 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2201 surface = texturesurfacelist[texturesurfaceindex];
2202 m.tex[1] = R_GetTexture(surface->lightmaptexture);
2203 m.pointer_vertex = surface->mesh.data_vertex3f;
2204 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2205 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
2206 m.pointer_texcoord[2] = surface->mesh.data_texcoorddetail2f;
2207 m.pointer_texcoord[3] = surface->mesh.data_texcoordtexture2f;
2209 GL_LockArrays(0, surface->mesh.num_vertices);
2210 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2211 GL_LockArrays(0, 0);
2214 else if (r_textureunits.integer >= 3 && !doambient && dodetail)
2216 m.tex[2] = R_GetTexture(texture->skin.detail);
2217 m.texrgbscale[2] = 2;
2219 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2221 surface = texturesurfacelist[texturesurfaceindex];
2222 m.tex[1] = R_GetTexture(surface->lightmaptexture);
2223 m.pointer_vertex = surface->mesh.data_vertex3f;
2224 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2225 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
2226 m.pointer_texcoord[2] = surface->mesh.data_texcoorddetail2f;
2228 GL_LockArrays(0, surface->mesh.num_vertices);
2229 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2230 GL_LockArrays(0, 0);
2233 else if (r_textureunits.integer >= 3 && !doambient && !dodetail && doglow)
2235 m.tex[2] = R_GetTexture(texture->skin.glow);
2236 m.texcombinergb[2] = GL_ADD;
2238 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2240 surface = texturesurfacelist[texturesurfaceindex];
2241 m.tex[1] = R_GetTexture(surface->lightmaptexture);
2242 m.pointer_vertex = surface->mesh.data_vertex3f;
2243 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2244 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
2245 m.pointer_texcoord[2] = surface->mesh.data_texcoordtexture2f;
2247 GL_LockArrays(0, surface->mesh.num_vertices);
2248 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2249 GL_LockArrays(0, 0);
2254 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2256 surface = texturesurfacelist[texturesurfaceindex];
2257 m.tex[1] = R_GetTexture(surface->lightmaptexture);
2258 m.pointer_vertex = surface->mesh.data_vertex3f;
2259 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2260 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
2262 GL_LockArrays(0, surface->mesh.num_vertices);
2263 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2264 GL_LockArrays(0, 0);
2268 // anything not handled above
2271 GL_BlendFunc(GL_ONE, GL_ZERO);
2274 GL_Color(1, 1, 1, 1);
2275 if (ent->flags & RENDER_LIGHT)
2276 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
2278 GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
2279 memset(&m, 0, sizeof(m));
2280 m.tex[0] = R_GetTexture(texture->skin.base);
2281 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2283 surface = texturesurfacelist[texturesurfaceindex];
2284 m.pointer_vertex = surface->mesh.data_vertex3f;
2285 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2287 GL_LockArrays(0, surface->mesh.num_vertices);
2288 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2289 GL_LockArrays(0, 0);
2292 GL_DepthMask(false);
2295 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2296 GL_DepthMask(false);
2298 GL_Color(1, 1, 1, 1);
2299 memset(&m, 0, sizeof(m));
2300 m.tex[0] = R_GetTexture(texture->skin.base);
2301 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2303 surface = texturesurfacelist[texturesurfaceindex];
2304 m.tex[0] = R_GetTexture(surface->lightmaptexture);
2305 m.pointer_vertex = surface->mesh.data_vertex3f;
2306 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
2308 GL_LockArrays(0, surface->mesh.num_vertices);
2309 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2310 GL_LockArrays(0, 0);
2315 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2316 GL_DepthMask(false);
2318 memset(&m, 0, sizeof(m));
2319 GL_Color(r_ambient.value * (1.0f / 128.0f) * ent->colormod[0], r_ambient.value * (1.0f / 128.0f) * ent->colormod[1], r_ambient.value * (1.0f / 128.0f) * ent->colormod[2], 1);
2320 m.tex[0] = R_GetTexture(texture->skin.base);
2321 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2323 surface = texturesurfacelist[texturesurfaceindex];
2324 m.pointer_vertex = surface->mesh.data_vertex3f;
2325 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2327 GL_LockArrays(0, surface->mesh.num_vertices);
2328 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2329 GL_LockArrays(0, 0);
2334 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2335 GL_DepthMask(false);
2337 GL_Color(1, 1, 1, 1);
2338 memset(&m, 0, sizeof(m));
2339 m.tex[0] = R_GetTexture(texture->skin.detail);
2340 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2342 surface = texturesurfacelist[texturesurfaceindex];
2343 m.pointer_vertex = surface->mesh.data_vertex3f;
2344 m.pointer_texcoord[0] = surface->mesh.data_texcoorddetail2f;
2346 GL_LockArrays(0, surface->mesh.num_vertices);
2347 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2348 GL_LockArrays(0, 0);
2353 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2354 GL_DepthMask(false);
2356 GL_Color(1, 1, 1, 1);
2357 memset(&m, 0, sizeof(m));
2358 m.tex[0] = R_GetTexture(texture->skin.glow);
2359 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2361 surface = texturesurfacelist[texturesurfaceindex];
2362 m.pointer_vertex = surface->mesh.data_vertex3f;
2363 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2365 GL_LockArrays(0, surface->mesh.num_vertices);
2366 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2367 GL_LockArrays(0, 0);
2372 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2373 GL_DepthMask(false);
2375 memset(&m, 0, sizeof(m));
2376 m.pointer_color = varray_color4f;
2377 m.tex[0] = R_GetTexture(texture->skin.glow);
2378 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2380 surface = texturesurfacelist[texturesurfaceindex];
2381 m.pointer_vertex = surface->mesh.data_vertex3f;
2383 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
2385 RSurf_FogPassColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, 1, surface->mesh.num_vertices, modelorg);
2386 GL_LockArrays(0, surface->mesh.num_vertices);
2387 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2388 GL_LockArrays(0, 0);
2393 if (texture->currentmaterialflags & MATERIALFLAG_WATER)
2395 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2397 surface = texturesurfacelist[texturesurfaceindex];
2398 RSurfShader_Transparent_Callback(ent, surface - ent->model->brush.data_surfaces);
2402 if (texture->currentmaterialflags & MATERIALFLAG_SKY)
2406 skyrendernow = false;
2407 if (skyrendermasked)
2410 // LordHavoc: HalfLife maps have freaky skypolys...
2411 if (!ent->model->brush.ishlbsp)
2413 R_Mesh_Matrix(&ent->matrix);
2414 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2415 if (skyrendermasked)
2417 // depth-only (masking)
2418 GL_ColorMask(0,0,0,0);
2419 // just to make sure that braindead drivers don't draw anything
2420 // despite that colormask...
2421 GL_BlendFunc(GL_ZERO, GL_ONE);
2426 GL_BlendFunc(GL_ONE, GL_ZERO);
2430 memset(&m, 0, sizeof(m));
2431 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2433 surface = texturesurfacelist[texturesurfaceindex];
2434 m.pointer_vertex = surface->mesh.data_vertex3f;
2436 GL_LockArrays(0, surface->mesh.num_vertices);
2437 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2438 GL_LockArrays(0, 0);
2440 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2447 void R_QueueSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
2449 int texturesurfaceindex;
2450 const msurface_t *surface;
2451 vec3_t tempcenter, center;
2452 if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
2454 // drawing sky transparently would be too difficult
2455 if (!(texture->currentmaterialflags & MATERIALFLAG_SKY))
2457 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2459 surface = texturesurfacelist[texturesurfaceindex];
2460 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
2461 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
2462 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
2463 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
2464 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->brush.data_surfaces);
2469 R_DrawSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
2472 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
2474 int i, j, f, flagsmask;
2475 msurface_t *surface, **surfacechain;
2476 texture_t *t, *texture;
2477 model_t *model = ent->model;
2479 const int maxsurfacelist = 1024;
2480 int numsurfacelist = 0;
2481 const msurface_t *surfacelist[1024];
2484 R_Mesh_Matrix(&ent->matrix);
2485 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2488 if (ent != r_refdef.worldentity)
2490 // because bmodels can be reused, we have to clear dlightframe every time
2491 surface = model->brush.data_surfaces + model->firstmodelsurface;
2492 for (i = 0;i < model->nummodelsurfaces;i++, surface++)
2493 surface->dlightframe = -1;
2497 // update light styles
2501 if (r_dynamic.integer && !r_rtdlight)
2504 for (i = 0;i < model->brushq1.light_styles;i++)
2506 if (model->brushq1.light_stylevalue[i] != d_lightstylevalue[model->brushq1.light_style[i]])
2508 model->brushq1.light_stylevalue[i] = d_lightstylevalue[model->brushq1.light_style[i]];
2509 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
2510 for (;(surface = *surfacechain);surfacechain++)
2511 surface->cached_dlight = true;
2516 R_UpdateAllTextureInfo(ent);
2517 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
2522 for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
2524 if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
2526 surface = model->brush.data_surfaces + j;
2527 if (t != surface->texture)
2531 R_QueueSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2534 t = surface->texture;
2535 f = t->currentmaterialflags & flagsmask;
2536 texture = t->currentframe;
2540 // if lightmap parameters changed, rebuild lightmap texture
2541 if (surface->cached_dlight && surface->samples)
2542 R_BuildLightMap(ent, surface);
2543 // add face to draw list
2544 surfacelist[numsurfacelist++] = surface;
2545 if (numsurfacelist >= maxsurfacelist)
2547 R_QueueSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2554 R_QueueSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2557 static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
2562 const mportal_t *portal = calldata1;
2563 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2564 GL_DepthMask(false);
2566 R_Mesh_Matrix(&r_identitymatrix);
2568 memset(&m, 0, sizeof(m));
2569 m.pointer_vertex = varray_vertex3f;
2573 GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f),
2574 ((i & 0x0038) >> 3) * (1.0f / 7.0f),
2575 ((i & 0x01C0) >> 6) * (1.0f / 7.0f),
2577 if (PlaneDiff(r_vieworigin, (&portal->plane)) < 0)
2579 for (i = portal->numpoints - 1, v = varray_vertex3f;i >= 0;i--, v += 3)
2580 VectorCopy(portal->points[i].position, v);
2583 for (i = 0, v = varray_vertex3f;i < portal->numpoints;i++, v += 3)
2584 VectorCopy(portal->points[i].position, v);
2585 GL_LockArrays(0, portal->numpoints);
2586 R_Mesh_Draw(portal->numpoints, portal->numpoints - 2, polygonelements);
2587 GL_LockArrays(0, 0);
2590 // LordHavoc: this is just a nice debugging tool, very slow
2591 static void R_DrawPortals(void)
2596 model_t *model = r_refdef.worldmodel;
2599 for (portalnum = 0, portal = model->brush.data_portals;portalnum < model->brush.num_portals;portalnum++, portal++)
2601 if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
2602 if (!R_CullBox(portal->mins, portal->maxs))
2604 VectorClear(center);
2605 for (i = 0;i < portal->numpoints;i++)
2606 VectorAdd(center, portal->points[i].position, center);
2607 f = ixtable[portal->numpoints];
2608 VectorScale(center, f, center);
2609 R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, portal, portalnum);
2614 static void R_DrawCollisionBrush(colbrushf_t *brush)
2618 memset(&m, 0, sizeof(m));
2619 m.pointer_vertex = brush->points->v;
2621 i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2622 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2623 GL_LockArrays(0, brush->numpoints);
2624 R_Mesh_Draw(brush->numpoints, brush->numtriangles, brush->elements);
2625 GL_LockArrays(0, 0);
2628 static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface)
2632 if (!surface->mesh.num_collisiontriangles)
2634 memset(&m, 0, sizeof(m));
2635 m.pointer_vertex = surface->mesh.data_collisionvertex3f;
2637 i = (int)(((size_t)surface) / sizeof(msurface_t));
2638 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2639 GL_LockArrays(0, surface->mesh.num_collisionvertices);
2640 R_Mesh_Draw(surface->mesh.num_collisionvertices, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i);
2641 GL_LockArrays(0, 0);
2644 void R_WorldVisibility(void)
2649 model_t *model = r_refdef.worldmodel;
2654 // if possible find the leaf the view origin is in
2655 viewleaf = model->brushq1.PointInLeaf ? model->brushq1.PointInLeaf(model, r_vieworigin) : NULL;
2656 // if possible fetch the visible cluster bits
2657 if (model->brush.FatPVS)
2658 model->brush.FatPVS(model, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
2660 // clear the visible surface and leaf flags arrays
2661 memset(r_worldsurfacevisible, 0, model->brush.num_surfaces);
2662 memset(r_worldleafvisible, 0, model->brush.num_leafs);
2664 // if the user prefers surfaceworldnode (testing?) or the viewleaf could
2665 // not be found, or the viewleaf is not part of the visible world
2666 // (floating around in the void), use the pvs method
2667 if (r_surfaceworldnode.integer || !viewleaf || viewleaf->clusterindex < 0)
2670 // similar to quake's RecursiveWorldNode but without cache misses
2671 for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
2673 // if leaf is in current pvs and on the screen, mark its surfaces
2674 if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
2677 r_worldleafvisible[j] = true;
2678 if (leaf->numleafsurfaces)
2679 for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
2680 r_worldsurfacevisible[*mark] = true;
2688 mleaf_t *leafstack[8192];
2690 // follows portals leading outward from viewleaf, does not venture
2691 // offscreen or into leafs that are not visible, faster than Quake's
2692 // RecursiveWorldNode and vastly better in unvised maps, often culls a
2693 // lot of surface that pvs alone would miss
2694 leafstack[0] = viewleaf;
2696 while (leafstackpos)
2699 leaf = leafstack[--leafstackpos];
2700 r_worldleafvisible[leaf - model->brush.data_leafs] = true;
2701 // mark any surfaces bounding this leaf
2702 if (leaf->numleafsurfaces)
2703 for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
2704 r_worldsurfacevisible[*mark] = true;
2705 // follow portals into other leafs
2707 // if viewer is behind portal (portal faces outward into the scene)
2708 // and the portal polygon's bounding box is on the screen
2709 // and the leaf has not been visited yet
2710 // and the leaf is visible in the pvs
2711 // (the first two checks won't cause as many cache misses as the leaf checks)
2712 for (p = leaf->portals;p;p = p->next)
2713 if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && !R_CullBox(p->mins, p->maxs) && !r_worldleafvisible[p->past - model->brush.data_leafs] && CHECKPVSBIT(r_pvsbits, p->past->clusterindex))
2714 leafstack[leafstackpos++] = p->past;
2718 if (r_drawportals.integer)
2722 void R_Q1BSP_DrawSky(entity_render_t *ent)
2724 if (ent->model == NULL)
2726 if (r_drawcollisionbrushes.integer < 2)
2727 R_DrawSurfaces(ent, true);
2730 void R_Q1BSP_Draw(entity_render_t *ent)
2732 if (ent->model == NULL)
2735 if (r_drawcollisionbrushes.integer < 2)
2736 R_DrawSurfaces(ent, false);
2737 if (r_drawcollisionbrushes.integer >= 1 && ent->model->brush.num_brushes)
2740 model_t *model = ent->model;
2741 msurface_t *surface;
2743 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2744 GL_DepthMask(false);
2746 qglPolygonOffset(r_drawcollisionbrushes_polygonfactor.value, r_drawcollisionbrushes_polygonoffset.value);
2747 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
2748 if (brush->colbrushf && brush->colbrushf->numtriangles)
2749 R_DrawCollisionBrush(brush->colbrushf);
2750 for (i = 0, surface = model->brush.data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
2751 if (surface->mesh.num_collisiontriangles)
2752 R_DrawCollisionSurface(ent, surface);
2753 qglPolygonOffset(0, 0);
2757 void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer)
2759 model_t *model = ent->model;
2760 vec3_t lightmins, lightmaxs;
2761 int t, leafindex, leafsurfaceindex, surfaceindex, triangleindex, outnumclusters = 0, outnumsurfaces = 0;
2764 msurface_t *surface;
2767 lightmins[0] = relativelightorigin[0] - lightradius;
2768 lightmins[1] = relativelightorigin[1] - lightradius;
2769 lightmins[2] = relativelightorigin[2] - lightradius;
2770 lightmaxs[0] = relativelightorigin[0] + lightradius;
2771 lightmaxs[1] = relativelightorigin[1] + lightradius;
2772 lightmaxs[2] = relativelightorigin[2] + lightradius;
2773 *outnumclusterspointer = 0;
2774 *outnumsurfacespointer = 0;
2775 memset(outclusterpvs, 0, model->brush.num_pvsclusterbytes);
2776 memset(outsurfacepvs, 0, (model->nummodelsurfaces + 7) >> 3);
2779 VectorCopy(lightmins, outmins);
2780 VectorCopy(lightmaxs, outmaxs);
2783 VectorCopy(relativelightorigin, outmins);
2784 VectorCopy(relativelightorigin, outmaxs);
2785 if (model->brush.GetPVS)
2786 pvs = model->brush.GetPVS(model, relativelightorigin);
2789 R_UpdateAllTextureInfo(ent);
2790 // FIXME: use BSP recursion as lights are often small
2791 for (leafindex = 0, leaf = model->brush.data_leafs;leafindex < model->brush.num_leafs;leafindex++, leaf++)
2793 if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
2795 outmins[0] = min(outmins[0], leaf->mins[0]);
2796 outmins[1] = min(outmins[1], leaf->mins[1]);
2797 outmins[2] = min(outmins[2], leaf->mins[2]);
2798 outmaxs[0] = max(outmaxs[0], leaf->maxs[0]);
2799 outmaxs[1] = max(outmaxs[1], leaf->maxs[1]);
2800 outmaxs[2] = max(outmaxs[2], leaf->maxs[2]);
2803 if (!CHECKPVSBIT(outclusterpvs, leaf->clusterindex))
2805 SETPVSBIT(outclusterpvs, leaf->clusterindex);
2806 outclusterlist[outnumclusters++] = leaf->clusterindex;
2811 for (leafsurfaceindex = 0;leafsurfaceindex < leaf->numleafsurfaces;leafsurfaceindex++)
2813 surfaceindex = leaf->firstleafsurface[leafsurfaceindex];
2814 if (!CHECKPVSBIT(outsurfacepvs, surfaceindex))
2816 surface = model->brush.data_surfaces + surfaceindex;
2817 if (BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs))
2818 if ((surface->texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL)
2820 for (triangleindex = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;triangleindex < surface->mesh.num_triangles;triangleindex++, t++, e += 3)
2822 v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
2823 v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
2824 v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
2825 if (lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
2827 SETPVSBIT(outsurfacepvs, surfaceindex);
2828 outsurfacelist[outnumsurfaces++] = surfaceindex;
2839 // limit combined leaf box to light boundaries
2840 outmins[0] = max(outmins[0], lightmins[0]);
2841 outmins[1] = max(outmins[1], lightmins[1]);
2842 outmins[2] = max(outmins[2], lightmins[2]);
2843 outmaxs[0] = min(outmaxs[0], lightmaxs[0]);
2844 outmaxs[1] = min(outmaxs[1], lightmaxs[1]);
2845 outmaxs[2] = min(outmaxs[2], lightmaxs[2]);
2847 *outnumclusterspointer = outnumclusters;
2848 *outnumsurfacespointer = outnumsurfaces;
2851 void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs)
2853 model_t *model = ent->model;
2854 msurface_t *surface;
2855 int surfacelistindex;
2856 if (r_drawcollisionbrushes.integer < 2)
2858 R_Mesh_Matrix(&ent->matrix);
2859 R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles);
2860 if (!r_shadow_compilingrtlight)
2861 R_UpdateAllTextureInfo(ent);
2862 for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
2864 surface = model->brush.data_surfaces + surfacelist[surfacelistindex];
2865 if ((surface->texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL)
2867 if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2869 R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->mesh.num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs);
2871 R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
2875 void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist)
2877 model_t *model = ent->model;
2878 msurface_t *surface;
2880 int surfacelistindex;
2881 if (r_drawcollisionbrushes.integer < 2)
2883 R_Mesh_Matrix(&ent->matrix);
2884 if (!r_shadow_compilingrtlight)
2885 R_UpdateAllTextureInfo(ent);
2886 for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
2888 surface = model->brush.data_surfaces + surfacelist[surfacelistindex];
2889 if (surface->texture->basematerialflags & MATERIALFLAG_NODRAW || !surface->mesh.num_triangles)
2891 if (r_shadow_compilingrtlight)
2893 // if compiling an rtlight, capture the mesh
2894 t = surface->texture;
2895 if ((t->basematerialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL)
2896 Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texture->skin.base, surface->texture->skin.gloss, surface->texture->skin.nmap, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, surface->mesh.num_triangles, surface->mesh.data_element3i);
2898 else if (ent != r_refdef.worldentity || r_worldsurfacevisible[surfacelist[surfacelistindex]])
2900 t = surface->texture->currentframe;
2901 // FIXME: transparent surfaces need to be lit later
2902 if ((t->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL)
2904 if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2905 qglDisable(GL_CULL_FACE);
2906 R_Shadow_RenderLighting(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, t->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale);
2907 if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2908 qglEnable(GL_CULL_FACE);
2916 void R_Q3BSP_DrawFaceList(entity_render_t *ent, texture_t *t, int texturenumsurfaces, msurface_t **texturesurfacelist)
2918 int i, texturesurfaceindex;
2919 vec3_t tempcenter, center, modelorg;
2920 msurface_t *surface;
2921 qboolean dolightmap;
2928 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2929 c_faces += texturenumsurfaces;
2930 // gl_lightmaps debugging mode skips normal texturing
2931 if (gl_lightmaps.integer)
2933 GL_BlendFunc(GL_ONE, GL_ZERO);
2936 qglDisable(GL_CULL_FACE);
2937 GL_Color(1, 1, 1, 1);
2938 memset(&m, 0, sizeof(m));
2939 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2941 surface = texturesurfacelist[texturesurfaceindex];
2942 m.tex[0] = R_GetTexture(surface->lightmaptexture);
2943 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
2944 if (surface->lightmaptexture)
2946 GL_Color(1, 1, 1, 1);
2947 m.pointer_color = NULL;
2950 m.pointer_color = surface->mesh.data_lightmapcolor4f;
2951 m.pointer_vertex = surface->mesh.data_vertex3f;
2953 GL_LockArrays(0, surface->mesh.num_vertices);
2954 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
2955 GL_LockArrays(0, 0);
2957 qglEnable(GL_CULL_FACE);
2960 // transparent surfaces get sorted for later drawing
2961 if ((t->surfaceparms & Q3SURFACEPARM_TRANS) || ent->alpha < 1 || (ent->effects & EF_ADDITIVE))
2963 // drawing sky transparently would be too difficult
2964 if (t->surfaceparms & Q3SURFACEPARM_SKY)
2966 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2968 surface = texturesurfacelist[texturesurfaceindex];
2969 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
2970 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
2971 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
2972 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
2973 R_MeshQueue_AddTransparent(center, RSurfShader_Transparent_Callback, ent, surface - ent->model->brush.data_surfaces);
2977 // sky surfaces draw sky if needed and render themselves as a depth mask
2978 if (t->surfaceparms & Q3SURFACEPARM_SKY)
2982 skyrendernow = false;
2983 if (skyrendermasked)
2986 if (!r_q3bsp_renderskydepth.integer)
2989 R_Mesh_Matrix(&ent->matrix);
2991 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2992 if (skyrendermasked)
2994 // depth-only (masking)
2995 GL_ColorMask(0,0,0,0);
2996 // just to make sure that braindead drivers don't draw anything
2997 // despite that colormask...
2998 GL_BlendFunc(GL_ZERO, GL_ONE);
3003 GL_BlendFunc(GL_ONE, GL_ZERO);
3008 memset(&m, 0, sizeof(m));
3009 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3011 surface = texturesurfacelist[texturesurfaceindex];
3012 m.pointer_vertex = surface->mesh.data_vertex3f;
3014 GL_LockArrays(0, surface->mesh.num_vertices);
3015 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3016 GL_LockArrays(0, 0);
3018 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
3021 // anything else is a typical wall, lightmap * texture + glow
3022 dolightmap = (ent->flags & RENDER_LIGHT);
3024 doambient = r_ambient.value > 0;
3025 dodetail = t->skin.detail != NULL && r_detailtextures.integer;
3026 doglow = t->skin.glow != NULL;
3028 if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
3029 qglDisable(GL_CULL_FACE);
3030 if (!dolightmap && dobase)
3036 GL_BlendFunc(GL_ONE, GL_ZERO);
3037 GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
3038 if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
3039 qglDisable(GL_CULL_FACE);
3040 memset(&m, 0, sizeof(m));
3041 m.tex[0] = R_GetTexture(t->skin.base);
3042 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3044 surface = texturesurfacelist[texturesurfaceindex];
3045 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3046 m.pointer_vertex = surface->mesh.data_vertex3f;
3048 GL_LockArrays(0, surface->mesh.num_vertices);
3049 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3050 GL_LockArrays(0, 0);
3053 if (r_lightmapintensity <= 0 && dolightmap && dobase)
3059 GL_BlendFunc(GL_ONE, GL_ZERO);
3060 GL_Color(0, 0, 0, 1);
3061 memset(&m, 0, sizeof(m));
3062 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3064 surface = texturesurfacelist[texturesurfaceindex];
3065 m.pointer_vertex = surface->mesh.data_vertex3f;
3067 GL_LockArrays(0, surface->mesh.num_vertices);
3068 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3069 GL_LockArrays(0, 0);
3072 if (r_textureunits.integer >= 2 && gl_combine.integer && dolightmap && dobase)
3074 // dualtexture combine
3079 GL_BlendFunc(GL_ONE, GL_ZERO);
3080 memset(&m, 0, sizeof(m));
3081 m.tex[0] = R_GetTexture(t->skin.base);
3082 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
3083 m.pointer_color = NULL;
3084 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3086 surface = texturesurfacelist[texturesurfaceindex];
3087 if (!surface->lightmaptexture)
3089 m.tex[1] = R_GetTexture(surface->lightmaptexture);
3090 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3091 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
3092 m.texrgbscale[1] = 2;
3093 m.pointer_vertex = surface->mesh.data_vertex3f;
3095 GL_LockArrays(0, surface->mesh.num_vertices);
3096 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3097 GL_LockArrays(0, 0);
3099 if (r_lightmapintensity == 1 && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
3101 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3103 surface = texturesurfacelist[texturesurfaceindex];
3104 if (surface->lightmaptexture)
3106 m.tex[1] = R_GetTexture(surface->lightmaptexture);
3107 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3108 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
3109 m.texrgbscale[1] = 2;
3110 m.pointer_color = surface->mesh.data_lightmapcolor4f;
3111 m.pointer_vertex = surface->mesh.data_vertex3f;
3113 GL_LockArrays(0, surface->mesh.num_vertices);
3114 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3115 GL_LockArrays(0, 0);
3120 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3122 surface = texturesurfacelist[texturesurfaceindex];
3123 if (surface->lightmaptexture)
3125 m.tex[1] = R_GetTexture(surface->lightmaptexture);
3126 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3127 m.pointer_texcoord[1] = surface->mesh.data_texcoordlightmap2f;
3128 m.texrgbscale[1] = 2;
3129 m.pointer_color = varray_color4f;
3130 for (i = 0;i < surface->mesh.num_vertices;i++)
3132 varray_color4f[i*4+0] = surface->mesh.data_lightmapcolor4f[i*4+0] * ent->colormod[0] * r_lightmapintensity;
3133 varray_color4f[i*4+1] = surface->mesh.data_lightmapcolor4f[i*4+1] * ent->colormod[1] * r_lightmapintensity;
3134 varray_color4f[i*4+2] = surface->mesh.data_lightmapcolor4f[i*4+2] * ent->colormod[2] * r_lightmapintensity;
3135 varray_color4f[i*4+3] = surface->mesh.data_lightmapcolor4f[i*4+3];
3137 m.pointer_vertex = surface->mesh.data_vertex3f;
3139 GL_LockArrays(0, surface->mesh.num_vertices);
3140 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3141 GL_LockArrays(0, 0);
3150 GL_BlendFunc(GL_ONE, GL_ZERO);
3151 memset(&m, 0, sizeof(m));
3152 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3154 surface = texturesurfacelist[texturesurfaceindex];
3155 m.tex[0] = R_GetTexture(surface->lightmaptexture);
3156 m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
3157 if (surface->lightmaptexture)
3158 m.pointer_color = NULL;
3160 m.pointer_color = surface->mesh.data_lightmapcolor4f;
3161 m.pointer_vertex = surface->mesh.data_vertex3f;
3163 GL_LockArrays(0, surface->mesh.num_vertices);
3164 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3165 GL_LockArrays(0, 0);
3170 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3171 GL_DepthMask(false);
3173 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
3174 memset(&m, 0, sizeof(m));
3175 m.tex[0] = R_GetTexture(t->skin.base);
3176 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3178 surface = texturesurfacelist[texturesurfaceindex];
3179 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3180 m.pointer_vertex = surface->mesh.data_vertex3f;
3182 GL_LockArrays(0, surface->mesh.num_vertices);
3183 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3184 GL_LockArrays(0, 0);
3189 GL_BlendFunc(GL_ONE, GL_ONE);
3190 GL_DepthMask(false);
3192 GL_Color(r_ambient.value * (1.0f / 128.0f) * ent->colormod[0], r_ambient.value * (1.0f / 128.0f) * ent->colormod[1], r_ambient.value * (1.0f / 128.0f) * ent->colormod[2], 1);
3193 memset(&m, 0, sizeof(m));
3194 m.tex[0] = R_GetTexture(t->skin.base);
3195 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3197 surface = texturesurfacelist[texturesurfaceindex];
3198 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3199 m.pointer_vertex = surface->mesh.data_vertex3f;
3201 GL_LockArrays(0, surface->mesh.num_vertices);
3202 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3203 GL_LockArrays(0, 0);
3208 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3209 GL_DepthMask(false);
3211 GL_Color(1, 1, 1, 1);
3212 memset(&m, 0, sizeof(m));
3213 m.tex[0] = R_GetTexture(t->skin.glow);
3214 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3216 surface = texturesurfacelist[texturesurfaceindex];
3217 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3218 m.pointer_vertex = surface->mesh.data_vertex3f;
3220 GL_LockArrays(0, surface->mesh.num_vertices);
3221 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3222 GL_LockArrays(0, 0);
3228 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
3229 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3230 GL_DepthMask(false);
3232 GL_Color(1, 1, 1, 1);
3233 memset(&m, 0, sizeof(m));
3234 m.tex[0] = R_GetTexture(t->skin.fog);
3235 m.pointer_color = varray_color4f;
3236 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3238 surface = texturesurfacelist[texturesurfaceindex];
3240 m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
3241 m.pointer_vertex = surface->mesh.data_vertex3f;
3243 RSurf_FogPassColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, 1, surface->mesh.num_vertices, modelorg);
3244 GL_LockArrays(0, surface->mesh.num_vertices);
3245 R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
3246 GL_LockArrays(0, 0);
3249 if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
3250 qglEnable(GL_CULL_FACE);
3253 void R_Q3BSP_DrawFaces(entity_render_t *ent, int skyfaces)
3255 int i, j, f, flagsmask, flags;
3256 msurface_t *surface;
3257 model_t *model = ent->model;
3259 const int maxfaces = 1024;
3260 int numsurfaces = 0;
3261 msurface_t *surfacelist[1024];
3262 R_Mesh_Matrix(&ent->matrix);
3263 flagsmask = Q3SURFACEFLAG_NODRAW | Q3SURFACEFLAG_SKY;
3265 flags = Q3SURFACEFLAG_SKY;
3271 for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
3273 if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
3275 surface = model->brush.data_surfaces + j;
3276 if (t != surface->texture)
3280 R_Q3BSP_DrawFaceList(ent, t, numsurfaces, surfacelist);
3283 t = surface->texture;
3284 f = t->surfaceflags & flagsmask;
3288 if (!surface->mesh.num_triangles)
3290 if (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
3292 // drawing sky transparently would be too difficult
3293 if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
3295 vec3_t tempcenter, center;
3296 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3297 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3298 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3299 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
3300 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->brush.data_surfaces);
3304 surfacelist[numsurfaces++] = surface;
3305 if (numsurfaces >= maxfaces)
3307 R_Q3BSP_DrawFaceList(ent, t, numsurfaces, surfacelist);
3314 R_Q3BSP_DrawFaceList(ent, t, numsurfaces, surfacelist);
3317 void R_Q3BSP_DrawSky(entity_render_t *ent)
3319 if (r_drawcollisionbrushes.integer < 2)
3320 R_Q3BSP_DrawFaces(ent, true);
3323 void R_Q3BSP_Draw(entity_render_t *ent)
3325 if (r_drawcollisionbrushes.integer < 2)
3326 R_Q3BSP_DrawFaces(ent, false);
3327 if (r_drawcollisionbrushes.integer >= 1)
3330 model_t *model = ent->model;
3331 msurface_t *surface;
3333 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3334 GL_DepthMask(false);
3336 qglPolygonOffset(r_drawcollisionbrushes_polygonfactor.value, r_drawcollisionbrushes_polygonoffset.value);
3337 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3338 if (brush->colbrushf && brush->colbrushf->numtriangles)
3339 R_DrawCollisionBrush(brush->colbrushf);
3340 for (i = 0, surface = model->brush.data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3341 if (surface->mesh.num_collisiontriangles)
3342 R_Q3BSP_DrawCollisionSurface(ent, surface);
3343 qglPolygonOffset(0, 0);
3349 static void gl_surf_start(void)
3353 static void gl_surf_shutdown(void)
3357 static void gl_surf_newmap(void)
3362 void GL_Surf_Init(void)
3366 dlightdivtable[0] = 4194304;
3367 for (i = 1;i < 32768;i++)
3368 dlightdivtable[i] = 4194304 / (i << 7);
3371 Cvar_RegisterVariable(&r_ambient);
3372 Cvar_RegisterVariable(&r_drawportals);
3373 Cvar_RegisterVariable(&r_testvis);
3374 Cvar_RegisterVariable(&r_floatbuildlightmap);
3375 Cvar_RegisterVariable(&r_detailtextures);
3376 Cvar_RegisterVariable(&r_surfaceworldnode);
3377 Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonfactor);
3378 Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonoffset);
3379 Cvar_RegisterVariable(&r_q3bsp_renderskydepth);
3380 Cvar_RegisterVariable(&gl_lightmaps);
3382 //R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);