From 3c8da461b7565f9c6524c48aecc362270815c3ee Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 1 Feb 2008 06:00:59 +0000 Subject: [PATCH] renamed MATERIALFLAG_WATER to MATERIALFLAG_WATERSCROLL changed all MATERIALFLAG_WATER materials to use MATERIALFLAG_WALL as their primary material flag, this simplified some rendering code did some more tweaks to fix issues with the mirror glass texture in the tenebrae testmap git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8059 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 218 +++++++++++++++++++++---------------------------- gl_rsurf.c | 105 ++++++++++++------------ model_brush.c | 31 +++---- model_brush.h | 10 +-- model_shared.c | 12 +-- render.h | 33 ++++++++ 6 files changed, 203 insertions(+), 206 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 227d213d..7310943f 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -149,36 +149,7 @@ static struct r_bloomstate_s } r_bloomstate; -typedef struct r_waterstate_waterplane_s -{ - rtexture_t *texture_refraction; - rtexture_t *texture_reflection; - mplane_t plane; - int materialflags; // combined flags of all water surfaces on this plane - unsigned char pvsbits[(32768+7)>>3]; // FIXME: buffer overflow on huge maps - qboolean pvsvalid; -} -r_waterstate_waterplane_t; - -#define MAX_WATERPLANES 16 - -static struct r_waterstate_s -{ - qboolean enabled; - - qboolean renderingscene; // true while rendering a refraction or reflection texture, disables water surfaces - - int waterwidth, waterheight; - int texturewidth, textureheight; - - int maxwaterplanes; // same as MAX_WATERPLANES - int numwaterplanes; - r_waterstate_waterplane_t waterplanes[MAX_WATERPLANES]; - - float screenscale[2]; - float screencenter[2]; -} -r_waterstate; +r_waterstate_t r_waterstate; // shadow volume bsp struct with automatically growing nodes buffer svbsp_t r_svbsp; @@ -4401,6 +4372,12 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) float tcmat[12]; q3shaderinfo_layer_tcmod_t *tcmod; + if (t->basematerialflags & MATERIALFLAG_NODRAW) + { + t->currentmaterialflags = MATERIALFLAG_NODRAW; + return; + } + // switch to an alternate material if this is a q1bsp animated material { texture_t *texture = t; @@ -4493,7 +4470,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER); // there is no tcmod - if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0) + if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL) t->currenttexmatrix = r_waterscrollmatrix; for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) @@ -4503,7 +4480,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) { case Q3TCMOD_COUNT: case Q3TCMOD_NONE: - if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0) + if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL) matrix = r_waterscrollmatrix; else matrix = identitymatrix; @@ -4585,105 +4562,98 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->basetexture = r_texture_grey128; t->backgroundbasetexture = NULL; t->specularscale = 0; - t->currentmaterialflags &= ~(MATERIALFLAG_ALPHA | MATERIALFLAG_ADD | MATERIALFLAG_WATERALPHA | MATERIALFLAG_WATER | MATERIALFLAG_SKY | MATERIALFLAG_ALPHATEST | MATERIALFLAG_BLENDED | MATERIALFLAG_CUSTOMBLEND | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION); - t->currentmaterialflags |= MATERIALFLAG_WALL; + t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE)); } Vector4Set(t->lightmapcolor, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha); VectorClear(t->dlightcolor); t->currentnumlayers = 0; - if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW)) + if (t->currentmaterialflags & MATERIALFLAG_WALL) { - if (!(t->currentmaterialflags & MATERIALFLAG_SKY)) + int layerflags = 0; + int blendfunc1, blendfunc2, depthmask; + if (t->currentmaterialflags & MATERIALFLAG_ADD) { - int blendfunc1, blendfunc2, depthmask; - if (t->currentmaterialflags & MATERIALFLAG_ADD) - { - blendfunc1 = GL_SRC_ALPHA; - blendfunc2 = GL_ONE; - } - else if (t->currentmaterialflags & MATERIALFLAG_ALPHA) - { - blendfunc1 = GL_SRC_ALPHA; - blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - } - else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) - { - blendfunc1 = t->customblendfunc[0]; - blendfunc2 = t->customblendfunc[1]; - } - else - { - blendfunc1 = GL_ONE; - blendfunc2 = GL_ZERO; - } - depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED); - if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL)) + blendfunc1 = GL_SRC_ALPHA; + blendfunc2 = GL_ONE; + } + else if (t->currentmaterialflags & MATERIALFLAG_ALPHA) + { + blendfunc1 = GL_SRC_ALPHA; + blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) + { + blendfunc1 = t->customblendfunc[0]; + blendfunc2 = t->customblendfunc[1]; + } + else + { + blendfunc1 = GL_ONE; + blendfunc2 = GL_ZERO; + } + depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED); + if (r_refdef.fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED)) + layerflags |= TEXTURELAYERFLAG_FOGDARKEN; + if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) + { + // fullbright is not affected by r_refdef.lightmapintensity + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); + if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * t->lightmapcolor[0], ent->colormap_pantscolor[1] * t->lightmapcolor[1], ent->colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * t->lightmapcolor[0], ent->colormap_shirtcolor[1] * t->lightmapcolor[1], ent->colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + } + else + { + vec3_t ambientcolor; + float colorscale; + // set the color tint used for lights affecting this surface + VectorSet(t->dlightcolor, ent->colormod[0] * t->lightmapcolor[3], ent->colormod[1] * t->lightmapcolor[3], ent->colormod[2] * t->lightmapcolor[3]); + colorscale = 2; + // q3bsp has no lightmap updates, so the lightstylevalue that + // would normally be baked into the lightmap must be + // applied to the color + // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright) + if (ent->model->type == mod_brushq3) + colorscale *= r_refdef.scene.rtlightstylevalue[0]; + colorscale *= r_refdef.lightmapintensity; + VectorScale(t->lightmapcolor, r_ambient.value * (1.0f / 64.0f), ambientcolor); + VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor); + // basic lit geometry + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); + // add pants/shirt if needed + if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * t->lightmapcolor[0], ent->colormap_pantscolor[1] * t->lightmapcolor[1], ent->colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * t->lightmapcolor[0], ent->colormap_shirtcolor[1] * t->lightmapcolor[1], ent->colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + // now add ambient passes if needed + if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f)) { - int layerflags = 0; - if (r_refdef.fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED)) - layerflags |= TEXTURELAYERFLAG_FOGDARKEN; - if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) - { - // fullbright is not affected by r_refdef.lightmapintensity - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * t->lightmapcolor[0], ent->colormap_pantscolor[1] * t->lightmapcolor[1], ent->colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * t->lightmapcolor[0], ent->colormap_shirtcolor[1] * t->lightmapcolor[1], ent->colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - } - else - { - vec3_t ambientcolor; - float colorscale; - // set the color tint used for lights affecting this surface - VectorSet(t->dlightcolor, ent->colormod[0] * t->lightmapcolor[3], ent->colormod[1] * t->lightmapcolor[3], ent->colormod[2] * t->lightmapcolor[3]); - colorscale = 2; - // q3bsp has no lightmap updates, so the lightstylevalue that - // would normally be baked into the lightmap must be - // applied to the color - // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright) - if (ent->model->type == mod_brushq3) - colorscale *= r_refdef.scene.rtlightstylevalue[0]; - colorscale *= r_refdef.lightmapintensity; - VectorScale(t->lightmapcolor, r_ambient.value * (1.0f / 64.0f), ambientcolor); - VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor); - // basic lit geometry - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); - // add pants/shirt if needed - if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * t->lightmapcolor[0], ent->colormap_pantscolor[1] * t->lightmapcolor[1], ent->colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * t->lightmapcolor[0], ent->colormap_shirtcolor[1] * t->lightmapcolor[1], ent->colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - // now add ambient passes if needed - if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f)) - { - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ambientcolor[0], ent->colormap_pantscolor[1] * ambientcolor[1], ent->colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ambientcolor[0], ent->colormap_shirtcolor[1] * ambientcolor[1], ent->colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]); - } - } - if (t->currentskinframe->glow != NULL && !gl_lightmaps.integer) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->glow, &t->currenttexmatrix, r_hdr_glowintensity.value, r_hdr_glowintensity.value, r_hdr_glowintensity.value, t->lightmapcolor[3]); - if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD)) - { - // if this is opaque use alpha blend which will darken the earlier - // passes cheaply. - // - // if this is an alpha blended material, all the earlier passes - // were darkened by fog already, so we only need to add the fog - // color ontop through the fog mask texture - // - // if this is an additive blended material, all the earlier passes - // were darkened by fog already, and we should not add fog color - // (because the background was not darkened, there is no fog color - // that was lost behind it). - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->currentskinframe->fog, &identitymatrix, r_refdef.fogcolor[0] / r_refdef.view.colorscale, r_refdef.fogcolor[1] / r_refdef.view.colorscale, r_refdef.fogcolor[2] / r_refdef.view.colorscale, t->lightmapcolor[3]); - } + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]); + if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->currentskinframe->pants) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ambientcolor[0], ent->colormap_pantscolor[1] * ambientcolor[1], ent->colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]); + if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->currentskinframe->shirt) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ambientcolor[0], ent->colormap_shirtcolor[1] * ambientcolor[1], ent->colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]); } } + if (t->currentskinframe->glow != NULL && !gl_lightmaps.integer) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->currentskinframe->glow, &t->currenttexmatrix, r_hdr_glowintensity.value, r_hdr_glowintensity.value, r_hdr_glowintensity.value, t->lightmapcolor[3]); + if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD)) + { + // if this is opaque use alpha blend which will darken the earlier + // passes cheaply. + // + // if this is an alpha blended material, all the earlier passes + // were darkened by fog already, so we only need to add the fog + // color ontop through the fog mask texture + // + // if this is an additive blended material, all the earlier passes + // were darkened by fog already, and we should not add fog color + // (because the background was not darkened, there is no fog color + // that was lost behind it). + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->currentskinframe->fog, &identitymatrix, r_refdef.fogcolor[0] / r_refdef.view.colorscale, r_refdef.fogcolor[1] / r_refdef.view.colorscale, r_refdef.fogcolor[2] / r_refdef.view.colorscale, t->lightmapcolor[3]); + } } } @@ -6453,7 +6423,7 @@ void R_DrawDebugModel(entity_render_t *ent) model_t *model = ent->model; vec3_t v; - flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WATER | MATERIALFLAG_WALL; + flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL; R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); @@ -6607,7 +6577,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep } R_UpdateAllTextureInfo(r_refdef.scene.worldentity); - flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL)); + flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL); if (debug) { @@ -6697,7 +6667,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr } R_UpdateAllTextureInfo(ent); - flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL)); + flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL); if (debug) { diff --git a/gl_rsurf.c b/gl_rsurf.c index 76f4782c..416c7720 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1086,67 +1086,49 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface for (kend = k;kend < batchnumsurfaces && tex == batchsurfacelist[kend]->texture;kend++) ; // now figure out what to do with this particular range of surfaces - if (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_WATER)) + if (!(rsurface.texture->currentmaterialflags & MATERIALFLAG_WALL)) + continue; + if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))) + continue; + if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) { - if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) + vec3_t tempcenter, center; + for (l = k;l < kend;l++) { - vec3_t tempcenter, center; - for (l = k;l < kend;l++) - { - surface = batchsurfacelist[l]; - tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; - tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; - tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; - Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); - R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); - } + surface = batchsurfacelist[l]; + tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; + tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; + tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); + R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); } - else + continue; + } + batchnumtriangles = 0; + batchfirsttriangle = surface->num_firsttriangle; + for (l = k;l < kend;l++) + { + surface = batchsurfacelist[l]; + RSurf_PrepareVerticesForBatch(true, true, 1, &surface); + for (m = surface->num_firsttriangle, mend = m + surface->num_triangles;m < mend;m++) { - batchnumtriangles = 0; - batchfirsttriangle = surface->num_firsttriangle; - for (l = k;l < kend;l++) + if (trispvs) { - surface = batchsurfacelist[l]; - RSurf_PrepareVerticesForBatch(true, true, 1, &surface); - for (m = surface->num_firsttriangle, mend = m + surface->num_triangles;m < mend;m++) + if (!CHECKPVSBIT(trispvs, m)) { - if (trispvs) - { - if (!CHECKPVSBIT(trispvs, m)) - { - usebufferobject = false; - continue; - } - } - else if (culltriangles) - { - if (r_shadow_frontsidecasting.integer && !PointInfrontOfTriangle(rsurface.entitylightorigin, rsurface.vertex3f + element3i[m*3+0]*3, rsurface.vertex3f + element3i[m*3+1]*3, rsurface.vertex3f + element3i[m*3+2]*3)) - { - usebufferobject = false; - continue; - } - } - if (batchnumtriangles >= BATCHSIZE) - { - r_refdef.stats.lights_lighttriangles += batchnumtriangles; - Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex); - // use the element buffer if all triangles are consecutive - if (m == batchfirsttriangle + batchnumtriangles) - R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle); - else - R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0); - usebufferobject = true; - batchnumtriangles = 0; - batchfirsttriangle = m; - } - batchelements[batchnumtriangles*3+0] = element3i[m*3+0]; - batchelements[batchnumtriangles*3+1] = element3i[m*3+1]; - batchelements[batchnumtriangles*3+2] = element3i[m*3+2]; - batchnumtriangles++; + usebufferobject = false; + continue; } } - if (batchnumtriangles > 0) + else if (culltriangles) + { + if (r_shadow_frontsidecasting.integer && !PointInfrontOfTriangle(rsurface.entitylightorigin, rsurface.vertex3f + element3i[m*3+0]*3, rsurface.vertex3f + element3i[m*3+1]*3, rsurface.vertex3f + element3i[m*3+2]*3)) + { + usebufferobject = false; + continue; + } + } + if (batchnumtriangles >= BATCHSIZE) { r_refdef.stats.lights_lighttriangles += batchnumtriangles; Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex); @@ -1155,9 +1137,26 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle); else R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0); + usebufferobject = true; + batchnumtriangles = 0; + batchfirsttriangle = m; } + batchelements[batchnumtriangles*3+0] = element3i[m*3+0]; + batchelements[batchnumtriangles*3+1] = element3i[m*3+1]; + batchelements[batchnumtriangles*3+2] = element3i[m*3+2]; + batchnumtriangles++; } } + if (batchnumtriangles > 0) + { + r_refdef.stats.lights_lighttriangles += batchnumtriangles; + Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex); + // use the element buffer if all triangles are consecutive + if (m == batchfirsttriangle + batchnumtriangles) + R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle); + else + R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0); + } } } } diff --git a/model_brush.c b/model_brush.c index 12ae4d6f..1b0cc330 100644 --- a/model_brush.c +++ b/model_brush.c @@ -1358,15 +1358,15 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) tx->currentskinframe = tx->skinframes[0]; tx->basematerialflags = 0; } + tx->basematerialflags = MATERIALFLAG_WALL; if (i == loadmodel->num_textures - 1) { - tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW; + tx->basematerialflags |= MATERIALFLAG_WATERSCROLL | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW; tx->supercontents = mod_q1bsp_texture_water.supercontents; tx->surfaceflags = mod_q1bsp_texture_water.surfaceflags; } else { - tx->basematerialflags |= MATERIALFLAG_WALL; tx->supercontents = mod_q1bsp_texture_solid.supercontents; tx->surfaceflags = mod_q1bsp_texture_solid.surfaceflags; } @@ -1532,36 +1532,37 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) tx->skinframes[0] = skinframe; } - tx->basematerialflags = 0; + tx->basematerialflags = MATERIALFLAG_WALL; if (tx->name[0] == '*') { // LordHavoc: some turbulent textures should not be affected by wateralpha if (!strncmp(tx->name, "*glassmirror", 12)) // Tenebrae { // replace the texture with transparent black - tx->skinframes[0] = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_MIPMAP | TEXF_PRECACHE, zero, 1, 1); - tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_NOSHADOW | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_REFLECTION; + Vector4Set(zero, 128, 128, 128, 128); + tx->skinframes[0] = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_MIPMAP | TEXF_PRECACHE | TEXF_ALPHA, zero, 1, 1); + tx->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_REFLECTION; } else if (!strncmp(tx->name,"*lava",5) || !strncmp(tx->name,"*teleport",9) || !strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture - tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW; + tx->basematerialflags |= MATERIALFLAG_WATERSCROLL | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW; else - tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERALPHA | MATERIALFLAG_WATERSHADER; + tx->basematerialflags |= MATERIALFLAG_WATERSCROLL | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERALPHA | MATERIALFLAG_WATERSHADER; + if (tx->skinframes[0] && tx->skinframes[0]->fog) + tx->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; } else if (!strncmp(tx->name, "mirror", 6)) // Tenebrae { - // replace the texture with transparent black + // replace the texture with black tx->skinframes[0] = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_PRECACHE, zero, 1, 1); - tx->basematerialflags |= MATERIALFLAG_WALL | MATERIALFLAG_REFLECTION; + tx->basematerialflags |= MATERIALFLAG_REFLECTION; } else if (!strncmp(tx->name, "sky", 3)) - tx->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW; + tx->basematerialflags = MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW; else if (!strcmp(tx->name, "caulk")) tx->basematerialflags = MATERIALFLAG_NODRAW; - else - tx->basematerialflags |= MATERIALFLAG_WALL; - if (tx->skinframes[0] && tx->skinframes[0]->fog) + else if (tx->skinframes[0] && tx->skinframes[0]->fog) tx->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // start out with no animation @@ -1984,7 +1985,7 @@ static void Mod_Q1BSP_LoadTexinfo(lump_t *l) { // if texture chosen is NULL or the shader needs a lightmap, // force to notexture water shader - if (out->texture == NULL || out->texture->basematerialflags & MATERIALFLAG_WALL) + if (out->texture == NULL) out->texture = loadmodel->data_textures + (loadmodel->num_textures - 1); } else @@ -2343,7 +2344,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) { surface->lightmapinfo->samples = NULL; // give non-lightmapped water a 1x white lightmap - if ((surface->texture->basematerialflags & MATERIALFLAG_WATER) && (surface->lightmapinfo->texinfo->flags & TEX_SPECIAL) && ssize <= 256 && tsize <= 256) + if (surface->texture->name[0] == '*' && (surface->lightmapinfo->texinfo->flags & TEX_SPECIAL) && ssize <= 256 && tsize <= 256) { surface->lightmapinfo->samples = (unsigned char *)Mem_Alloc(loadmodel->mempool, ssize * tsize * 3); surface->lightmapinfo->styles[0] = 0; diff --git a/model_brush.h b/model_brush.h index 7ec6c1a6..8eaeddd3 100644 --- a/model_brush.h +++ b/model_brush.h @@ -72,13 +72,13 @@ mplane_t; #define MATERIALFLAG_WATERALPHA 16 // draw with no lighting #define MATERIALFLAG_FULLBRIGHT 32 -// drawn as a normal lightmapped wall +// drawn as a normal surface (alternative to SKY) #define MATERIALFLAG_WALL 64 -// swirling water effect -#define MATERIALFLAG_WATER 128 -// this surface shows the sky +// this surface shows the sky in its place, alternative to WALL // skipped if transparent -#define MATERIALFLAG_SKY 256 +#define MATERIALFLAG_SKY 128 +// swirling water effect (used with MATERIALFLAG_WALL) +#define MATERIALFLAG_WATERSCROLL 256 // skips drawing the surface #define MATERIALFLAG_NODRAW 512 // probably used only on q1bsp water diff --git a/model_shared.c b/model_shared.c index 246a1873..9899adcf 100644 --- a/model_shared.c +++ b/model_shared.c @@ -1696,7 +1696,7 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool texture->basematerialflags = 0; if (shader->surfaceparms & Q3SURFACEPARM_SKY) { - texture->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW; + texture->basematerialflags = MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW; if (shader->skyboxname[0]) { // quake3 seems to append a _ to the skybox name, so this must do so as well @@ -1704,15 +1704,9 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool } } else if ((texture->surfaceflags & Q3SURFACEFLAG_NODRAW) || shader->numlayers == 0) - texture->basematerialflags |= MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW; - else if (shader->surfaceparms & Q3SURFACEPARM_LAVA) - texture->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOSHADOW; - else if (shader->surfaceparms & Q3SURFACEPARM_SLIME) - texture->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW; - else if (shader->surfaceparms & Q3SURFACEPARM_WATER) - texture->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW; + texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW; else - texture->basematerialflags |= MATERIALFLAG_WALL; + texture->basematerialflags = MATERIALFLAG_WALL; if (shader->layers[0].alphatest) texture->basematerialflags |= MATERIALFLAG_ALPHATEST | MATERIALFLAG_NOSHADOW; if (shader->textureflags & Q3TEXTUREFLAG_TWOSIDED) diff --git a/render.h b/render.h index ff6258b7..5e004ef9 100644 --- a/render.h +++ b/render.h @@ -405,5 +405,38 @@ void R_SetupGenericTwoTextureShader(int texturemode); void R_SetupDepthOrShadowShader(void); void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass); +typedef struct r_waterstate_waterplane_s +{ + rtexture_t *texture_refraction; + rtexture_t *texture_reflection; + mplane_t plane; + int materialflags; // combined flags of all water surfaces on this plane + unsigned char pvsbits[(32768+7)>>3]; // FIXME: buffer overflow on huge maps + qboolean pvsvalid; +} +r_waterstate_waterplane_t; + +#define MAX_WATERPLANES 16 + +typedef struct r_waterstate_s +{ + qboolean enabled; + + qboolean renderingscene; // true while rendering a refraction or reflection texture, disables water surfaces + + int waterwidth, waterheight; + int texturewidth, textureheight; + + int maxwaterplanes; // same as MAX_WATERPLANES + int numwaterplanes; + r_waterstate_waterplane_t waterplanes[MAX_WATERPLANES]; + + float screenscale[2]; + float screencenter[2]; +} +r_waterstate_t; + +extern r_waterstate_t r_waterstate; + #endif -- 2.39.2