r_viewcache_t r_viewcache;
cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
-cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"};
+cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"};
cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
cvar_t r_hdr = {CVAR_SAVE, "r_hdr", "0", "enables High Dynamic Range bloom effect (higher quality version of r_bloom)"};
cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
+cvar_t r_hdr_range = {CVAR_SAVE, "r_hdr_range", "4", "how much dynamic range to render bloom with (equivilant to multiplying r_bloom_brighten by this value and dividing r_bloom_colorscale by this value)"};
cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
}
r_bloomstate;
+// shadow volume bsp struct with automatically growing nodes buffer
+svbsp_t r_svbsp;
+
rtexture_t *r_texture_blanknormalmap;
rtexture_t *r_texture_white;
rtexture_t *r_texture_black;
{NULL, NULL}
};
-void R_GLSL_CompilePermutation(int permutation)
+void R_GLSL_CompilePermutation(const char *filename, int permutation)
{
int i;
- r_glsl_permutation_t *p = r_glsl_permutations + permutation;
+ qboolean shaderfound;
+ r_glsl_permutation_t *p = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK);
int vertstrings_count;
+ int geomstrings_count;
int fragstrings_count;
char *shaderstring;
const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
+ const char *geomstrings_list[SHADERPERMUTATION_COUNT+1];
const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
char permutationname[256];
if (p->compiled)
return;
p->compiled = true;
+ p->program = 0;
vertstrings_list[0] = "#define VERTEX_SHADER\n";
+ geomstrings_list[0] = "#define GEOMETRY_SHADER\n";
fragstrings_list[0] = "#define FRAGMENT_SHADER\n";
vertstrings_count = 1;
+ geomstrings_count = 1;
fragstrings_count = 1;
permutationname[0] = 0;
for (i = 0;permutationinfo[i][0];i++)
if (permutation & (1<<i))
{
vertstrings_list[vertstrings_count++] = permutationinfo[i][0];
+ geomstrings_list[geomstrings_count++] = permutationinfo[i][0];
fragstrings_list[fragstrings_count++] = permutationinfo[i][0];
strlcat(permutationname, permutationinfo[i][1], sizeof(permutationname));
}
{
// keep line numbers correct
vertstrings_list[vertstrings_count++] = "\n";
+ geomstrings_list[geomstrings_count++] = "\n";
fragstrings_list[fragstrings_count++] = "\n";
}
}
- shaderstring = (char *)FS_LoadFile("glsl/default.glsl", r_main_mempool, false, NULL);
+ shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
+ shaderfound = false;
if (shaderstring)
{
- Con_DPrintf("GLSL shader text loaded from disk\n");
+ Con_DPrintf("GLSL shader text for \"%s\" loaded from disk\n", filename);
vertstrings_list[vertstrings_count++] = shaderstring;
+ geomstrings_list[geomstrings_count++] = shaderstring;
fragstrings_list[fragstrings_count++] = shaderstring;
+ shaderfound = true;
}
- else
+ else if (!strcmp(filename, "glsl/default.glsl"))
{
+ Con_DPrintf("GLSL shader text for \"%s\" loaded from engine\n", filename);
vertstrings_list[vertstrings_count++] = builtinshaderstring;
+ geomstrings_list[geomstrings_count++] = builtinshaderstring;
fragstrings_list[fragstrings_count++] = builtinshaderstring;
- }
- p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
+ shaderfound = true;
+ }
+ // clear any lists that are not needed by this shader
+ if (!(permutation & SHADERPERMUTATION_USES_VERTEXSHADER))
+ vertstrings_count = 0;
+ if (!(permutation & SHADERPERMUTATION_USES_GEOMETRYSHADER))
+ geomstrings_count = 0;
+ if (!(permutation & SHADERPERMUTATION_USES_FRAGMENTSHADER))
+ fragstrings_count = 0;
+ // compile the shader program
+ if (shaderfound && vertstrings_count + geomstrings_count + fragstrings_count)
+ p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
if (p->program)
{
CHECKGLERROR
qglUseProgramObjectARB(p->program);CHECKGLERROR
+ // look up all the uniform variable names we care about, so we don't
+ // have to look them up every time we set them
p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
+ // initialize the samplers to refer to the texture units we use
if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal, 0);
if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color, 1);
if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss, 2);
// combination of texture, entity, light source, and fogging, only use the
// minimum features necessary to avoid wasting rendering time in the
// fragment shader on features that are not being used
+ const char *shaderfilename = NULL;
int permutation = 0;
float specularscale = rsurface_texture->specularscale;
r_glsl_permutation = NULL;
+ // TODO: implement geometry-shader based shadow volumes someday
if (r_shadow_rtlight)
{
- permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
+ // light source
+ shaderfilename = "glsl/default.glsl";
+ permutation = SHADERPERMUTATION_MODE_LIGHTSOURCE | SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
specularscale *= r_shadow_rtlight->specularscale;
if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
permutation |= SHADERPERMUTATION_CUBEFILTER;
+ if (specularscale > 0)
+ permutation |= SHADERPERMUTATION_SPECULAR;
+ if (r_refdef.fogenabled)
+ permutation |= SHADERPERMUTATION_FOG;
+ if (rsurface_texture->colormapping)
+ permutation |= SHADERPERMUTATION_COLORMAPPING;
+ if (r_glsl_offsetmapping.integer)
+ {
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING;
+ if (r_glsl_offsetmapping_reliefmapping.integer)
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ }
}
- else
+ else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
- if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+ // bright unshaded geometry
+ shaderfilename = "glsl/default.glsl";
+ permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
+ if (rsurface_texture->currentskinframe->glow)
+ permutation |= SHADERPERMUTATION_GLOW;
+ if (r_refdef.fogenabled)
+ permutation |= SHADERPERMUTATION_FOG;
+ if (rsurface_texture->colormapping)
+ permutation |= SHADERPERMUTATION_COLORMAPPING;
+ if (r_glsl_offsetmapping.integer)
{
- if (modellighting)
- permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
- else if (r_glsl_deluxemapping.integer >= 1 && rsurface_lightmaptexture)
- {
- if (r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping)
- {
- if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
- permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
- else
- permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
- }
- else if (r_glsl_deluxemapping.integer >= 2) // fake mode
- permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
- }
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING;
+ if (r_glsl_offsetmapping_reliefmapping.integer)
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
}
+ }
+ else if (modellighting)
+ {
+ // directional model lighting
+ shaderfilename = "glsl/default.glsl";
+ permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
+ permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
if (rsurface_texture->currentskinframe->glow)
permutation |= SHADERPERMUTATION_GLOW;
+ if (specularscale > 0)
+ permutation |= SHADERPERMUTATION_SPECULAR;
+ if (r_refdef.fogenabled)
+ permutation |= SHADERPERMUTATION_FOG;
+ if (rsurface_texture->colormapping)
+ permutation |= SHADERPERMUTATION_COLORMAPPING;
+ if (r_glsl_offsetmapping.integer)
+ {
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING;
+ if (r_glsl_offsetmapping_reliefmapping.integer)
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ }
}
- if (specularscale > 0)
- permutation |= SHADERPERMUTATION_SPECULAR;
- if (r_refdef.fogenabled)
- permutation |= SHADERPERMUTATION_FOG;
- if (rsurface_texture->colormapping)
- permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_glsl_offsetmapping.integer)
+ else
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ // lightmapped wall
+ shaderfilename = "glsl/default.glsl";
+ permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
+ if (r_glsl_deluxemapping.integer >= 1 && rsurface_lightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping)
+ {
+ // deluxemapping (light direction texture)
+ if (rsurface_lightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
+ permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
+ else
+ permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
+ if (specularscale > 0)
+ permutation |= SHADERPERMUTATION_SPECULAR;
+ }
+ else if (r_glsl_deluxemapping.integer >= 2)
+ {
+ // fake deluxemapping (uniform light direction in tangentspace)
+ permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
+ if (specularscale > 0)
+ permutation |= SHADERPERMUTATION_SPECULAR;
+ }
+ else
+ {
+ // ordinary lightmapping
+ permutation |= 0;
+ }
+ if (rsurface_texture->currentskinframe->glow)
+ permutation |= SHADERPERMUTATION_GLOW;
+ if (r_refdef.fogenabled)
+ permutation |= SHADERPERMUTATION_FOG;
+ if (rsurface_texture->colormapping)
+ permutation |= SHADERPERMUTATION_COLORMAPPING;
+ if (r_glsl_offsetmapping.integer)
+ {
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING;
+ if (r_glsl_offsetmapping_reliefmapping.integer)
+ permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ }
}
- if (!r_glsl_permutations[permutation].program)
+ if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program)
{
- if (!r_glsl_permutations[permutation].compiled)
- R_GLSL_CompilePermutation(permutation);
- if (!r_glsl_permutations[permutation].program)
+ if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].compiled)
+ R_GLSL_CompilePermutation(shaderfilename, permutation);
+ if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program)
{
// remove features until we find a valid permutation
int i;
if (permutation < i)
continue;
permutation &= i;
- if (!r_glsl_permutations[permutation].compiled)
- R_GLSL_CompilePermutation(permutation);
- if (r_glsl_permutations[permutation].program)
+ if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].compiled)
+ R_GLSL_CompilePermutation(shaderfilename, permutation);
+ if (r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program)
break;
if (!i)
return 0; // utterly failed
}
}
}
- r_glsl_permutation = r_glsl_permutations + permutation;
+ r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK);
CHECKGLERROR
qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
R_Mesh_TexMatrix(0, &rsurface_texture->currenttexmatrix);
void R_SwitchSurfaceShader(int permutation)
{
- if (r_glsl_permutation != r_glsl_permutations + permutation)
+ if (r_glsl_permutation != r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK))
{
- r_glsl_permutation = r_glsl_permutations + permutation;
+ r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK);
CHECKGLERROR
qglUseProgramObjectARB(r_glsl_permutation->program);
CHECKGLERROR
R_BuildFogTexture();
memset(&r_bloomstate, 0, sizeof(r_bloomstate));
memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
+ memset(&r_svbsp, 0, sizeof (r_svbsp));
}
void gl_main_shutdown(void)
{
+ if (r_svbsp.nodes)
+ Mem_Free(r_svbsp.nodes);
+ memset(&r_svbsp, 0, sizeof (r_svbsp));
R_FreeTexturePool(&r_main_texturepool);
r_texture_blanknormalmap = NULL;
r_texture_white = NULL;
Cvar_RegisterVariable(&r_hdr);
Cvar_RegisterVariable(&r_hdr_scenebrightness);
Cvar_RegisterVariable(&r_hdr_glowintensity);
+ Cvar_RegisterVariable(&r_hdr_range);
Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
Cvar_RegisterVariable(&developer_texturelogging);
Cvar_RegisterVariable(&gl_lightmaps);
R_View_UpdateEntityVisible();
}
-void R_ResetViewRendering(void)
+void R_SetupView(const matrix4x4_t *matrix)
+{
+ if (r_refdef.rtworldshadows || r_refdef.rtdlightshadows)
+ GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip);
+ else
+ GL_SetupView_Mode_Perspective(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip, r_refdef.farclip);
+
+ GL_SetupView_Orientation_FromEntity(matrix);
+}
+
+void R_ResetViewRendering2D(void)
{
if (gl_support_fragment_shader)
{
qglUseProgramObjectARB(0);CHECKGLERROR
}
+ DrawQ_Finish();
+
// GL is weird because it's bottom to top, r_view.y is top to bottom
qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+ GL_Color(1, 1, 1, 1);
GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_AlphaTest(false);
GL_ScissorTest(false);
GL_DepthMask(false);
GL_DepthTest(false);
R_Mesh_Matrix(&identitymatrix);
R_Mesh_ResetTextureState();
+ qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
+ qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+ qglDisable(GL_STENCIL_TEST);CHECKGLERROR
+ qglStencilMask(~0);CHECKGLERROR
+ qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
+ qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
+ GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+}
+
+void R_ResetViewRendering3D(void)
+{
+ if (gl_support_fragment_shader)
+ {
+ qglUseProgramObjectARB(0);CHECKGLERROR
+ }
+
+ DrawQ_Finish();
+
+ // GL is weird because it's bottom to top, r_view.y is top to bottom
+ qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+ R_SetupView(&r_view.matrix);
+ GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+ GL_Color(1, 1, 1, 1);
+ GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_AlphaTest(false);
+ GL_ScissorTest(true);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
+ R_Mesh_Matrix(&identitymatrix);
+ R_Mesh_ResetTextureState();
+ qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
+ qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+ qglDisable(GL_STENCIL_TEST);CHECKGLERROR
+ qglStencilMask(~0);CHECKGLERROR
+ qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
+ qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
+ GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
}
/*
"#endif // FRAGMENT_SHADER\n"
*/
-void R_SetupView(const matrix4x4_t *matrix)
-{
- if (r_refdef.rtworldshadows || r_refdef.rtdlightshadows)
- GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip);
- else
- GL_SetupView_Mode_Perspective(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip, r_refdef.farclip);
-
- GL_SetupView_Orientation_FromEntity(matrix);
-}
-
void R_RenderScene(void);
void R_Bloom_StartFrame(void)
{
r_refdef.stats.bloom++;
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Mesh_VertexPointer(r_screenvertex3f);
R_Mesh_ColorPointer(NULL);
R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f);
void R_Bloom_MakeTexture(void)
{
int x, range, dir;
- float xoffset, yoffset, r;
+ float xoffset, yoffset, r, brighten;
r_refdef.stats.bloom++;
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Mesh_VertexPointer(r_screenvertex3f);
R_Mesh_ColorPointer(NULL);
}
range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320;
+ brighten = r_bloom_brighten.value;
+ if (r_hdr.integer)
+ brighten *= r_hdr_range.value;
R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
R_Mesh_TexCoordPointer(0, 2, r_bloomstate.offsettexcoord2f);
// black at the edges
// (probably not realistic but looks good enough)
//r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
- //r = (dir ? 1.0f : r_bloom_brighten.value)/(range*2+1);
- r = (dir ? 1.0f : r_bloom_brighten.value)/(range*2+1)*(1 - x*x/(float)(range*range));
+ //r = (dir ? 1.0f : brighten)/(range*2+1);
+ r = (dir ? 1.0f : brighten)/(range*2+1)*(1 - x*x/(float)(range*range));
GL_Color(r, r, r, 1);
R_Mesh_Draw(0, 4, 2, polygonelements);
r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
// TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer? it might improve SLI performance.
// TODO: add exposure compensation features
+ // TODO: add fp16 framebuffer support
r_view.colorscale = r_bloom_colorscale.value * r_hdr_scenebrightness.value;
+ if (r_hdr.integer)
+ r_view.colorscale /= r_hdr_range.value;
R_RenderScene();
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Bloom_CopyHDRTexture();
R_Bloom_MakeTexture();
- R_ResetViewRendering();
- GL_ScissorTest(true);
- GL_DepthMask(true);
- GL_DepthTest(true);
+ R_ResetViewRendering3D();
+
R_ClearScreen();
if (r_timereport_active)
R_TimeReport("clear");
+
// restore the view settings
r_view.width = oldwidth;
r_view.height = oldheight;
// render high dynamic range bloom effect
// the bloom texture was made earlier this render, so we just need to
// blend it onto the screen...
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Mesh_VertexPointer(r_screenvertex3f);
R_Mesh_ColorPointer(NULL);
GL_Color(1, 1, 1, 1);
R_Bloom_MakeTexture();
// put the original screen image back in place and blend the bloom
// texture on it
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Mesh_VertexPointer(r_screenvertex3f);
R_Mesh_ColorPointer(NULL);
GL_Color(1, 1, 1, 1);
if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
{
// apply a color tint to the whole view
- R_ResetViewRendering();
+ R_ResetViewRendering2D();
R_Mesh_VertexPointer(r_screenvertex3f);
R_Mesh_ColorPointer(NULL);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
r_refdef.rtworld = r_shadow_realtime_world.integer;
r_refdef.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
- r_refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
+ r_refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer;
r_refdef.rtdlightshadows = r_refdef.rtdlight && (r_refdef.rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
r_refdef.lightmapintensity = r_refdef.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
if (r_showsurfaces.integer)
if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
return; //Host_Error ("R_RenderView: NULL worldmodel");
+ R_Shadow_UpdateWorldLightSelection();
+
CHECKGLERROR
if (r_timereport_active)
R_TimeReport("setup");
if (r_timereport_active)
R_TimeReport("visibility");
- R_ResetViewRendering();
- GL_ScissorTest(true);
- GL_DepthMask(true);
- GL_DepthTest(true);
+ R_ResetViewRendering3D();
+
R_ClearScreen();
if (r_timereport_active)
R_TimeReport("clear");
extern void R_DrawPortals (void);
void R_RenderScene(void)
{
- DrawQ_Finish();
-
// don't let sound skip if going slow
if (r_refdef.extraupdate)
S_ExtraUpdate ();
- CHECKGLERROR
- if (gl_support_fragment_shader)
- {
- qglUseProgramObjectARB(0);CHECKGLERROR
- }
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
- qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
- qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
-
- R_ResetViewRendering();
- R_SetupView(&r_view.matrix);
+ R_ResetViewRendering3D();
R_MeshQueue_BeginScene();
- R_Shadow_UpdateWorldLightSelection();
-
R_SkyStartFrame();
Matrix4x4_CreateTranslate(&r_waterscrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
{
R_DrawModelShadows();
+ R_ResetViewRendering3D();
+
// don't let sound skip if going slow
if (r_refdef.extraupdate)
S_ExtraUpdate ();
if (r_refdef.extraupdate)
S_ExtraUpdate ();
- CHECKGLERROR
- if (gl_support_fragment_shader)
- {
- qglUseProgramObjectARB(0);CHECKGLERROR
- }
- qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
- qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ R_ResetViewRendering2D();
}
/*
GL_DepthMask(true);
}
GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
+ GL_CullFace((ent->flags & RENDER_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
R_Mesh_VertexPointer(nomodelvertex3f);
if (r_refdef.fogenabled)
{
void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
{
+ model_t *model = ent->model;
+
// FIXME: identify models using a better check than ent->model->brush.shadowmesh
//int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
// switch to an alternate material if this is a q1bsp animated material
{
texture_t *texture = t;
- model_t *model = ent->model;
int s = ent->skinnum;
if ((unsigned int)s >= (unsigned int)model->numskins)
s = 0;
// pick a new currentskinframe if the material is animated
if (t->numskinframes >= 2)
t->currentskinframe = t->skinframes + ((int)(t->skinframerate * (cl.time - ent->frame2time)) % t->numskinframes);
+ if (t->backgroundnumskinframes >= 2)
+ t->backgroundcurrentskinframe = t->backgroundskinframes + ((int)(t->backgroundskinframerate * (cl.time - ent->frame2time)) % t->backgroundnumskinframes);
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = ent->alpha;
- if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
+ if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
t->currentalpha *= r_wateralpha.value;
if (!(ent->flags & RENDER_LIGHT))
t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
if (ent->effects & EF_ADDITIVE)
- t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
+ t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_NOSHADOW;
else if (t->currentalpha < 1)
- t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
+ t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_NOSHADOW;
+ if (ent->flags & RENDER_NOCULLFACE)
+ t->currentmaterialflags |= MATERIALFLAG_NOSHADOW;
if (ent->effects & EF_NODEPTHTEST)
- t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
+ t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_NOSHADOW;
if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
t->currenttexmatrix = r_waterscrollmatrix;
else
t->currenttexmatrix = identitymatrix;
+ if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+ t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base;
t->glosstexture = r_texture_white;
+ t->backgroundbasetexture = t->backgroundnumskinframes ? ((!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base) : r_texture_white;
+ t->backgroundglosstexture = r_texture_white;
t->specularpower = r_shadow_glossexponent.value;
t->specularscale = 0;
if (r_shadow_gloss.integer > 0)
{
- if (t->currentskinframe->gloss)
+ if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss))
{
if (r_shadow_glossintensity.value > 0)
{
- t->glosstexture = t->currentskinframe->gloss;
+ t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_black;
+ t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_black;
t->specularscale = r_shadow_glossintensity.value;
}
}
static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
{
+ int j;
int texturesurfaceindex;
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ if (r_showsurfaces.integer == 2)
{
- const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
- int k = (int)(((size_t)surface) / sizeof(msurface_t));
- GL_Color((k & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_view.colorscale, 0.2f);
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+ for (j = 0;j < surface->num_triangles;j++)
+ {
+ float f = ((j + surface->num_firsttriangle) & 31) * (1.0f / 31.0f) * r_view.colorscale;
+ GL_Color(f, f, f, 1);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface_model->surfmesh.data_element3i + 3 * (j + surface->num_firsttriangle)));
+ }
+ }
+ }
+ else
+ {
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+ int k = (int)(((size_t)surface) / sizeof(msurface_t));
+ GL_Color((k & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_view.colorscale, 1);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
+ }
}
}
static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
{
+ GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
if (rsurface_mode != RSURFMODE_SHOWSURFACES)
{
rsurface_mode = RSURFMODE_SHOWSURFACES;
// restore entity matrix
R_Mesh_Matrix(&rsurface_entity->matrix);
}
+ GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
GL_DepthMask(true);
// LordHavoc: HalfLife maps have freaky skypolys so don't use
// skymasking on them, and Quake3 never did sky masking (unlike
static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **texturesurfacelist)
{
- int lightmode;
- // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
- lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
if (rsurface_mode != RSURFMODE_GLSL)
{
rsurface_mode = RSURFMODE_GLSL;
}
if (rsurface_glsl_texture != rsurface_texture || rsurface_glsl_uselightmap != (rsurface_lightmaptexture != NULL))
{
+ int lightmode;
rsurface_glsl_texture = rsurface_texture;
- rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL;
+ rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
+ GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
GL_DepthMask(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED));
GL_Color(rsurface_entity->colormod[0], rsurface_entity->colormod[1], rsurface_entity->colormod[2], rsurface_texture->currentalpha);
+ // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
+ lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
R_SetupSurfaceShader(vec3_origin, lightmode == 2);
//permutation_deluxemapping = permutation_lightmapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, false);
//if (r_glsl_deluxemapping.integer)
R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f);
R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f);
GL_AlphaTest((rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
+ R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
+ R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
+ R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
+ if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
+ {
+ R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
+ if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+ R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+ R_Mesh_ColorPointer(NULL);
+ }
+ else if (rsurface_lightmaptexture)
+ {
+ R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
+ if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+ R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
+ R_Mesh_ColorPointer(NULL);
+ }
+ else
+ {
+ R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
+ if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+ R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+ R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
+ }
}
+ else
+ RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
if (!r_glsl_permutation)
return;
- RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
- R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
- R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
- R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
- if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
- {
- R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
- if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
- R_Mesh_ColorPointer(NULL);
- }
- else if (rsurface_lightmaptexture)
+ if (rsurface_glsl_uselightmap)
{
R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
- R_Mesh_ColorPointer(NULL);
}
- else
+ RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
+ if (rsurface_texture->backgroundnumskinframes && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
{
- R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
- if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
- R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
}
- RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
}
static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **texturesurfacelist)
int layerindex;
const texturelayer_t *layer;
CHECKGLERROR
+ GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
// FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
if (rsurface_mode != RSURFMODE_MULTIPASS)
int layerindex;
const texturelayer_t *layer;
CHECKGLERROR
+ GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
// FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
if (rsurface_mode != RSURFMODE_MULTIPASS)
r_shadow_rtlight = NULL;
r_refdef.stats.entities_surfaces += texturenumsurfaces;
CHECKGLERROR
- GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
- GL_CullFace(((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE)) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
if (r_showsurfaces.integer)
R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist);
else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
{
- int i, j, f, flagsmask;
+ int i, j, k, l, endj, f, flagsmask;
int counttriangles = 0;
+ msurface_t *surface, *endsurface, **surfacechain;
texture_t *t;
+ q3mbrush_t *brush;
model_t *model = ent->model;
+ const int *elements;
const int maxsurfacelist = 1024;
int numsurfacelist = 0;
msurface_t *surfacelist[1024];
+ vec3_t v;
if (model == NULL)
return;
// update light styles
if (!skysurfaces && model->brushq1.light_styleupdatechains)
{
- msurface_t *surface, **surfacechain;
for (i = 0;i < model->brushq1.light_styles;i++)
{
if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
numsurfacelist = 0;
if (ent == r_refdef.worldentity)
{
- msurface_t *surface;
- for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+ j = model->firstmodelsurface;
+ endj = j + model->nummodelsurfaces;
+ while (j < endj)
{
- if (!r_viewcache.world_surfacevisible[j])
- continue;
- if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
+ // quickly skip over non-visible surfaces
+ for (;j < endj && !r_viewcache.world_surfacevisible[j];j++)
+ ;
+ // quickly iterate over visible surfaces
+ for (;j < endj && r_viewcache.world_surfacevisible[j];j++)
{
- if (numsurfacelist)
+ // process this surface
+ surface = model->data_surfaces + j;
+ // if texture or lightmap has changed, start a new batch
+ if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
{
- R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
- numsurfacelist = 0;
+ if (numsurfacelist)
+ {
+ R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
+ numsurfacelist = 0;
+ }
+ t = surface->texture;
+ rsurface_lightmaptexture = surface->lightmaptexture;
+ rsurface_texture = t->currentframe;
+ f = rsurface_texture->currentmaterialflags & flagsmask;
}
- t = surface->texture;
- rsurface_lightmaptexture = surface->lightmaptexture;
- rsurface_texture = t->currentframe;
- f = rsurface_texture->currentmaterialflags & flagsmask;
- }
- if (f && surface->num_triangles)
- {
- // if lightmap parameters changed, rebuild lightmap texture
- if (surface->cached_dlight)
- R_BuildLightMap(ent, surface);
- // add face to draw list
- surfacelist[numsurfacelist++] = surface;
- counttriangles += surface->num_triangles;
- if (numsurfacelist >= maxsurfacelist)
+ // if this surface fits the criteria, add it to the list
+ if (f && surface->num_triangles)
{
- R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
- numsurfacelist = 0;
+ // if lightmap parameters changed, rebuild lightmap texture
+ if (surface->cached_dlight)
+ R_BuildLightMap(ent, surface);
+ // add face to draw list
+ surfacelist[numsurfacelist++] = surface;
+ counttriangles += surface->num_triangles;
+ if (numsurfacelist >= maxsurfacelist)
+ {
+ R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
+ numsurfacelist = 0;
+ }
}
}
}
}
else
{
- msurface_t *surface;
- for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+ surface = model->data_surfaces + model->firstmodelsurface;
+ endsurface = surface + model->nummodelsurfaces;
+ for (;surface < endsurface;surface++)
{
+ // if texture or lightmap has changed, start a new batch
if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
{
if (numsurfacelist)
rsurface_texture = t->currentframe;
f = rsurface_texture->currentmaterialflags & flagsmask;
}
+ // if this surface fits the criteria, add it to the list
if (f && surface->num_triangles)
{
// if lightmap parameters changed, rebuild lightmap texture
if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
{
- int i;
- const msurface_t *surface;
- q3mbrush_t *brush;
CHECKGLERROR
R_Mesh_Matrix(&ent->matrix);
R_Mesh_ColorPointer(NULL);
if (r_showtris.integer || r_shownormals.integer)
{
- int k, l;
- msurface_t *surface;
- const int *elements;
- vec3_t v;
CHECKGLERROR
- GL_DepthTest(true);
+ GL_DepthTest(!r_showdisabledepthtest.integer);
GL_DepthMask(true);
- if (r_showdisabledepthtest.integer)
- {
- qglDepthFunc(GL_ALWAYS);CHECKGLERROR
- }
GL_BlendFunc(GL_ONE, GL_ZERO);
R_Mesh_ColorPointer(NULL);
R_Mesh_ResetTextureState();
}
}
rsurface_texture = NULL;
- if (r_showdisabledepthtest.integer)
- {
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
- }
}
}