#include "quakedef.h"
-extern int skytexturenum;
-
int lightmap_textures;
signed blocklights[18*18*3]; // LordHavoc: *3 for colored lighting
R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown);
}
-extern qboolean lighthalf;
/*
===============
R_BuildLightMap
{
int smax, tmax;
// upload the new lightmap texture fragment
- glBindTexture(GL_TEXTURE_2D, lightmap_textures + lnum);
+ if(r_upload.value)
+ glBindTexture(GL_TEXTURE_2D, lightmap_textures + lnum);
if (nosubimage || nosubimagefragments)
{
if (lightmapupdate[lnum][0] > s->light_t)
if (lightmaprgba)
{
R_BuildLightMap (s, templight, smax * 4);
- glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
+ if(r_upload.value)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
}
else
{
R_BuildLightMap (s, templight, smax * 3);
- glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
+ if(r_upload.value)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, s->light_s, s->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
}
}
}
{
if (lightmapupdate[i][0] < lightmapupdate[i][1])
{
- glBindTexture(GL_TEXTURE_2D, lightmap_textures + i);
- if (nosubimage)
- {
- if (lightmaprgba)
- glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]);
- }
- else
+ if(r_upload.value)
{
- if (lightmaprgba)
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 4 * lightmapupdate[i][0]));
+ glBindTexture(GL_TEXTURE_2D, lightmap_textures + i);
+ if (nosubimage)
+ {
+ if (lightmaprgba)
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]);
+ }
else
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 3 * lightmapupdate[i][0]));
+ {
+ if (lightmaprgba)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 4 * lightmapupdate[i][0]));
+ else
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 3 * lightmapupdate[i][0]));
+ }
}
}
lightmapupdate[i][0] = BLOCK_HEIGHT;
}
}
-void RSurf_CheckLightmap(msurface_t *s)
+void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
{
+ int i, lit = false, polys = 0, verts = 0;
+ float *v, *wv;
+ glpoly_t *p;
+ wallpoly_t *wp;
+ wallvert_t *out;
+ // check for lightmap modification
if (r_dynamic.value)
{
if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf
|| (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))
R_UpdateLightmap(s, s->lightmaptexturenum);
}
-}
-
-void RSurf_Transform(glpoly_t *p, int transform)
-{
- int i;
- float *v, *wv = wvert;
- for (;p;p = p->next)
+ wv = wvert;
+ for (p = s->polys;p;p = p->next)
{
for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
{
wv[3] = wv[4] = wv[5] = 0.0f;
wv += 6;
}
+ verts += p->numverts;
+ polys++;
}
-}
-
-void RSurf_EmitWallpolys(int lightmap, glpoly_t *p, texture_t *t, int lit)
-{
- int i;
- float *v, *wv = wvert;
- wallpoly_t *wp = &wallpoly[currentwallpoly];
- wallvert_t *out = &wallvert[currentwallvert];
- for (;p;p = p->next)
+ if ((currentwallpoly + polys > MAX_WALLPOLYS) || (currentwallvert+verts > MAX_WALLVERTS))
+ return;
+ if (s->dlightframe == r_dlightframecount && r_dynamic.value)
+ lit = RSurf_Light(s->dlightbits, s->polys);
+ wv = wvert;
+ wp = &wallpoly[currentwallpoly];
+ out = &wallvert[currentwallvert];
+ currentwallpoly += polys;
+ for (p = s->polys;p;p = p->next)
{
- if (currentwallpoly >= MAX_WALLPOLYS)
- break;
- if (currentwallvert+p->numverts > MAX_WALLVERTS)
- break;
v = p->verts[0];
wp->texnum = (unsigned short) t->gl_texturenum;
- wp->lighttexnum = (unsigned short) lightmap;
+ wp->lighttexnum = (unsigned short) (lightmap_textures + s->lightmaptexturenum);
wp->glowtexnum = (unsigned short) t->gl_glowtexturenum;
wp->firstvert = currentwallvert;
wp->numverts = p->numverts;
wp->lit = lit;
wp++;
- currentwallpoly++;
currentwallvert += p->numverts;
for (i = 0;i < p->numverts;i++, v += VERTEXSIZE, wv += 6, out++)
{
}
}
-void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
-{
- int lit = false;
- // check for lightmap modification
- RSurf_CheckLightmap(s);
- RSurf_Transform(s->polys, transform);
- if (s->dlightframe == r_dlightframecount && r_dynamic.value)
- lit = RSurf_Light(s->dlightbits, s->polys);
- RSurf_EmitWallpolys(lightmap_textures + s->lightmaptexturenum, s->polys, t, lit);
-}
-
// LordHavoc: transparent brush models
extern int r_dlightframecount;
extern float modelalpha;
-void RSurf_EmitWallVertex(glpoly_t *p, texture_t *t, int modulate, int alpha)
-{
- int i;
- float *v, *wv = wvert;
- if (modulate)
- {
- for (;p;p = p->next)
- {
- v = p->verts[0];
- transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
- for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
- transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->colormod[0], wv[4] * currententity->colormod[1], wv[5] * currententity->colormod[2], alpha);
- transpolyend();
- }
- }
- else
- {
- for (;p;p = p->next)
- {
- v = p->verts[0];
- transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
- for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
- transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3], wv[4], wv[5], alpha);
- transpolyend();
- }
- }
-}
-
-void RSurf_WallVertexTransform(msurface_t *s, texture_t *t, int transform)
+void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmodel)
{
- int i;
- glpoly_t *p;
- float *wv, *v;
- int size3;
- float scale;
- byte *lm;
+ int i, alpha, size3;
+ float *v, *wv, scale;
+ glpoly_t *p;
+ byte *lm;
+ alpha = (int) (modelalpha * 255.0f);
size3 = ((s->extents[0]>>4)+1)*((s->extents[1]>>4)+1)*3; // *3 for colored lighting
wv = wvert;
for (p = s->polys;p;p = p->next)
wv += 6;
}
}
-}
-
-void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmodel)
-{
- RSurf_WallVertexTransform(s, t, transform);
if (s->dlightframe == r_dlightframecount && r_dynamic.value)
RSurf_Light(s->dlightbits, s->polys);
- RSurf_EmitWallVertex(s->polys, t, isbmodel && (currententity->colormod[0] != 1 || currententity->colormod[1] != 1 || currententity->colormod[2] != 1), (int) (modelalpha * 255.0f));
+ wv = wvert;
+ if (isbmodel && (currententity->colormod[0] != 1 || currententity->colormod[1] != 1 || currententity->colormod[2] != 1))
+ {
+ for (p = s->polys;p;p = p->next)
+ {
+ v = p->verts[0];
+ transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
+ transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->colormod[0], wv[4] * currententity->colormod[1], wv[5] * currententity->colormod[2], alpha);
+ transpolyend();
+ }
+ }
+ else
+ {
+ for (p = s->polys;p;p = p->next)
+ {
+ v = p->verts[0];
+ transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
+ transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3], wv[4], wv[5], alpha);
+ transpolyend();
+ }
+ }
}
/*
void R_StoreEfrags (efrag_t **ppefrag);
+struct nodestack_s
+{
+ int side;
+ mnode_t *node;
+} nodestack[8192];
+
/*
================
R_WorldNode
*/
void R_WorldNode ()
{
- int c, side, s = 0;
- double dot;
- struct
- {
- double dot;
- mnode_t *node;
- } nodestack[8192];
+ int side, texsort, vertex;
+ struct nodestack_s *nstack;
mnode_t *node;
+ mleaf_t *pleaf;
+ msurface_t *surf, *endsurf, **mark, **endmark;
+ nstack = nodestack;
+ texsort = gl_texsort.value;
+ vertex = gl_vertex.value;
if (!(node = cl.worldmodel->nodes))
return;
{
if (node->contents != CONTENTS_SOLID)
{
- mleaf_t *pleaf;
pleaf = (mleaf_t *)node;
c_leafs++;
- if ((c = pleaf->nummarksurfaces))
+ if (pleaf->nummarksurfaces)
{
- msurface_t **mark;
mark = pleaf->firstmarksurface;
+ endmark = mark + pleaf->nummarksurfaces;
do
{
(*mark)->visframe = r_framecount;
mark++;
- } while (--c);
+ }
+ while (mark < endmark);
}
// deal with model fragments in this leaf
R_StoreEfrags (&pleaf->efrags);
}
- if (!s)
+ if (nstack <= nodestack)
break;
- node = nodestack[--s].node;
- dot = nodestack[s].dot;
+ nstack--;
+ node = nstack->node;
+ side = nstack->side;
goto loc0;
}
c_nodes++;
- // node is just a decision point, so go down the apropriate sides
+ // node is just a decision point, so go down the apropriate sides
- // find which side of the node we are on
- dot = (node->plane->type < 3 ? modelorg[node->plane->type] : DotProduct (modelorg, node->plane->normal)) - node->plane->dist;
+ // find which side of the node we are on
+ side = PlaneDist(modelorg, node->plane) < node->plane->dist;
- // recurse down the children, front side first
- side = dot < 0;
+ // recurse down the children, front side first
if (node->children[side]->visframe == r_visframecount && R_NotCulledBox(node->children[side]->minmaxs, node->children[side]->minmaxs+3))
{
- nodestack[s].node = node;
- nodestack[s++].dot = dot;
+ nstack->node = node;
+ nstack->side = !side; // go down back side when we come back up
+ nstack++;
node = node->children[side];
continue;
}
+ side = !side;
loc0:
- // backside
- side = dot >= 0;
// draw stuff
- if ((c = node->numsurfaces))
+ if (node->numsurfaces)
{
- msurface_t *surf;
surf = cl.worldmodel->surfaces + node->firstsurface;
+ endsurf = surf + node->numsurfaces;
- if (side)
+ if (texsort)
{
- for (;c;c--, surf++)
+ if (side)
{
- if (surf->visframe == r_framecount && !(surf->flags & SURF_PLANEBACK))
+ do
{
- if (gl_texsort.value)
+ if (surf->visframe == r_framecount && !(surf->flags & SURF_PLANEBACK))
{
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
- else
- R_DrawSurf(surf, false, gl_vertex.value);
+ surf++;
}
+ while (surf < endsurf);
}
- }
- else
- {
- for (;c;c--, surf++)
+ else
{
- if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
+ do
{
- if (gl_texsort.value)
+ if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
{
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
- else
- R_DrawSurf(surf, false, gl_vertex.value);
+ surf++;
+ }
+ while (surf < endsurf);
+ }
+ }
+ else
+ {
+ if (side)
+ {
+ do
+ {
+ if (surf->visframe == r_framecount && !(surf->flags & SURF_PLANEBACK))
+ R_DrawSurf(surf, false, vertex);
+ surf++;
+ }
+ while (surf < endsurf);
+ }
+ else
+ {
+ do
+ {
+ if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
+ R_DrawSurf(surf, false, vertex);
+ surf++;
}
+ while (surf < endsurf);
}
}
}
continue;
}
- if (!s)
+ if (nstack <= nodestack)
break;
- node = nodestack[--s].node;
- dot = nodestack[s].dot;
+ nstack--;
+ node = nstack->node;
+ side = nstack->side;
goto loc0;
}
}
if (cl.worldmodel)
R_WorldNode ();
- glClear (GL_DEPTH_BUFFER_BIT);
-
R_PushDlights (); // now mark the lit surfaces
DrawTextureChains ();
-
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
*/
// returns a texture number and the position inside it
-int AllocBlock (int w, int h, int *x, int *y)
+int AllocBlock (int w, int h, short *x, short *y)
{
int i, j;
int best, best2;
{
byte blank[BLOCK_WIDTH*BLOCK_HEIGHT*3];
memset(blank, 0, sizeof(blank));
- glBindTexture(GL_TEXTURE_2D, lightmap_textures + texnum);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (lightmaprgba)
- glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, blank);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, blank);
+ if(r_upload.value)
+ {
+ glBindTexture(GL_TEXTURE_2D, lightmap_textures + texnum);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (lightmaprgba)
+ glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, blank);
+ else
+ glTexImage2D (GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, blank);
+ }
}
for (i=0 ; i<w ; i++)
if (lightmaprgba)
{
R_BuildLightMap (surf, templight, smax * 4);
- glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
+ if(r_upload.value)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight);
}
else
{
R_BuildLightMap (surf, templight, smax * 3);
- glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
+ if(r_upload.value)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight);
}
}
if (nosubimage || nosubimagefragments)
{
- if (gl_mtexable)
- qglSelectTexture(gl_mtex_enum+1);
+ if(r_upload.value)
+ if (gl_mtexable)
+ qglSelectTexture(gl_mtex_enum+1);
for (i = 0;i < MAX_LIGHTMAPS;i++)
{
if (!allocated[i][0])
break;
lightmapupdate[i][0] = BLOCK_HEIGHT;
lightmapupdate[i][1] = 0;
- glBindTexture(GL_TEXTURE_2D, lightmap_textures + i);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (lightmaprgba)
- glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]);
+ if(r_upload.value)
+ {
+ glBindTexture(GL_TEXTURE_2D, lightmap_textures + i);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (lightmaprgba)
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]);
+ }
}
- if (gl_mtexable)
- qglSelectTexture(gl_mtex_enum+0);
+ if(r_upload.value)
+ if (gl_mtexable)
+ qglSelectTexture(gl_mtex_enum+0);
}
}