cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
+cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "0", "enables alpha-to-coverage antialiasing technique on alphatest surfaces, this is not yet finished as multisampling is not used"};
cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
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_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
+cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
-cvar_t r_track_sprites = {CVAR_SAVE, "r_track_sprites", "1", "track SPR_LABEL* sprites by putting them as indicator at the screen border to rotate to"};
-cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accordingly, 2: Make it a continuous rotation"};
-cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"};
-cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"};
-cvar_t r_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspective", "5", "fake perspective effect for SPR_OVERHEAD sprites"};
-cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "15", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"};
-cvar_t r_overheadsprites_scalex = {CVAR_SAVE, "r_overheadsprites_scalex", "1", "additional scale for overhead sprites for x axis"};
-cvar_t r_overheadsprites_scaley = {CVAR_SAVE, "r_overheadsprites_scaley", "1", "additional scale for overhead sprites for y axis"};
cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
cubemapinfo_t;
int r_texture_numcubemaps;
-cubemapinfo_t r_texture_cubemaps[MAX_CUBEMAPS];
+cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
unsigned int r_queries[MAX_OCCLUSION_QUERIES];
unsigned int r_numqueries;
{
int i;
for (i = 0;i < r_texture_numcubemaps;i++)
- if (!strcasecmp(r_texture_cubemaps[i].basename, basename))
- return r_texture_cubemaps[i].texture ? r_texture_cubemaps[i].texture : r_texture_whitecube;
- if (i >= MAX_CUBEMAPS)
+ if (r_texture_cubemaps[i] != NULL)
+ if (!strcasecmp(r_texture_cubemaps[i]->basename, basename))
+ return r_texture_cubemaps[i]->texture ? r_texture_cubemaps[i]->texture : r_texture_whitecube;
+ if (i >= MAX_CUBEMAPS || !r_main_mempool)
return r_texture_whitecube;
r_texture_numcubemaps++;
- strlcpy(r_texture_cubemaps[i].basename, basename, sizeof(r_texture_cubemaps[i].basename));
- r_texture_cubemaps[i].texture = R_LoadCubemap(r_texture_cubemaps[i].basename);
- return r_texture_cubemaps[i].texture;
+ r_texture_cubemaps[i] = (cubemapinfo_t *)Mem_Alloc(r_main_mempool, sizeof(cubemapinfo_t));
+ strlcpy(r_texture_cubemaps[i]->basename, basename, sizeof(r_texture_cubemaps[i]->basename));
+ r_texture_cubemaps[i]->texture = R_LoadCubemap(r_texture_cubemaps[i]->basename);
+ return r_texture_cubemaps[i]->texture;
+}
+
+void R_FreeCubemap(const char *basename)
+{
+ int i;
+
+ for (i = 0;i < r_texture_numcubemaps;i++)
+ {
+ if (r_texture_cubemaps[i] != NULL)
+ {
+ if (r_texture_cubemaps[i]->texture)
+ {
+ if (developer_loading.integer)
+ Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
+ R_FreeTexture(r_texture_cubemaps[i]->texture);
+ Mem_Free(r_texture_cubemaps[i]);
+ r_texture_cubemaps[i] = NULL;
+ }
+ }
+ }
}
void R_FreeCubemaps(void)
for (i = 0;i < r_texture_numcubemaps;i++)
{
if (developer_loading.integer)
- Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i].basename);
- if (r_texture_cubemaps[i].texture)
- R_FreeTexture(r_texture_cubemaps[i].texture);
+ Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
+ if (r_texture_cubemaps[i] != NULL)
+ {
+ if (r_texture_cubemaps[i]->texture)
+ R_FreeTexture(r_texture_cubemaps[i]->texture);
+ Mem_Free(r_texture_cubemaps[i]);
+ }
}
r_texture_numcubemaps = 0;
}
hlslshaderstring = NULL;
memset(&r_svbsp, 0, sizeof (r_svbsp));
+ memset(r_texture_cubemaps, 0, sizeof(r_texture_cubemaps));
+ r_texture_numcubemaps = 0;
+
r_refdef.fogmasktable_density = 0;
}
Cvar_RegisterVariable(&r_nearclip);
Cvar_RegisterVariable(&r_deformvertexes);
Cvar_RegisterVariable(&r_transparent);
+ Cvar_RegisterVariable(&r_transparent_alphatocoverage);
Cvar_RegisterVariable(&r_showoverdraw);
Cvar_RegisterVariable(&r_showbboxes);
Cvar_RegisterVariable(&r_showsurfaces);
Cvar_RegisterVariable(&r_water_refractdistort);
Cvar_RegisterVariable(&r_water_reflectdistort);
Cvar_RegisterVariable(&r_water_scissormode);
+ Cvar_RegisterVariable(&r_water_lowquality);
+
Cvar_RegisterVariable(&r_lerpsprites);
Cvar_RegisterVariable(&r_lerpmodels);
Cvar_RegisterVariable(&r_lerplightstyles);
if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
-
- Cvar_RegisterVariable(&r_track_sprites);
- Cvar_RegisterVariable(&r_track_sprites_flags);
- Cvar_RegisterVariable(&r_track_sprites_scalew);
- Cvar_RegisterVariable(&r_track_sprites_scaleh);
- Cvar_RegisterVariable(&r_overheadsprites_perspective);
- Cvar_RegisterVariable(&r_overheadsprites_pushback);
- Cvar_RegisterVariable(&r_overheadsprites_scalex);
- Cvar_RegisterVariable(&r_overheadsprites_scaley);
}
extern void R_Textures_Init(void);
//==================================================================================
+extern cvar_t r_overheadsprites_pushback;
+
static void R_View_UpdateEntityLighting (void)
{
int i;
// set waterwidth and waterheight to the water resolution that will be
// used (often less than the screen resolution for faster rendering)
- waterwidth = (int)bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width);
- waterheight = (int)bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height);
+ R_GetScaledViewSize(bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width), bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height), &waterwidth, &waterheight);
// calculate desired texture sizes
// can't use water if the card does not support the texture size
if (r_waterstate.texturewidth)
{
+ int scaledwidth, scaledheight;
+
r_waterstate.enabled = true;
// when doing a reduced render (HDR) we want to use a smaller area
r_waterstate.waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
r_waterstate.waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
+ R_GetScaledViewSize(r_waterstate.waterwidth, r_waterstate.waterheight, &scaledwidth, &scaledheight);
// set up variables that will be used in shader setup
- r_waterstate.screenscale[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
- r_waterstate.screenscale[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
- r_waterstate.screencenter[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
- r_waterstate.screencenter[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
+ r_waterstate.screenscale[0] = 0.5f * (float)scaledwidth / (float)r_waterstate.texturewidth;
+ r_waterstate.screenscale[1] = 0.5f * (float)scaledheight / (float)r_waterstate.textureheight;
+ r_waterstate.screencenter[0] = 0.5f * (float)scaledwidth / (float)r_waterstate.texturewidth;
+ r_waterstate.screencenter[1] = 0.5f * (float)scaledheight / (float)r_waterstate.textureheight;
}
r_waterstate.maxwaterplanes = MAX_WATERPLANES;
}
}
+extern cvar_t r_drawparticles;
+extern cvar_t r_drawdecals;
+
static void R_Water_ProcessPlanes(void)
{
int myscissor[4];
r_refdef_view_t originalview;
r_refdef_view_t myview;
- int planeindex;
+ int planeindex, qualityreduction = 0, old_r_dynamic = 0, old_r_shadows = 0, old_r_worldrtlight = 0, old_r_dlight = 0, old_r_particles = 0, old_r_decals = 0;
r_waterstate_waterplane_t *p;
vec3_t visorigin;
originalview = r_refdef.view;
+ // lowquality hack, temporarily shut down some cvars and restore afterwards
+ qualityreduction = r_water_lowquality.integer;
+ if (qualityreduction > 0)
+ {
+ if (qualityreduction >= 1)
+ {
+ old_r_shadows = r_shadows.integer;
+ old_r_worldrtlight = r_shadow_realtime_world.integer;
+ old_r_dlight = r_shadow_realtime_dlight.integer;
+ Cvar_SetValueQuick(&r_shadows, 0);
+ Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
+ Cvar_SetValueQuick(&r_shadow_realtime_dlight, 0);
+ }
+ if (qualityreduction >= 2)
+ {
+ old_r_dynamic = r_dynamic.integer;
+ old_r_particles = r_drawparticles.integer;
+ old_r_decals = r_drawdecals.integer;
+ Cvar_SetValueQuick(&r_dynamic, 0);
+ Cvar_SetValueQuick(&r_drawparticles, 0);
+ Cvar_SetValueQuick(&r_drawdecals, 0);
+ }
+ }
+
// make sure enough textures are allocated
for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
{
// update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
r_refdef.view.clipplane = p->plane;
-
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.cullface_back = GL_BACK;
R_ResetViewRendering3D();
R_ClearScreen(r_refdef.fogenabled);
R_View_Update();
- return;
+ goto finish;
error:
r_refdef.view = originalview;
r_waterstate.renderingscene = false;
Cvar_SetValueQuick(&r_water, 0);
Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed! Turned off r_water.\n");
- return;
+finish:
+ // lowquality hack, restore cvars
+ if (qualityreduction > 0)
+ {
+ if (qualityreduction >= 1)
+ {
+ Cvar_SetValueQuick(&r_shadows, old_r_shadows);
+ Cvar_SetValueQuick(&r_shadow_realtime_world, old_r_worldrtlight);
+ Cvar_SetValueQuick(&r_shadow_realtime_dlight, old_r_dlight);
+ }
+ if (qualityreduction >= 2)
+ {
+ Cvar_SetValueQuick(&r_dynamic, old_r_dynamic);
+ Cvar_SetValueQuick(&r_drawparticles, old_r_particles);
+ Cvar_SetValueQuick(&r_drawdecals, old_r_decals);
+ }
+ }
}
void R_Bloom_StartFrame(void)
if (edict->priv.server->free)
continue;
// exclude the following for now, as they don't live in world coordinate space and can't be solid:
- if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.tag_entity)->edict != 0)
+ if(PRVM_serveredictedict(edict, tag_entity) != 0)
continue;
- if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.viewmodelforclient)->edict != 0)
+ if(PRVM_serveredictedict(edict, viewmodelforclient) != 0)
continue;
VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
GL_DepthMask(true);
R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL);
RSurf_DrawBatch();
- return;
}
// bind lightmap texture
// render surface batch normally
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL);
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
+ GL_AlphaTest(true);
RSurf_DrawBatch();
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
+ GL_AlphaTest(false);
}
static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)