Merge brush model with world model rendering.

With this, non-mtex global fog now works properly :).
This commit is contained in:
Bill Currie 2011-12-17 21:45:52 +09:00
parent a8e354536a
commit 52d9269867
6 changed files with 103 additions and 223 deletions

View file

@ -47,7 +47,6 @@ void gl_lightmap_init (void);
void GL_BuildLightmaps (struct model_s **models, int num_models);
void R_BlendLightmaps (void);
void R_CalcLightmaps (void);
void R_CalcAndBlendLightmaps (void); // FIXME: temporary hack
extern void (*R_BuildLightMap) (msurface_t *surf);
#endif // __QF_GL_lightmap_h

View file

@ -132,8 +132,6 @@ typedef struct {
typedef struct glpoly_s {
struct glpoly_s *next;
struct glpoly_s *chain;
struct glpoly_s *fb_chain;
int numverts;
int flags; // for SURF_UNDERWATER
float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2)
@ -157,6 +155,7 @@ typedef struct msurface_s {
glpoly_t *polys; // multiple if warped
instsurf_t *instsurf; ///< null if not part of world model/sub-model
instsurf_t *tinst; ///< for instance models
mtexinfo_t *texinfo;

View file

@ -74,6 +74,7 @@ typedef struct entity_s {
vec3_t old_origin;
vec3_t angles;
vec_t transform[4 * 4];
vec_t full_transform[4 * 4];
struct model_s *model; // NULL = no model
int frame;
byte *colormap;

View file

@ -72,7 +72,7 @@ unsigned int blocklights[34 * 34 * 3]; //FIXME make dynamic
int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
qboolean lightmap_modified[MAX_GLTEXTURES];
glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
instsurf_t *lightmap_polys[MAX_LIGHTMAPS];
glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
static int lmshift = 7;
@ -482,11 +482,9 @@ void
R_CalcLightmaps (void)
{
int i;
glpoly_t *p;
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)
if (!lightmap_polys[i])
continue;
if (lightmap_modified[i]) {
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
@ -501,24 +499,30 @@ R_BlendLightmaps (void)
{
float *v;
int i, j;
instsurf_t *sc;
glpoly_t *p;
qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (lm_src_blend, lm_dest_blend);
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)
continue;
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
for (; p; p = p->chain) {
qfglBegin (GL_POLYGON);
v = p->verts[0];
for (j = 0; j < p->numverts; j++, v += VERTEXSIZE) {
qfglTexCoord2fv (&v[5]);
qfglVertex3fv (v);
for (sc = lightmap_polys[i]; sc; sc = sc->lm_chain) {
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
if (sc->transform) {
qfglPushMatrix ();
qfglLoadMatrixf (sc->transform);
}
qfglEnd ();
for (p = sc->surface->polys; p; p = p->next) {
qfglBegin (GL_POLYGON);
v = p->verts[0];
for (j = 0; j < p->numverts; j++, v += VERTEXSIZE) {
qfglTexCoord2fv (&v[5]);
qfglVertex3fv (v);
}
qfglEnd ();
}
if (sc->transform)
qfglPopMatrix ();
}
}
@ -619,41 +623,6 @@ gl_overbright_f (cvar_t *var)
}
}
void
R_CalcAndBlendLightmaps (void)
{
float *v;
int i, j;
glpoly_t *p;
qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (lm_src_blend, lm_dest_blend);
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)
continue;
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
if (lightmap_modified[i]) {
GL_UploadLightmap (i);
lightmap_modified[i] = false;
}
for (; p; p = p->chain) {
qfglBegin (GL_POLYGON);
v = p->verts[0];
for (j = 0; j < p->numverts; j++, v += VERTEXSIZE) {
qfglTexCoord2fv (&v[5]);
qfglVertex3fv (v);
}
qfglEnd ();
}
}
// Return to normal blending --KB
qfglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qfglDepthMask (GL_TRUE); // back to normal Z buffering
}
// LIGHTMAP ALLOCATION ========================================================
// returns a texture number and the position inside it

View file

@ -220,13 +220,6 @@ R_DrawEntitiesOnList (void)
return;
// LordHavoc: split into 3 loops to simplify state changes
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_brush)
continue;
currententity = ent;
R_DrawBrushModel (currententity);
}
if (gl_mtex_active_tmus >= 2) {
qglActiveTexture (gl_mtex_enum + 1);

View file

@ -60,35 +60,33 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
int skytexturenum;
glpoly_t *fullbright_polys[MAX_GLTEXTURES];
instsurf_t *waterchain = NULL;
instsurf_t **waterchain_tail = &waterchain;
instsurf_t *sky_chain;
instsurf_t **sky_chain_tail;
#define CHAIN_SURF_F2B(surf,chain) \
do { \
instsurf_t *inst = (surf)->instsurf; \
if (!inst) inst = get_instsurf (); \
inst->surface = (surf); \
*(chain##_tail) = inst; \
(chain##_tail) = &inst->tex_chain; \
*(chain##_tail) = 0; \
#define CHAIN_SURF_F2B(surf,chain) \
do { \
instsurf_t *inst = (surf)->instsurf; \
if (!inst) (surf)->tinst = inst = get_instsurf (); \
inst->surface = (surf); \
*(chain##_tail) = inst; \
(chain##_tail) = &inst->tex_chain; \
*(chain##_tail) = 0; \
} while (0)
#define CHAIN_SURF_B2F(surf,chain) \
do { \
instsurf_t *inst = (surf)->instsurf; \
if (!inst) inst = get_instsurf (); \
inst->surface = (surf); \
inst->tex_chain = (chain); \
(chain) = inst; \
#define CHAIN_SURF_B2F(surf,chain) \
do { \
instsurf_t *inst = (surf)->instsurf; \
if (!inst) (surf)->tinst = inst = get_instsurf (); \
inst->surface = (surf); \
inst->tex_chain = (chain); \
(chain) = inst; \
} while (0)
extern int lightmap_textures;
extern qboolean lightmap_modified[MAX_LIGHTMAPS];
extern glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
extern instsurf_t *lightmap_polys[MAX_LIGHTMAPS];
extern glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
static texture_t **r_texture_chains;
@ -209,19 +207,34 @@ R_RenderFullbrights (void)
float *v;
int i, j;
glpoly_t *p;
instsurf_t *sc;
texture_t *tex;
for (i = 1; i < MAX_GLTEXTURES; i++) {
if (!fullbright_polys[i])
for (i = 0; i < r_num_texture_chains; i++) {
if (!(tex = r_texture_chains[i]) || !tex->gl_fb_texturenum)
continue;
qfglBindTexture (GL_TEXTURE_2D, i);
for (p = fullbright_polys[i]; p; p = p->fb_chain) {
qfglBegin (GL_POLYGON);
for (j = 0, v = p->verts[0]; j < p->numverts; j++, v += VERTEXSIZE)
{
qfglTexCoord2fv (&v[3]);
qfglVertex3fv (v);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_fb_texturenum);
for (sc = tex->tex_chain; sc; sc = sc->tex_chain) {
if (sc->transform) {
qfglPushMatrix ();
qfglLoadMatrixf (sc->transform);
}
qfglEnd ();
if (sc->color)
qfglColor4fv (sc->color);
for (p = sc->surface->polys; p; p = p->next) {
qfglBegin (GL_POLYGON);
for (j = 0, v = p->verts[0]; j < p->numverts;
j++, v += VERTEXSIZE)
{
qfglTexCoord2fv (&v[3]);
qfglVertex3fv (v);
}
qfglEnd ();
}
if (sc->transform)
qfglPopMatrix ();
if (sc->color)
qfglColor3ubv (color_white);
}
}
}
@ -291,11 +304,14 @@ R_AddToLightmapChain (msurface_t *fa)
{
int maps, smax, tmax;
glRect_t *theRect;
instsurf_t *sc;
// add the poly to the proper lightmap chain
if (!(sc = fa->instsurf))
sc = fa->tinst;
fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
lightmap_polys[fa->lightmaptexturenum] = fa->polys;
sc->lm_chain = lightmap_polys[fa->lightmaptexturenum];
lightmap_polys[fa->lightmaptexturenum] = sc;
// check for lightmap modification
for (maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++)
@ -388,8 +404,8 @@ DrawTextureChains (int disable_blend, int do_bind)
qglActiveTexture (gl_mtex_enum + 0);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for (i = 0; i < r_worldentity.model->numtextures; i++) {
tex = r_worldentity.model->textures[i];
for (i = 0; i < r_num_texture_chains; i++) {
tex = r_texture_chains[i];
if (!tex)
continue;
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
@ -410,12 +426,13 @@ DrawTextureChains (int disable_blend, int do_bind)
qfglColor4fv (s->color);
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures +
fa->lightmaptexturenum);
R_RenderBrushPoly_3 (fa);
if (s->transform)
qfglPopMatrix ();
if (s->color && do_bind)
qfglColor3ubv (color_white);
R_RenderBrushPoly_3 (fa);
}
qglActiveTexture (gl_mtex_enum + 2);
@ -456,8 +473,8 @@ DrawTextureChains (int disable_blend, int do_bind)
} else {
if (disable_blend)
qfglDisable (GL_BLEND);
for (i = 0; i < r_worldentity.model->numtextures; i++) {
tex = r_worldentity.model->textures[i];
for (i = 0; i < r_num_texture_chains; i++) {
tex = r_texture_chains[i];
if (!tex)
continue;
if (do_bind)
@ -498,11 +515,15 @@ clear_texture_chains (void)
tex->tex_chain = NULL;
tex->tex_chain_tail = &tex->tex_chain;
release_instsurfs ();
memset (lightmap_polys, 0, sizeof (lightmap_polys));
}
static inline void
chain_surface (msurface_t *surf)
chain_surface (msurface_t *surf, vec_t *transform, float *color)
{
instsurf_t *sc;
if (surf->flags & SURF_DRAWTURB) {
CHAIN_SURF_B2F (surf, waterchain);
} else if (surf->flags & SURF_DRAWSKY) {
@ -510,27 +531,24 @@ chain_surface (msurface_t *surf)
} else {
texture_t *tex;
R_AddToLightmapChain (surf);
if (!surf->texinfo->texture->anim_total)
tex = surf->texinfo->texture;
else
tex = R_TextureAnimation (surf);
if (gl_fb_bmodels->int_val && tex->gl_fb_texturenum
&& !gl_mtex_fullbright) {
surf->polys->fb_chain =
fullbright_polys[tex->gl_fb_texturenum];
fullbright_polys[tex->gl_fb_texturenum] = surf->polys;
}
CHAIN_SURF_F2B (surf, tex->tex_chain);
R_AddToLightmapChain (surf);
}
if (!(sc = surf->instsurf))
sc = surf->tinst;
sc->transform = transform;
sc->color = color;
}
void
R_DrawBrushModel (entity_t *e)
{
float dot, radius;
float color[4], watercolor[4];
int i;
unsigned int k;
model_t *model;
@ -564,16 +582,6 @@ R_DrawBrushModel (entity_t *e)
return;
}
VectorCopy (e->colormod, color);
VectorCopy (color, watercolor);
color[3] = e->colormod[3]; // entity alpha
qfglColor4fv (color);
if (color[3] < 1.0)
qfglDepthMask (GL_FALSE);
memset (lightmap_polys, 0, sizeof (lightmap_polys));
memset (fullbright_polys, 0, sizeof (fullbright_polys));
VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
if (rotated) {
vec3_t temp;
@ -602,16 +610,8 @@ R_DrawBrushModel (entity_t *e)
qfglPushMatrix ();
R_RotateForEntity (e);
// Build lightmap chains
for (i = 0; i < model->nummodelsurfaces; i++, psurf++) {
if (psurf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
continue;
R_AddToLightmapChain (psurf);
}
if (gl_mtex_active_tmus >= 2)
R_CalcLightmaps ();
qfglGetFloatv (GL_MODELVIEW_MATRIX, e->full_transform);
qfglPopMatrix ();
psurf = &model->surfaces[model->firstmodelsurface];
@ -625,97 +625,9 @@ R_DrawBrushModel (entity_t *e)
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
if (psurf->flags & SURF_DRAWTURB) {
qfglBindTexture (GL_TEXTURE_2D,
psurf->texinfo->texture->gl_texturenum);
if (cl_wateralpha < 1.0) {
if (color[3] >= 1.0)
qfglDepthMask (GL_FALSE);
watercolor[3] = color[3] * cl_wateralpha;
qfglColor4fv (watercolor);
EmitWaterPolys (psurf);
qfglColor4fv (color);
if (color[3] >= 1.0)
qfglDepthMask (GL_TRUE);
} else {
EmitWaterPolys (psurf);
}
} else if (psurf->flags & SURF_DRAWSKY) {
// QSG FIXME: add modelalpha support for sky brushes
CHAIN_SURF_F2B (psurf, sky_chain);
} else {
texture_t *tex;
if (!psurf->texinfo->texture->anim_total)
tex = psurf->texinfo->texture;
else
tex = R_TextureAnimation (psurf);
if (gl_mtex_active_tmus >= 2) {
if (tex->gl_fb_texturenum && gl_mtex_fullbright) {
qglActiveTexture (gl_mtex_enum + 2);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_fb_texturenum);
qglActiveTexture (gl_mtex_enum + 1);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures +
psurf->lightmaptexturenum);
qglActiveTexture (gl_mtex_enum + 0);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
R_RenderBrushPoly_3 (psurf);
qglActiveTexture (gl_mtex_enum + 2);
qfglDisable (GL_TEXTURE_2D);
qglActiveTexture (gl_mtex_enum + 1);
qfglDisable (GL_TEXTURE_2D);
qglActiveTexture (gl_mtex_enum + 0);
} else {
qglActiveTexture (gl_mtex_enum + 1);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures +
psurf->lightmaptexturenum);
qglActiveTexture (gl_mtex_enum + 0);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
R_RenderBrushPoly_2 (psurf);
qglActiveTexture (gl_mtex_enum + 1);
qfglDisable (GL_TEXTURE_2D);
qglActiveTexture (gl_mtex_enum + 0);
}
} else {
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
R_RenderBrushPoly_1 (psurf);
if (tex->gl_fb_texturenum && gl_mtex_fullbright) {
psurf->polys->fb_chain =
fullbright_polys[tex->gl_fb_texturenum];
fullbright_polys[tex->gl_fb_texturenum] = psurf->polys;
}
}
}
chain_surface (psurf, e->full_transform, e->colormod);
}
}
if (gl_mtex_active_tmus >= 2) {
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
} else {
R_CalcAndBlendLightmaps ();
}
if (gl_fb_bmodels->int_val && !gl_mtex_fullbright)
R_RenderFullbrights ();
qfglPopMatrix ();
if (color[3] < 1.0)
qfglDepthMask (GL_TRUE);
qfglColor3ubv (color_white);
}
// WORLD MODEL ================================================================
@ -758,7 +670,7 @@ visit_node (mnode_t *node, int side)
if (side ^ (surf->flags & SURF_PLANEBACK))
continue; // wrong side
chain_surface (surf);
chain_surface (surf, 0, 0);
}
}
}
@ -826,17 +738,14 @@ R_RecursiveWorldNode (mnode_t *node)
void
R_DrawWorld (void)
{
entity_t ent;
entity_t worldent;
memset (&ent, 0, sizeof (ent));
ent.model = r_worldentity.model;
memset (&worldent, 0, sizeof (worldent));
worldent.model = r_worldentity.model;
VectorCopy (r_refdef.vieworg, modelorg);
currententity = &ent;
memset (lightmap_polys, 0, sizeof (lightmap_polys));
memset (fullbright_polys, 0, sizeof (fullbright_polys));
currententity = &worldent;
sky_chain = 0;
sky_chain_tail = &sky_chain;
@ -845,6 +754,16 @@ R_DrawWorld (void)
}
R_RecursiveWorldNode (r_worldentity.model->nodes);
if (r_drawentities->int_val) {
entity_t *ent;
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_brush)
continue;
currententity = ent;
R_DrawBrushModel (currententity);
}
}
R_CalcLightmaps ();