- fixed weapon positioning again, after finding out that the first fix just worked around the actual problem: The entire coordinate calculation must be done in floating point with no integer math at all. Due to roundoff errors the stored int values needed for wall and flat placement significantly lack precision and with the high scaling factor that needs to be used for weapon HUD sprites these can easily become several pixels. After fixing this the border around sprite textures could be reverted to one pixel again.

- fixed: The 'may not be expanded' state should be stored in the texture and reused later. This also needs to revalidate the material if it decides that expansion should be disallowed.
This commit is contained in:
Christoph Oelckers 2015-04-04 17:50:22 +02:00
parent 85ef1a11e9
commit bead3e046b
5 changed files with 67 additions and 62 deletions

View file

@ -75,13 +75,13 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
{
float fU1,fV1;
float fU2,fV2;
fixed_t tx;
int x1,y1,x2,y2;
float tx;
float x1,y1,x2,y2;
float scale;
fixed_t scalex;
float scalex;
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};
// 4:3 16:9 16:10 17:10 5:4
static float xratio[] = {1.f, 3.f/4, 5.f/6, 40.f/51, 1.f};
// [BB] In the HUD model step we just render the model and break out.
if ( hudModelStep )
@ -100,30 +100,34 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
gl_RenderState.SetMaterial(tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture);
int vw = viewwidth;
int vh = viewheight;
float vw = (float)viewwidth;
float vh = (float)viewheight;
FloatRect r;
tex->GetSpriteRect(&r);
// calculate edges of the shape
scalex = xratio[WidescreenRatio] * vw / 320;
tx = sx - ((160 + tex->GetScaledLeftOffset())<<FRACBITS);
x1 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
tx = FIXED2FLOAT(sx) - (160 - r.left);
x1 = tx * scalex + vw/2;
if (x1 > vw) return; // off the right side
x1+=viewwindowx;
x1 += viewwindowx;
tx += tex->TextureWidth() << FRACBITS;
x2 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
tx += r.width;
x2 = tx * scalex + vw / 2;
if (x2 < 0) return; // off the left side
x2+=viewwindowx;
x2 += viewwindowx;
// killough 12/98: fix psprite positioning problem
ftexturemid = 100.f - FIXED2FLOAT(sy) + tex->GetScaledTopOffsetFloat();
ftexturemid = 100.f - FIXED2FLOAT(sy) - r.top;
AWeapon * wi=player->ReadyWeapon;
if (wi && wi->YAdjust)
{
float fYAd = FIXED2FLOAT(wi->YAdjust);
if (screenblocks>=11)
if (screenblocks >= 11)
{
ftexturemid -= fYAd;
}
@ -133,23 +137,23 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
}
}
scale = (SCREENHEIGHT*vw)/ (SCREENWIDTH * 200.0f);
y1 = viewwindowy + (vh >> 1) - (int)(ftexturemid * scale);
y2 = y1 + (int)((float)tex->TextureHeight() * scale) + 1;
scale = (SCREENHEIGHT*vw) / (SCREENWIDTH * 200.0f);
y1 = viewwindowy + vh / 2 - (ftexturemid * scale);
y2 = y1 + (r.height * scale) + 1;
if (!mirror)
{
fU1=tex->GetUL();
fV1=tex->GetVT();
fU2=tex->GetUR();
fV2=tex->GetVB();
fU1=tex->GetSpriteUL();
fV1=tex->GetSpriteVT();
fU2=tex->GetSpriteUR();
fV2=tex->GetSpriteVB();
}
else
{
fU2=tex->GetUL();
fV1=tex->GetVT();
fU1=tex->GetUR();
fV2=tex->GetVB();
fU2=tex->GetSpriteUL();
fV1=tex->GetSpriteVT();
fU1=tex->GetSpriteUR();
fV2=tex->GetSpriteVB();
}
if (tex->GetTransparent() || OverrideShader != -1)

View file

@ -89,7 +89,6 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
bHasColorkey = false;
bIsTransparent = -1;
bExpandFlag = expandpatches;
mExpandX = mExpandY = 0;
tex->gl_info.SystemTexture[expandpatches] = this;
}
@ -199,20 +198,10 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
}
}
int exx, exy;
if (createexpanded)
{
exx = mExpandX;
exy = mExpandY;
}
else
{
exx = exy = 0;
}
int exx = bExpandFlag && createexpanded;
W = w = tex->GetWidth() + 2 * exx;
H = h = tex->GetHeight() + 2 * exy;
H = h = tex->GetHeight() + 2 * exx;
buffer=new unsigned char[W*(H+1)*4];
@ -230,7 +219,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
if (imgCreate.Create(W, H))
{
memset(imgCreate.GetPixels(), 0, W * H * 4);
int trans = tex->CopyTrueColorPixels(&imgCreate, exx, exy);
int trans = tex->CopyTrueColorPixels(&imgCreate, exx, exx);
bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA);
tex->CheckTrans(buffer, W*H, trans);
bIsTransparent = tex->gl_info.mIsTransparent;
@ -238,7 +227,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
}
else if (translation<=0)
{
int trans = tex->CopyTrueColorPixels(&bmp, exx, exy);
int trans = tex->CopyTrueColorPixels(&bmp, exx, exx);
tex->CheckTrans(buffer, W*H, trans);
bIsTransparent = tex->gl_info.mIsTransparent;
}
@ -247,7 +236,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
// When using translations everything must be mapped to the base palette.
// Since FTexture's method is doing exactly that by calling GetPixels let's use that here
// to do all the dirty work for us. ;)
tex->FTexture::CopyTrueColorPixels(&bmp, exx, exy);
tex->FTexture::CopyTrueColorPixels(&bmp, exx, exx);
bIsTransparent = 0;
}
@ -271,7 +260,7 @@ FHardwareTexture *FGLTexture::CreateHwTexture()
if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture
if (mHwTexture == NULL)
{
mHwTexture = new FHardwareTexture(tex->GetWidth() + mExpandX*2, tex->GetHeight() + mExpandY*2, tex->gl_info.bNoCompress);
mHwTexture = new FHardwareTexture(tex->GetWidth() + bExpandFlag*2, tex->GetHeight() + bExpandFlag*2, tex->gl_info.bNoCompress);
}
return mHwTexture;
}
@ -454,7 +443,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
}
}
}
mBaseLayer = ValidateSysTexture(tx, true);
mBaseLayer = ValidateSysTexture(tx, expanded);
mWidth = tx->GetWidth();
@ -467,7 +456,11 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mSpriteU[1] = mSpriteV[1] = 1.f;
FTexture *basetex = tx->GetRedirect(false);
mBaseLayer = ValidateSysTexture(basetex, expanded);
// allow the redirect only if the textute is not expanded or the scale matches.
if (!expanded || (tx->xScale == basetex->xScale && tx->yScale == basetex->yScale))
{
mBaseLayer = ValidateSysTexture(basetex, expanded);
}
float fxScale = FIXED2FLOAT(tx->xScale);
float fyScale = FIXED2FLOAT(tx->yScale);
@ -481,20 +474,17 @@ 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. The frame must be the same size as the texture scale so that
// position calculations remain scale independent.
// create a 1 pixel wide empty frame around them.
int trim[4];
bool trimmed = TrimBorders(trim); // get the trim size before adding the empty frame
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;
mWidth+=2;
mHeight+=2;
mLeftOffset+=1;
mTopOffset+=1;
mRenderWidth = mRenderWidth * mWidth / oldwidth;
mRenderHeight = mRenderHeight * mHeight / oldheight;
@ -793,14 +783,30 @@ void FMaterial::BindToFrameBuffer()
FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand)
{
again:
if (tex && tex->UseType!=FTexture::TEX_Null)
{
if (tex->gl_info.bNoExpand) expand = false;
FMaterial *gltex = tex->gl_info.Material[expand];
if (gltex == NULL)
{
if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER)// || tex->xScale != FRACUNIT && tex->yScale != FRACUNIT)
if (expand)
{
expand = false;
if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER)
{
tex->gl_info.bNoExpand = true;
goto again;
}
if (tex->gl_info.Brightmap != NULL &&
(tex->GetWidth() != tex->gl_info.Brightmap->GetWidth() ||
tex->GetHeight() != tex->gl_info.Brightmap->GetHeight())
)
{
// do not expand if the brightmap's size differs.
tex->gl_info.bNoExpand = true;
goto again;
}
}
gltex = new FMaterial(tex, expand);
}

View file

@ -66,8 +66,6 @@ private:
bool bHasColorkey; // only for hires
bool bExpandFlag;
int mExpandX;
int mExpandY;
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height);
@ -80,11 +78,6 @@ public:
~FGLTexture();
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true);
void SetExpand(int x, int y)
{
mExpandX = x;
mExpandY = y;
}
void Clean(bool all);
int Dump(int i);

View file

@ -235,6 +235,7 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
bDisableFullbright = false;
bNoFilter = false;
bNoCompress = false;
bNoExpand = false;
areas = NULL;
areacount = 0;
mIsTransparent = -1;

View file

@ -352,6 +352,7 @@ public:
bool bDisableFullbright:1; // This texture will not be displayed as fullbright sprite
bool bNoFilter:1;
bool bNoCompress:1;
bool bNoExpand:1;
MiscGLInfo() throw ();
~MiscGLInfo();