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; }