cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
+cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
vec3_t v;
vec_t s, t, intensity;
#define NORMSIZE 64
- unsigned char data[6][NORMSIZE][NORMSIZE][4];
+ unsigned char *data;
+ data = Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
for (side = 0;side < 6;side++)
{
for (y = 0;y < NORMSIZE;y++)
break;
}
intensity = 127.0f / sqrt(DotProduct(v, v));
- data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[0]);
- data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
- data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[2]);
- data[side][y][x][3] = 255;
+ data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
+ data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
+ data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
+ data[((side*64+y)*64+x)*4+3] = 255;
}
}
}
- r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+ r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+ Mem_Free(data);
}
static void R_BuildFogTexture(void)
}
else
{
- r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
- //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
+ r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT | TEXF_ALLOWUPDATES, NULL);
+ //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALLOWUPDATES, NULL);
}
}
"#endif\n"
"#else // !MODE_SHOWDEPTH\n"
"#ifdef MODE_POSTPROCESS\n"
+"varying vec2 TexCoord1;\n"
+"varying vec2 TexCoord2;\n"
+"\n"
"#ifdef VERTEX_SHADER\n"
"void main(void)\n"
"{\n"
" gl_Position = ftransform();\n"
-" gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
+" TexCoord1 = gl_MultiTexCoord0.xy;\n"
"#ifdef USEBLOOM\n"
-" gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;\n"
+" TexCoord2 = gl_MultiTexCoord1.xy;\n"
"#endif\n"
"}\n"
"#endif\n"
"uniform vec2 PixelSize;\n"
"void main(void)\n"
"{\n"
-" gl_FragColor = texture2D(Texture_First, gl_TexCoord[0].xy);\n"
+" gl_FragColor = texture2D(Texture_First, TexCoord1);\n"
"#ifdef USEBLOOM\n"
-" gl_FragColor += texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
+" gl_FragColor += texture2D(Texture_Second, TexCoord2);\n"
"#endif\n"
"#ifdef USEVIEWTINT\n"
" gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
"#ifdef USEPOSTPROCESSING\n"
"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
"// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
-" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n"
+" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
+" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
+" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
+" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n"
+" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n"
" gl_FragColor /= (1 + 5 * UserVec1.y);\n"
"#endif\n"
"\n"
"#endif\n"
"#else // !MODE_POSTPROCESS\n"
"#ifdef MODE_GENERIC\n"
+"#ifdef USEDIFFUSE\n"
+"varying vec2 TexCoord1;\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"varying vec2 TexCoord2;\n"
+"#endif\n"
"#ifdef VERTEX_SHADER\n"
"void main(void)\n"
"{\n"
" gl_FrontColor = gl_Color;\n"
"#ifdef USEDIFFUSE\n"
-" gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
+" TexCoord1 = gl_MultiTexCoord0.xy;\n"
"#endif\n"
"#ifdef USESPECULAR\n"
-" gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;\n"
+" TexCoord2 = gl_MultiTexCoord1.xy;\n"
"#endif\n"
" gl_Position = ftransform();\n"
"}\n"
"{\n"
" gl_FragColor = gl_Color;\n"
"#ifdef USEDIFFUSE\n"
-" gl_FragColor *= texture2D(Texture_First, gl_TexCoord[0].xy);\n"
+" gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
"#endif\n"
"\n"
"#ifdef USESPECULAR\n"
-" vec4 tex2 = texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
+" vec4 tex2 = texture2D(Texture_Second, TexCoord2);\n"
"#endif\n"
"#ifdef USECOLORMAPPING\n"
" gl_FragColor *= tex2;\n"
"#endif\n"
"#else // !MODE_GENERIC\n"
"#ifdef MODE_BLOOMBLUR\n"
+"varying TexCoord;\n"
"#ifdef VERTEX_SHADER\n"
"void main(void)\n"
"{\n"
" gl_FrontColor = gl_Color;\n"
-" gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
+" TexCoord = gl_MultiTexCoord0.xy;\n"
" gl_Position = ftransform();\n"
"}\n"
"#endif\n"
"void main(void)\n"
"{\n"
" int i;\n"
-" vec2 tc = gl_TexCoord[0].xy;\n"
+" vec2 tc = TexCoord;\n"
" vec3 color = texture2D(Texture_First, tc).rgb;\n"
" tc += BloomBlur_Parameters.xy;\n"
" for (i = 1;i < SAMPLES;i++)\n"
"#ifdef MODE_REFRACTION\n"
"varying vec2 TexCoord;\n"
"varying vec4 ModelViewProjectionPosition;\n"
+"uniform mat4 TexMatrix;\n"
"#ifdef VERTEX_SHADER\n"
"\n"
"void main(void)\n"
"{\n"
-" TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
" gl_Position = ftransform();\n"
" ModelViewProjectionPosition = gl_Position;\n"
"}\n"
"varying vec4 ModelViewProjectionPosition;\n"
"#ifdef VERTEX_SHADER\n"
"uniform vec3 EyePosition;\n"
+"uniform mat4 TexMatrix;\n"
"\n"
"void main(void)\n"
"{\n"
-" TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
"// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
"\n"
"#ifdef MODE_DEFERREDGEOMETRY\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
"void main(void)\n"
"{\n"
-" TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
"#ifdef USEVERTEXTEXTUREBLEND\n"
" gl_FrontColor = gl_Color;\n"
-" TexCoord2 = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord0);\n"
+" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
"#endif\n"
"\n"
" // transform unnormalized eye direction into tangent space\n"
" gl_Position = ftransform();\n"
"}\n"
"#else // !MODE_DEFERREDLIGHTSOURCE\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform mat4 ModelToLight;\n"
+"#endif\n"
"void main(void)\n"
"{\n"
"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
" gl_FrontColor = gl_Color;\n"
"#endif\n"
" // copy the surface texcoord\n"
-" TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
"#ifdef USEVERTEXTEXTUREBLEND\n"
-" TexCoord2 = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord0);\n"
+" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
"#endif\n"
"#ifdef USELIGHTMAP\n"
" TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
"#ifdef MODE_LIGHTSOURCE\n"
" // transform vertex position into light attenuation/cubemap space\n"
" // (-1 to +1 across the light box)\n"
-" CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
+" CubeVector = vec3(ModelToLight * gl_Vertex);\n"
"\n"
"# ifdef USEDIFFUSE\n"
" // transform unnormalized light direction into tangent space\n"
int loc_UserVec4;
int loc_ViewTintColor;
int loc_ViewToLight;
+ int loc_ModelToLight;
+ int loc_TexMatrix;
+ int loc_BackgroundTexMatrix;
}
r_glsl_permutation_t;
p->loc_UserVec4 = qglGetUniformLocationARB(p->program, "UserVec4");
p->loc_ViewTintColor = qglGetUniformLocationARB(p->program, "ViewTintColor");
p->loc_ViewToLight = qglGetUniformLocationARB(p->program, "ViewToLight");
+ p->loc_ModelToLight = qglGetUniformLocationARB(p->program, "ModelToLight");
+ p->loc_TexMatrix = qglGetUniformLocationARB(p->program, "TexMatrix");
+ p->loc_BackgroundTexMatrix = qglGetUniformLocationARB(p->program, "BackgroundTexMatrix");
// initialize the samplers to refer to the texture units we use
if (p->loc_Texture_First >= 0) qglUniform1iARB(p->loc_Texture_First , GL20TU_FIRST);
if (p->loc_Texture_Second >= 0) qglUniform1iARB(p->loc_Texture_Second , GL20TU_SECOND);
// fragment shader on features that are not being used
unsigned int permutation = 0;
unsigned int mode = 0;
+ float m16f[16];
// TODO: implement geometry-shader based shadow volumes someday
if (r_glsl_offsetmapping.integer)
{
R_SetupShader_SetPermutation(mode, permutation);
if (mode == SHADERMODE_LIGHTSOURCE)
{
+ if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
}
+ if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
Cvar_RegisterVariable(&r_polygonoffset_decals_offset);
Cvar_RegisterVariable(&r_fog_exp2);
Cvar_RegisterVariable(&r_drawfog);
+ Cvar_RegisterVariable(&r_transparentdepthmasking);
Cvar_RegisterVariable(&r_textureunits);
Cvar_RegisterVariable(&gl_combine);
Cvar_RegisterVariable(&r_glsl);
void R_SetupView(qboolean allowwaterclippingplane)
{
- const double *customclipplane = NULL;
- double plane[4];
+ const float *customclipplane = NULL;
+ float plane[4];
if (r_refdef.view.useclipplane && allowwaterclippingplane)
{
// LordHavoc: couldn't figure out how to make this approach the
r_refdef.view.width = oldwidth;
r_refdef.view.height = oldheight;
r_refdef.view.colorscale = oldcolorscale;
+ r_frame++; // used only by R_GetCurrentTexture
R_ResetViewRendering3D();
}
else
{
- r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+ r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT | TEXF_ALLOWUPDATES, NULL);
}
}
}
t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION);
if (!(rsurface.ent_flags & RENDER_LIGHT))
t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
- else if (rsurface.modeltexcoordlightmap2f == NULL)
+ else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
{
// pick a model lighting mode
if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f))
}
else
t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER);
+ if ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) == MATERIALFLAG_BLENDED && r_transparentdepthmasking.integer && !(t->basematerialflags & MATERIALFLAG_BLENDED))
+ t->currentmaterialflags |= MATERIALFLAG_TRANSDEPTH;
// there is no tcmod
if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL)
t->currentnumlayers = 0;
if (t->currentmaterialflags & MATERIALFLAG_WALL)
{
- int layerflags = 0;
int blendfunc1, blendfunc2;
qboolean depthmask;
if (t->currentmaterialflags & MATERIALFLAG_ADD)
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
// 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, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->currentskinframe->fog, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->lightmapcolor[3]);
}
}
{
#define MAXBATCHTRIANGLES 4096
int batchtriangles = 0;
- int batchelements[MAXBATCHTRIANGLES*3];
+ static int batchelements[MAXBATCHTRIANGLES*3];
for (i = 0;i < texturenumsurfaces;i = j)
{
surface = texturesurfacelist[i];
if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION)))
return;
- R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
- R_Mesh_TexMatrix(1, &rsurface.texture->currentbackgroundtexmatrix);
R_Mesh_TexBind(GL20TU_NORMAL, R_GetTexture(rsurface.texture->currentskinframe->nmap));
R_Mesh_TexBind(GL20TU_COLOR, R_GetTexture(rsurface.texture->basetexture));
R_Mesh_TexBind(GL20TU_GLOSS, R_GetTexture(rsurface.texture->glosstexture));
int texturesurfaceindex;
qboolean applycolor;
qboolean applyfog;
- rmeshstate_t m;
int layerindex;
const texturelayer_t *layer;
RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
layercolor[3] = layer->color[3];
applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
R_Mesh_ColorPointer(NULL, 0, 0);
- applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
+ applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
switch (layer->type)
{
case TEXTURELAYERTYPE_LITTEXTURE:
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(r_texture_white);
- m.pointer_texcoord[0] = rsurface.modeltexcoordlightmap2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.modeltexcoordlightmap2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.modeltexcoordlightmap2f_bufferoffset;
- m.tex[1] = R_GetTexture(layer->texture);
- m.texmatrix[1] = layer->texmatrix;
- m.texrgbscale[1] = layertexrgbscale;
- m.pointer_texcoord[1] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[1] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[1] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ // single-pass lightmapped texture with 2x rgbscale
+ R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+ R_Mesh_TexMatrix(0, NULL);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset);
+ R_Mesh_TexBind(1, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(1, &layer->texmatrix);
+ R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
+ R_Mesh_TexCoordPointer(1, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
else if (rsurface.uselightmaptexture)
RSurf_DrawBatch_GL11_VertexColor(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
break;
case TEXTURELAYERTYPE_TEXTURE:
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.texrgbscale[0] = layertexrgbscale;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ // singletexture unlit texture with transparency support
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
+ R_Mesh_TexBind(1, 0);
+ R_Mesh_TexCoordPointer(1, 2, NULL, 0, 0);
RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
break;
case TEXTURELAYERTYPE_FOG:
- memset(&m, 0, sizeof(m));
- m.texrgbscale[0] = layertexrgbscale;
+ // singletexture fogging
if (layer->texture)
{
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
+ }
+ else
+ {
+ R_Mesh_TexBind(0, 0);
+ R_Mesh_TexCoordPointer(0, 2, NULL, 0, 0);
}
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(1, 0);
+ R_Mesh_TexCoordPointer(1, 2, NULL, 0, 0);
// generate a color array for the fog pass
R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
// OpenGL 1.1 - crusty old voodoo path
int texturesurfaceindex;
qboolean applyfog;
- rmeshstate_t m;
int layerindex;
const texturelayer_t *layer;
RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
GL_DepthMask(layer->depthmask && writedepth);
GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
R_Mesh_ColorPointer(NULL, 0, 0);
- applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
+ applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
switch (layer->type)
{
case TEXTURELAYERTYPE_LITTEXTURE:
{
// two-pass lit texture with 2x rgbscale
// first the lightmap pass
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(r_texture_white);
- m.pointer_texcoord[0] = rsurface.modeltexcoordlightmap2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.modeltexcoordlightmap2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.modeltexcoordlightmap2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+ R_Mesh_TexMatrix(0, NULL);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset);
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false);
else if (rsurface.uselightmaptexture)
GL_LockArrays(0, 0);
// then apply the texture to it
GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0] * 0.5f, layer->color[1] * 0.5f, layer->color[2] * 0.5f, layer->color[3], layer->color[0] != 2 || layer->color[1] != 2 || layer->color[2] != 2 || layer->color[3] != 1, false);
}
else
{
// single pass vertex-lighting-only texture with 1x rgbscale and transparency support
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
else
break;
case TEXTURELAYERTYPE_TEXTURE:
// singletexture unlit texture with transparency support
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
break;
case TEXTURELAYERTYPE_FOG:
// singletexture fogging
- R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
if (layer->texture)
{
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(layer->texture);
- m.texmatrix[0] = layer->texmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- R_Mesh_TextureState(&m);
+ R_Mesh_TexBind(0, R_GetTexture(layer->texture));
+ R_Mesh_TexMatrix(0, &layer->texmatrix);
+ R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
}
else
- R_Mesh_ResetTextureState();
+ {
+ R_Mesh_TexBind(0, 0);
+ R_Mesh_TexCoordPointer(0, 2, NULL, 0, 0);
+ }
// generate a color array for the fog pass
+ R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
int i;
int texturenumsurfaces, endsurface;
texture_t *texture;
const msurface_t *surface;
- const msurface_t *texturesurfacelist[1024];
+ const msurface_t *texturesurfacelist[256];
// if the model is static it doesn't matter what value we give for
// wantnormals and wanttangents, so this logic uses only rules applicable
}
}
+ if (r_transparentdepthmasking.integer)
+ {
+ qboolean setup = false;
+ for (i = 0;i < numsurfaces;i = j)
+ {
+ j = i + 1;
+ surface = rsurface.modelsurfaces + surfacelist[i];
+ texture = surface->texture;
+ rsurface.texture = R_GetCurrentTexture(texture);
+ rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
+ // scan ahead until we find a different texture
+ endsurface = min(i + 1024, numsurfaces);
+ texturenumsurfaces = 0;
+ texturesurfacelist[texturenumsurfaces++] = surface;
+ for (;j < endsurface;j++)
+ {
+ surface = rsurface.modelsurfaces + surfacelist[j];
+ if (texture != surface->texture || rsurface.uselightmaptexture != (surface->lightmaptexture != NULL))
+ break;
+ texturesurfacelist[texturenumsurfaces++] = surface;
+ }
+ if (!(rsurface.texture->currentmaterialflags & MATERIALFLAG_TRANSDEPTH))
+ continue;
+ // render the range of surfaces as depth
+ if (!setup)
+ {
+ setup = true;
+ GL_ColorMask(0,0,0,0);
+ GL_Color(1,1,1,1);
+ GL_DepthTest(true);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_AlphaTest(false);
+ R_Mesh_ColorPointer(NULL, 0, 0);
+ R_Mesh_ResetTextureState();
+ R_SetupDepthOrShadowShader();
+ }
+ RSurf_SetupDepthAndCulling();
+ RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
+ RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
+ }
+ if (setup)
+ GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
+ }
+
for (i = 0;i < numsurfaces;i = j)
{
j = i + 1;
GL_AlphaTest(false);
}
+static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity)
+{
+ // transparent surfaces get pushed off into the transparent queue
+ int surfacelistindex;
+ const msurface_t *surface;
+ vec3_t tempcenter, center;
+ for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
+ {
+ surface = texturesurfacelist[surfacelistindex];
+ 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);
+ if (queueentity->transparent_offset) // transparent offset
+ {
+ center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset;
+ center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset;
+ center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset;
+ }
+ R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
+ }
+}
+
static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
{
const entity_render_t *queueentity = r_refdef.scene.worldentity;
}
else if (prepass)
{
- if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
- return;
if (!rsurface.texture->currentnumlayers)
return;
- R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
+ R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+ else
+ R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
}
- else if (r_showsurfaces.integer && !r_refdef.view.showdebug)
+ else if (r_showsurfaces.integer && !r_refdef.view.showdebug && !prepass)
{
RSurf_SetupDepthAndCulling();
GL_AlphaTest(false);
GL_DepthTest(writedepth);
RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
}
- else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
+ else if (r_showsurfaces.integer && r_showsurfaces.integer != 3 && !prepass)
{
RSurf_SetupDepthAndCulling();
GL_AlphaTest(false);
return;
else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
{
- // transparent surfaces get pushed off into the transparent queue
- int surfacelistindex;
- const msurface_t *surface;
- vec3_t tempcenter, center;
- for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
- {
- surface = texturesurfacelist[surfacelistindex];
- 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_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
- }
+ // in the deferred case, transparent surfaces were queued during prepass
+ if (!r_shadow_usingdeferredprepass)
+ R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
}
else
{
}
else if (prepass)
{
- if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
- return;
if (!rsurface.texture->currentnumlayers)
return;
- R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
+ R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+ else
+ R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
}
else if (r_showsurfaces.integer && !r_refdef.view.showdebug)
{
return;
else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
{
- // transparent surfaces get pushed off into the transparent queue
- int surfacelistindex;
- const msurface_t *surface;
- vec3_t tempcenter, center;
- for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
- {
- surface = texturesurfacelist[surfacelistindex];
- 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);
- if (queueentity->transparent_offset) // transparent offset
- {
- center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset;
- center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset;
- center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset;
- }
- R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
- }
+ // in the deferred case, transparent surfaces were queued during prepass
+ if (!r_shadow_usingdeferredprepass)
+ R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
}
else
{
float *c4f;
float *t2f;
const int *e;
- const unsigned char *surfacevisible = r_refdef.viewcache.world_surfacevisible;
+ const unsigned char *surfacevisible = ent == r_refdef.scene.worldentity ? r_refdef.viewcache.world_surfacevisible : NULL;
int numtris = 0;
numdecals = decalsystem->numdecals;
if (!decal->color4ub[0][3])
continue;
- if (decal->surfaceindex >= 0 && !surfacevisible[decal->surfaceindex])
+ if (surfacevisible && !surfacevisible[decal->surfaceindex])
continue;
// update color values for fading decals
if (numtris > 0)
{
r_refdef.stats.drawndecals += numtris;
+
+ if (r_refdef.fogenabled)
+ {
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ for (i = 0, v3f = decalsystem->vertex3f, c4f = decalsystem->color4f;i < numtris*3;i++, v3f += 3, c4f += 4)
+ {
+ alpha = RSurf_FogVertex(v3f);
+ c4f[0] *= alpha;
+ c4f[1] *= alpha;
+ c4f[2] *= alpha;
+ }
+ break;
+ }
+ }
+
// now render the decals all at once
// (this assumes they all use one particle font texture!)
RSurf_ActiveCustomEntity(&rsurface.matrix, &rsurface.inversematrix, rsurface.ent_flags, rsurface.ent_shadertime, 1, 1, 1, 1, numdecals*3, decalsystem->vertex3f, decalsystem->texcoord2f, NULL, NULL, NULL, decalsystem->color4f, numtris, decalsystem->element3i, decalsystem->element3s, false, false);
}
// update lightmaps if needed
if (update)
+ {
+ int updated = 0;
for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
+ {
if (r_refdef.viewcache.world_surfacevisible[j])
+ {
if (update[j])
+ {
+ updated++;
R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
+ }
+ }
+ }
+ if (updated)
+ {
+ int count = model->brushq3.num_mergedlightmaps;
+ for (i = 0;i < count;i++)
+ {
+ if (model->brushq3.data_deluxemaps[i])
+ R_FlushTexture(model->brushq3.data_deluxemaps[i]);
+ if (model->brushq3.data_lightmaps[i])
+ R_FlushTexture(model->brushq3.data_lightmaps[i]);
+ }
+ }
+ }
// don't do anything if there were no surfaces
if (!numsurfacelist)
{
return;
}
// update lightmaps if needed
+ if (update)
+ {
+ int updated = 0;
+ for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
+ {
+ if (update[j])
+ {
+ updated++;
+ R_BuildLightMap(ent, surfaces + j);
+ }
+ }
+ if (updated)
+ {
+ int count = model->brushq3.num_mergedlightmaps;
+ for (i = 0;i < count;i++)
+ {
+ if (model->brushq3.data_deluxemaps[i])
+ R_FlushTexture(model->brushq3.data_deluxemaps[i]);
+ if (model->brushq3.data_lightmaps[i])
+ R_FlushTexture(model->brushq3.data_lightmaps[i]);
+ }
+ }
+ }
if (update)
for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
if (update[j])
rsurface.uselightmaptexture = false;
R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
}
+
+void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)
+{
+ static msurface_t surface;
+ const msurface_t *surfacelist = &surface;
+
+ // fake enough texture and surface state to render this geometry
+
+ surface.texture = texture;
+ surface.num_triangles = numtriangles;
+ surface.num_firsttriangle = firsttriangle;
+ surface.num_vertices = numvertices;
+ surface.num_firstvertex = firstvertex;
+
+ // now render it
+ rsurface.texture = R_GetCurrentTexture(surface.texture);
+ rsurface.uselightmaptexture = false;
+ R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
+}