From 12160bd29c7efd09f92aecd4a025fc6f77ed6b85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Aug 2014 15:34:14 +0200 Subject: [PATCH] - remove some obsolete code from decal rendering. - avoid rebinding the same texture multiple times, as there's considerable overhead in the texture manager. - check gl_sort_textures only once per scene, not per draw list. --- src/gl/scene/gl_decal.cpp | 12 ++++++++---- src/gl/scene/gl_drawinfo.cpp | 19 +++++++++++++++---- src/gl/scene/gl_drawinfo.h | 2 +- src/gl/scene/gl_scene.cpp | 16 ++++++++++------ src/gl/scene/gl_walls_draw.cpp | 12 ------------ src/gl/textures/gl_material.cpp | 18 +++++++++++++++--- wadsrc/static/menudef.z | 1 + 7 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index db6d1ad7c..4fc7603cf 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -349,11 +349,15 @@ void GLWall::DrawDecal(DBaseDecal *decal) //========================================================================== void GLWall::DoDrawDecals() { - DBaseDecal *decal = seg->sidedef->AttachedDecals; - while (decal) + if (seg->sidedef && seg->sidedef->AttachedDecals) { - DrawDecal(decal); - decal = decal->WallNext; + gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false); + DBaseDecal *decal = seg->sidedef->AttachedDecals; + while (decal) + { + DrawDecal(decal); + decal = decal->WallNext; + } } } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index c468b2a7a..3f469d999 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -59,8 +59,6 @@ FDrawInfo * gl_drawinfo; -CVAR(Bool, gl_sort_textures, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - //========================================================================== // // @@ -811,6 +809,19 @@ void GLDrawList::DrawFlats(int pass) RenderFlat.Unclock(); } +//========================================================================== +// +// +// +//========================================================================== +void GLDrawList::DrawDecals() +{ + for(unsigned i=0;i 1) { sortinfo=this; qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp); @@ -853,7 +864,7 @@ void GLDrawList::SortWalls() void GLDrawList::SortFlats() { - if (drawitems.Size()!=0 && gl_sort_textures) + if (drawitems.Size() > 1) { sortinfo=this; qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp); diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index b0a139108..67ed2099c 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -32,7 +32,6 @@ enum Drawpasses GLPASS_LIGHTSONLY, // only collect dynamic lights GLPASS_PLAIN, // Main pass without dynamic lights GLPASS_DECALS, // Draws a decal - GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer) GLPASS_TRANSLUCENT, // Draws translucent objects }; @@ -130,6 +129,7 @@ public: void Draw(int pass); void DrawWalls(int pass); void DrawFlats(int pass); + void DrawDecals(); GLDrawList * next; } ; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index f9b713335..f1fdfb812 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -85,6 +85,7 @@ CVAR(Bool, gl_texture, true, 0) CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Float, gl_mask_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Float, gl_mask_sprite_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Int, screenblocks) EXTERN_CVAR (Bool, cl_capfps) @@ -340,11 +341,14 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls(); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats(); - gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls(); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats(); - gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); + if (gl_sort_textures) + { + gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls(); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats(); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls(); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats(); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); + } // if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front, // so that we don't have to do repeated map/unmap calls on the buffer. @@ -414,7 +418,7 @@ void FGLRenderer::RenderScene(int recursion) glDepthMask(false); // this is the only geometry type on which decals can possibly appear - gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(GLPASS_DECALS); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals(); gl_RenderState.SetTextureMode(TM_MODULATE); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 5bb81fbe5..bf3e9dbd1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -395,18 +395,6 @@ void GLWall::Draw(int pass) gl_RenderState.EnableGlow(false); break; - case GLPASS_DECALS: - case GLPASS_DECALS_NOFOG: - if (seg->sidedef && seg->sidedef->AttachedDecals) - { - if (pass==GLPASS_DECALS) - { - gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false); - } - DoDrawDecals(); - } - break; - case GLPASS_TRANSLUCENT: switch (type) { diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index d29f75ddb..503c0b793 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -611,15 +611,27 @@ outl: // //=========================================================================== +static FMaterial *last; +static int lastclamp; +static int lasttrans; +static bool lastalpha; + void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture) { - int usebright = false; int shaderindex = overrideshader >= 0? overrideshader : mShaderIndex; + gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); + + // avoid rebinding the same texture multiple times. + if (this == last && lastclamp == clampmode && translation == lasttrans && lastalpha == alphatexture) return; + last = this; + lastclamp = clampmode; + lastalpha = alphatexture; + lasttrans = translation; + + int usebright = false; int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded; - gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); - if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index cdfce4145..d3394fc96 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -139,6 +139,7 @@ OptionMenu "GLTextureGLOptions" Option "Precache GL textures", gl_precache, "YesNo" Option "Camera textures offscreen", gl_usefb, "OnOff" Option "Trim sprite edges", gl_trimsprites, "OnOff" + Option "Sort draw lists by texture", gl_sort_textures, "YesNo" } OptionMenu "GLLightOptions"