diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index 4ea5bfc0b..f0baf6f9d 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -2050,7 +2050,8 @@ void OpenGLSWFrameBuffer::Atlas::FreeBox(OpenGLSWFrameBuffer::PackedTexture *box // //========================================================================== -OpenGLSWFrameBuffer::OpenGLTex::OpenGLTex(FTexture *tex, OpenGLSWFrameBuffer *fb, bool wrapping) +OpenGLSWFrameBuffer::OpenGLTex::OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping) + : FNativeTexture(tex, fmt) { // Attach to the texture list for the OpenGLSWFrameBuffer Next = fb->Textures; @@ -2090,7 +2091,7 @@ OpenGLSWFrameBuffer::OpenGLTex::~OpenGLTex() // Remove link from the game texture if (GameTex != nullptr) { - GameTex->Native = nullptr; + mGameTex->Native[mFormat] = nullptr; } } @@ -2199,7 +2200,7 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Update() { dest += pitch + (format == GL_R8 ? 1 : 4); } - GameTex->FillBuffer(dest, pitch, GameTex->GetHeight(), ToTexFmt(format)); + GameTex->FillBuffer(dest, pitch, GameTex->GetHeight(), mFormat); if (Box->Padded) { // Clear top padding row. @@ -2265,50 +2266,25 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Update() int OpenGLSWFrameBuffer::OpenGLTex::GetTexFormat() { - FTextureFormat fmt = GameTex->GetFormat(); - IsGray = false; - switch (fmt) + switch (mFormat) { case TEX_Pal: return GL_R8; case TEX_Gray: IsGray = true; return GL_R8; case TEX_RGB: return GL_RGBA8; +#if 0 case TEX_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; case TEX_DXT2: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; case TEX_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case TEX_DXT4: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; // Doesn't exist in OpenGL. Closest match is DXT5. case TEX_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; +#endif default: I_FatalError("GameTex->GetFormat() returned invalid format."); } return GL_R8; } -//========================================================================== -// -// OpenGLTex :: ToTexFmt -// -// Converts an OpenGL internal format constant to something the FTexture system -// understands. -// -//========================================================================== - -FTextureFormat OpenGLSWFrameBuffer::OpenGLTex::ToTexFmt(int fmt) -{ - switch (fmt) - { - case GL_R8: return IsGray ? TEX_Gray : TEX_Pal; - case GL_RGBA8: return TEX_RGB; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return TEX_DXT1; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return TEX_DXT2; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return TEX_DXT3; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return TEX_DXT5; - default: - assert(0); // LOL WUT? - return TEX_Pal; - } -} - //========================================================================== // // OpenGLPal Constructor @@ -2540,9 +2516,9 @@ void OpenGLSWFrameBuffer::DrawBlendingRect() // //========================================================================== -FNativeTexture *OpenGLSWFrameBuffer::CreateTexture(FTexture *gametex, bool wrapping) +FNativeTexture *OpenGLSWFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) { - OpenGLTex *tex = new OpenGLTex(gametex, this, wrapping); + OpenGLTex *tex = new OpenGLTex(gametex, fmt, this, wrapping); if (tex->Box == nullptr) { delete tex; @@ -2767,7 +2743,12 @@ void OpenGLSWFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) return; } - OpenGLTex *tex = static_cast(img->GetNative(false)); + FTextureFormat fmt; + if (parms.style.Flags & STYLEF_RedIsAlpha) fmt = TEX_Gray; + else if (parms.remap != nullptr) fmt = TEX_Pal; + else fmt = img->GetFormat(); + + OpenGLTex *tex = static_cast(img->GetNative(fmt, false)); if (tex == nullptr) { @@ -2944,7 +2925,7 @@ void OpenGLSWFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTe { return; } - OpenGLTex *tex = static_cast(src->GetNative(true)); + OpenGLTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); if (tex == nullptr) { return; @@ -3069,7 +3050,7 @@ void OpenGLSWFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, in { return; } - tex = static_cast(texture->GetNative(true)); + tex = static_cast(texture->GetNative(texture->GetFormat(), true)); if (tex == nullptr) { return; diff --git a/src/gl/system/gl_swframebuffer.h b/src/gl/system/gl_swframebuffer.h index 8c45b17af..401c0a072 100644 --- a/src/gl/system/gl_swframebuffer.h +++ b/src/gl/system/gl_swframebuffer.h @@ -49,7 +49,7 @@ public: void SetBlendingRect(int x1, int y1, int x2, int y2) override; bool Begin2D(bool copy3d) override; void DrawBlendingRect() override; - FNativeTexture *CreateTexture(FTexture *gametex, bool wrapping) override; + FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) override; FNativePalette *CreatePalette(FRemapTable *remap) override; void DrawTextureParms(FTexture *img, DrawParms &parms) override; void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override; @@ -265,7 +265,7 @@ private: class OpenGLTex : public FNativeTexture { public: - OpenGLTex(FTexture *tex, OpenGLSWFrameBuffer *fb, bool wrapping); + OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping); ~OpenGLTex(); FTexture *GameTex; @@ -280,7 +280,6 @@ private: bool Update(); bool CheckWrapping(bool wrapping); int GetTexFormat(); - FTextureFormat ToTexFmt(int fmt); }; class OpenGLPal : public FNativePalette diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 83ea3cdd0..60b8b84b8 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -150,7 +150,7 @@ FTexture::FTexture (const char *name, int lumpnum) WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum), UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), - Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0), Native(NULL) + Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0) { id.SetInvalid(); if (name != NULL) @@ -711,34 +711,37 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, } } -FNativeTexture *FTexture::GetNative(bool wrapping) +FNativeTexture *FTexture::GetNative(FTextureFormat fmt, bool wrapping) { - if (Native != NULL) + if (Native[fmt] != NULL) { - if (!Native->CheckWrapping(wrapping)) + if (!Native[fmt]->CheckWrapping(wrapping)) { // Texture's wrapping mode is not compatible. // Destroy it and get a new one. - delete Native; + delete Native[fmt]; } else { if (CheckModified(DefaultRenderStyle())) { - Native->Update(); + Native[fmt]->Update(); } - return Native; + return Native[fmt]; } } - Native = screen->CreateTexture(this, wrapping); - return Native; + Native[fmt] = screen->CreateTexture(this, fmt, wrapping); + return Native[fmt]; } void FTexture::KillNative() { - if (Native != NULL) + for (auto &nat : Native) { - delete Native; - Native = NULL; + if (nat != nullptr) + { + delete nat; + nat = nullptr; + } } } @@ -1000,4 +1003,7 @@ CCMD (printspans) Printf ("\n"); } } + #endif + + diff --git a/src/textures/textures.h b/src/textures/textures.h index 0fd751bbf..94fa38567 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -159,15 +159,20 @@ enum FTextureFormat TEX_Pal, TEX_Gray, TEX_RGB, // Actually ARGB + /* TEX_DXT1, TEX_DXT2, TEX_DXT3, TEX_DXT4, TEX_DXT5, + */ + TEX_Count }; class FNativeTexture; + + // Base texture class class FTexture { @@ -257,7 +262,7 @@ public: virtual FTextureFormat GetFormat(); // Returns a native 3D representation of the texture - FNativeTexture *GetNative(bool wrapping); + FNativeTexture *GetNative(FTextureFormat fmt, bool wrapping); // Frees the native 3D representation of the texture void KillNative(); @@ -310,7 +315,7 @@ public: protected: uint16_t Width, Height, WidthMask; static uint8_t GrayMap[256]; - FNativeTexture *Native; + FNativeTexture *Native[TEX_Count] = { nullptr }; // keep a slot for each type, because some render modes do not work with the base texture uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) { if (style.Flags & STYLEF_RedIsAlpha) @@ -399,7 +404,7 @@ public: static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); - friend class D3DTex; + friend class FNativeTexture; friend class OpenGLSWFrameBuffer; public: diff --git a/src/v_font.cpp b/src/v_font.cpp index e38ecfbde..6375e5d1f 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -973,6 +973,9 @@ void FFont::LoadTranslations() // means all the characters of a font have a better chance of being packed // into the same hardware texture. // +// (Note that this is a rather dumb implementation. The atlasing should +// occur at a higher level, independently of the renderer being used.) +// //========================================================================== void FFont::Preload() const @@ -989,7 +992,7 @@ void FFont::Preload() const FTexture *pic = GetChar(i, &foo); if (pic != NULL) { - pic->GetNative(false); + pic->GetNative(pic->GetFormat(), false); } } } diff --git a/src/v_video.cpp b/src/v_video.cpp index 5e86b915b..761c805d7 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1161,10 +1161,12 @@ void DFrameBuffer::DrawBlendingRect() // DFrameBuffer :: CreateTexture // // Creates a native texture for a game texture, if supported. +// The hardware renderer does not use this interface because it is +// far too limited // //========================================================================== -FNativeTexture *DFrameBuffer::CreateTexture(FTexture *gametex, bool wrapping) +FNativeTexture *DFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) { return NULL; } @@ -1261,6 +1263,12 @@ FNativePalette::~FNativePalette() FNativeTexture::~FNativeTexture() { + // Remove link from the game texture + if (mGameTex != nullptr) + { + mGameTex->Native[mFormat] = nullptr; + } + } bool FNativeTexture::CheckWrapping(bool wrapping) diff --git a/src/v_video.h b/src/v_video.h index 4d30cb0ef..98e81bc1f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -53,6 +53,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real class FTexture; struct FColormap; +enum FTextureFormat; // TagItem definitions for DrawTexture. As far as I know, tag lists // originated on the Amiga. @@ -336,7 +337,11 @@ protected: // This class represents a native texture, as opposed to an FTexture. class FNativeTexture { +protected: + FTexture * mGameTex; + FTextureFormat mFormat; public: + FNativeTexture(FTexture *tex, FTextureFormat fmt) : mGameTex(tex), mFormat(fmt) {} virtual ~FNativeTexture(); virtual bool Update() = 0; virtual bool CheckWrapping(bool wrapping); @@ -425,7 +430,7 @@ public: virtual void DrawBlendingRect(); // Create a native texture from a game texture. - virtual FNativeTexture *CreateTexture(FTexture *gametex, bool wrapping); + virtual FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping); // Create a palette texture from a remap/palette table. virtual FNativePalette *CreatePalette(FRemapTable *remap); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index fe033946b..7e35c55b1 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -128,10 +128,9 @@ struct D3DFB::Atlas class D3DTex : public FNativeTexture { public: - D3DTex(FTexture *tex, D3DFB *fb, bool wrapping); + D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping); ~D3DTex(); - FTexture *GameTex; D3DFB::PackedTexture *Box; D3DTex **Prev; @@ -143,7 +142,6 @@ public: bool Update(); bool CheckWrapping(bool wrapping); D3DFORMAT GetTexFormat(); - FTextureFormat ToTexFmt(D3DFORMAT fmt); }; class D3DPal : public FNativePalette @@ -2208,7 +2206,8 @@ void D3DFB::Atlas::FreeBox(D3DFB::PackedTexture *box) // //========================================================================== -D3DTex::D3DTex(FTexture *tex, D3DFB *fb, bool wrapping) +D3DTex::D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping) + : FNativeTexture(tex, fmt) { // Attach to the texture list for the D3DFB Next = fb->Textures; @@ -2219,7 +2218,6 @@ D3DTex::D3DTex(FTexture *tex, D3DFB *fb, bool wrapping) Prev = &fb->Textures; fb->Textures = this; - GameTex = tex; Box = NULL; IsGray = false; @@ -2245,11 +2243,6 @@ D3DTex::~D3DTex() { Next->Prev = Prev; } - // Remove link from the game texture - if (GameTex != NULL) - { - GameTex->Native = NULL; - } } //========================================================================== @@ -2289,7 +2282,7 @@ bool D3DTex::Create(D3DFB *fb, bool wrapping) Box->Owner->FreeBox(Box); } - Box = fb->AllocPackedTexture(GameTex->GetWidth(), GameTex->GetHeight(), wrapping, GetTexFormat()); + Box = fb->AllocPackedTexture(mGameTex->GetWidth(), mGameTex->GetHeight(), wrapping, GetTexFormat()); if (Box == NULL) { @@ -2322,7 +2315,7 @@ bool D3DTex::Update() assert(Box != NULL); assert(Box->Owner != NULL); assert(Box->Owner->Tex != NULL); - assert(GameTex != NULL); + assert(mGameTex != NULL); if (FAILED(Box->Owner->Tex->GetLevelDesc(0, &desc))) { @@ -2338,12 +2331,12 @@ bool D3DTex::Update() { dest += lrect.Pitch + (desc.Format == D3DFMT_L8 ? 1 : 4); } - GameTex->FillBuffer(dest, lrect.Pitch, GameTex->GetHeight(), ToTexFmt(desc.Format)); + mGameTex->FillBuffer(dest, lrect.Pitch, mGameTex->GetHeight(), mFormat); if (Box->Padded) { // Clear top padding row. dest = (uint8_t *)lrect.pBits; - int numbytes = GameTex->GetWidth() + 2; + int numbytes = mGameTex->GetWidth() + 2; if (desc.Format != D3DFMT_L8) { numbytes <<= 2; @@ -2386,51 +2379,25 @@ bool D3DTex::Update() D3DFORMAT D3DTex::GetTexFormat() { - FTextureFormat fmt = GameTex->GetFormat(); - IsGray = false; - switch (fmt) + switch (mFormat) { case TEX_Pal: return D3DFMT_L8; case TEX_Gray: IsGray = true; return D3DFMT_L8; case TEX_RGB: return D3DFMT_A8R8G8B8; +#if 0 case TEX_DXT1: return D3DFMT_DXT1; case TEX_DXT2: return D3DFMT_DXT2; case TEX_DXT3: return D3DFMT_DXT3; case TEX_DXT4: return D3DFMT_DXT4; case TEX_DXT5: return D3DFMT_DXT5; +#endif default: I_FatalError ("GameTex->GetFormat() returned invalid format."); } return D3DFMT_L8; } -//========================================================================== -// -// D3DTex :: ToTexFmt -// -// Converts a D3DFORMAT constant to something the FTexture system -// understands. -// -//========================================================================== - -FTextureFormat D3DTex::ToTexFmt(D3DFORMAT fmt) -{ - switch (fmt) - { - case D3DFMT_L8: return IsGray ? TEX_Gray : TEX_Pal; - case D3DFMT_A8R8G8B8: return TEX_RGB; - case D3DFMT_DXT1: return TEX_DXT1; - case D3DFMT_DXT2: return TEX_DXT2; - case D3DFMT_DXT3: return TEX_DXT3; - case D3DFMT_DXT4: return TEX_DXT4; - case D3DFMT_DXT5: return TEX_DXT5; - default: - assert(0); // LOL WUT? - return TEX_Pal; - } -} - //========================================================================== // // D3DPal Constructor @@ -2597,9 +2564,9 @@ void D3DFB::DrawBlendingRect() // //========================================================================== -FNativeTexture *D3DFB::CreateTexture(FTexture *gametex, bool wrapping) +FNativeTexture *D3DFB::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) { - D3DTex *tex = new D3DTex(gametex, this, wrapping); + D3DTex *tex = new D3DTex(gametex, fmt, this, wrapping); if (tex->Box == NULL) { delete tex; @@ -2824,7 +2791,12 @@ void D3DFB::DrawTextureParms (FTexture *img, DrawParms &parms) return; } - D3DTex *tex = static_cast(img->GetNative(false)); + FTextureFormat fmt; + if (parms.style.Flags & STYLEF_RedIsAlpha) fmt = TEX_Gray; + else if (parms.remap != nullptr) fmt = TEX_Pal; + else fmt = img->GetFormat(); + + D3DTex *tex = static_cast(img->GetNative(fmt, false)); if (tex == NULL) { @@ -3023,7 +2995,8 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo { return; } - D3DTex *tex = static_cast(src->GetNative(true)); + + D3DTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); if (tex == NULL) { return; @@ -3158,7 +3131,8 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, { return; } - tex = static_cast(texture->GetNative(true)); + + tex = static_cast(texture->GetNative(texture->GetFormat(), true)); if (tex == NULL) { return; diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h index d3523e17b..110469777 100644 --- a/src/win32/win32swiface.h +++ b/src/win32/win32swiface.h @@ -129,7 +129,7 @@ public: void SetBlendingRect (int x1, int y1, int x2, int y2); bool Begin2D (bool copy3d); void DrawBlendingRect (); - FNativeTexture *CreateTexture (FTexture *gametex, bool wrapping); + FNativeTexture *CreateTexture (FTexture *gametex, FTextureFormat fmt, bool wrapping); FNativePalette *CreatePalette (FRemapTable *remap); void DrawTextureParms (FTexture *img, DrawParms &parms); void DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color);