mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +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/bitmap.cpp
|
||||||
common/textures/m_png.cpp
|
common/textures/m_png.cpp
|
||||||
common/textures/texture.cpp
|
common/textures/texture.cpp
|
||||||
|
common/textures/gametexture.cpp
|
||||||
common/textures/image.cpp
|
common/textures/image.cpp
|
||||||
common/textures/imagetexture.cpp
|
common/textures/imagetexture.cpp
|
||||||
common/textures/texturemanager.cpp
|
common/textures/texturemanager.cpp
|
||||||
|
@ -1018,6 +1019,7 @@ include_directories(
|
||||||
common/textures
|
common/textures
|
||||||
common/textures/formats
|
common/textures/formats
|
||||||
common/textures/hires
|
common/textures/hires
|
||||||
|
common/textures
|
||||||
common/filesystem
|
common/filesystem
|
||||||
common/utility
|
common/utility
|
||||||
common/console
|
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 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,
|
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,
|
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 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, palette_t p);
|
||||||
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry 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 //////////
|
////////// 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,
|
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,
|
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);
|
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:
|
// 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,
|
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);
|
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 IDP2_MAGIC 0x32504449
|
||||||
#define IDP3_MAGIC 0x33504449
|
#define IDP3_MAGIC 0x33504449
|
||||||
|
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
class FHardwareTexture;
|
class FHardwareTexture;
|
||||||
|
|
||||||
struct mdmodel_t
|
struct mdmodel_t
|
||||||
{
|
{
|
||||||
int32_t mdnum, shadeoff;
|
int32_t mdnum, shadeoff;
|
||||||
float scale, bscale, zadd, yoffset;
|
float scale, bscale, zadd, yoffset;
|
||||||
FTexture *texture;
|
FGameTexture *texture;
|
||||||
|
|
||||||
int32_t flags;
|
int32_t flags;
|
||||||
};
|
};
|
||||||
|
@ -200,7 +200,7 @@ struct voxmodel_t : public mdmodel_t
|
||||||
|
|
||||||
EXTERN mdmodel_t **models;
|
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 mdinit(void);
|
||||||
void freeallmodels(void);
|
void freeallmodels(void);
|
||||||
int32_t polymost_mddraw(tspriteptr_t tspr);
|
int32_t polymost_mddraw(tspriteptr_t tspr);
|
||||||
|
|
|
@ -50,7 +50,7 @@ void VPXTexture::SetFrame(const void *data_, int width, int height)
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
data = data_;
|
data = data_;
|
||||||
SystemTextures.Clean(true, true);
|
SystemTextures.Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -412,27 +412,27 @@ read_ivf_frame:
|
||||||
|
|
||||||
/////////////// DRAWING! ///////////////
|
/////////////// DRAWING! ///////////////
|
||||||
static int sampler;
|
static int sampler;
|
||||||
static VPXTexture* vpxtex[2];
|
static FGameTexture* vpxtex[2];
|
||||||
static int which;
|
static int which;
|
||||||
|
|
||||||
void animvpx_setup_glstate(int32_t animvpx_flags)
|
void animvpx_setup_glstate(int32_t animvpx_flags)
|
||||||
{
|
{
|
||||||
////////// GL STATE //////////
|
////////// GL STATE //////////
|
||||||
vpxtex[0] = new VPXTexture;
|
vpxtex[0] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special);
|
||||||
vpxtex[1] = new VPXTexture;
|
vpxtex[1] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special);
|
||||||
|
|
||||||
if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && hw_texfilter == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER ||
|
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
|
else
|
||||||
{
|
{
|
||||||
sampler = SamplerNoFilterClampXY;
|
sampler = CLAMP_XY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLInterface.ClearScreen(0, true);
|
GLInterface.ClearScreen(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animvpx_restore_glstate(void)
|
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
|
return 2; // shouldn't happen
|
||||||
|
|
||||||
which ^= 1;
|
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;
|
float vid_wbyh = ((float)codec->width)/codec->height;
|
||||||
if (animvpx_aspect > 0)
|
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,
|
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,
|
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 = {};
|
F2DDrawer::RenderCommand dg = {};
|
||||||
int method = 0;
|
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);
|
int light = clamp(scale((numshades - dashade), 255, numshades), 0, 255);
|
||||||
auto p = PalEntry((uint8_t)(alpha * 255), light, light, light);
|
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 };
|
vec2_16_t ofs = { 0, 0 };
|
||||||
|
|
||||||
if (!(dastat & RS_TOPLEFT))
|
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,
|
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,
|
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)
|
if (!tex && (unsigned)picnum >= MAXTILES)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -463,7 +463,7 @@ int32_t md_undefinemodel(int32_t modelid)
|
||||||
|
|
||||||
|
|
||||||
//Note: even though it says md2model, it works for both md2model&md3model
|
//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;
|
int32_t i;
|
||||||
mdskinmap_t *sk, *skzero = NULL;
|
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;
|
if (exact) *exact = true;
|
||||||
//Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile);
|
//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)
|
//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; }
|
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);
|
//Printf("Using def skin 0,0 as fallback, pal=%d\n", pal);
|
||||||
if (exact) *exact = false;
|
if (exact) *exact = false;
|
||||||
return TexMan.GetTexture(skzero->texture);
|
return TexMan.GetGameTexture(skzero->texture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1711,7 +1711,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
|
||||||
if (!tex)
|
if (!tex)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FTexture *det = nullptr, *glow = nullptr;
|
FGameTexture *det = nullptr, *glow = nullptr;
|
||||||
float detscale = 1.f;
|
float detscale = 1.f;
|
||||||
|
|
||||||
// The data lookup here is one incredible mess. Thanks to whoever cooked this up... :(
|
// 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];
|
float const r = 1.f / dd[i];
|
||||||
|
|
||||||
if (tileGetTexture(globalpicnum)->isCanvas())
|
if (tileGetTexture(globalpicnum)->GetTexture()->isHardwareCanvas())
|
||||||
{
|
{
|
||||||
//update texcoords, canvas textures are upside down!
|
//update texcoords, canvas textures are upside down!
|
||||||
vt->SetTexCoord(
|
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;
|
FRenderStyle style = parms.style;
|
||||||
float alpha;
|
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.
|
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
|
// [MK] bail out if vertex/coord array sizes are mismatched
|
||||||
if ( shape->mVertices.Size() != shape->mCoords.Size() )
|
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,
|
double originx, double originy, double scalex, double scaley,
|
||||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double fadelevel,
|
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double fadelevel,
|
||||||
uint32_t *indices, size_t indexcount)
|
uint32_t *indices, size_t indexcount)
|
||||||
{
|
{
|
||||||
|
|
||||||
RenderCommand poly;
|
RenderCommand poly;
|
||||||
|
|
||||||
poly.mType = DrawTypeTriangles;
|
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 = {};
|
RenderCommand dg = {};
|
||||||
int method = 0;
|
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;
|
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.
|
// scaling is not used here.
|
||||||
if (!local_origin)
|
if (!local_origin)
|
||||||
{
|
{
|
||||||
fU1 = float(left) / src->GetDisplayWidth();
|
fU1 = float(left) / (float)src->GetDisplayWidth();
|
||||||
fV1 = float(top) / src->GetDisplayHeight();
|
fV1 = float(top) / (float)src->GetDisplayHeight();
|
||||||
fU2 = float(right) / src->GetDisplayWidth();
|
fU2 = float(right) / (float)src->GetDisplayWidth();
|
||||||
fV2 = float(bottom) / src->GetDisplayHeight();
|
fV2 = float(bottom) / (float)src->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fU1 = 0;
|
fU1 = 0;
|
||||||
fV1 = 0;
|
fV1 = 0;
|
||||||
fU2 = float(right - left) / src->GetDisplayWidth();
|
fU2 = float(right - left) / (float)src->GetDisplayWidth();
|
||||||
fV2 = float(bottom - top) / src->GetDisplayHeight();
|
fV2 = float(bottom - top) / (float)src->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||||
auto ptr = &mVertices[dg.mVertIndex];
|
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;
|
PalEntry p = (PalEntry)color;
|
||||||
p.a = alpha;
|
p.a = alpha;
|
||||||
|
|
|
@ -124,7 +124,7 @@ public:
|
||||||
int mIndexIndex;
|
int mIndexIndex;
|
||||||
int mIndexCount;
|
int mIndexCount;
|
||||||
|
|
||||||
FTexture *mTexture;
|
FGameTexture *mTexture;
|
||||||
int mTranslationId;
|
int mTranslationId;
|
||||||
PalEntry mSpecialColormap[2];
|
PalEntry mSpecialColormap[2];
|
||||||
int mScissor[4];
|
int mScissor[4];
|
||||||
|
@ -170,19 +170,19 @@ public:
|
||||||
void AddIndices(int firstvert, int count, ...);
|
void AddIndices(int firstvert, int count, ...);
|
||||||
private:
|
private:
|
||||||
void AddIndices(int firstvert, TArray<int> &v);
|
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);
|
void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void AddTexture(FTexture *img, DrawParms &parms);
|
void AddTexture(FGameTexture* img, DrawParms& parms);
|
||||||
void AddShape(FTexture *img, DShape2D *shape, DrawParms &parms);
|
void AddShape(FGameTexture *img, DShape2D *shape, DrawParms &parms);
|
||||||
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
void AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
|
||||||
double originx, double originy, double scalex, double scaley,
|
double originx, double originy, double scalex, double scaley,
|
||||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double lightlevel, uint32_t *indices, size_t indexcount);
|
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,
|
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);
|
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 AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr);
|
||||||
void ClearScreen(PalEntry color = 0xff000000);
|
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 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 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);
|
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_List tags;
|
||||||
va_start(tags.list, tags_first);
|
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);
|
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;
|
DrawParms parms;
|
||||||
uint32_t tag = ListGetInt(args);
|
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");
|
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 };
|
VMVa_List args = { param + 4, 0, numparam - 5, va_reginfo + 4 };
|
||||||
DrawTexture(twod, tex, x, y, args);
|
DrawTexture(twod, tex, x, y, args);
|
||||||
return 0;
|
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_List tags;
|
||||||
va_start(tags.list, tags_first);
|
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);
|
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;
|
DrawParms parms;
|
||||||
uint32_t tag = ListGetInt(args);
|
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");
|
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 };
|
VMVa_List args = { param + 3, 0, numparam - 4, va_reginfo + 3 };
|
||||||
|
|
||||||
DrawShape(twod, tex, shape, args);
|
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 GetWidth = [=]() { return drawer->GetWidth(); };
|
||||||
auto GetHeight = [=]() {return drawer->GetHeight(); };
|
auto GetHeight = [=]() {return drawer->GetHeight(); };
|
||||||
|
@ -342,8 +342,8 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
||||||
{
|
{
|
||||||
parms->x = xx;
|
parms->x = xx;
|
||||||
parms->y = yy;
|
parms->y = yy;
|
||||||
parms->texwidth = img->GetDisplayWidthDouble();
|
parms->texwidth = img->GetDisplayWidth();
|
||||||
parms->texheight = img->GetDisplayHeightDouble();
|
parms->texheight = img->GetDisplayHeight();
|
||||||
if (parms->top == INT_MAX || parms->fortext)
|
if (parms->top == INT_MAX || parms->fortext)
|
||||||
{
|
{
|
||||||
parms->top = img->GetDisplayTopOffset();
|
parms->top = img->GetDisplayTopOffset();
|
||||||
|
@ -354,11 +354,11 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
||||||
}
|
}
|
||||||
if (parms->destwidth == INT_MAX || parms->fortext)
|
if (parms->destwidth == INT_MAX || parms->fortext)
|
||||||
{
|
{
|
||||||
parms->destwidth = img->GetDisplayWidthDouble();
|
parms->destwidth = img->GetDisplayWidth();
|
||||||
}
|
}
|
||||||
if (parms->destheight == INT_MAX || parms->fortext)
|
if (parms->destheight == INT_MAX || parms->fortext)
|
||||||
{
|
{
|
||||||
parms->destheight = img->GetDisplayHeightDouble();
|
parms->destheight = img->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (parms->cleanmode)
|
switch (parms->cleanmode)
|
||||||
|
@ -387,10 +387,12 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FTexture *img, double
|
||||||
case DTA_FullscreenEx:
|
case DTA_FullscreenEx:
|
||||||
{
|
{
|
||||||
double aspect;
|
double aspect;
|
||||||
double srcwidth = img->GetDisplayWidthDouble();
|
double srcwidth = img->GetDisplayWidth();
|
||||||
double srcheight = img->GetDisplayHeightDouble();
|
double srcheight = img->GetDisplayHeight();
|
||||||
int autoaspect = parms->fsscalemode;
|
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->x = parms->y = 0;
|
||||||
parms->keepratio = true;
|
parms->keepratio = true;
|
||||||
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
|
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
|
||||||
|
@ -531,7 +533,7 @@ static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
template<class T>
|
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;
|
INTBOOL boolval;
|
||||||
int intval;
|
int intval;
|
||||||
|
@ -724,8 +726,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
if (img == NULL) return false;
|
if (img == NULL) return false;
|
||||||
parms->cleanmode = DTA_Fullscreen;
|
parms->cleanmode = DTA_Fullscreen;
|
||||||
parms->fsscalemode = (uint8_t)twod->fullscreenautoaspect;
|
parms->fsscalemode = (uint8_t)twod->fullscreenautoaspect;
|
||||||
parms->virtWidth = img->GetDisplayWidthDouble();
|
parms->virtWidth = img->GetDisplayWidth();
|
||||||
parms->virtHeight = img->GetDisplayHeightDouble();
|
parms->virtHeight = img->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -738,8 +740,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
if (img == NULL) return false;
|
if (img == NULL) return false;
|
||||||
parms->cleanmode = DTA_Fullscreen;
|
parms->cleanmode = DTA_Fullscreen;
|
||||||
parms->fsscalemode = (uint8_t)intval;
|
parms->fsscalemode = (uint8_t)intval;
|
||||||
parms->virtWidth = img->GetDisplayWidthDouble();
|
parms->virtWidth = img->GetDisplayWidth();
|
||||||
parms->virtHeight = img->GetDisplayHeightDouble();
|
parms->virtHeight = img->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -785,19 +787,19 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_SrcX:
|
case DTA_SrcX:
|
||||||
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidthDouble();
|
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidth();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_SrcY:
|
case DTA_SrcY:
|
||||||
parms->srcy = ListGetDouble(tags) / img->GetDisplayHeightDouble();
|
parms->srcy = ListGetDouble(tags) / img->GetDisplayHeight();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_SrcWidth:
|
case DTA_SrcWidth:
|
||||||
parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidthDouble();
|
parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidth();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_SrcHeight:
|
case DTA_SrcHeight:
|
||||||
parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeightDouble();
|
parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeight();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_TopOffset:
|
case DTA_TopOffset:
|
||||||
|
@ -829,8 +831,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
if (fortext) return false;
|
if (fortext) return false;
|
||||||
if (ListGetInt(tags))
|
if (ListGetInt(tags))
|
||||||
{
|
{
|
||||||
parms->left = img->GetDisplayWidthDouble() * 0.5;
|
parms->left = img->GetDisplayWidth() * 0.5;
|
||||||
parms->top = img->GetDisplayHeightDouble() * 0.5;
|
parms->top = img->GetDisplayHeight() * 0.5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -839,8 +841,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
if (fortext) return false;
|
if (fortext) return false;
|
||||||
if (ListGetInt(tags))
|
if (ListGetInt(tags))
|
||||||
{
|
{
|
||||||
parms->left = img->GetDisplayWidthDouble() * 0.5;
|
parms->left = img->GetDisplayWidth() * 0.5;
|
||||||
parms->top = img->GetDisplayHeightDouble();
|
parms->top = img->GetDisplayHeight();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1038,8 +1040,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture *img, double x, double y,
|
||||||
}
|
}
|
||||||
// explicitly instantiate both versions for v_text.cpp.
|
// 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<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, FTexture *img, double x, double y, uint32_t tag, VMVa_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 Width = drawer->GetWidth();
|
||||||
auto Height = drawer->GetHeight();
|
auto Height = drawer->GetHeight();
|
||||||
|
@ -1351,7 +1353,7 @@ void DrawBorder (F2DDrawer *drawer, FTextureID picnum, int x1, int y1, int x2, i
|
||||||
{
|
{
|
||||||
if (picnum.isValid())
|
if (picnum.isValid())
|
||||||
{
|
{
|
||||||
drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetTexture(picnum, false));
|
drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(picnum, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,20 +203,21 @@ inline int active_con_scale(F2DDrawer *drawer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class T>
|
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>
|
template<class T>
|
||||||
void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms);
|
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 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 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 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 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 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 DrawFrame(F2DDrawer* drawer, int left, int top, int width, int height);
|
||||||
void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2);
|
void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2);
|
||||||
|
|
|
@ -53,7 +53,7 @@ int ListGetInt(VMVa_List &tags);
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
#if 0
|
#if 0
|
||||||
FTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
FGameTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
const uint8_t *ch;
|
const uint8_t *ch;
|
||||||
|
@ -61,7 +61,7 @@ FTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
|
||||||
int cy;
|
int cy;
|
||||||
int trans = -1;
|
int trans = -1;
|
||||||
int kerning;
|
int kerning;
|
||||||
FTexture *pic;
|
FGameTexture *pic;
|
||||||
|
|
||||||
kerning = font->GetDefaultKerning();
|
kerning = font->GetDefaultKerning();
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ void DrawChar(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double
|
||||||
if (normalcolor >= NumTextColors)
|
if (normalcolor >= NumTextColors)
|
||||||
normalcolor = CR_UNTRANSLATED;
|
normalcolor = CR_UNTRANSLATED;
|
||||||
|
|
||||||
FTexture* pic;
|
FGameTexture* pic;
|
||||||
int dummy;
|
int dummy;
|
||||||
bool redirected;
|
bool redirected;
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ void DrawChar(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double
|
||||||
if (normalcolor >= NumTextColors)
|
if (normalcolor >= NumTextColors)
|
||||||
normalcolor = CR_UNTRANSLATED;
|
normalcolor = CR_UNTRANSLATED;
|
||||||
|
|
||||||
FTexture *pic;
|
FGameTexture *pic;
|
||||||
int dummy;
|
int dummy;
|
||||||
bool redirected;
|
bool redirected;
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
|
||||||
int boldcolor;
|
int boldcolor;
|
||||||
int trans = -1;
|
int trans = -1;
|
||||||
int kerning;
|
int kerning;
|
||||||
FTexture *pic;
|
FGameTexture *pic;
|
||||||
|
|
||||||
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
|
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
|
||||||
parms.celly *= parms.scaley;
|
parms.celly *= parms.scaley;
|
||||||
|
|
|
@ -1082,16 +1082,17 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
||||||
}
|
}
|
||||||
FTextureID chk = value;
|
FTextureID chk = value;
|
||||||
if (chk.GetIndex() >= TexMan.NumTextures()) chk.SetNull();
|
if (chk.GetIndex() >= TexMan.NumTextures()) chk.SetNull();
|
||||||
FTexture *pic = TexMan.GetTexture(chk);
|
auto pic = TexMan.GetGameTexture(chk);
|
||||||
const char *name;
|
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
|
else
|
||||||
{
|
{
|
||||||
name = pic->Name;
|
name = pic->GetName();
|
||||||
}
|
}
|
||||||
arc.WriteKey(key);
|
arc.WriteKey(key);
|
||||||
arc.w->StartArray();
|
arc.w->StartArray();
|
||||||
|
|
|
@ -57,7 +57,7 @@ extern FILE* hashfile;
|
||||||
struct FileSystem::LumpRecord
|
struct FileSystem::LumpRecord
|
||||||
{
|
{
|
||||||
FResourceLump *lump;
|
FResourceLump *lump;
|
||||||
FTexture* linkedTexture;
|
FGameTexture* linkedTexture;
|
||||||
LumpShortName shortName;
|
LumpShortName shortName;
|
||||||
FString longName;
|
FString longName;
|
||||||
int rfnum;
|
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)
|
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)
|
if ((size_t)lump < NumEntries)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class FResourceFile;
|
class FResourceFile;
|
||||||
struct FResourceLump;
|
struct FResourceLump;
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
|
|
||||||
union LumpShortName
|
union LumpShortName
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ public:
|
||||||
~FileData ();
|
~FileData ();
|
||||||
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
|
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
|
||||||
size_t GetSize () { return Block.Len(); }
|
size_t GetSize () { return Block.Len(); }
|
||||||
FString GetString () { return Block; }
|
const FString &GetString () const { return Block; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileData (const FString &source);
|
FileData (const FString &source);
|
||||||
|
@ -124,8 +124,8 @@ public:
|
||||||
inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); }
|
inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); }
|
||||||
inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); }
|
inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); }
|
||||||
|
|
||||||
void SetLinkedTexture(int lump, FTexture *tex);
|
void SetLinkedTexture(int lump, FGameTexture *tex);
|
||||||
FTexture *GetLinkedTexture(int lump);
|
FGameTexture *GetLinkedTexture(int lump);
|
||||||
|
|
||||||
|
|
||||||
void ReadFile (int lump, void *dest);
|
void ReadFile (int lump, void *dest);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#ifndef __RESFILE_H
|
#ifndef __RESFILE_H
|
||||||
#define __RESFILE_H
|
#define __RESFILE_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
struct LumpFilterInfo
|
struct LumpFilterInfo
|
||||||
|
@ -17,7 +19,6 @@ struct LumpFilterInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
class FResourceFile;
|
class FResourceFile;
|
||||||
class FTexture;
|
|
||||||
|
|
||||||
// [RH] Namespaces from BOOM.
|
// [RH] Namespaces from BOOM.
|
||||||
// These are needed here in the low level part so that WAD files can be properly set up.
|
// 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;
|
int i;
|
||||||
FTextureID lump;
|
FTextureID lump;
|
||||||
char buffer[12];
|
char buffer[12];
|
||||||
int maxyoffs;
|
|
||||||
DVector2 Scale = { 1, 1 };
|
DVector2 Scale = { 1, 1 };
|
||||||
|
|
||||||
noTranslate = notranslate;
|
noTranslate = notranslate;
|
||||||
|
@ -91,9 +90,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
||||||
translateUntranslated = false;
|
translateUntranslated = false;
|
||||||
int FixedWidth = 0;
|
int FixedWidth = 0;
|
||||||
|
|
||||||
maxyoffs = 0;
|
TMap<int, FGameTexture*> charMap;
|
||||||
|
|
||||||
TMap<int, FTexture*> charMap;
|
|
||||||
int minchar = INT_MAX;
|
int minchar = INT_MAX;
|
||||||
int maxchar = INT_MIN;
|
int maxchar = INT_MIN;
|
||||||
|
|
||||||
|
@ -231,13 +228,13 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
||||||
Type = Multilump;
|
Type = Multilump;
|
||||||
if (position < minchar) minchar = position;
|
if (position < minchar) minchar = position;
|
||||||
if (position > maxchar) maxchar = position;
|
if (position > maxchar) maxchar = position;
|
||||||
charMap.Insert(position, TexMan.GetTexture(lump));
|
charMap.Insert(position, TexMan.GetGameTexture(lump));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FTexture *texs[256] = {};
|
FGameTexture *texs[256] = {};
|
||||||
if (lcount > 256 - start) lcount = 256 - start;
|
if (lcount > 256 - start) lcount = 256 - start;
|
||||||
for (i = 0; i < lcount; i++)
|
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);
|
TexMan.ListTextures(buffer, array, true);
|
||||||
for (auto entry : array)
|
for (auto entry : array)
|
||||||
{
|
{
|
||||||
FTexture *tex = TexMan.GetTexture(entry, false);
|
auto tex = TexMan.GetGameTexture(entry, false);
|
||||||
if (tex && tex->GetSourceLump() >= 0 && fileSystem.GetFileContainer(tex->GetSourceLump()) <= fileSystem.GetMaxIwadNum() && tex->GetUseType() == ETextureType::MiscPatch)
|
if (tex && !tex->isUserContent() && tex->GetUseType() == ETextureType::MiscPatch)
|
||||||
{
|
{
|
||||||
texs[i] = tex;
|
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 < minchar) minchar = (int)position;
|
||||||
if ((int)position > maxchar) maxchar = (int)position;
|
if ((int)position > maxchar) maxchar = (int)position;
|
||||||
auto tex = TexMan.GetTexture(lump);
|
auto tex = TexMan.GetGameTexture(lump);
|
||||||
tex->SetScale(Scale);
|
tex->SetScale((float)Scale.X, (float)Scale.Y);
|
||||||
charMap.Insert((int)position, tex);
|
charMap.Insert((int)position, tex);
|
||||||
Type = Folder;
|
Type = Folder;
|
||||||
}
|
}
|
||||||
|
@ -312,17 +309,13 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
||||||
auto lump = charMap.CheckKey(FirstChar + i);
|
auto lump = charMap.CheckKey(FirstChar + i);
|
||||||
if (lump != nullptr)
|
if (lump != nullptr)
|
||||||
{
|
{
|
||||||
FTexture *pic = *lump;
|
auto pic = *lump;
|
||||||
if (pic != nullptr)
|
if (pic != nullptr)
|
||||||
{
|
{
|
||||||
int height = pic->GetDisplayHeight();
|
double fheight = pic->GetDisplayHeight();
|
||||||
int yoffs = pic->GetDisplayTopOffset();
|
double yoffs = pic->GetDisplayTopOffset();
|
||||||
|
|
||||||
if (yoffs > maxyoffs)
|
int height = int(fheight + abs(yoffs) + 0.5);
|
||||||
{
|
|
||||||
maxyoffs = yoffs;
|
|
||||||
}
|
|
||||||
height += abs(yoffs);
|
|
||||||
if (height > fontheight)
|
if (height > fontheight)
|
||||||
{
|
{
|
||||||
fontheight = height;
|
fontheight = height;
|
||||||
|
@ -333,24 +326,24 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
auto orig = pic->GetTexture();
|
||||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
auto tex = MakeGameTexture(orig, nullptr, ETextureType::FontChar);
|
||||||
Chars[i].OriginalPic->CopySize(pic);
|
tex->CopySize(pic);
|
||||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
TexMan.AddGameTexture(tex);
|
||||||
|
Chars[i].OriginalPic = tex;
|
||||||
|
|
||||||
if (!noTranslate)
|
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->CopySize(pic);
|
||||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
|
||||||
}
|
}
|
||||||
else
|
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
|
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)
|
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,
|
// 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);
|
TArray<TexPartBuild> part(1, true);
|
||||||
TMap<int, FTexture*> charMap;
|
TMap<int, FGameTexture*> charMap;
|
||||||
int minchar = INT_MAX;
|
int minchar = INT_MAX;
|
||||||
int maxchar = INT_MIN;
|
int maxchar = INT_MIN;
|
||||||
for (auto &entry : folderdata)
|
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);
|
auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch);
|
||||||
if (lump.isValid())
|
if (lump.isValid())
|
||||||
{
|
{
|
||||||
auto tex = TexMan.GetTexture(lump);
|
auto tex = TexMan.GetGameTexture(lump);
|
||||||
int numtex_x = tex->GetTexelWidth() / width;
|
int numtex_x = tex->GetTexelWidth() / width;
|
||||||
int numtex_y = tex->GetTexelHeight() / height;
|
int numtex_y = tex->GetTexelHeight() / height;
|
||||||
int maxinsheet = int(position) + numtex_x * numtex_y - 1;
|
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].OriginX = -width * x;
|
||||||
part[0].OriginY = -height * y;
|
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);
|
FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false);
|
||||||
FImageTexture *tex = new FImageTexture(image, "");
|
FImageTexture *tex = new FImageTexture(image);
|
||||||
tex->SetUseType(ETextureType::FontChar);
|
auto gtex = MakeGameTexture(tex, nullptr, ETextureType::FontChar);
|
||||||
tex->bMultiPatch = true;
|
gtex->SetWorldPanning(true);
|
||||||
tex->Width = width;
|
gtex->SetOffsets(0, 0, 0);
|
||||||
tex->Height = height;
|
gtex->SetOffsets(1, 0, 0);
|
||||||
tex->_LeftOffset[0] =
|
gtex->SetScale((float)Scale.X, (float)Scale.Y);
|
||||||
tex->_LeftOffset[1] =
|
TexMan.AddGameTexture(gtex);
|
||||||
tex->_TopOffset[0] =
|
charMap.Insert(int(position) + x + y * numtex_x, gtex);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,18 +442,18 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
||||||
auto lump = charMap.CheckKey(FirstChar + i);
|
auto lump = charMap.CheckKey(FirstChar + i);
|
||||||
if (lump != nullptr)
|
if (lump != nullptr)
|
||||||
{
|
{
|
||||||
FTexture *pic = *lump;
|
auto pic = (*lump)->GetTexture();
|
||||||
|
|
||||||
auto b = pic->Get8BitPixels(false);
|
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->SetUseType(ETextureType::FontChar);
|
||||||
Chars[i].OriginalPic->CopySize(pic);
|
Chars[i].OriginalPic->CopySize(*lump);
|
||||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1(pic->GetImage()), "");
|
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage())), nullptr, ETextureType::FontChar);
|
||||||
Chars[i].TranslatedPic->CopySize(pic);
|
Chars[i].TranslatedPic->CopySize(*lump);
|
||||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||||
}
|
}
|
||||||
Chars[i].XMove = width;
|
Chars[i].XMove = width;
|
||||||
}
|
}
|
||||||
|
@ -619,7 +603,7 @@ void FFont::RecordAllTextureColors(uint32_t *usedcolors)
|
||||||
{
|
{
|
||||||
if (Chars[i].TranslatedPic)
|
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)
|
if (pic)
|
||||||
{
|
{
|
||||||
// The remap must be temporarily reset here because this can be called on an initialized font.
|
// 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);
|
code = GetCharCode(code, true);
|
||||||
int xmove = SpaceWidth;
|
int xmove = SpaceWidth;
|
||||||
|
@ -1037,11 +1021,11 @@ int FFont::GetCharWidth (int code) const
|
||||||
double GetBottomAlignOffset(FFont *font, int c)
|
double GetBottomAlignOffset(FFont *font, int c)
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
FTexture *tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
|
auto tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
|
||||||
FTexture *texc = font->GetChar(c, CR_UNDEFINED, &w);
|
auto texc = font->GetChar(c, CR_UNDEFINED, &w);
|
||||||
double offset = 0;
|
double offset = 0;
|
||||||
if (texc) offset += texc->GetDisplayTopOffsetDouble();
|
if (texc) offset += texc->GetDisplayTopOffset();
|
||||||
if (tex_zero) offset += -tex_zero->GetDisplayTopOffsetDouble() + tex_zero->GetDisplayHeightDouble();
|
if (tex_zero) offset += -tex_zero->GetDisplayTopOffset() + tex_zero->GetDisplayHeight();
|
||||||
return offset;
|
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 w = 0;
|
||||||
int maxw = 0;
|
int maxw = 0;
|
||||||
|
@ -1123,13 +1107,17 @@ int FFont::StringWidth(const uint8_t *string) const
|
||||||
maxw = w;
|
maxw = w;
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
|
else if (spacing >= 0)
|
||||||
|
{
|
||||||
|
w += GetCharWidth(chr) + GlobalKerning + spacing;
|
||||||
|
}
|
||||||
else
|
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)
|
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)
|
if (pic)
|
||||||
{
|
{
|
||||||
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
|
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++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if(Chars[i].TranslatedPic)
|
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);
|
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr);
|
||||||
|
@ -1286,7 +1274,7 @@ void FFont::FixXMoves()
|
||||||
}
|
}
|
||||||
if (Chars[i].OriginalPic)
|
if (Chars[i].OriginalPic)
|
||||||
{
|
{
|
||||||
int ofs = Chars[i].OriginalPic->GetDisplayTopOffset();
|
int ofs = (int)Chars[i].OriginalPic->GetDisplayTopOffset();
|
||||||
if (ofs > Displacement) Displacement = ofs;
|
if (ofs > Displacement) Displacement = ofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,10 +289,9 @@ public:
|
||||||
{
|
{
|
||||||
auto offset = hexdata.glyphmap[i];
|
auto offset = hexdata.glyphmap[i];
|
||||||
int size = hexdata.glyphdata[offset] / 16;
|
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 = MakeGameTexture(new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16)), nullptr, ETextureType::FontChar);
|
||||||
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
|
||||||
Chars[i - FirstChar].XMove = size * spacing;
|
Chars[i - FirstChar].XMove = size * spacing;
|
||||||
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||||
}
|
}
|
||||||
else Chars[i - FirstChar].XMove = spacing;
|
else Chars[i - FirstChar].XMove = spacing;
|
||||||
|
|
||||||
|
@ -362,10 +361,9 @@ public:
|
||||||
{
|
{
|
||||||
auto offset = hexdata.glyphmap[i];
|
auto offset = hexdata.glyphmap[i];
|
||||||
int size = hexdata.glyphdata[offset] / 16;
|
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 = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)), nullptr, ETextureType::FontChar);
|
||||||
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
|
|
||||||
Chars[i - FirstChar].XMove = size * spacing;
|
Chars[i - FirstChar].XMove = size * spacing;
|
||||||
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
|
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
|
||||||
}
|
}
|
||||||
else Chars[i - FirstChar].XMove = spacing;
|
else Chars[i - FirstChar].XMove = spacing;
|
||||||
|
|
||||||
|
|
|
@ -167,10 +167,10 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
|
||||||
|
|
||||||
void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
||||||
{
|
{
|
||||||
FTexture *pic = TexMan.GetTexture(picnum);
|
auto pic = TexMan.GetGameTexture(picnum);
|
||||||
|
|
||||||
FontHeight = pic->GetDisplayHeight ();
|
FontHeight = (int)pic->GetDisplayHeight ();
|
||||||
SpaceWidth = pic->GetDisplayWidth ();
|
SpaceWidth = (int)pic->GetDisplayWidth ();
|
||||||
GlobalKerning = 0;
|
GlobalKerning = 0;
|
||||||
|
|
||||||
FirstChar = LastChar = 'A';
|
FirstChar = LastChar = 'A';
|
||||||
|
@ -222,7 +222,7 @@ void FSingleLumpFont::LoadTranslations()
|
||||||
for(unsigned int i = 0;i < count;++i)
|
for(unsigned int i = 0;i < count;++i)
|
||||||
{
|
{
|
||||||
if(Chars[i].TranslatedPic)
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
|
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)), nullptr, ETextureType::FontChar);
|
||||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int8_t code = *data_p++;
|
int8_t code = *data_p++;
|
||||||
|
@ -483,15 +482,14 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
||||||
{ // Empty character: skip it.
|
{ // Empty character: skip it.
|
||||||
continue;
|
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+1], // width
|
||||||
chardata[chari+2], // height
|
chardata[chari+2], // height
|
||||||
-(int8_t)chardata[chari+3], // x offset
|
-(int8_t)chardata[chari+3], // x offset
|
||||||
-(int8_t)chardata[chari+4] // y offset
|
-(int8_t)chardata[chari+4] // y offset
|
||||||
));
|
)), nullptr, ETextureType::FontChar);
|
||||||
tex->SetUseType(ETextureType::FontChar);
|
|
||||||
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
|
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.
|
// 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)
|
if(!Chars[i].TranslatedPic)
|
||||||
{
|
{
|
||||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
|
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)), nullptr, ETextureType::FontChar);
|
||||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
|
||||||
Chars[i].XMove = SpaceWidth;
|
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.
|
// Advance to next char's data and count the used colors.
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
FSinglePicFont(const char *picname);
|
FSinglePicFont(const char *picname);
|
||||||
|
|
||||||
// FFont interface
|
// 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;
|
int GetCharWidth (int code) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -72,11 +72,11 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
|
||||||
I_FatalError ("%s is not a font or texture", picname);
|
I_FatalError ("%s is not a font or texture", picname);
|
||||||
}
|
}
|
||||||
|
|
||||||
FTexture *pic = TexMan.GetTexture(picnum);
|
auto pic = TexMan.GetGameTexture(picnum);
|
||||||
|
|
||||||
FontName = picname;
|
FontName = picname;
|
||||||
FontHeight = pic->GetDisplayHeight();
|
FontHeight = (int)pic->GetDisplayHeight();
|
||||||
SpaceWidth = pic->GetDisplayWidth();
|
SpaceWidth = (int)pic->GetDisplayWidth();
|
||||||
GlobalKerning = 0;
|
GlobalKerning = 0;
|
||||||
FirstChar = LastChar = 'A';
|
FirstChar = LastChar = 'A';
|
||||||
ActiveColors = 0;
|
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;
|
*width = SpaceWidth;
|
||||||
if (redirected) *redirected = false;
|
if (redirected) *redirected = false;
|
||||||
if (code == 'a' || code == 'A')
|
if (code == 'a' || code == 'A')
|
||||||
{
|
{
|
||||||
return TexMan.GetPalettedTexture(PicNum, true);
|
return TexMan.GetGameTexture(PicNum, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
class FSpecialFont : public FFont
|
class FSpecialFont : public FFont
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
: FFont(lump)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
TArray<FTexture *> charlumps(count, true);
|
TArray<FGameTexture *> charlumps(count, true);
|
||||||
int maxyoffs;
|
int maxyoffs;
|
||||||
FTexture *pic;
|
FGameTexture *pic;
|
||||||
|
|
||||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
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];
|
pic = charlumps[i] = lumplist[i];
|
||||||
if (pic != nullptr)
|
if (pic != nullptr)
|
||||||
{
|
{
|
||||||
int height = pic->GetDisplayHeight();
|
int height = (int)pic->GetDisplayHeight();
|
||||||
int yoffs = pic->GetDisplayTopOffset();
|
int yoffs = (int)pic->GetDisplayTopOffset();
|
||||||
|
|
||||||
if (yoffs > maxyoffs)
|
if (yoffs > maxyoffs)
|
||||||
{
|
{
|
||||||
|
@ -104,20 +104,18 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
if (charlumps[i] != nullptr)
|
if (charlumps[i] != nullptr)
|
||||||
{
|
{
|
||||||
auto pic = charlumps[i];
|
auto pic = charlumps[i];
|
||||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
Chars[i].OriginalPic = MakeGameTexture(pic->GetTexture(), nullptr, ETextureType::FontChar);
|
||||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
|
||||||
Chars[i].OriginalPic->CopySize(pic);
|
Chars[i].OriginalPic->CopySize(pic);
|
||||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||||
|
|
||||||
if (!noTranslate)
|
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->CopySize(charlumps[i]);
|
||||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
TexMan.AddGameTexture(Chars[i].TranslatedPic);
|
||||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
|
||||||
}
|
}
|
||||||
else Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
else Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
||||||
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
|
Chars[i].XMove = (int)Chars[i].TranslatedPic->GetDisplayWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -167,7 +165,7 @@ void FSpecialFont::LoadTranslations()
|
||||||
{
|
{
|
||||||
if (Chars[i].TranslatedPic)
|
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)
|
if (pic)
|
||||||
{
|
{
|
||||||
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
|
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++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if(Chars[i].TranslatedPic)
|
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)
|
BuildTranslations(Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr, [=](FRemapTable* remap)
|
||||||
|
@ -217,7 +215,7 @@ void FSpecialFont::LoadTranslations()
|
||||||
ActiveColors = TotalColors;
|
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);
|
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);
|
FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any);
|
||||||
if (picnum.isValid())
|
if (picnum.isValid())
|
||||||
{
|
{
|
||||||
FTexture *tex = TexMan.GetTexture(picnum);
|
auto tex = TexMan.GetGameTexture(picnum);
|
||||||
if (tex && tex->GetSourceLump() >= folderfile)
|
if (tex && tex->GetSourceLump() >= folderfile)
|
||||||
{
|
{
|
||||||
FFont *CreateSinglePicFont(const char *name);
|
FFont *CreateSinglePicFont(const char *name);
|
||||||
|
@ -170,7 +170,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
||||||
void V_InitCustomFonts()
|
void V_InitCustomFonts()
|
||||||
{
|
{
|
||||||
FScanner sc;
|
FScanner sc;
|
||||||
FTexture *lumplist[256];
|
FGameTexture *lumplist[256];
|
||||||
bool notranslate[256];
|
bool notranslate[256];
|
||||||
bool donttranslate;
|
bool donttranslate;
|
||||||
FString namebuffer, templatebuf;
|
FString namebuffer, templatebuf;
|
||||||
|
@ -266,12 +266,12 @@ void V_InitCustomFonts()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (format == 1) goto wrong;
|
if (format == 1) goto wrong;
|
||||||
FTexture **p = &lumplist[*(unsigned char*)sc.String];
|
FGameTexture **p = &lumplist[*(unsigned char*)sc.String];
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FTextureID texid = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch);
|
FTextureID texid = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch);
|
||||||
if (texid.Exists())
|
if (texid.Exists())
|
||||||
{
|
{
|
||||||
*p = TexMan.GetTexture(texid);
|
*p = TexMan.GetGameTexture(texid);
|
||||||
}
|
}
|
||||||
else if (fileSystem.GetFileContainer(sc.LumpNum) >= fileSystem.GetIwadNum())
|
else if (fileSystem.GetFileContainer(sc.LumpNum) >= fileSystem.GetIwadNum())
|
||||||
{
|
{
|
||||||
|
@ -307,7 +307,7 @@ void V_InitCustomFonts()
|
||||||
}
|
}
|
||||||
if (count > 0)
|
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);
|
FFont *fnt = CreateSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump, donttranslate);
|
||||||
fnt->SetCursor(cursor);
|
fnt->SetCursor(cursor);
|
||||||
fnt->SetKerning(kerning);
|
fnt->SetKerning(kerning);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
|
|
||||||
class DCanvas;
|
class DCanvas;
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
struct FRemapTable;
|
struct FRemapTable;
|
||||||
|
|
||||||
enum EColorRange : int
|
enum EColorRange : int
|
||||||
|
@ -77,7 +77,7 @@ enum EColorRange : int
|
||||||
|
|
||||||
extern int NumTextColors;
|
extern int NumTextColors;
|
||||||
|
|
||||||
using GlyphSet = TMap<int, FTexture*>;
|
using GlyphSet = TMap<int, FGameTexture*>;
|
||||||
|
|
||||||
class FFont
|
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);
|
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 ~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;
|
virtual int GetCharWidth (int code) const;
|
||||||
int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
||||||
int GetLump() const { return Lump; }
|
int GetLump() const { return Lump; }
|
||||||
|
@ -113,9 +113,9 @@ public:
|
||||||
static FFont *FindFont(FName fontname);
|
static FFont *FindFont(FName fontname);
|
||||||
|
|
||||||
// Return width of string in pixels (unscaled)
|
// Return width of string in pixels (unscaled)
|
||||||
int StringWidth (const uint8_t *str) const;
|
int StringWidth (const uint8_t *str, int spacing = 0) const;
|
||||||
inline int StringWidth (const char *str) const { return StringWidth ((const uint8_t *)str); }
|
inline int StringWidth (const char *str, int spacing = 0) const { return StringWidth ((const uint8_t *)str, spacing); }
|
||||||
inline int StringWidth (const FString &str) const { return StringWidth ((const uint8_t *)str.GetChars()); }
|
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.
|
// Checks if the font contains all characters to print this text.
|
||||||
bool CanPrint(const uint8_t *str) const;
|
bool CanPrint(const uint8_t *str) const;
|
||||||
|
@ -161,8 +161,8 @@ protected:
|
||||||
bool forceremap = false;
|
bool forceremap = false;
|
||||||
struct CharData
|
struct CharData
|
||||||
{
|
{
|
||||||
FTexture *TranslatedPic = nullptr; // Texture for use with font translations.
|
FGameTexture *TranslatedPic = nullptr; // Texture for use with font translations.
|
||||||
FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
|
FGameTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
|
||||||
int XMove = INT_MIN;
|
int XMove = INT_MIN;
|
||||||
};
|
};
|
||||||
TArray<CharData> Chars;
|
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 int CastS2So(FString *b) { return FSoundID(*b); }
|
||||||
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(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 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()
|
void JitCompiler::EmitCAST()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1848,7 +1848,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
||||||
case CAST_TID2S:
|
case CAST_TID2S:
|
||||||
{
|
{
|
||||||
ASSERTS(a); ASSERTD(b);
|
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();
|
reg.s[a] = tex == nullptr ? "(null)" : tex->GetName().GetChars();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,14 @@
|
||||||
void AnimTexture::SetFrameSize(int width, int height)
|
void AnimTexture::SetFrameSize(int width, int height)
|
||||||
{
|
{
|
||||||
FTexture::SetSize(width, 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(Palette, palette, 768);
|
||||||
memcpy(Image.Data(), data_, Width * Height);
|
memcpy(Image.Data(), data_, Width * Height);
|
||||||
SystemTextures.Clean(true, true);
|
CleanHardwareTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -70,10 +70,10 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans)
|
||||||
for (int i = 0; i < Width * Height; i++)
|
for (int i = 0; i < Width * Height; i++)
|
||||||
{
|
{
|
||||||
int p = i * 4;
|
int p = i * 4;
|
||||||
int index = spix[i];
|
int index = spix[i];
|
||||||
dpix[p + 0] = Palette[index*3+2];
|
dpix[p + 0] = Palette[index * 3 + 2];
|
||||||
dpix[p + 1] = Palette[index*3+1];
|
dpix[p + 1] = Palette[index * 3 + 1];
|
||||||
dpix[p + 2] = Palette[index*3];
|
dpix[p + 2] = Palette[index * 3];
|
||||||
dpix[p + 3] = 255;
|
dpix[p + 3] = 255;
|
||||||
}
|
}
|
||||||
return bmp;
|
return bmp;
|
||||||
|
@ -87,30 +87,32 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans)
|
||||||
|
|
||||||
AnimTextures::AnimTextures()
|
AnimTextures::AnimTextures()
|
||||||
{
|
{
|
||||||
active = 1;
|
active = 1;
|
||||||
tex[0] = new AnimTexture;
|
tex[0] = MakeGameTexture(new AnimTexture, "", ETextureType::Special);
|
||||||
tex[1] = new AnimTexture;
|
tex[1] = MakeGameTexture(new AnimTexture, "", ETextureType::Special);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimTextures::~AnimTextures()
|
AnimTextures::~AnimTextures()
|
||||||
{
|
{
|
||||||
delete tex[0];
|
delete tex[0];
|
||||||
delete tex[1];
|
delete tex[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimTextures::SetSize(int width, int height)
|
void AnimTextures::SetSize(int width, int height)
|
||||||
{
|
{
|
||||||
tex[0]->SetFrameSize(width, height);
|
static_cast<AnimTexture*>(tex[0]->GetTexture())->SetFrameSize(width, height);
|
||||||
tex[1]->SetFrameSize(width, height);
|
static_cast<AnimTexture*>(tex[1]->GetTexture())->SetFrameSize(width, height);
|
||||||
}
|
tex[0]->SetSize(width, height);
|
||||||
|
tex[1]->SetSize(width, height);
|
||||||
void AnimTextures::SetFrame(const uint8_t *palette, const void* data)
|
|
||||||
{
|
|
||||||
active ^= 1;
|
|
||||||
tex[active]->SetFrame(palette, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
uint8_t Palette[768];
|
||||||
TArray<uint8_t> Image;
|
TArray<uint8_t> Image;
|
||||||
public:
|
public:
|
||||||
AnimTexture() = default;
|
AnimTexture() = default;
|
||||||
void SetFrameSize(int width, int height);
|
void SetFrameSize(int width, int height);
|
||||||
void SetFrame(const uint8_t *palette, const void* data);
|
void SetFrame(const uint8_t* palette, const void* data);
|
||||||
virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override;
|
virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimTextures
|
class AnimTextures
|
||||||
{
|
{
|
||||||
int active;
|
int active;
|
||||||
AnimTexture *tex[2];
|
FGameTexture* tex[2];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AnimTextures();
|
AnimTextures();
|
||||||
~AnimTextures();
|
~AnimTextures();
|
||||||
void SetSize(int width, int height);
|
void SetSize(int width, int height);
|
||||||
void SetFrame(const uint8_t *palette, const void* data);
|
void SetFrame(const uint8_t* palette, const void* data);
|
||||||
FTexture *GetFrame();
|
FGameTexture* GetFrame();
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,6 +69,11 @@ FImageSource *EmptyImage_TryCreate(FileReader & file, int lumpnum)
|
||||||
return new FEmptyTexture(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;
|
Width = w;
|
||||||
Height = h;
|
Height = h;
|
||||||
bComplex = complex;
|
bComplex = complex;
|
||||||
bTextual = textual;
|
bTextual = textual;
|
||||||
Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size());
|
Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size());
|
||||||
NumParts = parts.Size();
|
NumParts = parts.Size();
|
||||||
memcpy(Parts, parts.Data(), sizeof(TexPart) * 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;
|
bUseGamePalette = false;
|
||||||
if (!bComplex)
|
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
|
// GetBlendMap
|
||||||
|
@ -203,11 +228,6 @@ TArray<uint8_t> FMultiPatchTexture::CreatePalettedPixels(int conversion)
|
||||||
}
|
}
|
||||||
if (conversion == noremap0)
|
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;
|
if (bTextual || !UseGamePalette()) conversion = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
class FImageTexture;
|
class FImageTexture;
|
||||||
|
class FTextureManager;
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// TexPart is the data that will get passed to the final texture.
|
// TexPart is the data that will get passed to the final texture.
|
||||||
|
@ -25,6 +28,18 @@ struct TexPart
|
||||||
uint8_t op = OP_COPY;
|
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
|
class FMultiPatchTexture : public FImageSource
|
||||||
{
|
{
|
||||||
friend class FTexture;
|
friend class FTexture;
|
||||||
|
friend class FGameTexture;
|
||||||
public:
|
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:
|
protected:
|
||||||
int NumParts;
|
int NumParts;
|
||||||
|
@ -64,7 +92,7 @@ struct TexInit
|
||||||
{
|
{
|
||||||
FString TexName;
|
FString TexName;
|
||||||
ETextureType UseType = ETextureType::Null;
|
ETextureType UseType = ETextureType::Null;
|
||||||
FTexture *Texture = nullptr;
|
FImageTexture *Texture = nullptr;
|
||||||
bool Silent = false;
|
bool Silent = false;
|
||||||
bool HasLine = false;
|
bool HasLine = false;
|
||||||
bool UseOffsets = false;
|
bool UseOffsets = false;
|
||||||
|
@ -82,7 +110,7 @@ struct FPatchLookup;
|
||||||
struct BuildInfo
|
struct BuildInfo
|
||||||
{
|
{
|
||||||
FString Name;
|
FString Name;
|
||||||
TArray<TexPart> Parts;
|
TArray<TexPartBuild> Parts;
|
||||||
TArray<TexInit> Inits;
|
TArray<TexInit> Inits;
|
||||||
int Width = 0;
|
int Width = 0;
|
||||||
int Height = 0;
|
int Height = 0;
|
||||||
|
@ -94,7 +122,7 @@ struct BuildInfo
|
||||||
bool bNoDecals = false;
|
bool bNoDecals = false;
|
||||||
int LeftOffset[2] = {};
|
int LeftOffset[2] = {};
|
||||||
int TopOffset[2] = {};
|
int TopOffset[2] = {};
|
||||||
FImageTexture *tex = nullptr;
|
FGameTexture *texture = nullptr;
|
||||||
|
|
||||||
void swap(BuildInfo &other)
|
void swap(BuildInfo &other)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +141,7 @@ struct BuildInfo
|
||||||
std::swap(LeftOffset[1], other.LeftOffset[1]);
|
std::swap(LeftOffset[1], other.LeftOffset[1]);
|
||||||
std::swap(TopOffset[0], other.TopOffset[0]);
|
std::swap(TopOffset[0], other.TopOffset[0]);
|
||||||
std::swap(TopOffset[1], other.TopOffset[1]);
|
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;
|
FTextureManager &TexMan;
|
||||||
TArray<BuildInfo> BuiltTextures;
|
TArray<BuildInfo> BuiltTextures;
|
||||||
|
TMap<FGameTexture*, bool> complex;
|
||||||
void(*progressFunc)();
|
void(*progressFunc)();
|
||||||
void(*checkForHacks)(BuildInfo&);
|
void(*checkForHacks)(BuildInfo&);
|
||||||
|
|
||||||
void MakeTexture(BuildInfo &buildinfo, ETextureType usetype);
|
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 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 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);
|
void ResolvePatches(BuildInfo &buildinfo);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex);
|
FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex);
|
||||||
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
|
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
|
||||||
int CopyPixels(FBitmap *bmp, int conversion) override;
|
int CopyPixels(FBitmap *bmp, int conversion) override;
|
||||||
|
bool SupportRemap0() override { return !badflag; }
|
||||||
void DetectBadPatches();
|
void DetectBadPatches();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include "texturemanager.h"
|
||||||
#include "filesystem.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)
|
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.
|
// 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;
|
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;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
|
Masked = false;
|
||||||
|
bTranslucent = false;
|
||||||
fr = std::move(lump);
|
fr = std::move(lump);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
|
|
||||||
class FBarShader : public FImageSource
|
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');
|
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 "texturemanager.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
|
int upscalemask;
|
||||||
|
|
||||||
EXTERN_CVAR(Int, gl_texture_hqresizemult)
|
EXTERN_CVAR(Int, gl_texture_hqresizemult)
|
||||||
CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
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))
|
if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0))
|
||||||
gl_texture_hqresizemult = 4;
|
gl_texture_hqresizemult = 4;
|
||||||
TexMan.FlushAll();
|
TexMan.FlushAll();
|
||||||
|
UpdateUpscaleMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
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))
|
if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0))
|
||||||
self = 4;
|
self = 4;
|
||||||
TexMan.FlushAll();
|
TexMan.FlushAll();
|
||||||
|
UpdateUpscaleMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
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)
|
CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||||
{
|
{
|
||||||
TexMan.FlushAll();
|
TexMan.FlushAll();
|
||||||
|
UpdateUpscaleMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1);
|
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)
|
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()
|
static void xbrzApplyOptions()
|
||||||
{
|
{
|
||||||
if (gl_texture_hqresizemult != 0 && (gl_texture_hqresizemode == 4 || gl_texture_hqresizemode == 5))
|
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.
|
// the upsampled buffer.
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly)
|
void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly)
|
||||||
{
|
{
|
||||||
// [BB] Make sure that inWidth and inHeight denote the size of
|
// [BB] Make sure that inWidth and inHeight denote the size of
|
||||||
// the returned buffer even if we don't upsample the input buffer.
|
// the returned buffer even if we don't upsample the input buffer.
|
||||||
|
|
||||||
int inWidth = texbuffer.mWidth;
|
int inWidth = texbuffer.mWidth;
|
||||||
int inHeight = texbuffer.mHeight;
|
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 type = gl_texture_hqresizemode;
|
||||||
int mult = gl_texture_hqresizemult;
|
int mult = gl_texture_hqresizemult;
|
||||||
#ifdef HAVE_MMX
|
#ifdef HAVE_MMX
|
||||||
|
@ -509,3 +494,28 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
|
||||||
contentId.scalefactor = mult;
|
contentId.scalefactor = mult;
|
||||||
texbuffer.mContentId = contentId.id;
|
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
|
MAX_TEXTURES = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
IHardwareTexture() {}
|
IHardwareTexture() = default;
|
||||||
virtual ~IHardwareTexture() {}
|
virtual ~IHardwareTexture() = default;
|
||||||
|
|
||||||
virtual void DeleteDescriptors() { }
|
|
||||||
|
|
||||||
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
||||||
virtual uint8_t *MapBuffer() = 0;
|
virtual uint8_t *MapBuffer() = 0;
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#include "hw_material.h"
|
#include "hw_material.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
|
||||||
IHardwareTexture* CreateHardwareTexture();
|
IHardwareTexture* CreateHardwareTexture();
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -37,99 +37,100 @@ IHardwareTexture* CreateHardwareTexture();
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
FMaterial::FMaterial(FTexture * tx, bool expanded)
|
FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||||
{
|
{
|
||||||
mShaderIndex = SHADER_Default;
|
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;
|
mShaderIndex = SHADER_Paletted;
|
||||||
}
|
}
|
||||||
else if (tx->isWarped())
|
|
||||||
{
|
|
||||||
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
|
||||||
}
|
|
||||||
else if (tx->isHardwareCanvas())
|
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
|
// no brightmap for cameratexture
|
||||||
}
|
}
|
||||||
else
|
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;
|
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;
|
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();
|
tx->CreateDefaultBrightmap();
|
||||||
if (tx->Brightmap)
|
auto placeholder = TexMan.GameByIndex(1);
|
||||||
|
if (tx->Brightmap.get())
|
||||||
{
|
{
|
||||||
mTextureLayers.Push(tx->Brightmap);
|
mTextureLayers.Push({ tx->Brightmap.get(), scaleflags });
|
||||||
if (mShaderIndex == SHADER_Specular)
|
mLayerFlags |= TEXF_Brightmap;
|
||||||
mShaderIndex = SHADER_SpecularBrightmap;
|
}
|
||||||
else if (mShaderIndex == SHADER_PBR)
|
else
|
||||||
mShaderIndex = SHADER_PBRBrightmap;
|
{
|
||||||
else
|
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||||
mShaderIndex = SHADER_Brightmap;
|
}
|
||||||
|
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
|
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||||
{
|
{
|
||||||
for (auto &texture : tx->CustomShaderTextures)
|
for (auto &texture : tx->CustomShaderTextures)
|
||||||
{
|
{
|
||||||
if (texture == nullptr) continue;
|
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();
|
mScaleFlags = scaleflags;
|
||||||
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();
|
|
||||||
|
|
||||||
mTextureLayers.ShrinkToFit();
|
mTextureLayers.ShrinkToFit();
|
||||||
tx->Material[expanded] = this;
|
tx->Material[scaleflags] = this;
|
||||||
if (tx->isHardwareCanvas()) tx->bTranslucent = 0;
|
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 &layer = mTextureLayers[i];
|
||||||
auto topOffset = tex->GetTopOffsetHW();
|
if (pLayer) *pLayer = &layer;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (layer && layer->UseType!=ETextureType::Null)
|
if (layer.layerTexture) return layer.layerTexture->GetHardwareTexture(translation, layer.scaleFlags);
|
||||||
{
|
|
||||||
IHardwareTexture *hwtex = layer->SystemTextures.GetHardwareTexture(translation, mExpanded);
|
|
||||||
if (hwtex == nullptr)
|
|
||||||
{
|
|
||||||
hwtex = CreateHardwareTexture();
|
|
||||||
layer->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex);
|
|
||||||
}
|
|
||||||
return hwtex;
|
|
||||||
}
|
|
||||||
return nullptr;
|
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
|
// 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 0
|
||||||
if (tex && tex->isValid())
|
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 (hwtex == NULL && create)
|
||||||
{
|
{
|
||||||
if (expand)
|
hwtex = screen->CreateMaterial(gtex, scaleflags);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
return hwtex;
|
return hwtex;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return NULL;
|
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)
|
void DeleteMaterial(FMaterial* mat)
|
||||||
{
|
{
|
||||||
delete 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;
|
struct FRemapTable;
|
||||||
class IHardwareTexture;
|
class IHardwareTexture;
|
||||||
|
|
||||||
enum
|
struct MaterialLayerInfo
|
||||||
{
|
{
|
||||||
CLAMP_NONE = 0,
|
FTexture* layerTexture;
|
||||||
CLAMP_X = 1,
|
int scaleFlags;
|
||||||
CLAMP_Y = 2,
|
|
||||||
CLAMP_XY = 3,
|
|
||||||
CLAMP_XY_NOMIP = 4,
|
|
||||||
CLAMP_NOFILTER = 5,
|
|
||||||
CLAMP_CAMTEX = 6,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// this is the material class for OpenGL.
|
// this is the material class for OpenGL.
|
||||||
|
@ -28,108 +22,42 @@ enum
|
||||||
|
|
||||||
class FMaterial
|
class FMaterial
|
||||||
{
|
{
|
||||||
TArray<FTexture*> mTextureLayers;
|
private:
|
||||||
|
TArray<MaterialLayerInfo> mTextureLayers; // the only layers allowed to scale are the brightmap and the glowmap.
|
||||||
int mShaderIndex;
|
int mShaderIndex;
|
||||||
|
int mLayerFlags = 0;
|
||||||
short mLeftOffset;
|
int mScaleFlags;
|
||||||
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);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FTexture *tex;
|
FGameTexture *sourcetex; // the owning texture.
|
||||||
FTexture *sourcetex; // in case of redirection this is different from tex.
|
|
||||||
|
FMaterial(FGameTexture *tex, int scaleflags);
|
||||||
FMaterial(FTexture *tex, bool forceexpand);
|
virtual ~FMaterial();
|
||||||
~FMaterial();
|
int GetLayerFlags() const { return mLayerFlags; }
|
||||||
void SetSpriteRect();
|
|
||||||
int GetShaderIndex() const { return mShaderIndex; }
|
int GetShaderIndex() const { return mShaderIndex; }
|
||||||
void AddTextureLayer(FTexture *tex)
|
int GetScaleFlags() const { return mScaleFlags; }
|
||||||
|
virtual void DeleteDescriptors() { }
|
||||||
|
|
||||||
|
FGameTexture* Source() const
|
||||||
{
|
{
|
||||||
ValidateTexture(tex, false);
|
return sourcetex;
|
||||||
mTextureLayers.Push(tex);
|
|
||||||
}
|
|
||||||
bool isMasked() const
|
|
||||||
{
|
|
||||||
return sourcetex->bMasked;
|
|
||||||
}
|
|
||||||
bool isExpanded() const
|
|
||||||
{
|
|
||||||
return mExpanded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLayers() const
|
void AddTextureLayer(FTexture *tex, bool allowscale)
|
||||||
{
|
{
|
||||||
return mTextureLayers.Size() + 1;
|
mTextureLayers.Push({ tex, allowscale });
|
||||||
}
|
|
||||||
|
|
||||||
bool hasCanvas()
|
|
||||||
{
|
|
||||||
return tex->isHardwareCanvas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr);
|
int NumLayers() const
|
||||||
|
|
||||||
// Patch drawing utilities
|
|
||||||
|
|
||||||
void GetSpriteRect(FloatRect * r) const
|
|
||||||
{
|
{
|
||||||
*r = mSpriteRect;
|
return mTextureLayers.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is scaled size in integer units as needed by walls and flats
|
IHardwareTexture *GetLayer(int i, int translation, MaterialLayerInfo **pLayer = nullptr) const;
|
||||||
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]; }
|
|
||||||
|
|
||||||
|
|
||||||
static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true);
|
static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true);
|
||||||
static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true);
|
const TArray<MaterialLayerInfo> &GetLayerArray() const
|
||||||
const TArray<FTexture*> &GetLayerArray() const
|
|
||||||
{
|
{
|
||||||
return mTextureLayers;
|
return mTextureLayers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,15 @@
|
||||||
struct FTextureBuffer;
|
struct FTextureBuffer;
|
||||||
class IHardwareTexture;
|
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
|
class FHardwareTextureContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -20,6 +29,7 @@ private:
|
||||||
{
|
{
|
||||||
IHardwareTexture *hwTexture = nullptr;
|
IHardwareTexture *hwTexture = nullptr;
|
||||||
int translation = 0;
|
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()
|
void Delete()
|
||||||
{
|
{
|
||||||
|
@ -27,23 +37,28 @@ private:
|
||||||
hwTexture = nullptr;
|
hwTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteDescriptors()
|
|
||||||
{
|
|
||||||
if (hwTexture) hwTexture->DeleteDescriptors();
|
|
||||||
}
|
|
||||||
|
|
||||||
~TranslatedTexture()
|
~TranslatedTexture()
|
||||||
{
|
{
|
||||||
Delete();
|
Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkForPrecache(bool on)
|
||||||
|
{
|
||||||
|
precacheMarker = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMarkedForPreache() const
|
||||||
|
{
|
||||||
|
return precacheMarker;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TranslatedTexture hwDefTex[2];
|
TranslatedTexture hwDefTex[4];
|
||||||
TArray<TranslatedTexture> hwTex_Translated;
|
TArray<TranslatedTexture> hwTex_Translated;
|
||||||
|
|
||||||
TranslatedTexture * GetTexID(int translation, bool expanded)
|
TranslatedTexture * GetTexID(int translation, int scaleflags)
|
||||||
{
|
{
|
||||||
// Allow negative indices to pass through unchanged.
|
// 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.
|
// 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;
|
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
|
// normally there aren't more than very few different
|
||||||
// translations here so this isn't performance critical.
|
// translations here so this isn't performance critical.
|
||||||
unsigned index = hwTex_Translated.FindEx([=](auto &element)
|
unsigned index = hwTex_Translated.FindEx([=](auto &element)
|
||||||
|
@ -78,32 +93,22 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void Clean()
|
||||||
void Clean(bool cleannormal, bool cleanexpanded)
|
|
||||||
{
|
{
|
||||||
if (cleannormal) hwDefTex[0].Delete();
|
hwDefTex[0].Delete();
|
||||||
if (cleanexpanded) hwDefTex[1].Delete();
|
hwDefTex[1].Delete();
|
||||||
hwDefTex[0].DeleteDescriptors();
|
hwTex_Translated.Clear();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
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->Delete();
|
||||||
tt->hwTexture =tex;
|
tt->hwTexture =tex;
|
||||||
}
|
}
|
||||||
|
@ -111,26 +116,44 @@ public:
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Deletes all allocated resources and considers translations
|
// 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--)
|
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);
|
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>
|
template<class T>
|
||||||
void Iterate(T callback)
|
void Iterate(T callback)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "palettecontainer.h"
|
#include "palettecontainer.h"
|
||||||
|
|
||||||
FMemArena FImageSource::ImageArena(32768);
|
FMemArena ImageArena(32768);
|
||||||
TArray<FImageSource *>FImageSource::ImageForLump;
|
TArray<FImageSource *>FImageSource::ImageForLump;
|
||||||
int FImageSource::NextID;
|
int FImageSource::NextID;
|
||||||
static PrecacheInfo precacheInfo;
|
static PrecacheInfo precacheInfo;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
class FImageSource;
|
class FImageSource;
|
||||||
using PrecacheInfo = TMap<int, std::pair<int, int>>;
|
using PrecacheInfo = TMap<int, std::pair<int, int>>;
|
||||||
|
extern FMemArena ImageArena;
|
||||||
|
|
||||||
// Doom patch format header
|
// Doom patch format header
|
||||||
struct patch_t
|
struct patch_t
|
||||||
|
@ -38,7 +39,6 @@ class FImageSource
|
||||||
friend class FBrightmapTexture;
|
friend class FBrightmapTexture;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static FMemArena ImageArena;
|
|
||||||
static TArray<FImageSource *>ImageForLump;
|
static TArray<FImageSource *>ImageForLump;
|
||||||
static int NextID;
|
static int NextID;
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
public:
|
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)
|
void CopySize(FImageSource &other)
|
||||||
{
|
{
|
||||||
|
@ -169,4 +171,4 @@ protected:
|
||||||
|
|
||||||
class FTexture;
|
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
|
FImageTexture::FImageTexture(FImageSource *img) noexcept
|
||||||
: FTexture(name, img ? img->LumpNum() : 0)
|
: FTexture(img? img->LumpNum() : 0)
|
||||||
{
|
{
|
||||||
mImage = img;
|
mImage = img;
|
||||||
if (img != nullptr)
|
if (img != nullptr)
|
||||||
{
|
{
|
||||||
if (name == nullptr) fileSystem.GetFileShortName(Name, img->LumpNum());
|
SetFromImage();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
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
|
#endif
|
||||||
|
|
|
@ -57,7 +57,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Data structures for the TEXTUREx lumps
|
// Data structures for the TEXTUREx lumps
|
||||||
|
@ -85,7 +84,7 @@ struct mappatch_t
|
||||||
struct maptexture_t
|
struct maptexture_t
|
||||||
{
|
{
|
||||||
uint8_t name[8];
|
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 ScaleX; // [RH] Scaling (8 is normal)
|
||||||
uint8_t ScaleY; // [RH] Same as above
|
uint8_t ScaleY; // [RH] Same as above
|
||||||
int16_t width;
|
int16_t width;
|
||||||
|
@ -113,7 +112,7 @@ struct strifemappatch_t
|
||||||
struct strifemaptexture_t
|
struct strifemaptexture_t
|
||||||
{
|
{
|
||||||
uint8_t name[8];
|
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 ScaleX; // [RH] Scaling (8 is normal)
|
||||||
uint8_t ScaleY; // [RH] Same as above
|
uint8_t ScaleY; // [RH] Same as above
|
||||||
int16_t width;
|
int16_t width;
|
||||||
|
@ -137,25 +136,23 @@ struct FPatchLookup
|
||||||
|
|
||||||
void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype)
|
void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype)
|
||||||
{
|
{
|
||||||
FImageTexture *tex = new FImageTexture(nullptr, buildinfo.Name);
|
buildinfo.texture = new FGameTexture(nullptr, buildinfo.Name);
|
||||||
tex->SetUseType(usetype);
|
buildinfo.texture->SetUseType(usetype);
|
||||||
tex->bMultiPatch = true;
|
TexMan.AddGameTexture(buildinfo.texture);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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].OriginX = LittleShort(mpatch.d->originx);
|
||||||
buildinfo.Parts[i].OriginY = LittleShort(mpatch.d->originy);
|
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].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name;
|
||||||
buildinfo.Inits[i].UseType = ETextureType::WallPatch;
|
buildinfo.Inits[i].UseType = ETextureType::WallPatch;
|
||||||
if (strife)
|
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.
|
// It still needs to be created in case someone uses it by name.
|
||||||
offset = LittleLong(directory[1]);
|
offset = LittleLong(directory[1]);
|
||||||
const maptexture_t *tex = (const maptexture_t *)((const uint8_t *)maptex + offset);
|
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));
|
tex0->SetSize(SAFESHORT(tex->width), SAFESHORT(tex->height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +370,7 @@ void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsi
|
||||||
int j;
|
int j;
|
||||||
for (j = (int)TexMan.NumTextures() - 1; j >= firstdup; --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;
|
break;
|
||||||
}
|
}
|
||||||
if (j + 1 == firstdup)
|
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;
|
FString patchname;
|
||||||
int Mirror = 0;
|
int Mirror = 0;
|
||||||
|
@ -672,7 +669,7 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
||||||
}
|
}
|
||||||
else if (sc.Compare("Patch"))
|
else if (sc.Compare("Patch"))
|
||||||
{
|
{
|
||||||
TexPart part;
|
TexPartBuild part;
|
||||||
TexInit init;
|
TexInit init;
|
||||||
ParsePatch(sc, buildinfo, part, init);
|
ParsePatch(sc, buildinfo, part, init);
|
||||||
if (init.TexName.IsNotEmpty())
|
if (init.TexName.IsNotEmpty())
|
||||||
|
@ -684,12 +681,12 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
||||||
init.sc = sc;
|
init.sc = sc;
|
||||||
buildinfo.Inits.Push(init);
|
buildinfo.Inits.Push(init);
|
||||||
}
|
}
|
||||||
part.Image = nullptr;
|
part.TexImage = nullptr;
|
||||||
part.Translation = nullptr;
|
part.Translation = nullptr;
|
||||||
}
|
}
|
||||||
else if (sc.Compare("Sprite"))
|
else if (sc.Compare("Sprite"))
|
||||||
{
|
{
|
||||||
TexPart part;
|
TexPartBuild part;
|
||||||
TexInit init;
|
TexInit init;
|
||||||
ParsePatch(sc, buildinfo, part, init);
|
ParsePatch(sc, buildinfo, part, init);
|
||||||
if (init.TexName.IsNotEmpty())
|
if (init.TexName.IsNotEmpty())
|
||||||
|
@ -701,12 +698,12 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
||||||
init.sc = sc;
|
init.sc = sc;
|
||||||
buildinfo.Inits.Push(init);
|
buildinfo.Inits.Push(init);
|
||||||
}
|
}
|
||||||
part.Image = nullptr;
|
part.TexImage = nullptr;
|
||||||
part.Translation = nullptr;
|
part.Translation = nullptr;
|
||||||
}
|
}
|
||||||
else if (sc.Compare("Graphic"))
|
else if (sc.Compare("Graphic"))
|
||||||
{
|
{
|
||||||
TexPart part;
|
TexPartBuild part;
|
||||||
TexInit init;
|
TexInit init;
|
||||||
ParsePatch(sc, buildinfo, part, init);
|
ParsePatch(sc, buildinfo, part, init);
|
||||||
if (init.TexName.IsNotEmpty())
|
if (init.TexName.IsNotEmpty())
|
||||||
|
@ -718,7 +715,7 @@ void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType)
|
||||||
init.sc = sc;
|
init.sc = sc;
|
||||||
buildinfo.Inits.Push(init);
|
buildinfo.Inits.Push(init);
|
||||||
}
|
}
|
||||||
part.Image = nullptr;
|
part.TexImage = nullptr;
|
||||||
part.Translation = nullptr;
|
part.Translation = nullptr;
|
||||||
}
|
}
|
||||||
else if (sc.Compare("Offset"))
|
else if (sc.Compare("Offset"))
|
||||||
|
@ -774,19 +771,23 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
|
||||||
for (unsigned i = 0; i < buildinfo.Inits.Size(); i++)
|
for (unsigned i = 0; i < buildinfo.Inits.Size(); i++)
|
||||||
{
|
{
|
||||||
FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType);
|
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;
|
TArray<FTextureID> list;
|
||||||
TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true);
|
TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true);
|
||||||
for (int i = list.Size() - 1; i >= 0; i--)
|
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;
|
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());
|
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());
|
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
|
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.
|
//We cannot set the image source yet. First all textures need to be resolved.
|
||||||
buildinfo.Inits[i].Texture = tex;
|
buildinfo.Inits[i].Texture = static_cast<FImageTexture*>(tex->GetTexture());
|
||||||
buildinfo.tex->bComplex |= tex->bComplex;
|
bool iscomplex = !!complex.CheckKey(tex);
|
||||||
buildinfo.bComplex |= tex->bComplex;
|
if (iscomplex) complex.Insert(buildinfo.texture, true);
|
||||||
|
buildinfo.bComplex |= iscomplex;
|
||||||
if (buildinfo.Inits[i].UseOffsets)
|
if (buildinfo.Inits[i].UseOffsets)
|
||||||
{
|
{
|
||||||
buildinfo.Parts[i].OriginX -= tex->GetLeftOffset(0);
|
buildinfo.Parts[i].OriginX -= tex->GetTexelLeftOffset(0);
|
||||||
buildinfo.Parts[i].OriginY -= tex->GetTopOffset(0);
|
buildinfo.Parts[i].OriginY -= tex->GetTexelTopOffset(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -841,8 +843,6 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForHacks(buildinfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FMultipatchTextureBuilder::ResolveAllPatches()
|
void FMultipatchTextureBuilder::ResolveAllPatches()
|
||||||
|
@ -874,12 +874,12 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
||||||
|
|
||||||
for (unsigned j = 0; j < buildinfo.Inits.Size(); j++)
|
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();
|
auto image = buildinfo.Inits[j].Texture;
|
||||||
if (image != nullptr)
|
if (image->GetImage() != nullptr)
|
||||||
{
|
{
|
||||||
buildinfo.Parts[j].Image = image;
|
buildinfo.Parts[j].TexImage = image;
|
||||||
donesomething = true;
|
donesomething = true;
|
||||||
}
|
}
|
||||||
else hasEmpty = 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
|
// If this texture is just a wrapper around a single patch, we can simply
|
||||||
// use that patch's image directly here.
|
// use that patch's image directly here.
|
||||||
|
checkForHacks(buildinfo);
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
if (buildinfo.Parts.Size() == 1)
|
if (buildinfo.Parts.Size() == 1)
|
||||||
{
|
{
|
||||||
if (buildinfo.Parts[0].OriginX == 0 && buildinfo.Parts[0].OriginY == 0 &&
|
if (buildinfo.Parts[0].OriginX == 0 && buildinfo.Parts[0].OriginY == 0 &&
|
||||||
buildinfo.Parts[0].Image->GetWidth() == buildinfo.Width &&
|
buildinfo.Parts[0].TexImage->GetWidth() == buildinfo.Width &&
|
||||||
buildinfo.Parts[0].Image->GetHeight() == buildinfo.Height &&
|
buildinfo.Parts[0].TexImage->GetHeight() == buildinfo.Height &&
|
||||||
buildinfo.Parts[0].Rotate == 0 &&
|
buildinfo.Parts[0].Rotate == 0 &&
|
||||||
!buildinfo.bComplex)
|
!buildinfo.bComplex)
|
||||||
{
|
{
|
||||||
buildinfo.tex->SetImage(buildinfo.Parts[0].Image);
|
AddImageToTexture(buildinfo.Parts[0].TexImage, buildinfo);
|
||||||
|
buildinfo.texture->Setup(buildinfo.Parts[0].TexImage);
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
auto img = new FMultiPatchTexture(buildinfo.Width, buildinfo.Height, buildinfo.Parts, buildinfo.bComplex, buildinfo.textual);
|
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);
|
BuiltTextures.Delete(i);
|
||||||
donesomething = true;
|
donesomething = true;
|
||||||
}
|
}
|
||||||
|
@ -919,7 +921,7 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
||||||
for (auto &b : BuiltTextures)
|
for (auto &b : BuiltTextures)
|
||||||
{
|
{
|
||||||
Printf("%s\n", b.Name.GetChars());
|
Printf("%s\n", b.Name.GetChars());
|
||||||
b.tex->SetUseType(ETextureType::Null);
|
b.texture->SetUseType(ETextureType::Null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,18 +47,15 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
FSkyBox::FSkyBox(const char *name)
|
FSkyBox::FSkyBox(const char *name)
|
||||||
: FTexture(name)
|
: FImageTexture(nullptr)
|
||||||
{
|
{
|
||||||
FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall);
|
FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall);
|
||||||
previous = nullptr;
|
|
||||||
if (texid.isValid())
|
if (texid.isValid())
|
||||||
{
|
{
|
||||||
previous = TexMan.GetTexture(texid);
|
previous = TexMan.GetGameTexture(texid);
|
||||||
CopySize(previous);
|
|
||||||
}
|
}
|
||||||
|
else previous = nullptr;
|
||||||
faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5] = nullptr;
|
faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5] = nullptr;
|
||||||
UseType = ETextureType::Override;
|
|
||||||
bSkybox = true;
|
|
||||||
fliptop = false;
|
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);
|
if (!previous && faces[0]) previous = faces[0];
|
||||||
}
|
if (previous && previous->GetTexture()->GetImage())
|
||||||
|
{
|
||||||
//-----------------------------------------------------------------------------
|
SetImage(previous->GetTexture()->GetImage());
|
||||||
//
|
}
|
||||||
//
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
FBitmap FSkyBox::GetBgraBitmap(const PalEntry *p, int *trans)
|
|
||||||
{
|
|
||||||
return previous->GetBgraBitmap(p, trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
FImageSource *FSkyBox::GetImage() const
|
|
||||||
{
|
|
||||||
return previous->GetImage();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// This is not a real texture but will be added to the texture manager
|
// Todo: Get rid of this
|
||||||
// so that it can be handled like any other sky.
|
// The faces can easily be stored in the material layer array
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class FSkyBox : public FTexture
|
class FSkyBox : public FImageTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FTexture *previous;
|
FGameTexture* previous;
|
||||||
FTexture * faces[6];
|
FGameTexture* faces[6]; // the faces need to be full materials as they can have all supported effects.
|
||||||
bool fliptop;
|
bool fliptop;
|
||||||
|
|
||||||
FSkyBox(const char *name);
|
FSkyBox(const char* name);
|
||||||
TArray<uint8_t> Get8BitPixels(bool alphatex);
|
void SetSize();
|
||||||
FBitmap GetBgraBitmap(const PalEntry *, int *trans) override;
|
|
||||||
FImageSource *GetImage() const override;
|
|
||||||
|
|
||||||
|
|
||||||
void SetSize()
|
|
||||||
{
|
|
||||||
if (!previous && faces[0]) previous = faces[0];
|
|
||||||
if (previous)
|
|
||||||
{
|
|
||||||
CopySize(previous);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Is3Face() const
|
bool Is3Face() const
|
||||||
{
|
{
|
||||||
|
@ -40,4 +29,14 @@ public:
|
||||||
{
|
{
|
||||||
return fliptop;
|
return fliptop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGameTexture* GetSkyFace(int num) const
|
||||||
|
{
|
||||||
|
return faces[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetSkyFlip() const
|
||||||
|
{
|
||||||
|
return fliptop;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,123 +47,24 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "formats/multipatchtexture.h"
|
#include "formats/multipatchtexture.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
|
||||||
// Wrappers to keep the definitions of these classes out of here.
|
// Wrappers to keep the definitions of these classes out of here.
|
||||||
void DeleteMaterial(FMaterial* mat);
|
|
||||||
void DeleteSoftwareTexture(FSoftwareTexture* swtex);
|
|
||||||
IHardwareTexture* CreateHardwareTexture();
|
IHardwareTexture* CreateHardwareTexture();
|
||||||
|
|
||||||
|
|
||||||
FTexture* CreateBrightmapTexture(FImageSource*);
|
|
||||||
|
|
||||||
// Make sprite offset adjustment user-configurable per renderer.
|
// Make sprite offset adjustment user-configurable per renderer.
|
||||||
int r_spriteadjustSW, r_spriteadjustHW;
|
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)
|
FTexture::FTexture (int lumpnum)
|
||||||
:
|
: SourceLump(lumpnum), bHasCanvas(false)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
bBrightmapChecked = false;
|
|
||||||
bGlowing = false;
|
|
||||||
bAutoGlowing = false;
|
|
||||||
bFullbright = false;
|
|
||||||
bDisableFullbright = false;
|
|
||||||
bSkybox = false;
|
|
||||||
bNoCompress = false;
|
|
||||||
bNoExpand = false;
|
|
||||||
bTranslucent = -1;
|
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;
|
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
|
// CheckRealHeight
|
||||||
|
@ -299,16 +95,13 @@ PalEntry FTexture::GetSkyCapColor(bool bottom)
|
||||||
int FTexture::CheckRealHeight()
|
int FTexture::CheckRealHeight()
|
||||||
{
|
{
|
||||||
auto pixels = Get8BitPixels(false);
|
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;
|
return h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,127 +109,6 @@ int FTexture::CheckRealHeight()
|
||||||
return 0;
|
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
|
// 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!
|
// already done!
|
||||||
if (areacount) return false;
|
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!
|
areacount = -1; //whatever happens next, it shouldn't be done twice!
|
||||||
|
|
||||||
// large textures are excluded for performance reasons
|
// large textures and non-images are excluded for performance reasons
|
||||||
if (h > 512) return false;
|
if (h>512 || !GetImage()) return false;
|
||||||
|
|
||||||
startdraw = -1;
|
startdraw = -1;
|
||||||
lendraw = 0;
|
lendraw = 0;
|
||||||
|
@ -510,7 +181,7 @@ bool FTexture::FindHoles(const unsigned char* buffer, int w, int h)
|
||||||
|
|
||||||
if (gapc > 0)
|
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++)
|
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)
|
bool FTexture::ProcessData(unsigned char* buffer, int w, int h, bool ispatch)
|
||||||
{
|
{
|
||||||
if (bMasked)
|
if (Masked)
|
||||||
{
|
{
|
||||||
bMasked = SmoothEdges(buffer, w, h);
|
Masked = SmoothEdges(buffer, w, h);
|
||||||
if (bMasked && !ispatch) FindHoles(buffer, w, h);
|
if (Masked && !ispatch) FindHoles(buffer, w, h);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -660,8 +331,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
||||||
|
|
||||||
int exx = !!(flags & CTF_Expand);
|
int exx = !!(flags & CTF_Expand);
|
||||||
|
|
||||||
W = GetTexelWidth() + 2 * exx;
|
W = GetWidth() + 2 * exx;
|
||||||
H = GetTexelHeight() + 2 * exx;
|
H = GetHeight() + 2 * exx;
|
||||||
|
|
||||||
if (!checkonly)
|
if (!checkonly)
|
||||||
{
|
{
|
||||||
|
@ -669,6 +340,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
||||||
memset(buffer, 0, W * (H + 1) * 4);
|
memset(buffer, 0, W * (H + 1) * 4);
|
||||||
|
|
||||||
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
||||||
|
if (remap) translation = remap->Index;
|
||||||
FBitmap bmp(buffer, W * 4, W, H);
|
FBitmap bmp(buffer, W * 4, W, H);
|
||||||
|
|
||||||
int trans;
|
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.)
|
// Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.)
|
||||||
if (GetImage() && flags & CTF_ProcessData)
|
if (GetImage() && flags & CTF_ProcessData)
|
||||||
{
|
{
|
||||||
#pragma message("Activate me")
|
if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
||||||
#if 0
|
|
||||||
CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
|
||||||
#endif
|
|
||||||
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
|
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,15 +393,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
||||||
|
|
||||||
bool FTexture::DetermineTranslucency()
|
bool FTexture::DetermineTranslucency()
|
||||||
{
|
{
|
||||||
if (!bHasCanvas)
|
|
||||||
{
|
|
||||||
// This will calculate all we need, so just discard the result.
|
// This will calculate all we need, so just discard the result.
|
||||||
CreateTexBuffer(0);
|
CreateTexBuffer(0);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bTranslucent = 0;
|
|
||||||
}
|
|
||||||
return !!bTranslucent;
|
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;
|
auto texbuffer = CreateTexBuffer(0);
|
||||||
else return rowoffset / scale;
|
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 (UseType != ETextureType::Null)
|
||||||
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);
|
IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags);
|
||||||
if (tscale == 1.f) return (float)mRenderWidth;
|
if (hwtex == nullptr)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
mRenderWidth = tex->GetScaledWidth();
|
hwtex = CreateHardwareTexture();
|
||||||
mScale.X = (float)tex->Scale.X;
|
SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex);
|
||||||
mTempScale.X = 1.f;
|
|
||||||
}
|
}
|
||||||
else
|
return hwtex;
|
||||||
{
|
|
||||||
float scale_x = x * (float)tex->Scale.X;
|
|
||||||
mRenderWidth = xs_CeilToInt(tex->GetTexelWidth() / scale_x);
|
|
||||||
mScale.X = scale_x;
|
|
||||||
mTempScale.X = x;
|
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -858,8 +534,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits)
|
||||||
Width = w;
|
Width = w;
|
||||||
Height = h;
|
Height = h;
|
||||||
Format = bits;
|
Format = bits;
|
||||||
UseType = ETextureType::SWCanvas;
|
//bNoCompress = true;
|
||||||
bNoCompress = true;
|
|
||||||
auto hwtex = CreateHardwareTexture();
|
auto hwtex = CreateHardwareTexture();
|
||||||
// todo: Initialize here.
|
// todo: Initialize here.
|
||||||
SystemTextures.AddHardwareTexture(0, false, hwtex);
|
SystemTextures.AddHardwareTexture(0, false, hwtex);
|
||||||
|
|
|
@ -17,7 +17,7 @@ enum class ETextureType : uint8_t
|
||||||
SkinGraphic,
|
SkinGraphic,
|
||||||
Null,
|
Null,
|
||||||
FirstDefined,
|
FirstDefined,
|
||||||
Canvas,
|
Special,
|
||||||
SWCanvas,
|
SWCanvas,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -103,15 +103,14 @@ void FTextureManager::DeleteAll()
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Flushes all hardware dependent data.
|
// 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
|
// 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
|
// 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.
|
// main reason to call this outside of the destruction code.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void DeleteSoftwareTexture(FSoftwareTexture* swtex);
|
|
||||||
|
|
||||||
void FTextureManager::FlushAll()
|
void FTextureManager::FlushAll()
|
||||||
{
|
{
|
||||||
|
@ -119,13 +118,33 @@ void FTextureManager::FlushAll()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
Textures[i].Texture->SystemTextures.Clean(true, true);
|
Textures[i].Texture->CleanHardwareData();
|
||||||
DeleteSoftwareTexture(Textures[i].Texture->SoftwareTexture);
|
delete Textures[i].Texture->GetSoftwareTexture();
|
||||||
Textures[i].Texture->SoftwareTexture = nullptr;
|
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
|
// 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)
|
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 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
auto texUseType = tex->GetUseType();
|
||||||
// The name matches, so check the texture type
|
// The name matches, so check the texture type
|
||||||
if (usetype == ETextureType::Any)
|
if (usetype == ETextureType::Any)
|
||||||
{
|
{
|
||||||
// All NULL textures should actually return 0
|
// All NULL textures should actually return 0
|
||||||
if (tex->UseType == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0;
|
if (texUseType == ETextureType::FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0;
|
||||||
if (tex->UseType == ETextureType::SkinGraphic && !(flags & TEXMAN_AllowSkins)) return 0;
|
if (texUseType == ETextureType::SkinGraphic && !(flags & TEXMAN_AllowSkins)) return 0;
|
||||||
return FTextureID(tex->UseType==ETextureType::Null ? 0 : i);
|
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);
|
return FTextureID(i);
|
||||||
}
|
}
|
||||||
else if (tex->UseType == usetype)
|
else if (texUseType == usetype)
|
||||||
{
|
{
|
||||||
return FTextureID(i);
|
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);
|
if (!(flags & TEXMAN_ReturnFirst)) return FTextureID(0);
|
||||||
else return FTextureID(i);
|
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
|
// We found a NULL texture on a wall -> return 0
|
||||||
return FTextureID(0);
|
return FTextureID(0);
|
||||||
|
@ -192,12 +212,12 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
|
||||||
{
|
{
|
||||||
if (firsttype == ETextureType::Null ||
|
if (firsttype == ETextureType::Null ||
|
||||||
(firsttype == ETextureType::MiscPatch &&
|
(firsttype == ETextureType::MiscPatch &&
|
||||||
tex->UseType != firsttype &&
|
texUseType != firsttype &&
|
||||||
tex->UseType != ETextureType::Null)
|
texUseType != ETextureType::Null)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
firstfound = i;
|
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.
|
// Any graphic being placed in the zip's root directory can not be found by this.
|
||||||
if (strchr(name, '/'))
|
if (strchr(name, '/'))
|
||||||
{
|
{
|
||||||
FTexture *const NO_TEXTURE = (FTexture*)-1;
|
FGameTexture *const NO_TEXTURE = (FGameTexture*)-1;
|
||||||
int lump = fileSystem.CheckNumForFullName(name);
|
int lump = fileSystem.CheckNumForFullName(name);
|
||||||
if (lump >= 0)
|
if (lump >= 0)
|
||||||
{
|
{
|
||||||
FTexture *tex = fileSystem.GetLinkedTexture(lump);
|
FGameTexture *tex = fileSystem.GetLinkedTexture(lump);
|
||||||
if (tex == NO_TEXTURE) return FTextureID(-1);
|
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.
|
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)
|
if (tex != NULL)
|
||||||
{
|
{
|
||||||
tex->AddAutoMaterials();
|
tex->AddAutoMaterials();
|
||||||
fileSystem.SetLinkedTexture(lump, tex);
|
fileSystem.SetLinkedTexture(lump, tex);
|
||||||
return AddTexture(tex);
|
return AddGameTexture(tex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -273,12 +293,13 @@ int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list, b
|
||||||
|
|
||||||
while (i != HASH_END)
|
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.
|
// NULL textures must be ignored.
|
||||||
if (tex->UseType!=ETextureType::Null)
|
if (texUseType!=ETextureType::Null)
|
||||||
{
|
{
|
||||||
unsigned int j = list.Size();
|
unsigned int j = list.Size();
|
||||||
if (!listall)
|
if (!listall)
|
||||||
|
@ -286,7 +307,7 @@ int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list, b
|
||||||
for (j = 0; j < list.Size(); j++)
|
for (j = 0; j < list.Size(); j++)
|
||||||
{
|
{
|
||||||
// Check for overriding definitions from newer WADs
|
// 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));
|
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);
|
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;
|
if (locmode == 2) return false;
|
||||||
|
|
||||||
// Mode 3 must also reject substitutions for non-IWAD content.
|
// 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;
|
if (file > fileSystem.GetMaxIwadNum()) return true;
|
||||||
|
|
||||||
return false;
|
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 bucket;
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
if (texture == NULL) return FTextureID(-1);
|
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
|
// 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];
|
hash = HashFirst[bucket];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -395,11 +420,13 @@ FTextureID FTextureManager::AddTexture (FTexture *texture)
|
||||||
hash = -1;
|
hash = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureHash hasher = { texture, hash };
|
TextureHash hasher = { texture, -1, -1, -1, hash };
|
||||||
int trans = Textures.Push (hasher);
|
int trans = Textures.Push (hasher);
|
||||||
Translation.Push (trans);
|
Translation.Push (trans);
|
||||||
if (bucket >= 0) HashFirst[bucket] = 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;
|
FString str;
|
||||||
fileSystem.GetFileShortName(str, lumpnum);
|
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
|
else
|
||||||
{
|
{
|
||||||
Printf (TEXTCOLOR_ORANGE "Invalid data encountered for texture %s\n", fileSystem.GetFileFullPath(lumpnum).GetChars());
|
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();
|
int index = picnum.GetIndex();
|
||||||
if (unsigned(index) >= Textures.Size())
|
if (unsigned(index) >= Textures.Size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FTexture *oldtexture = Textures[index].Texture;
|
auto oldtexture = Textures[index].Texture;
|
||||||
|
|
||||||
newtexture->Name = oldtexture->Name;
|
newtexture->SetName(oldtexture->GetName());
|
||||||
newtexture->UseType = oldtexture->UseType;
|
newtexture->SetUseType(oldtexture->GetUseType());
|
||||||
Textures[index].Texture = newtexture;
|
Textures[index].Texture = newtexture;
|
||||||
newtexture->id = oldtexture->id;
|
newtexture->SetID(oldtexture->GetID());
|
||||||
oldtexture->Name = "";
|
oldtexture->SetName("");
|
||||||
AddTexture(oldtexture);
|
AddGameTexture(oldtexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -465,11 +515,11 @@ bool FTextureManager::AreTexturesCompatible (FTextureID picnum1, FTextureID picn
|
||||||
if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size())
|
if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FTexture *texture1 = Textures[index1].Texture;
|
auto texture1 = Textures[index1].Texture;
|
||||||
FTexture *texture2 = Textures[index2].Texture;
|
auto texture2 = Textures[index2].Texture;
|
||||||
|
|
||||||
// both textures must be the same type.
|
// 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;
|
return false;
|
||||||
|
|
||||||
// both textures must be from the same file
|
// both textures must be from the same file
|
||||||
|
@ -556,30 +606,28 @@ void FTextureManager::AddHiresTextures (int wadnum)
|
||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
{
|
{
|
||||||
// A texture with this name does not yet exist
|
// 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)
|
if (newtex != NULL)
|
||||||
{
|
{
|
||||||
newtex->UseType=ETextureType::Override;
|
AddGameTexture(newtex);
|
||||||
AddTexture(newtex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
for(unsigned int i = 0; i < tlist.Size(); i++)
|
||||||
{
|
{
|
||||||
FTexture * newtex = FTexture::CreateTexture ("", firsttx, ETextureType::Any);
|
FTexture * newtex = CreateTextureFromLump(firsttx);
|
||||||
if (newtex != NULL)
|
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.
|
// Replace the entire texture and adjust the scaling and offset factors.
|
||||||
newtex->bWorldPanning = true;
|
auto gtex = MakeGameTexture(newtex, nullptr, ETextureType::Override);
|
||||||
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
gtex->SetWorldPanning(true);
|
||||||
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
|
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||||
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
|
gtex->SetOffsets(0, xs_RoundToInt(oldtex->GetDisplayLeftOffset(0) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(0) * gtex->GetScaleY()));
|
||||||
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
|
gtex->SetOffsets(1, xs_RoundToInt(oldtex->GetDisplayLeftOffset(1) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(1) * gtex->GetScaleY()));
|
||||||
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
|
ReplaceTexture(tlist[i], gtex, true);
|
||||||
ReplaceTexture(tlist[i], newtex, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,28 +703,27 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
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;
|
int sl;
|
||||||
|
|
||||||
// only replace matching types. For sprites also replace any MiscPatches
|
// only replace matching types. For sprites also replace any MiscPatches
|
||||||
// based on the same lump. These can be created for icons.
|
// based on the same lump. These can be created for icons.
|
||||||
if (oldtex->UseType == type || type == ETextureType::Any ||
|
if (oldtex->GetUseType() == type || type == ETextureType::Any ||
|
||||||
(mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) ||
|
(mode == TEXMAN_Overridable && oldtex->GetUseType() == ETextureType::Override) ||
|
||||||
(type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch &&
|
(type == ETextureType::Sprite && oldtex->GetUseType() == ETextureType::MiscPatch &&
|
||||||
(sl=oldtex->GetSourceLump()) >= 0 && fileSystem.GetFileNamespace(sl) == ns_sprites)
|
(sl=oldtex->GetSourceLump()) >= 0 && fileSystem.GetFileNamespace(sl) == ns_sprites)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FTexture * newtex = FTexture::CreateTexture ("", lumpnum, ETextureType::Any);
|
FTexture * newtex = CreateTextureFromLump(lumpnum);
|
||||||
if (newtex != NULL)
|
if (newtex != NULL)
|
||||||
{
|
{
|
||||||
// Replace the entire texture and adjust the scaling and offset factors.
|
// Replace the entire texture and adjust the scaling and offset factors.
|
||||||
newtex->bWorldPanning = true;
|
auto gtex = MakeGameTexture(newtex, nullptr, ETextureType::Override);
|
||||||
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
gtex->SetWorldPanning(true);
|
||||||
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
|
gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
|
||||||
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
|
gtex->SetOffsets(0, xs_RoundToInt(oldtex->GetDisplayLeftOffset(0) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(0) * gtex->GetScaleY()));
|
||||||
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
|
gtex->SetOffsets(1, xs_RoundToInt(oldtex->GetDisplayLeftOffset(1) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(1) * gtex->GetScaleY()));
|
||||||
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
|
ReplaceTexture(tlist[i], gtex, true);
|
||||||
ReplaceTexture(tlist[i], newtex, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,21 +752,21 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
|
||||||
|
|
||||||
if (lumpnum>=0)
|
if (lumpnum>=0)
|
||||||
{
|
{
|
||||||
FTexture *newtex = FTexture::CreateTexture(src, lumpnum, ETextureType::Override);
|
auto newtex = MakeGameTexture(CreateTextureFromLump(lumpnum), src, ETextureType::Override);
|
||||||
|
|
||||||
if (newtex != NULL)
|
if (newtex != NULL)
|
||||||
{
|
{
|
||||||
// Replace the entire texture and adjust the scaling and offset factors.
|
// Replace the entire texture and adjust the scaling and offset factors.
|
||||||
newtex->bWorldPanning = true;
|
newtex->SetWorldPanning(true);
|
||||||
newtex->SetDisplaySize(width, height);
|
newtex->SetDisplaySize((float)width, (float)height);
|
||||||
|
|
||||||
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
|
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
|
||||||
if (oldtex.isValid())
|
if (oldtex.isValid())
|
||||||
{
|
{
|
||||||
ReplaceTexture(oldtex, newtex, true);
|
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.
|
// Try to create a texture from this lump and add it.
|
||||||
// Unfortunately we have to look at everything that comes through here...
|
// 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)
|
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)
|
void FTextureManager::SortTexturesByType(int start, int end)
|
||||||
{
|
{
|
||||||
TArray<FTexture *> newtextures;
|
TArray<FGameTexture *> newtextures;
|
||||||
|
|
||||||
// First unlink all newly added textures from the hash chain
|
// First unlink all newly added textures from the hash chain
|
||||||
for (int i = 0; i < HASH_SIZE; i++)
|
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++)
|
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;
|
newtextures[j] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -993,8 +1040,8 @@ void FTextureManager::SortTexturesByType(int start, int end)
|
||||||
{
|
{
|
||||||
if (newtextures[j] != NULL)
|
if (newtextures[j] != NULL)
|
||||||
{
|
{
|
||||||
Printf("Texture %s has unknown type!\n", newtextures[j]->Name.GetChars());
|
Printf("Texture %s has unknown type!\n", newtextures[j]->GetName().GetChars());
|
||||||
AddTexture(newtextures[j]);
|
AddGameTexture(newtextures[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,8 +1079,8 @@ void FTextureManager::AddLocalizedVariants()
|
||||||
FTextureID tex = CheckForTexture(entry.name, ETextureType::MiscPatch);
|
FTextureID tex = CheckForTexture(entry.name, ETextureType::MiscPatch);
|
||||||
if (tex.isValid())
|
if (tex.isValid())
|
||||||
{
|
{
|
||||||
FTexture *otex = GetTexture(origTex);
|
auto otex = GetGameTexture(origTex);
|
||||||
FTexture *ntex = GetTexture(tex);
|
auto ntex = GetGameTexture(tex);
|
||||||
if (otex->GetDisplayWidth() != ntex->GetDisplayWidth() || otex->GetDisplayHeight() != ntex->GetDisplayHeight())
|
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);
|
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
|
// FTextureManager :: Init
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
FTexture *CreateShaderTexture(bool, bool);
|
FGameTexture *CreateShaderTexture(bool, bool);
|
||||||
void InitBuildTiles();
|
void InitBuildTiles();
|
||||||
|
FImageSource* CreateEmptyTexture();
|
||||||
|
|
||||||
void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo&))
|
void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo&))
|
||||||
{
|
{
|
||||||
|
@ -1090,15 +1138,18 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI
|
||||||
DeleteAll();
|
DeleteAll();
|
||||||
//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
|
//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
|
||||||
|
|
||||||
// Texture 0 is a dummy texture used to indicate "no texture"
|
auto nulltex = MakeGameTexture(new FImageTexture(CreateEmptyTexture()), nullptr, ETextureType::Null);
|
||||||
auto nulltex = new FImageTexture(nullptr, "");
|
AddGameTexture(nulltex);
|
||||||
nulltex->SetUseType(ETextureType::Null);
|
|
||||||
AddTexture (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.
|
// some special textures used in the game.
|
||||||
AddTexture(CreateShaderTexture(false, false));
|
AddGameTexture(CreateShaderTexture(false, false));
|
||||||
AddTexture(CreateShaderTexture(false, true));
|
AddGameTexture(CreateShaderTexture(false, true));
|
||||||
AddTexture(CreateShaderTexture(true, false));
|
AddGameTexture(CreateShaderTexture(true, false));
|
||||||
AddTexture(CreateShaderTexture(true, true));
|
AddGameTexture(CreateShaderTexture(true, true));
|
||||||
|
|
||||||
int wadcnt = fileSystem.GetNumWads();
|
int wadcnt = fileSystem.GetNumWads();
|
||||||
|
|
||||||
|
@ -1133,6 +1184,13 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI
|
||||||
glPart = TexMan.CheckForTexture("glstuff/glpart.png", ETextureType::MiscPatch);
|
glPart = TexMan.CheckForTexture("glstuff/glpart.png", ETextureType::MiscPatch);
|
||||||
mirrorTexture = TexMan.CheckForTexture("glstuff/mirror.png", ETextureType::MiscPatch);
|
mirrorTexture = TexMan.CheckForTexture("glstuff/mirror.png", ETextureType::MiscPatch);
|
||||||
AddLocalizedVariants();
|
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);
|
FTextureID pic2 = CheckForTexture(sc.String, ETextureType::Any);
|
||||||
if (!pic2.isValid())
|
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())
|
if (pic1.isValid() && pic2.isValid())
|
||||||
{
|
{
|
||||||
FTexture *owner = GetTexture(pic1);
|
Textures[pic1.GetIndex()].Paletted = pic2.GetIndex();
|
||||||
FTexture *owned = GetTexture(pic2);
|
|
||||||
|
|
||||||
if (owner && owned) owner->PalVersion = owned;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
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);
|
fileSystem.GetFileShortName(str, i);
|
||||||
str[8] = 0;
|
str[8] = 0;
|
||||||
FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 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.
|
// This texture has been replaced by some PWAD.
|
||||||
memcpy(&sprid, str, 4);
|
memcpy(&sprid, str, 4);
|
||||||
|
@ -1349,7 +1483,7 @@ void FTextureManager::AdjustSpriteOffsets()
|
||||||
}
|
}
|
||||||
if (texno.isValid())
|
if (texno.isValid())
|
||||||
{
|
{
|
||||||
FTexture * tex = GetTexture(texno);
|
auto tex = GetGameTexture(texno);
|
||||||
|
|
||||||
int lumpnum = tex->GetSourceLump();
|
int lumpnum = tex->GetSourceLump();
|
||||||
// We only want to change texture offsets for sprites in the IWAD or the file this lump originated from.
|
// 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)
|
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.
|
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
|
||||||
}
|
}
|
||||||
tex->_LeftOffset[1] = x;
|
tex->SetOffsets(1, x, y);
|
||||||
tex->_TopOffset[1] = y;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
|
|
||||||
class FxAddSub;
|
class FxAddSub;
|
||||||
class FTexture;
|
|
||||||
struct BuildInfo;
|
struct BuildInfo;
|
||||||
|
class FMultipatchTextureBuilder;
|
||||||
int PalCheck(int tex);
|
int PalCheck(int tex);
|
||||||
|
|
||||||
// Texture manager
|
// Texture manager
|
||||||
|
@ -25,42 +25,59 @@ public:
|
||||||
private:
|
private:
|
||||||
int ResolveLocalizedTexture(int texnum);
|
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 (animate) texnum = Translation[texnum];
|
||||||
if (localize && Textures[texnum].HasLocalization) texnum = ResolveLocalizedTexture(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;
|
return Textures[texnum].Texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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.
|
// 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);
|
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch);
|
||||||
return InternalGetTexture(texnum.GetIndex(), animate, true, false);
|
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.
|
FGameTexture* GameByIndex(int i, bool animate = false)
|
||||||
FTexture *GetPalettedTexture(FTextureID texnum, bool animate)
|
|
||||||
{
|
{
|
||||||
return InternalGetTexture(texnum.GetIndex(), animate, true, true);
|
return InternalGetTexture(i, animate, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FTexture *ByIndex(int i, bool animate = false)
|
FGameTexture* FindGameTexture(const char* texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
||||||
{
|
|
||||||
return InternalGetTexture(i, animate, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
FTexture *FindTexture(const char *texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
|
||||||
bool OkForLocalization(FTextureID texnum, const char *substitute, int locnum);
|
bool OkForLocalization(FTextureID texnum, const char *substitute, int locnum);
|
||||||
|
|
||||||
void FlushAll();
|
void FlushAll();
|
||||||
|
FTextureID GetFrontSkyLayer(FTextureID);
|
||||||
|
FTextureID GetRawTexture(FTextureID);
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -99,7 +116,7 @@ public:
|
||||||
void AddLocalizedVariants();
|
void AddLocalizedVariants();
|
||||||
|
|
||||||
FTextureID CreateTexture (int lumpnum, ETextureType usetype=ETextureType::Any); // Also calls AddTexture
|
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; }
|
FTextureID GetDefaultTexture() const { return DefaultTexture; }
|
||||||
|
|
||||||
void LoadTextureX(int wadnum, FMultipatchTextureBuilder &build);
|
void LoadTextureX(int wadnum, FMultipatchTextureBuilder &build);
|
||||||
|
@ -107,7 +124,7 @@ public:
|
||||||
void Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo &));
|
void Init(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo &));
|
||||||
void DeleteAll();
|
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(); }
|
int NumTextures () const { return (int)Textures.Size(); }
|
||||||
|
|
||||||
|
@ -144,7 +161,7 @@ public:
|
||||||
return BuildTileData.Last();
|
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);
|
void SetTranslation(FTextureID fromtexnum, FTextureID totexnum);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -155,7 +172,10 @@ private:
|
||||||
|
|
||||||
struct TextureHash
|
struct TextureHash
|
||||||
{
|
{
|
||||||
FTexture *Texture;
|
FGameTexture* Texture;
|
||||||
|
int Paletted; // redirection to paletted variant
|
||||||
|
int FrontSkyLayer; // and front sky layer,
|
||||||
|
int RawTexture;
|
||||||
int HashNext;
|
int HashNext;
|
||||||
bool HasLocalization;
|
bool HasLocalization;
|
||||||
};
|
};
|
||||||
|
@ -185,3 +205,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FTextureManager TexMan;
|
extern FTextureManager TexMan;
|
||||||
|
|
||||||
|
|
|
@ -42,23 +42,33 @@
|
||||||
#include "textureid.h"
|
#include "textureid.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "hw_texcontainer.h"
|
#include "hw_texcontainer.h"
|
||||||
|
#include "floatrect.h"
|
||||||
// 15 because 0th texture is our texture
|
#include "refcounted.h"
|
||||||
#define MAX_CUSTOM_HW_SHADER_TEXTURES 15
|
|
||||||
|
|
||||||
typedef TMap<int, bool> SpriteHits;
|
typedef TMap<int, bool> SpriteHits;
|
||||||
class FImageSource;
|
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
|
enum MaterialShaderIndex
|
||||||
{
|
{
|
||||||
SHADER_Default,
|
SHADER_Default,
|
||||||
SHADER_Warp1,
|
SHADER_Warp1,
|
||||||
SHADER_Warp2,
|
SHADER_Warp2,
|
||||||
SHADER_Brightmap,
|
|
||||||
SHADER_Specular,
|
SHADER_Specular,
|
||||||
SHADER_SpecularBrightmap,
|
|
||||||
SHADER_PBR,
|
SHADER_PBR,
|
||||||
SHADER_PBRBrightmap,
|
|
||||||
SHADER_Paletted,
|
SHADER_Paletted,
|
||||||
SHADER_NoTexture,
|
SHADER_NoTexture,
|
||||||
SHADER_BasicFuzz,
|
SHADER_BasicFuzz,
|
||||||
|
@ -72,46 +82,34 @@ enum MaterialShaderIndex
|
||||||
FIRST_USER_SHADER
|
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
|
struct UserShaderDesc
|
||||||
{
|
{
|
||||||
FString shader;
|
FString shader;
|
||||||
MaterialShaderIndex shaderType;
|
MaterialShaderIndex shaderType;
|
||||||
FString defines;
|
FString defines;
|
||||||
bool disablealphatest = false;
|
bool disablealphatest = false;
|
||||||
|
uint8_t shaderFlags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TArray<UserShaderDesc> usershaders;
|
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;
|
class FBitmap;
|
||||||
struct FRemapTable;
|
struct FRemapTable;
|
||||||
struct FCopyInfo;
|
struct FCopyInfo;
|
||||||
|
@ -141,7 +139,12 @@ enum FTextureFormat : uint32_t
|
||||||
TEX_Count
|
TEX_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
class FSoftwareTexture;
|
class ISoftwareTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ISoftwareTexture() = default;
|
||||||
|
};
|
||||||
|
|
||||||
class FGLRenderState;
|
class FGLRenderState;
|
||||||
|
|
||||||
struct spriteframewithrotate;
|
struct spriteframewithrotate;
|
||||||
|
@ -202,115 +205,62 @@ struct FTextureBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base texture class
|
// Base texture class
|
||||||
class FTexture
|
class FTexture : public RefCountedBase
|
||||||
{
|
{
|
||||||
friend class GLDefsParser;
|
friend class FGameTexture; // only for the porting work
|
||||||
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);
|
|
||||||
|
|
||||||
// For now only give access to classes which cannot be reworked yet. None of these should remain here when all is done.
|
public:
|
||||||
friend class FSoftwareTexture;
|
FHardwareTextureContainer SystemTextures;
|
||||||
friend class FWarpTexture;
|
protected:
|
||||||
friend class FMaterial;
|
FloatRect* areas = nullptr;
|
||||||
friend class OpenGLRenderer::FGLRenderState; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class
|
int SourceLump;
|
||||||
friend class VkRenderState;
|
uint16_t Width = 0, Height = 0;
|
||||||
friend class PolyRenderState;
|
|
||||||
friend struct FTexCoordInfo;
|
bool Masked = false; // Texture (might) have holes
|
||||||
friend class OpenGLRenderer::FHardwareTexture;
|
bool bHasCanvas = false;
|
||||||
friend class VkHardwareTexture;
|
int8_t bTranslucent = -1;
|
||||||
friend class PolyHardwareTexture;
|
int8_t areacount = 0; // this is capped at 4 sections.
|
||||||
friend class FMultiPatchTexture;
|
|
||||||
friend class FSkyBox;
|
|
||||||
friend class FBrightmapTexture;
|
|
||||||
friend class FFont;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
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; }
|
virtual FImageSource *GetImage() const { return nullptr; }
|
||||||
void AddAutoMaterials();
|
|
||||||
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
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.
|
void CleanHardwareTextures()
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
_LeftOffset[0] = _LeftOffset[1] = l;
|
SystemTextures.Clean();
|
||||||
_TopOffset[0] = _TopOffset[1] = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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 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; }
|
int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
|
||||||
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();
|
|
||||||
bool FindHoles(const unsigned char * buffer, int w, int h);
|
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)
|
void CopySize(FTexture* BaseTexture)
|
||||||
{
|
{
|
||||||
Width = BaseTexture->GetTexelWidth();
|
Width = BaseTexture->GetWidth();
|
||||||
Height = BaseTexture->GetTexelHeight();
|
Height = BaseTexture->GetHeight();
|
||||||
_TopOffset[0] = BaseTexture->_TopOffset[0];
|
|
||||||
_TopOffset[1] = BaseTexture->_TopOffset[1];
|
|
||||||
_LeftOffset[0] = BaseTexture->_LeftOffset[0];
|
|
||||||
_LeftOffset[1] = BaseTexture->_LeftOffset[1];
|
|
||||||
Scale = BaseTexture->Scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only used for the null texture and for Heretic's skies.
|
// This is only used for the null texture and for Heretic's skies.
|
||||||
|
@ -320,119 +270,20 @@ public:
|
||||||
Height = h;
|
Height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TrimBorders(uint16_t* rect);
|
||||||
|
int GetAreas(FloatRect** pAreas) const;
|
||||||
|
|
||||||
// Returns the whole texture, stored in column-major order
|
// Returns the whole texture, stored in column-major order
|
||||||
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
||||||
virtual FBitmap GetBgraBitmap(const PalEntry *remap, int *trans = nullptr);
|
virtual FBitmap GetBgraBitmap(const PalEntry *remap, int *trans = nullptr);
|
||||||
|
|
||||||
static bool SmoothEdges(unsigned char * buffer,int w, int h);
|
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() {}
|
virtual void ResolvePatches() {}
|
||||||
|
|
||||||
void SetScale(const DVector2 &scale)
|
|
||||||
{
|
|
||||||
Scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
FTexture (int lumpnum = -1);
|
||||||
uint16_t Width, Height;
|
|
||||||
int16_t _LeftOffset[2], _TopOffset[2];
|
|
||||||
|
|
||||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||||
|
@ -442,27 +293,6 @@ public:
|
||||||
{
|
{
|
||||||
return bTranslucent != -1 ? bTranslucent : DetermineTranslucency();
|
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:
|
public:
|
||||||
|
|
||||||
|
@ -479,17 +309,13 @@ public:
|
||||||
class FCanvasTexture : public FTexture
|
class FCanvasTexture : public FTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FCanvasTexture(const char* name, int width, int height)
|
FCanvasTexture(int width, int height)
|
||||||
{
|
{
|
||||||
Name = name;
|
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
|
|
||||||
bMasked = false;
|
|
||||||
bHasCanvas = true;
|
bHasCanvas = true;
|
||||||
bTranslucent = false;
|
aspectRatio = (float)width / height;
|
||||||
bNoExpand = true;
|
|
||||||
UseType = ETextureType::Wall;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeedUpdate() { bNeedsUpdate = true; }
|
void NeedUpdate() { bNeedsUpdate = true; }
|
||||||
|
@ -501,6 +327,7 @@ protected:
|
||||||
bool bNeedsUpdate = true;
|
bool bNeedsUpdate = true;
|
||||||
public:
|
public:
|
||||||
bool bFirstUpdate = true;
|
bool bFirstUpdate = true;
|
||||||
|
float aspectRatio;
|
||||||
|
|
||||||
friend struct FCanvasTextureInfo;
|
friend struct FCanvasTextureInfo;
|
||||||
};
|
};
|
||||||
|
@ -514,7 +341,7 @@ public:
|
||||||
FWrapperTexture(int w, int h, int bits = 1);
|
FWrapperTexture(int w, int h, int bits = 1);
|
||||||
IHardwareTexture *GetSystemTexture()
|
IHardwareTexture *GetSystemTexture()
|
||||||
{
|
{
|
||||||
return SystemTextures.GetHardwareTexture(0, false);
|
return SystemTextures.GetHardwareTexture(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetColorFormat() const
|
int GetColorFormat() const
|
||||||
|
@ -527,14 +354,19 @@ public:
|
||||||
class FImageTexture : public FTexture
|
class FImageTexture : public FTexture
|
||||||
{
|
{
|
||||||
FImageSource* mImage;
|
FImageSource* mImage;
|
||||||
|
bool bNoRemap0 = false;
|
||||||
|
protected:
|
||||||
|
void SetFromImage();
|
||||||
public:
|
public:
|
||||||
FImageTexture(FImageSource* image, const char* name = nullptr) noexcept;
|
FImageTexture(FImageSource* image) noexcept;
|
||||||
virtual TArray<uint8_t> Get8BitPixels(bool alphatex);
|
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;
|
mImage = img;
|
||||||
|
SetFromImage();
|
||||||
}
|
}
|
||||||
|
void SetNoRemap0() { bNoRemap0 = true; }
|
||||||
|
|
||||||
FImageSource* GetImage() const override { return mImage; }
|
FImageSource* GetImage() const override { return mImage; }
|
||||||
FBitmap GetBgraBitmap(const PalEntry* p, int* trans) override;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static bool TabbedList; // True if tab list was shown
|
||||||
CVAR(Bool, con_notablist, false, CVAR_ARCHIVE)
|
CVAR(Bool, con_notablist, false, CVAR_ARCHIVE)
|
||||||
|
|
||||||
|
|
||||||
static FTexture* conback;
|
static FGameTexture* conback;
|
||||||
static uint32_t conshade;
|
static uint32_t conshade;
|
||||||
static bool conline;
|
static bool conline;
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,7 @@ bool FListMenuItem::Selectable()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FListMenuItem::DrawSelector(int xofs, int yofs, FTexture *tex)
|
void FListMenuItem::DrawSelector(int xofs, int yofs, FGameTexture *tex)
|
||||||
{
|
{
|
||||||
if (!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)
|
: FListMenuItem(x, y)
|
||||||
{
|
{
|
||||||
mTexture = patch;
|
mTexture = patch;
|
||||||
|
@ -414,7 +414,7 @@ void FListMenuItemStaticPatch::Drawer(DListMenu* menu, const DVector2& origin, b
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = mXpos;
|
int x = mXpos;
|
||||||
FTexture *tex = mTexture;
|
FGameTexture *tex = mTexture;
|
||||||
if (mYpos >= 0)
|
if (mYpos >= 0)
|
||||||
{
|
{
|
||||||
if (mCentered) x -= tex->GetDisplayWidth()/2;
|
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)
|
: FListMenuItemSelectable(x, y, height, child, param)
|
||||||
{
|
{
|
||||||
mHotkey = hotkey;
|
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);
|
auto texid = TexMan.CheckForTexture("engine/graphics/m_back.png", ETextureType::Any);
|
||||||
if (texid.isValid())
|
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&1) x -= screen->GetWidth() - tex->GetDisplayWidth() * CleanXfac;
|
||||||
if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetDisplayHeight() * CleanYfac;
|
if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetDisplayHeight() * CleanYfac;
|
||||||
mBackbuttonSelected = ( x >= 0 && x < tex->GetDisplayWidth() * CleanXfac &&
|
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);
|
auto texid = TexMan.CheckForTexture("engine/graphics/m_back.png", ETextureType::Any);
|
||||||
if (texid.isValid())
|
if (texid.isValid())
|
||||||
{
|
{
|
||||||
auto tex = TexMan.GetTexture(texid);
|
auto tex = TexMan.GetGameTexture(texid);
|
||||||
int w = tex->GetDisplayWidth() * CleanXfac;
|
int w = tex->GetDisplayWidth() * CleanXfac;
|
||||||
int h = tex->GetDisplayHeight() * CleanYfac;
|
int h = tex->GetDisplayHeight() * CleanYfac;
|
||||||
int x = (!(m_show_backbutton & 1)) ? 0 : screen->GetWidth() - w;
|
int x = (!(m_show_backbutton & 1)) ? 0 : screen->GetWidth() - w;
|
||||||
|
|
|
@ -107,7 +107,7 @@ enum EMenuSounds : int
|
||||||
EXTERN_CVAR(Bool, menu_sounds)
|
EXTERN_CVAR(Bool, menu_sounds)
|
||||||
|
|
||||||
struct event_t;
|
struct event_t;
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
class FFont;
|
class FFont;
|
||||||
enum EColorRange : int;
|
enum EColorRange : int;
|
||||||
class FPlayerClass;
|
class FPlayerClass;
|
||||||
|
@ -196,7 +196,7 @@ struct FListMenuDescriptor : public FMenuDescriptor
|
||||||
int mSelectedItem;
|
int mSelectedItem;
|
||||||
int mSelectOfsX;
|
int mSelectOfsX;
|
||||||
int mSelectOfsY;
|
int mSelectOfsY;
|
||||||
FTexture *mSelector;
|
FGameTexture *mSelector;
|
||||||
int mDisplayTop;
|
int mDisplayTop;
|
||||||
int mXpos, mYpos, mYbotton;
|
int mXpos, mYpos, mYbotton;
|
||||||
int mWLeft, mWRight;
|
int mWLeft, mWRight;
|
||||||
|
@ -401,7 +401,7 @@ public:
|
||||||
virtual bool MouseEvent(int type, int x, int y);
|
virtual bool MouseEvent(int type, int x, int y);
|
||||||
virtual bool CheckHotkey(int c);
|
virtual bool CheckHotkey(int c);
|
||||||
virtual int GetWidth();
|
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; }
|
void OffsetPositionY(int ydelta) { mYpos += ydelta; }
|
||||||
int GetY() { return mYpos; }
|
int GetY() { return mYpos; }
|
||||||
int GetX() { return mXpos; }
|
int GetX() { return mXpos; }
|
||||||
|
@ -414,11 +414,11 @@ public:
|
||||||
class FListMenuItemStaticPatch : public FListMenuItem
|
class FListMenuItemStaticPatch : public FListMenuItem
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
FTexture *mTexture;
|
FGameTexture *mTexture;
|
||||||
bool mCentered;
|
bool mCentered;
|
||||||
|
|
||||||
public:
|
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);
|
void Drawer(DListMenu* menu, const DVector2& origin, bool selected);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -496,15 +496,15 @@ public:
|
||||||
~FListMenuItemNativeText();
|
~FListMenuItemNativeText();
|
||||||
void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override;
|
void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override;
|
||||||
int GetWidth() 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
|
class FListMenuItemPatch : public FListMenuItemSelectable
|
||||||
{
|
{
|
||||||
FTexture* mTexture;
|
FGameTexture* mTexture;
|
||||||
public:
|
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;
|
void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override;
|
||||||
int GetWidth() override;
|
int GetWidth() override;
|
||||||
};
|
};
|
||||||
|
@ -806,7 +806,7 @@ private:
|
||||||
int LastSaved = -1;
|
int LastSaved = -1;
|
||||||
int LastAccessed = -1;
|
int LastAccessed = -1;
|
||||||
TArray<char> SavePicData;
|
TArray<char> SavePicData;
|
||||||
FTexture *SavePic = nullptr;
|
FGameTexture *SavePic = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int WindowSize = 0;
|
int WindowSize = 0;
|
||||||
|
|
|
@ -104,7 +104,7 @@ void M_DeinitMenus()
|
||||||
DefaultListMenuSettings.mItems.Clear();
|
DefaultListMenuSettings.mItems.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static FTexture* GetMenuTexture(const char* const name)
|
static FGameTexture* GetMenuTexture(const char* const name)
|
||||||
{
|
{
|
||||||
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
||||||
if (!texid.isValid())
|
if (!texid.isValid())
|
||||||
|
@ -112,7 +112,7 @@ static FTexture* GetMenuTexture(const char* const name)
|
||||||
Printf("Missing menu texture: \"%s\"\n", 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;
|
int y = sc.Number;
|
||||||
sc.MustGetStringName(",");
|
sc.MustGetStringName(",");
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FTexture* tex = GetMenuTexture(sc.String);
|
auto tex = GetMenuTexture(sc.String);
|
||||||
|
|
||||||
FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered);
|
FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered);
|
||||||
desc->mItems.Push(it);
|
desc->mItems.Push(it);
|
||||||
|
@ -401,7 +401,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
|
||||||
else if (sc.Compare("PatchItem"))
|
else if (sc.Compare("PatchItem"))
|
||||||
{
|
{
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FTexture* tex = GetMenuTexture(sc.String);
|
auto tex = GetMenuTexture(sc.String);
|
||||||
sc.MustGetStringName(",");
|
sc.MustGetStringName(",");
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
int hotkey = sc.String[0];
|
int hotkey = sc.String[0];
|
||||||
|
|
|
@ -330,7 +330,7 @@ void DTextEnterMenu::Drawer ()
|
||||||
int width;
|
int width;
|
||||||
const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2;
|
const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2;
|
||||||
const int ch = InputGridChars[y * INPUTGRID_WIDTH + x];
|
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;
|
EColorRange color;
|
||||||
int remap;
|
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;
|
auto BaseLayer = pBaseLayer ? (::FHardwareTexture*)pBaseLayer : nullptr;
|
||||||
|
|
||||||
if (BaseLayer == nullptr)
|
if (BaseLayer == nullptr)
|
||||||
|
@ -179,7 +179,7 @@ void FGLRenderer::BindToFrameBuffer(FTexture *mat)
|
||||||
// must create the hardware texture first
|
// must create the hardware texture first
|
||||||
BaseLayer = new ::FHardwareTexture;
|
BaseLayer = new ::FHardwareTexture;
|
||||||
BaseLayer->CreateTexture(mat->GetTexelWidth()*4, mat->GetTexelHeight()*4, ::FHardwareTexture::TrueColor, false);
|
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);
|
BaseLayer->BindToFrameBuffer(mat->GetTexelWidth()*4, mat->GetTexelHeight()*4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
bool StartOffscreen();
|
bool StartOffscreen();
|
||||||
void EndOffscreen();
|
void EndOffscreen();
|
||||||
|
|
||||||
void BindToFrameBuffer(FTexture* tex);
|
void BindToFrameBuffer(FGameTexture* tex);
|
||||||
|
|
||||||
private:
|
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 tex = new FArtTile(backingstore, offset, width, height);
|
||||||
auto p = &backingstore[offset];
|
auto p = &backingstore[offset];
|
||||||
|
@ -122,7 +122,7 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
|
||||||
|
|
||||||
if (tex)
|
if (tex)
|
||||||
{
|
{
|
||||||
return new FImageTexture(tex, name);
|
return MakeGameTexture(new FImageTexture(tex), name, ETextureType::Any);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
|
||||||
|
|
||||||
void BuildTiles::Init()
|
void BuildTiles::Init()
|
||||||
{
|
{
|
||||||
Placeholder = TexMan.ByIndex(0);
|
Placeholder = TexMan.GameByIndex(0);
|
||||||
for (auto& tile : tiledata)
|
for (auto& tile : tiledata)
|
||||||
{
|
{
|
||||||
tile.texture = Placeholder;
|
tile.texture = Placeholder;
|
||||||
|
@ -138,6 +138,7 @@ void BuildTiles::Init()
|
||||||
tile.picanm = {};
|
tile.picanm = {};
|
||||||
tile.RotTile = { -1,-1 };
|
tile.RotTile = { -1,-1 };
|
||||||
tile.replacement = ReplacementType::Art;
|
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.
|
assert(!tex->GetID().isValid()); // must not be added yet.
|
||||||
TexMan.AddTexture(tex);
|
TexMan.AddGameTexture(tex);
|
||||||
tiledata[tilenum].texture = tex;
|
tiledata[tilenum].texture = tex;
|
||||||
if (!permap) tiledata[tilenum].backup = tex;
|
if (!permap) tiledata[tilenum].backup = tex;
|
||||||
}
|
}
|
||||||
|
@ -300,12 +301,12 @@ void BuildTiles::InvalidateTile(int num)
|
||||||
if ((unsigned) num < MAXTILES)
|
if ((unsigned) num < MAXTILES)
|
||||||
{
|
{
|
||||||
auto tex = tiledata[num].texture;
|
auto tex = tiledata[num].texture;
|
||||||
tex->SystemTextures.Clean(true, true);
|
tex->GetTexture()->SystemTextures.Clean();
|
||||||
for (auto &rep : tiledata[num].Hightiles)
|
for (auto &rep : tiledata[num].Hightiles)
|
||||||
{
|
{
|
||||||
for (auto &reptex : rep.faces)
|
for (auto &reptex : rep.faces)
|
||||||
{
|
{
|
||||||
if (reptex) reptex->SystemTextures.Clean(true, true);
|
if (reptex) reptex->GetTexture()->SystemTextures.Clean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tiledata[num].rawCache.data.Clear();
|
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;
|
if (tilenum < 0 || tilenum >= MAXTILES) return nullptr;
|
||||||
auto &td = tiledata[tilenum];
|
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...
|
// 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.
|
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.
|
// 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)
|
else if (type == ReplacementType::Canvas)
|
||||||
{
|
{
|
||||||
replacement = new FCanvasTexture("camera", 0, 0);
|
replacement = new FCanvasTexture(0, 0);
|
||||||
}
|
}
|
||||||
else return nullptr;
|
else return nullptr;
|
||||||
AddTile(tilenum, replacement);
|
auto reptex = MakeGameTexture(replacement, "", ETextureType::Any);
|
||||||
return replacement;
|
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;
|
if (width <= 0 || height <= 0) return nullptr;
|
||||||
auto tex = ValidateCustomTile(tilenum, ReplacementType::Writable);
|
auto tex = ValidateCustomTile(tilenum, ReplacementType::Writable);
|
||||||
if (tex == nullptr) return nullptr;
|
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;
|
if (!wtex->ResizeImage(width, height)) return nullptr;
|
||||||
tex->SetSize(width, height);
|
tex->SetSize(width, height);
|
||||||
return wtex->GetRawData();
|
return wtex->GetRawData();
|
||||||
|
@ -486,7 +488,7 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
|
||||||
uint8_t* BuildTiles::tileMakeWritable(int num)
|
uint8_t* BuildTiles::tileMakeWritable(int num)
|
||||||
{
|
{
|
||||||
auto tex = ValidateCustomTile(num, ReplacementType::Restorable);
|
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;
|
return wtex ? wtex->GetRawData() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +501,7 @@ uint8_t* BuildTiles::tileMakeWritable(int num)
|
||||||
int32_t tileGetCRC32(int tileNum)
|
int32_t tileGetCRC32(int tileNum)
|
||||||
{
|
{
|
||||||
if ((unsigned)tileNum >= (unsigned)MAXTILES) return 0;
|
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;
|
if (!tile) return 0;
|
||||||
auto pixels = tile->GetRawData();
|
auto pixels = tile->GetRawData();
|
||||||
if (!pixels) return 0;
|
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);
|
FTextureID texid = TexMan.CheckForTexture(fn, ETextureType::Any);
|
||||||
if (!texid.isValid()) return -1;
|
if (!texid.isValid()) return -1;
|
||||||
auto tex = TexMan.GetTexture(texid);
|
auto tex = TexMan.GetGameTexture(texid);
|
||||||
//tex->alphaThreshold = 255 - alphacut;
|
//tex->alphaThreshold = 255 - alphacut;
|
||||||
|
|
||||||
int32_t xsiz = tex->GetTexelWidth(), ysiz = tex->GetTexelHeight();
|
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* picanm = nullptr;
|
||||||
picanm_t* sourceanm = nullptr;
|
picanm_t* sourceanm = nullptr;
|
||||||
int srcxo, srcyo;
|
int srcxo, srcyo;
|
||||||
FTexture* tex;
|
FGameTexture* tex;
|
||||||
|
|
||||||
if (pal == -1 && tile == source)
|
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);
|
srcxo = tex->GetTexelLeftOffset(0);
|
||||||
srcyo = tex->GetTexelTopOffset(0);
|
srcyo = tex->GetTexelTopOffset(0);
|
||||||
|
|
||||||
TArray<uint8_t> buffer = tex->Get8BitPixels(false);
|
TArray<uint8_t> buffer = tex->GetTexture()->Get8BitPixels(false);
|
||||||
|
|
||||||
if (pal != -1)
|
if (pal != -1)
|
||||||
{
|
{
|
||||||
|
@ -604,7 +606,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
|
||||||
pixel = remap[pixel];
|
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;
|
picanm = &TileFiles.tiledata[tile].picanm;
|
||||||
TileFiles.AddTile(tile, tex);
|
TileFiles.AddTile(tile, tex);
|
||||||
}
|
}
|
||||||
|
@ -656,7 +658,7 @@ void artSetupMapArt(const char* filename)
|
||||||
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
|
||||||
if (texid.isValid())
|
if (texid.isValid())
|
||||||
{
|
{
|
||||||
TileFiles.tiledata[i].texture = TexMan.GetTexture(texid);
|
TileFiles.tiledata[i].texture = TexMan.GetGameTexture(texid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -691,7 +693,7 @@ void artSetupMapArt(const char* filename)
|
||||||
void tileDelete(int tile)
|
void tileDelete(int tile)
|
||||||
{
|
{
|
||||||
TileFiles.TextureToTile.Remove(tileGetTexture(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);
|
vox_undefine(tile);
|
||||||
md_undefinetile(tile);
|
md_undefinetile(tile);
|
||||||
tileRemoveReplacement(tile);
|
tileRemoveReplacement(tile);
|
||||||
|
@ -723,7 +725,7 @@ void tileSetDummy(int tile, int width, int height)
|
||||||
}
|
}
|
||||||
else if (width > 0 && height > 0)
|
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);
|
TileFiles.AddTile(tile, dtile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -760,7 +762,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
|
||||||
if ((unsigned)tileNum >= MAXTILES) return tileNum;
|
if ((unsigned)tileNum >= MAXTILES) return tileNum;
|
||||||
auto tex = tileGetTexture(tileNum);
|
auto tex = tileGetTexture(tileNum);
|
||||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return 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);
|
TArray<uint8_t> dbuffer(tex->GetTexelWidth() * tex->GetTexelHeight(), true);
|
||||||
|
|
||||||
auto src = buffer.Data();
|
auto src = buffer.Data();
|
||||||
|
@ -777,7 +779,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
|
||||||
*(dst + y * width + xofs) = *(src + y + yofs);
|
*(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();
|
int index = findUnusedTile();
|
||||||
bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup;
|
bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup;
|
||||||
TileFiles.AddTile(index, dtex, mapart);
|
TileFiles.AddTile(index, dtex, mapart);
|
||||||
|
@ -821,7 +823,7 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
replace.faces[0] = TexMan.GetTexture(texid);
|
replace.faces[0] = TexMan.GetGameTexture(texid);
|
||||||
if (replace.faces[0] == nullptr)
|
if (replace.faces[0] == nullptr)
|
||||||
replace.alphacut = min(alphacut,1.f);
|
replace.alphacut = min(alphacut,1.f);
|
||||||
replace.scale = { xscale, yscale };
|
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);
|
Printf("%s: Skybox image for tile %d does not exist or is invalid\n", *facenames, picnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
face = TexMan.GetTexture(texid);
|
face = TexMan.GetGameTexture(texid);
|
||||||
}
|
}
|
||||||
replace.flags = flags;
|
replace.flags = flags;
|
||||||
replace.palnum = (uint16_t)palnum;
|
replace.palnum = (uint16_t)palnum;
|
||||||
|
|
|
@ -62,7 +62,7 @@ struct rottile_t
|
||||||
|
|
||||||
struct HightileReplacement
|
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;
|
vec2f_t scale;
|
||||||
float alphacut, specpower, specfactor;
|
float alphacut, specpower, specfactor;
|
||||||
uint16_t palnum, flags;
|
uint16_t palnum, flags;
|
||||||
|
@ -257,23 +257,24 @@ struct RawCacheNode
|
||||||
|
|
||||||
struct TileDesc
|
struct TileDesc
|
||||||
{
|
{
|
||||||
FTexture* texture; // the currently active tile
|
FGameTexture* texture; // the currently active tile
|
||||||
FTexture* backup; // original backup for map tiles
|
FGameTexture* backup; // original backup for map tiles
|
||||||
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
|
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
|
||||||
picanm_t picanm; // animation descriptor
|
picanm_t picanm; // animation descriptor
|
||||||
picanm_t picanmbackup; // animation descriptor backup when using map tiles
|
picanm_t picanmbackup; // animation descriptor backup when using map tiles
|
||||||
rottile_t RotTile;// = { -1,-1 };
|
rottile_t RotTile;// = { -1,-1 };
|
||||||
TArray<HightileReplacement> Hightiles;
|
TArray<HightileReplacement> Hightiles;
|
||||||
ReplacementType replacement;
|
ReplacementType replacement;
|
||||||
|
FixedBitArray<256> NoBrightmapFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuildTiles
|
struct BuildTiles
|
||||||
{
|
{
|
||||||
FTexture* Placeholder;
|
FGameTexture* Placeholder;
|
||||||
TDeletingArray<BuildArtFile*> ArtFiles;
|
TDeletingArray<BuildArtFile*> ArtFiles;
|
||||||
TileDesc tiledata[MAXTILES];
|
TileDesc tiledata[MAXTILES];
|
||||||
TArray<FString> addedArt;
|
TArray<FString> addedArt;
|
||||||
TMap<FTexture*, int> TextureToTile;
|
TMap<FGameTexture*, int> TextureToTile;
|
||||||
TArray<FString> maptilesadded;
|
TArray<FString> maptilesadded;
|
||||||
|
|
||||||
void Init(); // This cannot be a constructor because it needs the texture manager running.
|
void Init(); // This cannot be a constructor because it needs the texture manager running.
|
||||||
|
@ -284,7 +285,7 @@ struct BuildTiles
|
||||||
|
|
||||||
void CloseAll();
|
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);
|
void AddTiles(int firsttile, TArray<uint8_t>& store, const char* mapname);
|
||||||
|
|
||||||
|
@ -302,7 +303,7 @@ struct BuildTiles
|
||||||
{
|
{
|
||||||
addedArt = std::move(art);
|
addedArt = std::move(art);
|
||||||
}
|
}
|
||||||
int GetTileIndex(FTexture* tex)
|
int GetTileIndex(FGameTexture* tex)
|
||||||
{
|
{
|
||||||
auto p = TextureToTile.CheckKey(tex);
|
auto p = TextureToTile.CheckKey(tex);
|
||||||
return p ? *p : -1;
|
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);
|
int32_t artLoadFiles(const char* filename);
|
||||||
uint8_t* tileMakeWritable(int num);
|
uint8_t* tileMakeWritable(int num);
|
||||||
uint8_t* tileCreate(int tilenum, int width, int height);
|
uint8_t* tileCreate(int tilenum, int width, int height);
|
||||||
void tileSetExternal(int tilenum, int width, int height, uint8_t* data);
|
|
||||||
int findUnusedTile(void);
|
int findUnusedTile(void);
|
||||||
int tileCreateRotated(int owner);
|
int tileCreateRotated(int owner);
|
||||||
void ClearTextureCache(bool artonly = false);
|
|
||||||
void InvalidateTile(int num);
|
void InvalidateTile(int num);
|
||||||
void MakeCanvas(int tilenum, int width, int height);
|
void MakeCanvas(int tilenum, int width, int height);
|
||||||
HightileReplacement* FindReplacement(int picnum, int palnum, bool skybox = false);
|
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;
|
auto tex = TileFiles.tiledata[num].texture;
|
||||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return nullptr;
|
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();
|
TileFiles.tiledata[num].rawCache.lastUseTime = I_nsTime();
|
||||||
return TileFiles.tiledata[num].rawCache.data.Data();
|
return TileFiles.tiledata[num].rawCache.data.Data();
|
||||||
|
@ -381,7 +380,7 @@ inline bool tileLoad(int tileNum)
|
||||||
inline uint8_t* tileData(int num)
|
inline uint8_t* tileData(int num)
|
||||||
{
|
{
|
||||||
auto tex = TileFiles.tiledata[num].texture;
|
auto tex = TileFiles.tiledata[num].texture;
|
||||||
auto p = dynamic_cast<FWritableTile*>(tex);
|
auto p = dynamic_cast<FWritableTile*>(tex->GetTexture());
|
||||||
return p ? p->GetRawData() : nullptr;
|
return p ? p->GetRawData() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +463,7 @@ inline void tileInvalidate(int tilenume, int32_t, int32_t)
|
||||||
TileFiles.InvalidateTile(tilenume);
|
TileFiles.InvalidateTile(tilenume);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline FTexture* tileGetTexture(int tile)
|
inline FGameTexture* tileGetTexture(int tile)
|
||||||
{
|
{
|
||||||
assert(tile < MAXTILES);
|
assert(tile < MAXTILES);
|
||||||
return TileFiles.tiledata[tile].texture;
|
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() };
|
vec2_t siz = { tex->GetTexelWidth(), tex->GetTexelHeight() };
|
||||||
|
|
||||||
auto store = tex->Get8BitPixels(false);
|
auto store = tex->GetTexture()->Get8BitPixels(false);
|
||||||
const uint8_t* p = store.Data();
|
const uint8_t* p = store.Data();
|
||||||
|
|
||||||
auto glpic = GLInterface.NewTexture();
|
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.
|
// Check if the texture is fully transparent. When creating a brightmap such textures can be discarded.
|
||||||
if (checkfulltransparency)
|
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;
|
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;
|
if (phwtex) return (FHardwareTexture*)phwtex;
|
||||||
|
|
||||||
FHardwareTexture *hwtex = nullptr;
|
FHardwareTexture *hwtex = nullptr;
|
||||||
if (textype == TT_INDEXED)
|
if (textype == TT_INDEXED)
|
||||||
hwtex = CreateIndexedTexture(tex);
|
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);
|
hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP);
|
||||||
else
|
else
|
||||||
hwtex = nullptr;
|
hwtex = nullptr;
|
||||||
|
|
||||||
if (hwtex) tex->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
if (hwtex) tex->GetTexture()->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
||||||
return hwtex;
|
return hwtex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
||||||
|
|
||||||
struct TexturePick
|
struct TexturePick
|
||||||
{
|
{
|
||||||
FTexture* texture; // which texture to use
|
FGameTexture* texture; // which texture to use
|
||||||
int translation; // which translation table to use
|
int translation; // which translation table to use
|
||||||
int tintFlags; // which shader tinting options to use
|
int tintFlags; // which shader tinting options to use
|
||||||
PalEntry tintColor; // Tint color
|
PalEntry tintColor; // Tint color
|
||||||
|
@ -165,7 +165,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
|
||||||
auto tex = TileFiles.tiles[tilenum];
|
auto tex = TileFiles.tiles[tilenum];
|
||||||
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? TileFiles.FindReplacement(tilenum, usepalswap) : nullptr;
|
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.
|
// 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;
|
bool applytint = false;
|
||||||
if (truecolor)
|
if (truecolor)
|
||||||
{
|
{
|
||||||
|
@ -203,7 +203,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
if (tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
|
||||||
int usepalette = fixpalette >= 0 ? fixpalette : curbasepal;
|
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.
|
// 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.
|
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;
|
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)
|
if (usepalette != 0)
|
||||||
{
|
{
|
||||||
|
@ -338,7 +338,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 1
|
#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)
|
if (TextureType == TT_HICREPLACE)
|
||||||
{
|
{
|
||||||
|
@ -364,7 +364,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
||||||
if (htex == nullptr)
|
if (htex == nullptr)
|
||||||
{
|
{
|
||||||
// Flag the texture as not being brightmapped for the given palette
|
// Flag the texture as not being brightmapped for the given palette
|
||||||
tex->NoBrightmapFlag.Set(usepalswap);
|
TileFiles.tiledata[picnum].NoBrightmapFlag.Set(usepalswap);
|
||||||
}
|
}
|
||||||
else
|
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);
|
auto mtex = LoadTexture(tex, palette>= 0? TT_TRUECOLOR : TT_HICREPLACE, palette);
|
||||||
if (!mtex) return false;
|
if (!mtex) return false;
|
||||||
|
@ -417,11 +417,6 @@ int PalCheck(int tex)
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteSoftwareTexture(FSoftwareTexture *)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitBuildTiles()
|
void InitBuildTiles()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class FSamplerManager;
|
||||||
class FShader;
|
class FShader;
|
||||||
class PolymostShader;
|
class PolymostShader;
|
||||||
class SurfaceShader;
|
class SurfaceShader;
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
class GLInstance;
|
class GLInstance;
|
||||||
class F2DDrawer;
|
class F2DDrawer;
|
||||||
struct palette_t;
|
struct palette_t;
|
||||||
|
@ -115,7 +115,7 @@ class GLInstance
|
||||||
PaletteManager palmanager;
|
PaletteManager palmanager;
|
||||||
int lastPalswapIndex = -1;
|
int lastPalswapIndex = -1;
|
||||||
FHardwareTexture* texv;
|
FHardwareTexture* texv;
|
||||||
FTexture* currentTexture = nullptr;
|
FGameTexture* currentTexture = nullptr;
|
||||||
int TextureType;
|
int TextureType;
|
||||||
int MatrixChange = 0;
|
int MatrixChange = 0;
|
||||||
|
|
||||||
|
@ -474,19 +474,19 @@ public:
|
||||||
renderState.AlphaThreshold = al;
|
renderState.AlphaThreshold = al;
|
||||||
}
|
}
|
||||||
|
|
||||||
FHardwareTexture* CreateIndexedTexture(FTexture* tex);
|
FHardwareTexture* CreateIndexedTexture(FGameTexture* tex);
|
||||||
FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
FHardwareTexture* CreateTrueColorTexture(FGameTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
||||||
FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
|
FHardwareTexture *LoadTexture(FGameTexture* tex, int texturetype, int palid);
|
||||||
bool SetTextureInternal(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow);
|
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);
|
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);
|
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
|
// The ini could not be saved at exit
|
||||||
bool I_WriteIniFailed ();
|
bool I_WriteIniFailed ();
|
||||||
|
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
bool I_SetCursor(FTexture *);
|
bool I_SetCursor(FGameTexture *);
|
||||||
|
|
||||||
static inline char *strlwr(char *str)
|
static inline char *strlwr(char *str)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,14 +38,14 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
bool I_SetCursor(FTexture *cursorpic)
|
bool I_SetCursor(FGameTexture *cursorpic)
|
||||||
{
|
{
|
||||||
static SDL_Cursor *cursor;
|
static SDL_Cursor *cursor;
|
||||||
static SDL_Surface *cursorSurface;
|
static SDL_Surface *cursorSurface;
|
||||||
|
|
||||||
if (cursorpic != NULL)
|
if (cursorpic != NULL)
|
||||||
{
|
{
|
||||||
auto src = cursorpic->GetBgraBitmap(nullptr);
|
auto src = cursorpic->GetTexture()->GetBgraBitmap(nullptr);
|
||||||
// Must be no larger than 32x32.
|
// Must be no larger than 32x32.
|
||||||
if (src.GetWidth() > 32 || src.GetHeight() > 32)
|
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;
|
HCURSOR cursor;
|
||||||
|
|
||||||
if (cursorpic != NULL)
|
if (cursorpic != NULL)
|
||||||
{
|
{
|
||||||
auto image = cursorpic->GetBgraBitmap(nullptr);
|
auto image = cursorpic->GetTexture()->GetBgraBitmap(nullptr);
|
||||||
// Must be no larger than 32x32. (is this still necessary?
|
// Must be no larger than 32x32. (is this still necessary?
|
||||||
if (image.GetWidth() > 32 || image.GetHeight() > 32)
|
if (image.GetWidth() > 32 || image.GetHeight() > 32)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,8 +62,8 @@ void I_Quit (void);
|
||||||
void I_Tactile (int on, int off, int total);
|
void I_Tactile (int on, int off, int total);
|
||||||
|
|
||||||
// Set the mouse cursor. The texture must be 32x32.
|
// Set the mouse cursor. The texture must be 32x32.
|
||||||
class FTexture;
|
class FGameTexture;
|
||||||
bool I_SetCursor(FTexture *cursor);
|
bool I_SetCursor(FGameTexture *cursor);
|
||||||
|
|
||||||
// Repaint the pre-game console
|
// Repaint the pre-game console
|
||||||
void I_PaintConsole (void);
|
void I_PaintConsole (void);
|
||||||
|
|
Loading…
Reference in a new issue