mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- updated to GZDoom's new texture management system.
This commit is contained in:
parent
7a1fda2cc2
commit
c4017de12f
68 changed files with 2046 additions and 1782 deletions
|
@ -783,6 +783,7 @@ set (PCH_SOURCES
|
|||
common/textures/bitmap.cpp
|
||||
common/textures/m_png.cpp
|
||||
common/textures/texture.cpp
|
||||
common/textures/gametexture.cpp
|
||||
common/textures/image.cpp
|
||||
common/textures/imagetexture.cpp
|
||||
common/textures/texturemanager.cpp
|
||||
|
@ -1018,6 +1019,7 @@ include_directories(
|
|||
common/textures
|
||||
common/textures/formats
|
||||
common/textures/hires
|
||||
common/textures
|
||||
common/filesystem
|
||||
common/utility
|
||||
common/console
|
||||
|
|
|
@ -856,7 +856,7 @@ void videoClearScreen(int32_t dacol);
|
|||
void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang);
|
||||
void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *pic = nullptr, int basepal = 0);
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture *pic = nullptr, int basepal = 0);
|
||||
void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col);
|
||||
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p);
|
||||
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p);
|
||||
|
@ -864,13 +864,13 @@ void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p);
|
|||
////////// specialized rotatesprite wrappers for (very) often used cases //////////
|
||||
static FORCE_INLINE void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture* pic = nullptr, int basepal = 0)
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture* pic = nullptr, int basepal = 0)
|
||||
{
|
||||
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2, pic, basepal);
|
||||
}
|
||||
// Don't clip at all, i.e. the whole screen real estate is available:
|
||||
static FORCE_INLINE void rotatesprite_fs(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, FTexture* pic = nullptr, int basepal = 0)
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, FGameTexture* pic = nullptr, int basepal = 0)
|
||||
{
|
||||
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1, pic, basepal);
|
||||
}
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
#define IDP2_MAGIC 0x32504449
|
||||
#define IDP3_MAGIC 0x33504449
|
||||
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
class FHardwareTexture;
|
||||
|
||||
struct mdmodel_t
|
||||
{
|
||||
int32_t mdnum, shadeoff;
|
||||
float scale, bscale, zadd, yoffset;
|
||||
FTexture *texture;
|
||||
FGameTexture *texture;
|
||||
|
||||
int32_t flags;
|
||||
};
|
||||
|
@ -200,7 +200,7 @@ struct voxmodel_t : public mdmodel_t
|
|||
|
||||
EXTERN mdmodel_t **models;
|
||||
|
||||
FTexture* mdloadskin(idmodel_t* m, int32_t number, int32_t pal, int32_t surf, bool* exact);
|
||||
FGameTexture* mdloadskin(idmodel_t* m, int32_t number, int32_t pal, int32_t surf, bool* exact);
|
||||
void mdinit(void);
|
||||
void freeallmodels(void);
|
||||
int32_t polymost_mddraw(tspriteptr_t tspr);
|
||||
|
|
|
@ -50,7 +50,7 @@ void VPXTexture::SetFrame(const void *data_, int width, int height)
|
|||
Width = width;
|
||||
Height = height;
|
||||
data = data_;
|
||||
SystemTextures.Clean(true, true);
|
||||
SystemTextures.Clean();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -412,27 +412,27 @@ read_ivf_frame:
|
|||
|
||||
/////////////// DRAWING! ///////////////
|
||||
static int sampler;
|
||||
static VPXTexture* vpxtex[2];
|
||||
static FGameTexture* vpxtex[2];
|
||||
static int which;
|
||||
|
||||
void animvpx_setup_glstate(int32_t animvpx_flags)
|
||||
{
|
||||
////////// GL STATE //////////
|
||||
vpxtex[0] = new VPXTexture;
|
||||
vpxtex[1] = new VPXTexture;
|
||||
vpxtex[0] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special);
|
||||
vpxtex[1] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special);
|
||||
|
||||
if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && hw_texfilter == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER ||
|
||||
(!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs
|
||||
(!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs
|
||||
{
|
||||
sampler = SamplerClampXY;
|
||||
sampler = CLAMP_XY;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampler = SamplerNoFilterClampXY;
|
||||
sampler = CLAMP_XY;
|
||||
}
|
||||
|
||||
|
||||
GLInterface.ClearScreen(0, true);
|
||||
GLInterface.ClearScreen(0, true);
|
||||
}
|
||||
|
||||
void animvpx_restore_glstate(void)
|
||||
|
@ -454,7 +454,8 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
|
|||
return 2; // shouldn't happen
|
||||
|
||||
which ^= 1;
|
||||
vpxtex[which]->SetFrame(codec->pic, codec->width, codec->height);
|
||||
static_cast<VPXTexture*>(vpxtex[which]->GetTexture())->SetFrame(codec->pic, codec->width, codec->height);
|
||||
vpxtex[which]->CleanHardwareData();
|
||||
|
||||
float vid_wbyh = ((float)codec->width)/codec->height;
|
||||
if (animvpx_aspect > 0)
|
||||
|
|
|
@ -3083,7 +3083,7 @@ static int32_t dorotspr_handle_bit2(int32_t* sxptr, int32_t* syptr, int32_t* z,
|
|||
|
||||
void twod_rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FTexture* pic, int basepal)
|
||||
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FGameTexture* pic, int basepal)
|
||||
{
|
||||
F2DDrawer::RenderCommand dg = {};
|
||||
int method = 0;
|
||||
|
@ -3122,7 +3122,7 @@ void twod_rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t pic
|
|||
int light = clamp(scale((numshades - dashade), 255, numshades), 0, 255);
|
||||
auto p = PalEntry((uint8_t)(alpha * 255), light, light, light);
|
||||
|
||||
vec2_t const siz = { dg.mTexture->GetDisplayWidth(), dg.mTexture->GetDisplayHeight() };
|
||||
vec2_t const siz = { (int)dg.mTexture->GetDisplayWidth(), (int)dg.mTexture->GetDisplayHeight() };
|
||||
vec2_16_t ofs = { 0, 0 };
|
||||
|
||||
if (!(dastat & RS_TOPLEFT))
|
||||
|
@ -5327,7 +5327,7 @@ void renderSetAspect(int32_t daxrange, int32_t daaspect)
|
|||
//
|
||||
void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *tex, int basepal)
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture *tex, int basepal)
|
||||
{
|
||||
if (!tex && (unsigned)picnum >= MAXTILES)
|
||||
return;
|
||||
|
|
|
@ -463,7 +463,7 @@ int32_t md_undefinemodel(int32_t modelid)
|
|||
|
||||
|
||||
//Note: even though it says md2model, it works for both md2model&md3model
|
||||
FTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bool *exact)
|
||||
FGameTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bool *exact)
|
||||
{
|
||||
int32_t i;
|
||||
mdskinmap_t *sk, *skzero = NULL;
|
||||
|
@ -482,7 +482,7 @@ FTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bo
|
|||
{
|
||||
if (exact) *exact = true;
|
||||
//Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile);
|
||||
return TexMan.GetTexture(sk->texture);
|
||||
return TexMan.GetGameTexture(sk->texture);
|
||||
}
|
||||
//If no match, give highest priority to number, then pal.. (Parkar's request, 02/27/2005)
|
||||
else if ((sk->palette == 0) && (sk->skinnum == number) && (sk->surfnum == surf) && (i < 5)) { i = 5; skzero = sk; }
|
||||
|
@ -501,7 +501,7 @@ FTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bo
|
|||
{
|
||||
//Printf("Using def skin 0,0 as fallback, pal=%d\n", pal);
|
||||
if (exact) *exact = false;
|
||||
return TexMan.GetTexture(skzero->texture);
|
||||
return TexMan.GetGameTexture(skzero->texture);
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -1711,7 +1711,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
|
|||
if (!tex)
|
||||
continue;
|
||||
|
||||
FTexture *det = nullptr, *glow = nullptr;
|
||||
FGameTexture *det = nullptr, *glow = nullptr;
|
||||
float detscale = 1.f;
|
||||
|
||||
// The data lookup here is one incredible mess. Thanks to whoever cooked this up... :(
|
||||
|
|
|
@ -502,7 +502,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
|
|||
{
|
||||
float const r = 1.f / dd[i];
|
||||
|
||||
if (tileGetTexture(globalpicnum)->isCanvas())
|
||||
if (tileGetTexture(globalpicnum)->GetTexture()->isHardwareCanvas())
|
||||
{
|
||||
//update texcoords, canvas textures are upside down!
|
||||
vt->SetTexCoord(
|
||||
|
|
|
@ -234,7 +234,7 @@ void F2DDrawer::AddIndices(int firstvert, TArray<int> &v)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor, RenderCommand &quad)
|
||||
bool F2DDrawer::SetStyle(FGameTexture *tex, DrawParms &parms, PalEntry &vertexcolor, RenderCommand &quad)
|
||||
{
|
||||
FRenderStyle style = parms.style;
|
||||
float alpha;
|
||||
|
@ -390,7 +390,7 @@ void F2DDrawer::SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcol
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
||||
void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
|
||||
{
|
||||
if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn.
|
||||
|
||||
|
@ -472,7 +472,7 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
||||
void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||
{
|
||||
// [MK] bail out if vertex/coord array sizes are mismatched
|
||||
if ( shape->mVertices.Size() != shape->mCoords.Size() )
|
||||
|
@ -550,12 +550,11 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
void F2DDrawer::AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double fadelevel,
|
||||
uint32_t *indices, size_t indexcount)
|
||||
{
|
||||
|
||||
RenderCommand poly;
|
||||
|
||||
poly.mType = DrawTypeTriangles;
|
||||
|
@ -630,7 +629,7 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddPoly(FTexture* img, FVector4* vt, size_t vtcount, unsigned int* ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2)
|
||||
void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigned int* ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2)
|
||||
{
|
||||
RenderCommand dg = {};
|
||||
int method = 0;
|
||||
|
@ -677,7 +676,7 @@ void F2DDrawer::AddPoly(FTexture* img, FVector4* vt, size_t vtcount, unsigned in
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin)
|
||||
{
|
||||
float fU1, fU2, fV1, fV2;
|
||||
|
||||
|
@ -693,17 +692,17 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *
|
|||
// scaling is not used here.
|
||||
if (!local_origin)
|
||||
{
|
||||
fU1 = float(left) / src->GetDisplayWidth();
|
||||
fV1 = float(top) / src->GetDisplayHeight();
|
||||
fU2 = float(right) / src->GetDisplayWidth();
|
||||
fV2 = float(bottom) / src->GetDisplayHeight();
|
||||
fU1 = float(left) / (float)src->GetDisplayWidth();
|
||||
fV1 = float(top) / (float)src->GetDisplayHeight();
|
||||
fU2 = float(right) / (float)src->GetDisplayWidth();
|
||||
fV2 = float(bottom) / (float)src->GetDisplayHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
fU1 = 0;
|
||||
fV1 = 0;
|
||||
fU2 = float(right - left) / src->GetDisplayWidth();
|
||||
fV2 = float(bottom - top) / src->GetDisplayHeight();
|
||||
fU2 = float(right - left) / (float)src->GetDisplayWidth();
|
||||
fV2 = float(bottom - top) / (float)src->GetDisplayHeight();
|
||||
}
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
auto ptr = &mVertices[dg.mVertIndex];
|
||||
|
@ -755,7 +754,7 @@ void F2DDrawer::ClearScreen(PalEntry color)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddLine(float x1, float y1, float x2, float y2, int clipx1, int clipy1, int clipx2, int clipy2, uint32_t color, uint8_t alpha)
|
||||
void F2DDrawer::AddLine(double x1, double y1, double x2, double y2, int clipx1, int clipy1, int clipx2, int clipy2, uint32_t color, uint8_t alpha)
|
||||
{
|
||||
PalEntry p = (PalEntry)color;
|
||||
p.a = alpha;
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
int mIndexIndex;
|
||||
int mIndexCount;
|
||||
|
||||
FTexture *mTexture;
|
||||
FGameTexture *mTexture;
|
||||
int mTranslationId;
|
||||
PalEntry mSpecialColormap[2];
|
||||
int mScissor[4];
|
||||
|
@ -170,19 +170,19 @@ public:
|
|||
void AddIndices(int firstvert, int count, ...);
|
||||
private:
|
||||
void AddIndices(int firstvert, TArray<int> &v);
|
||||
bool SetStyle(FTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad);
|
||||
bool SetStyle(FGameTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad);
|
||||
void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor);
|
||||
|
||||
public:
|
||||
void AddTexture(FTexture *img, DrawParms &parms);
|
||||
void AddShape(FTexture *img, DShape2D *shape, DrawParms &parms);
|
||||
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
void AddTexture(FGameTexture* img, DrawParms& parms);
|
||||
void AddShape(FGameTexture *img, DShape2D *shape, DrawParms &parms);
|
||||
void AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double lightlevel, uint32_t *indices, size_t indexcount);
|
||||
void AddPoly(FTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
|
||||
void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
|
||||
void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
|
||||
int clipx1, int clipy1, int clipx2, int clipy2);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin = false);
|
||||
|
||||
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr);
|
||||
void ClearScreen(PalEntry color = 0xff000000);
|
||||
|
@ -190,7 +190,7 @@ public:
|
|||
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
|
||||
|
||||
void AddLine(float x1, float y1, float x2, float y2, int cx, int cy, int cx2, int cy2, uint32_t color, uint8_t alpha = 255);
|
||||
void AddLine(double x1, double y1, double x2, double y2, int cx, int cy, int cx2, int cy2, uint32_t color, uint8_t alpha = 255);
|
||||
void AddThickLine(int x1, int y1, int x2, int y2, double thickness, uint32_t color, uint8_t alpha = 255);
|
||||
void AddPixel(int x1, int y1, uint32_t color);
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DrawTexture(F2DDrawer *drawer, FTexture* img, double x, double y, int tags_first, ...)
|
||||
void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int tags_first, ...)
|
||||
{
|
||||
Va_List tags;
|
||||
va_start(tags.list, tags_first);
|
||||
|
@ -203,7 +203,7 @@ void DrawTexture(F2DDrawer *drawer, FTexture* img, double x, double y, int tags_
|
|||
|
||||
int ListGetInt(VMVa_List &tags);
|
||||
|
||||
static void DrawTexture(F2DDrawer *drawer, FTexture *img, double x, double y, VMVa_List &args)
|
||||
static void DrawTexture(F2DDrawer *drawer, FGameTexture *img, double x, double y, VMVa_List &args)
|
||||
{
|
||||
DrawParms parms;
|
||||
uint32_t tag = ListGetInt(args);
|
||||
|
@ -224,7 +224,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
|
|||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
FTexture *tex = TexMan.ByIndex(texid, animate);
|
||||
auto tex = TexMan.GameByIndex(texid, animate);
|
||||
VMVa_List args = { param + 4, 0, numparam - 5, va_reginfo + 4 };
|
||||
DrawTexture(twod, tex, x, y, args);
|
||||
return 0;
|
||||
|
@ -236,7 +236,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DrawShape(F2DDrawer *drawer, FTexture *img, DShape2D *shape, int tags_first, ...)
|
||||
void DrawShape(F2DDrawer *drawer, FGameTexture *img, DShape2D *shape, int tags_first, ...)
|
||||
{
|
||||
Va_List tags;
|
||||
va_start(tags.list, tags_first);
|
||||
|
@ -248,7 +248,7 @@ void DrawShape(F2DDrawer *drawer, FTexture *img, DShape2D *shape, int tags_first
|
|||
drawer->AddShape(img, shape, parms);
|
||||
}
|
||||
|
||||
void DrawShape(F2DDrawer *drawer, FTexture *img, DShape2D *shape, VMVa_List &args)
|
||||
void DrawShape(F2DDrawer *drawer, FGameTexture *img, DShape2D *shape, VMVa_List &args)
|
||||
{
|
||||
DrawParms parms;
|
||||
uint32_t tag = ListGetInt(args);
|
||||
|
@ -269,7 +269,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawShape)
|
|||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
FTexture *tex = TexMan.ByIndex(texid, animate);
|
||||
auto tex = TexMan.GameByIndex(texid, animate);
|
||||
VMVa_List args = { param + 3, 0, numparam - 4, va_reginfo + 3 };
|
||||
|
||||
DrawShape(twod, tex, shape, args);
|
||||
|
@ -334,7 +334,7 @@ DEFINE_ACTION_FUNCTION(_Screen, GetClipRect)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double xx, double yy)
|
||||
bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, double xx, double yy)
|
||||
{
|
||||
auto GetWidth = [=]() { return drawer->GetWidth(); };
|
||||
auto GetHeight = [=]() {return drawer->GetHeight(); };
|
||||
|
@ -342,8 +342,8 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
|||
{
|
||||
parms->x = xx;
|
||||
parms->y = yy;
|
||||
parms->texwidth = img->GetDisplayWidthDouble();
|
||||
parms->texheight = img->GetDisplayHeightDouble();
|
||||
parms->texwidth = img->GetDisplayWidth();
|
||||
parms->texheight = img->GetDisplayHeight();
|
||||
if (parms->top == INT_MAX || parms->fortext)
|
||||
{
|
||||
parms->top = img->GetDisplayTopOffset();
|
||||
|
@ -354,11 +354,11 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
|||
}
|
||||
if (parms->destwidth == INT_MAX || parms->fortext)
|
||||
{
|
||||
parms->destwidth = img->GetDisplayWidthDouble();
|
||||
parms->destwidth = img->GetDisplayWidth();
|
||||
}
|
||||
if (parms->destheight == INT_MAX || parms->fortext)
|
||||
{
|
||||
parms->destheight = img->GetDisplayHeightDouble();
|
||||
parms->destheight = img->GetDisplayHeight();
|
||||
}
|
||||
|
||||
switch (parms->cleanmode)
|
||||
|
@ -387,10 +387,12 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
|||
case DTA_FullscreenEx:
|
||||
{
|
||||
double aspect;
|
||||
double srcwidth = img->GetDisplayWidthDouble();
|
||||
double srcheight = img->GetDisplayHeightDouble();
|
||||
double srcwidth = img->GetDisplayWidth();
|
||||
double srcheight = img->GetDisplayHeight();
|
||||
int autoaspect = parms->fsscalemode;
|
||||
aspect = autoaspect == 0 || (srcwidth == 320 && srcheight == 200) || (srcwidth == 640 && srcheight == 400)? 1.333 : srcwidth / srcheight;
|
||||
if (srcheight == 200) aspect = srcwidth / 240.;
|
||||
else if (srcheight == 400) aspect = srcwidth / 480;
|
||||
else aspect = srcwidth / srcheight;
|
||||
parms->x = parms->y = 0;
|
||||
parms->keepratio = true;
|
||||
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
|
||||
|
@ -531,7 +533,7 @@ static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags)
|
|||
//==========================================================================
|
||||
|
||||
template<class T>
|
||||
bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext)
|
||||
bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext)
|
||||
{
|
||||
INTBOOL boolval;
|
||||
int intval;
|
||||
|
@ -724,8 +726,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
if (img == NULL) return false;
|
||||
parms->cleanmode = DTA_Fullscreen;
|
||||
parms->fsscalemode = (uint8_t)twod->fullscreenautoaspect;
|
||||
parms->virtWidth = img->GetDisplayWidthDouble();
|
||||
parms->virtHeight = img->GetDisplayHeightDouble();
|
||||
parms->virtWidth = img->GetDisplayWidth();
|
||||
parms->virtHeight = img->GetDisplayHeight();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -738,8 +740,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
if (img == NULL) return false;
|
||||
parms->cleanmode = DTA_Fullscreen;
|
||||
parms->fsscalemode = (uint8_t)intval;
|
||||
parms->virtWidth = img->GetDisplayWidthDouble();
|
||||
parms->virtHeight = img->GetDisplayHeightDouble();
|
||||
parms->virtWidth = img->GetDisplayWidth();
|
||||
parms->virtHeight = img->GetDisplayHeight();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -785,19 +787,19 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
break;
|
||||
|
||||
case DTA_SrcX:
|
||||
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidthDouble();
|
||||
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidth();
|
||||
break;
|
||||
|
||||
case DTA_SrcY:
|
||||
parms->srcy = ListGetDouble(tags) / img->GetDisplayHeightDouble();
|
||||
parms->srcy = ListGetDouble(tags) / img->GetDisplayHeight();
|
||||
break;
|
||||
|
||||
case DTA_SrcWidth:
|
||||
parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidthDouble();
|
||||
parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidth();
|
||||
break;
|
||||
|
||||
case DTA_SrcHeight:
|
||||
parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeightDouble();
|
||||
parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeight();
|
||||
break;
|
||||
|
||||
case DTA_TopOffset:
|
||||
|
@ -829,8 +831,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
if (fortext) return false;
|
||||
if (ListGetInt(tags))
|
||||
{
|
||||
parms->left = img->GetDisplayWidthDouble() * 0.5;
|
||||
parms->top = img->GetDisplayHeightDouble() * 0.5;
|
||||
parms->left = img->GetDisplayWidth() * 0.5;
|
||||
parms->top = img->GetDisplayHeight() * 0.5;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -839,8 +841,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
if (fortext) return false;
|
||||
if (ListGetInt(tags))
|
||||
{
|
||||
parms->left = img->GetDisplayWidthDouble() * 0.5;
|
||||
parms->top = img->GetDisplayHeightDouble();
|
||||
parms->left = img->GetDisplayWidth() * 0.5;
|
||||
parms->top = img->GetDisplayHeight();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1038,8 +1040,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
|||
}
|
||||
// explicitly instantiate both versions for v_text.cpp.
|
||||
|
||||
template bool ParseDrawTextureTags<Va_List>(F2DDrawer* drawer, FTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext);
|
||||
template bool ParseDrawTextureTags<VMVa_List>(F2DDrawer* drawer, FTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, bool fortext);
|
||||
template bool ParseDrawTextureTags<Va_List>(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext);
|
||||
template bool ParseDrawTextureTags<VMVa_List>(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, bool fortext);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -1131,7 +1133,7 @@ void VirtualToRealCoordsInt(F2DDrawer *drawer, int &x, int &y, int &w, int &h,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FillBorder (F2DDrawer *drawer, FTexture *img)
|
||||
void FillBorder (F2DDrawer *drawer, FGameTexture *img)
|
||||
{
|
||||
auto Width = drawer->GetWidth();
|
||||
auto Height = drawer->GetHeight();
|
||||
|
@ -1351,7 +1353,7 @@ void DrawBorder (F2DDrawer *drawer, FTextureID picnum, int x1, int y1, int x2, i
|
|||
{
|
||||
if (picnum.isValid())
|
||||
{
|
||||
drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetTexture(picnum, false));
|
||||
drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(picnum, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -203,20 +203,21 @@ inline int active_con_scale(F2DDrawer *drawer)
|
|||
#endif
|
||||
|
||||
template<class T>
|
||||
bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, bool fortext);
|
||||
bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, bool fortext);
|
||||
|
||||
template<class T>
|
||||
void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms);
|
||||
bool SetTextureParms(F2DDrawer *drawer, DrawParms* parms, FTexture* img, double x, double y);
|
||||
bool SetTextureParms(F2DDrawer *drawer, DrawParms* parms, FGameTexture* img, double x, double y);
|
||||
|
||||
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...);
|
||||
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...);
|
||||
void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...);
|
||||
void DrawTexture(F2DDrawer* drawer, FTexture* img, double x, double y, int tags_first, ...);
|
||||
|
||||
void DrawTexture(F2DDrawer* drawer, FGameTexture* img, double x, double y, int tags_first, ...);
|
||||
|
||||
void DoDim(F2DDrawer* drawer, PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
|
||||
void Dim(F2DDrawer* drawer, PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
|
||||
void FillBorder(F2DDrawer *drawer, FTexture* img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
|
||||
void FillBorder(F2DDrawer *drawer, FGameTexture* img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
|
||||
|
||||
void DrawFrame(F2DDrawer* drawer, int left, int top, int width, int height);
|
||||
void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2);
|
||||
|
|
|
@ -53,7 +53,7 @@ int ListGetInt(VMVa_List &tags);
|
|||
//
|
||||
//==========================================================================
|
||||
#if 0
|
||||
FTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
||||
FGameTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
||||
{
|
||||
int w;
|
||||
const uint8_t *ch;
|
||||
|
@ -61,7 +61,7 @@ FTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
|||
int cy;
|
||||
int trans = -1;
|
||||
int kerning;
|
||||
FTexture *pic;
|
||||
FGameTexture *pic;
|
||||
|
||||
kerning = font->GetDefaultKerning();
|
||||
|
||||
|
@ -170,7 +170,7 @@ void DrawChar(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double
|
|||
if (normalcolor >= NumTextColors)
|
||||
normalcolor = CR_UNTRANSLATED;
|
||||
|
||||
FTexture* pic;
|
||||
FGameTexture* pic;
|
||||
int dummy;
|
||||
bool redirected;
|
||||
|
||||
|
@ -200,7 +200,7 @@ void DrawChar(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double
|
|||
if (normalcolor >= NumTextColors)
|
||||
normalcolor = CR_UNTRANSLATED;
|
||||
|
||||
FTexture *pic;
|
||||
FGameTexture *pic;
|
||||
int dummy;
|
||||
bool redirected;
|
||||
|
||||
|
@ -256,7 +256,7 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
|
|||
int boldcolor;
|
||||
int trans = -1;
|
||||
int kerning;
|
||||
FTexture *pic;
|
||||
FGameTexture *pic;
|
||||
|
||||
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
|
||||
parms.celly *= parms.scaley;
|
||||
|
|
|
@ -1082,16 +1082,17 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
|||
}
|
||||
FTextureID chk = value;
|
||||
if (chk.GetIndex() >= TexMan.NumTextures()) chk.SetNull();
|
||||
FTexture *pic = TexMan.GetTexture(chk);
|
||||
auto pic = TexMan.GetGameTexture(chk);
|
||||
const char *name;
|
||||
auto lump = pic->GetSourceLump();
|
||||
|
||||
if (fileSystem.GetLinkedTexture(pic->SourceLump) == pic)
|
||||
if (fileSystem.GetLinkedTexture(lump) == pic)
|
||||
{
|
||||
name = fileSystem.GetFileFullName(pic->SourceLump);
|
||||
name = fileSystem.GetFileFullName(lump);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = pic->Name;
|
||||
name = pic->GetName();
|
||||
}
|
||||
arc.WriteKey(key);
|
||||
arc.w->StartArray();
|
||||
|
|
|
@ -57,7 +57,7 @@ extern FILE* hashfile;
|
|||
struct FileSystem::LumpRecord
|
||||
{
|
||||
FResourceLump *lump;
|
||||
FTexture* linkedTexture;
|
||||
FGameTexture* linkedTexture;
|
||||
LumpShortName shortName;
|
||||
FString longName;
|
||||
int rfnum;
|
||||
|
@ -725,7 +725,7 @@ int FileSystem::GetResource (int resid, const char *type, int filenum) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FileSystem::SetLinkedTexture(int lump, FTexture *tex)
|
||||
void FileSystem::SetLinkedTexture(int lump, FGameTexture *tex)
|
||||
{
|
||||
if ((size_t)lump < NumEntries)
|
||||
{
|
||||
|
@ -739,7 +739,7 @@ void FileSystem::SetLinkedTexture(int lump, FTexture *tex)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *FileSystem::GetLinkedTexture(int lump)
|
||||
FGameTexture *FileSystem::GetLinkedTexture(int lump)
|
||||
{
|
||||
if ((size_t)lump < NumEntries)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class FResourceFile;
|
||||
struct FResourceLump;
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
|
||||
union LumpShortName
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
~FileData ();
|
||||
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
|
||||
size_t GetSize () { return Block.Len(); }
|
||||
FString GetString () { return Block; }
|
||||
const FString &GetString () const { return Block; }
|
||||
|
||||
private:
|
||||
FileData (const FString &source);
|
||||
|
@ -124,8 +124,8 @@ public:
|
|||
inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); }
|
||||
inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); }
|
||||
|
||||
void SetLinkedTexture(int lump, FTexture *tex);
|
||||
FTexture *GetLinkedTexture(int lump);
|
||||
void SetLinkedTexture(int lump, FGameTexture *tex);
|
||||
FGameTexture *GetLinkedTexture(int lump);
|
||||
|
||||
|
||||
void ReadFile (int lump, void *dest);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#ifndef __RESFILE_H
|
||||
#define __RESFILE_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "files.h"
|
||||
|
||||
struct LumpFilterInfo
|
||||
|
@ -17,7 +19,6 @@ struct LumpFilterInfo
|
|||
};
|
||||
|
||||
class FResourceFile;
|
||||
class FTexture;
|
||||
|
||||
// [RH] Namespaces from BOOM.
|
||||
// These are needed here in the low level part so that WAD files can be properly set up.
|
||||
|
|
|
@ -73,7 +73,6 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
int i;
|
||||
FTextureID lump;
|
||||
char buffer[12];
|
||||
int maxyoffs;
|
||||
DVector2 Scale = { 1, 1 };
|
||||
|
||||
noTranslate = notranslate;
|
||||
|
@ -91,9 +90,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
translateUntranslated = false;
|
||||
int FixedWidth = 0;
|
||||
|
||||
maxyoffs = 0;
|
||||
|
||||
TMap<int, FTexture*> charMap;
|
||||
TMap<int, FGameTexture*> charMap;
|
||||
int minchar = INT_MAX;
|
||||
int maxchar = INT_MIN;
|
||||
|
||||
|
@ -231,13 +228,13 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
Type = Multilump;
|
||||
if (position < minchar) minchar = position;
|
||||
if (position > maxchar) maxchar = position;
|
||||
charMap.Insert(position, TexMan.GetTexture(lump));
|
||||
charMap.Insert(position, TexMan.GetGameTexture(lump));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FTexture *texs[256] = {};
|
||||
FGameTexture *texs[256] = {};
|
||||
if (lcount > 256 - start) lcount = 256 - start;
|
||||
for (i = 0; i < lcount; i++)
|
||||
{
|
||||
|
@ -247,8 +244,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
TexMan.ListTextures(buffer, array, true);
|
||||
for (auto entry : array)
|
||||
{
|
||||
FTexture *tex = TexMan.GetTexture(entry, false);
|
||||
if (tex && tex->GetSourceLump() >= 0 && fileSystem.GetFileContainer(tex->GetSourceLump()) <= fileSystem.GetMaxIwadNum() && tex->GetUseType() == ETextureType::MiscPatch)
|
||||
auto tex = TexMan.GetGameTexture(entry, false);
|
||||
if (tex && !tex->isUserContent() && tex->GetUseType() == ETextureType::MiscPatch)
|
||||
{
|
||||
texs[i] = tex;
|
||||
}
|
||||
|
@ -292,8 +289,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
{
|
||||
if ((int)position < minchar) minchar = (int)position;
|
||||
if ((int)position > maxchar) maxchar = (int)position;
|
||||
auto tex = TexMan.GetTexture(lump);
|
||||
tex->SetScale(Scale);
|
||||
auto tex = TexMan.GetGameTexture(lump);
|
||||
tex->SetScale((float)Scale.X, (float)Scale.Y);
|
||||
charMap.Insert((int)position, tex);
|
||||
Type = Folder;
|
||||
}
|
||||
|
@ -312,17 +309,13 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
auto lump = charMap.CheckKey(FirstChar + i);
|
||||
if (lump != nullptr)
|
||||
{
|
||||
FTexture *pic = *lump;
|
||||
auto pic = *lump;
|
||||
if (pic != nullptr)
|
||||
{
|
||||
int height = pic->GetDisplayHeight();
|
||||
int yoffs = pic->GetDisplayTopOffset();
|
||||
double fheight = pic->GetDisplayHeight();
|
||||
double yoffs = pic->GetDisplayTopOffset();
|
||||
|
||||
if (yoffs > maxyoffs)
|
||||
{
|
||||
maxyoffs = yoffs;
|
||||
}
|
||||
height += abs(yoffs);
|
||||
int height = int(fheight + abs(yoffs) + 0.5);
|
||||
if (height > fontheight)
|
||||
{
|
||||
fontheight = height;
|
||||
|
@ -333,24 +326,24 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
}
|
||||
}
|
||||
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
auto orig = pic->GetTexture();
|
||||
auto tex = MakeGameTexture(orig, nullptr, ETextureType::FontChar);
|
||||
tex->CopySize(pic);
|
||||
TexMan.AddGameTexture(tex);
|
||||
Chars[i].OriginalPic = tex;
|
||||
|
||||
if (!noTranslate)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1(pic->GetImage()), "");
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(orig->GetImage())), nullptr, ETextureType::FontChar);
|
||||
Chars[i].TranslatedPic->CopySize(pic);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
||||
Chars[i].TranslatedPic = tex;
|
||||
}
|
||||
|
||||
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
Chars[i].XMove = (int)Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -388,8 +381,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
|||
void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale)
|
||||
{
|
||||
// all valid lumps must be named with a hex number that represents the Unicode character index for its first character,
|
||||
TArray<TexPart> part(1, true);
|
||||
TMap<int, FTexture*> charMap;
|
||||
TArray<TexPartBuild> part(1, true);
|
||||
TMap<int, FGameTexture*> charMap;
|
||||
int minchar = INT_MAX;
|
||||
int maxchar = INT_MIN;
|
||||
for (auto &entry : folderdata)
|
||||
|
@ -402,7 +395,7 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch);
|
||||
if (lump.isValid())
|
||||
{
|
||||
auto tex = TexMan.GetTexture(lump);
|
||||
auto tex = TexMan.GetGameTexture(lump);
|
||||
int numtex_x = tex->GetTexelWidth() / width;
|
||||
int numtex_y = tex->GetTexelHeight() / height;
|
||||
int maxinsheet = int(position) + numtex_x * numtex_y - 1;
|
||||
|
@ -415,25 +408,16 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
{
|
||||
part[0].OriginX = -width * x;
|
||||
part[0].OriginY = -height * y;
|
||||
part[0].Image = tex->GetImage();
|
||||
part[0].TexImage = static_cast<FImageTexture*>(tex->GetTexture());
|
||||
FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false);
|
||||
FImageTexture *tex = new FImageTexture(image, "");
|
||||
tex->SetUseType(ETextureType::FontChar);
|
||||
tex->bMultiPatch = true;
|
||||
tex->Width = width;
|
||||
tex->Height = height;
|
||||
tex->_LeftOffset[0] =
|
||||
tex->_LeftOffset[1] =
|
||||
tex->_TopOffset[0] =
|
||||
tex->_TopOffset[1] = 0;
|
||||
tex->Scale = Scale;
|
||||
tex->bMasked = true;
|
||||
tex->bTranslucent = -1;
|
||||
tex->bWorldPanning = true;
|
||||
tex->bNoDecals = false;
|
||||
tex->SourceLump = -1; // We do not really care.
|
||||
TexMan.AddTexture(tex);
|
||||
charMap.Insert(int(position) + x + y * numtex_x, tex);
|
||||
FImageTexture *tex = new FImageTexture(image);
|
||||
auto gtex = MakeGameTexture(tex, nullptr, ETextureType::FontChar);
|
||||
gtex->SetWorldPanning(true);
|
||||
gtex->SetOffsets(0, 0, 0);
|
||||
gtex->SetOffsets(1, 0, 0);
|
||||
gtex->SetScale((float)Scale.X, (float)Scale.Y);
|
||||
TexMan.AddGameTexture(gtex);
|
||||
charMap.Insert(int(position) + x + y * numtex_x, gtex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,18 +442,18 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
auto lump = charMap.CheckKey(FirstChar + i);
|
||||
if (lump != nullptr)
|
||||
{
|
||||
FTexture *pic = *lump;
|
||||
auto pic = (*lump)->GetTexture();
|
||||
|
||||
auto b = pic->Get8BitPixels(false);
|
||||
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic = MakeGameTexture(pic, nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1(pic->GetImage()), "");
|
||||
Chars[i].TranslatedPic->CopySize(pic);
|
||||
Chars[i].OriginalPic->CopySize(*lump);
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage())), nullptr, ETextureType::FontChar);
|
||||
Chars[i].TranslatedPic->CopySize(*lump);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
Chars[i].XMove = width;
|
||||
}
|
||||
|
@ -619,7 +603,7 @@ void FFont::RecordAllTextureColors(uint32_t *usedcolors)
|
|||
{
|
||||
if (Chars[i].TranslatedPic)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetTexture()->GetImage());
|
||||
if (pic)
|
||||
{
|
||||
// The remap must be temporarily reset here because this can be called on an initialized font.
|
||||
|
@ -982,7 +966,7 @@ int FFont::GetCharCode(int code, bool needpic) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *FFont::GetChar (int code, int translation, int *const width, bool *redirected) const
|
||||
FGameTexture *FFont::GetChar (int code, int translation, int *const width, bool *redirected) const
|
||||
{
|
||||
code = GetCharCode(code, true);
|
||||
int xmove = SpaceWidth;
|
||||
|
@ -1037,11 +1021,11 @@ int FFont::GetCharWidth (int code) const
|
|||
double GetBottomAlignOffset(FFont *font, int c)
|
||||
{
|
||||
int w;
|
||||
FTexture *tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
|
||||
FTexture *texc = font->GetChar(c, CR_UNDEFINED, &w);
|
||||
auto tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
|
||||
auto texc = font->GetChar(c, CR_UNDEFINED, &w);
|
||||
double offset = 0;
|
||||
if (texc) offset += texc->GetDisplayTopOffsetDouble();
|
||||
if (tex_zero) offset += -tex_zero->GetDisplayTopOffsetDouble() + tex_zero->GetDisplayHeightDouble();
|
||||
if (texc) offset += texc->GetDisplayTopOffset();
|
||||
if (tex_zero) offset += -tex_zero->GetDisplayTopOffset() + tex_zero->GetDisplayHeight();
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -1093,7 +1077,7 @@ bool FFont::CanPrint(const uint8_t *string) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FFont::StringWidth(const uint8_t *string) const
|
||||
int FFont::StringWidth(const uint8_t *string, int spacing) const
|
||||
{
|
||||
int w = 0;
|
||||
int maxw = 0;
|
||||
|
@ -1123,13 +1107,17 @@ int FFont::StringWidth(const uint8_t *string) const
|
|||
maxw = w;
|
||||
w = 0;
|
||||
}
|
||||
else if (spacing >= 0)
|
||||
{
|
||||
w += GetCharWidth(chr) + GlobalKerning + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
w += GetCharWidth(chr) + GlobalKerning;
|
||||
w -= spacing;
|
||||
}
|
||||
}
|
||||
|
||||
return MAX(maxw, w);
|
||||
return std::max(maxw, w);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1196,7 +1184,7 @@ void FFont::LoadTranslations()
|
|||
{
|
||||
if (Chars[i].TranslatedPic)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetTexture()->GetImage());
|
||||
if (pic)
|
||||
{
|
||||
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
|
||||
|
@ -1210,7 +1198,7 @@ void FFont::LoadTranslations()
|
|||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if(Chars[i].TranslatedPic)
|
||||
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
|
||||
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr);
|
||||
|
@ -1286,7 +1274,7 @@ void FFont::FixXMoves()
|
|||
}
|
||||
if (Chars[i].OriginalPic)
|
||||
{
|
||||
int ofs = Chars[i].OriginalPic->GetDisplayTopOffset();
|
||||
int ofs = (int)Chars[i].OriginalPic->GetDisplayTopOffset();
|
||||
if (ofs > Displacement) Displacement = ofs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,10 +289,9 @@ public:
|
|||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16));
|
||||
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
|
@ -362,10 +361,9 @@ public:
|
|||
{
|
||||
auto offset = hexdata.glyphmap[i];
|
||||
int size = hexdata.glyphdata[offset] / 16;
|
||||
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18));
|
||||
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)), nullptr, ETextureType::FontChar);
|
||||
Chars[i - FirstChar].XMove = size * spacing;
|
||||
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||
}
|
||||
else Chars[i - FirstChar].XMove = spacing;
|
||||
|
||||
|
|
|
@ -167,10 +167,10 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
|
|||
|
||||
void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
||||
{
|
||||
FTexture *pic = TexMan.GetTexture(picnum);
|
||||
auto pic = TexMan.GetGameTexture(picnum);
|
||||
|
||||
FontHeight = pic->GetDisplayHeight ();
|
||||
SpaceWidth = pic->GetDisplayWidth ();
|
||||
FontHeight = (int)pic->GetDisplayHeight ();
|
||||
SpaceWidth = (int)pic->GetDisplayWidth ();
|
||||
GlobalKerning = 0;
|
||||
|
||||
FirstChar = LastChar = 'A';
|
||||
|
@ -222,7 +222,7 @@ void FSingleLumpFont::LoadTranslations()
|
|||
for(unsigned int i = 0;i < count;++i)
|
||||
{
|
||||
if(Chars[i].TranslatedPic)
|
||||
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
|
||||
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations (luminosity, useidentity ? identity : nullptr, ranges, ActiveColors, usepalette ? local_palette : nullptr);
|
||||
|
@ -353,9 +353,8 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)), nullptr, ETextureType::FontChar);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
do
|
||||
{
|
||||
int8_t code = *data_p++;
|
||||
|
@ -483,15 +482,14 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
|||
{ // Empty character: skip it.
|
||||
continue;
|
||||
}
|
||||
auto tex = new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data),
|
||||
auto tex = MakeGameTexture(new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data),
|
||||
chardata[chari+1], // width
|
||||
chardata[chari+2], // height
|
||||
-(int8_t)chardata[chari+3], // x offset
|
||||
-(int8_t)chardata[chari+4] // y offset
|
||||
));
|
||||
tex->SetUseType(ETextureType::FontChar);
|
||||
)), nullptr, ETextureType::FontChar);
|
||||
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
|
||||
TexMan.AddTexture(tex);
|
||||
TexMan.AddGameTexture(tex);
|
||||
}
|
||||
|
||||
// If the font did not define a space character, determine a suitable space width now.
|
||||
|
@ -556,10 +554,9 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
|
|||
|
||||
if(!Chars[i].TranslatedPic)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)), nullptr, ETextureType::FontChar);
|
||||
Chars[i].XMove = SpaceWidth;
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
|
||||
// Advance to next char's data and count the used colors.
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
FSinglePicFont(const char *picname);
|
||||
|
||||
// FFont interface
|
||||
FTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override;
|
||||
FGameTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override;
|
||||
int GetCharWidth (int code) const;
|
||||
|
||||
protected:
|
||||
|
@ -72,11 +72,11 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
|
|||
I_FatalError ("%s is not a font or texture", picname);
|
||||
}
|
||||
|
||||
FTexture *pic = TexMan.GetTexture(picnum);
|
||||
auto pic = TexMan.GetGameTexture(picnum);
|
||||
|
||||
FontName = picname;
|
||||
FontHeight = pic->GetDisplayHeight();
|
||||
SpaceWidth = pic->GetDisplayWidth();
|
||||
FontHeight = (int)pic->GetDisplayHeight();
|
||||
SpaceWidth = (int)pic->GetDisplayWidth();
|
||||
GlobalKerning = 0;
|
||||
FirstChar = LastChar = 'A';
|
||||
ActiveColors = 0;
|
||||
|
@ -94,13 +94,13 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const
|
||||
FGameTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const
|
||||
{
|
||||
*width = SpaceWidth;
|
||||
if (redirected) *redirected = false;
|
||||
if (code == 'a' || code == 'A')
|
||||
{
|
||||
return TexMan.GetPalettedTexture(PicNum, true);
|
||||
return TexMan.GetGameTexture(PicNum, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
class FSpecialFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
FSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
|
||||
void LoadTranslations();
|
||||
|
||||
|
@ -60,13 +60,13 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
: FFont(lump)
|
||||
{
|
||||
int i;
|
||||
TArray<FTexture *> charlumps(count, true);
|
||||
TArray<FGameTexture *> charlumps(count, true);
|
||||
int maxyoffs;
|
||||
FTexture *pic;
|
||||
FGameTexture *pic;
|
||||
|
||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
||||
|
||||
|
@ -87,8 +87,8 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
pic = charlumps[i] = lumplist[i];
|
||||
if (pic != nullptr)
|
||||
{
|
||||
int height = pic->GetDisplayHeight();
|
||||
int yoffs = pic->GetDisplayTopOffset();
|
||||
int height = (int)pic->GetDisplayHeight();
|
||||
int yoffs = (int)pic->GetDisplayTopOffset();
|
||||
|
||||
if (yoffs > maxyoffs)
|
||||
{
|
||||
|
@ -104,20 +104,18 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
if (charlumps[i] != nullptr)
|
||||
{
|
||||
auto pic = charlumps[i];
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic = MakeGameTexture(pic->GetTexture(), nullptr, ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||
|
||||
if (!noTranslate)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), "");
|
||||
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1 (charlumps[i]->GetTexture()->GetImage())), nullptr, ETextureType::FontChar);
|
||||
Chars[i].TranslatedPic->CopySize(charlumps[i]);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
||||
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
Chars[i].XMove = (int)Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -167,7 +165,7 @@ void FSpecialFont::LoadTranslations()
|
|||
{
|
||||
if (Chars[i].TranslatedPic)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetTexture()->GetImage());
|
||||
if (pic)
|
||||
{
|
||||
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
|
||||
|
@ -197,7 +195,7 @@ void FSpecialFont::LoadTranslations()
|
|||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if(Chars[i].TranslatedPic)
|
||||
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
|
||||
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations(Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr, [=](FRemapTable* remap)
|
||||
|
@ -217,7 +215,7 @@ void FSpecialFont::LoadTranslations()
|
|||
ActiveColors = TotalColors;
|
||||
}
|
||||
|
||||
FFont *CreateSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
FFont *CreateSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
{
|
||||
return new FSpecialFont(name, first, count, lumplist, notranslate, lump, donttranslate);
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
|||
FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any);
|
||||
if (picnum.isValid())
|
||||
{
|
||||
FTexture *tex = TexMan.GetTexture(picnum);
|
||||
auto tex = TexMan.GetGameTexture(picnum);
|
||||
if (tex && tex->GetSourceLump() >= folderfile)
|
||||
{
|
||||
FFont *CreateSinglePicFont(const char *name);
|
||||
|
@ -170,7 +170,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
|||
void V_InitCustomFonts()
|
||||
{
|
||||
FScanner sc;
|
||||
FTexture *lumplist[256];
|
||||
FGameTexture *lumplist[256];
|
||||
bool notranslate[256];
|
||||
bool donttranslate;
|
||||
FString namebuffer, templatebuf;
|
||||
|
@ -266,12 +266,12 @@ void V_InitCustomFonts()
|
|||
else
|
||||
{
|
||||
if (format == 1) goto wrong;
|
||||
FTexture **p = &lumplist[*(unsigned char*)sc.String];
|
||||
FGameTexture **p = &lumplist[*(unsigned char*)sc.String];
|
||||
sc.MustGetString();
|
||||
FTextureID texid = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch);
|
||||
if (texid.Exists())
|
||||
{
|
||||
*p = TexMan.GetTexture(texid);
|
||||
*p = TexMan.GetGameTexture(texid);
|
||||
}
|
||||
else if (fileSystem.GetFileContainer(sc.LumpNum) >= fileSystem.GetIwadNum())
|
||||
{
|
||||
|
@ -307,7 +307,7 @@ void V_InitCustomFonts()
|
|||
}
|
||||
if (count > 0)
|
||||
{
|
||||
FFont *CreateSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
FFont *CreateSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
FFont *fnt = CreateSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump, donttranslate);
|
||||
fnt->SetCursor(cursor);
|
||||
fnt->SetKerning(kerning);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "name.h"
|
||||
|
||||
class DCanvas;
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
struct FRemapTable;
|
||||
|
||||
enum EColorRange : int
|
||||
|
@ -77,7 +77,7 @@ enum EColorRange : int
|
|||
|
||||
extern int NumTextColors;
|
||||
|
||||
using GlyphSet = TMap<int, FTexture*>;
|
||||
using GlyphSet = TMap<int, FGameTexture*>;
|
||||
|
||||
class FFont
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
FFont (const char *fontname, const char *nametemplate, const char *filetemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false, bool iwadonly = false, bool doomtemplate = false, GlyphSet *baseGlpyphs = nullptr);
|
||||
virtual ~FFont ();
|
||||
|
||||
virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
|
||||
virtual FGameTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
|
||||
virtual int GetCharWidth (int code) const;
|
||||
int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
||||
int GetLump() const { return Lump; }
|
||||
|
@ -113,9 +113,9 @@ public:
|
|||
static FFont *FindFont(FName fontname);
|
||||
|
||||
// Return width of string in pixels (unscaled)
|
||||
int StringWidth (const uint8_t *str) const;
|
||||
inline int StringWidth (const char *str) const { return StringWidth ((const uint8_t *)str); }
|
||||
inline int StringWidth (const FString &str) const { return StringWidth ((const uint8_t *)str.GetChars()); }
|
||||
int StringWidth (const uint8_t *str, int spacing = 0) const;
|
||||
inline int StringWidth (const char *str, int spacing = 0) const { return StringWidth ((const uint8_t *)str, spacing); }
|
||||
inline int StringWidth (const FString &str, int spacing = 0) const { return StringWidth ((const uint8_t *)str.GetChars(), spacing); }
|
||||
|
||||
// Checks if the font contains all characters to print this text.
|
||||
bool CanPrint(const uint8_t *str) const;
|
||||
|
@ -161,8 +161,8 @@ protected:
|
|||
bool forceremap = false;
|
||||
struct CharData
|
||||
{
|
||||
FTexture *TranslatedPic = nullptr; // Texture for use with font translations.
|
||||
FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
|
||||
FGameTexture *TranslatedPic = nullptr; // Texture for use with font translations.
|
||||
FGameTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
|
||||
int XMove = INT_MIN;
|
||||
};
|
||||
TArray<CharData> Chars;
|
||||
|
|
|
@ -54,7 +54,7 @@ static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %0
|
|||
static int CastS2So(FString *b) { return FSoundID(*b); }
|
||||
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(b); }
|
||||
static void CastSID2S(FString* a, unsigned int b) { VM_CastSpriteIDToString(a, b); }
|
||||
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
||||
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetGameTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
||||
|
||||
void JitCompiler::EmitCAST()
|
||||
{
|
||||
|
|
|
@ -1848,7 +1848,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
|||
case CAST_TID2S:
|
||||
{
|
||||
ASSERTS(a); ASSERTD(b);
|
||||
auto tex = TexMan.GetTexture(*(FTextureID*)&(reg.d[b]));
|
||||
auto tex = TexMan.GetGameTexture(*(FTextureID*)&(reg.d[b]));
|
||||
reg.s[a] = tex == nullptr ? "(null)" : tex->GetName().GetChars();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -43,14 +43,14 @@
|
|||
void AnimTexture::SetFrameSize(int width, int height)
|
||||
{
|
||||
FTexture::SetSize(width, height);
|
||||
Image.Resize(width*height);
|
||||
Image.Resize(width * height);
|
||||
}
|
||||
|
||||
void AnimTexture::SetFrame(const uint8_t *palette, const void *data_)
|
||||
void AnimTexture::SetFrame(const uint8_t* palette, const void* data_)
|
||||
{
|
||||
memcpy(Palette, palette, 768);
|
||||
memcpy(Image.Data(), data_, Width * Height);
|
||||
SystemTextures.Clean(true, true);
|
||||
memcpy(Palette, palette, 768);
|
||||
memcpy(Image.Data(), data_, Width * Height);
|
||||
CleanHardwareTextures();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -70,10 +70,10 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans)
|
|||
for (int i = 0; i < Width * Height; i++)
|
||||
{
|
||||
int p = i * 4;
|
||||
int index = spix[i];
|
||||
dpix[p + 0] = Palette[index*3+2];
|
||||
dpix[p + 1] = Palette[index*3+1];
|
||||
dpix[p + 2] = Palette[index*3];
|
||||
int index = spix[i];
|
||||
dpix[p + 0] = Palette[index * 3 + 2];
|
||||
dpix[p + 1] = Palette[index * 3 + 1];
|
||||
dpix[p + 2] = Palette[index * 3];
|
||||
dpix[p + 3] = 255;
|
||||
}
|
||||
return bmp;
|
||||
|
@ -87,30 +87,32 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans)
|
|||
|
||||
AnimTextures::AnimTextures()
|
||||
{
|
||||
active = 1;
|
||||
tex[0] = new AnimTexture;
|
||||
tex[1] = new AnimTexture;
|
||||
active = 1;
|
||||
tex[0] = MakeGameTexture(new AnimTexture, "", ETextureType::Special);
|
||||
tex[1] = MakeGameTexture(new AnimTexture, "", ETextureType::Special);
|
||||
}
|
||||
|
||||
AnimTextures::~AnimTextures()
|
||||
{
|
||||
delete tex[0];
|
||||
delete tex[1];
|
||||
delete tex[0];
|
||||
delete tex[1];
|
||||
}
|
||||
|
||||
void AnimTextures::SetSize(int width, int height)
|
||||
{
|
||||
tex[0]->SetFrameSize(width, height);
|
||||
tex[1]->SetFrameSize(width, height);
|
||||
}
|
||||
|
||||
void AnimTextures::SetFrame(const uint8_t *palette, const void* data)
|
||||
{
|
||||
active ^= 1;
|
||||
tex[active]->SetFrame(palette, data);
|
||||
static_cast<AnimTexture*>(tex[0]->GetTexture())->SetFrameSize(width, height);
|
||||
static_cast<AnimTexture*>(tex[1]->GetTexture())->SetFrameSize(width, height);
|
||||
tex[0]->SetSize(width, height);
|
||||
tex[1]->SetSize(width, height);
|
||||
}
|
||||
|
||||
FTexture * AnimTextures::GetFrame()
|
||||
void AnimTextures::SetFrame(const uint8_t* palette, const void* data)
|
||||
{
|
||||
return tex[active];
|
||||
active ^= 1;
|
||||
static_cast<AnimTexture*>(tex[active]->GetTexture())->SetFrame(palette, data);
|
||||
}
|
||||
|
||||
FGameTexture* AnimTextures::GetFrame()
|
||||
{
|
||||
return tex[active];
|
||||
}
|
||||
|
|
|
@ -8,21 +8,21 @@ class AnimTexture : public FTexture
|
|||
uint8_t Palette[768];
|
||||
TArray<uint8_t> Image;
|
||||
public:
|
||||
AnimTexture() = default;
|
||||
AnimTexture() = default;
|
||||
void SetFrameSize(int width, int height);
|
||||
void SetFrame(const uint8_t *palette, const void* data);
|
||||
virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override;
|
||||
void SetFrame(const uint8_t* palette, const void* data);
|
||||
virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override;
|
||||
};
|
||||
|
||||
class AnimTextures
|
||||
{
|
||||
int active;
|
||||
AnimTexture *tex[2];
|
||||
FGameTexture* tex[2];
|
||||
|
||||
public:
|
||||
AnimTextures();
|
||||
~AnimTextures();
|
||||
void SetSize(int width, int height);
|
||||
void SetFrame(const uint8_t *palette, const void* data);
|
||||
FTexture *GetFrame();
|
||||
void SetFrame(const uint8_t* palette, const void* data);
|
||||
FGameTexture* GetFrame();
|
||||
};
|
||||
|
|
|
@ -69,6 +69,11 @@ FImageSource *EmptyImage_TryCreate(FileReader & file, int lumpnum)
|
|||
return new FEmptyTexture(lumpnum);
|
||||
}
|
||||
|
||||
FImageSource* CreateEmptyTexture()
|
||||
{
|
||||
return new FEmptyTexture(0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -46,15 +46,19 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual)
|
||||
FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray<TexPartBuild> &parts, bool complex, bool textual)
|
||||
{
|
||||
Width = w;
|
||||
Height = h;
|
||||
bComplex = complex;
|
||||
bTextual = textual;
|
||||
bTextual = textual;
|
||||
Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size());
|
||||
NumParts = parts.Size();
|
||||
memcpy(Parts, parts.Data(), sizeof(TexPart) * parts.Size());
|
||||
for (unsigned i = 0; i < parts.Size(); i++)
|
||||
{
|
||||
Parts[i].Image = parts[i].TexImage->GetImage();
|
||||
}
|
||||
|
||||
bUseGamePalette = false;
|
||||
if (!bComplex)
|
||||
|
@ -67,6 +71,27 @@ FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray<TexPart> &part
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// sky remapping will only happen if
|
||||
// - the texture was defined through a TEXTUREx lump (this implies only trivial copies)
|
||||
// - all patches use the base palette.
|
||||
// - all patches are in a format that allows the remap.
|
||||
// All other cases would not be able to properly deal with this special case.
|
||||
// For textual definitions this hack isn't necessary.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FMultiPatchTexture::SupportRemap0()
|
||||
{
|
||||
if (bTextual || UseGamePalette()) return false;
|
||||
for (int i = 0; i < NumParts; i++)
|
||||
{
|
||||
if (!Parts[i].Image->SupportRemap0()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetBlendMap
|
||||
|
@ -203,11 +228,6 @@ TArray<uint8_t> FMultiPatchTexture::CreatePalettedPixels(int conversion)
|
|||
}
|
||||
if (conversion == noremap0)
|
||||
{
|
||||
// sky remapping will only happen if
|
||||
// - the texture was defined through a TEXTUREx lump (this implies only trivial copies)
|
||||
// - all patches use the base palette.
|
||||
// All other cases would not be able to properly deal with this special case.
|
||||
// For textual definitions this hack isn't necessary.
|
||||
if (bTextual || !UseGamePalette()) conversion = normal;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
#include "vectors.h"
|
||||
#include "bitmap.h"
|
||||
#include "image.h"
|
||||
#include "textures.h"
|
||||
|
||||
class FImageTexture;
|
||||
class FTextureManager;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TexPart is the data that will get passed to the final texture.
|
||||
|
@ -25,6 +28,18 @@ struct TexPart
|
|||
uint8_t op = OP_COPY;
|
||||
};
|
||||
|
||||
struct TexPartBuild
|
||||
{
|
||||
FRemapTable* Translation = nullptr;
|
||||
FImageTexture *TexImage = nullptr;
|
||||
PalEntry Blend = 0;
|
||||
blend_t Alpha = FRACUNIT;
|
||||
int16_t OriginX = 0;
|
||||
int16_t OriginY = 0;
|
||||
uint8_t Rotate = 0;
|
||||
uint8_t op = OP_COPY;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -36,8 +51,21 @@ struct TexPart
|
|||
class FMultiPatchTexture : public FImageSource
|
||||
{
|
||||
friend class FTexture;
|
||||
friend class FGameTexture;
|
||||
public:
|
||||
FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual);
|
||||
FMultiPatchTexture(int w, int h, const TArray<TexPartBuild> &parts, bool complex, bool textual);
|
||||
int GetNumParts() const { return NumParts; }
|
||||
// Query some needed info for texture hack support.
|
||||
bool SupportRemap0() override;
|
||||
bool IsRawCompatible() override
|
||||
{
|
||||
return NumParts != 1 || Parts[0].OriginY == 0 || bTextual;
|
||||
}
|
||||
FImageSource* GetImageForPart(int num)
|
||||
{
|
||||
if (num >= 0 && num < NumParts) return Parts[num].Image;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
int NumParts;
|
||||
|
@ -64,7 +92,7 @@ struct TexInit
|
|||
{
|
||||
FString TexName;
|
||||
ETextureType UseType = ETextureType::Null;
|
||||
FTexture *Texture = nullptr;
|
||||
FImageTexture *Texture = nullptr;
|
||||
bool Silent = false;
|
||||
bool HasLine = false;
|
||||
bool UseOffsets = false;
|
||||
|
@ -82,7 +110,7 @@ struct FPatchLookup;
|
|||
struct BuildInfo
|
||||
{
|
||||
FString Name;
|
||||
TArray<TexPart> Parts;
|
||||
TArray<TexPartBuild> Parts;
|
||||
TArray<TexInit> Inits;
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
|
@ -94,7 +122,7 @@ struct BuildInfo
|
|||
bool bNoDecals = false;
|
||||
int LeftOffset[2] = {};
|
||||
int TopOffset[2] = {};
|
||||
FImageTexture *tex = nullptr;
|
||||
FGameTexture *texture = nullptr;
|
||||
|
||||
void swap(BuildInfo &other)
|
||||
{
|
||||
|
@ -113,7 +141,7 @@ struct BuildInfo
|
|||
std::swap(LeftOffset[1], other.LeftOffset[1]);
|
||||
std::swap(TopOffset[0], other.TopOffset[0]);
|
||||
std::swap(TopOffset[1], other.TopOffset[1]);
|
||||
std::swap(tex, other.tex);
|
||||
std::swap(texture, other.texture);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -123,15 +151,17 @@ class FMultipatchTextureBuilder
|
|||
{
|
||||
FTextureManager &TexMan;
|
||||
TArray<BuildInfo> BuiltTextures;
|
||||
TMap<FGameTexture*, bool> complex;
|
||||
void(*progressFunc)();
|
||||
void(*checkForHacks)(BuildInfo&);
|
||||
|
||||
void MakeTexture(BuildInfo &buildinfo, ETextureType usetype);
|
||||
void AddImageToTexture(FImageTexture* tex, BuildInfo& buildinfo);
|
||||
|
||||
void BuildTexture(const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum, ETextureType usetyoe);
|
||||
void AddTexturesLump(const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1);
|
||||
|
||||
void ParsePatch(FScanner &sc, BuildInfo &info, TexPart &part, TexInit &init);
|
||||
void ParsePatch(FScanner &sc, BuildInfo &info, TexPartBuild &part, TexInit &init);
|
||||
void ResolvePatches(BuildInfo &buildinfo);
|
||||
|
||||
public:
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex);
|
||||
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
|
||||
int CopyPixels(FBitmap *bmp, int conversion) override;
|
||||
bool SupportRemap0() override { return !badflag; }
|
||||
void DetectBadPatches();
|
||||
};
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
#include "imagehelpers.h"
|
||||
#include "image.h"
|
||||
#include "printf.h"
|
||||
#include "texturemanager.h"
|
||||
#include "filesystem.h"
|
||||
#include "colormatcher.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -591,7 +591,7 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
|
||||
FGameTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
|
||||
{
|
||||
if (M_FindPNGChunk(png, MAKE_ID('I','H','D','R')) == 0)
|
||||
{
|
||||
|
@ -610,7 +610,7 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
|
|||
|
||||
// Reject anything that cannot be put into a savegame picture by GZDoom itself.
|
||||
if (compression != 0 || filter != 0 || interlace > 0 || bitdepth != 8 || (colortype != 2 && colortype != 3)) return nullptr;
|
||||
else return new FPNGFileTexture (png->File, width, height, colortype);
|
||||
else return MakeGameTexture(new FPNGFileTexture (png->File, width, height, colortype), nullptr, ETextureType::Override);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -624,6 +624,8 @@ FPNGFileTexture::FPNGFileTexture (FileReader &lump, int width, int height, uint8
|
|||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Masked = false;
|
||||
bTranslucent = false;
|
||||
fr = std::move(lump);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "bitmap.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "image.h"
|
||||
#include "textures.h"
|
||||
|
||||
|
||||
class FBarShader : public FImageSource
|
||||
|
@ -128,9 +129,9 @@ private:
|
|||
};
|
||||
|
||||
|
||||
FTexture *CreateShaderTexture(bool vertical, bool reverse)
|
||||
FGameTexture *CreateShaderTexture(bool vertical, bool reverse)
|
||||
{
|
||||
FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f');
|
||||
return CreateImageTexture(new FBarShader(vertical, reverse), name.GetChars());
|
||||
return MakeGameTexture(CreateImageTexture(new FBarShader(vertical, reverse)), name.GetChars(), ETextureType::Override);
|
||||
|
||||
}
|
||||
|
|
512
source/common/textures/gametexture.cpp
Normal file
512
source/common/textures/gametexture.cpp
Normal file
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
** gametexture.cpp
|
||||
** The game-facing texture class.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2004-2007 Randy Heit
|
||||
** Copyright 2006-2020 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "printf.h"
|
||||
#include "files.h"
|
||||
#include "filesystem.h"
|
||||
#include "templates.h"
|
||||
#include "textures.h"
|
||||
#include "bitmap.h"
|
||||
#include "colormatcher.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "m_fixed.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "image.h"
|
||||
#include "formats/multipatchtexture.h"
|
||||
#include "texturemanager.h"
|
||||
#include "c_cvars.h"
|
||||
#include "hw_material.h"
|
||||
|
||||
FTexture *CreateBrightmapTexture(FImageSource*);
|
||||
|
||||
|
||||
FGameTexture::FGameTexture(FTexture* wrap, const char* name) : Name(name)
|
||||
{
|
||||
if (wrap) Setup(wrap);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGameTexture::Setup(FTexture *wrap)
|
||||
{
|
||||
Base = wrap;
|
||||
id.SetInvalid();
|
||||
TexelWidth = Base->GetWidth();
|
||||
DisplayWidth = (float)TexelWidth;
|
||||
TexelHeight = Base->GetHeight();
|
||||
DisplayHeight = (float)TexelHeight;
|
||||
auto img = Base->GetImage();
|
||||
if (img)
|
||||
{
|
||||
auto ofs = img->GetOffsets();
|
||||
LeftOffset[0] = LeftOffset[1] = ofs.first;
|
||||
TopOffset[0] = TopOffset[1] = ofs.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
LeftOffset[0] = LeftOffset[1] =
|
||||
TopOffset[0] = TopOffset[1] = 0;
|
||||
|
||||
}
|
||||
ScaleX = ScaleY = 1.f;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FGameTexture::~FGameTexture()
|
||||
{
|
||||
FGameTexture* link = fileSystem.GetLinkedTexture(GetSourceLump());
|
||||
if (link == this) fileSystem.SetLinkedTexture(GetSourceLump(), nullptr);
|
||||
if (SoftwareTexture != nullptr)
|
||||
{
|
||||
delete SoftwareTexture;
|
||||
SoftwareTexture = nullptr;
|
||||
}
|
||||
for (auto &mat : Material)
|
||||
{
|
||||
if (mat != nullptr) delete mat;
|
||||
mat = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGameTexture::isUserContent() const
|
||||
{
|
||||
int filenum = fileSystem.GetFileContainer(Base->GetSourceLump());
|
||||
return (filenum > fileSystem.GetMaxIwadNum());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Search auto paths for extra material textures
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGameTexture::AddAutoMaterials()
|
||||
{
|
||||
struct AutoTextureSearchPath
|
||||
{
|
||||
const char* path;
|
||||
RefCountedPtr<FTexture> FGameTexture::* pointer;
|
||||
};
|
||||
|
||||
static AutoTextureSearchPath autosearchpaths[] =
|
||||
{
|
||||
{ "brightmaps/", &FGameTexture::Brightmap }, // For backwards compatibility, only for short names
|
||||
{ "materials/brightmaps/", &FGameTexture::Brightmap },
|
||||
{ "materials/normalmaps/", &FGameTexture::Normal },
|
||||
{ "materials/specular/", &FGameTexture::Specular },
|
||||
{ "materials/metallic/", &FGameTexture::Metallic },
|
||||
{ "materials/roughness/", &FGameTexture::Roughness },
|
||||
{ "materials/ao/", &FGameTexture::AmbientOcclusion }
|
||||
};
|
||||
|
||||
|
||||
bool fullname = !!(flags & GTexf_FullNameTexture);
|
||||
FString searchname = GetName();
|
||||
|
||||
if (fullname)
|
||||
{
|
||||
auto dot = searchname.LastIndexOf('.');
|
||||
auto slash = searchname.LastIndexOf('/');
|
||||
if (dot > slash) searchname.Truncate(dot);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < countof(autosearchpaths); i++)
|
||||
{
|
||||
auto& layer = autosearchpaths[i];
|
||||
if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done.
|
||||
{
|
||||
FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars());
|
||||
auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true);
|
||||
if (lump != -1)
|
||||
{
|
||||
auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny);
|
||||
if (bmtex != nullptr)
|
||||
{
|
||||
this->*(layer.pointer) = bmtex->GetTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Checks if the texture has a default brightmap and creates it if so
|
||||
//
|
||||
//===========================================================================
|
||||
void FGameTexture::CreateDefaultBrightmap()
|
||||
{
|
||||
auto tex = GetTexture();
|
||||
if (flags & GTexf_BrightmapChecked)
|
||||
{
|
||||
flags |= GTexf_BrightmapChecked;
|
||||
// Check for brightmaps
|
||||
if (tex->GetImage() && tex->GetImage()->UseGamePalette() && GPalette.HasGlobalBrightmap &&
|
||||
GetUseType() != ETextureType::Decal && GetUseType() != ETextureType::MiscPatch && GetUseType() != ETextureType::FontChar &&
|
||||
Brightmap == nullptr)
|
||||
{
|
||||
// May have one - let's check when we use this texture
|
||||
auto texbuf = tex->Get8BitPixels(false);
|
||||
const int white = ColorMatcher.Pick(255, 255, 255);
|
||||
|
||||
int size = tex->GetWidth() * tex->GetHeight();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (GPalette.GlobalBrightmap.Remap[texbuf[i]] == white)
|
||||
{
|
||||
// Create a brightmap
|
||||
DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", GetName().GetChars());
|
||||
Brightmap = CreateBrightmapTexture(tex->GetImage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No bright pixels found
|
||||
DPrintf(DMSG_SPAMMY, "No bright pixels found in texture '%s'\n", GetName().GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Calculates glow color for a texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGameTexture::GetGlowColor(float* data)
|
||||
{
|
||||
if (isGlowing() && GlowColor == 0)
|
||||
{
|
||||
auto buffer = Base->GetBgraBitmap(nullptr);
|
||||
GlowColor = averageColor((uint32_t*)buffer.GetPixels(), buffer.GetWidth() * buffer.GetHeight(), 153);
|
||||
|
||||
// Black glow equals nothing so switch glowing off
|
||||
if (GlowColor == 0) flags &= ~GTexf_Glowing;
|
||||
}
|
||||
data[0] = GlowColor.r * (1 / 255.0f);
|
||||
data[1] = GlowColor.g * (1 / 255.0f);
|
||||
data[2] = GlowColor.b * (1 / 255.0f);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int FGameTexture::GetAreas(FloatRect** pAreas) const
|
||||
{
|
||||
if (shaderindex == SHADER_Default) // texture splitting can only be done if there's no attached effects
|
||||
{
|
||||
*pAreas = Base->areas;
|
||||
return Base->areacount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Checks if a sprite may be expanded with an empty frame
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FGameTexture::ShouldExpandSprite()
|
||||
{
|
||||
if (expandSprite != -1) return expandSprite;
|
||||
// Only applicable to image textures with no shader effect.
|
||||
if (GetShaderIndex() != SHADER_Default || !dynamic_cast<FImageTexture*>(Base.get()))
|
||||
{
|
||||
expandSprite = false;
|
||||
return false;
|
||||
}
|
||||
if (Brightmap != NULL && (Base->GetWidth() != Brightmap->GetWidth() || Base->GetHeight() != Brightmap->GetHeight()))
|
||||
{
|
||||
// do not expand if the brightmap's physical size differs from the base.
|
||||
expandSprite = false;
|
||||
return false;
|
||||
}
|
||||
if (Glowmap != NULL && (Base->GetWidth() != Glowmap->GetWidth() || Base->GetHeight() != Glowmap->GetHeight()))
|
||||
{
|
||||
// same restriction for the glow map
|
||||
expandSprite = false;
|
||||
return false;
|
||||
}
|
||||
expandSprite = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Sets up the sprite positioning data for this texture
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGameTexture::SetupSpriteData()
|
||||
{
|
||||
// Since this is only needed for real sprites it gets allocated on demand.
|
||||
// It also allocates from the image memory arena because it has the same lifetime and to reduce maintenance.
|
||||
if (spi == nullptr) spi = (SpritePositioningInfo*)ImageArena.Alloc(2 * sizeof(SpritePositioningInfo));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto& spi = this->spi[i];
|
||||
spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f;
|
||||
spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f;
|
||||
spi.spriteWidth = GetTexelWidth();
|
||||
spi.spriteHeight = GetTexelHeight();
|
||||
|
||||
if (i == 1 && ShouldExpandSprite())
|
||||
{
|
||||
spi.mTrimResult = Base->TrimBorders(spi.trim); // get the trim size before adding the empty frame
|
||||
spi.spriteWidth += 2;
|
||||
spi.spriteHeight += 2;
|
||||
}
|
||||
}
|
||||
SetSpriteRect();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Set the sprite rectangle. This is separate because it may be called by a CVAR, too.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGameTexture::SetSpriteRect()
|
||||
{
|
||||
|
||||
if (!spi) return;
|
||||
auto leftOffset = GetTexelLeftOffset(r_spriteadjustHW);
|
||||
auto topOffset = GetTexelTopOffset(r_spriteadjustHW);
|
||||
|
||||
float fxScale = GetScaleX();
|
||||
float fyScale = GetScaleY();
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto& spi = this->spi[i];
|
||||
|
||||
// mSpriteRect is for positioning the sprite in the scene.
|
||||
spi.mSpriteRect.left = -leftOffset / fxScale;
|
||||
spi.mSpriteRect.top = -topOffset / fyScale;
|
||||
spi.mSpriteRect.width = spi.spriteWidth / fxScale;
|
||||
spi.mSpriteRect.height = spi.spriteHeight / fyScale;
|
||||
|
||||
if (i == 1 && ShouldExpandSprite())
|
||||
{
|
||||
// a little adjustment to make sprites look better with texture filtering:
|
||||
// create a 1 pixel wide empty frame around them.
|
||||
|
||||
int oldwidth = spi.spriteWidth - 2;
|
||||
int oldheight = spi.spriteHeight - 2;
|
||||
|
||||
leftOffset += 1;
|
||||
topOffset += 1;
|
||||
|
||||
// Reposition the sprite with the frame considered
|
||||
spi.mSpriteRect.left = -(float)leftOffset / fxScale;
|
||||
spi.mSpriteRect.top = -(float)topOffset / fyScale;
|
||||
spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale;
|
||||
spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale;
|
||||
|
||||
if (spi.mTrimResult > 0)
|
||||
{
|
||||
spi.mSpriteRect.left += (float)spi.trim[0] / fxScale;
|
||||
spi.mSpriteRect.top += (float)spi.trim[1] / fyScale;
|
||||
|
||||
spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale;
|
||||
spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale;
|
||||
|
||||
spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth;
|
||||
spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight;
|
||||
spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth;
|
||||
spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Cleans the attached hardware resources.
|
||||
// This should only be used on textures which alter their content at run time
|
||||
//or when the engine shuts down.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGameTexture::CleanHardwareData(bool full)
|
||||
{
|
||||
Base->CleanHardwareTextures();
|
||||
for (auto mat : Material) if (mat) mat->DeleteDescriptors();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Make sprite offset adjustment user-configurable per renderer.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
r_spriteadjustHW = !!(self & 2);
|
||||
r_spriteadjustSW = !!(self & 1);
|
||||
for (int i = 0; i < TexMan.NumTextures(); i++)
|
||||
{
|
||||
auto tex = TexMan.GetGameTexture(FSetTextureID(i));
|
||||
if (tex->GetTexelLeftOffset(0) != tex->GetTexelLeftOffset(1) || tex->GetTexelTopOffset(0) != tex->GetTexelTopOffset(1))
|
||||
{
|
||||
tex->SetSpriteRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Coordinate helper.
|
||||
// The only reason this is even needed is that many years ago someone
|
||||
// was convinced that having per-texel panning on walls was a good idea.
|
||||
// If it wasn't for this relatively useless feature the entire positioning
|
||||
// code for wall textures could be a lot simpler.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::RowOffset(float rowoffset) const
|
||||
{
|
||||
float scale = fabs(mScale.Y);
|
||||
if (scale == 1.f || mWorldPanning) return rowoffset;
|
||||
else return rowoffset / scale;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::TextureOffset(float textureoffset) const
|
||||
{
|
||||
float scale = fabs(mScale.X);
|
||||
if (scale == 1.f || mWorldPanning) return textureoffset;
|
||||
else return textureoffset / scale;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Returns the size for which texture offset coordinates are used.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::TextureAdjustWidth() const
|
||||
{
|
||||
if (mWorldPanning)
|
||||
{
|
||||
float tscale = fabs(mTempScale.X);
|
||||
if (tscale == 1.f) return (float)mRenderWidth;
|
||||
else return mWidth / fabs(tscale);
|
||||
}
|
||||
else return (float)mWidth;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Retrieve texture coordinate info for per-wall scaling
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTexCoordInfo::GetFromTexture(FGameTexture *tex, float x, float y, bool forceworldpanning)
|
||||
{
|
||||
if (x == 1.f)
|
||||
{
|
||||
mRenderWidth = xs_RoundToInt(tex->GetDisplayWidth());
|
||||
mScale.X = tex->GetScaleX();
|
||||
mTempScale.X = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale_x = x * tex->GetScaleX();
|
||||
mRenderWidth = xs_CeilToInt(tex->GetTexelWidth() / scale_x);
|
||||
mScale.X = scale_x;
|
||||
mTempScale.X = x;
|
||||
}
|
||||
|
||||
if (y == 1.f)
|
||||
{
|
||||
mRenderHeight = xs_RoundToInt(tex->GetDisplayHeight());
|
||||
mScale.Y = tex->GetScaleY();
|
||||
mTempScale.Y = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale_y = y * tex->GetScaleY();
|
||||
mRenderHeight = xs_CeilToInt(tex->GetTexelHeight() / scale_y);
|
||||
mScale.Y = scale_y;
|
||||
mTempScale.Y = y;
|
||||
}
|
||||
if (tex->isHardwareCanvas())
|
||||
{
|
||||
mScale.Y = -mScale.Y;
|
||||
mRenderHeight = -mRenderHeight;
|
||||
}
|
||||
mWorldPanning = tex->useWorldPanning() || forceworldpanning;
|
||||
mWidth = tex->GetTexelWidth();
|
||||
}
|
||||
|
339
source/common/textures/gametexture.h
Normal file
339
source/common/textures/gametexture.h
Normal file
|
@ -0,0 +1,339 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "vectors.h"
|
||||
#include "floatrect.h"
|
||||
#include "refcounted.h"
|
||||
#include "xs_Float.h"
|
||||
#include "palentry.h"
|
||||
#include "zstring.h"
|
||||
#include "textureid.h"
|
||||
|
||||
// 15 because 0th texture is our texture
|
||||
#define MAX_CUSTOM_HW_SHADER_TEXTURES 15
|
||||
class FTexture;
|
||||
class ISoftwareTexture;
|
||||
class FMaterial;
|
||||
|
||||
struct SpritePositioningInfo
|
||||
{
|
||||
uint16_t trim[4];
|
||||
int spriteWidth, spriteHeight;
|
||||
float mSpriteU[2], mSpriteV[2];
|
||||
FloatRect mSpriteRect;
|
||||
uint8_t mTrimResult;
|
||||
|
||||
float GetSpriteUL() const { return mSpriteU[0]; }
|
||||
float GetSpriteVT() const { return mSpriteV[0]; }
|
||||
float GetSpriteUR() const { return mSpriteU[1]; }
|
||||
float GetSpriteVB() const { return mSpriteV[1]; }
|
||||
|
||||
const FloatRect &GetSpriteRect() const
|
||||
{
|
||||
return mSpriteRect;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct MaterialLayers
|
||||
{
|
||||
float Glossiness;
|
||||
float SpecularLevel;
|
||||
FGameTexture* Brightmap;
|
||||
FGameTexture* Normal;
|
||||
FGameTexture* Specular;
|
||||
FGameTexture* Metallic;
|
||||
FGameTexture* Roughness;
|
||||
FGameTexture* AmbientOcclusion;
|
||||
FGameTexture* CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES];
|
||||
};
|
||||
|
||||
enum EGameTexFlags
|
||||
{
|
||||
GTexf_NoDecals = 1, // Decals should not stick to texture
|
||||
GTexf_WorldPanning = 2, // Texture is panned in world units rather than texels
|
||||
GTexf_FullNameTexture = 4, // Name is taken from the file system.
|
||||
GTexf_Glowing = 8, // Texture emits a glow
|
||||
GTexf_AutoGlowing = 16, // Glow info is determined from texture image.
|
||||
GTexf_RenderFullbright = 32, // always draw fullbright
|
||||
GTexf_DisableFullbrightSprites = 64, // This texture will not be displayed as fullbright sprite
|
||||
GTexf_BrightmapChecked = 128, // Check for a colormap-based brightmap was already done.
|
||||
};
|
||||
|
||||
// Refactoring helper to allow piece by piece adjustment of the API
|
||||
class FGameTexture
|
||||
{
|
||||
friend class FMaterial;
|
||||
|
||||
// Material layers. These are shared so reference counting is used.
|
||||
RefCountedPtr<FTexture> Base;
|
||||
RefCountedPtr<FTexture> Brightmap;
|
||||
RefCountedPtr<FTexture> Detailmap;
|
||||
RefCountedPtr<FTexture> Glowmap;
|
||||
RefCountedPtr<FTexture> Normal; // Normal map texture
|
||||
RefCountedPtr<FTexture> Specular; // Specular light texture for the diffuse+normal+specular light model
|
||||
RefCountedPtr<FTexture> Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
||||
RefCountedPtr<FTexture> Roughness; // Roughness texture for PBR
|
||||
RefCountedPtr<FTexture> AmbientOcclusion; // Ambient occlusion texture for PBR
|
||||
RefCountedPtr<FTexture> CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES]; // Custom texture maps for custom hardware shaders
|
||||
|
||||
FString Name;
|
||||
FTextureID id;
|
||||
|
||||
uint16_t TexelWidth, TexelHeight;
|
||||
int16_t LeftOffset[2], TopOffset[2];
|
||||
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;
|
||||
|
||||
ISoftwareTexture* SoftwareTexture = nullptr;
|
||||
FMaterial* Material[4] = { };
|
||||
|
||||
// Material properties
|
||||
float Glossiness = 10.f;
|
||||
float SpecularLevel = 0.1f;
|
||||
float shaderspeed = 1.f;
|
||||
int shaderindex = 0;
|
||||
|
||||
int flags = 0;
|
||||
uint8_t warped = 0;
|
||||
int8_t expandSprite = -1;
|
||||
uint16_t GlowHeight;
|
||||
PalEntry GlowColor = 0;
|
||||
|
||||
int16_t SkyOffset = 0;
|
||||
uint16_t Rotations = 0xffff;
|
||||
|
||||
|
||||
public:
|
||||
float alphaThreshold = 0.5f;
|
||||
|
||||
FGameTexture(FTexture* wrap, const char *name);
|
||||
~FGameTexture();
|
||||
void Setup(FTexture* wrap);
|
||||
FTextureID GetID() const { return id; }
|
||||
void SetID(FTextureID newid) { id = newid; } // should only be called by the texture manager
|
||||
const FString& GetName() const { return Name; }
|
||||
void SetName(const char* name) { Name = name; } // should only be called by setup code.
|
||||
|
||||
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();
|
||||
void SetupSpriteData();
|
||||
void SetSpriteRect();
|
||||
|
||||
ETextureType GetUseType() const { return UseType; }
|
||||
void SetUpscaleFlag(int what) { shouldUpscaleFlag = what; }
|
||||
int GetUpscaleFlag() { return shouldUpscaleFlag; }
|
||||
|
||||
FTexture* GetTexture() { return Base.get(); }
|
||||
int GetSourceLump() const { return Base->GetSourceLump(); }
|
||||
void SetBrightmap(FGameTexture* tex) { Brightmap = tex->GetTexture(); }
|
||||
|
||||
int GetTexelLeftOffset(int adjusted = 0) const { return LeftOffset[adjusted]; }
|
||||
int GetTexelTopOffset(int adjusted = 0) const { return TopOffset[adjusted]; }
|
||||
float GetDisplayLeftOffset(int adjusted = 0) const { return LeftOffset[adjusted] / ScaleX; }
|
||||
float GetDisplayTopOffset(int adjusted = 0) const { return TopOffset[adjusted] / ScaleY; }
|
||||
|
||||
bool isMiscPatch() const { return GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
|
||||
bool isFullbrightDisabled() const { return !!(flags & GTexf_DisableFullbrightSprites); }
|
||||
bool isFullbright() const { return !!(flags & GTexf_RenderFullbright); }
|
||||
bool isFullNameTexture() const { return !!(flags & GTexf_FullNameTexture); }
|
||||
bool expandSprites() { return expandSprite == -1? ShouldExpandSprite() : !!expandSprite; }
|
||||
bool useWorldPanning() const { return !!(flags & GTexf_WorldPanning); }
|
||||
void SetWorldPanning(bool on) { if (on) flags |= GTexf_WorldPanning; else flags &= ~GTexf_WorldPanning; }
|
||||
bool allowNoDecals() const { return !!(flags & GTexf_NoDecals); }
|
||||
void SetNoDecals(bool on) { if (on) flags |= GTexf_NoDecals; else flags &= ~GTexf_NoDecals; }
|
||||
|
||||
bool isValid() const { return UseType != ETextureType::Null; }
|
||||
int isWarped() { return warped; }
|
||||
void SetWarpStyle(int style) { warped = style; }
|
||||
bool isMasked() { return Base->Masked; }
|
||||
bool isHardwareCanvas() const { return Base->isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later.
|
||||
bool isSoftwareCanvas() const { return Base->isCanvas(); }
|
||||
|
||||
void SetTranslucent(bool on) { Base->bTranslucent = on; }
|
||||
void SetUseType(ETextureType type) { UseType = type; }
|
||||
int GetRotations() const { return Rotations; }
|
||||
void SetRotations(int rot) { Rotations = int16_t(rot); }
|
||||
void SetSkyOffset(int offs) { SkyOffset = offs; }
|
||||
int GetSkyOffset() const { return SkyOffset; }
|
||||
|
||||
ISoftwareTexture* GetSoftwareTexture()
|
||||
{
|
||||
return SoftwareTexture;
|
||||
}
|
||||
void SetSoftwareTexture(ISoftwareTexture* swtex)
|
||||
{
|
||||
SoftwareTexture = swtex;
|
||||
}
|
||||
|
||||
FMaterial* GetMaterial(int num)
|
||||
{
|
||||
return Material[num];
|
||||
}
|
||||
|
||||
int GetShaderIndex() const { return shaderindex; }
|
||||
float GetShaderSpeed() const { return shaderspeed; }
|
||||
void SetShaderSpeed(float speed) { shaderspeed = speed; }
|
||||
void SetShaderIndex(int index) { shaderindex = index; }
|
||||
void SetShaderLayers(MaterialLayers& lay)
|
||||
{
|
||||
// Only update layers that have something defind.
|
||||
if (lay.Glossiness > -1000) Glossiness = lay.Glossiness;
|
||||
if (lay.SpecularLevel > -1000) SpecularLevel = lay.SpecularLevel;
|
||||
if (lay.Brightmap) Brightmap = lay.Brightmap->GetTexture();
|
||||
if (lay.Normal) Normal = lay.Normal->GetTexture();
|
||||
if (lay.Specular) Specular = lay.Specular->GetTexture();
|
||||
if (lay.Metallic) Metallic = lay.Metallic->GetTexture();
|
||||
if (lay.Roughness) Roughness = lay.Roughness->GetTexture();
|
||||
if (lay.AmbientOcclusion) AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
|
||||
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
|
||||
{
|
||||
if (lay.CustomShaderTextures[i]) CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
|
||||
}
|
||||
}
|
||||
float GetGlossiness() const { return Glossiness; }
|
||||
float GetSpecularLevel() const { return SpecularLevel; }
|
||||
|
||||
void CopySize(FGameTexture* BaseTexture)
|
||||
{
|
||||
Base->CopySize(BaseTexture->Base.get());
|
||||
}
|
||||
|
||||
// Glowing is a pure material property that should not filter down to the actual texture objects.
|
||||
void GetGlowColor(float* data);
|
||||
bool isGlowing() const { return !!(flags & GTexf_Glowing); }
|
||||
bool isAutoGlowing() const { return !!(flags & GTexf_AutoGlowing); }
|
||||
int GetGlowHeight() const { return GlowHeight; }
|
||||
void SetAutoGlowing() { flags |= (GTexf_AutoGlowing | GTexf_Glowing | GTexf_RenderFullbright); }
|
||||
void SetGlowHeight(int v) { GlowHeight = v; }
|
||||
void SetFullbright() { flags |= GTexf_RenderFullbright; }
|
||||
void SetDisableFullbright(bool on) { if (on) flags |= GTexf_DisableFullbrightSprites; else flags &= ~GTexf_DisableFullbrightSprites; }
|
||||
void SetGlowing(PalEntry color) { flags = (flags & ~GTexf_AutoGlowing) | GTexf_Glowing; GlowColor = color; }
|
||||
|
||||
bool isUserContent() const;
|
||||
int CheckRealHeight() { return xs_RoundToInt(Base->CheckRealHeight() / ScaleY); }
|
||||
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 = TexelWidth / w;
|
||||
ScaleY = TexelHeight / h;
|
||||
|
||||
// compensate for roundoff errors
|
||||
if (int(ScaleX * w) != TexelWidth) ScaleX += (1 / 65536.);
|
||||
if (int(ScaleY * h) != TexelHeight) ScaleY += (1 / 65536.);
|
||||
|
||||
}
|
||||
void SetOffsets(int which, int x, int y)
|
||||
{
|
||||
LeftOffset[which] = x;
|
||||
TopOffset[which] = y;
|
||||
}
|
||||
void SetOffsets(int x, int y)
|
||||
{
|
||||
LeftOffset[0] = x;
|
||||
TopOffset[0] = y;
|
||||
LeftOffset[1] = x;
|
||||
TopOffset[1] = y;
|
||||
}
|
||||
void SetScale(float x, float y)
|
||||
{
|
||||
ScaleX = x;
|
||||
ScaleY = y;
|
||||
DisplayWidth = x * TexelWidth;
|
||||
DisplayHeight = y * TexelHeight;
|
||||
}
|
||||
|
||||
const SpritePositioningInfo& GetSpritePositioning(int which) { if (spi == nullptr) SetupSpriteData(); return spi[which]; }
|
||||
int GetAreas(FloatRect** pAreas) const;
|
||||
|
||||
bool GetTranslucency()
|
||||
{
|
||||
return Base->GetTranslucency();
|
||||
}
|
||||
|
||||
int GetClampMode(int clampmode)
|
||||
{
|
||||
if (GetUseType() == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER;
|
||||
else if (isHardwareCanvas()) clampmode = CLAMP_CAMTEX;
|
||||
else if ((isWarped() || shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
||||
return clampmode;
|
||||
}
|
||||
|
||||
void CleanHardwareData(bool full = true);
|
||||
|
||||
void GetLayers(TArray<FTexture*>& layers)
|
||||
{
|
||||
layers.Clear();
|
||||
for (auto tex : { Base.get(), Brightmap.get(), Detailmap.get(), Glowmap.get(), Normal.get(), Specular.get(), Metallic.get(), Roughness.get(), AmbientOcclusion.get() })
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex);
|
||||
}
|
||||
for (auto& tex : CustomShaderTextures)
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex.get());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType)
|
||||
{
|
||||
if (!tex) return nullptr;
|
||||
auto t = new FGameTexture(tex, name);
|
||||
t->SetUseType(useType);
|
||||
return t;
|
||||
}
|
||||
|
||||
enum EUpscaleFlags
|
||||
{
|
||||
UF_None = 0,
|
||||
UF_Texture = 1,
|
||||
UF_Sprite = 2,
|
||||
UF_Font = 4
|
||||
};
|
||||
|
||||
extern int upscalemask;
|
||||
void UpdateUpscaleMask();
|
||||
|
||||
int calcShouldUpscale(FGameTexture* tex);
|
||||
inline int shouldUpscale(FGameTexture* tex, EUpscaleFlags UseType)
|
||||
{
|
||||
// This only checks the global scale mask and the texture's validation for upscaling. Everything else has been done up front elsewhere.
|
||||
if (!(upscalemask & UseType)) return 0;
|
||||
return tex->GetUpscaleFlag();
|
||||
}
|
||||
|
||||
struct FTexCoordInfo
|
||||
{
|
||||
int mRenderWidth;
|
||||
int mRenderHeight;
|
||||
int mWidth;
|
||||
FVector2 mScale;
|
||||
FVector2 mTempScale;
|
||||
bool mWorldPanning;
|
||||
|
||||
float FloatToTexU(float v) const { return v / mRenderWidth; }
|
||||
float FloatToTexV(float v) const { return v / mRenderHeight; }
|
||||
float RowOffset(float ofs) const;
|
||||
float TextureOffset(float ofs) const;
|
||||
float TextureAdjustWidth() const;
|
||||
void GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning);
|
||||
};
|
|
@ -46,6 +46,8 @@
|
|||
#include "texturemanager.h"
|
||||
#include "printf.h"
|
||||
|
||||
int upscalemask;
|
||||
|
||||
EXTERN_CVAR(Int, gl_texture_hqresizemult)
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
|
@ -54,6 +56,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG |
|
|||
if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0))
|
||||
gl_texture_hqresizemult = 4;
|
||||
TexMan.FlushAll();
|
||||
UpdateUpscaleMask();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
|
@ -63,6 +66,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG |
|
|||
if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0))
|
||||
self = 4;
|
||||
TexMan.FlushAll();
|
||||
UpdateUpscaleMask();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
|
@ -74,6 +78,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOB
|
|||
CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
TexMan.FlushAll();
|
||||
UpdateUpscaleMask();
|
||||
}
|
||||
|
||||
CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1);
|
||||
|
@ -96,6 +101,13 @@ CUSTOM_CVAR(Int, gl_texture_hqresize_mt_height, 4, CVAR_ARCHIVE | CVAR_GLOBALCON
|
|||
|
||||
CVAR(Int, xbrz_colorformat, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
void UpdateUpscaleMask()
|
||||
{
|
||||
if (!gl_texture_hqresizemode || gl_texture_hqresizemult == 1) upscalemask = 0;
|
||||
else upscalemask = gl_texture_hqresize_targets;
|
||||
}
|
||||
|
||||
|
||||
static void xbrzApplyOptions()
|
||||
{
|
||||
if (gl_texture_hqresizemult != 0 && (gl_texture_hqresizemode == 4 || gl_texture_hqresizemode == 5))
|
||||
|
@ -405,42 +417,15 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int
|
|||
// the upsampled buffer.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly)
|
||||
{
|
||||
// [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;
|
||||
|
||||
switch (UseType)
|
||||
{
|
||||
case ETextureType::Sprite:
|
||||
case ETextureType::SkinSprite:
|
||||
if (!(gl_texture_hqresize_targets & 2)) return;
|
||||
break;
|
||||
|
||||
case ETextureType::FontChar:
|
||||
if (!(gl_texture_hqresize_targets & 4)) return;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(gl_texture_hqresize_targets & 1)) return;
|
||||
break;
|
||||
}
|
||||
|
||||
int type = gl_texture_hqresizemode;
|
||||
int mult = gl_texture_hqresizemult;
|
||||
#ifdef HAVE_MMX
|
||||
|
@ -509,3 +494,28 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
|
|||
contentId.scalefactor = mult;
|
||||
texbuffer.mContentId = contentId.id;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// This was pulled out of the above function to allow running these
|
||||
// checks before the texture is passed to the render state.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int calcShouldUpscale(FGameTexture *tex)
|
||||
{
|
||||
// [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 0;
|
||||
|
||||
// [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!)
|
||||
if (tex->isHardwareCanvas())
|
||||
return 0;
|
||||
|
||||
// already scaled?
|
||||
if (tex->GetDisplayWidth() >= 2* tex->GetTexelWidth() || tex->GetDisplayHeight() >= 2*tex->GetTexelHeight())
|
||||
return 0;
|
||||
|
||||
return CTF_Upscale;
|
||||
}
|
|
@ -14,10 +14,8 @@ public:
|
|||
MAX_TEXTURES = 16
|
||||
};
|
||||
|
||||
IHardwareTexture() {}
|
||||
virtual ~IHardwareTexture() {}
|
||||
|
||||
virtual void DeleteDescriptors() { }
|
||||
IHardwareTexture() = default;
|
||||
virtual ~IHardwareTexture() = default;
|
||||
|
||||
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
||||
virtual uint8_t *MapBuffer() = 0;
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include "hw_material.h"
|
||||
#include "texturemanager.h"
|
||||
#include "c_cvars.h"
|
||||
#include "v_video.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||
IHardwareTexture* CreateHardwareTexture();
|
||||
|
||||
//===========================================================================
|
||||
|
@ -37,99 +37,100 @@ IHardwareTexture* CreateHardwareTexture();
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FMaterial::FMaterial(FTexture * tx, bool expanded)
|
||||
FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||
{
|
||||
mShaderIndex = SHADER_Default;
|
||||
sourcetex = tex = tx;
|
||||
sourcetex = tx;
|
||||
auto imgtex = tx->GetTexture();
|
||||
mTextureLayers.Push({ imgtex, scaleflags });
|
||||
|
||||
if (tx->UseType == ETextureType::SWCanvas && static_cast<FWrapperTexture*>(tx)->GetColorFormat() == 0)
|
||||
if (tx->GetUseType() == ETextureType::SWCanvas && static_cast<FWrapperTexture*>(imgtex)->GetColorFormat() == 0)
|
||||
{
|
||||
mShaderIndex = SHADER_Paletted;
|
||||
}
|
||||
else if (tx->isWarped())
|
||||
{
|
||||
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
||||
}
|
||||
else if (tx->isHardwareCanvas())
|
||||
{
|
||||
if (tx->shaderindex >= FIRST_USER_SHADER)
|
||||
if (tx->GetShaderIndex() >= FIRST_USER_SHADER)
|
||||
{
|
||||
mShaderIndex = tx->shaderindex;
|
||||
mShaderIndex = tx->GetShaderIndex();
|
||||
}
|
||||
// no brightmap for cameratexture
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tx->Normal && tx->Specular)
|
||||
if (tx->isWarped())
|
||||
{
|
||||
for (auto &texture : { tx->Normal, tx->Specular })
|
||||
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
||||
}
|
||||
// Note that the material takes no ownership of the texture!
|
||||
else if (tx->Normal.get() && tx->Specular.get())
|
||||
{
|
||||
for (auto &texture : { tx->Normal.get(), tx->Specular.get() })
|
||||
{
|
||||
mTextureLayers.Push(texture);
|
||||
mTextureLayers.Push({ texture, 0 });
|
||||
}
|
||||
mShaderIndex = SHADER_Specular;
|
||||
}
|
||||
else if (tx->Normal && tx->Metallic && tx->Roughness && tx->AmbientOcclusion)
|
||||
else if (tx->Normal.get() && tx->Metallic.get() && tx->Roughness.get() && tx->AmbientOcclusion.get())
|
||||
{
|
||||
for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion })
|
||||
for (auto &texture : { tx->Normal.get(), tx->Metallic.get(), tx->Roughness.get(), tx->AmbientOcclusion.get() })
|
||||
{
|
||||
mTextureLayers.Push(texture);
|
||||
mTextureLayers.Push({ texture, 0 });
|
||||
}
|
||||
mShaderIndex = SHADER_PBR;
|
||||
}
|
||||
|
||||
// Note that these layers must present a valid texture even if not used, because empty TMUs in the shader are an undefined condition.
|
||||
tx->CreateDefaultBrightmap();
|
||||
if (tx->Brightmap)
|
||||
auto placeholder = TexMan.GameByIndex(1);
|
||||
if (tx->Brightmap.get())
|
||||
{
|
||||
mTextureLayers.Push(tx->Brightmap);
|
||||
if (mShaderIndex == SHADER_Specular)
|
||||
mShaderIndex = SHADER_SpecularBrightmap;
|
||||
else if (mShaderIndex == SHADER_PBR)
|
||||
mShaderIndex = SHADER_PBRBrightmap;
|
||||
else
|
||||
mShaderIndex = SHADER_Brightmap;
|
||||
mTextureLayers.Push({ tx->Brightmap.get(), scaleflags });
|
||||
mLayerFlags |= TEXF_Brightmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
if (tx->Detailmap.get())
|
||||
{
|
||||
mTextureLayers.Push({ tx->Detailmap.get(), 0 });
|
||||
mLayerFlags |= TEXF_Detailmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
if (tx->Glowmap.get())
|
||||
{
|
||||
mTextureLayers.Push({ tx->Glowmap.get(), scaleflags });
|
||||
mLayerFlags |= TEXF_Glowmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
|
||||
if (tx->shaderindex >= FIRST_USER_SHADER)
|
||||
auto index = tx->GetShaderIndex();
|
||||
if (index >= FIRST_USER_SHADER)
|
||||
{
|
||||
const UserShaderDesc &usershader = usershaders[tx->shaderindex - FIRST_USER_SHADER];
|
||||
const UserShaderDesc &usershader = usershaders[index - FIRST_USER_SHADER];
|
||||
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||
{
|
||||
for (auto &texture : tx->CustomShaderTextures)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push(texture);
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
}
|
||||
mShaderIndex = tx->shaderindex;
|
||||
mShaderIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
mWidth = tx->GetTexelWidth();
|
||||
mHeight = tx->GetTexelHeight();
|
||||
mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets.
|
||||
mTopOffset = tx->GetTopOffset(0);
|
||||
mRenderWidth = tx->GetScaledWidth();
|
||||
mRenderHeight = tx->GetScaledHeight();
|
||||
mSpriteU[0] = mSpriteV[0] = 0.f;
|
||||
mSpriteU[1] = mSpriteV[1] = 1.f;
|
||||
|
||||
mExpanded = expanded;
|
||||
if (expanded)
|
||||
{
|
||||
int oldwidth = mWidth;
|
||||
int oldheight = mHeight;
|
||||
|
||||
mTrimResult = TrimBorders(trim); // get the trim size before adding the empty frame
|
||||
mWidth += 2;
|
||||
mHeight += 2;
|
||||
mRenderWidth = mRenderWidth * mWidth / oldwidth;
|
||||
mRenderHeight = mRenderHeight * mHeight / oldheight;
|
||||
|
||||
}
|
||||
SetSpriteRect();
|
||||
mScaleFlags = scaleflags;
|
||||
|
||||
mTextureLayers.ShrinkToFit();
|
||||
tx->Material[expanded] = this;
|
||||
if (tx->isHardwareCanvas()) tx->bTranslucent = 0;
|
||||
tx->Material[scaleflags] = this;
|
||||
if (tx->isHardwareCanvas()) tx->SetTranslucent(false);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -142,193 +143,22 @@ FMaterial::~FMaterial()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Set the sprite rectangle
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMaterial::SetSpriteRect()
|
||||
IHardwareTexture *FMaterial::GetLayer(int i, int translation, MaterialLayerInfo **pLayer) const
|
||||
{
|
||||
auto leftOffset = tex->GetLeftOffsetHW();
|
||||
auto topOffset = tex->GetTopOffsetHW();
|
||||
|
||||
float fxScale = (float)tex->Scale.X;
|
||||
float fyScale = (float)tex->Scale.Y;
|
||||
|
||||
// mSpriteRect is for positioning the sprite in the scene.
|
||||
mSpriteRect.left = -leftOffset / fxScale;
|
||||
mSpriteRect.top = -topOffset / fyScale;
|
||||
mSpriteRect.width = mWidth / fxScale;
|
||||
mSpriteRect.height = mHeight / fyScale;
|
||||
|
||||
if (mExpanded)
|
||||
{
|
||||
// a little adjustment to make sprites look better with texture filtering:
|
||||
// create a 1 pixel wide empty frame around them.
|
||||
|
||||
int oldwidth = mWidth - 2;
|
||||
int oldheight = mHeight - 2;
|
||||
|
||||
leftOffset += 1;
|
||||
topOffset += 1;
|
||||
|
||||
// Reposition the sprite with the frame considered
|
||||
mSpriteRect.left = -leftOffset / fxScale;
|
||||
mSpriteRect.top = -topOffset / fyScale;
|
||||
mSpriteRect.width = mWidth / fxScale;
|
||||
mSpriteRect.height = mHeight / fyScale;
|
||||
|
||||
if (mTrimResult)
|
||||
{
|
||||
mSpriteRect.left += trim[0] / fxScale;
|
||||
mSpriteRect.top += trim[1] / fyScale;
|
||||
|
||||
mSpriteRect.width -= (oldwidth - trim[2]) / fxScale;
|
||||
mSpriteRect.height -= (oldheight - trim[3]) / fyScale;
|
||||
|
||||
mSpriteU[0] = trim[0] / (float)mWidth;
|
||||
mSpriteV[0] = trim[1] / (float)mHeight;
|
||||
mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth;
|
||||
mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Finds empty space around the texture.
|
||||
// Used for sprites that got placed into a huge empty frame.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FMaterial::TrimBorders(uint16_t *rect)
|
||||
{
|
||||
|
||||
auto texbuffer = sourcetex->CreateTexBuffer(0);
|
||||
int w = texbuffer.mWidth;
|
||||
int h = texbuffer.mHeight;
|
||||
auto Buffer = texbuffer.mBuffer;
|
||||
|
||||
if (texbuffer.mBuffer == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (w != mWidth || h != mHeight)
|
||||
{
|
||||
// external Hires replacements cannot be trimmed.
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = w*h;
|
||||
if (size == 1)
|
||||
{
|
||||
// nothing to be done here.
|
||||
rect[0] = 0;
|
||||
rect[1] = 0;
|
||||
rect[2] = 1;
|
||||
rect[3] = 1;
|
||||
return true;
|
||||
}
|
||||
int first, last;
|
||||
|
||||
for(first = 0; first < size; first++)
|
||||
{
|
||||
if (Buffer[first*4+3] != 0) break;
|
||||
}
|
||||
if (first >= size)
|
||||
{
|
||||
// completely empty
|
||||
rect[0] = 0;
|
||||
rect[1] = 0;
|
||||
rect[2] = 1;
|
||||
rect[3] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
for(last = size-1; last >= first; last--)
|
||||
{
|
||||
if (Buffer[last*4+3] != 0) break;
|
||||
}
|
||||
|
||||
rect[1] = first / w;
|
||||
rect[3] = 1 + last/w - rect[1];
|
||||
|
||||
rect[0] = 0;
|
||||
rect[2] = w;
|
||||
|
||||
unsigned char *bufferoff = Buffer + (rect[1] * w * 4);
|
||||
h = rect[3];
|
||||
|
||||
for(int x = 0; x < w; x++)
|
||||
{
|
||||
for(int y = 0; y < h; y++)
|
||||
{
|
||||
if (bufferoff[(x+y*w)*4+3] != 0) goto outl;
|
||||
}
|
||||
rect[0]++;
|
||||
}
|
||||
outl:
|
||||
rect[2] -= rect[0];
|
||||
|
||||
for(int x = w-1; rect[2] > 1; x--)
|
||||
{
|
||||
for(int y = 0; y < h; y++)
|
||||
{
|
||||
if (bufferoff[(x+y*w)*4+3] != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rect[2]--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer)
|
||||
{
|
||||
FTexture *layer = i == 0 ? tex : mTextureLayers[i - 1];
|
||||
if (pLayer) *pLayer = layer;
|
||||
auto &layer = mTextureLayers[i];
|
||||
if (pLayer) *pLayer = &layer;
|
||||
|
||||
if (layer && layer->UseType!=ETextureType::Null)
|
||||
{
|
||||
IHardwareTexture *hwtex = layer->SystemTextures.GetHardwareTexture(translation, mExpanded);
|
||||
if (hwtex == nullptr)
|
||||
{
|
||||
hwtex = CreateHardwareTexture();
|
||||
layer->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex);
|
||||
}
|
||||
return hwtex;
|
||||
}
|
||||
if (layer.layerTexture) return layer.layerTexture->GetHardwareTexture(translation, layer.scaleFlags);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int FMaterial::GetAreas(FloatRect **pAreas) const
|
||||
{
|
||||
if (mShaderIndex == SHADER_Default) // texture splitting can only be done if there's no attached effects
|
||||
{
|
||||
*pAreas = sourcetex->areas;
|
||||
return sourcetex->areacount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets a texture from the texture manager and checks its validity for
|
||||
|
@ -336,75 +166,27 @@ int FMaterial::GetAreas(FloatRect **pAreas) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand, bool create)
|
||||
FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool create)
|
||||
{
|
||||
again:
|
||||
if (tex && tex->isValid())
|
||||
#if 0
|
||||
if (gtex && gtex->isValid())
|
||||
{
|
||||
if (tex->bNoExpand) expand = false;
|
||||
if (!gtex->expandSprites()) scaleflags &= ~CTF_Expand;
|
||||
|
||||
FMaterial *hwtex = tex->Material[expand];
|
||||
FMaterial *hwtex = gtex->Material[scaleflags];
|
||||
if (hwtex == NULL && create)
|
||||
{
|
||||
if (expand)
|
||||
{
|
||||
if (tex->isWarped() || tex->isHardwareCanvas() || tex->shaderindex >= FIRST_USER_SHADER || (tex->shaderindex >= SHADER_Specular && tex->shaderindex <= SHADER_PBRBrightmap))
|
||||
{
|
||||
tex->bNoExpand = true;
|
||||
goto again;
|
||||
}
|
||||
if (tex->Brightmap != NULL &&
|
||||
(tex->GetTexelWidth() != tex->Brightmap->GetTexelWidth() ||
|
||||
tex->GetTexelHeight() != tex->Brightmap->GetTexelHeight())
|
||||
)
|
||||
{
|
||||
// do not expand if the brightmap's size differs.
|
||||
tex->bNoExpand = true;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
hwtex = new FMaterial(tex, expand);
|
||||
hwtex = screen->CreateMaterial(gtex, scaleflags);
|
||||
}
|
||||
return hwtex;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate, bool create)
|
||||
{
|
||||
return ValidateTexture(TexMan.GetTexture(no, translate), expand, create);
|
||||
}
|
||||
|
||||
|
||||
void DeleteMaterial(FMaterial* mat)
|
||||
{
|
||||
delete mat;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Make sprite offset adjustment user-configurable per renderer.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern int r_spriteadjustSW, r_spriteadjustHW;
|
||||
|
||||
CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
r_spriteadjustHW = !!(self & 2);
|
||||
r_spriteadjustSW = !!(self & 1);
|
||||
for (int i = 0; i < TexMan.NumTextures(); i++)
|
||||
{
|
||||
auto tex = TexMan.GetTexture(FSetTextureID(i));
|
||||
if (tex->GetTexelLeftOffset(0) != tex->GetTexelLeftOffset(1) || tex->GetTexelTopOffset(0) != tex->GetTexelTopOffset(1))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto mat = tex->GetMaterial(i);
|
||||
if (mat != nullptr) mat->SetSpriteRect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,18 +8,12 @@
|
|||
struct FRemapTable;
|
||||
class IHardwareTexture;
|
||||
|
||||
enum
|
||||
struct MaterialLayerInfo
|
||||
{
|
||||
CLAMP_NONE = 0,
|
||||
CLAMP_X = 1,
|
||||
CLAMP_Y = 2,
|
||||
CLAMP_XY = 3,
|
||||
CLAMP_XY_NOMIP = 4,
|
||||
CLAMP_NOFILTER = 5,
|
||||
CLAMP_CAMTEX = 6,
|
||||
FTexture* layerTexture;
|
||||
int scaleFlags;
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// this is the material class for OpenGL.
|
||||
|
@ -28,108 +22,42 @@ enum
|
|||
|
||||
class FMaterial
|
||||
{
|
||||
TArray<FTexture*> mTextureLayers;
|
||||
private:
|
||||
TArray<MaterialLayerInfo> mTextureLayers; // the only layers allowed to scale are the brightmap and the glowmap.
|
||||
int mShaderIndex;
|
||||
|
||||
short mLeftOffset;
|
||||
short mTopOffset;
|
||||
short mWidth;
|
||||
short mHeight;
|
||||
short mRenderWidth;
|
||||
short mRenderHeight;
|
||||
bool mExpanded;
|
||||
bool mTrimResult;
|
||||
uint16_t trim[4];
|
||||
|
||||
float mSpriteU[2], mSpriteV[2];
|
||||
FloatRect mSpriteRect;
|
||||
|
||||
bool TrimBorders(uint16_t *rect);
|
||||
int mLayerFlags = 0;
|
||||
int mScaleFlags;
|
||||
|
||||
public:
|
||||
FTexture *tex;
|
||||
FTexture *sourcetex; // in case of redirection this is different from tex.
|
||||
|
||||
FMaterial(FTexture *tex, bool forceexpand);
|
||||
~FMaterial();
|
||||
void SetSpriteRect();
|
||||
FGameTexture *sourcetex; // the owning texture.
|
||||
|
||||
FMaterial(FGameTexture *tex, int scaleflags);
|
||||
virtual ~FMaterial();
|
||||
int GetLayerFlags() const { return mLayerFlags; }
|
||||
int GetShaderIndex() const { return mShaderIndex; }
|
||||
void AddTextureLayer(FTexture *tex)
|
||||
int GetScaleFlags() const { return mScaleFlags; }
|
||||
virtual void DeleteDescriptors() { }
|
||||
|
||||
FGameTexture* Source() const
|
||||
{
|
||||
ValidateTexture(tex, false);
|
||||
mTextureLayers.Push(tex);
|
||||
}
|
||||
bool isMasked() const
|
||||
{
|
||||
return sourcetex->bMasked;
|
||||
}
|
||||
bool isExpanded() const
|
||||
{
|
||||
return mExpanded;
|
||||
return sourcetex;
|
||||
}
|
||||
|
||||
int GetLayers() const
|
||||
void AddTextureLayer(FTexture *tex, bool allowscale)
|
||||
{
|
||||
return mTextureLayers.Size() + 1;
|
||||
}
|
||||
|
||||
bool hasCanvas()
|
||||
{
|
||||
return tex->isHardwareCanvas();
|
||||
mTextureLayers.Push({ tex, allowscale });
|
||||
}
|
||||
|
||||
IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr);
|
||||
|
||||
// Patch drawing utilities
|
||||
|
||||
void GetSpriteRect(FloatRect * r) const
|
||||
int NumLayers() const
|
||||
{
|
||||
*r = mSpriteRect;
|
||||
return mTextureLayers.Size();
|
||||
}
|
||||
|
||||
// This is scaled size in integer units as needed by walls and flats
|
||||
int TextureHeight() const { return mRenderHeight; }
|
||||
int TextureWidth() const { return mRenderWidth; }
|
||||
|
||||
int GetAreas(FloatRect **pAreas) const;
|
||||
|
||||
int GetWidth() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
int GetHeight() const
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
int GetLeftOffset() const
|
||||
{
|
||||
return mLeftOffset;
|
||||
}
|
||||
|
||||
int GetTopOffset() const
|
||||
{
|
||||
return mTopOffset;
|
||||
}
|
||||
|
||||
// Get right/bottom UV coordinates for patch drawing
|
||||
float GetUL() const { return 0; }
|
||||
float GetVT() const { return 0; }
|
||||
float GetUR() const { return 1; }
|
||||
float GetVB() const { return 1; }
|
||||
float GetU(float upix) const { return upix/(float)mWidth; }
|
||||
float GetV(float vpix) const { return vpix/(float)mHeight; }
|
||||
|
||||
float GetSpriteUL() const { return mSpriteU[0]; }
|
||||
float GetSpriteVT() const { return mSpriteV[0]; }
|
||||
float GetSpriteUR() const { return mSpriteU[1]; }
|
||||
float GetSpriteVB() const { return mSpriteV[1]; }
|
||||
IHardwareTexture *GetLayer(int i, int translation, MaterialLayerInfo **pLayer = nullptr) const;
|
||||
|
||||
|
||||
static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true);
|
||||
static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true);
|
||||
const TArray<FTexture*> &GetLayerArray() const
|
||||
static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true);
|
||||
const TArray<MaterialLayerInfo> &GetLayerArray() const
|
||||
{
|
||||
return mTextureLayers;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
@ -20,6 +29,7 @@ private:
|
|||
{
|
||||
IHardwareTexture *hwTexture = nullptr;
|
||||
int translation = 0;
|
||||
bool precacheMarker; // This is used to check whether a texture has been hit by the precacher, so that the cleanup code can delete the unneeded ones.
|
||||
|
||||
void Delete()
|
||||
{
|
||||
|
@ -27,23 +37,28 @@ private:
|
|||
hwTexture = nullptr;
|
||||
}
|
||||
|
||||
void DeleteDescriptors()
|
||||
{
|
||||
if (hwTexture) hwTexture->DeleteDescriptors();
|
||||
}
|
||||
|
||||
~TranslatedTexture()
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
void MarkForPrecache(bool on)
|
||||
{
|
||||
precacheMarker = on;
|
||||
}
|
||||
|
||||
bool isMarkedForPreache() const
|
||||
{
|
||||
return precacheMarker;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
TranslatedTexture hwDefTex[2];
|
||||
TranslatedTexture hwDefTex[4];
|
||||
TArray<TranslatedTexture> hwTex_Translated;
|
||||
|
||||
TranslatedTexture * GetTexID(int translation, bool expanded)
|
||||
TranslatedTexture * GetTexID(int translation, int scaleflags)
|
||||
{
|
||||
// Allow negative indices to pass through unchanged.
|
||||
// This is needed for allowing the client to allocate slots that aren't matched to a palette, e.g. Build's indexed variants.
|
||||
|
@ -54,12 +69,12 @@ private:
|
|||
}
|
||||
else translation &= ~0x7fffffff;
|
||||
|
||||
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)
|
||||
|
@ -78,32 +93,22 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
|
||||
void Clean(bool cleannormal, bool cleanexpanded)
|
||||
void Clean()
|
||||
{
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -111,26 +116,44 @@ public:
|
|||
//===========================================================================
|
||||
//
|
||||
// Deletes all allocated resources and considers translations
|
||||
// This will only be called for sprites
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CleanUnused(SpriteHits &usedtranslations, bool expanded)
|
||||
void CleanUnused()
|
||||
{
|
||||
if (usedtranslations.CheckKey(0) == nullptr)
|
||||
for (auto& tt : hwDefTex)
|
||||
{
|
||||
hwDefTex[expanded].Delete();
|
||||
if (!tt.isMarkedForPreache()) tt.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)
|
||||
auto& tt = hwTex_Translated[i];
|
||||
if (!tt.isMarkedForPreache())
|
||||
{
|
||||
hwTex_Translated.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UnmarkAll()
|
||||
{
|
||||
for (auto& tt : hwDefTex)
|
||||
{
|
||||
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
||||
}
|
||||
for (auto& tt : hwTex_Translated)
|
||||
{
|
||||
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkForPrecache(int translation, int scaleflags)
|
||||
{
|
||||
auto tt = GetTexID(translation, scaleflags);
|
||||
tt->MarkForPrecache(true);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Iterate(T callback)
|
||||
{
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "cmdlib.h"
|
||||
#include "palettecontainer.h"
|
||||
|
||||
FMemArena FImageSource::ImageArena(32768);
|
||||
FMemArena ImageArena(32768);
|
||||
TArray<FImageSource *>FImageSource::ImageForLump;
|
||||
int FImageSource::NextID;
|
||||
static PrecacheInfo precacheInfo;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
class FImageSource;
|
||||
using PrecacheInfo = TMap<int, std::pair<int, int>>;
|
||||
extern FMemArena ImageArena;
|
||||
|
||||
// Doom patch format header
|
||||
struct patch_t
|
||||
|
@ -38,7 +39,6 @@ class FImageSource
|
|||
friend class FBrightmapTexture;
|
||||
protected:
|
||||
|
||||
static FMemArena ImageArena;
|
||||
static TArray<FImageSource *>ImageForLump;
|
||||
static int NextID;
|
||||
|
||||
|
@ -57,6 +57,8 @@ protected:
|
|||
|
||||
|
||||
public:
|
||||
virtual bool SupportRemap0() { return false; } // Unfortunate hackery that's needed for Hexen's skies. Only the image can know about the needed parameters
|
||||
virtual bool IsRawCompatible() { return true; } // Same thing for mid texture compatibility handling. Can only be determined by looking at the composition data which is private to the image.
|
||||
|
||||
void CopySize(FImageSource &other)
|
||||
{
|
||||
|
@ -169,4 +171,4 @@ protected:
|
|||
|
||||
class FTexture;
|
||||
|
||||
FTexture* CreateImageTexture(FImageSource* img, const char *name = nullptr) noexcept;
|
||||
FTexture* CreateImageTexture(FImageSource* img) noexcept;
|
||||
|
|
|
@ -47,25 +47,25 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FImageTexture::FImageTexture(FImageSource* img, const char* name) noexcept
|
||||
: FTexture(name, img ? img->LumpNum() : 0)
|
||||
FImageTexture::FImageTexture(FImageSource *img) noexcept
|
||||
: FTexture(img? img->LumpNum() : 0)
|
||||
{
|
||||
mImage = img;
|
||||
if (img != nullptr)
|
||||
{
|
||||
if (name == nullptr) fileSystem.GetFileShortName(Name, img->LumpNum());
|
||||
Width = img->GetWidth();
|
||||
Height = img->GetHeight();
|
||||
|
||||
auto offsets = img->GetOffsets();
|
||||
_LeftOffset[1] = _LeftOffset[0] = offsets.first;
|
||||
_TopOffset[1] = _TopOffset[0] = offsets.second;
|
||||
|
||||
bMasked = img->bMasked;
|
||||
bTranslucent = img->bTranslucent;
|
||||
SetFromImage();
|
||||
}
|
||||
}
|
||||
|
||||
void FImageTexture::SetFromImage()
|
||||
{
|
||||
auto img = mImage;
|
||||
Width = img->GetWidth();
|
||||
Height = img->GetHeight();
|
||||
|
||||
Masked = img->bMasked;
|
||||
bTranslucent = img->bTranslucent;
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -108,8 +108,8 @@ bool FImageTexture::DetermineTranslucency()
|
|||
}
|
||||
|
||||
|
||||
FTexture* CreateImageTexture(FImageSource* img, const char* name) noexcept
|
||||
FTexture* CreateImageTexture(FImageSource* img) noexcept
|
||||
{
|
||||
return new FImageTexture(img, name);
|
||||
return new FImageTexture(img);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,8 +119,8 @@ bool M_ReadIDAT (FileReader &file, uint8_t *buffer, int width, int height, int p
|
|||
uint8_t bitdepth, uint8_t colortype, uint8_t interlace, unsigned int idatlen);
|
||||
|
||||
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
|
||||
FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename);
|
||||
FGameTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Data structures for the TEXTUREx lumps
|
||||
|
@ -85,7 +84,7 @@ struct mappatch_t
|
|||
struct maptexture_t
|
||||
{
|
||||
uint8_t name[8];
|
||||
uint16_t Flags; // [RH] Was unused
|
||||
uint16_t Flags; // [RH] Was unused
|
||||
uint8_t ScaleX; // [RH] Scaling (8 is normal)
|
||||
uint8_t ScaleY; // [RH] Same as above
|
||||
int16_t width;
|
||||
|
@ -113,7 +112,7 @@ struct strifemappatch_t
|
|||
struct strifemaptexture_t
|
||||
{
|
||||
uint8_t name[8];
|
||||
uint16_t Flags; // [RH] Was unused
|
||||
uint16_t Flags; // [RH] Was unused
|
||||
uint8_t ScaleX; // [RH] Scaling (8 is normal)
|
||||
uint8_t ScaleY; // [RH] Same as above
|
||||
int16_t width;
|
||||
|
@ -137,25 +136,23 @@ struct FPatchLookup
|
|||
|
||||
void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype)
|
||||
{
|
||||
FImageTexture *tex = new FImageTexture(nullptr, buildinfo.Name);
|
||||
tex->SetUseType(usetype);
|
||||
tex->bMultiPatch = true;
|
||||
tex->Width = buildinfo.Width;
|
||||
tex->Height = buildinfo.Height;
|
||||
tex->_LeftOffset[0] = buildinfo.LeftOffset[0];
|
||||
tex->_LeftOffset[1] = buildinfo.LeftOffset[1];
|
||||
tex->_TopOffset[0] = buildinfo.TopOffset[0];
|
||||
tex->_TopOffset[1] = buildinfo.TopOffset[1];
|
||||
tex->Scale = buildinfo.Scale;
|
||||
tex->bMasked = true; // we do not really know yet.
|
||||
tex->bTranslucent = -1;
|
||||
tex->bWorldPanning = buildinfo.bWorldPanning;
|
||||
tex->bNoDecals = buildinfo.bNoDecals;
|
||||
tex->SourceLump = buildinfo.DefinitionLump;
|
||||
buildinfo.tex = tex;
|
||||
TexMan.AddTexture(tex);
|
||||
buildinfo.texture = new FGameTexture(nullptr, buildinfo.Name);
|
||||
buildinfo.texture->SetUseType(usetype);
|
||||
TexMan.AddGameTexture(buildinfo.texture);
|
||||
}
|
||||
|
||||
void FMultipatchTextureBuilder::AddImageToTexture(FImageTexture *tex, BuildInfo& buildinfo)
|
||||
{
|
||||
buildinfo.texture->Setup(tex);
|
||||
buildinfo.texture->SetOffsets(0, buildinfo.LeftOffset[0], buildinfo.TopOffset[0]);
|
||||
buildinfo.texture->SetOffsets(1, buildinfo.LeftOffset[1], buildinfo.TopOffset[1]);
|
||||
buildinfo.texture->SetScale((float)buildinfo.Scale.X, (float)buildinfo.Scale.X);
|
||||
buildinfo.texture->SetWorldPanning(buildinfo.bWorldPanning);
|
||||
buildinfo.texture->SetNoDecals(buildinfo.bNoDecals);
|
||||
calcShouldUpscale(buildinfo.texture); // calculate this once at insertion
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// The reader for TEXTUREx
|
||||
|
@ -238,7 +235,7 @@ void FMultipatchTextureBuilder::BuildTexture(const void *texdef, FPatchLookup *p
|
|||
}
|
||||
buildinfo.Parts[i].OriginX = LittleShort(mpatch.d->originx);
|
||||
buildinfo.Parts[i].OriginY = LittleShort(mpatch.d->originy);
|
||||
buildinfo.Parts[i].Image = nullptr;
|
||||
buildinfo.Parts[i].TexImage = nullptr;
|
||||
buildinfo.Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name;
|
||||
buildinfo.Inits[i].UseType = ETextureType::WallPatch;
|
||||
if (strife)
|
||||
|
@ -356,7 +353,7 @@ void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsi
|
|||
// It still needs to be created in case someone uses it by name.
|
||||
offset = LittleLong(directory[1]);
|
||||
const maptexture_t *tex = (const maptexture_t *)((const uint8_t *)maptex + offset);
|
||||
FTexture *tex0 = TexMan.ByIndex(0);
|
||||
auto tex0 = TexMan.GameByIndex(0);
|
||||
tex0->SetSize(SAFESHORT(tex->width), SAFESHORT(tex->height));
|
||||
}
|
||||
|
||||
|
@ -373,7 +370,7 @@ void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsi
|
|||
int j;
|
||||
for (j = (int)TexMan.NumTextures() - 1; j >= firstdup; --j)
|
||||
{
|
||||
if (strnicmp(TexMan.ByIndex(j)->GetName(), (const char *)maptex + offset, 8) == 0)
|
||||
if (strnicmp(TexMan.GameByIndex(j)->GetName(), (const char *)maptex + offset, 8) == 0)
|
||||
break;
|
||||
}
|
||||
if (j + 1 == firstdup)
|
||||
|
@ -420,7 +417,7 @@ void FMultipatchTextureBuilder::AddTexturesLumps(int lump1, int lump2, int patch
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPart & part, TexInit &init)
|
||||
void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPartBuild & part, TexInit &init)
|
||||
{
|
||||
FString patchname;
|
||||
int Mirror = 0;
|
||||
|
@ -672,7 +669,7 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
|||
}
|
||||
else if (sc.Compare("Patch"))
|
||||
{
|
||||
TexPart part;
|
||||
TexPartBuild part;
|
||||
TexInit init;
|
||||
ParsePatch(sc, buildinfo, part, init);
|
||||
if (init.TexName.IsNotEmpty())
|
||||
|
@ -684,12 +681,12 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
|||
init.sc = sc;
|
||||
buildinfo.Inits.Push(init);
|
||||
}
|
||||
part.Image = nullptr;
|
||||
part.TexImage = nullptr;
|
||||
part.Translation = nullptr;
|
||||
}
|
||||
else if (sc.Compare("Sprite"))
|
||||
{
|
||||
TexPart part;
|
||||
TexPartBuild part;
|
||||
TexInit init;
|
||||
ParsePatch(sc, buildinfo, part, init);
|
||||
if (init.TexName.IsNotEmpty())
|
||||
|
@ -701,12 +698,12 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
|||
init.sc = sc;
|
||||
buildinfo.Inits.Push(init);
|
||||
}
|
||||
part.Image = nullptr;
|
||||
part.TexImage = nullptr;
|
||||
part.Translation = nullptr;
|
||||
}
|
||||
else if (sc.Compare("Graphic"))
|
||||
{
|
||||
TexPart part;
|
||||
TexPartBuild part;
|
||||
TexInit init;
|
||||
ParsePatch(sc, buildinfo, part, init);
|
||||
if (init.TexName.IsNotEmpty())
|
||||
|
@ -718,7 +715,7 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
|||
init.sc = sc;
|
||||
buildinfo.Inits.Push(init);
|
||||
}
|
||||
part.Image = nullptr;
|
||||
part.TexImage = nullptr;
|
||||
part.Translation = nullptr;
|
||||
}
|
||||
else if (sc.Compare("Offset"))
|
||||
|
@ -774,19 +771,23 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
|
|||
for (unsigned i = 0; i < buildinfo.Inits.Size(); i++)
|
||||
{
|
||||
FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType);
|
||||
if (texno == buildinfo.tex->id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself.
|
||||
if (texno == buildinfo.texture->GetID()) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself.
|
||||
{
|
||||
TArray<FTextureID> list;
|
||||
TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true);
|
||||
for (int i = list.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (list[i] != buildinfo.tex->id && !TexMan.GetTexture(list[i])->bMultiPatch)
|
||||
if (list[i] != buildinfo.texture->GetID())
|
||||
{
|
||||
texno = list[i];
|
||||
auto gtex = TexMan.GetGameTexture(list[i]);
|
||||
if (gtex && !dynamic_cast<FMultiPatchTexture*>(gtex->GetTexture()))
|
||||
{
|
||||
texno = list[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (texno == buildinfo.tex->id)
|
||||
if (texno == buildinfo.texture->GetID())
|
||||
{
|
||||
if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars());
|
||||
else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars());
|
||||
|
@ -809,18 +810,19 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
|
|||
}
|
||||
else
|
||||
{
|
||||
FTexture *tex = TexMan.GetTexture(texno);
|
||||
FGameTexture *tex = TexMan.GetGameTexture(texno);
|
||||
|
||||
if (tex != nullptr && tex->isValid())
|
||||
if (tex != nullptr && tex->isValid() && dynamic_cast<FImageTexture*>(tex->GetTexture()))
|
||||
{
|
||||
//We cannot set the image source yet. First all textures need to be resolved.
|
||||
buildinfo.Inits[i].Texture = tex;
|
||||
buildinfo.tex->bComplex |= tex->bComplex;
|
||||
buildinfo.bComplex |= tex->bComplex;
|
||||
buildinfo.Inits[i].Texture = static_cast<FImageTexture*>(tex->GetTexture());
|
||||
bool iscomplex = !!complex.CheckKey(tex);
|
||||
if (iscomplex) complex.Insert(buildinfo.texture, true);
|
||||
buildinfo.bComplex |= iscomplex;
|
||||
if (buildinfo.Inits[i].UseOffsets)
|
||||
{
|
||||
buildinfo.Parts[i].OriginX -= tex->GetLeftOffset(0);
|
||||
buildinfo.Parts[i].OriginY -= tex->GetTopOffset(0);
|
||||
buildinfo.Parts[i].OriginX -= tex->GetTexelLeftOffset(0);
|
||||
buildinfo.Parts[i].OriginY -= tex->GetTexelTopOffset(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -841,8 +843,6 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
|
|||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
checkForHacks(buildinfo);
|
||||
}
|
||||
|
||||
void FMultipatchTextureBuilder::ResolveAllPatches()
|
||||
|
@ -874,12 +874,12 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
|||
|
||||
for (unsigned j = 0; j < buildinfo.Inits.Size(); j++)
|
||||
{
|
||||
if (buildinfo.Parts[j].Image == nullptr)
|
||||
if (buildinfo.Parts[j].TexImage == nullptr)
|
||||
{
|
||||
auto image = buildinfo.Inits[j].Texture->GetImage();
|
||||
if (image != nullptr)
|
||||
auto image = buildinfo.Inits[j].Texture;
|
||||
if (image->GetImage() != nullptr)
|
||||
{
|
||||
buildinfo.Parts[j].Image = image;
|
||||
buildinfo.Parts[j].TexImage = image;
|
||||
donesomething = true;
|
||||
}
|
||||
else hasEmpty = true;
|
||||
|
@ -889,26 +889,28 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
|||
{
|
||||
// If this texture is just a wrapper around a single patch, we can simply
|
||||
// use that patch's image directly here.
|
||||
checkForHacks(buildinfo);
|
||||
|
||||
bool done = false;
|
||||
if (buildinfo.Parts.Size() == 1)
|
||||
{
|
||||
if (buildinfo.Parts[0].OriginX == 0 && buildinfo.Parts[0].OriginY == 0 &&
|
||||
buildinfo.Parts[0].Image->GetWidth() == buildinfo.Width &&
|
||||
buildinfo.Parts[0].Image->GetHeight() == buildinfo.Height &&
|
||||
buildinfo.Parts[0].TexImage->GetWidth() == buildinfo.Width &&
|
||||
buildinfo.Parts[0].TexImage->GetHeight() == buildinfo.Height &&
|
||||
buildinfo.Parts[0].Rotate == 0 &&
|
||||
!buildinfo.bComplex)
|
||||
{
|
||||
buildinfo.tex->SetImage(buildinfo.Parts[0].Image);
|
||||
AddImageToTexture(buildinfo.Parts[0].TexImage, buildinfo);
|
||||
buildinfo.texture->Setup(buildinfo.Parts[0].TexImage);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
{
|
||||
auto img = new FMultiPatchTexture(buildinfo.Width, buildinfo.Height, buildinfo.Parts, buildinfo.bComplex, buildinfo.textual);
|
||||
buildinfo.tex->SetImage(img);
|
||||
auto itex = new FImageTexture(img);
|
||||
AddImageToTexture(itex, buildinfo);
|
||||
}
|
||||
|
||||
BuiltTextures.Delete(i);
|
||||
donesomething = true;
|
||||
}
|
||||
|
@ -919,7 +921,7 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
|||
for (auto &b : BuiltTextures)
|
||||
{
|
||||
Printf("%s\n", b.Name.GetChars());
|
||||
b.tex->SetUseType(ETextureType::Null);
|
||||
b.texture->SetUseType(ETextureType::Null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -47,18 +47,15 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
FSkyBox::FSkyBox(const char *name)
|
||||
: FTexture(name)
|
||||
: FImageTexture(nullptr)
|
||||
{
|
||||
FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall);
|
||||
previous = nullptr;
|
||||
if (texid.isValid())
|
||||
{
|
||||
previous = TexMan.GetTexture(texid);
|
||||
CopySize(previous);
|
||||
previous = TexMan.GetGameTexture(texid);
|
||||
}
|
||||
else previous = nullptr;
|
||||
faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5] = nullptr;
|
||||
UseType = ETextureType::Override;
|
||||
bSkybox = true;
|
||||
fliptop = false;
|
||||
}
|
||||
|
||||
|
@ -68,29 +65,11 @@ FSkyBox::FSkyBox(const char *name)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TArray<uint8_t> FSkyBox::Get8BitPixels(bool alphatex)
|
||||
void FSkyBox::SetSize()
|
||||
{
|
||||
return previous->Get8BitPixels(alphatex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FBitmap FSkyBox::GetBgraBitmap(const PalEntry *p, int *trans)
|
||||
{
|
||||
return previous->GetBgraBitmap(p, trans);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FImageSource *FSkyBox::GetImage() const
|
||||
{
|
||||
return previous->GetImage();
|
||||
if (!previous && faces[0]) previous = faces[0];
|
||||
if (previous && previous->GetTexture()->GetImage())
|
||||
{
|
||||
SetImage(previous->GetTexture()->GetImage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "textures.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// This is not a real texture but will be added to the texture manager
|
||||
// so that it can be handled like any other sky.
|
||||
// Todo: Get rid of this
|
||||
// The faces can easily be stored in the material layer array
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class FSkyBox : public FTexture
|
||||
class FSkyBox : public FImageTexture
|
||||
{
|
||||
public:
|
||||
|
||||
FTexture *previous;
|
||||
FTexture * faces[6];
|
||||
FGameTexture* previous;
|
||||
FGameTexture* faces[6]; // the faces need to be full materials as they can have all supported effects.
|
||||
bool fliptop;
|
||||
|
||||
FSkyBox(const char *name);
|
||||
TArray<uint8_t> Get8BitPixels(bool alphatex);
|
||||
FBitmap GetBgraBitmap(const PalEntry *, int *trans) override;
|
||||
FImageSource *GetImage() const override;
|
||||
|
||||
|
||||
void SetSize()
|
||||
{
|
||||
if (!previous && faces[0]) previous = faces[0];
|
||||
if (previous)
|
||||
{
|
||||
CopySize(previous);
|
||||
}
|
||||
}
|
||||
FSkyBox(const char* name);
|
||||
void SetSize();
|
||||
|
||||
bool Is3Face() const
|
||||
{
|
||||
|
@ -40,4 +29,14 @@ public:
|
|||
{
|
||||
return fliptop;
|
||||
}
|
||||
|
||||
FGameTexture* GetSkyFace(int num) const
|
||||
{
|
||||
return faces[num];
|
||||
}
|
||||
|
||||
bool GetSkyFlip() const
|
||||
{
|
||||
return fliptop;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -47,123 +47,24 @@
|
|||
#include "image.h"
|
||||
#include "formats/multipatchtexture.h"
|
||||
#include "texturemanager.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
// Wrappers to keep the definitions of these classes out of here.
|
||||
void DeleteMaterial(FMaterial* mat);
|
||||
void DeleteSoftwareTexture(FSoftwareTexture* swtex);
|
||||
IHardwareTexture* CreateHardwareTexture();
|
||||
|
||||
|
||||
FTexture* CreateBrightmapTexture(FImageSource*);
|
||||
|
||||
// Make sprite offset adjustment user-configurable per renderer.
|
||||
int r_spriteadjustSW, r_spriteadjustHW;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
// Examines the lump contents to decide what type of texture to create,
|
||||
// and creates the texture.
|
||||
FTexture* FTexture::CreateTexture(const char* name, int lumpnum, ETextureType usetype)
|
||||
{
|
||||
if (lumpnum == -1) return nullptr;
|
||||
|
||||
auto image = FImageSource::GetImage(lumpnum, usetype == ETextureType::Flat);
|
||||
if (image != nullptr)
|
||||
{
|
||||
FTexture* tex = new FImageTexture(image);
|
||||
if (tex != nullptr)
|
||||
{
|
||||
tex->UseType = usetype;
|
||||
if (usetype == ETextureType::Flat)
|
||||
{
|
||||
int w = tex->GetTexelWidth();
|
||||
int h = tex->GetTexelHeight();
|
||||
|
||||
// Auto-scale flats with dimensions 128x128 and 256x256.
|
||||
// In hindsight, a bad idea, but RandomLag made it sound better than it really is.
|
||||
// Now we're stuck with this stupid behaviour.
|
||||
if (w == 128 && h == 128)
|
||||
{
|
||||
tex->Scale.X = tex->Scale.Y = 2;
|
||||
tex->bWorldPanning = true;
|
||||
}
|
||||
else if (w == 256 && h == 256)
|
||||
{
|
||||
tex->Scale.X = tex->Scale.Y = 4;
|
||||
tex->bWorldPanning = true;
|
||||
}
|
||||
}
|
||||
tex->Name = name;
|
||||
tex->Name.ToUpper();
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture::FTexture(const char* name, int lumpnum)
|
||||
:
|
||||
Scale(1, 1), SourceLump(lumpnum),
|
||||
UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
|
||||
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bFullNameTexture(false),
|
||||
Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0)
|
||||
FTexture::FTexture (int lumpnum)
|
||||
: SourceLump(lumpnum), bHasCanvas(false)
|
||||
{
|
||||
bBrightmapChecked = false;
|
||||
bGlowing = false;
|
||||
bAutoGlowing = false;
|
||||
bFullbright = false;
|
||||
bDisableFullbright = false;
|
||||
bSkybox = false;
|
||||
bNoCompress = false;
|
||||
bNoExpand = false;
|
||||
bTranslucent = -1;
|
||||
|
||||
|
||||
_LeftOffset[0] = _LeftOffset[1] = _TopOffset[0] = _TopOffset[1] = 0;
|
||||
id.SetInvalid();
|
||||
if (name != NULL)
|
||||
{
|
||||
Name = name;
|
||||
Name.ToUpper();
|
||||
}
|
||||
else if (lumpnum < 0)
|
||||
{
|
||||
Name = FString();
|
||||
}
|
||||
else
|
||||
{
|
||||
fileSystem.GetFileShortName(Name, lumpnum);
|
||||
}
|
||||
}
|
||||
|
||||
FTexture::~FTexture()
|
||||
{
|
||||
FTexture* link = fileSystem.GetLinkedTexture(SourceLump);
|
||||
if (link == this) fileSystem.SetLinkedTexture(SourceLump, nullptr);
|
||||
if (areas != nullptr) delete[] areas;
|
||||
areas = nullptr;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (Material[i] != nullptr) DeleteMaterial(Material[i]);
|
||||
Material[i] = nullptr;
|
||||
}
|
||||
if (SoftwareTexture != nullptr)
|
||||
{
|
||||
DeleteSoftwareTexture(SoftwareTexture);
|
||||
SoftwareTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -182,111 +83,6 @@ FBitmap FTexture::GetBgraBitmap(const PalEntry* remap, int* ptrans)
|
|||
return bmp;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture* FTexture::GetRawTexture()
|
||||
{
|
||||
if (OffsetLess) return OffsetLess;
|
||||
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
|
||||
auto image = static_cast<FMultiPatchTexture*>(GetImage());
|
||||
if (bMultiPatch != 1 || UseType != ETextureType::Wall || Scale.X != 1 || Scale.Y != 1 || bWorldPanning || image == nullptr || image->NumParts != 1 || _TopOffset[0] == 0)
|
||||
{
|
||||
OffsetLess = this;
|
||||
return this;
|
||||
}
|
||||
// Set up a new texture that directly references the underlying patch.
|
||||
// From here we cannot retrieve the original texture made for it, so just create a new one.
|
||||
FImageSource* source = image->Parts[0].Image;
|
||||
|
||||
// Size must match for this to work as intended
|
||||
if (source->GetWidth() != Width || source->GetHeight() != Height)
|
||||
{
|
||||
OffsetLess = this;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
OffsetLess = new FImageTexture(source, "");
|
||||
TexMan.AddTexture(OffsetLess);
|
||||
return OffsetLess;
|
||||
}
|
||||
|
||||
void FTexture::SetDisplaySize(int fitwidth, int fitheight)
|
||||
{
|
||||
Scale.X = double(Width) / fitwidth;
|
||||
Scale.Y = double(Height) / fitheight;
|
||||
// compensate for roundoff errors
|
||||
if (int(Scale.X * fitwidth) != Width) Scale.X += (1 / 65536.);
|
||||
if (int(Scale.Y * fitheight) != Height) Scale.Y += (1 / 65536.);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Gets the average color of a texture for use as a sky cap color
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
PalEntry FTexture::averageColor(const uint32_t* data, int size, int maxout)
|
||||
{
|
||||
int i;
|
||||
unsigned int r, g, b;
|
||||
|
||||
// First clear them.
|
||||
r = g = b = 0;
|
||||
if (size == 0)
|
||||
{
|
||||
return PalEntry(255, 255, 255);
|
||||
}
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
b += BPART(data[i]);
|
||||
g += GPART(data[i]);
|
||||
r += RPART(data[i]);
|
||||
}
|
||||
|
||||
r = r / size;
|
||||
g = g / size;
|
||||
b = b / size;
|
||||
|
||||
int maxv = MAX(MAX(r, g), b);
|
||||
|
||||
if (maxv && maxout)
|
||||
{
|
||||
r = ::Scale(r, maxout, maxv);
|
||||
g = ::Scale(g, maxout, maxv);
|
||||
b = ::Scale(b, maxout, maxv);
|
||||
}
|
||||
return PalEntry(255, r, g, b);
|
||||
}
|
||||
|
||||
PalEntry FTexture::GetSkyCapColor(bool bottom)
|
||||
{
|
||||
if (!bSWSkyColorDone)
|
||||
{
|
||||
bSWSkyColorDone = true;
|
||||
|
||||
FBitmap bitmap = GetBgraBitmap(nullptr);
|
||||
int w = bitmap.GetWidth();
|
||||
int h = bitmap.GetHeight();
|
||||
|
||||
const uint32_t* buffer = (const uint32_t*)bitmap.GetPixels();
|
||||
if (buffer)
|
||||
{
|
||||
CeilingSkyColor = averageColor((uint32_t*)buffer, w * MIN(30, h), 0);
|
||||
if (h > 30)
|
||||
{
|
||||
FloorSkyColor = averageColor(((uint32_t*)buffer) + (h - 30) * w, w * 30, 0);
|
||||
}
|
||||
else FloorSkyColor = CeilingSkyColor;
|
||||
}
|
||||
}
|
||||
return bottom ? FloorSkyColor : CeilingSkyColor;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
//
|
||||
// CheckRealHeight
|
||||
|
@ -299,16 +95,13 @@ PalEntry FTexture::GetSkyCapColor(bool bottom)
|
|||
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);
|
||||
h = (h >> 1) + (h & 1);
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
@ -316,127 +109,6 @@ int FTexture::CheckRealHeight()
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Search auto paths for extra material textures
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTexture::AddAutoMaterials()
|
||||
{
|
||||
struct AutoTextureSearchPath
|
||||
{
|
||||
const char* path;
|
||||
FTexture* FTexture::* pointer;
|
||||
};
|
||||
|
||||
static AutoTextureSearchPath autosearchpaths[] =
|
||||
{
|
||||
{ "brightmaps/", &FTexture::Brightmap }, // For backwards compatibility, only for short names
|
||||
{ "materials/brightmaps/", &FTexture::Brightmap },
|
||||
{ "materials/normalmaps/", &FTexture::Normal },
|
||||
{ "materials/specular/", &FTexture::Specular },
|
||||
{ "materials/metallic/", &FTexture::Metallic },
|
||||
{ "materials/roughness/", &FTexture::Roughness },
|
||||
{ "materials/ao/", &FTexture::AmbientOcclusion }
|
||||
};
|
||||
|
||||
|
||||
int startindex = bFullNameTexture ? 1 : 0;
|
||||
FString searchname = Name;
|
||||
|
||||
if (bFullNameTexture)
|
||||
{
|
||||
auto dot = searchname.LastIndexOf('.');
|
||||
auto slash = searchname.LastIndexOf('/');
|
||||
if (dot > slash) searchname.Truncate(dot);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < countof(autosearchpaths); i++)
|
||||
{
|
||||
auto& layer = autosearchpaths[i];
|
||||
if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done.
|
||||
{
|
||||
FStringf lookup("%s%s%s", layer.path, bFullNameTexture ? "" : "auto/", searchname.GetChars());
|
||||
auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true);
|
||||
if (lump != -1)
|
||||
{
|
||||
auto bmtex = TexMan.FindTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny);
|
||||
if (bmtex != nullptr)
|
||||
{
|
||||
bmtex->bMasked = false;
|
||||
this->*(layer.pointer) = bmtex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Checks if the texture has a default brightmap and creates it if so
|
||||
//
|
||||
//===========================================================================
|
||||
void FTexture::CreateDefaultBrightmap()
|
||||
{
|
||||
if (!bBrightmapChecked)
|
||||
{
|
||||
// Check for brightmaps
|
||||
if (GetImage() && GetImage()->UseGamePalette() && GPalette.HasGlobalBrightmap &&
|
||||
UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar &&
|
||||
Brightmap == NULL && bWarped == 0)
|
||||
{
|
||||
// May have one - let's check when we use this texture
|
||||
auto texbuf = Get8BitPixels(false);
|
||||
const int white = ColorMatcher.Pick(255, 255, 255);
|
||||
|
||||
int size = GetTexelWidth() * GetTexelHeight();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (GPalette.GlobalBrightmap.Remap[texbuf[i]] == white)
|
||||
{
|
||||
// Create a brightmap
|
||||
DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", Name.GetChars());
|
||||
Brightmap = CreateBrightmapTexture(static_cast<FImageTexture*>(this)->GetImage());
|
||||
bBrightmapChecked = true;
|
||||
TexMan.AddTexture(Brightmap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No bright pixels found
|
||||
DPrintf(DMSG_SPAMMY, "No bright pixels found in texture '%s'\n", Name.GetChars());
|
||||
bBrightmapChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// does not have one so set the flag to 'done'
|
||||
bBrightmapChecked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Calculates glow color for a texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTexture::GetGlowColor(float* data)
|
||||
{
|
||||
if (bGlowing && GlowColor == 0)
|
||||
{
|
||||
auto buffer = GetBgraBitmap(nullptr);
|
||||
GlowColor = averageColor((uint32_t*)buffer.GetPixels(), buffer.GetWidth() * buffer.GetHeight(), 153);
|
||||
|
||||
// Black glow equals nothing so switch glowing off
|
||||
if (GlowColor == 0) bGlowing = false;
|
||||
}
|
||||
data[0] = GlowColor.r / 255.0f;
|
||||
data[1] = GlowColor.g / 255.0f;
|
||||
data[2] = GlowColor.b / 255.0f;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Finds gaps in the texture which can be skipped by the renderer
|
||||
|
@ -455,11 +127,10 @@ bool FTexture::FindHoles(const unsigned char* buffer, int w, int h)
|
|||
|
||||
// already done!
|
||||
if (areacount) return false;
|
||||
if (UseType == ETextureType::Flat) return false; // flats don't have transparent parts
|
||||
areacount = -1; //whatever happens next, it shouldn't be done twice!
|
||||
|
||||
// large textures are excluded for performance reasons
|
||||
if (h > 512) return false;
|
||||
// large textures and non-images are excluded for performance reasons
|
||||
if (h>512 || !GetImage()) return false;
|
||||
|
||||
startdraw = -1;
|
||||
lendraw = 0;
|
||||
|
@ -510,7 +181,7 @@ bool FTexture::FindHoles(const unsigned char* buffer, int w, int h)
|
|||
|
||||
if (gapc > 0)
|
||||
{
|
||||
FloatRect* rcs = new FloatRect[gapc];
|
||||
FloatRect* rcs = (FloatRect*)ImageArena.Alloc(gapc * sizeof(FloatRect)); // allocate this on the image arena
|
||||
|
||||
for (x = 0; x < gapc; x++)
|
||||
{
|
||||
|
@ -635,10 +306,10 @@ bool FTexture::SmoothEdges(unsigned char* buffer, int w, int h)
|
|||
|
||||
bool FTexture::ProcessData(unsigned char* buffer, int w, int h, bool ispatch)
|
||||
{
|
||||
if (bMasked)
|
||||
if (Masked)
|
||||
{
|
||||
bMasked = SmoothEdges(buffer, w, h);
|
||||
if (bMasked && !ispatch) FindHoles(buffer, w, h);
|
||||
Masked = SmoothEdges(buffer, w, h);
|
||||
if (Masked && !ispatch) FindHoles(buffer, w, h);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -660,8 +331,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)
|
||||
{
|
||||
|
@ -669,6 +340,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
|||
memset(buffer, 0, W * (H + 1) * 4);
|
||||
|
||||
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
||||
if (remap) translation = remap->Index;
|
||||
FBitmap bmp(buffer, W * 4, W, H);
|
||||
|
||||
int trans;
|
||||
|
@ -705,10 +377,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
|||
// 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)
|
||||
{
|
||||
#pragma message("Activate me")
|
||||
#if 0
|
||||
CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
||||
#endif
|
||||
if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
||||
|
||||
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
|
||||
}
|
||||
|
||||
|
@ -723,15 +393,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
|||
|
||||
bool FTexture::DetermineTranslucency()
|
||||
{
|
||||
if (!bHasCanvas)
|
||||
{
|
||||
// This will calculate all we need, so just discard the result.
|
||||
CreateTexBuffer(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bTranslucent = 0;
|
||||
}
|
||||
return !!bTranslucent;
|
||||
}
|
||||
|
||||
|
@ -749,101 +412,114 @@ TArray<uint8_t> FTexture::Get8BitPixels(bool alphatex)
|
|||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Coordinate helper.
|
||||
// The only reason this is even needed is that many years ago someone
|
||||
// was convinced that having per-texel panning on walls was a good idea.
|
||||
// If it wasn't for this relatively useless feature the entire positioning
|
||||
// code for wall textures could be a lot simpler.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
// Finds empty space around the texture.
|
||||
// Used for sprites that got placed into a huge empty frame.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::RowOffset(float rowoffset) const
|
||||
bool FTexture::TrimBorders(uint16_t* rect)
|
||||
{
|
||||
float scale = fabs(mScale.Y);
|
||||
if (scale == 1.f || mWorldPanning) return rowoffset;
|
||||
else return rowoffset / scale;
|
||||
|
||||
auto texbuffer = CreateTexBuffer(0);
|
||||
int w = texbuffer.mWidth;
|
||||
int h = texbuffer.mHeight;
|
||||
auto Buffer = texbuffer.mBuffer;
|
||||
|
||||
if (texbuffer.mBuffer == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (w != Width || h != Height)
|
||||
{
|
||||
// external Hires replacements cannot be trimmed.
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = w * h;
|
||||
if (size == 1)
|
||||
{
|
||||
// nothing to be done here.
|
||||
rect[0] = 0;
|
||||
rect[1] = 0;
|
||||
rect[2] = 1;
|
||||
rect[3] = 1;
|
||||
return true;
|
||||
}
|
||||
int first, last;
|
||||
|
||||
for (first = 0; first < size; first++)
|
||||
{
|
||||
if (Buffer[first * 4 + 3] != 0) break;
|
||||
}
|
||||
if (first >= size)
|
||||
{
|
||||
// completely empty
|
||||
rect[0] = 0;
|
||||
rect[1] = 0;
|
||||
rect[2] = 1;
|
||||
rect[3] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (last = size - 1; last >= first; last--)
|
||||
{
|
||||
if (Buffer[last * 4 + 3] != 0) break;
|
||||
}
|
||||
|
||||
rect[1] = first / w;
|
||||
rect[3] = 1 + last / w - rect[1];
|
||||
|
||||
rect[0] = 0;
|
||||
rect[2] = w;
|
||||
|
||||
unsigned char* bufferoff = Buffer + (rect[1] * w * 4);
|
||||
h = rect[3];
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
if (bufferoff[(x + y * w) * 4 + 3] != 0) goto outl;
|
||||
}
|
||||
rect[0]++;
|
||||
}
|
||||
outl:
|
||||
rect[2] -= rect[0];
|
||||
|
||||
for (int x = w - 1; rect[2] > 1; x--)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
if (bufferoff[(x + y * w) * 4 + 3] != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rect[2]--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
// Create a hardware texture for this texture image.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::TextureOffset(float textureoffset) const
|
||||
IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags)
|
||||
{
|
||||
float scale = fabs(mScale.X);
|
||||
if (scale == 1.f || mWorldPanning) return textureoffset;
|
||||
else return textureoffset / scale;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Returns the size for which texture offset coordinates are used.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float FTexCoordInfo::TextureAdjustWidth() const
|
||||
{
|
||||
if (mWorldPanning)
|
||||
//if (UseType != ETextureType::Null)
|
||||
{
|
||||
float tscale = fabs(mTempScale.X);
|
||||
if (tscale == 1.f) return (float)mRenderWidth;
|
||||
else return mWidth / fabs(tscale);
|
||||
}
|
||||
else return (float)mWidth;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Retrieve texture coordinate info for per-wall scaling
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTexCoordInfo::GetFromTexture(FTexture* tex, float x, float y, bool forceworldpanning)
|
||||
{
|
||||
if (x == 1.f)
|
||||
IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags);
|
||||
if (hwtex == nullptr)
|
||||
{
|
||||
mRenderWidth = tex->GetScaledWidth();
|
||||
mScale.X = (float)tex->Scale.X;
|
||||
mTempScale.X = 1.f;
|
||||
hwtex = CreateHardwareTexture();
|
||||
SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex);
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale_x = x * (float)tex->Scale.X;
|
||||
mRenderWidth = xs_CeilToInt(tex->GetTexelWidth() / scale_x);
|
||||
mScale.X = scale_x;
|
||||
mTempScale.X = x;
|
||||
return hwtex;
|
||||
}
|
||||
|
||||
if (y == 1.f)
|
||||
{
|
||||
mRenderHeight = tex->GetScaledHeight();
|
||||
mScale.Y = (float)tex->Scale.Y;
|
||||
mTempScale.Y = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale_y = y * (float)tex->Scale.Y;
|
||||
mRenderHeight = xs_CeilToInt(tex->GetTexelHeight() / scale_y);
|
||||
mScale.Y = scale_y;
|
||||
mTempScale.Y = y;
|
||||
}
|
||||
if (tex->bHasCanvas)
|
||||
{
|
||||
mScale.Y = -mScale.Y;
|
||||
mRenderHeight = -mRenderHeight;
|
||||
}
|
||||
mWorldPanning = tex->bWorldPanning || forceworldpanning;
|
||||
mWidth = tex->GetTexelWidth();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -858,8 +534,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits)
|
|||
Width = w;
|
||||
Height = h;
|
||||
Format = bits;
|
||||
UseType = ETextureType::SWCanvas;
|
||||
bNoCompress = true;
|
||||
//bNoCompress = true;
|
||||
auto hwtex = CreateHardwareTexture();
|
||||
// todo: Initialize here.
|
||||
SystemTextures.AddHardwareTexture(0, false, hwtex);
|
||||
|
|
|
@ -17,7 +17,7 @@ enum class ETextureType : uint8_t
|
|||
SkinGraphic,
|
||||
Null,
|
||||
FirstDefined,
|
||||
Canvas,
|
||||
Special,
|
||||
SWCanvas,
|
||||
};
|
||||
|
||||
|
|
|
@ -103,15 +103,14 @@ void FTextureManager::DeleteAll()
|
|||
//==========================================================================
|
||||
//
|
||||
// Flushes all hardware dependent data.
|
||||
// Thia must not, under any circumstances, delete the wipe textures, because
|
||||
// This must not, under any circumstances, delete the wipe textures, because
|
||||
// all CCMDs triggering a flush can be executed while a wipe is in progress
|
||||
//
|
||||
// This now also deletes the software textures because having the software
|
||||
// renderer use the texture scalers is a planned feature and that is the
|
||||
// renderer can also use the texture scalers and that is the
|
||||
// main reason to call this outside of the destruction code.
|
||||
//
|
||||
//==========================================================================
|
||||
void DeleteSoftwareTexture(FSoftwareTexture* swtex);
|
||||
|
||||
void FTextureManager::FlushAll()
|
||||
{
|
||||
|
@ -119,13 +118,33 @@ void FTextureManager::FlushAll()
|
|||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Textures[i].Texture->SystemTextures.Clean(true, true);
|
||||
DeleteSoftwareTexture(Textures[i].Texture->SoftwareTexture);
|
||||
Textures[i].Texture->SoftwareTexture = nullptr;
|
||||
Textures[i].Texture->CleanHardwareData();
|
||||
delete Textures[i].Texture->GetSoftwareTexture();
|
||||
Textures[i].Texture->SetSoftwareTexture(nullptr);
|
||||
calcShouldUpscale(Textures[i].Texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Examines the lump contents to decide what type of texture to create,
|
||||
// and creates the texture.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static FTexture* CreateTextureFromLump(int lumpnum, bool allowflats = false)
|
||||
{
|
||||
if (lumpnum == -1) return nullptr;
|
||||
|
||||
auto image = FImageSource::GetImage(lumpnum, allowflats);
|
||||
if (image != nullptr)
|
||||
{
|
||||
return new FImageTexture(image);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FTextureManager :: CheckForTexture
|
||||
|
@ -152,38 +171,39 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
|||
|
||||
for(i = HashFirst[MakeKey(name) % HASH_SIZE]; i != HASH_END; i = Textures[i].HashNext)
|
||||
{
|
||||
const FTexture *tex = Textures[i].Texture;
|
||||
auto tex = Textures[i].Texture;
|
||||
|
||||
|
||||
if (stricmp (tex->Name, name) == 0 )
|
||||
if (stricmp (tex->GetName(), name) == 0 )
|
||||
{
|
||||
// If we look for short names, we must ignore any long name texture.
|
||||
if ((flags & TEXMAN_ShortNameOnly) && tex->bFullNameTexture)
|
||||
if ((flags & TEXMAN_ShortNameOnly) && tex->isFullNameTexture())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto texUseType = tex->GetUseType();
|
||||
// The name matches, so check the texture type
|
||||
if (usetype == ETextureType::Any)
|
||||
{
|
||||
// All NULL textures should actually return 0
|
||||
if (tex->UseType == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0;
|
||||
if (tex->UseType == ETextureType::SkinGraphic && !(flags & TEXMAN_AllowSkins)) return 0;
|
||||
return FTextureID(tex->UseType==ETextureType::Null ? 0 : i);
|
||||
if (texUseType == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0;
|
||||
if (texUseType == ETextureType::SkinGraphic && !(flags & TEXMAN_AllowSkins)) return 0;
|
||||
return FTextureID(texUseType==ETextureType::Null ? 0 : i);
|
||||
}
|
||||
else if ((flags & TEXMAN_Overridable) && tex->UseType == ETextureType::Override)
|
||||
else if ((flags & TEXMAN_Overridable) && texUseType == ETextureType::Override)
|
||||
{
|
||||
return FTextureID(i);
|
||||
}
|
||||
else if (tex->UseType == usetype)
|
||||
else if (texUseType == usetype)
|
||||
{
|
||||
return FTextureID(i);
|
||||
}
|
||||
else if (tex->UseType == ETextureType::FirstDefined && usetype == ETextureType::Wall)
|
||||
else if (texUseType == ETextureType::FirstDefined && usetype == ETextureType::Wall)
|
||||
{
|
||||
if (!(flags & TEXMAN_ReturnFirst)) return FTextureID(0);
|
||||
else return FTextureID(i);
|
||||
}
|
||||
else if (tex->UseType == ETextureType::Null && usetype == ETextureType::Wall)
|
||||
else if (texUseType == ETextureType::Null && usetype == ETextureType::Wall)
|
||||
{
|
||||
// We found a NULL texture on a wall -> return 0
|
||||
return FTextureID(0);
|
||||
|
@ -192,12 +212,12 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
|||
{
|
||||
if (firsttype == ETextureType::Null ||
|
||||
(firsttype == ETextureType::MiscPatch &&
|
||||
tex->UseType != firsttype &&
|
||||
tex->UseType != ETextureType::Null)
|
||||
texUseType != firsttype &&
|
||||
texUseType != ETextureType::Null)
|
||||
)
|
||||
{
|
||||
firstfound = i;
|
||||
firsttype = tex->UseType;
|
||||
firsttype = texUseType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,20 +241,20 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
|||
// Any graphic being placed in the zip's root directory can not be found by this.
|
||||
if (strchr(name, '/'))
|
||||
{
|
||||
FTexture *const NO_TEXTURE = (FTexture*)-1;
|
||||
FGameTexture *const NO_TEXTURE = (FGameTexture*)-1;
|
||||
int lump = fileSystem.CheckNumForFullName(name);
|
||||
if (lump >= 0)
|
||||
{
|
||||
FTexture *tex = fileSystem.GetLinkedTexture(lump);
|
||||
FGameTexture *tex = fileSystem.GetLinkedTexture(lump);
|
||||
if (tex == NO_TEXTURE) return FTextureID(-1);
|
||||
if (tex != NULL) return tex->id;
|
||||
if (tex != NULL) return tex->GetID();
|
||||
if (flags & TEXMAN_DontCreate) return FTextureID(-1); // we only want to check, there's no need to create a texture if we don't have one yet.
|
||||
tex = FTexture::CreateTexture("", lump, ETextureType::Override);
|
||||
tex = MakeGameTexture(CreateTextureFromLump(lump), nullptr, ETextureType::Override);
|
||||
if (tex != NULL)
|
||||
{
|
||||
tex->AddAutoMaterials();
|
||||
fileSystem.SetLinkedTexture(lump, tex);
|
||||
return AddTexture(tex);
|
||||
return AddGameTexture(tex);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -273,12 +293,13 @@ int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list, b
|
|||
|
||||
while (i != HASH_END)
|
||||
{
|
||||
const FTexture *tex = Textures[i].Texture;
|
||||
auto tex = Textures[i].Texture;
|
||||
|
||||
if (stricmp (tex->Name, name) == 0)
|
||||
if (stricmp (tex->GetName(), name) == 0)
|
||||
{
|
||||
auto texUseType = tex->GetUseType();
|
||||
// NULL textures must be ignored.
|
||||
if (tex->UseType!=ETextureType::Null)
|
||||
if (texUseType!=ETextureType::Null)
|
||||
{
|
||||
unsigned int j = list.Size();
|
||||
if (!listall)
|
||||
|
@ -286,7 +307,7 @@ int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list, b
|
|||
for (j = 0; j < list.Size(); j++)
|
||||
{
|
||||
// Check for overriding definitions from newer WADs
|
||||
if (Textures[list[j].GetIndex()].Texture->UseType == tex->UseType) break;
|
||||
if (Textures[list[j].GetIndex()].Texture->GetUseType() == texUseType) break;
|
||||
}
|
||||
}
|
||||
if (j==list.Size()) list.Push(FTextureID(i));
|
||||
|
@ -331,10 +352,10 @@ FTextureID FTextureManager::GetTextureID (const char *name, ETextureType usetype
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *FTextureManager::FindTexture(const char *texname, ETextureType usetype, BITFIELD flags)
|
||||
FGameTexture *FTextureManager::FindGameTexture(const char *texname, ETextureType usetype, BITFIELD flags)
|
||||
{
|
||||
FTextureID texnum = CheckForTexture (texname, usetype, flags);
|
||||
return GetTexture(texnum.GetIndex());
|
||||
return GetGameTexture(texnum.GetIndex());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -362,7 +383,7 @@ bool FTextureManager::OkForLocalization(FTextureID texnum, const char *substitut
|
|||
if (locmode == 2) return false;
|
||||
|
||||
// Mode 3 must also reject substitutions for non-IWAD content.
|
||||
int file = fileSystem.GetFileContainer(Textures[texnum.GetIndex()].Texture->SourceLump);
|
||||
int file = fileSystem.GetFileContainer(Textures[texnum.GetIndex()].Texture->GetSourceLump());
|
||||
if (file > fileSystem.GetMaxIwadNum()) return true;
|
||||
|
||||
return false;
|
||||
|
@ -374,19 +395,23 @@ bool FTextureManager::OkForLocalization(FTextureID texnum, const char *substitut
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureID FTextureManager::AddTexture (FTexture *texture)
|
||||
FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohash)
|
||||
{
|
||||
int bucket;
|
||||
int hash;
|
||||
|
||||
if (texture == NULL) return FTextureID(-1);
|
||||
|
||||
// Later textures take precedence over earlier ones
|
||||
if (texture->GetTexture())
|
||||
{
|
||||
// Later textures take precedence over earlier ones
|
||||
calcShouldUpscale(texture); // calculate this once at insertion
|
||||
}
|
||||
|
||||
// Textures without name can't be looked for
|
||||
if (texture->Name[0] != '\0')
|
||||
if (addtohash && texture->GetName().IsNotEmpty())
|
||||
{
|
||||
bucket = int(MakeKey (texture->Name) % HASH_SIZE);
|
||||
bucket = int(MakeKey (texture->GetName()) % HASH_SIZE);
|
||||
hash = HashFirst[bucket];
|
||||
}
|
||||
else
|
||||
|
@ -395,11 +420,13 @@ FTextureID FTextureManager::AddTexture (FTexture *texture)
|
|||
hash = -1;
|
||||
}
|
||||
|
||||
TextureHash hasher = { texture, hash };
|
||||
TextureHash hasher = { texture, -1, -1, -1, hash };
|
||||
int trans = Textures.Push (hasher);
|
||||
Translation.Push (trans);
|
||||
if (bucket >= 0) HashFirst[bucket] = trans;
|
||||
return (texture->id = FTextureID(trans));
|
||||
auto id = FTextureID(trans);
|
||||
texture->SetID(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -416,9 +443,32 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype)
|
|||
{
|
||||
FString str;
|
||||
fileSystem.GetFileShortName(str, lumpnum);
|
||||
FTexture *out = FTexture::CreateTexture(str, lumpnum, usetype);
|
||||
auto out = MakeGameTexture(CreateTextureFromLump(lumpnum, usetype == ETextureType::Flat), str, usetype);
|
||||
|
||||
if (out != NULL) return AddTexture (out);
|
||||
if (out != NULL)
|
||||
{
|
||||
if (usetype == ETextureType::Flat)
|
||||
{
|
||||
int w = out->GetTexelWidth();
|
||||
int h = out->GetTexelHeight();
|
||||
|
||||
// Auto-scale flats with dimensions 128x128 and 256x256.
|
||||
// In hindsight, a bad idea, but RandomLag made it sound better than it really is.
|
||||
// Now we're stuck with this stupid behaviour.
|
||||
if (w == 128 && h == 128)
|
||||
{
|
||||
out->SetScale(2, 2);
|
||||
out->SetWorldPanning(true);
|
||||
}
|
||||
else if (w == 256 && h == 256)
|
||||
{
|
||||
out->SetScale(4, 4);
|
||||
out->SetWorldPanning(true);
|
||||
}
|
||||
}
|
||||
|
||||
return AddGameTexture(out);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE "Invalid data encountered for texture %s\n", fileSystem.GetFileFullPath(lumpnum).GetChars());
|
||||
|
@ -434,20 +484,20 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free)
|
||||
void FTextureManager::ReplaceTexture (FTextureID picnum, FGameTexture *newtexture, bool free)
|
||||
{
|
||||
int index = picnum.GetIndex();
|
||||
if (unsigned(index) >= Textures.Size())
|
||||
return;
|
||||
|
||||
FTexture *oldtexture = Textures[index].Texture;
|
||||
auto oldtexture = Textures[index].Texture;
|
||||
|
||||
newtexture->Name = oldtexture->Name;
|
||||
newtexture->UseType = oldtexture->UseType;
|
||||
newtexture->SetName(oldtexture->GetName());
|
||||
newtexture->SetUseType(oldtexture->GetUseType());
|
||||
Textures[index].Texture = newtexture;
|
||||
newtexture->id = oldtexture->id;
|
||||
oldtexture->Name = "";
|
||||
AddTexture(oldtexture);
|
||||
newtexture->SetID(oldtexture->GetID());
|
||||
oldtexture->SetName("");
|
||||
AddGameTexture(oldtexture);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -465,11 +515,11 @@ bool FTextureManager::AreTexturesCompatible (FTextureID picnum1, FTextureID picn
|
|||
if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size())
|
||||
return false;
|
||||
|
||||
FTexture *texture1 = Textures[index1].Texture;
|
||||
FTexture *texture2 = Textures[index2].Texture;
|
||||
auto texture1 = Textures[index1].Texture;
|
||||
auto texture2 = Textures[index2].Texture;
|
||||
|
||||
// both textures must be the same type.
|
||||
if (texture1 == NULL || texture2 == NULL || texture1->UseType != texture2->UseType)
|
||||
if (texture1 == NULL || texture2 == NULL || texture1->GetUseType() != texture2->GetUseType())
|
||||
return false;
|
||||
|
||||
// both textures must be from the same file
|
||||
|
@ -556,30 +606,28 @@ void FTextureManager::AddHiresTextures (int wadnum)
|
|||
if (amount == 0)
|
||||
{
|
||||
// A texture with this name does not yet exist
|
||||
FTexture * newtex = FTexture::CreateTexture (Name, firsttx, ETextureType::Any);
|
||||
auto newtex = MakeGameTexture(CreateTextureFromLump(firsttx), Name, ETextureType::Override);
|
||||
if (newtex != NULL)
|
||||
{
|
||||
newtex->UseType=ETextureType::Override;
|
||||
AddTexture(newtex);
|
||||
AddGameTexture(newtex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
||||
{
|
||||
FTexture * newtex = FTexture::CreateTexture ("", firsttx, ETextureType::Any);
|
||||
FTexture * newtex = CreateTextureFromLump(firsttx);
|
||||
if (newtex != NULL)
|
||||
{
|
||||
FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
auto oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
|
||||
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
|
||||
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
|
||||
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
|
||||
ReplaceTexture(tlist[i], newtex, true);
|
||||
auto gtex = MakeGameTexture(newtex, nullptr, ETextureType::Override);
|
||||
gtex->SetWorldPanning(true);
|
||||
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||
gtex->SetOffsets(0, xs_RoundToInt(oldtex->GetDisplayLeftOffset(0) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(0) * gtex->GetScaleY()));
|
||||
gtex->SetOffsets(1, xs_RoundToInt(oldtex->GetDisplayLeftOffset(1) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(1) * gtex->GetScaleY()));
|
||||
ReplaceTexture(tlist[i], gtex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -655,28 +703,27 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
|
|||
{
|
||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
||||
{
|
||||
FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
auto oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
int sl;
|
||||
|
||||
// only replace matching types. For sprites also replace any MiscPatches
|
||||
// based on the same lump. These can be created for icons.
|
||||
if (oldtex->UseType == type || type == ETextureType::Any ||
|
||||
(mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) ||
|
||||
(type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch &&
|
||||
if (oldtex->GetUseType() == type || type == ETextureType::Any ||
|
||||
(mode == TEXMAN_Overridable && oldtex->GetUseType() == ETextureType::Override) ||
|
||||
(type == ETextureType::Sprite && oldtex->GetUseType() == ETextureType::MiscPatch &&
|
||||
(sl=oldtex->GetSourceLump()) >= 0 && fileSystem.GetFileNamespace(sl) == ns_sprites)
|
||||
)
|
||||
{
|
||||
FTexture * newtex = FTexture::CreateTexture ("", lumpnum, ETextureType::Any);
|
||||
FTexture * newtex = CreateTextureFromLump(lumpnum);
|
||||
if (newtex != NULL)
|
||||
{
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
|
||||
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
|
||||
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
|
||||
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
|
||||
ReplaceTexture(tlist[i], newtex, true);
|
||||
auto gtex = MakeGameTexture(newtex, nullptr, ETextureType::Override);
|
||||
gtex->SetWorldPanning(true);
|
||||
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||
gtex->SetOffsets(0, xs_RoundToInt(oldtex->GetDisplayLeftOffset(0) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(0) * gtex->GetScaleY()));
|
||||
gtex->SetOffsets(1, xs_RoundToInt(oldtex->GetDisplayLeftOffset(1) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(1) * gtex->GetScaleY()));
|
||||
ReplaceTexture(tlist[i], gtex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -705,21 +752,21 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
|
|||
|
||||
if (lumpnum>=0)
|
||||
{
|
||||
FTexture *newtex = FTexture::CreateTexture(src, lumpnum, ETextureType::Override);
|
||||
auto newtex = MakeGameTexture(CreateTextureFromLump(lumpnum), src, ETextureType::Override);
|
||||
|
||||
if (newtex != NULL)
|
||||
{
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetDisplaySize(width, height);
|
||||
newtex->SetWorldPanning(true);
|
||||
newtex->SetDisplaySize((float)width, (float)height);
|
||||
|
||||
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
|
||||
if (oldtex.isValid())
|
||||
{
|
||||
ReplaceTexture(oldtex, newtex, true);
|
||||
newtex->UseType = ETextureType::Override;
|
||||
newtex->SetUseType(ETextureType::Override);
|
||||
}
|
||||
else AddTexture(newtex);
|
||||
else AddGameTexture(newtex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -925,11 +972,11 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b
|
|||
|
||||
// Try to create a texture from this lump and add it.
|
||||
// Unfortunately we have to look at everything that comes through here...
|
||||
FTexture *out = FTexture::CreateTexture(Name, i, skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch);
|
||||
auto out = MakeGameTexture(CreateTextureFromLump(i), Name, skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch);
|
||||
|
||||
if (out != NULL)
|
||||
{
|
||||
AddTexture (out);
|
||||
AddGameTexture (out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -953,7 +1000,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b
|
|||
|
||||
void FTextureManager::SortTexturesByType(int start, int end)
|
||||
{
|
||||
TArray<FTexture *> newtextures;
|
||||
TArray<FGameTexture *> newtextures;
|
||||
|
||||
// First unlink all newly added textures from the hash chain
|
||||
for (int i = 0; i < HASH_SIZE; i++)
|
||||
|
@ -981,9 +1028,9 @@ void FTextureManager::SortTexturesByType(int start, int end)
|
|||
{
|
||||
for(unsigned j = 0; j<newtextures.Size(); j++)
|
||||
{
|
||||
if (newtextures[j] != NULL && newtextures[j]->UseType == texturetypes[i])
|
||||
if (newtextures[j] != NULL && newtextures[j]->GetUseType() == texturetypes[i])
|
||||
{
|
||||
AddTexture(newtextures[j]);
|
||||
AddGameTexture(newtextures[j]);
|
||||
newtextures[j] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -993,8 +1040,8 @@ void FTextureManager::SortTexturesByType(int start, int end)
|
|||
{
|
||||
if (newtextures[j] != NULL)
|
||||
{
|
||||
Printf("Texture %s has unknown type!\n", newtextures[j]->Name.GetChars());
|
||||
AddTexture(newtextures[j]);
|
||||
Printf("Texture %s has unknown type!\n", newtextures[j]->GetName().GetChars());
|
||||
AddGameTexture(newtextures[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1032,8 +1079,8 @@ void FTextureManager::AddLocalizedVariants()
|
|||
FTextureID tex = CheckForTexture(entry.name, ETextureType::MiscPatch);
|
||||
if (tex.isValid())
|
||||
{
|
||||
FTexture *otex = GetTexture(origTex);
|
||||
FTexture *ntex = GetTexture(tex);
|
||||
auto otex = GetGameTexture(origTex);
|
||||
auto ntex = GetGameTexture(tex);
|
||||
if (otex->GetDisplayWidth() != ntex->GetDisplayWidth() || otex->GetDisplayHeight() != ntex->GetDisplayHeight())
|
||||
{
|
||||
Printf("Localized texture %s must be the same size as the one it replaces\n", entry.name);
|
||||
|
@ -1081,8 +1128,9 @@ void FTextureManager::AddLocalizedVariants()
|
|||
// FTextureManager :: Init
|
||||
//
|
||||
//==========================================================================
|
||||
FTexture *CreateShaderTexture(bool, bool);
|
||||
FGameTexture *CreateShaderTexture(bool, bool);
|
||||
void InitBuildTiles();
|
||||
FImageSource* CreateEmptyTexture();
|
||||
|
||||
void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo&))
|
||||
{
|
||||
|
@ -1090,15 +1138,18 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI
|
|||
DeleteAll();
|
||||
//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
|
||||
|
||||
// Texture 0 is a dummy texture used to indicate "no texture"
|
||||
auto nulltex = new FImageTexture(nullptr, "");
|
||||
nulltex->SetUseType(ETextureType::Null);
|
||||
AddTexture (nulltex);
|
||||
auto nulltex = MakeGameTexture(new FImageTexture(CreateEmptyTexture()), nullptr, ETextureType::Null);
|
||||
AddGameTexture(nulltex);
|
||||
|
||||
// This is for binding to unused texture units, because accessing an unbound texture unit is undefined. It's a one pixel empty texture.
|
||||
auto emptytex = MakeGameTexture(new FImageTexture(CreateEmptyTexture()), nullptr, ETextureType::Override);
|
||||
emptytex->SetSize(1, 1);
|
||||
AddGameTexture(emptytex);
|
||||
// some special textures used in the game.
|
||||
AddTexture(CreateShaderTexture(false, false));
|
||||
AddTexture(CreateShaderTexture(false, true));
|
||||
AddTexture(CreateShaderTexture(true, false));
|
||||
AddTexture(CreateShaderTexture(true, true));
|
||||
AddGameTexture(CreateShaderTexture(false, false));
|
||||
AddGameTexture(CreateShaderTexture(false, true));
|
||||
AddGameTexture(CreateShaderTexture(true, false));
|
||||
AddGameTexture(CreateShaderTexture(true, true));
|
||||
|
||||
int wadcnt = fileSystem.GetNumWads();
|
||||
|
||||
|
@ -1133,6 +1184,13 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI
|
|||
glPart = TexMan.CheckForTexture("glstuff/glpart.png", ETextureType::MiscPatch);
|
||||
mirrorTexture = TexMan.CheckForTexture("glstuff/mirror.png", ETextureType::MiscPatch);
|
||||
AddLocalizedVariants();
|
||||
|
||||
// Make sure all ID's are correct by resetting them here to the proper index.
|
||||
for (unsigned int i = 0, count = Textures.Size(); i < count; ++i)
|
||||
{
|
||||
Textures[i].Texture->SetID(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1160,19 +1218,95 @@ void FTextureManager::InitPalettedVersions()
|
|||
FTextureID pic2 = CheckForTexture(sc.String, ETextureType::Any);
|
||||
if (!pic2.isValid())
|
||||
{
|
||||
sc.ScriptMessage("Unknown texture %s to use as replacement", sc.String);
|
||||
sc.ScriptMessage("Unknown texture %s to use as paletted replacement", sc.String);
|
||||
}
|
||||
if (pic1.isValid() && pic2.isValid())
|
||||
{
|
||||
FTexture *owner = GetTexture(pic1);
|
||||
FTexture *owned = GetTexture(pic2);
|
||||
|
||||
if (owner && owned) owner->PalVersion = owned;
|
||||
Textures[pic1.GetIndex()].Paletted = pic2.GetIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureID FTextureManager::GetRawTexture(FTextureID texid)
|
||||
{
|
||||
int texidx = texid.GetIndex();
|
||||
if ((unsigned)texidx >= Textures.Size()) return texid;
|
||||
if (Textures[texidx].FrontSkyLayer != -1) return FSetTextureID(Textures[texidx].FrontSkyLayer);
|
||||
|
||||
// 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 = ttex->GetImage();
|
||||
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
|
||||
if (image == nullptr || image->IsRawCompatible() || tex->GetUseType() != ETextureType::Wall || ttex->GetWidth() != tex->GetDisplayWidth() ||
|
||||
ttex->GetHeight() != tex->GetDisplayHeight())
|
||||
{
|
||||
Textures[texidx].RawTexture = texidx;
|
||||
return texid;
|
||||
}
|
||||
|
||||
// Let the hackery begin
|
||||
auto mptimage = static_cast<FMultiPatchTexture*>(image);
|
||||
auto source = mptimage->GetImageForPart(0);
|
||||
|
||||
// Size must match for this to work as intended
|
||||
if (source->GetWidth() != ttex->GetWidth() || source->GetHeight() != ttex->GetHeight())
|
||||
{
|
||||
Textures[texidx].RawTexture = texidx;
|
||||
return texid;
|
||||
}
|
||||
|
||||
// Todo: later this can just link to the already existing texture for this source graphic, once it can be retrieved through the image's SourceLump index
|
||||
auto RawTexture = MakeGameTexture(new FImageTexture(source), nullptr, ETextureType::Wall);
|
||||
texid = TexMan.AddGameTexture(RawTexture);
|
||||
Textures[texidx].RawTexture = texid.GetIndex();
|
||||
Textures[texid.GetIndex()].RawTexture = texid.GetIndex();
|
||||
return texid;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Same shit for a different hack, this time Hexen's front sky layers.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid)
|
||||
{
|
||||
int texidx = texid.GetIndex();
|
||||
if ((unsigned)texidx >= Textures.Size()) return texid;
|
||||
if (Textures[texidx].FrontSkyLayer != -1) return FSetTextureID(Textures[texidx].FrontSkyLayer);
|
||||
|
||||
// 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 = ttex->GetImage();
|
||||
if (image == nullptr || !image->SupportRemap0() || tex->GetUseType() != ETextureType::Wall || tex->useWorldPanning() || tex->GetTexelTopOffset() != 0 ||
|
||||
ttex->GetWidth() != tex->GetDisplayWidth() || ttex->GetHeight() != tex->GetDisplayHeight())
|
||||
{
|
||||
Textures[texidx].FrontSkyLayer = texidx;
|
||||
return texid;
|
||||
}
|
||||
|
||||
// Set this up so that it serializes to the same info as the base texture - this is needed to restore it on load.
|
||||
// But do not link the new texture into the hash chain!
|
||||
auto itex = new FImageTexture(image);
|
||||
itex->SetNoRemap0();
|
||||
auto FrontSkyLayer = MakeGameTexture(itex, tex->GetName(), ETextureType::Wall);
|
||||
FrontSkyLayer->SetUseType(tex->GetUseType());
|
||||
texid = TexMan.AddGameTexture(FrontSkyLayer, false);
|
||||
Textures[texidx].FrontSkyLayer = texid.GetIndex();
|
||||
Textures[texid.GetIndex()].FrontSkyLayer = texid.GetIndex(); // also let it refer to itself as its front sky layer, in case for repeated InitSkyMap calls.
|
||||
return texid;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1314,7 +1448,7 @@ void FTextureManager::AdjustSpriteOffsets()
|
|||
fileSystem.GetFileShortName(str, i);
|
||||
str[8] = 0;
|
||||
FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0);
|
||||
if (texid.isValid() && fileSystem.GetFileContainer(GetTexture(texid)->SourceLump) > fileSystem.GetMaxIwadNum())
|
||||
if (texid.isValid() && fileSystem.GetFileContainer(GetGameTexture(texid)->GetSourceLump()) > fileSystem.GetMaxIwadNum())
|
||||
{
|
||||
// This texture has been replaced by some PWAD.
|
||||
memcpy(&sprid, str, 4);
|
||||
|
@ -1349,7 +1483,7 @@ void FTextureManager::AdjustSpriteOffsets()
|
|||
}
|
||||
if (texno.isValid())
|
||||
{
|
||||
FTexture * tex = GetTexture(texno);
|
||||
auto tex = GetGameTexture(texno);
|
||||
|
||||
int lumpnum = tex->GetSourceLump();
|
||||
// We only want to change texture offsets for sprites in the IWAD or the file this lump originated from.
|
||||
|
@ -1360,11 +1494,10 @@ void FTextureManager::AdjustSpriteOffsets()
|
|||
{
|
||||
if (wadno >= fileSystem.GetIwadNum() && wadno <= fileSystem.GetMaxIwadNum() && !forced && iwadonly)
|
||||
{
|
||||
memcpy(&sprid, &tex->Name[0], 4);
|
||||
memcpy(&sprid, tex->GetName().GetChars(), 4);
|
||||
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
|
||||
}
|
||||
tex->_LeftOffset[1] = x;
|
||||
tex->_TopOffset[1] = y;
|
||||
tex->SetOffsets(1, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "name.h"
|
||||
|
||||
class FxAddSub;
|
||||
class FTexture;
|
||||
struct BuildInfo;
|
||||
class FMultipatchTextureBuilder;
|
||||
int PalCheck(int tex);
|
||||
|
||||
// Texture manager
|
||||
|
@ -25,42 +25,59 @@ public:
|
|||
private:
|
||||
int ResolveLocalizedTexture(int texnum);
|
||||
|
||||
FTexture *InternalGetTexture(int texnum, bool animate, bool localize, bool palettesubst)
|
||||
int ResolveTextureIndex(int texnum, bool animate, bool localize)
|
||||
{
|
||||
if ((unsigned)texnum >= Textures.Size()) return nullptr;
|
||||
if ((unsigned)texnum >= Textures.Size()) return -1;
|
||||
if (animate) texnum = Translation[texnum];
|
||||
if (localize && Textures[texnum].HasLocalization) texnum = ResolveLocalizedTexture(texnum);
|
||||
if (palettesubst) texnum = PalCheck(texnum);
|
||||
return texnum;
|
||||
}
|
||||
|
||||
FGameTexture *InternalGetTexture(int texnum, bool animate, bool localize)
|
||||
{
|
||||
texnum = ResolveTextureIndex(texnum, animate, localize);
|
||||
if (texnum == -1) return nullptr;
|
||||
return Textures[texnum].Texture;
|
||||
}
|
||||
|
||||
public:
|
||||
FTextureID ResolveTextureIndex(FTextureID texid, bool animate, bool localize)
|
||||
{
|
||||
return FSetTextureID(ResolveTextureIndex(texid.GetIndex(), animate, localize));
|
||||
}
|
||||
|
||||
// This only gets used in UI code so we do not need PALVERS handling.
|
||||
FTexture *GetTextureByName(const char *name, bool animate = false)
|
||||
FGameTexture* GetGameTextureByName(const char *name, bool animate = false)
|
||||
{
|
||||
FTextureID texnum = GetTextureID (name, ETextureType::MiscPatch);
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true, false);
|
||||
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch);
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true);
|
||||
}
|
||||
|
||||
FGameTexture* GetGameTexture(FTextureID texnum, bool animate = false)
|
||||
{
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true);
|
||||
}
|
||||
|
||||
FTexture *GetTexture(FTextureID texnum, bool animate = false)
|
||||
FGameTexture* GetPalettedTexture(FTextureID texnum, bool animate = false, bool allowsubstitute = true)
|
||||
{
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true, false);
|
||||
auto texid = ResolveTextureIndex(texnum.GetIndex(), animate, true);
|
||||
if (texid == -1) return nullptr;
|
||||
if (allowsubstitute && Textures[texid].Paletted > 0) texid = Textures[texid].Paletted;
|
||||
return Textures[texid].Texture;
|
||||
}
|
||||
|
||||
// This is the only access function that should be used inside the software renderer.
|
||||
FTexture *GetPalettedTexture(FTextureID texnum, bool animate)
|
||||
|
||||
FGameTexture* GameByIndex(int i, bool animate = false)
|
||||
{
|
||||
return InternalGetTexture(texnum.GetIndex(), animate, true, true);
|
||||
return InternalGetTexture(i, animate, true);
|
||||
}
|
||||
|
||||
FTexture *ByIndex(int i, bool animate = false)
|
||||
{
|
||||
return InternalGetTexture(i, animate, true, false);
|
||||
}
|
||||
|
||||
FTexture *FindTexture(const char *texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
||||
|
||||
FGameTexture* FindGameTexture(const char* texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
||||
|
||||
bool OkForLocalization(FTextureID texnum, const char *substitute, int locnum);
|
||||
|
||||
void FlushAll();
|
||||
FTextureID GetFrontSkyLayer(FTextureID);
|
||||
FTextureID GetRawTexture(FTextureID);
|
||||
|
||||
|
||||
enum
|
||||
|
@ -99,7 +116,7 @@ public:
|
|||
void AddLocalizedVariants();
|
||||
|
||||
FTextureID CreateTexture (int lumpnum, ETextureType usetype=ETextureType::Any); // Also calls AddTexture
|
||||
FTextureID AddTexture (FTexture *texture);
|
||||
FTextureID AddGameTexture(FGameTexture* texture, bool addtohash = true);
|
||||
FTextureID GetDefaultTexture() const { return DefaultTexture; }
|
||||
|
||||
void LoadTextureX(int wadnum, FMultipatchTextureBuilder &build);
|
||||
|
@ -107,7 +124,7 @@ public:
|
|||
void Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo &));
|
||||
void DeleteAll();
|
||||
|
||||
void ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free);
|
||||
void ReplaceTexture (FTextureID picnum, FGameTexture *newtexture, bool free);
|
||||
|
||||
int NumTextures () const { return (int)Textures.Size(); }
|
||||
|
||||
|
@ -144,7 +161,7 @@ public:
|
|||
return BuildTileData.Last();
|
||||
}
|
||||
|
||||
FTexture* Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
|
||||
FGameTexture* GameTexture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
|
||||
void SetTranslation(FTextureID fromtexnum, FTextureID totexnum);
|
||||
|
||||
private:
|
||||
|
@ -155,7 +172,10 @@ private:
|
|||
|
||||
struct TextureHash
|
||||
{
|
||||
FTexture *Texture;
|
||||
FGameTexture* Texture;
|
||||
int Paletted; // redirection to paletted variant
|
||||
int FrontSkyLayer; // and front sky layer,
|
||||
int RawTexture;
|
||||
int HashNext;
|
||||
bool HasLocalization;
|
||||
};
|
||||
|
@ -185,3 +205,4 @@ public:
|
|||
};
|
||||
|
||||
extern FTextureManager TexMan;
|
||||
|
||||
|
|
|
@ -42,23 +42,33 @@
|
|||
#include "textureid.h"
|
||||
#include <vector>
|
||||
#include "hw_texcontainer.h"
|
||||
|
||||
// 15 because 0th texture is our texture
|
||||
#define MAX_CUSTOM_HW_SHADER_TEXTURES 15
|
||||
#include "floatrect.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
typedef TMap<int, bool> SpriteHits;
|
||||
class FImageSource;
|
||||
class FGameTexture;
|
||||
class IHardwareTexture;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CLAMP_NONE = 0,
|
||||
CLAMP_X = 1,
|
||||
CLAMP_Y = 2,
|
||||
CLAMP_XY = 3,
|
||||
CLAMP_XY_NOMIP = 4,
|
||||
CLAMP_NOFILTER = 5,
|
||||
CLAMP_CAMTEX = 6,
|
||||
};
|
||||
|
||||
enum MaterialShaderIndex
|
||||
{
|
||||
SHADER_Default,
|
||||
SHADER_Warp1,
|
||||
SHADER_Warp2,
|
||||
SHADER_Brightmap,
|
||||
SHADER_Specular,
|
||||
SHADER_SpecularBrightmap,
|
||||
SHADER_PBR,
|
||||
SHADER_PBRBrightmap,
|
||||
SHADER_Paletted,
|
||||
SHADER_NoTexture,
|
||||
SHADER_BasicFuzz,
|
||||
|
@ -72,46 +82,34 @@ enum MaterialShaderIndex
|
|||
FIRST_USER_SHADER
|
||||
};
|
||||
|
||||
enum texflags
|
||||
{
|
||||
// These get Or'ed into uTextureMode because it only uses its 3 lowermost bits.
|
||||
TEXF_Brightmap = 0x10000,
|
||||
TEXF_Detailmap = 0x20000,
|
||||
TEXF_Glowmap = 0x40000,
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SFlag_Brightmap = 1,
|
||||
SFlag_Detailmap = 2,
|
||||
SFlag_Glowmap = 4,
|
||||
};
|
||||
|
||||
struct UserShaderDesc
|
||||
{
|
||||
FString shader;
|
||||
MaterialShaderIndex shaderType;
|
||||
FString defines;
|
||||
bool disablealphatest = false;
|
||||
uint8_t shaderFlags = 0;
|
||||
};
|
||||
|
||||
extern TArray<UserShaderDesc> usershaders;
|
||||
|
||||
|
||||
struct FloatRect
|
||||
{
|
||||
float left,top;
|
||||
float width,height;
|
||||
|
||||
|
||||
void Offset(float xofs,float yofs)
|
||||
{
|
||||
left+=xofs;
|
||||
top+=yofs;
|
||||
}
|
||||
void Scale(float xfac,float yfac)
|
||||
{
|
||||
left*=xfac;
|
||||
width*=xfac;
|
||||
top*=yfac;
|
||||
height*=yfac;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -141,7 +139,12 @@ enum FTextureFormat : uint32_t
|
|||
TEX_Count
|
||||
};
|
||||
|
||||
class FSoftwareTexture;
|
||||
class ISoftwareTexture
|
||||
{
|
||||
public:
|
||||
virtual ~ISoftwareTexture() = default;
|
||||
};
|
||||
|
||||
class FGLRenderState;
|
||||
|
||||
struct spriteframewithrotate;
|
||||
|
@ -202,115 +205,62 @@ struct FTextureBuffer
|
|||
};
|
||||
|
||||
// Base texture class
|
||||
class FTexture
|
||||
class FTexture : public RefCountedBase
|
||||
{
|
||||
friend class GLDefsParser;
|
||||
friend class FMultipatchTextureBuilder;
|
||||
|
||||
// The serializer also needs access to more specific info that shouldn't be accessible through the interface.
|
||||
friend FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTextureID *defval);
|
||||
friend class FGameTexture; // only for the porting work
|
||||
|
||||
// For now only give access to classes which cannot be reworked yet. None of these should remain here when all is done.
|
||||
friend class FSoftwareTexture;
|
||||
friend class FWarpTexture;
|
||||
friend class FMaterial;
|
||||
friend class OpenGLRenderer::FGLRenderState; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class
|
||||
friend class VkRenderState;
|
||||
friend class PolyRenderState;
|
||||
friend struct FTexCoordInfo;
|
||||
friend class OpenGLRenderer::FHardwareTexture;
|
||||
friend class VkHardwareTexture;
|
||||
friend class PolyHardwareTexture;
|
||||
friend class FMultiPatchTexture;
|
||||
friend class FSkyBox;
|
||||
friend class FBrightmapTexture;
|
||||
friend class FFont;
|
||||
public:
|
||||
FHardwareTextureContainer SystemTextures;
|
||||
protected:
|
||||
FloatRect* areas = nullptr;
|
||||
int SourceLump;
|
||||
uint16_t Width = 0, Height = 0;
|
||||
|
||||
bool Masked = false; // Texture (might) have holes
|
||||
bool bHasCanvas = false;
|
||||
int8_t bTranslucent = -1;
|
||||
int8_t areacount = 0; // this is capped at 4 sections.
|
||||
|
||||
|
||||
public:
|
||||
static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype);
|
||||
virtual ~FTexture ();
|
||||
|
||||
IHardwareTexture* GetHardwareTexture(int translation, int scaleflags);
|
||||
virtual FImageSource *GetImage() const { return nullptr; }
|
||||
void AddAutoMaterials();
|
||||
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
||||
|
||||
// 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() { return GetScaledLeftOffsetDouble(0); }
|
||||
double GetDisplayTopOffsetDouble() { return GetScaledTopOffsetDouble(0); }
|
||||
void SetOffsets(int l, int t)
|
||||
void CleanHardwareTextures()
|
||||
{
|
||||
_LeftOffset[0] = _LeftOffset[1] = l;
|
||||
_TopOffset[0] = _TopOffset[1] = t;
|
||||
SystemTextures.Clean();
|
||||
}
|
||||
|
||||
int GetTexelWidth() { return Width; }
|
||||
int GetTexelHeight() { return Height; }
|
||||
int GetTexelLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
|
||||
int GetTexelTopOffset(int adjusted) { return _TopOffset[adjusted]; }
|
||||
|
||||
void CleanPrecacheMarker()
|
||||
{
|
||||
SystemTextures.UnmarkAll();
|
||||
}
|
||||
|
||||
void MarkForPrecache(int translation, int scaleflags)
|
||||
{
|
||||
SystemTextures.MarkForPrecache(translation, scaleflags);
|
||||
}
|
||||
|
||||
void CleanUnused()
|
||||
{
|
||||
SystemTextures.CleanUnused();
|
||||
}
|
||||
|
||||
int GetWidth() { return Width; }
|
||||
int GetHeight() { return Height; }
|
||||
|
||||
bool isValid() const { return UseType != ETextureType::Null; }
|
||||
bool isSWCanvas() const { return UseType == ETextureType::SWCanvas; }
|
||||
bool isSkybox() const { return bSkybox; }
|
||||
bool isFullbrightDisabled() const { return bDisableFullbright; }
|
||||
bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later.
|
||||
bool isCanvas() const { return bHasCanvas; }
|
||||
bool isMiscPatch() const { return UseType == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
|
||||
int isWarped() const { return bWarped; }
|
||||
int GetRotations() const { return Rotations; }
|
||||
void SetRotations(int rot) { Rotations = int16_t(rot); }
|
||||
bool isSprite() const { return UseType == ETextureType::Sprite || UseType == ETextureType::SkinSprite || UseType == ETextureType::Decal; }
|
||||
|
||||
const FString &GetName() const { return Name; }
|
||||
void SetNoDecals(bool on) { bNoDecals = on; }
|
||||
void SetWarpStyle(int style) { bWarped = style; }
|
||||
bool allowNoDecals() const { return bNoDecals; }
|
||||
bool isScaled() const { return Scale.X != 1 || Scale.Y != 1; }
|
||||
bool isMasked() const { return bMasked; }
|
||||
void SetSkyOffset(int offs) { SkyOffset = offs; }
|
||||
int GetSkyOffset() const { return SkyOffset; }
|
||||
FTextureID GetID() const { return id; }
|
||||
PalEntry GetSkyCapColor(bool bottom);
|
||||
FTexture *GetRawTexture();
|
||||
virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
|
||||
void GetGlowColor(float *data);
|
||||
bool isGlowing() const { return bGlowing; }
|
||||
bool isAutoGlowing() const { return bAutoGlowing; }
|
||||
int GetGlowHeight() const { return GlowHeight; }
|
||||
bool isFullbright() const { return bFullbright; }
|
||||
void CreateDefaultBrightmap();
|
||||
int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
|
||||
bool FindHoles(const unsigned char * buffer, int w, int h);
|
||||
void SetUseType(ETextureType type) { UseType = type; }
|
||||
int GetSourceLump() const { return SourceLump; }
|
||||
ETextureType GetUseType() const { return UseType; }
|
||||
void SetSpeed(float fac) { shaderspeed = fac; }
|
||||
void SetWorldPanning(bool on) { bWorldPanning = on; }
|
||||
void SetDisplaySize(int fitwidth, int fitheight);
|
||||
void SetFrontSkyLayer(bool on = true) { bNoRemap0 = on; }
|
||||
bool IsFrontSkyLayer() { return bNoRemap0; }
|
||||
|
||||
FTexture* GetBrightmap()
|
||||
{
|
||||
if (!bBrightmapChecked)
|
||||
CreateDefaultBrightmap();
|
||||
return Brightmap;
|
||||
}
|
||||
|
||||
void CopySize(FTexture* BaseTexture)
|
||||
{
|
||||
Width = BaseTexture->GetTexelWidth();
|
||||
Height = BaseTexture->GetTexelHeight();
|
||||
_TopOffset[0] = BaseTexture->_TopOffset[0];
|
||||
_TopOffset[1] = BaseTexture->_TopOffset[1];
|
||||
_LeftOffset[0] = BaseTexture->_LeftOffset[0];
|
||||
_LeftOffset[1] = BaseTexture->_LeftOffset[1];
|
||||
Scale = BaseTexture->Scale;
|
||||
Width = BaseTexture->GetWidth();
|
||||
Height = BaseTexture->GetHeight();
|
||||
}
|
||||
|
||||
// This is only used for the null texture and for Heretic's skies.
|
||||
|
@ -320,119 +270,20 @@ public:
|
|||
Height = h;
|
||||
}
|
||||
|
||||
bool TrimBorders(uint16_t* rect);
|
||||
int GetAreas(FloatRect** pAreas) const;
|
||||
|
||||
// Returns the whole texture, stored in column-major order
|
||||
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
||||
virtual FBitmap GetBgraBitmap(const PalEntry *remap, int *trans = nullptr);
|
||||
|
||||
static bool SmoothEdges(unsigned char * buffer,int w, int h);
|
||||
static PalEntry averageColor(const uint32_t *data, int size, int maxout);
|
||||
|
||||
|
||||
FSoftwareTexture *GetSoftwareTexture();
|
||||
|
||||
protected:
|
||||
|
||||
DVector2 Scale;
|
||||
|
||||
int SourceLump;
|
||||
FTextureID id;
|
||||
|
||||
FMaterial *Material[2] = { nullptr, nullptr };
|
||||
public:
|
||||
FHardwareTextureContainer SystemTextures;
|
||||
int alphaThreshold = 0.5;
|
||||
FixedBitArray<256> NoBrightmapFlag = false;
|
||||
protected:
|
||||
FSoftwareTexture *SoftwareTexture = nullptr;
|
||||
|
||||
// None of the following pointers are owned by this texture, they are all controlled by the texture manager.
|
||||
|
||||
// Offset-less version for COMPATF_MASKEDMIDTEX
|
||||
FTexture *OffsetLess = nullptr;
|
||||
// Paletted variant
|
||||
FTexture *PalVersion = nullptr;
|
||||
// Material layers
|
||||
FTexture *Brightmap = nullptr;
|
||||
FTexture *Normal = nullptr; // Normal map texture
|
||||
FTexture *Specular = nullptr; // Specular light texture for the diffuse+normal+specular light model
|
||||
FTexture *Metallic = nullptr; // Metalness texture for the physically based rendering (PBR) light model
|
||||
FTexture *Roughness = nullptr; // Roughness texture for PBR
|
||||
FTexture *AmbientOcclusion = nullptr; // Ambient occlusion texture for PBR
|
||||
|
||||
FTexture *CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES] = { nullptr }; // Custom texture maps for custom hardware shaders
|
||||
|
||||
FString Name;
|
||||
ETextureType UseType; // This texture's primary purpose
|
||||
|
||||
uint8_t bNoDecals:1; // Decals should not stick to texture
|
||||
uint8_t bNoRemap0:1; // Do not remap color 0 (used by front layer of parallax skies)
|
||||
uint8_t bWorldPanning:1; // Texture is panned in world units rather than texels
|
||||
uint8_t bMasked:1; // Texture (might) have holes
|
||||
uint8_t bAlphaTexture:1; // Texture is an alpha channel without color information
|
||||
uint8_t bHasCanvas:1; // Texture is based off FCanvasTexture
|
||||
uint8_t bWarped:2; // This is a warped texture. Used to avoid multiple warps on one texture
|
||||
uint8_t bComplex:1; // Will be used to mark extended MultipatchTextures that have to be
|
||||
// fully composited before subjected to any kind of postprocessing instead of
|
||||
// doing it per patch.
|
||||
uint8_t bMultiPatch:2; // This is a multipatch texture (we really could use real type info for textures...)
|
||||
uint8_t bFullNameTexture : 1;
|
||||
uint8_t bBrightmapChecked : 1; // Set to 1 if brightmap has been checked
|
||||
uint8_t bGlowing : 1; // Texture glow color
|
||||
uint8_t bAutoGlowing : 1; // Glow info is determined from texture image.
|
||||
uint8_t bFullbright : 1; // always draw fullbright
|
||||
uint8_t bDisableFullbright : 1; // This texture will not be displayed as fullbright sprite
|
||||
uint8_t bSkybox : 1; // is a cubic skybox
|
||||
uint8_t bNoCompress : 1;
|
||||
uint8_t bNoExpand : 1;
|
||||
int8_t bTranslucent : 2;
|
||||
bool bHiresHasColorKey = false; // Support for old color-keyed Doomsday textures
|
||||
|
||||
uint16_t Rotations;
|
||||
int16_t SkyOffset;
|
||||
FloatRect *areas = nullptr;
|
||||
int areacount = 0;
|
||||
int GlowHeight = 128;
|
||||
PalEntry GlowColor = 0;
|
||||
int HiresLump = -1; // For external hires textures.
|
||||
float Glossiness = 10.f;
|
||||
float SpecularLevel = 0.1f;
|
||||
float shaderspeed = 1.f;
|
||||
int shaderindex = 0;
|
||||
|
||||
int GetScaledWidth () { int foo = int((Width * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
|
||||
int GetScaledHeight () { int foo = int((Height * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
|
||||
double GetScaledWidthDouble () { return Width / Scale.X; }
|
||||
double GetScaledHeightDouble () { return Height / Scale.Y; }
|
||||
double GetScaleY() const { return Scale.Y; }
|
||||
|
||||
// Now with improved offset adjustment.
|
||||
int GetLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
|
||||
int GetTopOffset(int adjusted) { return _TopOffset[adjusted]; }
|
||||
int GetScaledLeftOffset (int adjusted) { int foo = int((_LeftOffset[adjusted] * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
|
||||
int GetScaledTopOffset (int adjusted) { int foo = int((_TopOffset[adjusted] * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
|
||||
double GetScaledLeftOffsetDouble(int adjusted) { return _LeftOffset[adjusted] / Scale.X; }
|
||||
double GetScaledTopOffsetDouble(int adjusted) { return _TopOffset[adjusted] / Scale.Y; }
|
||||
|
||||
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
|
||||
// should use these, so that if changes are needed, this is the only place to edit.
|
||||
|
||||
// For the hardware renderer. The software renderer's have been offloaded to FSoftwareTexture
|
||||
int GetLeftOffsetHW() { return _LeftOffset[r_spriteadjustHW]; }
|
||||
int GetTopOffsetHW() { return _TopOffset[r_spriteadjustHW]; }
|
||||
|
||||
virtual void ResolvePatches() {}
|
||||
|
||||
void SetScale(const DVector2 &scale)
|
||||
{
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint16_t Width, Height;
|
||||
int16_t _LeftOffset[2], _TopOffset[2];
|
||||
|
||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
||||
FTexture (int lumpnum = -1);
|
||||
|
||||
public:
|
||||
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||
|
@ -442,27 +293,6 @@ public:
|
|||
{
|
||||
return bTranslucent != -1 ? bTranslucent : DetermineTranslucency();
|
||||
}
|
||||
FMaterial* GetMaterial(int num)
|
||||
{
|
||||
return Material[num];
|
||||
}
|
||||
FTexture* GetPalVersion()
|
||||
{
|
||||
return PalVersion;
|
||||
}
|
||||
|
||||
void DeleteHardwareTextures()
|
||||
{
|
||||
SystemTextures.Clean(true, true);
|
||||
}
|
||||
|
||||
private:
|
||||
int CheckDDPK3();
|
||||
int CheckExternalFile(bool & hascolorkey);
|
||||
|
||||
bool bSWSkyColorDone = false;
|
||||
PalEntry FloorSkyColor;
|
||||
PalEntry CeilingSkyColor;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -479,17 +309,13 @@ public:
|
|||
class FCanvasTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
FCanvasTexture(const char* name, int width, int height)
|
||||
FCanvasTexture(int width, int height)
|
||||
{
|
||||
Name = name;
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
bMasked = false;
|
||||
bHasCanvas = true;
|
||||
bTranslucent = false;
|
||||
bNoExpand = true;
|
||||
UseType = ETextureType::Wall;
|
||||
aspectRatio = (float)width / height;
|
||||
}
|
||||
|
||||
void NeedUpdate() { bNeedsUpdate = true; }
|
||||
|
@ -501,6 +327,7 @@ protected:
|
|||
bool bNeedsUpdate = true;
|
||||
public:
|
||||
bool bFirstUpdate = true;
|
||||
float aspectRatio;
|
||||
|
||||
friend struct FCanvasTextureInfo;
|
||||
};
|
||||
|
@ -514,7 +341,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
|
||||
|
@ -527,14 +354,19 @@ public:
|
|||
class FImageTexture : public FTexture
|
||||
{
|
||||
FImageSource* mImage;
|
||||
bool bNoRemap0 = false;
|
||||
protected:
|
||||
void SetFromImage();
|
||||
public:
|
||||
FImageTexture(FImageSource* image, const char* name = nullptr) noexcept;
|
||||
FImageTexture(FImageSource* image) noexcept;
|
||||
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
||||
|
||||
void SetImage(FImageSource* img) // This is only for the multipatch texture builder!
|
||||
void SetImage(FImageSource* img)
|
||||
{
|
||||
mImage = img;
|
||||
SetFromImage();
|
||||
}
|
||||
void SetNoRemap0() { bNoRemap0 = true; }
|
||||
|
||||
FImageSource* GetImage() const override { return mImage; }
|
||||
FBitmap GetBgraBitmap(const PalEntry* p, int* trans) override;
|
||||
|
@ -542,24 +374,8 @@ public:
|
|||
|
||||
};
|
||||
|
||||
struct FTexCoordInfo
|
||||
{
|
||||
int mRenderWidth;
|
||||
int mRenderHeight;
|
||||
int mWidth;
|
||||
FVector2 mScale;
|
||||
FVector2 mTempScale;
|
||||
bool mWorldPanning;
|
||||
|
||||
float FloatToTexU(float v) const { return v / mRenderWidth; }
|
||||
float FloatToTexV(float v) const { return v / mRenderHeight; }
|
||||
float RowOffset(float ofs) const;
|
||||
float TextureOffset(float ofs) const;
|
||||
float TextureAdjustWidth() const;
|
||||
void GetFromTexture(FTexture *tex, float x, float y, bool forceworldpanning);
|
||||
};
|
||||
|
||||
|
||||
#include "gametexture.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ static bool TabbedList; // True if tab list was shown
|
|||
CVAR(Bool, con_notablist, false, CVAR_ARCHIVE)
|
||||
|
||||
|
||||
static FTexture* conback;
|
||||
static FGameTexture* conback;
|
||||
static uint32_t conshade;
|
||||
static bool conline;
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ bool FListMenuItem::Selectable()
|
|||
return false;
|
||||
}
|
||||
|
||||
void FListMenuItem::DrawSelector(int xofs, int yofs, FTexture *tex)
|
||||
void FListMenuItem::DrawSelector(int xofs, int yofs, FGameTexture *tex)
|
||||
{
|
||||
if (!tex)
|
||||
{
|
||||
|
@ -399,7 +399,7 @@ int FListMenuItem::GetWidth()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered)
|
||||
FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FGameTexture *patch, bool centered)
|
||||
: FListMenuItem(x, y)
|
||||
{
|
||||
mTexture = patch;
|
||||
|
@ -414,7 +414,7 @@ void FListMenuItemStaticPatch::Drawer(DListMenu* menu, const DVector2& origin, b
|
|||
}
|
||||
|
||||
int x = mXpos;
|
||||
FTexture *tex = mTexture;
|
||||
FGameTexture *tex = mTexture;
|
||||
if (mYpos >= 0)
|
||||
{
|
||||
if (mCentered) x -= tex->GetDisplayWidth()/2;
|
||||
|
@ -631,7 +631,7 @@ int FListMenuItemNativeText::GetWidth()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture *patch, FName child, int param)
|
||||
FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FGameTexture *patch, FName child, int param)
|
||||
: FListMenuItemSelectable(x, y, height, child, param)
|
||||
{
|
||||
mHotkey = hotkey;
|
||||
|
|
|
@ -270,7 +270,7 @@ bool DMenu::MouseEventBack(int type, int x, int y)
|
|||
auto texid = TexMan.CheckForTexture("engine/graphics/m_back.png", ETextureType::Any);
|
||||
if (texid.isValid())
|
||||
{
|
||||
auto tex = TexMan.GetTexture(texid);
|
||||
auto tex = TexMan.GetGameTexture(texid);
|
||||
if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetDisplayWidth() * CleanXfac;
|
||||
if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetDisplayHeight() * CleanYfac;
|
||||
mBackbuttonSelected = ( x >= 0 && x < tex->GetDisplayWidth() * CleanXfac &&
|
||||
|
@ -327,7 +327,7 @@ void DMenu::Drawer ()
|
|||
auto texid = TexMan.CheckForTexture("engine/graphics/m_back.png", ETextureType::Any);
|
||||
if (texid.isValid())
|
||||
{
|
||||
auto tex = TexMan.GetTexture(texid);
|
||||
auto tex = TexMan.GetGameTexture(texid);
|
||||
int w = tex->GetDisplayWidth() * CleanXfac;
|
||||
int h = tex->GetDisplayHeight() * CleanYfac;
|
||||
int x = (!(m_show_backbutton & 1)) ? 0 : screen->GetWidth() - w;
|
||||
|
|
|
@ -107,7 +107,7 @@ enum EMenuSounds : int
|
|||
EXTERN_CVAR(Bool, menu_sounds)
|
||||
|
||||
struct event_t;
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
class FFont;
|
||||
enum EColorRange : int;
|
||||
class FPlayerClass;
|
||||
|
@ -196,7 +196,7 @@ struct FListMenuDescriptor : public FMenuDescriptor
|
|||
int mSelectedItem;
|
||||
int mSelectOfsX;
|
||||
int mSelectOfsY;
|
||||
FTexture *mSelector;
|
||||
FGameTexture *mSelector;
|
||||
int mDisplayTop;
|
||||
int mXpos, mYpos, mYbotton;
|
||||
int mWLeft, mWRight;
|
||||
|
@ -401,7 +401,7 @@ public:
|
|||
virtual bool MouseEvent(int type, int x, int y);
|
||||
virtual bool CheckHotkey(int c);
|
||||
virtual int GetWidth();
|
||||
virtual void DrawSelector(int xofs, int yofs, FTexture *tex);
|
||||
virtual void DrawSelector(int xofs, int yofs, FGameTexture *tex);
|
||||
void OffsetPositionY(int ydelta) { mYpos += ydelta; }
|
||||
int GetY() { return mYpos; }
|
||||
int GetX() { return mXpos; }
|
||||
|
@ -414,11 +414,11 @@ public:
|
|||
class FListMenuItemStaticPatch : public FListMenuItem
|
||||
{
|
||||
protected:
|
||||
FTexture *mTexture;
|
||||
FGameTexture *mTexture;
|
||||
bool mCentered;
|
||||
|
||||
public:
|
||||
FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered);
|
||||
FListMenuItemStaticPatch(int x, int y, FGameTexture *patch, bool centered);
|
||||
void Drawer(DListMenu* menu, const DVector2& origin, bool selected);
|
||||
};
|
||||
|
||||
|
@ -496,15 +496,15 @@ public:
|
|||
~FListMenuItemNativeText();
|
||||
void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override;
|
||||
int GetWidth() override;
|
||||
void DrawSelector(int xofs, int yofs, FTexture* tex) override { } // The text drawer handles this itself.
|
||||
void DrawSelector(int xofs, int yofs, FGameTexture* tex) override { } // The text drawer handles this itself.
|
||||
};
|
||||
|
||||
|
||||
class FListMenuItemPatch : public FListMenuItemSelectable
|
||||
{
|
||||
FTexture* mTexture;
|
||||
FGameTexture* mTexture;
|
||||
public:
|
||||
FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture* patch, FName child, int param = 0);
|
||||
FListMenuItemPatch(int x, int y, int height, int hotkey, FGameTexture* patch, FName child, int param = 0);
|
||||
void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override;
|
||||
int GetWidth() override;
|
||||
};
|
||||
|
@ -806,7 +806,7 @@ private:
|
|||
int LastSaved = -1;
|
||||
int LastAccessed = -1;
|
||||
TArray<char> SavePicData;
|
||||
FTexture *SavePic = nullptr;
|
||||
FGameTexture *SavePic = nullptr;
|
||||
|
||||
public:
|
||||
int WindowSize = 0;
|
||||
|
|
|
@ -104,7 +104,7 @@ void M_DeinitMenus()
|
|||
DefaultListMenuSettings.mItems.Clear();
|
||||
}
|
||||
|
||||
static FTexture* GetMenuTexture(const char* const name)
|
||||
static FGameTexture* GetMenuTexture(const char* const name)
|
||||
{
|
||||
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
||||
if (!texid.isValid())
|
||||
|
@ -112,7 +112,7 @@ static FTexture* GetMenuTexture(const char* const name)
|
|||
Printf("Missing menu texture: \"%s\"\n", name);
|
||||
}
|
||||
|
||||
return TexMan.GetTexture(texid);
|
||||
return TexMan.GetGameTexture(texid);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -370,7 +370,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
|
|||
int y = sc.Number;
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
FTexture* tex = GetMenuTexture(sc.String);
|
||||
auto tex = GetMenuTexture(sc.String);
|
||||
|
||||
FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered);
|
||||
desc->mItems.Push(it);
|
||||
|
@ -401,7 +401,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
|
|||
else if (sc.Compare("PatchItem"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FTexture* tex = GetMenuTexture(sc.String);
|
||||
auto tex = GetMenuTexture(sc.String);
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
int hotkey = sc.String[0];
|
||||
|
|
|
@ -330,7 +330,7 @@ void DTextEnterMenu::Drawer ()
|
|||
int width;
|
||||
const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2;
|
||||
const int ch = InputGridChars[y * INPUTGRID_WIDTH + x];
|
||||
FTexture *pic = displayFont->GetChar(ch, CR_DARKGRAY, &width);
|
||||
auto pic = displayFont->GetChar(ch, CR_DARKGRAY, &width);
|
||||
EColorRange color;
|
||||
int remap;
|
||||
|
||||
|
|
|
@ -169,9 +169,9 @@ void FGLRenderer::EndOffscreen()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::BindToFrameBuffer(FTexture *mat)
|
||||
void FGLRenderer::BindToFrameBuffer(FGameTexture *mat)
|
||||
{
|
||||
auto pBaseLayer = mat->SystemTextures.GetHardwareTexture(0, false);
|
||||
auto pBaseLayer = mat->GetTexture()->SystemTextures.GetHardwareTexture(0, false);
|
||||
auto BaseLayer = pBaseLayer ? (::FHardwareTexture*)pBaseLayer : nullptr;
|
||||
|
||||
if (BaseLayer == nullptr)
|
||||
|
@ -179,7 +179,7 @@ void FGLRenderer::BindToFrameBuffer(FTexture *mat)
|
|||
// must create the hardware texture first
|
||||
BaseLayer = new ::FHardwareTexture;
|
||||
BaseLayer->CreateTexture(mat->GetTexelWidth()*4, mat->GetTexelHeight()*4, ::FHardwareTexture::TrueColor, false);
|
||||
mat->SystemTextures.AddHardwareTexture(0, false, BaseLayer);
|
||||
mat->GetTexture()->SystemTextures.AddHardwareTexture(0, false, BaseLayer);
|
||||
}
|
||||
BaseLayer->BindToFrameBuffer(mat->GetTexelWidth()*4, mat->GetTexelHeight()*4);
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
bool StartOffscreen();
|
||||
void EndOffscreen();
|
||||
|
||||
void BindToFrameBuffer(FTexture* tex);
|
||||
void BindToFrameBuffer(FGameTexture* tex);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ TArray<uint8_t> FTileTexture::CreatePalettedPixels(int conversion)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height)
|
||||
static FGameTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height)
|
||||
{
|
||||
auto tex = new FArtTile(backingstore, offset, width, height);
|
||||
auto p = &backingstore[offset];
|
||||
|
@ -122,7 +122,7 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
|
|||
|
||||
if (tex)
|
||||
{
|
||||
return new FImageTexture(tex, name);
|
||||
return MakeGameTexture(new FImageTexture(tex), name, ETextureType::Any);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
|
|||
|
||||
void BuildTiles::Init()
|
||||
{
|
||||
Placeholder = TexMan.ByIndex(0);
|
||||
Placeholder = TexMan.GameByIndex(0);
|
||||
for (auto& tile : tiledata)
|
||||
{
|
||||
tile.texture = Placeholder;
|
||||
|
@ -138,6 +138,7 @@ void BuildTiles::Init()
|
|||
tile.picanm = {};
|
||||
tile.RotTile = { -1,-1 };
|
||||
tile.replacement = ReplacementType::Art;
|
||||
tile.NoBrightmapFlag.Zero();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,10 +148,10 @@ void BuildTiles::Init()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void BuildTiles::AddTile(int tilenum, FTexture* tex, bool permap)
|
||||
void BuildTiles::AddTile(int tilenum, FGameTexture* tex, bool permap)
|
||||
{
|
||||
assert(!tex->GetID().isValid()); // must not be added yet.
|
||||
TexMan.AddTexture(tex);
|
||||
TexMan.AddGameTexture(tex);
|
||||
tiledata[tilenum].texture = tex;
|
||||
if (!permap) tiledata[tilenum].backup = tex;
|
||||
}
|
||||
|
@ -300,12 +301,12 @@ void BuildTiles::InvalidateTile(int num)
|
|||
if ((unsigned) num < MAXTILES)
|
||||
{
|
||||
auto tex = tiledata[num].texture;
|
||||
tex->SystemTextures.Clean(true, true);
|
||||
tex->GetTexture()->SystemTextures.Clean();
|
||||
for (auto &rep : tiledata[num].Hightiles)
|
||||
{
|
||||
for (auto &reptex : rep.faces)
|
||||
{
|
||||
if (reptex) reptex->SystemTextures.Clean(true, true);
|
||||
if (reptex) reptex->GetTexture()->SystemTextures.Clean();
|
||||
}
|
||||
}
|
||||
tiledata[num].rawCache.data.Clear();
|
||||
|
@ -404,7 +405,7 @@ void BuildTiles::LoadArtSet(const char* filename)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
|
||||
FGameTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
|
||||
{
|
||||
if (tilenum < 0 || tilenum >= MAXTILES) return nullptr;
|
||||
auto &td = tiledata[tilenum];
|
||||
|
@ -435,15 +436,16 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
|
|||
// All of these effects should probably be redone without actual texture hacking...
|
||||
if (tile->GetTexelWidth() == 0 || tile->GetTexelHeight() == 0) return nullptr; // The base must have a size for this to work.
|
||||
// todo: invalidate hardware textures for tile.
|
||||
replacement = new FImageTexture(new FRestorableTile(tile->GetImage()));
|
||||
replacement = new FImageTexture(new FRestorableTile(tile->GetTexture()->GetImage()));
|
||||
}
|
||||
else if (type == ReplacementType::Canvas)
|
||||
{
|
||||
replacement = new FCanvasTexture("camera", 0, 0);
|
||||
replacement = new FCanvasTexture(0, 0);
|
||||
}
|
||||
else return nullptr;
|
||||
AddTile(tilenum, replacement);
|
||||
return replacement;
|
||||
auto reptex = MakeGameTexture(replacement, "", ETextureType::Any);
|
||||
AddTile(tilenum, reptex);
|
||||
return reptex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -470,7 +472,7 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
|
|||
if (width <= 0 || height <= 0) return nullptr;
|
||||
auto tex = ValidateCustomTile(tilenum, ReplacementType::Writable);
|
||||
if (tex == nullptr) return nullptr;
|
||||
auto wtex = static_cast<FWritableTile*>(tex->GetImage());
|
||||
auto wtex = static_cast<FWritableTile*>(tex->GetTexture()->GetImage());
|
||||
if (!wtex->ResizeImage(width, height)) return nullptr;
|
||||
tex->SetSize(width, height);
|
||||
return wtex->GetRawData();
|
||||
|
@ -486,7 +488,7 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
|
|||
uint8_t* BuildTiles::tileMakeWritable(int num)
|
||||
{
|
||||
auto tex = ValidateCustomTile(num, ReplacementType::Restorable);
|
||||
auto wtex = static_cast<FWritableTile*>(tex->GetImage());
|
||||
auto wtex = static_cast<FWritableTile*>(tex->GetTexture()->GetImage());
|
||||
return wtex ? wtex->GetRawData() : nullptr;
|
||||
}
|
||||
|
||||
|
@ -499,7 +501,7 @@ uint8_t* BuildTiles::tileMakeWritable(int num)
|
|||
int32_t tileGetCRC32(int tileNum)
|
||||
{
|
||||
if ((unsigned)tileNum >= (unsigned)MAXTILES) return 0;
|
||||
auto tile = dynamic_cast<FArtTile*>(TileFiles.tiledata[tileNum].texture->GetImage()); // only consider original ART tiles.
|
||||
auto tile = dynamic_cast<FArtTile*>(TileFiles.tiledata[tileNum].texture->GetTexture()->GetImage()); // only consider original ART tiles.
|
||||
if (!tile) return 0;
|
||||
auto pixels = tile->GetRawData();
|
||||
if (!pixels) return 0;
|
||||
|
@ -541,7 +543,7 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu
|
|||
{
|
||||
FTextureID texid = TexMan.CheckForTexture(fn, ETextureType::Any);
|
||||
if (!texid.isValid()) return -1;
|
||||
auto tex = TexMan.GetTexture(texid);
|
||||
auto tex = TexMan.GetGameTexture(texid);
|
||||
//tex->alphaThreshold = 255 - alphacut;
|
||||
|
||||
int32_t xsiz = tex->GetTexelWidth(), ysiz = tex->GetTexelHeight();
|
||||
|
@ -573,7 +575,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
|
|||
picanm_t* picanm = nullptr;
|
||||
picanm_t* sourceanm = nullptr;
|
||||
int srcxo, srcyo;
|
||||
FTexture* tex;
|
||||
FGameTexture* tex;
|
||||
|
||||
if (pal == -1 && tile == source)
|
||||
{
|
||||
|
@ -594,7 +596,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
|
|||
srcxo = tex->GetTexelLeftOffset(0);
|
||||
srcyo = tex->GetTexelTopOffset(0);
|
||||
|
||||
TArray<uint8_t> buffer = tex->Get8BitPixels(false);
|
||||
TArray<uint8_t> buffer = tex->GetTexture()->Get8BitPixels(false);
|
||||
|
||||
if (pal != -1)
|
||||
{
|
||||
|
@ -604,7 +606,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
|
|||
pixel = remap[pixel];
|
||||
}
|
||||
}
|
||||
tex = new FImageTexture(new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight()));
|
||||
tex = MakeGameTexture(new FImageTexture(new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight())), "", ETextureType::Any);
|
||||
picanm = &TileFiles.tiledata[tile].picanm;
|
||||
TileFiles.AddTile(tile, tex);
|
||||
}
|
||||
|
@ -656,7 +658,7 @@ void artSetupMapArt(const char* filename)
|
|||
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
||||
if (texid.isValid())
|
||||
{
|
||||
TileFiles.tiledata[i].texture = TexMan.GetTexture(texid);
|
||||
TileFiles.tiledata[i].texture = TexMan.GetGameTexture(texid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -691,7 +693,7 @@ void artSetupMapArt(const char* filename)
|
|||
void tileDelete(int tile)
|
||||
{
|
||||
TileFiles.TextureToTile.Remove(tileGetTexture(tile));
|
||||
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.ByIndex(0);
|
||||
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.GameByIndex(0);
|
||||
vox_undefine(tile);
|
||||
md_undefinetile(tile);
|
||||
tileRemoveReplacement(tile);
|
||||
|
@ -723,7 +725,7 @@ void tileSetDummy(int tile, int width, int height)
|
|||
}
|
||||
else if (width > 0 && height > 0)
|
||||
{
|
||||
auto dtile = new FImageTexture(new FDummyTile(width, height));
|
||||
auto dtile = MakeGameTexture(new FImageTexture(new FDummyTile(width, height)), "", ETextureType::Any);
|
||||
TileFiles.AddTile(tile, dtile);
|
||||
}
|
||||
}
|
||||
|
@ -760,7 +762,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
|
|||
if ((unsigned)tileNum >= MAXTILES) return tileNum;
|
||||
auto tex = tileGetTexture(tileNum);
|
||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return tileNum;
|
||||
TArray<uint8_t> buffer = tex->Get8BitPixels(false);
|
||||
TArray<uint8_t> buffer = tex->GetTexture()->Get8BitPixels(false);
|
||||
TArray<uint8_t> dbuffer(tex->GetTexelWidth() * tex->GetTexelHeight(), true);
|
||||
|
||||
auto src = buffer.Data();
|
||||
|
@ -777,7 +779,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
|
|||
*(dst + y * width + xofs) = *(src + y + yofs);
|
||||
}
|
||||
|
||||
auto dtex = new FImageTexture(new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth()));
|
||||
auto dtex = MakeGameTexture(new FImageTexture(new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth())), "", ETextureType::Any);
|
||||
int index = findUnusedTile();
|
||||
bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup;
|
||||
TileFiles.AddTile(index, dtex, mapart);
|
||||
|
@ -821,7 +823,7 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo
|
|||
return -1;
|
||||
}
|
||||
|
||||
replace.faces[0] = TexMan.GetTexture(texid);
|
||||
replace.faces[0] = TexMan.GetGameTexture(texid);
|
||||
if (replace.faces[0] == nullptr)
|
||||
replace.alphacut = min(alphacut,1.f);
|
||||
replace.scale = { xscale, yscale };
|
||||
|
@ -861,7 +863,7 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
|
|||
Printf("%s: Skybox image for tile %d does not exist or is invalid\n", *facenames, picnum);
|
||||
return -1;
|
||||
}
|
||||
face = TexMan.GetTexture(texid);
|
||||
face = TexMan.GetGameTexture(texid);
|
||||
}
|
||||
replace.flags = flags;
|
||||
replace.palnum = (uint16_t)palnum;
|
||||
|
|
|
@ -62,7 +62,7 @@ struct rottile_t
|
|||
|
||||
struct HightileReplacement
|
||||
{
|
||||
FTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only
|
||||
FGameTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only
|
||||
vec2f_t scale;
|
||||
float alphacut, specpower, specfactor;
|
||||
uint16_t palnum, flags;
|
||||
|
@ -257,23 +257,24 @@ struct RawCacheNode
|
|||
|
||||
struct TileDesc
|
||||
{
|
||||
FTexture* texture; // the currently active tile
|
||||
FTexture* backup; // original backup for map tiles
|
||||
FGameTexture* texture; // the currently active tile
|
||||
FGameTexture* backup; // original backup for map tiles
|
||||
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
|
||||
picanm_t picanm; // animation descriptor
|
||||
picanm_t picanmbackup; // animation descriptor backup when using map tiles
|
||||
rottile_t RotTile;// = { -1,-1 };
|
||||
TArray<HightileReplacement> Hightiles;
|
||||
ReplacementType replacement;
|
||||
FixedBitArray<256> NoBrightmapFlag;
|
||||
};
|
||||
|
||||
struct BuildTiles
|
||||
{
|
||||
FTexture* Placeholder;
|
||||
FGameTexture* Placeholder;
|
||||
TDeletingArray<BuildArtFile*> ArtFiles;
|
||||
TileDesc tiledata[MAXTILES];
|
||||
TArray<FString> addedArt;
|
||||
TMap<FTexture*, int> TextureToTile;
|
||||
TMap<FGameTexture*, int> TextureToTile;
|
||||
TArray<FString> maptilesadded;
|
||||
|
||||
void Init(); // This cannot be a constructor because it needs the texture manager running.
|
||||
|
@ -284,7 +285,7 @@ struct BuildTiles
|
|||
|
||||
void CloseAll();
|
||||
|
||||
void AddTile(int tilenum, FTexture* tex, bool permap = false);
|
||||
void AddTile(int tilenum, FGameTexture* tex, bool permap = false);
|
||||
|
||||
void AddTiles(int firsttile, TArray<uint8_t>& store, const char* mapname);
|
||||
|
||||
|
@ -302,7 +303,7 @@ struct BuildTiles
|
|||
{
|
||||
addedArt = std::move(art);
|
||||
}
|
||||
int GetTileIndex(FTexture* tex)
|
||||
int GetTileIndex(FGameTexture* tex)
|
||||
{
|
||||
auto p = TextureToTile.CheckKey(tex);
|
||||
return p ? *p : -1;
|
||||
|
@ -317,14 +318,12 @@ struct BuildTiles
|
|||
}
|
||||
|
||||
}
|
||||
FTexture* ValidateCustomTile(int tilenum, ReplacementType type);
|
||||
FGameTexture* ValidateCustomTile(int tilenum, ReplacementType type);
|
||||
int32_t artLoadFiles(const char* filename);
|
||||
uint8_t* tileMakeWritable(int num);
|
||||
uint8_t* tileCreate(int tilenum, int width, int height);
|
||||
void tileSetExternal(int tilenum, int width, int height, uint8_t* data);
|
||||
int findUnusedTile(void);
|
||||
int tileCreateRotated(int owner);
|
||||
void ClearTextureCache(bool artonly = false);
|
||||
void InvalidateTile(int num);
|
||||
void MakeCanvas(int tilenum, int width, int height);
|
||||
HightileReplacement* FindReplacement(int picnum, int palnum, bool skybox = false);
|
||||
|
@ -367,7 +366,7 @@ inline const uint8_t* tilePtr(int num)
|
|||
{
|
||||
auto tex = TileFiles.tiledata[num].texture;
|
||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return nullptr;
|
||||
TileFiles.tiledata[num].rawCache.data = std::move(tex->Get8BitPixels(false));
|
||||
TileFiles.tiledata[num].rawCache.data = std::move(tex->GetTexture()->Get8BitPixels(false));
|
||||
}
|
||||
TileFiles.tiledata[num].rawCache.lastUseTime = I_nsTime();
|
||||
return TileFiles.tiledata[num].rawCache.data.Data();
|
||||
|
@ -381,7 +380,7 @@ inline bool tileLoad(int tileNum)
|
|||
inline uint8_t* tileData(int num)
|
||||
{
|
||||
auto tex = TileFiles.tiledata[num].texture;
|
||||
auto p = dynamic_cast<FWritableTile*>(tex);
|
||||
auto p = dynamic_cast<FWritableTile*>(tex->GetTexture());
|
||||
return p ? p->GetRawData() : nullptr;
|
||||
}
|
||||
|
||||
|
@ -464,7 +463,7 @@ inline void tileInvalidate(int tilenume, int32_t, int32_t)
|
|||
TileFiles.InvalidateTile(tilenume);
|
||||
}
|
||||
|
||||
inline FTexture* tileGetTexture(int tile)
|
||||
inline FGameTexture* tileGetTexture(int tile)
|
||||
{
|
||||
assert(tile < MAXTILES);
|
||||
return TileFiles.tiledata[tile].texture;
|
||||
|
|
|
@ -66,11 +66,11 @@ void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex)
|
||||
FHardwareTexture* GLInstance::CreateIndexedTexture(FGameTexture* tex)
|
||||
{
|
||||
vec2_t siz = { tex->GetTexelWidth(), tex->GetTexelHeight() };
|
||||
|
||||
auto store = tex->Get8BitPixels(false);
|
||||
auto store = tex->GetTexture()->Get8BitPixels(false);
|
||||
const uint8_t* p = store.Data();
|
||||
|
||||
auto glpic = GLInterface.NewTexture();
|
||||
|
@ -88,9 +88,9 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit)
|
||||
FHardwareTexture* GLInstance::CreateTrueColorTexture(FGameTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit)
|
||||
{
|
||||
auto texbuffer = tex->CreateTexBuffer(palid, checkfulltransparency? 0: CTF_ProcessData);
|
||||
auto texbuffer = tex->GetTexture()->CreateTexBuffer(palid, checkfulltransparency? 0: CTF_ProcessData);
|
||||
// Check if the texture is fully transparent. When creating a brightmap such textures can be discarded.
|
||||
if (checkfulltransparency)
|
||||
{
|
||||
|
@ -122,21 +122,21 @@ FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, b
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
||||
FHardwareTexture* GLInstance::LoadTexture(FGameTexture* tex, int textype, int palid)
|
||||
{
|
||||
if (textype == TT_INDEXED) palid = -1;
|
||||
auto phwtex = tex->SystemTextures.GetHardwareTexture(palid, false);
|
||||
auto phwtex = tex->GetTexture()->SystemTextures.GetHardwareTexture(palid, false);
|
||||
if (phwtex) return (FHardwareTexture*)phwtex;
|
||||
|
||||
FHardwareTexture *hwtex = nullptr;
|
||||
if (textype == TT_INDEXED)
|
||||
hwtex = CreateIndexedTexture(tex);
|
||||
else if (tex->GetUseType() != ETextureType::Canvas)
|
||||
else if (!tex->GetTexture()->isHardwareCanvas())
|
||||
hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP);
|
||||
else
|
||||
hwtex = nullptr;
|
||||
|
||||
if (hwtex) tex->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
||||
if (hwtex) tex->GetTexture()->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
||||
return hwtex;
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
|||
|
||||
struct TexturePick
|
||||
{
|
||||
FTexture* texture; // which texture to use
|
||||
FGameTexture* texture; // which texture to use
|
||||
int translation; // which translation table to use
|
||||
int tintFlags; // which shader tinting options to use
|
||||
PalEntry tintColor; // Tint color
|
||||
|
@ -165,7 +165,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
|
|||
auto tex = TileFiles.tiles[tilenum];
|
||||
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? TileFiles.FindReplacement(tilenum, usepalswap) : nullptr;
|
||||
// Canvas textures must be treated like hightile replacements in the following code.
|
||||
bool truecolor = rep || tex->GetUseType() == FTexture::Canvas;
|
||||
bool truecolor = rep || tex->GetUseType() == FGameTexture::Canvas;
|
||||
bool applytint = false;
|
||||
if (truecolor)
|
||||
{
|
||||
|
@ -203,7 +203,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow)
|
||||
bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int palette, int method, int sampleroverride, FGameTexture *det, float detscale, FGameTexture *glow)
|
||||
{
|
||||
if (tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
|
||||
int usepalette = fixpalette >= 0 ? fixpalette : curbasepal;
|
||||
|
@ -225,7 +225,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
// Canvas textures must be treated like hightile replacements in the following code.
|
||||
if (picnum < 0) picnum = TileFiles.GetTileIndex(tex); // Allow getting replacements also when the texture is not passed by its tile number.
|
||||
auto rep = (picnum >= 0 && hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? TileFiles.FindReplacement(picnum, palette) : nullptr;
|
||||
if (rep || tex->GetUseType() == ETextureType::Canvas)
|
||||
if (rep || tex->GetTexture()->isHardwareCanvas())
|
||||
{
|
||||
if (usepalette != 0)
|
||||
{
|
||||
|
@ -338,7 +338,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
}
|
||||
}
|
||||
#if 1
|
||||
if (picnum > -1 && !(TileFiles.tiledata[picnum].picanm.sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT) && !tex->NoBrightmapFlag[usepalswap])
|
||||
if (picnum > -1 && !(TileFiles.tiledata[picnum].picanm.sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT) && !TileFiles.tiledata[picnum].NoBrightmapFlag[usepalswap])
|
||||
{
|
||||
if (TextureType == TT_HICREPLACE)
|
||||
{
|
||||
|
@ -364,7 +364,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
if (htex == nullptr)
|
||||
{
|
||||
// Flag the texture as not being brightmapped for the given palette
|
||||
tex->NoBrightmapFlag.Set(usepalswap);
|
||||
TileFiles.tiledata[picnum].NoBrightmapFlag.Set(usepalswap);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -400,7 +400,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool GLInstance::SetNamedTexture(FTexture* tex, int palette, int sampler)
|
||||
bool GLInstance::SetNamedTexture(FGameTexture* tex, int palette, int sampler)
|
||||
{
|
||||
auto mtex = LoadTexture(tex, palette>= 0? TT_TRUECOLOR : TT_HICREPLACE, palette);
|
||||
if (!mtex) return false;
|
||||
|
@ -417,11 +417,6 @@ int PalCheck(int tex)
|
|||
return tex;
|
||||
}
|
||||
|
||||
void DeleteSoftwareTexture(FSoftwareTexture *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InitBuildTiles()
|
||||
{
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class FSamplerManager;
|
|||
class FShader;
|
||||
class PolymostShader;
|
||||
class SurfaceShader;
|
||||
class FTexture;
|
||||
class FGameTexture;
|
||||
class GLInstance;
|
||||
class F2DDrawer;
|
||||
struct palette_t;
|
||||
|
@ -115,7 +115,7 @@ class GLInstance
|
|||
PaletteManager palmanager;
|
||||
int lastPalswapIndex = -1;
|
||||
FHardwareTexture* texv;
|
||||
FTexture* currentTexture = nullptr;
|
||||
FGameTexture* currentTexture = nullptr;
|
||||
int TextureType;
|
||||
int MatrixChange = 0;
|
||||
|
||||
|
@ -474,19 +474,19 @@ public:
|
|||
renderState.AlphaThreshold = al;
|
||||
}
|
||||
|
||||
FHardwareTexture* CreateIndexedTexture(FTexture* tex);
|
||||
FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
||||
FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
|
||||
bool SetTextureInternal(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow);
|
||||
FHardwareTexture* CreateIndexedTexture(FGameTexture* tex);
|
||||
FHardwareTexture* CreateTrueColorTexture(FGameTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
||||
FHardwareTexture *LoadTexture(FGameTexture* tex, int texturetype, int palid);
|
||||
bool SetTextureInternal(int globalpicnum, FGameTexture* tex, int palette, int method, int sampleroverride, FGameTexture *det, float detscale, FGameTexture *glow);
|
||||
|
||||
bool SetNamedTexture(FTexture* tex, int palette, int sampleroverride);
|
||||
bool SetNamedTexture(FGameTexture* tex, int palette, int sampleroverride);
|
||||
|
||||
bool SetTexture(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride)
|
||||
bool SetTexture(int globalpicnum, FGameTexture* tex, int palette, int method, int sampleroverride)
|
||||
{
|
||||
return SetTextureInternal(globalpicnum, tex, palette, method, sampleroverride, nullptr, 1, nullptr);
|
||||
}
|
||||
|
||||
bool SetModelTexture(FTexture *tex, int palette, FTexture *det, float detscale, FTexture *glow)
|
||||
bool SetModelTexture(FGameTexture *tex, int palette, FGameTexture *det, float detscale, FGameTexture *glow)
|
||||
{
|
||||
return SetTextureInternal(-1, tex, palette, 8/*DAMETH_MODEL*/, -1, det, detscale, glow);
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ TArray<FString> I_GetGogPaths();
|
|||
// The ini could not be saved at exit
|
||||
bool I_WriteIniFailed ();
|
||||
|
||||
class FTexture;
|
||||
bool I_SetCursor(FTexture *);
|
||||
class FGameTexture;
|
||||
bool I_SetCursor(FGameTexture *);
|
||||
|
||||
static inline char *strlwr(char *str)
|
||||
{
|
||||
|
|
|
@ -38,14 +38,14 @@
|
|||
#include "bitmap.h"
|
||||
#include "textures.h"
|
||||
|
||||
bool I_SetCursor(FTexture *cursorpic)
|
||||
bool I_SetCursor(FGameTexture *cursorpic)
|
||||
{
|
||||
static SDL_Cursor *cursor;
|
||||
static SDL_Surface *cursorSurface;
|
||||
|
||||
if (cursorpic != NULL)
|
||||
{
|
||||
auto src = cursorpic->GetBgraBitmap(nullptr);
|
||||
auto src = cursorpic->GetTexture()->GetBgraBitmap(nullptr);
|
||||
// Must be no larger than 32x32.
|
||||
if (src.GetWidth() > 32 || src.GetHeight() > 32)
|
||||
{
|
||||
|
|
|
@ -646,13 +646,13 @@ int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool I_SetCursor(FTexture *cursorpic)
|
||||
bool I_SetCursor(FGameTexture *cursorpic)
|
||||
{
|
||||
HCURSOR cursor;
|
||||
|
||||
if (cursorpic != NULL)
|
||||
{
|
||||
auto image = cursorpic->GetBgraBitmap(nullptr);
|
||||
auto image = cursorpic->GetTexture()->GetBgraBitmap(nullptr);
|
||||
// Must be no larger than 32x32. (is this still necessary?
|
||||
if (image.GetWidth() > 32 || image.GetHeight() > 32)
|
||||
{
|
||||
|
|
|
@ -62,8 +62,8 @@ void I_Quit (void);
|
|||
void I_Tactile (int on, int off, int total);
|
||||
|
||||
// Set the mouse cursor. The texture must be 32x32.
|
||||
class FTexture;
|
||||
bool I_SetCursor(FTexture *cursor);
|
||||
class FGameTexture;
|
||||
bool I_SetCursor(FGameTexture *cursor);
|
||||
|
||||
// Repaint the pre-game console
|
||||
void I_PaintConsole (void);
|
||||
|
|
Loading…
Reference in a new issue