diff --git a/source/build/src/animvpx.cpp b/source/build/src/animvpx.cpp index a612db7b0..88446425c 100644 --- a/source/build/src/animvpx.cpp +++ b/source/build/src/animvpx.cpp @@ -398,7 +398,7 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect) if (!texuploaded) { - texture->CreateTexture(codec->width, codec->height, false, false); + texture->CreateTexture(codec->width, codec->height, FHardwareTexture::TrueColor, false); texuploaded = 1; } texture->LoadTexture(codec->pic); diff --git a/source/build/src/glsurface.cpp b/source/build/src/glsurface.cpp index 1e5589725..d396eb7b2 100644 --- a/source/build/src/glsurface.cpp +++ b/source/build/src/glsurface.cpp @@ -27,7 +27,7 @@ bool glsurface_initialize(vec2_t bufferResolution) buffer.Resize(bufferRes.x * bufferRes.y); bufferTexture = GLInterface.NewTexture(); - bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, true, false); + bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, FHardwareTexture::Indexed, false); glsurface_setPalette(curpalettefaded); GLInterface.SetSurfaceShader(); @@ -52,7 +52,7 @@ void glsurface_setPalette(void* pPalette) if (!paletteTexture) { paletteTexture = GLInterface.NewTexture(); - paletteTexture->CreateTexture(256, 1, false, false); + paletteTexture->CreateTexture(256, 1, FHardwareTexture::TrueColor, false); } paletteTexture->LoadTexture(palette); GLInterface.BindTexture(1, paletteTexture, SamplerNoFilterClampXY); diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 87467ac80..eca268cd7 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -5230,7 +5230,7 @@ static int32_t gen_font_glyph_tex(void) } } - polymosttext->CreateTexture(256, 128, false, false); + polymosttext->CreateTexture(256, 128, FHardwareTexture::TrueColor, false); polymosttext->LoadTexture((uint8_t*)tbuf); polymosttext->SetSampler(SamplerNoFilterClampXY); Xfree(tbuf); diff --git a/source/build/src/texcache.cpp b/source/build/src/texcache.cpp index 4d47805a3..7ff1586e1 100644 --- a/source/build/src/texcache.cpp +++ b/source/build/src/texcache.cpp @@ -51,7 +51,7 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex) } auto glpic = GLInterface.NewTexture(); - glpic->CreateTexture(siz.x, siz.y, true, false); + glpic->CreateTexture(siz.x, siz.y, FHardwareTexture::Indexed, false); TArray<uint8_t> flipped(siz.x * siz.y, true); FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y); @@ -65,7 +65,7 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex) // //=========================================================================== -FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency) +FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit) { auto siz = tex->GetSize(); bool npoty = false; @@ -89,7 +89,10 @@ FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, b } auto glpic = GLInterface.NewTexture(); - glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, false, true); + if (!rgb8bit) + glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, FHardwareTexture::TrueColor, true); + else + glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, FHardwareTexture::Brightmap, false); // Use a more memory friendly format for simple brightmaps. glpic->LoadTexture(texbuffer.mBuffer); return glpic; } @@ -110,7 +113,7 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid) if (textype == TT_INDEXED) hwtex = CreateIndexedTexture(tex); else - hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP); + hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP); tex->SetHardwareTexture(palid, hwtex); return hwtex; diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index dd1343513..55ffcbec3 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -69,7 +69,7 @@ FHardwareTexture *gloadtex(const int32_t *picbuf, int32_t xsiz, int32_t ysiz, in } auto tex = GLInterface.NewTexture(); - tex->CreateTexture(xsiz, ysiz, false, false); + tex->CreateTexture(xsiz, ysiz, FHardwareTexture::TrueColor, false); tex->LoadTexture((uint8_t*)pic2); tex->SetSampler(SamplerNoFilterClampXY); Xfree(pic2); diff --git a/source/glbackend/gl_hwtexture.cpp b/source/glbackend/gl_hwtexture.cpp index 61a0330a1..0ee7aedc1 100644 --- a/source/glbackend/gl_hwtexture.cpp +++ b/source/glbackend/gl_hwtexture.cpp @@ -38,20 +38,21 @@ // //=========================================================================== -unsigned int FHardwareTexture::CreateTexture(int w, int h, bool eightbit, bool mipmapped) +unsigned int FHardwareTexture::CreateTexture(int w, int h, int type, bool mipmapped) { + static int gltypes[] = { GL_R8, GL_RGBA8, GL_RGB5_A1, GL_RGBA2 }; glTexID = GLInterface.GetTextureID(); glActiveTexture(GL_TEXTURE15); glBindTexture(GL_TEXTURE_2D, glTexID); int size = std::max(w, h); int bits = 0; while (size) bits++, size >>= 1; - glTextureBytes = eightbit? 1 : 4; - if (eightbit) mipmapped = false; + internalType = type; + if (type == Indexed) mipmapped = false; mWidth = w; mHeight = h; - glTexStorage2D(GL_TEXTURE_2D, mipmapped? bits : 1, eightbit? GL_R8 : GL_RGBA8, w, h); + glTexStorage2D(GL_TEXTURE_2D, mipmapped? bits : 1, gltypes[type], w, h); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); this->mipmapped = mipmapped; @@ -85,20 +86,19 @@ unsigned int FHardwareTexture::LoadTexturePart(const unsigned char* buffer, int { if (glTexID == 0) return 0; - int dstformat = glTextureBytes == 1 ? GL_R8 : GL_RGBA8;// TexFormat[gl_texture_format]; - int srcformat = glTextureBytes == 1 ? GL_RED : GL_BGRA;// TexFormat[gl_texture_format]; + int srcformat = internalType == Indexed ? GL_RED : GL_BGRA;// TexFormat[gl_texture_format]; glActiveTexture(GL_TEXTURE15); glBindTexture(GL_TEXTURE_2D, glTexID); - if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (internalType == Indexed) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, srcformat, GL_UNSIGNED_BYTE, buffer); if (mipmapped) glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); - if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + if (internalType == Indexed) glPixelStorei(GL_UNPACK_ALIGNMENT, 4); return glTexID; } diff --git a/source/glbackend/gl_hwtexture.h b/source/glbackend/gl_hwtexture.h index 363663f33..917661701 100644 --- a/source/glbackend/gl_hwtexture.h +++ b/source/glbackend/gl_hwtexture.h @@ -10,12 +10,19 @@ class FTexture; class FHardwareTexture //: public IHardwareTexture { public: + enum + { + Indexed, + TrueColor, + HighColor, // 16 bit - Can be used to save space in memory constrained scenarios at the cost of visual accuracy. + Brightmap, // This can be stored as RGBA2 to save space, it also doesn't really need a mipmap. + }; private: int mSampler = 0; unsigned int glTexID = 0; - int glTextureBytes = 4; + int internalType = TrueColor; bool mipmapped = true; int mWidth = 0, mHeight = 0; int colorId = 0; @@ -26,56 +33,18 @@ public: //bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags); - unsigned int CreateTexture(int w, int h, bool eightbit, bool mipmapped); + unsigned int CreateTexture(int w, int h, bool type, bool mipmapped) = delete; + unsigned int CreateTexture(int w, int h, int type, bool mipmapped); unsigned int LoadTexture(const unsigned char * buffer); unsigned int LoadTexturePart(const unsigned char* buffer, int x, int y, int w, int h); unsigned int LoadTexture(FBitmap &bmp); unsigned int GetTextureHandle(); int GetSampler() { return mSampler; } void SetSampler(int sampler) { mSampler = sampler; } - bool isIndexed() const { return glTextureBytes == 1; } + bool isIndexed() const { return internalType == Indexed; } friend class FGameTexture; }; -// This class identifies a single source image to the game. -// Since hightile palette variations are identified by file name, they will create separate game textures. -class FGameTexture -{ - int Width, Height; - bool isHightile; - - // Source image for this texture. - FTexture* sourceData = nullptr; - // indexed or the sole image for hightiles. - FHardwareTexture* hwBase = nullptr; - // If the number was large a TMap would be better - - // but in most cases the maximum number of palettes for a single tile is less than 10 where a linear search is much faster than a TMap. - TArray<FHardwareTexture*> hwTextures; -public: - FGameTexture(bool hightile, int width, int height); - virtual ~FGameTexture(); - - // For dynamic subtypes. - virtual void SizeChanged(int width, int height); - static constexpr int MakeId(int palette, int palswap) - { - return palette + 256 * palswap; - } - - FHardwareTexture* GetBaseTexture(); - FHardwareTexture* CreateHardwareTexture(int palette, int palswap); - - FHardwareTexture* GetHardwareTexture(int palette, int palswap) - { - if (isHightile) return GetBaseTexture(); - auto id = MakeId(palette, palswap); - auto found = hwTextures.FindEx([=](FHardwareTexture* tex) - { - return tex->colorId == id; - }); - if (!found) return CreateHardwareTexture(palette, palswap); - } -}; #endif diff --git a/source/glbackend/gl_palmanager.cpp b/source/glbackend/gl_palmanager.cpp index 5a25e643b..4a02ee4e2 100644 --- a/source/glbackend/gl_palmanager.cpp +++ b/source/glbackend/gl_palmanager.cpp @@ -195,7 +195,7 @@ void PaletteManager::BindPalette(int index) if (palettes[uindex].paltexture == nullptr) { auto p = GLInterface.NewTexture(); - p->CreateTexture(256, 1, false, false); + p->CreateTexture(256, 1, FHardwareTexture::TrueColor, false); p->LoadTexture((uint8_t*)palettes[uindex].colors); p->SetSampler(SamplerNoFilterClampXY); palettes[uindex].paltexture = p; @@ -237,7 +237,7 @@ void PaletteManager::BindPalswap(int index) if (ps.swaptexture == nullptr) { auto p = GLInterface.NewTexture(); - p->CreateTexture(256, numshades, true, false); + p->CreateTexture(256, numshades, FHardwareTexture::Indexed, false); p->LoadTexture((uint8_t*)ps.lookup); p->SetSampler(SamplerNoFilterClampXY); ps.swaptexture = p; diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index d659a5ef3..5c44220cf 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -245,9 +245,7 @@ public: int GetTextureID(); FHardwareTexture* NewTexture(); - FGameTexture* NewTexture(const char *name, bool hightile); void BindTexture(int texunit, FHardwareTexture *texid, int sampler = NoSampler); - void BindTexture(int texunit, FGameTexture* texid, int sampler = NoSampler); void UnbindTexture(int texunit); void UnbindAllTextures(); void EnableBlend(bool on); @@ -395,7 +393,7 @@ public: } FHardwareTexture* CreateIndexedTexture(FTexture* tex); - FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false); + FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false); FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid); bool SetTextureInternal(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow);