X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_rmain.c;h=9c0dfd0d027413989bf2c6981e84a7d34829712f;hp=35e975988dd9d1f10847ae27af8061fd7672bc38;hb=9308068bbd92e3d211fabba4a451c09235688c4a;hpb=57aa864e165668e67f943c09a963bace2e2643e0 diff --git a/gl_rmain.c b/gl_rmain.c index 35e97598..9c0dfd0d 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // r_main.c #include "quakedef.h" +#include "r_shadow.h" // used for dlight push checking and other things int r_framecount; @@ -38,12 +39,22 @@ qboolean envmap; float r_farclip; +// forces all rendering to draw triangle outlines +int r_showtrispass; + // view origin vec3_t r_vieworigin; vec3_t r_viewforward; vec3_t r_viewleft; vec3_t r_viewright; vec3_t r_viewup; +int r_view_x; +int r_view_y; +int r_view_width; +int r_view_height; +float r_view_fov_x; +float r_view_fov_y; +matrix4x4_t r_view_matrix; // // screen size info @@ -53,15 +64,14 @@ refdef_t r_refdef; // 8.8 fraction of base light value unsigned short d_lightstylevalue[256]; +cvar_t r_showtris = {0, "r_showtris", "0"}; cvar_t r_drawentities = {0, "r_drawentities","1"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"}; -cvar_t r_shadow_staticworldlights = {0, "r_shadow_staticworldlights", "1"}; cvar_t r_speeds = {0, "r_speeds","0"}; cvar_t r_fullbright = {0, "r_fullbright","0"}; cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"}; cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"}; cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"}; -cvar_t r_shadow_cull = {0, "r_shadow_cull", "1"}; cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"}; cvar_t gl_fogenable = {0, "gl_fogenable", "0"}; @@ -142,7 +152,7 @@ vec_t fogdensity; float fog_density, fog_red, fog_green, fog_blue; qboolean fogenabled; qboolean oldgl_fogenable; -void R_SetupFog(void) +void R_UpdateFog(void) { if (gamemode == GAME_NEHAHRA) { @@ -247,48 +257,35 @@ void GL_Main_Init(void) // FIXME: move this to client? FOG_registercvars(); Cmd_AddCommand("timerefresh", R_TimeRefresh_f); + Cvar_RegisterVariable(&r_showtris); Cvar_RegisterVariable(&r_drawentities); Cvar_RegisterVariable(&r_drawviewmodel); - Cvar_RegisterVariable(&r_shadow_staticworldlights); Cvar_RegisterVariable(&r_speeds); Cvar_RegisterVariable(&r_fullbrights); Cvar_RegisterVariable(&r_wateralpha); Cvar_RegisterVariable(&r_dynamic); Cvar_RegisterVariable(&r_fullbright); Cvar_RegisterVariable(&r_textureunits); - Cvar_RegisterVariable(&r_shadow_cull); Cvar_RegisterVariable(&r_lerpsprites); Cvar_RegisterVariable(&r_lerpmodels); Cvar_RegisterVariable(&r_waterscroll); Cvar_RegisterVariable(&r_watershader); Cvar_RegisterVariable(&r_drawcollisionbrushes); - if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ) + if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE) Cvar_SetValue("r_fullbrights", 0); R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap); } -vec3_t r_farclip_origin; -vec3_t r_farclip_direction; -vec_t r_farclip_directiondist; -vec_t r_farclip_meshfarclip; -int r_farclip_directionbit0; -int r_farclip_directionbit1; -int r_farclip_directionbit2; - -// start a farclip measuring session -void R_FarClip_Start(vec3_t origin, vec3_t direction, vec_t startfarclip) -{ - VectorCopy(origin, r_farclip_origin); - VectorCopy(direction, r_farclip_direction); - r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction); - r_farclip_directionbit0 = r_farclip_direction[0] < 0; - r_farclip_directionbit1 = r_farclip_direction[1] < 0; - r_farclip_directionbit2 = r_farclip_direction[2] < 0; - r_farclip_meshfarclip = r_farclip_directiondist + startfarclip; -} +static vec3_t r_farclip_origin; +static vec3_t r_farclip_direction; +static vec_t r_farclip_directiondist; +static vec_t r_farclip_meshfarclip; +static int r_farclip_directionbit0; +static int r_farclip_directionbit1; +static int r_farclip_directionbit2; // enlarge farclip to accomodate box -void R_FarClip_Box(vec3_t mins, vec3_t maxs) +static void R_FarClip_Box(vec3_t mins, vec3_t maxs) { float d; d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0] @@ -299,8 +296,23 @@ void R_FarClip_Box(vec3_t mins, vec3_t maxs) } // return farclip value -float R_FarClip_Finish(void) +static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip) { + int i; + + VectorCopy(origin, r_farclip_origin); + VectorCopy(direction, r_farclip_direction); + r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction); + r_farclip_directionbit0 = r_farclip_direction[0] < 0; + r_farclip_directionbit1 = r_farclip_direction[1] < 0; + r_farclip_directionbit2 = r_farclip_direction[2] < 0; + r_farclip_meshfarclip = r_farclip_directiondist + startfarclip; + + if (cl.worldmodel) + R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs); + for (i = 0;i < r_refdef.numentities;i++) + R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs); + return r_farclip_meshfarclip - r_farclip_directiondist; } @@ -404,8 +416,6 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs) return false; } -#define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (cl.worldmodel && cl.worldmodel->brush.BoxTouchingPVS && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, r_pvsbits, (mins), (maxs)))) - //================================================================================== static void R_MarkEntities (void) @@ -417,9 +427,6 @@ static void R_MarkEntities (void) Matrix4x4_CreateIdentity(&ent->matrix); Matrix4x4_CreateIdentity(&ent->inversematrix); - if (cl.worldmodel) - R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs); - if (!r_drawentities.integer) return; @@ -436,10 +443,7 @@ static void R_MarkEntities (void) if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL)) && !VIS_CullBox(ent->mins, ent->maxs) && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL)))) - { ent->visframe = r_framecount; - R_FarClip_Box(ent->mins, ent->maxs); - } } } @@ -511,296 +515,37 @@ void R_DrawModels(void) } } -#include "r_shadow.h" - -int shadowframecount = 0; - -void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t lightmins, vec3_t lightmaxs, vec3_t clipmins, vec3_t clipmaxs, int lightmarked) -{ - vec3_t relativelightorigin; - // rough checks - if ((ent->flags & RENDER_SHADOW) && ent->model && ent->model->DrawShadowVolume && !(r_shadow_cull.integer && (ent->maxs[0] < lightmins[0] || ent->mins[0] > lightmaxs[0] || ent->maxs[1] < lightmins[1] || ent->mins[1] > lightmaxs[1] || ent->maxs[2] < lightmins[2] || ent->mins[2] > lightmaxs[2]))) - { - Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin); - ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius); - } -} - -void R_Shadow_DrawWorldLightShadowVolume(matrix4x4_t *matrix, worldlight_t *light); - -void R_ShadowVolumeLighting(int visiblevolumes) +static void R_SetFrustum(void) { - int i; - entity_render_t *ent; - int lnum; - float f, lightradius, cullradius; - vec3_t relativelightorigin, relativeeyeorigin, lightcolor, clipmins, clipmaxs; - worldlight_t *wl; - rdlight_t *rd; - rmeshstate_t m; - matrix4x4_t matrix; - matrix4x4_t matrix_worldtofilter, matrix_worldtoattenuationxyz, matrix_worldtoattenuationz; - matrix4x4_t matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz; - - if (visiblevolumes) - { - memset(&m, 0, sizeof(m)); - R_Mesh_State_Texture(&m); - - GL_BlendFunc(GL_ONE, GL_ONE); - GL_DepthMask(false); - GL_DepthTest(r_shadow_visiblevolumes.integer < 2); - qglDisable(GL_CULL_FACE); - GL_Color(0.0, 0.0125, 0.1, 1); - } - else - R_Shadow_Stage_Begin(); - shadowframecount++; - if (r_shadow_realtime_world.integer) - { - R_Shadow_LoadWorldLightsIfNeeded(); - for (lnum = 0, wl = r_shadow_worldlightchain;wl;wl = wl->next, lnum++) - { - if (d_lightstylevalue[wl->style] <= 0) - continue; - if (VIS_CullBox(wl->mins, wl->maxs)) - continue; - if (r_shadow_debuglight.integer >= 0 && lnum != r_shadow_debuglight.integer) - continue; - if (R_Shadow_ScissorForBBox(wl->mins, wl->maxs)) - continue; - - cullradius = wl->cullradius; - lightradius = wl->lightradius; - VectorCopy(wl->mins, clipmins); - VectorCopy(wl->maxs, clipmaxs); - - f = d_lightstylevalue[wl->style] * (1.0f / 256.0f); - VectorScale(wl->light, f, lightcolor); - if (wl->selected) - { - f = 2 + sin(realtime * M_PI * 4.0); - VectorScale(lightcolor, f, lightcolor); - } - - if (r_shadow_worldshadows.integer && wl->castshadows && (gl_stencil || visiblevolumes)) - { - if (!visiblevolumes) - R_Shadow_Stage_ShadowVolumes(); - ent = &cl_entities[0].render; - if (r_shadow_staticworldlights.integer) - R_Shadow_DrawStaticWorldLight_Shadow(wl, &ent->matrix); - else - R_TestAndDrawShadowVolume(ent, wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs, true); - if (r_drawentities.integer) - for (i = 0;i < r_refdef.numentities;i++) - R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs, true); - } - - if (!visiblevolumes) - { - if (r_shadow_worldshadows.integer && wl->castshadows && gl_stencil) - R_Shadow_Stage_LightWithShadows(); - else - R_Shadow_Stage_LightWithoutShadows(); - - // calculate world to filter matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - - ent = &cl_entities[0].render; - if (ent->model && ent->model->DrawLight) - { - Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - if (r_shadow_staticworldlights.integer) - R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); - else - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); - } - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight - && BoxesOverlap(ent->mins, ent->maxs, clipmins, clipmaxs) - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - { - Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); - } - } - } - } - } - } - if (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) - { - for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++) - { - lightradius = rd->cullradius; - clipmins[0] = rd->origin[0] - lightradius; - clipmins[1] = rd->origin[1] - lightradius; - clipmins[2] = rd->origin[2] - lightradius; - clipmaxs[0] = rd->origin[0] + lightradius; - clipmaxs[1] = rd->origin[1] + lightradius; - clipmaxs[2] = rd->origin[2] + lightradius; - if (VIS_CullBox(clipmins, clipmaxs) || R_Shadow_ScissorForBBox(clipmins, clipmaxs)) - continue; - - cullradius = RadiusFromBoundsAndOrigin(clipmins, clipmaxs, rd->origin); - VectorScale(rd->light, (1.0f / 4096.0f), lightcolor); - - if (r_shadow_dlightshadows.integer && (gl_stencil || visiblevolumes)) - { - if (!visiblevolumes) - R_Shadow_Stage_ShadowVolumes(); - ent = &cl_entities[0].render; - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs, false); - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent != rd->ent) - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs, false); - } - } - } - - if (!visiblevolumes) - { - if (r_shadow_dlightshadows.integer && gl_stencil) - R_Shadow_Stage_LightWithShadows(); - else - R_Shadow_Stage_LightWithoutShadows(); - - // calculate world to filter matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, rd->origin[0], rd->origin[1], rd->origin[2], 0, 0, 0, lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - - ent = &cl_entities[0].render; - if (ent->model && ent->model->DrawLight) - { - Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); - } - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight - && BoxesOverlap(ent->mins, ent->maxs, clipmins, clipmaxs) - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - { - Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); - } - } - } - } - } - } - - if (visiblevolumes) - { - qglEnable(GL_CULL_FACE); - qglDisable(GL_SCISSOR_TEST); - } - else - R_Shadow_Stage_End(); -} + // break apart the view matrix into vectors for various purposes + Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin); + VectorNegate(r_viewleft, r_viewright); -static void R_SetFrustum (void) -{ // LordHavoc: note to all quake engine coders, the special case for 90 // degrees assumed a square view (wrong), so I removed it, Quake2 has it // disabled as well. // rotate R_VIEWFORWARD right by FOV_X/2 degrees - RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2)); + RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2)); frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal); PlaneClassify(&frustum[0]); // rotate R_VIEWFORWARD left by FOV_X/2 degrees - RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2)); + RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2)); frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal); PlaneClassify(&frustum[1]); // rotate R_VIEWFORWARD up by FOV_X/2 degrees - RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2)); + RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2)); frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal); PlaneClassify(&frustum[2]); // rotate R_VIEWFORWARD down by FOV_X/2 degrees - RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2)); + RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2)); frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal); PlaneClassify(&frustum[3]); } -/* -=============== -R_SetupFrame -=============== -*/ -static void R_SetupFrame (void) -{ -// don't allow cheats in multiplayer - if (!cl.islocalgame) - { - if (r_fullbright.integer != 0) - Cvar_Set ("r_fullbright", "0"); - if (r_ambient.value != 0) - Cvar_Set ("r_ambient", "0"); - } - - r_framecount++; - - // break apart the viewentity matrix into vectors for various purposes - Matrix4x4_ToVectors(&r_refdef.viewentitymatrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin); - VectorNegate(r_viewleft, r_viewright); - - GL_SetupView_ViewPort(r_refdef.x, r_refdef.y, r_refdef.width, r_refdef.height); - - R_AnimateLight(); -} - - static void R_BlendView(void) { rmeshstate_t m; @@ -833,69 +578,132 @@ static void R_BlendView(void) R_Mesh_Draw(3, 1, polygonelements); } +void R_UpdateWorld(void) +{ + if (!r_refdef.entities/* || !cl.worldmodel*/) + return; //Host_Error ("R_RenderView: NULL worldmodel"); + + if (r_shadow_realtime_world.integer && !gl_stencil) + { + Con_Printf("Realtime world lighting requires 32bit color; turning off r_shadow_realtime_world, please type vid_bitsperpixel 32;vid_restart and try again\n"); + Cvar_SetValueQuick(&r_shadow_realtime_world, 0); + } + + // don't allow cheats in multiplayer + if (!cl.islocalgame) + { + if (r_fullbright.integer != 0) + Cvar_Set ("r_fullbright", "0"); + if (r_ambient.value != 0) + Cvar_Set ("r_ambient", "0"); + } + + R_Textures_Frame(); + R_UpdateFog(); + R_UpdateLights(); +} + +void R_RenderScene(void); + /* ================ R_RenderView - -r_refdef must be set before the first call ================ */ -extern void R_DrawLightningBeams (void); -void R_RenderView (void) +void R_RenderView(void) { - entity_render_t *world; if (!r_refdef.entities/* || !cl.worldmodel*/) return; //Host_Error ("R_RenderView: NULL worldmodel"); + + r_view_width = bound(0, r_refdef.width, vid.realwidth); + r_view_height = bound(0, r_refdef.height, vid.realheight); + r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width); + r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height); + r_view_fov_x = bound(1, r_refdef.fov_x, 170); + r_view_fov_y = bound(1, r_refdef.fov_y, 170); + r_view_matrix = r_refdef.viewentitymatrix; + + // GL is weird because it's bottom to top, r_view_y is top to bottom + qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height); + GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height); + GL_ScissorTest(true); + R_ClearScreen(); + + R_Mesh_Start(); + R_TimeReport("setup"); - if (r_shadow_realtime_world.integer) + qglDepthFunc(GL_LEQUAL); + qglPolygonOffset(0, 0); + qglEnable(GL_POLYGON_OFFSET_FILL); + + R_RenderScene(); + if (r_showtris.integer) { - if (!gl_stencil) - { - Con_Printf("Realtime world lighting requires 32bit color turning off r_shadow_realtime_world, please type vid_bitsperpixel 32;vid_restart and try again\n"); - Cvar_SetValueQuick(&r_shadow_realtime_world, 0); - } + rmeshstate_t m; + GL_Color(1,1,1,1); + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthTest(GL_FALSE); + GL_DepthMask(GL_FALSE); + memset(&m, 0, sizeof(m)); + R_Mesh_State_Texture(&m); + r_showtrispass = true; + R_RenderScene(); + r_showtrispass = false; } - world = &cl_entities[0].render; + qglPolygonOffset(0, 0); + qglDisable(GL_POLYGON_OFFSET_FILL); - // FIXME: move to client - R_MoveExplosions(); - R_TimeReport("mexplosion"); + R_BlendView(); + R_TimeReport("blendview"); + + R_Mesh_Finish(); + R_TimeReport("meshfinish"); - qglPolygonOffset(0, 0); - qglEnable(GL_POLYGON_OFFSET_FILL); + GL_Scissor(0, 0, vid.realwidth, vid.realheight); + GL_ScissorTest(false); +} + +extern void R_DrawLightningBeams (void); +void R_RenderScene(void) +{ + entity_render_t *world; + + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); + + r_framecount++; - R_Textures_Frame(); - R_SetupFrame(); R_SetFrustum(); - R_SetupFog(); + + r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f; + if (gl_stencil && ((r_shadow_realtime_world.integer && r_shadow_worldshadows.integer) || ((r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && r_shadow_dlightshadows.integer))) + GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f); + else + GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip); + + GL_SetupView_Orientation_FromEntity(&r_view_matrix); + R_SkyStartFrame(); - R_BuildLightList(); - R_TimeReport("setup"); if (cl.worldmodel && cl.worldmodel->brush.FatPVS) cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits)); - + world = &cl_entities[0].render; R_WorldVisibility(world); R_TimeReport("worldvis"); - R_FarClip_Start(r_vieworigin, r_viewforward, 768.0f); R_MarkEntities(); - r_farclip = R_FarClip_Finish() + 256.0f; - if (gl_stencil && ((r_shadow_realtime_world.integer && r_shadow_worldshadows.integer) || ((r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && r_shadow_dlightshadows.integer))) - GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.fov_x, r_refdef.fov_y, 1.0f); - else - GL_SetupView_Mode_Perspective(r_refdef.fov_x, r_refdef.fov_y, 1.0f, r_farclip); - GL_SetupView_Orientation_FromEntity(&r_refdef.viewentitymatrix); R_TimeReport("markentity"); - qglDepthFunc(GL_LEQUAL); - - R_Mesh_Start(); R_MeshQueue_BeginScene(); R_Shadow_UpdateWorldLightSelection(); + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); + if (R_DrawBrushModelsSky()) R_TimeReport("bmodelsky"); @@ -910,9 +718,17 @@ void R_RenderView (void) R_DrawModels(); R_TimeReport("models"); + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); + R_ShadowVolumeLighting(false); R_TimeReport("rtlights"); + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); + R_DrawLightningBeams(); R_TimeReport("lightning"); @@ -931,9 +747,6 @@ void R_RenderView (void) R_DrawWorldCrosshair(); R_TimeReport("crosshair"); - R_BlendView(); - R_TimeReport("blendview"); - R_MeshQueue_Render(); R_MeshQueue_EndScene(); @@ -943,11 +756,9 @@ void R_RenderView (void) R_TimeReport("shadowvolume"); } - R_Mesh_Finish(); - R_TimeReport("meshfinish"); - - qglPolygonOffset(0, 0); - qglDisable(GL_POLYGON_OFFSET_FILL); + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); } /*