From ef12f815c93e72a119837d2ff37d6258d78bf45e Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 5 Aug 2002 13:28:26 +0000 Subject: [PATCH] a rather hefty 6% speed gain by getting rid of the R_Mesh_UpdateFarClip function, and reorganizing it to use bounding boxes instead (outside of gl_backend even) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2203 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_backend.c | 56 +++++++------------- gl_backend.h | 2 +- gl_rmain.c | 145 +++++++++++++++++++++++++++++++++------------------ r_sky.c | 20 ++++--- render.h | 13 ++++- 5 files changed, 138 insertions(+), 98 deletions(-) diff --git a/gl_backend.c b/gl_backend.c index b991a9e6..0cc530dc 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -69,17 +69,19 @@ void GL_PrintError(int errornumber, char *filename, int linenumber) } #endif -float r_farclip, r_newfarclip; +float r_mesh_farclip; int polyindexarray[768]; static float viewdist; +// sign bits (true if negative) for vpn[] entries, so quick integer compares can be used instead of float compares +static int vpnbit0, vpnbit1, vpnbit2; int c_meshs, c_meshtris, c_transmeshs, c_transtris; -int lightscalebit; -float lightscale; -float overbrightscale; +int lightscalebit; +float lightscale; +float overbrightscale; void SCR_ScreenShot_f (void); @@ -145,7 +147,6 @@ typedef struct } buf_texcoord_t; -static float meshfarclip; static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, transranout; static buf_mesh_t *buf_mesh; static buf_tri_t *buf_tri; @@ -297,7 +298,6 @@ static void gl_backend_bufferchanges(int init) static void gl_backend_newmap(void) { - r_farclip = r_newfarclip = 2048.0f; } void gl_backend_init(void) @@ -358,9 +358,6 @@ static void GL_SetupFrame (void) double xmax, ymax; double fovx, fovy, zNear, zFar, aspect; - // update farclip based on previous frame - r_farclip = r_newfarclip; - if (!r_render.integer) return; @@ -375,7 +372,7 @@ static void GL_SetupFrame (void) // depth range zNear = 1.0; - zFar = r_farclip; + zFar = r_mesh_farclip; // fov angles fovx = r_refdef.fov_x; @@ -498,7 +495,7 @@ void GL_SetupTextureState(void) // called at beginning of frame int usedarrays; -void R_Mesh_Start(void) +void R_Mesh_Start(float farclip) { int i; if (!backendactive) @@ -514,9 +511,12 @@ void R_Mesh_Start(void) currenttransmesh = 0; currenttranstriangle = 0; currenttransvertex = 0; - meshfarclip = 0; transranout = false; + r_mesh_farclip = farclip; viewdist = DotProduct(r_origin, vpn); + vpnbit0 = vpn[0] < 0; + vpnbit1 = vpn[1] < 0; + vpnbit2 = vpn[2] < 0; c_meshs = 0; c_meshtris = 0; @@ -572,27 +572,6 @@ void R_Mesh_Start(void) int gl_backend_rebindtextures; -void GL_UpdateFarclip(void) -{ - int i; - float farclip; - - // push out farclip based on vertices - // FIXME: wouldn't this be slow when using matrix transforms? - for (i = 0;i < currentvertex;i++) - { - farclip = DotProduct(buf_vertex[i].v, vpn); - if (meshfarclip < farclip) - meshfarclip = farclip; - } - - farclip = meshfarclip + 256.0f - viewdist; // + 256 just to be safe - - // push out farclip for next frame - if (farclip > r_newfarclip) - r_newfarclip = ceil((farclip + 255) / 256) * 256 + 256; -} - void GL_ConvertColorsFloatToByte(void) { int i, k, total; @@ -821,8 +800,6 @@ void R_Mesh_Render(void) CHECKGLERROR - GL_UpdateFarclip(); - // drawmode 0 always uses byte colors if (!gl_mesh_floatcolors.integer || gl_mesh_drawmode.integer <= 0) GL_ConvertColorsFloatToByte(); @@ -921,10 +898,13 @@ void R_Mesh_Finish(void) void R_Mesh_ClearDepth(void) { - R_Mesh_AddTransparent(); + if (currenttransmesh) + R_Mesh_AddTransparent(); + if (currentmesh) + R_Mesh_Render(); R_Mesh_Finish(); qglClear(GL_DEPTH_BUFFER_BIT); - R_Mesh_Start(); + R_Mesh_Start(r_mesh_farclip); } void R_Mesh_AddTransparent(void) @@ -955,7 +935,7 @@ void R_Mesh_AddTransparent(void) } // map farclip to 0-4095 list range - centerscaler = (TRANSDEPTHRES / r_farclip) * (1.0f / 3.0f); + centerscaler = (TRANSDEPTHRES / r_mesh_farclip) * (1.0f / 3.0f); viewdistcompare = viewdist + 4.0f; memset(buf_sorttranstri_list, 0, TRANSDEPTHRES * sizeof(buf_transtri_t *)); diff --git a/gl_backend.h b/gl_backend.h index be9ecf7d..e7183ad0 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -54,7 +54,7 @@ rmeshbufferinfo_t; void gl_backend_init(void); // starts mesh rendering for the frame -void R_Mesh_Start(void); +void R_Mesh_Start(float farclip); // ends mesh rendering for the frame // (only valid after R_Mesh_Start) diff --git a/gl_rmain.c b/gl_rmain.c index 8ec79d52..3c20a454 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -21,49 +21,52 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -entity_render_t *currentrenderentity; +entity_render_t *currentrenderentity; -int r_framecount; // used for dlight push checking +// used for dlight push checking and other things +int r_framecount; -mplane_t frustum[4]; +mplane_t frustum[4]; -int c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights; +int c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights; -qboolean envmap; // true during envmap command capture +// true during envmap command capture +qboolean envmap; + +float r_farclip; -// // view origin -// -vec3_t vup; -vec3_t vpn; -vec3_t vright; -vec3_t r_origin; +vec3_t r_origin; +vec3_t vpn; +vec3_t vright; +vec3_t vup; // // screen size info // -refdef_t r_refdef; - -mleaf_t *r_viewleaf, *r_oldviewleaf; - -unsigned short d_lightstylevalue[256]; // 8.8 fraction of base light value - -cvar_t r_drawentities = {0, "r_drawentities","1"}; -cvar_t r_drawviewmodel = {0, "r_drawviewmodel","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_waterripple = {CVAR_SAVE, "r_waterripple","0"}; -cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"}; - -cvar_t gl_fogenable = {0, "gl_fogenable", "0"}; -cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"}; -cvar_t gl_fogred = {0, "gl_fogred","0.3"}; -cvar_t gl_foggreen = {0, "gl_foggreen","0.3"}; -cvar_t gl_fogblue = {0, "gl_fogblue","0.3"}; -cvar_t gl_fogstart = {0, "gl_fogstart", "0"}; -cvar_t gl_fogend = {0, "gl_fogend","0"}; +refdef_t r_refdef; + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +// 8.8 fraction of base light value +unsigned short d_lightstylevalue[256]; + +cvar_t r_drawentities = {0, "r_drawentities","1"}; +cvar_t r_drawviewmodel = {0, "r_drawviewmodel","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_waterripple = {CVAR_SAVE, "r_waterripple","0"}; +cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"}; + +cvar_t gl_fogenable = {0, "gl_fogenable", "0"}; +cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"}; +cvar_t gl_fogred = {0, "gl_fogred","0.3"}; +cvar_t gl_foggreen = {0, "gl_foggreen","0.3"}; +cvar_t gl_fogblue = {0, "gl_fogblue","0.3"}; +cvar_t gl_fogstart = {0, "gl_fogstart", "0"}; +cvar_t gl_fogend = {0, "gl_fogend","0"}; cvar_t r_multitexture = {0, "r_multitexture", "1"}; @@ -77,8 +80,8 @@ For program optimization qboolean intimerefresh = 0; static void R_TimeRefresh_f (void) { - int i; - float start, stop, time; + int i; + float start, stop, time; intimerefresh = 1; start = Sys_DoubleTime (); @@ -245,6 +248,43 @@ void GL_Main_Init(void) 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; +} + +// enlarge farclip to accomodate box +void R_FarClip_Box(vec3_t mins, vec3_t maxs) +{ + float d; + d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0] + + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1] + + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2]; + if (r_farclip_meshfarclip < d) + r_farclip_meshfarclip = d; +} + +// return farclip value +float R_FarClip_Finish(void) +{ + return r_farclip_meshfarclip - r_farclip_directiondist; +} + /* =============== R_NewMap @@ -253,15 +293,17 @@ R_NewMap void CL_ParseEntityLump(char *entitystring); void R_NewMap (void) { - int i; + int i; - for (i=0 ; i<256 ; i++) + for (i = 0;i < 256;i++) d_lightstylevalue[i] = 264; // normal light value r_viewleaf = NULL; if (cl.worldmodel->entities) CL_ParseEntityLump(cl.worldmodel->entities); R_Modules_NewMap(); + + r_farclip = 64.0f; } extern void R_Textures_Init(void); @@ -317,19 +359,16 @@ void GL_Init (void) //================================================================================== -void R_Entity_Callback(void *data, void *junk) -{ - ((entity_render_t *)data)->visframe = r_framecount; -} - static void R_MarkEntities (void) { - int i; - vec3_t v; + int i; + vec3_t v; if (!r_drawentities.integer) return; + R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs); + for (i = 0;i < r_refdef.numentities;i++) { currentrenderentity = r_refdef.entities[i]; @@ -369,17 +408,20 @@ static void R_MarkEntities (void) R_LerpAnimation(currentrenderentity); currentrenderentity->visframe = r_framecount; + + R_FarClip_Box(currentrenderentity->mins, currentrenderentity->maxs); } } // only used if skyrendermasked, and normally returns false int R_DrawBModelSky (void) { - int i, sky = false; + int i, sky; if (!r_drawentities.integer) return false; + sky = false; for (i = 0;i < r_refdef.numentities;i++) { currentrenderentity = r_refdef.entities[i]; @@ -394,7 +436,7 @@ int R_DrawBModelSky (void) void R_DrawModels (void) { - int i; + int i; if (!r_drawentities.integer) return; @@ -428,7 +470,7 @@ void R_DrawViewModel (void) static void R_SetFrustum (void) { - int i; + int i; // 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 @@ -442,8 +484,7 @@ static void R_SetFrustum (void) // rotate VPN down by FOV_X/2 degrees RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) ); - - for (i=0 ; i<4 ; i++) + for (i = 0;i < 4;i++) { frustum[i].type = PLANE_ANYZ; frustum[i].dist = DotProduct (r_origin, frustum[i].normal); @@ -544,7 +585,7 @@ void R_RenderView (void) R_SkyStartFrame(); R_BuildLightList(); - R_Mesh_Start(); + R_FarClip_Start(r_origin, vpn, 768.0f); R_TimeReport("setup"); @@ -557,6 +598,10 @@ void R_RenderView (void) R_MarkWorldLights(); R_TimeReport("marklights"); + r_farclip = R_FarClip_Finish() + 256.0f; + + R_Mesh_Start(r_farclip); + if (skyrendermasked) { if (R_DrawBModelSky()) diff --git a/r_sky.c b/r_sky.c index deec3439..c6290d91 100644 --- a/r_sky.c +++ b/r_sky.c @@ -168,19 +168,23 @@ void LoadSky_f (void) } } -#define R_SkyBoxPolyVec(i,s,t,x,y,z) \ - vert[i][0] = (x) * 1024.0f + r_origin[0];\ - vert[i][1] = (y) * 1024.0f + r_origin[1];\ - vert[i][2] = (z) * 1024.0f + r_origin[2];\ - st[i][0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\ - st[i][1] = (t) * (254.0f/256.0f) + (1.0f/256.0f); - int skyboxindex[6] = {0, 1, 2, 0, 2, 3}; static void R_SkyBox(void) { + float r; float vert[4][4], st[4][2]; rmeshinfo_t m; + +#define R_SkyBoxPolyVec(i,s,t,x,y,z) \ + vert[i][0] = (x) * r + r_origin[0];\ + vert[i][1] = (y) * r + r_origin[1];\ + vert[i][2] = (z) * r + r_origin[2];\ + st[i][0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\ + st[i][1] = (t) * (254.0f/256.0f) + (1.0f/256.0f); + + r = 16.0f; + memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ONE; @@ -315,7 +319,7 @@ static void R_SkySphere(void) if (!skysphereinitialized) { skysphereinitialized = true; - skyspherecalc(skysphere, 1024, 1024, 1024 / 3); + skyspherecalc(skysphere, 16, 16, 16 / 3); } memset(&m, 0, sizeof(m)); m.transparent = false; diff --git a/render.h b/render.h index a1f175a1..0496a441 100644 --- a/render.h +++ b/render.h @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern float ixtable[4096]; // far clip distance for scene -extern float r_farclip, r_newfarclip; +extern float r_farclip; // fog stuff extern void FOG_clear(void); @@ -132,6 +132,17 @@ extern vec_t fogdensity; #define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_origin[0])*((v)[0] - r_origin[0])+((v)[1] - r_origin[1])*((v)[1] - r_origin[1])+((v)[2] - r_origin[2])*((v)[2] - r_origin[2]))))) #define calcfogbyte(v) ((qbyte) (bound(0, ((int) ((float) (calcfog((v)) * 255.0f))), 255))) +// start a farclip measuring session +void R_FarClip_Start(vec3_t origin, vec3_t direction, vec_t startfarclip); +// enlarge farclip to accomodate box +void R_FarClip_Box(vec3_t mins, vec3_t maxs); +// return farclip value +float R_FarClip_Finish(void); + +// updates farclip distance so it is large enough for the specified box +// (*important*) +void R_Mesh_EnlargeFarClipBBox(vec3_t mins, vec3_t maxs); + #include "r_modules.h" extern float overbrightscale; -- 2.39.2