From 9b023749daa61f98fdc340ded4ba21490a579631 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Tue, 10 Sep 2019 18:58:03 +0100 Subject: [PATCH] Quick attempt at skyrooms. Seems to work for me. Note that the server's pvs is not opened, nor have I tried to depthmask sky surfaces to avoid leakage. _skyroom "x y z" in worldspawn to use. --- Quake/gl_rmain.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- Quake/gl_sky.c | 19 +++++++++++++++++-- Quake/glquake.h | 3 +++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Quake/gl_rmain.c b/Quake/gl_rmain.c index 261b47b9..8694d011 100644 --- a/Quake/gl_rmain.c +++ b/Quake/gl_rmain.c @@ -530,7 +530,7 @@ void R_Clear (void) // from mh -- if we get a stencil buffer, we should clear it, even though we don't use it if (gl_stencilbits) clearbits |= GL_STENCIL_BUFFER_BIT; - if (gl_clear.value) + if (gl_clear.value && !skyroom_drawn) clearbits |= GL_COLOR_BUFFER_BIT; glClear (clearbits); } @@ -591,7 +591,8 @@ void R_SetupView (void) R_CullSurfaces (); //johnfitz -- do after R_SetFrustum and R_MarkSurfaces - R_UpdateWarpTextures (); //johnfitz -- do this before R_Clear + if (!skyroom_drawn) + R_UpdateWarpTextures (); //johnfitz -- do this before R_Clear R_Clear (); @@ -1069,6 +1070,22 @@ void R_ScaleView (void) GL_ClearBindings (); } +static qboolean R_SkyroomWasVisible(void) +{ + qmodel_t *model = cl.worldmodel; + texture_t *t; + size_t i; + if (!skyroom_enabled) + return false; + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (t && t->texturechains[chain_world] && t->texturechains[chain_world]->flags & SURF_DRAWSKY) + return true; + } + return false; +} + /* ================ R_RenderView @@ -1076,6 +1093,7 @@ R_RenderView */ void R_RenderView (void) { + static qboolean skyroom_visible; double time1, time2; if (r_norefresh.value) @@ -1097,6 +1115,23 @@ void R_RenderView (void) else if (gl_finish.value) glFinish (); + //Spike -- quickly draw the world from the skyroom camera's point of view. + skyroom_drawn = false; + if (skyroom_enabled && skyroom_visible) + { + vec3_t vieworg; + VectorCopy(r_refdef.vieworg, vieworg); + VectorCopy(skyroom_origin, r_refdef.vieworg); + R_SetupView (); + //note: sky boxes are generally considered an 'infinite' distance away such that you'd not see paralax. + //that's my excuse for not handling r_stereo here, and I'm sticking to it. + R_RenderScene (); + + VectorCopy(vieworg, r_refdef.vieworg); + skyroom_drawn = true; //disable glClear(GL_COLOR_BUFFER_BIT) + } + //skyroom end + R_SetupView (); //johnfitz -- this does everything that should be done once per frame //johnfitz -- stereo rendering -- full of hacky goodness @@ -1135,6 +1170,14 @@ void R_RenderView (void) } //johnfitz + //Spike: flag whether the skyroom was actually visible, so we don't needlessly draw it when its not (1 frame's lag, hopefully not too noticable) + if (r_viewleaf->contents == CONTENTS_SOLID || r_drawflat_cheatsafe || r_lightmap_cheatsafe) + skyroom_visible = false; //don't do skyrooms when the view is in the void, for framerate reasons while debugging. + else + skyroom_visible = R_SkyroomWasVisible(); + skyroom_drawn = false; + //skyroom end + R_ScaleView (); //johnfitz -- modified r_speeds output diff --git a/Quake/gl_sky.c b/Quake/gl_sky.c index 34155e81..b9912d21 100644 --- a/Quake/gl_sky.c +++ b/Quake/gl_sky.c @@ -35,6 +35,10 @@ extern int rs_skypasses; //for r_speeds readout float skyflatcolor[3]; float skymins[2][6], skymaxs[2][6]; +qboolean skyroom_drawn; +qboolean skyroom_enabled; +vec3_t skyroom_origin; + char skybox_name[1024]; //name of current skybox, or "" if no skybox gltexture_t *skybox_textures[6]; @@ -225,6 +229,7 @@ void Sky_NewMap (void) // // initially no sky // + skyroom_enabled = false; skybox_name[0] = 0; for (i=0; i<6; i++) skybox_textures[i] = NULL; @@ -263,8 +268,18 @@ void Sky_NewMap (void) if (!strcmp("sky", key)) Sky_LoadSkyBox(value); + else if (!strcmp("skyroom", key)) + { //"_skyroom" "X Y Z". ideally the gamecode would do this with an entity, but people want to use the vanilla gamecode from 1996 for some reason. + const char *t = COM_Parse(value); + skyroom_origin[0] = atof(com_token); + t = COM_Parse(t); + skyroom_origin[1] = atof(com_token); + t = COM_Parse(t); + skyroom_origin[2] = atof(com_token); + skyroom_enabled = true; + } - if (!strcmp("skyfog", key)) + else if (!strcmp("skyfog", key)) skyfog = atof(value); #if 1 //also accept non-standard keys @@ -986,7 +1001,7 @@ void Sky_DrawSky (void) int i; //in these special render modes, the sky faces are handled in the normal world/brush renderer - if (r_drawflat_cheatsafe || r_lightmap_cheatsafe ) + if (r_drawflat_cheatsafe || r_lightmap_cheatsafe || skyroom_drawn) return; // diff --git a/Quake/glquake.h b/Quake/glquake.h index bfaf29fa..42a5ca38 100644 --- a/Quake/glquake.h +++ b/Quake/glquake.h @@ -433,6 +433,9 @@ void Sky_DrawSky (void); void Sky_NewMap (void); void Sky_LoadTexture (texture_t *mt); void Sky_LoadSkyBox (const char *name); +extern qboolean skyroom_drawn; //we draw a skyroom this frame +extern qboolean skyroom_enabled; //we know where the skyroom is ... +extern vec3_t skyroom_origin; //... and it is here. void TexMgr_RecalcWarpImageSize (void);