- moved most of the texture size maintenance to the FGameTexture class.

This commit is contained in:
Christoph Oelckers 2020-04-17 21:32:09 +02:00
parent 9bc1d4f38f
commit 8843761bf8
11 changed files with 96 additions and 73 deletions

View file

@ -171,11 +171,11 @@ int FTexture::CheckRealHeight()
{
auto pixels = Get8BitPixels(false);
for(int h = GetTexelHeight()-1; h>= 0; h--)
for(int h = GetHeight()-1; h>= 0; h--)
{
for(int w = 0; w < GetTexelWidth(); w++)
for(int w = 0; w < GetWidth(); w++)
{
if (pixels[h + w * GetTexelHeight()] != 0)
if (pixels[h + w * GetHeight()] != 0)
{
// Scale maxy before returning it
h = int((h * 2) / Scale.Y);
@ -262,7 +262,7 @@ void FGameTexture::CreateDefaultBrightmap()
auto texbuf = tex->Get8BitPixels(false);
const int white = ColorMatcher.Pick(255, 255, 255);
int size = GetTexelWidth() * GetTexelHeight();
int size = tex->GetWidth() * tex->GetHeight();
for (int i = 0; i<size; i++)
{
if (GPalette.GlobalBrightmap.Remap[texbuf[i]] == white)
@ -550,8 +550,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
int exx = !!(flags & CTF_Expand);
W = GetTexelWidth() + 2 * exx;
H = GetTexelHeight() + 2 * exx;
W = GetWidth() + 2 * exx;
H = GetHeight() + 2 * exx;
if (!checkonly)
{
@ -656,7 +656,7 @@ bool FGameTexture::ShouldExpandSprite()
Base->bExpandSprite = false;
return false;
}
if (Brightmap != NULL && (GetTexelWidth() != Brightmap->GetTexelWidth() || GetTexelHeight() != Brightmap->GetTexelHeight()))
if (Brightmap != NULL && (Base->GetWidth() != Brightmap->GetWidth() || Base->GetHeight() != Brightmap->GetHeight()))
{
// do not expand if the brightmap's size differs.
Base->bExpandSprite = false;
@ -927,17 +927,17 @@ float FTexCoordInfo::TextureAdjustWidth() const
//
//===========================================================================
void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y, bool forceworldpanning)
void FTexCoordInfo::GetFromTexture(FGameTexture *tex, float x, float y, bool forceworldpanning)
{
if (x == 1.f)
{
mRenderWidth = tex->GetDisplayWidth();
mScale.X = (float)tex->Scale.X;
mRenderWidth = xs_RoundToInt(tex->GetDisplayWidth());
mScale.X = tex->GetScaleX();
mTempScale.X = 1.f;
}
else
{
float scale_x = x * (float)tex->Scale.X;
float scale_x = x * tex->GetScaleX();
mRenderWidth = xs_CeilToInt(tex->GetTexelWidth() / scale_x);
mScale.X = scale_x;
mTempScale.X = x;
@ -945,30 +945,26 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y, bool forcewo
if (y == 1.f)
{
mRenderHeight = tex->GetDisplayHeight();
mScale.Y = (float)tex->Scale.Y;
mRenderHeight = xs_RoundToInt(tex->GetDisplayHeight());
mScale.Y = tex->GetScaleY();
mTempScale.Y = 1.f;
}
else
{
float scale_y = y * (float)tex->Scale.Y;
float scale_y = y * tex->GetScaleY();
mRenderHeight = xs_CeilToInt(tex->GetTexelHeight() / scale_y);
mScale.Y = scale_y;
mTempScale.Y = y;
}
if (tex->bHasCanvas)
if (tex->isHardwareCanvas())
{
mScale.Y = -mScale.Y;
mRenderHeight = -mRenderHeight;
}
mWorldPanning = tex->bWorldPanning || forceworldpanning;
mWorldPanning = tex->useWorldPanning() || forceworldpanning;
mWidth = tex->GetTexelWidth();
}
void FTexCoordInfo::GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning)
{
GetFromTexture(tex->GetTexture(), x, y, forceworldpanning);
}
//==========================================================================
//

View file

@ -600,13 +600,14 @@ void FTextureManager::AddHiresTextures (int wadnum)
auto oldtex = Textures[tlist[i].GetIndex()].Texture;
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetDisplaySize((int)oldtex->GetDisplayWidth(), (int)oldtex->GetDisplayHeight());
newtex->_LeftOffset[0] = int(oldtex->GetDisplayLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetDisplayLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetDisplayTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetDisplayTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], MakeGameTexture(newtex, ETextureType::Override), true);
auto gtex = MakeGameTexture(newtex, ETextureType::Override);
gtex->SetWorldPanning(true);
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
ReplaceTexture(tlist[i], gtex, true);
}
}
}
@ -697,13 +698,14 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
if (newtex != NULL)
{
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetDisplaySize((int)oldtex->GetDisplayWidth(), (int)oldtex->GetDisplayHeight());
newtex->_LeftOffset[0] = int(oldtex->GetDisplayLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetDisplayLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetDisplayTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetDisplayTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], MakeGameTexture(newtex, ETextureType::Override), true);
auto gtex = MakeGameTexture(newtex, ETextureType::Override);
gtex->SetWorldPanning(true);
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
ReplaceTexture(tlist[i], gtex, true);
}
}
}
@ -1216,10 +1218,10 @@ FTextureID FTextureManager::GetRawTexture(FTextureID texid)
// Reject anything that cannot have been a front layer for the sky in original Hexen, i.e. it needs to be an unscaled wall texture only using Doom patches.
auto tex = Textures[texidx].Texture;
auto ttex = tex->GetTexture();
auto image = tex->GetTexture()->GetImage();
auto image = ttex->GetImage();
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
if (image == nullptr || image->IsRawCompatible() || tex->GetUseType() != ETextureType::Wall || tex->GetTexelWidth() != tex->GetDisplayWidth() ||
tex->GetTexelHeight() != tex->GetDisplayHeight())
if (image == nullptr || image->IsRawCompatible() || tex->GetUseType() != ETextureType::Wall || ttex->GetWidth() != tex->GetDisplayWidth() ||
ttex->GetHeight() != tex->GetDisplayHeight())
{
Textures[texidx].RawTexture = texidx;
return texid;
@ -1230,7 +1232,7 @@ FTextureID FTextureManager::GetRawTexture(FTextureID texid)
auto source = mptimage->GetImageForPart(0);
// Size must match for this to work as intended
if (source->GetWidth() != tex->GetTexelWidth() || source->GetHeight() != tex->GetTexelHeight())
if (source->GetWidth() != ttex->GetWidth() || source->GetHeight() != ttex->GetHeight())
{
Textures[texidx].RawTexture = texidx;
return texid;
@ -1259,9 +1261,10 @@ FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid)
// Reject anything that cannot have been a front layer for the sky in original Hexen, i.e. it needs to be an unscaled wall texture only using Doom patches.
auto tex = Textures[texidx].Texture;
auto image = tex->GetTexture()->GetImage();
auto ttex = tex->GetTexture();
auto image = ttex->GetImage();
if (image == nullptr || !image->SupportRemap0() || tex->GetUseType() != ETextureType::Wall || tex->useWorldPanning() || tex->GetTexelTopOffset() != 0 ||
tex->GetTexelWidth() != tex->GetDisplayWidth() || tex->GetTexelHeight() != tex->GetDisplayHeight())
ttex->GetWidth() != tex->GetDisplayWidth() || ttex->GetHeight() != tex->GetDisplayHeight())
{
Textures[texidx].FrontSkyLayer = texidx;
return texid;

View file

@ -256,17 +256,13 @@ public:
void CleanHardwareTextures(bool reallyclean);
// These are mainly meant for 2D code which only needs logical information about the texture to position it properly.
int GetDisplayWidth() { int foo = int((Width * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
int GetDisplayHeight() { int foo = int((Height * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
double GetDisplayWidthDouble() { return Width / Scale.X; }
double GetDisplayHeightDouble() { return Height / Scale.Y; }
int GetDisplayLeftOffset() { return GetScaledLeftOffset(0); }
int GetDisplayTopOffset() { return GetScaledTopOffset(0); }
double GetDisplayLeftOffsetDouble(int adjusted = 0) { return _LeftOffset[adjusted] / Scale.X; }
double GetDisplayTopOffsetDouble(int adjusted = 0) { return _TopOffset[adjusted] / Scale.Y; }
int GetTexelWidth() { return Width; }
int GetTexelHeight() { return Height; }
int GetWidth() { return Width; }
int GetHeight() { return Height; }
int GetTexelLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
int GetTexelTopOffset(int adjusted) { return _TopOffset[adjusted]; }
@ -304,8 +300,8 @@ public:
void CopySize(FTexture* BaseTexture)
{
Width = BaseTexture->GetTexelWidth();
Height = BaseTexture->GetTexelHeight();
Width = BaseTexture->GetWidth();
Height = BaseTexture->GetHeight();
_TopOffset[0] = BaseTexture->_TopOffset[0];
_TopOffset[1] = BaseTexture->_TopOffset[1];
_LeftOffset[0] = BaseTexture->_LeftOffset[0];
@ -330,7 +326,6 @@ public:
static bool SmoothEdges(unsigned char * buffer,int w, int h);
protected:
DVector2 Scale;
int SourceLump;
@ -447,6 +442,7 @@ public:
bHasCanvas = true;
bTranslucent = false;
bExpandSprite = false;
aspectRatio = (float)width / height;
}
void NeedUpdate() { bNeedsUpdate = true; }
@ -458,6 +454,7 @@ protected:
bool bNeedsUpdate = true;
public:
bool bFirstUpdate = true;
float aspectRatio;
friend struct FCanvasTextureInfo;
};
@ -529,7 +526,6 @@ struct FTexCoordInfo
float RowOffset(float ofs) const;
float TextureOffset(float ofs) const;
float TextureAdjustWidth() const;
void GetFromTexture(FTexture *tex, float x, float y, bool forceworldpanning);
void GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning);
};
@ -593,6 +589,10 @@ class FGameTexture
FTextureID id;
uint16_t TexelWidth, TexelHeight;
float DisplayWidth, DisplayHeight;
float ScaleX, ScaleY;
int8_t shouldUpscaleFlag = 0; // Without explicit setup, scaling is disabled for a texture.
ETextureType UseType = ETextureType::Wall; // This texture's primary purpose
SpritePositioningInfo* spi = nullptr;
@ -604,11 +604,23 @@ public:
FGameTexture(FTexture* wrap) : Base(wrap)
{
id.SetInvalid();
TexelWidth = Base->GetWidth();
DisplayWidth = (float)TexelWidth;
TexelHeight = Base->GetHeight();
DisplayHeight = (float)TexelHeight;
ScaleX = ScaleY = 1.f;
}
~FGameTexture();
FTextureID GetID() const { return id; }
void SetID(FTextureID newid) { id = newid; } // should only be called by the texture manager
float GetScaleX() { return ScaleX; }
float GetScaleY() { return ScaleY; }
float GetDisplayWidth() const { return DisplayWidth; }
float GetDisplayHeight() const { return DisplayHeight; }
int GetTexelWidth() const { return TexelWidth; }
int GetTexelHeight() const { return TexelHeight; }
void CreateDefaultBrightmap();
void AddAutoMaterials();
bool ShouldExpandSprite();
@ -623,10 +635,6 @@ public:
int GetSourceLump() const { return Base->GetSourceLump(); }
void SetBrightmap(FGameTexture* tex) { Brightmap = tex->GetTexture(); }
double GetDisplayWidth() /*const*/ { return Base->GetDisplayWidthDouble(); }
double GetDisplayHeight() /*const*/ { return Base->GetDisplayHeightDouble(); }
int GetTexelWidth() /*const*/ { return Base->GetTexelWidth(); }
int GetTexelHeight() /*const*/ { return Base->GetTexelHeight(); }
int GetTexelLeftOffset(int adjusted = 0) /*const*/ { return Base->GetTexelLeftOffset(adjusted); }
int GetTexelTopOffset(int adjusted = 0) /*const*/ { return Base->GetTexelTopOffset(adjusted); }
double GetDisplayLeftOffset(int adjusted = 0) /*const*/ { return Base->GetDisplayLeftOffsetDouble(adjusted); }
@ -716,8 +724,19 @@ public:
bool isUserContent() const;
int CheckRealHeight() { return Base->CheckRealHeight(); }
bool isSkybox() const { return Base->isSkybox(); }
void SetSize(int x, int y) { Base->SetSize(x, y); }
void SetDisplaySize(float w, float h) { Base->SetSize((int)w, (int)h); }
void SetSize(int x, int y)
{
TexelWidth = x;
TexelHeight = y;
SetDisplaySize(float(x), float(y));
}
void SetDisplaySize(float w, float h)
{
DisplayWidth = w;
DisplayHeight = h;
ScaleX = w / TexelWidth;
ScaleY = h / TexelHeight;
}
const SpritePositioningInfo& GetSpritePositioning(int which) { if (spi == nullptr) SetupSpriteData(); return spi[which]; }
int GetAreas(FloatRect** pAreas) const { return Base->GetAreas(pAreas); }

View file

@ -2670,10 +2670,13 @@ static void CheckForHacks(BuildInfo& buildinfo)
buildinfo.Name[2] == 'Y' &&
buildinfo.Name[3] >= '1' &&
buildinfo.Name[3] <= '3' &&
buildinfo.Height == 128)
buildinfo.Height == 128 &&
buildinfo.Parts.Size() == 1)
{
buildinfo.Height = 200;
buildinfo.texture->SetSize(buildinfo.texture->GetTexelWidth(), 200);
// This must alter the size of both the texture image and the game texture.
buildinfo.Height = buildinfo.Parts[0].Image->GetHeight();
buildinfo.texture->GetTexture()->SetSize(buildinfo.texture->GetTexelWidth(), buildinfo.Height);
buildinfo.texture->SetSize(buildinfo.texture->GetTexelWidth(), buildinfo.Height);
return;
}

View file

@ -709,7 +709,8 @@ void FTextureAnimator::ParseCameraTexture(FScanner &sc)
sc.MustGetNumber ();
height = sc.Number;
FTextureID picnum = TexMan.CheckForTexture (picname, ETextureType::Flat, texflags);
FGameTexture *viewer = MakeGameTexture(new FCanvasTexture (picname, width, height), ETextureType::Wall);
auto canvas = new FCanvasTexture(picname, width, height);
FGameTexture *viewer = MakeGameTexture(canvas, ETextureType::Wall);
if (picnum.Exists())
{
auto oldtex = TexMan.GameTexture(picnum);
@ -750,6 +751,7 @@ void FTextureAnimator::ParseCameraTexture(FScanner &sc)
sc.UnGet();
}
}
canvas->aspectRatio = (float)fitwidth / (float)fitheight;
viewer->SetDisplaySize((float)fitwidth, (float)fitheight);
}

View file

@ -306,7 +306,7 @@ void FGLRenderer::BindToFrameBuffer(FTexture *tex)
FHardwareTexture::Unbind(0);
gl_RenderState.ClearLastMaterial();
}
BaseLayer->BindToFrameBuffer(tex->GetTexelWidth(), tex->GetTexelHeight());
BaseLayer->BindToFrameBuffer(tex->GetWidth(), tex->GetHeight());
}
//===========================================================================
@ -319,15 +319,15 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
{
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble();
float ratio = tex->aspectRatio;
StartOffscreen();
BindToFrameBuffer(tex);
IntRect bounds;
bounds.left = bounds.top = 0;
bounds.width = FHardwareTexture::GetTexDimension(tex->GetTexelWidth());
bounds.height = FHardwareTexture::GetTexDimension(tex->GetTexelHeight());
bounds.width = FHardwareTexture::GetTexDimension(tex->GetWidth());
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
FRenderViewpoint texvp;
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, ratio, ratio, false, false);

View file

@ -337,8 +337,8 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
}
else
{
w = tex->GetTexelWidth();
h = tex->GetTexelHeight();
w = tex->GetWidth();
h = tex->GetHeight();
}
if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, "FHardwareTexture.BindOrCreate"))
{

View file

@ -379,15 +379,15 @@ void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint,
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
auto BaseLayer = static_cast<PolyHardwareTexture*>(tex->GetHardwareTexture(0, 0));
float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble();
float ratio = tex->aspectRatio;
DCanvas *image = BaseLayer->GetImage(tex, 0, 0);
PolyDepthStencil *depthStencil = BaseLayer->GetDepthStencil(tex);
mRenderState->SetRenderTarget(image, depthStencil, false);
IntRect bounds;
bounds.left = bounds.top = 0;
bounds.width = std::min(tex->GetTexelWidth(), image->GetWidth());
bounds.height = std::min(tex->GetTexelHeight(), image->GetHeight());
bounds.width = std::min(tex->GetWidth(), image->GetWidth());
bounds.height = std::min(tex->GetHeight(), image->GetHeight());
FRenderViewpoint texvp;
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, ratio, ratio, false, false);

View file

@ -84,8 +84,8 @@ PolyDepthStencil *PolyHardwareTexture::GetDepthStencil(FTexture *tex)
{
if (!mDepthStencil)
{
int w = tex->GetTexelWidth();
int h = tex->GetTexelHeight();
int w = tex->GetWidth();
int h = tex->GetHeight();
mDepthStencil.reset(new PolyDepthStencil(w, h));
}
return mDepthStencil.get();
@ -148,8 +148,8 @@ void PolyHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
}
else
{
int w = tex->GetTexelWidth();
int h = tex->GetTexelHeight();
int w = tex->GetWidth();
int h = tex->GetHeight();
mCanvas->Resize(w, h, false);
}
}

View file

@ -517,7 +517,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
{
auto BaseLayer = static_cast<VkHardwareTexture*>(tex->GetHardwareTexture(0, 0));
float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble();
float ratio = tex->aspectRatio;
VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0);
VkTextureImage *depthStencil = BaseLayer->GetDepthStencil(tex);
@ -531,8 +531,8 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
IntRect bounds;
bounds.left = bounds.top = 0;
bounds.width = std::min(tex->GetTexelWidth(), image->Image->width);
bounds.height = std::min(tex->GetTexelHeight(), image->Image->height);
bounds.width = std::min(tex->GetWidth(), image->Image->width);
bounds.height = std::min(tex->GetHeight(), image->Image->height);
FRenderViewpoint texvp;
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, ratio, ratio, false, false);

View file

@ -172,8 +172,8 @@ VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex)
auto fb = GetVulkanFrameBuffer();
VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat;
int w = tex->GetTexelWidth();
int h = tex->GetTexelHeight();
int w = tex->GetWidth();
int h = tex->GetHeight();
ImageBuilder builder;
builder.setSize(w, h);
@ -208,8 +208,8 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
auto fb = GetVulkanFrameBuffer();
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
int w = tex->GetTexelWidth();
int h = tex->GetTexelHeight();
int w = tex->GetWidth();
int h = tex->GetHeight();
ImageBuilder imgbuilder;
imgbuilder.setFormat(format);