From e0833d50054ef7a8af848c48b2035c524567e7df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 May 2018 23:49:16 +0200 Subject: [PATCH] - prepared the weapon sprite drawer for full separation. --- src/gl/scene/gl_scenedrawer.h | 4 +- src/gl/scene/gl_weapon.cpp | 132 ++++++++++++++--------------- src/hwrenderer/scene/hw_weapon.cpp | 89 +++++++++++-------- src/hwrenderer/scene/hw_weapon.h | 29 ++++--- 4 files changed, 140 insertions(+), 114 deletions(-) diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 1565074b29..05a7d53d3b 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -9,6 +9,8 @@ #include "r_utility.h" #include "c_cvars.h" +struct HUDSprite; + class GLSceneDrawer { fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. @@ -68,7 +70,7 @@ public: void RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void DrawPSprite(player_t * player, DPSprite *psp, float sx, float sy, int OverrideShader, bool alphatexture); + void DrawPSprite(HUDSprite *huds); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); void DrawPlayerHUDModel(sector_t * viewsector); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index e4de678482..ebfaddc322 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -50,30 +50,43 @@ EXTERN_CVAR (Bool, r_drawplayersprites) EXTERN_CVAR (Bool, r_deathcamera) + //========================================================================== // // R_DrawPSprite // //========================================================================== -void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float sy, int OverrideShader, bool alphatexture) +void GLSceneDrawer::DrawPSprite (HUDSprite *huds) { - WeaponRect rc; - - if (!GetWeaponRect(psp, sx, sy, player, rc)) return; - gl_RenderState.SetMaterial(rc.tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture); - if (rc.tex->tex->GetTranslucency() || OverrideShader != -1) + if (huds->RenderStyle.BlendOp == STYLEOP_Shadow) { - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, huds->cm.Desaturation); } + else + { + SetColor(huds->lightlevel, 0, huds->cm, huds->alpha, true); + } + gl_SetRenderStyle(huds->RenderStyle, false, false); + gl_RenderState.SetObjectColor(huds->ObjectColor); + gl_RenderState.SetDynLight(huds->dynrgb[0], huds->dynrgb[1], huds->dynrgb[2]); + gl_RenderState.SetMaterial(huds->tex, CLAMP_XY_NOMIP, 0, huds->OverrideShader, !!(huds->RenderStyle.Flags & STYLEF_RedIsAlpha)); + float thresh = (huds->tex->tex->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold; + gl_RenderState.AlphaFunc(GL_GEQUAL, thresh); + gl_RenderState.EnableBrightmap(!(huds->RenderStyle.Flags & STYLEF_ColorIsFixed)); + gl_RenderState.Apply(); FQuadDrawer qd; - qd.Set(0, rc.x1, rc.y1, 0, rc.u1, rc.v1); - qd.Set(1, rc.x1, rc.y2, 0, rc.u1, rc.v2); - qd.Set(2, rc.x2, rc.y1, 0, rc.u2, rc.v1); - qd.Set(3, rc.x2, rc.y2, 0, rc.u2, rc.v2); + qd.Set(0, huds->x1, huds->y1, 0, huds->u1, huds->v1); + qd.Set(1, huds->x1, huds->y2, 0, huds->u1, huds->v2); + qd.Set(2, huds->x2, huds->y1, 0, huds->u2, huds->v1); + qd.Set(3, huds->x2, huds->y2, 0, huds->u2, huds->v2); qd.Render(GL_TRIANGLE_STRIP); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.SetDynLight(0, 0, 0); + gl_RenderState.EnableBrightmap(false); } //========================================================================== @@ -143,8 +156,6 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) WeaponPosition weap = GetWeaponPosition(camera->player); WeaponLighting light = GetWeaponLighting(viewsector, r_viewpoint.Pos, FixedColormap, in_area, camera->Pos()); - gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); - // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. int oldlightmode = level.lightmode; @@ -153,61 +164,40 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { if (!psp->GetState()) continue; - WeaponRenderStyle rs = GetWeaponRenderStyle(psp, camera); - if (rs.RenderStyle.BlendOp == STYLEOP_None) continue; + FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr; + // This is an 'either-or' proposition. This maybe needs some work to allow overlays with weapon models but as originally implemented this just won't work. + if (smf && !hudModelStep) continue; + if (!smf && hudModelStep) continue; - gl_SetRenderStyle(rs.RenderStyle, false, false); + HUDSprite hudsprite; + hudsprite.owner = playermo; + hudsprite.mframe = smf; - PalEntry ThingColor = (camera->RenderStyle.Flags & STYLEF_ColorIsFixed) ? camera->fillcolor : 0xffffff; - ThingColor.a = 255; - - // now draw the different layers of the weapon. - // For stencil render styles brightmaps need to be disabled. - gl_RenderState.EnableBrightmap(!(rs.RenderStyle.Flags & STYLEF_ColorIsFixed)); - - const bool bright = isBright(psp); - const PalEntry finalcol = bright? ThingColor : ThingColor.Modulate(viewsector->SpecialColors[sector_t::sprites]); - gl_RenderState.SetObjectColor(finalcol); - - auto ll = light; - if (bright) ll.SetBright(); - - // set the lighting parameters - if (rs.RenderStyle.BlendOp == STYLEOP_Shadow) - { - gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, ll.cm.Desaturation); - } - else - { - if (level.HasDynamicLights && FixedColormap == CM_DEFAULT && gl_light_sprites) - { - FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr; - if (!smf || gl.legacyMode) // For models with per-pixel lighting this was done in a previous pass. - { - float out[3]; - gl_drawinfo->GetDynSpriteLight(playermo, nullptr, out); - gl_RenderState.SetDynLight(out[0], out[1], out[2]); - } - } - SetColor(ll.lightlevel, 0, ll.cm, rs.alpha, true); - } + if (!hudsprite.GetWeaponRenderStyle(psp, camera, viewsector, light)) continue; FVector2 spos = BobWeapon(weap, psp); + hudsprite.dynrgb[0] = hudsprite.dynrgb[1] = hudsprite.dynrgb[2] = 0; + // set the lighting parameters + if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && level.HasDynamicLights && FixedColormap == CM_DEFAULT && gl_light_sprites && !hudModelStep || gl.legacyMode) + // For models with per-pixel lighting this was done in a previous pass. + { + gl_drawinfo->GetDynSpriteLight(playermo, nullptr, hudsprite.dynrgb); + } + // [BB] In the HUD model step we just render the model and break out. if (hudModelStep) { - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + hudsprite.x1 = spos.X; + hudsprite.y1 = spos.Y; gl_RenderHUDModel(psp, spos.X, spos.Y, weapondynlightindex[psp]); } else { - DrawPSprite(player, psp, spos.X, spos.Y, rs.OverrideShader, !!(rs.RenderStyle.Flags & STYLEF_RedIsAlpha)); + if (!hudsprite.GetWeaponRect(psp, spos.X, spos.Y, player)) continue; + DrawPSprite(&hudsprite); } } - gl_RenderState.SetObjectColor(0xffffffff); - gl_RenderState.SetDynLight(0, 0, 0); - gl_RenderState.EnableBrightmap(false); level.lightmode = oldlightmode; } @@ -220,22 +210,32 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) void GLSceneDrawer::DrawTargeterSprites() { - AActor * playermo=players[consoleplayer].camera; - player_t * player=playermo->player; - - if(!player || playermo->renderflags&RF_INVISIBLE || !r_drawplayersprites || - GLRenderer->mViewActor!=playermo) return; + AActor * playermo = players[consoleplayer].camera; + player_t * player = playermo->player; - gl_RenderState.EnableBrightmap(false); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); - gl_RenderState.BlendEquation(GL_FUNC_ADD); - gl_RenderState.ResetColor(); - gl_RenderState.SetTextureMode(TM_MODULATE); + if (!player || playermo->renderflags&RF_INVISIBLE || !r_drawplayersprites || GLRenderer->mViewActor != playermo) return; + + HUDSprite hudsprite; + + hudsprite.owner = playermo; + hudsprite.mframe = nullptr; + hudsprite.cm.Clear(); + hudsprite.lightlevel = 255; + hudsprite.ObjectColor = 0xffffffff; + hudsprite.alpha = 1; + hudsprite.RenderStyle = DefaultRenderStyle(); + hudsprite.OverrideShader = -1; + hudsprite.dynrgb[0] = hudsprite.dynrgb[1] = hudsprite.dynrgb[2] = 0; // The Targeter's sprites are always drawn normally. for (DPSprite *psp = player->FindPSprite(PSP_TARGETCENTER); psp != nullptr; psp = psp->GetNext()) { - if (psp->GetState() != nullptr) DrawPSprite(player, psp, psp->x, psp->y, 0, false); + if (psp->GetState() != nullptr && (psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr)) + { + hudsprite.weapon = psp; + hudsprite.GetWeaponRect(psp, psp->x, psp->y, player); + + DrawPSprite(&hudsprite); + } } } diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 33c74aca3d..371e1006dc 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -47,7 +47,7 @@ EXTERN_CVAR(Int, gl_fuzztype) // //========================================================================== -bool isBright(DPSprite *psp) +static bool isBright(DPSprite *psp) { if (psp != nullptr && psp->GetState() != nullptr) { @@ -134,7 +134,7 @@ FVector2 BobWeapon(WeaponPosition &weap, DPSprite *psp) // //========================================================================== -WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int FixedColormap, area_t in_area, const DVector3 &playerpos ) +WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int FixedColormap, area_t in_area, const DVector3 &playerpos) { WeaponLighting l; @@ -212,7 +212,13 @@ WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int return l; } -void WeaponLighting::SetBright() +//========================================================================== +// +// +// +//========================================================================== + +void HUDSprite::SetBright(bool isbelow) { if (!isbelow) { @@ -234,9 +240,8 @@ void WeaponLighting::SetBright() // //========================================================================== -WeaponRenderStyle GetWeaponRenderStyle(DPSprite *psp, AActor *playermo) +bool HUDSprite::GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t *viewsector, WeaponLighting &lighting) { - WeaponRenderStyle r; auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha); visstyle_t vis; @@ -251,52 +256,63 @@ WeaponRenderStyle GetWeaponRenderStyle(DPSprite *psp, AActor *playermo) if (vis.RenderStyle != STYLE_Count && !(psp->Flags & PSPF_FORCESTYLE)) { - r.RenderStyle = vis.RenderStyle; + RenderStyle = vis.RenderStyle; } else { - r.RenderStyle = rs.first; + RenderStyle = rs.first; } - if (r.RenderStyle.BlendOp == STYLEOP_None) return r; + if (RenderStyle.BlendOp == STYLEOP_None) return false; if (vis.Invert) { // this only happens for Strife's inverted weapon sprite - r.RenderStyle.Flags |= STYLEF_InvertSource; + RenderStyle.Flags |= STYLEF_InvertSource; } // Set the render parameters - r.OverrideShader = -1; - if (r.RenderStyle.BlendOp == STYLEOP_Fuzz) + OverrideShader = -1; + if (RenderStyle.BlendOp == STYLEOP_Fuzz) { if (gl_fuzztype != 0) { // Todo: implement shader selection here - r.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; - r.OverrideShader = SHADER_NoTexture + gl_fuzztype; - r.alpha = 0.99f; // trans may not be 1 here + RenderStyle = LegacyRenderStyles[STYLE_Translucent]; + OverrideShader = SHADER_NoTexture + gl_fuzztype; + alpha = 0.99f; // trans may not be 1 here } else { - r.RenderStyle.BlendOp = STYLEOP_Shadow; + RenderStyle.BlendOp = STYLEOP_Shadow; } } - - if (r.RenderStyle.Flags & STYLEF_TransSoulsAlpha) + if (RenderStyle.Flags & STYLEF_TransSoulsAlpha) { - r.alpha = transsouls; + alpha = transsouls; } - else if (r.RenderStyle.Flags & STYLEF_Alpha1) + else if (RenderStyle.Flags & STYLEF_Alpha1) { - r.alpha = 1.f; + alpha = 1.f; } else if (trans == 0.f) { - r.alpha = vis.Alpha; + alpha = vis.Alpha; } - return r; + if (!RenderStyle.IsVisible(alpha)) return false; // if it isn't visible skip the rest. + + PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; + ThingColor.a = 255; + + const bool bright = isBright(psp); + ObjectColor = bright ? ThingColor : ThingColor.Modulate(viewsector->SpecialColors[sector_t::sprites]); + + lightlevel = lighting.lightlevel; + cm = lighting.cm; + if (bright) SetBright(lighting.isbelow); + + return true; } //========================================================================== @@ -305,10 +321,9 @@ WeaponRenderStyle GetWeaponRenderStyle(DPSprite *psp, AActor *playermo) // //========================================================================== -bool GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player, WeaponRect &rc) +bool HUDSprite::GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player) { float tx; - float x1, x2; float scale; float scalex; float ftexturemid; @@ -333,13 +348,13 @@ bool GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player, WeaponRe tx = (psp->Flags & PSPF_MIRROR) ? ((160 - r.width) - (sx + r.left)) : (sx - (160 - r.left)); x1 = tx * scalex + vw / 2; if (x1 > vw) return false; // off the right side - rc.x1 = x1 + viewwindowx; + x1 += viewwindowx; tx += r.width; x2 = tx * scalex + vw / 2; if (x2 < 0) return false; // off the left side - rc.x2 = x2 + viewwindowx; + x2 += viewwindowx; // killough 12/98: fix psprite positioning problem ftexturemid = 100.f - sy - r.top; @@ -359,25 +374,25 @@ bool GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player, WeaponRe } scale = (SCREENHEIGHT*vw) / (SCREENWIDTH * 200.0f); - rc.y1 = viewwindowy + vh / 2 - (ftexturemid * scale); - rc.y2 = rc.y1 + (r.height * scale) + 1; + y1 = viewwindowy + vh / 2 - (ftexturemid * scale); + y2 = y1 + (r.height * scale) + 1; if (!(mirror) != !(psp->Flags & (PSPF_FLIP))) { - rc.u2 = tex->GetSpriteUL(); - rc.v1 = tex->GetSpriteVT(); - rc.u1 = tex->GetSpriteUR(); - rc.v2 = tex->GetSpriteVB(); + u2 = tex->GetSpriteUL(); + v1 = tex->GetSpriteVT(); + u1 = tex->GetSpriteUR(); + v2 = tex->GetSpriteVB(); } else { - rc.u1 = tex->GetSpriteUL(); - rc.v1 = tex->GetSpriteVT(); - rc.u2 = tex->GetSpriteUR(); - rc.v2 = tex->GetSpriteVB(); + u1 = tex->GetSpriteUL(); + v1 = tex->GetSpriteVT(); + u2 = tex->GetSpriteUR(); + v2 = tex->GetSpriteVB(); } - rc.tex = tex; + this->tex = tex; return true; } diff --git a/src/hwrenderer/scene/hw_weapon.h b/src/hwrenderer/scene/hw_weapon.h index 88a7f3fb76..8d4c755bd6 100644 --- a/src/hwrenderer/scene/hw_weapon.h +++ b/src/hwrenderer/scene/hw_weapon.h @@ -6,6 +6,9 @@ class DPSprite; class player_t; class AActor; enum area_t : int; +struct FSpriteModelFrame; + + struct WeaponPosition { @@ -19,31 +22,37 @@ struct WeaponLighting FColormap cm; int lightlevel; bool isbelow; - - void SetBright(); }; -struct WeaponRenderStyle +struct HUDSprite { + AActor *owner; + DPSprite *weapon; + FMaterial *tex; + FSpriteModelFrame *mframe; + + FColormap cm; + int lightlevel; + PalEntry ObjectColor; + FRenderStyle RenderStyle; float alpha; int OverrideShader; -}; -struct WeaponRect -{ - FMaterial *tex; float x1, y1; float x2, y2; float u1, v1; float u2, v2; + float dynrgb[3]; + + void SetBright(bool isbelow); + bool GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t *viewsector, WeaponLighting &light); + bool GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player); + }; -bool isBright(DPSprite *psp); WeaponPosition GetWeaponPosition(player_t *player); FVector2 BobWeapon(WeaponPosition &weap, DPSprite *psp); WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int FixedColormap, area_t in_area, const DVector3 &playerpos ); -WeaponRenderStyle GetWeaponRenderStyle(DPSprite *psp, AActor *playermo); -bool GetWeaponRect(DPSprite *psp, float sx, float sy, player_t *player, WeaponRect &rc);