- major refactor of texture upscaling control.

All decisions were done deep inside the texture creation code, leaving zero options to the higher level code for controlling the feature.
Changed this so that the option to upscale must be passed as a parameter to FRenderState::SetMaterial and extended all needed variables to manage the added texture variants.
Still not solved: Material layers need explicit control, not only for scaling but also for filtering.
This commit is contained in:
Christoph Oelckers 2020-04-16 23:37:22 +02:00
parent 0b990f0dcb
commit 8505c7ee7d
27 changed files with 144 additions and 129 deletions

View file

@ -409,22 +409,10 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
{
// [BB] Make sure that inWidth and inHeight denote the size of
// the returned buffer even if we don't upsample the input buffer.
int inWidth = texbuffer.mWidth;
int inHeight = texbuffer.mHeight;
// [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared.
const int maxInputSize = gl_texture_hqresize_maxinputsize;
if (inWidth * inHeight > maxInputSize * maxInputSize)
return;
// [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!)
if (bHasCanvas)
return;
// already scaled?
if (Scale.X >= 2 && Scale.Y >= 2)
return;
int type = gl_texture_hqresizemode;
int mult = gl_texture_hqresizemult;
#ifdef HAVE_MMX
@ -493,3 +481,33 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
contentId.scalefactor = mult;
texbuffer.mContentId = contentId.id;
}
bool shouldUpscale(FGameTexture *tex, ETextureType UseType)
{
// [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared.
const int maxInputSize = gl_texture_hqresize_maxinputsize;
if (tex->GetTexelWidth() * tex->GetTexelHeight() > maxInputSize * maxInputSize)
return false;
// [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!)
if (tex->isHardwareCanvas())
return false;
// already scaled?
if (tex->GetDisplayWidth() >= 2* tex->GetTexelWidth() || tex->GetDisplayHeight() >= 2*tex->GetTexelHeight())
return false;
switch (UseType)
{
case ETextureType::Sprite:
case ETextureType::SkinSprite:
return !!(gl_texture_hqresize_targets & 2);
case ETextureType::FontChar:
return !!(gl_texture_hqresize_targets & 4);
default:
return !!(gl_texture_hqresize_targets & 1);
}
}

View file

@ -36,7 +36,7 @@ IHardwareTexture* CreateHardwareTexture();
//
//===========================================================================
FMaterial::FMaterial(FGameTexture * tx, bool expanded)
FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
{
mShaderIndex = SHADER_Default;
sourcetex = tx;
@ -122,10 +122,10 @@ FMaterial::FMaterial(FGameTexture * tx, bool expanded)
}
}
}
mExpanded = expanded;
mScaleFlags = scaleflags;
mTextureLayers.ShrinkToFit();
imgtex->Material[expanded] = this;
imgtex->Material[scaleflags] = this;
if (tx->isHardwareCanvas()) tx->SetTranslucent(false);
}
@ -151,7 +151,7 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer)
FTexture *layer = i == 0 ? imgtex : mTextureLayers[i - 1];
if (pLayer) *pLayer = layer;
if (layer) return layer->GetHardwareTexture(translation, mExpanded);
if (layer) return layer->GetHardwareTexture(translation, mScaleFlags);
return nullptr;
}
@ -162,17 +162,17 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer)
//
//==========================================================================
FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, bool expand, bool create)
FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool create)
{
if (gtex && gtex->isValid())
{
auto tex = gtex->GetTexture();
if (!tex->ShouldExpandSprite()) expand = false;
if (!tex->ShouldExpandSprite()) scaleflags &= ~CTF_Expand;
FMaterial *hwtex = tex->Material[expand];
FMaterial *hwtex = tex->Material[scaleflags];
if (hwtex == NULL && create)
{
hwtex = new FMaterial(gtex, expand);
hwtex = new FMaterial(gtex, scaleflags);
}
return hwtex;
}

View file

@ -20,16 +20,17 @@ class FMaterial
TArray<FTexture*> mTextureLayers;
int mShaderIndex;
int mLayerFlags = 0;
bool mExpanded;
int mScaleFlags;
public:
FGameTexture *sourcetex; // the owning texture.
FTexture* imgtex; // the first layer's texture image - should be moved into the array
FMaterial(FGameTexture *tex, bool forceexpand);
FMaterial(FGameTexture *tex, int scaleflags);
~FMaterial();
int GetLayerFlags() const { return mLayerFlags; }
int GetShaderIndex() const { return mShaderIndex; }
int GetScaleFlags() const { return mScaleFlags; }
FGameTexture* Source() const
{
@ -45,10 +46,6 @@ public:
//ValidateTexture(tex, false);
mTextureLayers.Push(tex);
}
bool isExpanded() const
{
return mExpanded;
}
int GetLayers() const
{
@ -58,7 +55,7 @@ public:
IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr) const;
static FMaterial *ValidateTexture(FGameTexture * tex, bool expand, bool create = true);
static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true);
const TArray<FTexture*> &GetLayerArray() const
{
return mTextureLayers;

View file

@ -7,6 +7,15 @@
struct FTextureBuffer;
class IHardwareTexture;
enum ECreateTexBufferFlags
{
CTF_Expand = 1, // create buffer with a one-pixel wide border
CTF_Upscale = 2, // Upscale the texture
CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation.
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
};
class FHardwareTextureContainer
{
public:
@ -40,20 +49,20 @@ private:
private:
TranslatedTexture hwDefTex[2];
TranslatedTexture hwDefTex[4];
TArray<TranslatedTexture> hwTex_Translated;
TranslatedTexture * GetTexID(int translation, bool expanded)
TranslatedTexture * GetTexID(int translation, int scaleflags)
{
auto remap = GPalette.TranslationToTable(translation);
translation = remap == nullptr ? 0 : remap->Index;
if (translation == 0)
if (translation == 0 && !(scaleflags & CTF_Upscale))
{
return &hwDefTex[expanded];
return &hwDefTex[scaleflags];
}
if (expanded) translation = -translation;
translation |= (scaleflags << 24);
// normally there aren't more than very few different
// translations here so this isn't performance critical.
unsigned index = hwTex_Translated.FindEx([=](auto &element)
@ -73,31 +82,28 @@ private:
public:
void Clean(bool cleannormal, bool cleanexpanded)
void Clean(bool reallyclean)
{
if (cleannormal) hwDefTex[0].Delete();
if (cleanexpanded) hwDefTex[1].Delete();
hwDefTex[0].DeleteDescriptors();
hwDefTex[1].DeleteDescriptors();
for (int i = hwTex_Translated.Size() - 1; i >= 0; i--)
{
if (cleannormal && hwTex_Translated[i].translation > 0) hwTex_Translated.Delete(i);
else if (cleanexpanded && hwTex_Translated[i].translation < 0) hwTex_Translated.Delete(i);
for (unsigned int j = 0; j < hwTex_Translated.Size(); j++)
hwTex_Translated[j].DeleteDescriptors();
for (unsigned int j = 0; j < hwTex_Translated.Size(); j++)
hwTex_Translated[j].DeleteDescriptors();
}
if (!reallyclean) return;
hwDefTex[0].Delete();
hwDefTex[1].Delete();
hwTex_Translated.Clear();
}
IHardwareTexture * GetHardwareTexture(int translation, bool expanded)
IHardwareTexture * GetHardwareTexture(int translation, int scaleflags)
{
auto tt = GetTexID(translation, expanded);
auto tt = GetTexID(translation, scaleflags);
return tt->hwTexture;
}
void AddHardwareTexture(int translation, bool expanded, IHardwareTexture *tex)
void AddHardwareTexture(int translation, int scaleflags, IHardwareTexture *tex)
{
auto tt = GetTexID(translation, expanded);
auto tt = GetTexID(translation, scaleflags);
tt->Delete();
tt->hwTexture =tex;
}
@ -109,16 +115,15 @@ public:
//
//===========================================================================
void CleanUnused(SpriteHits &usedtranslations, bool expanded)
void CleanUnused(SpriteHits &usedtranslations, int scaleflags)
{
if (usedtranslations.CheckKey(0) == nullptr)
{
hwDefTex[expanded].Delete();
hwDefTex[scaleflags].Delete();
}
int fac = expanded ? -1 : 1;
for (int i = hwTex_Translated.Size()-1; i>= 0; i--)
{
if (usedtranslations.CheckKey(hwTex_Translated[i].translation * fac) == nullptr)
if (usedtranslations.CheckKey(hwTex_Translated[i].translation & 0xffffff) == nullptr)
{
hwTex_Translated.Delete(i);
}

View file

@ -688,27 +688,10 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
result.mWidth = W;
result.mHeight = H;
bool upscale = true;
switch (UseType)
{
case ETextureType::Sprite:
case ETextureType::SkinSprite:
if (!(gl_texture_hqresize_targets & 2)) upscale = false;
break;
case ETextureType::FontChar:
if (!(gl_texture_hqresize_targets & 4)) upscale = false;
break;
default:
if (!(gl_texture_hqresize_targets & 1)) upscale = false;
break;
}
// Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.)
if (GetImage() && flags & CTF_ProcessData)
{
if (upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
}
@ -738,7 +721,7 @@ bool FTexture::DetermineTranslucency()
void FTexture::CleanHardwareTextures(bool reallyclean)
{
SystemTextures.Clean(reallyclean, reallyclean);
SystemTextures.Clean(reallyclean);
}
//===========================================================================
@ -964,15 +947,15 @@ void FTexture::SetSpriteRect()
//
//===========================================================================
IHardwareTexture* FTexture::GetHardwareTexture(int translation, bool expanded)
IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags)
{
if (UseType != ETextureType::Null)
{
IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, expanded);
IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags);
if (hwtex == nullptr)
{
hwtex = CreateHardwareTexture();
SystemTextures.AddHardwareTexture(translation, expanded, hwtex);
SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex);
}
return hwtex;
}

View file

@ -120,15 +120,6 @@ struct FloatRect
}
};
enum ECreateTexBufferFlags
{
CTF_Expand = 2, // create buffer with a one-pixel wide border
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
};
class FBitmap;
struct FRemapTable;
struct FCopyInfo;
@ -258,7 +249,7 @@ public:
SpritePositioningInfo *spi = nullptr;
IHardwareTexture* GetHardwareTexture(int translation, bool expanded);
IHardwareTexture* GetHardwareTexture(int translation, int scaleflags);
static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype);
virtual ~FTexture ();
virtual FImageSource *GetImage() const { return nullptr; }
@ -369,7 +360,7 @@ protected:
int SourceLump;
FTextureID id;
FMaterial *Material[2] = { nullptr, nullptr };
FMaterial *Material[4] = { };
public:
FHardwareTextureContainer SystemTextures;
protected:
@ -534,7 +525,7 @@ public:
FWrapperTexture(int w, int h, int bits = 1);
IHardwareTexture *GetSystemTexture()
{
return SystemTextures.GetHardwareTexture(0, false);
return SystemTextures.GetHardwareTexture(0, 0);
}
int GetColorFormat() const
@ -764,6 +755,7 @@ inline FGameTexture* MakeGameTexture(FTexture* tex)
return new FGameTexture(tex);
}
bool shouldUpscale(FGameTexture* tex, ETextureType UseType);
#endif

View file

@ -297,7 +297,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
void FGLRenderer::BindToFrameBuffer(FTexture *tex)
{
auto BaseLayer = static_cast<FHardwareTexture*>(tex->GetHardwareTexture(0, false));
auto BaseLayer = static_cast<FHardwareTexture*>(tex->GetHardwareTexture(0, 0));
if (BaseLayer == nullptr)
{

View file

@ -323,7 +323,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio
int usebright = false;
int maxbound = 0;
int flags = mat->isExpanded() ? CTF_Expand : 0;
int flags = mat->GetScaleFlags();
int numLayers = mat->GetLayers();
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation));
@ -333,7 +333,8 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio
{
FTexture *layer;
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0);
// fixme: Upscale flags must be disabled for certain layers.
systex->BindOrCreate(layer, i, clampmode, 0, flags);
maxbound = i;
}
}

View file

@ -310,7 +310,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
{
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
int flags = mat->isExpanded() ? CTF_Expand : 0;
int flags = mat->GetScaleFlags();
int numLayers = mat->GetLayers();
FTexture* layer;
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
@ -320,7 +320,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
for (int i = 1; i < numLayers; i++)
{
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0);
systex->BindOrCreate(layer, i, CLAMP_NONE, 0, flags);
}
}
// unbind everything.

View file

@ -114,7 +114,7 @@ void FHWModelRenderer::SetInterpolation(double inter)
void FHWModelRenderer::SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation)
{
state.SetMaterial(skin, false, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1);
state.SetMaterial(skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1);
state.SetLightIndex(modellightindex);
}

View file

@ -66,7 +66,8 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
state.SetTextureMode(decal->RenderStyle);
state.SetRenderStyle(decal->RenderStyle);
state.SetMaterial(texture, false, CLAMP_XY, decal->Translation, -1);
int flags = shouldUpscale(texture, ETextureType::Sprite) ? CTF_Upscale : 0;
state.SetMaterial(texture, flags, CLAMP_XY, decal->Translation, -1);
// If srcalpha is one it looks better with a higher alpha threshold

View file

@ -204,7 +204,8 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
void HWFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state)
{
state.SetMaterial(texture, false, CLAMP_NONE, 0, -1);
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1);
// Draw the subsectors assigned to it due to missing textures
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
@ -236,7 +237,8 @@ void HWFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state)
// This requires a stencil because the projected plane interferes with
// the depth buffer
state.SetMaterial(texture, false, CLAMP_NONE, 0, -1);
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1);
// Draw the subsectors assigned to it due to missing textures
auto pNode = (renderflags&SSRF_RENDERFLOOR) ?
@ -322,16 +324,17 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
}
else if (!translucent)
{
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
if (sector->special != GLSector_Skybox)
{
state.SetMaterial(texture, false, CLAMP_NONE, 0, -1);
state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1);
state.SetPlaneTextureRotation(&plane, texture);
DrawSubsectors(di, state);
state.EnableTextureMatrix(false);
}
else if (!hacktype)
{
state.SetMaterial(texture, false, CLAMP_XY, 0, -1);
state.SetMaterial(texture, flags, CLAMP_XY, 0, -1);
state.SetLightIndex(dynlightindex);
state.Draw(DT_TriangleStrip,iboindex, 4);
flatvertices += 4;
@ -352,7 +355,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
{
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
else state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetMaterial(texture, false, CLAMP_NONE, 0, -1);
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1);
state.SetPlaneTextureRotation(&plane, texture);
DrawSubsectors(di, state);
state.EnableTextureMatrix(false);

View file

@ -975,7 +975,8 @@ void HWHorizonPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
}
state.SetMaterial(texture, false, CLAMP_NONE, 0, -1);
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1);
state.SetObjectColor(origin->specialcolor);
state.SetPlaneTextureRotation(sp, texture);

View file

@ -569,10 +569,10 @@ public:
mTextureModeFlags = mat->GetLayerFlags();
}
void SetMaterial(FGameTexture* tex, bool expandmode, int clampmode, int translation, int overrideshader)
void SetMaterial(FGameTexture* tex, int scaleflags, int clampmode, int translation, int overrideshader)
{
expandmode &= tex->expandSprites();
SetMaterial(FMaterial::ValidateTexture(tex, expandmode), clampmode, translation, overrideshader);
if (!tex->expandSprites()) scaleflags &= ~CTF_Expand;
SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader);
}
void SetClipSplit(float bottom, float top)

View file

@ -52,9 +52,10 @@ void HWSkyPortal::RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim,
void HWSkyPortal::RenderDome(HWDrawInfo *di, FRenderState &state, FGameTexture * tex, float x_offset, float y_offset, bool mirror, int mode)
{
int flags = shouldUpscale(tex, ETextureType::Wall) ? CTF_Upscale : 0;
if (tex)
{
state.SetMaterial(tex, false, CLAMP_NONE, 0, -1);
state.SetMaterial(tex, flags, CLAMP_NONE, 0, -1);
state.EnableModelMatrix(true);
state.EnableTextureMatrix(true);
@ -106,39 +107,41 @@ void HWSkyPortal::RenderBox(HWDrawInfo *di, FRenderState &state, FTextureID texn
else
state.mModelMatrix.rotate(-180.0f+x_offset, di->Level->info->skyrotatevector2.X, di->Level->info->skyrotatevector2.Z, di->Level->info->skyrotatevector2.Y);
if (tex->GetSkyFace(5))
// Only test the first face - the result here must be consistent - either all get scaled or none.
int flags = shouldUpscale(tex->GetSkyFace(0), ETextureType::Flat) ? CTF_Upscale : 0;
if (tex->GetSkyFace(5))
{
faces=4;
// north
state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(0), 4);
// east
state.SetMaterial(tex->GetSkyFace(1), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(1), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(1), 4);
// south
state.SetMaterial(tex->GetSkyFace(2), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(2), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(2), 4);
// west
state.SetMaterial(tex->GetSkyFace(3), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(3), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(3), 4);
}
else
{
faces=1;
state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(-1), 10);
}
// top
state.SetMaterial(tex->GetSkyFace(faces), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(faces), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(tex->GetSkyFlip() ? 6 : 5), 4);
// bottom
state.SetMaterial(tex->GetSkyFace(faces+1), false, CLAMP_XY, 0, -1);
state.SetMaterial(tex->GetSkyFace(faces+1), flags, CLAMP_XY, 0, -1);
state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(4), 4);
state.EnableModelMatrix(false);

View file

@ -198,7 +198,9 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
}
uint32_t spritetype = (actor->renderflags & RF_SPRITETYPEMASK);
if (texture) state.SetMaterial(texture, spritetype == RF_FACESPRITE, CLAMP_XY, translation, OverrideShader);
int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
if (spritetype == RF_FACESPRITE) flags |= CTF_Expand;
if (texture) state.SetMaterial(texture, flags, CLAMP_XY, translation, OverrideShader);
else if (!modelframe) state.EnableTexture(false);
//SetColor(lightlevel, rel, Colormap, trans);

View file

@ -156,7 +156,8 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
state.SetGlowParams(topglowcolor, bottomglowcolor);
state.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane);
}
state.SetMaterial(texture, false, flags & 3, 0, -1);
int uflags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0;
state.SetMaterial(texture, uflags, flags & 3, 0, -1);
if (type == RENDERWALL_M2SNF)
{

View file

@ -96,7 +96,8 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
{
float thresh = (huds->texture->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold;
state.AlphaFunc(Alpha_GEqual, thresh);
state.SetMaterial(huds->texture, true, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader);
int flags = shouldUpscale(huds->texture, ETextureType::Flat) ? CTF_Upscale|CTF_Expand : CTF_Expand;
state.SetMaterial(huds->texture, flags, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader);
state.Draw(DT_TriangleStrip, huds->mx, 4);
}

View file

@ -62,7 +62,7 @@ static void PrecacheTexture(FGameTexture *tex, int cache)
//===========================================================================
static void PrecacheList(FMaterial *gltex, SpriteHits& translations)
{
gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->isExpanded());
gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->GetScaleFlags());
SpriteHits::Iterator it(translations);
SpriteHits::Pair* pair;
while (it.NextPair(pair)) screen->PrecacheMaterial(gltex, pair->Key);
@ -252,7 +252,8 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
{
if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
{
if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, false) == nullptr)
int flags = shouldUpscale(gtex, ETextureType::Wall) ? CTF_Upscale : 0;
if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, flags) == nullptr)
{
FImageSource::RegisterForPrecache(tex->GetImage(), V_IsTrueColor());
}

View file

@ -164,7 +164,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
if (cmd.mTexture != nullptr && cmd.mTexture->isValid())
{
state.SetMaterial(cmd.mTexture, false, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1);
state.SetMaterial(cmd.mTexture, 0, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1);
state.EnableTexture(true);
// Canvas textures are stored upside down

View file

@ -377,7 +377,7 @@ sector_t *PolyFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * ca
void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
// 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, false));
auto BaseLayer = static_cast<PolyHardwareTexture*>(tex->GetHardwareTexture(0, 0));
float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble();
DCanvas *image = BaseLayer->GetImage(tex, 0, 0);
@ -535,7 +535,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
{
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
int flags = mat->isExpanded() ? CTF_Expand : 0;
int flags = mat->GetScaleFlags();
FTexture* layer;
auto systex = static_cast<PolyHardwareTexture*>(mat->GetLayer(0, translation, &layer));
systex->GetImage(layer, translation, flags);
@ -544,7 +544,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
for (int i = 1; i < numLayers; i++)
{
auto systex = static_cast<PolyHardwareTexture*>(mat->GetLayer(i, 0, &layer));
systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0);
systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers.
}
}

View file

@ -68,7 +68,7 @@ DCanvas *PolyHardwareTexture::GetImage(FTexture *baselayer, const FMaterialState
if (!mCanvas)
{
int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0;
int flags = state.mMaterial->GetScaleFlags();
return GetImage(baselayer, state.mTranslation, flags);
}

View file

@ -327,7 +327,7 @@ void PolyRenderState::ApplyMaterial()
FTexture* layer;
auto systex = static_cast<PolyHardwareTexture*>(mMaterial.mMaterial->GetLayer(i, 0, &layer));
texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->isExpanded() ? CTF_Expand : 0);
texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->GetScaleFlags());
mDrawCommands->SetTexture(i, texcanvas->GetPixels(), texcanvas->GetWidth(), texcanvas->GetHeight(), texcanvas->IsBgra());
}
}

View file

@ -94,7 +94,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player)
FBTextureIndex = (FBTextureIndex + 1) % 2;
auto &fbtex = FBTexture[FBTextureIndex];
auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, false); };
auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, 0); };
if (fbtex == nullptr || GetSystemTexture() == nullptr ||
fbtex->GetTexelWidth() != screen->GetWidth() ||

View file

@ -54,8 +54,10 @@ FSoftwareTexture::FSoftwareTexture(FGameTexture *tex)
mSource = tex->GetTexture();
mBufferFlags = CTF_ProcessData;
auto f = mBufferFlags;
if (shouldUpscale(tex, tex->GetUseType())) f |= CTF_Upscale;
// calculate the real size after running the scaler.
auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| f);
mPhysicalWidth = info.mWidth;
mPhysicalHeight = info.mHeight;
mPhysicalScale = tex->GetTexelWidth() > 0 ? mPhysicalWidth / tex->GetTexelWidth() : mPhysicalWidth;
@ -113,6 +115,8 @@ const uint8_t *FSoftwareTexture::GetPixels(int style)
}
else
{
auto f = mBufferFlags;
if (shouldUpscale(mTexture, mTexture->GetUseType())) f |= CTF_Upscale;
auto tempbuffer = mSource->CreateTexBuffer(0, mBufferFlags);
Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight());
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;

View file

@ -515,7 +515,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
auto BaseLayer = static_cast<VkHardwareTexture*>(tex->GetHardwareTexture(0, false));
auto BaseLayer = static_cast<VkHardwareTexture*>(tex->GetHardwareTexture(0, 0));
float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble();
VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0);
@ -648,17 +648,17 @@ void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
int flags = mat->isExpanded() ? CTF_Expand : 0;
int flags = mat->GetScaleFlags();
FTexture* layer;
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(0, translation, &layer));
systex->GetImage(layer, translation, mat->isExpanded() ? CTF_Expand : 0);
systex->GetImage(layer, translation, flags);
int numLayers = mat->GetLayers();
for (int i = 1; i < numLayers; i++)
{
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0);
systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers.
}
}

View file

@ -119,7 +119,7 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
clampmode = base->GetClampMode(clampmode);
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0;
int flags = mat->GetScaleFlags();
for (auto &set : mDescriptorSets)
{
@ -141,7 +141,8 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
{
FTexture *layer;
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0)->View.get(), sampler, systex->mImage.Layout);
// fixme: Upscale flags must be disabled for certain layers.
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, flags)->View.get(), sampler, systex->mImage.Layout);
}
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();