From 67334bfa2bc26c641e1a9705db901af1b4889743 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Apr 2015 12:35:10 +0200 Subject: [PATCH] - calculate weapon positions fully in floating point to avoid roundoff errors. - In order to get reliable results the empty border around scaled sprites must be the same scale as the sprite (i.e. 2 pixels for 2x scale and 4 pixels for 4x scale.) --- src/gl/scene/gl_weapon.cpp | 14 +++++++------ src/gl/textures/gl_material.cpp | 35 +++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 42397166ba..89a5e1efb0 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -79,7 +79,8 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed int x1,y1,x2,y2; float scale; fixed_t scalex; - fixed_t texturemid;// 4:3 16:9 16:10 17:10 5:4 + float ftexturemid; + // 4:3 16:9 16:10 17:10 5:4 static fixed_t xratio[] = {FRACUNIT, FRACUNIT*3/4, FRACUNIT*5/6, FRACUNIT*40/51, FRACUNIT}; // [BB] In the HUD model step we just render the model and break out. @@ -116,23 +117,24 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed x2+=viewwindowx; // killough 12/98: fix psprite positioning problem - texturemid = (100<GetScaledTopOffset()<GetScaledTopOffsetFloat(); AWeapon * wi=player->ReadyWeapon; if (wi && wi->YAdjust) { + float fYAd = FIXED2FLOAT(wi->YAdjust); if (screenblocks>=11) { - texturemid -= wi->YAdjust; + ftexturemid -= fYAd; } else if (!st_scale) { - texturemid -= FixedMul (StatusBar->GetDisplacement (), wi->YAdjust); + ftexturemid -= FIXED2FLOAT(StatusBar->GetDisplacement ()) * fYAd; } } - scale = ((SCREENHEIGHT*vw)/SCREENWIDTH) / 200.0f; - y1 = viewwindowy + (vh >> 1) - (int)(((float)texturemid / (float)FRACUNIT) * scale); + scale = (SCREENHEIGHT*vw)/ (SCREENWIDTH * 200.0f); + y1 = viewwindowy + (vh >> 1) - (int)(ftexturemid * scale); y2 = y1 + (int)((float)tex->TextureHeight() * scale) + 1; if (!mirror) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index eca7c66c54..c5eb7fc34e 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -460,17 +460,25 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) if (expanded) { // a little adjustment to make sprites look better with texture filtering: - // create a 1 pixel wide empty frame around them. - mWidth+=2; - mHeight+=2; - mLeftOffset+=1; - mTopOffset+=1; - mRenderWidth = mRenderWidth * mWidth / (mWidth-2); - mRenderHeight = mRenderHeight * mHeight / (mHeight-2); - + // create a 1 pixel wide empty frame around them. The frame must be the same size as the texture scale so that + // position calculations remain scale independent. int trim[4]; + bool trimmed = TrimBorders(trim); // get the trim size before adding the empty frame - if (TrimBorders(trim)) + int intscaleX = MAX(1, tex->xScale >> FRACBITS); + int intscaleY = MAX(1, tex->yScale >> FRACBITS); + int oldwidth = mWidth; + int oldheight = mHeight; + + mWidth+=2*intscaleX; + mHeight+=2*intscaleY; + mLeftOffset+=intscaleX; + mTopOffset+=intscaleY; + mRenderWidth = mRenderWidth * mWidth / oldwidth; + mRenderHeight = mRenderHeight * mHeight / oldheight; + + /* NOTE: This formula is a bit broken and needs fixing.*/ + if (trimmed) { mSpriteRect.left = -(mLeftOffset - trim[0]) / FIXED2FLOAT(tx->xScale); mSpriteRect.top = -(mTopOffset - trim[1]) / FIXED2FLOAT(tx->yScale); @@ -482,6 +490,13 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mSpriteU[1] *= (trim[0]+trim[2]+2) / (float)mWidth; mSpriteV[1] *= (trim[1]+trim[3]+2) / (float)mHeight; } + else + { + mSpriteRect.left = -mLeftOffset / FIXED2FLOAT(tx->xScale); + mSpriteRect.top = -mTopOffset / FIXED2FLOAT(tx->yScale); + mSpriteRect.width = mWidth / FIXED2FLOAT(tx->xScale); + mSpriteRect.height = mHeight / FIXED2FLOAT(tx->yScale); + } } mTextureLayers.ShrinkToFit(); @@ -761,7 +776,7 @@ FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand) FMaterial *gltex = tex->gl_info.Material[expand]; if (gltex == NULL) { - if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER) + if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER)// || tex->xScale != FRACUNIT && tex->yScale != FRACUNIT) { expand = false; }