From 92e2ce2aefa4fb7e6f5ad0d94e27d73549c84cfd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Jun 2016 17:21:42 +0200 Subject: [PATCH] - adjustments for weapon rendering in GL. This adds support for the new weapon state code and fixed some lighting calculations. Note that this currently will not allow combination of HUD models with other sprite frames yet. --- src/gl/models/gl_models.cpp | 11 +-- src/gl/models/gl_models.h | 2 +- src/gl/renderer/gl_renderer.h | 4 +- src/gl/scene/gl_weapon.cpp | 159 ++++++++++++++++++++++------------ src/p_pspr.h | 1 + 5 files changed, 113 insertions(+), 64 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index a79e5ba7c..d28dfc805 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -1019,10 +1019,10 @@ void gl_RenderModel(GLSprite * spr) // //=========================================================================== -void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY) +void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) { AActor * playermo=players[consoleplayer].camera; - FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->state->sprite, psp->state->GetFrame(), false); + FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false); // [BB] No model found for this sprite, so we can't render anything. if ( smf == nullptr ) @@ -1062,7 +1062,7 @@ void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY) gl_RenderState.mViewMatrix.rotate(-smf->rolloffset, 1, 0, 0); gl_RenderState.ApplyMatrices(); - gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), nullptr, 0 ); + gl_RenderFrameModels( smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0 ); glDepthFunc(GL_LESS); if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) @@ -1077,10 +1077,11 @@ void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY) bool gl_IsHUDModelForPlayerAvailable (player_t * player) { - if ( (player == nullptr) || (player->ReadyWeapon == nullptr) || (player->psprites[0].state == nullptr) ) + DPSprite *psp = player->FindPSprite(PSP_WEAPON); + if ( (player == nullptr) || (player->ReadyWeapon == nullptr) || (psp->GetState() == nullptr) ) return false; - FState* state = player->psprites[0].state; + FState* state = psp->GetState(); FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); return ( smf != nullptr ); } diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 33fa00736..9ccf765f6 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -371,7 +371,7 @@ FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, void gl_RenderModel(GLSprite * spr); // [BB] HUD weapon model rendering functions. -void gl_RenderHUDModel(pspdef_t *psp, float ofsx, float ofsy); +void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); bool gl_IsHUDModelForPlayerAvailable (player_t * player); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index a78b8c5dc..3da5a22df 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -13,11 +13,11 @@ class FFlatVertexBuffer; class FSkyVertexBuffer; class OpenGLFrameBuffer; struct FDrawInfo; -struct pspdef_t; class FShaderManager; class GLPortal; class FLightBuffer; class FSamplerManager; +class DPSprite; inline float DEG2RAD(float deg) { @@ -109,7 +109,7 @@ public: void DrawScene(bool toscreen = false); void DrawBlend(sector_t * viewsector); - void DrawPSprite (player_t * player,pspdef_t *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture); + void DrawPSprite (player_t * player,DPSprite *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index f1cd5e38b..c5d1dc82a 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -71,7 +71,7 @@ EXTERN_CVAR (Bool, r_deathcamera) // //========================================================================== -void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture) +void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture) { float fU1,fV1; float fU2,fV2; @@ -86,13 +86,13 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float // [BB] In the HUD model step we just render the model and break out. if ( hudModelStep ) { - gl_RenderHUDModel( psp, sx, sy); + gl_RenderHUDModel(psp, sx, sy); return; } // decide which patch to use bool mirror; - FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, &mirror); + FTextureID lump = gl_GetSpriteFrame(psp->GetSprite(), psp->GetFrame(), 0, 0, &mirror); if (!lump.isValid()) return; FMaterial * tex = FMaterial::ValidateTexture(lump, true, false); @@ -174,6 +174,29 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); } +//========================================================================== +// +// +// +//========================================================================== + +static bool isBright(DPSprite *psp) +{ + if (psp != nullptr && psp->GetState() != nullptr) + { + bool disablefullbright = false; + FTextureID lump = gl_GetSpriteFrame(psp->GetSprite(), psp->GetFrame(), 0, 0, NULL); + if (lump.isValid()) + { + FMaterial * tex = FMaterial::ValidateTexture(lump, false, false); + if (tex) + disablefullbright = tex->tex->gl_info.bDisableFullbright; + } + return psp->GetState()->GetFullbright() && !disablefullbright; + } + return false; +} + //========================================================================== // // R_DrawPlayerSprites @@ -184,11 +207,9 @@ EXTERN_CVAR(Bool, gl_brightfog) void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { - bool statebright[2] = {false, false}; + bool brightflash = false; unsigned int i; - pspdef_t *psp; int lightlevel=0; - float ofsx, ofsy; FColormap cm; sector_t * fakesec, fs; AActor * playermo=players[consoleplayer].camera; @@ -202,33 +223,35 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) (r_deathcamera && camera->health <= 0)) return; - P_BobWeapon (player, &player->psprites[ps_weapon], &ofsx, &ofsy, r_TicFracF); + float bobx, boby, wx, wy; + DPSprite *weapon; - // check for fullbright - if (player->fixedcolormap==NOFIXEDCOLORMAP) + P_BobWeapon(camera->player, &bobx, &boby, r_TicFracF); + + // Interpolate the main weapon layer once so as to be able to add it to other layers. + if ((weapon = camera->player->FindPSprite(PSP_WEAPON)) != nullptr) { - for (i = 0, psp = player->psprites; i <= ps_flash; i++, psp++) + if (weapon->firstTic) { - if (psp->state != NULL) - { - bool disablefullbright = false; - FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL); - if (lump.isValid()) - { - FMaterial * tex=FMaterial::ValidateTexture(lump, false, false); - if (tex) - disablefullbright = tex->tex->gl_info.bDisableFullbright; - } - statebright[i] = !!psp->state->GetFullbright() && !disablefullbright; - } + wx = weapon->x; + wy = weapon->y; } + else + { + wx = weapon->oldx + (weapon->x - weapon->oldx) * r_TicFracF; + wy = weapon->oldy + (weapon->y - weapon->oldy) * r_TicFracF; + } + } + else + { + wx = 0; + wy = 0; } if (gl_fixedcolormap) { lightlevel=255; cm.Clear(); - statebright[0] = statebright[1] = true; fakesec = viewsector; } else @@ -237,20 +260,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // calculate light level for weapon sprites lightlevel = gl_ClampLight(fakesec->lightlevel); - if (glset.lightmode == 8) - { - lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true); - - // Korshun: the way based on max possible light level for sector like in software renderer. - float min_L = 36.0/31.0 - ((lightlevel/255.0) * (63.0/31.0)); // Lightlevel in range 0-63 - if (min_L < 0) - min_L = 0; - else if (min_L > 1.0) - min_L = 1.0; - - lightlevel = (1.0 - min_L) * 255; - } - lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos()); // calculate colormap for weapon sprites if (viewsector->e->XFloor.ffloors.Size() && !glset.nocoloredspritelighting) @@ -282,8 +291,27 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) cm=fakesec->ColorMap; if (glset.nocoloredspritelighting) cm.ClearColor(); } - } + lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true); + + if (glset.lightmode == 8) + { + // Korshun: the way based on max possible light level for sector like in software renderer. + float min_L = 36.0 / 31.0 - ((lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 + if (min_L < 0) + min_L = 0; + else if (min_L > 1.0) + min_L = 1.0; + + lightlevel = (1.0 - min_L) * 255; + } + else + { + lightlevel = (2 * lightlevel + 255) / 3; + } + lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos()); + + } // Korshun: fullbright fog in opengl, render weapon sprites fullbright (but don't cancel out the light color!) if (glset.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0)) @@ -332,7 +360,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) vis.RenderStyle.BlendOp = STYLEOP_Shadow; } } - statebright[0] = statebright[1] = false; } gl_SetRenderStyle(vis.RenderStyle, false, false); @@ -356,24 +383,19 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) 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); - if (statebright[0] || statebright[1]) - { - // brighten the weapon to reduce the difference between - // normal sprite and fullbright flash. - if (glset.lightmode != 8) lightlevel = (2*lightlevel+255)/3; - } - + // 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 = glset.lightmode; if (glset.lightmode == 8) glset.lightmode = 2; - - for (i=0, psp=player->psprites; i<=ps_flash; i++,psp++) + + for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { - if (psp->state) + if (psp->GetState() != nullptr) { FColormap cmc = cm; - if (statebright[i]) + int ll = lightlevel; + if (isBright(psp)) { if (fakesec == viewsector || in_area != area_below) { @@ -388,6 +410,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4; cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4; } + ll = 255; } // set the lighting parameters if (vis.RenderStyle.BlendOp == STYLEOP_Shadow) @@ -400,9 +423,33 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { gl_SetDynSpriteLight(playermo, NULL); } - gl_SetColor(statebright[i] ? 255 : lightlevel, 0, cmc, trans, true); + gl_SetColor(ll, 0, cmc, trans, true); } - DrawPSprite(player, psp, psp->sx + ofsx, psp->sy + ofsy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha)); + + if (psp->firstTic) + { // Can't interpolate the first tic. + psp->firstTic = false; + psp->oldx = psp->x; + psp->oldy = psp->y; + } + + float sx = psp->oldx + (psp->x - psp->oldx) * r_TicFracF; + float sy = psp->oldy + (psp->y - psp->oldy) * r_TicFracF; + + if (psp->Flags & PSPF_ADDBOB) + { + sx += bobx; + sy += boby; + } + + if (psp->Flags & PSPF_ADDWEAPON && psp->GetID() != PSP_WEAPON) + { + sx += wx; + sy += wy; + } + + + DrawPSprite(player, psp, sx, sy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha)); } } gl_RenderState.SetObjectColor(0xffffffff); @@ -419,8 +466,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) void FGLRenderer::DrawTargeterSprites() { - int i; - pspdef_t *psp; AActor * playermo=players[consoleplayer].camera; player_t * player=playermo->player; @@ -435,6 +480,8 @@ void FGLRenderer::DrawTargeterSprites() gl_RenderState.SetTextureMode(TM_MODULATE); // The Targeter's sprites are always drawn normally. - for (i=ps_targetcenter, psp = &player->psprites[ps_targetcenter]; istate) DrawPSprite (player,psp,psp->sx, psp->sy, false, 0, false); + for (DPSprite *psp = player->FindPSprite(PSP_TARGETCENTER); psp != nullptr; psp = psp->GetNext()) + { + if (psp->GetState() != nullptr) DrawPSprite(player, psp, psp->x, psp->y, false, 0, false); + } } \ No newline at end of file diff --git a/src/p_pspr.h b/src/p_pspr.h index 2c7a36518..e00f8916f 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -73,6 +73,7 @@ public: int GetID() const { return ID; } int GetSprite() const { return Sprite; } int GetFrame() const { return Frame; } + int GetTics() const { return Tics; } FState* GetState() const { return State; } DPSprite* GetNext() { return Next; } AActor* GetCaller() { return Caller; }