From 8b79eedfeabc5e2fed7a122947bca637483e2893 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Apr 2018 14:38:48 +0200 Subject: [PATCH] - moved CreateTexBuffer out of the GL code. This is merely a buffer creation function with no dependencies on the renderer. --- src/gl/renderer/gl_renderer.cpp | 16 ----- src/gl/renderer/gl_renderer.h | 1 - src/gl/renderer/gl_renderstate.h | 2 +- src/gl/scene/gl_flats.cpp | 4 +- src/gl/scene/gl_sprite.cpp | 4 +- src/gl/scene/gl_walls.cpp | 4 +- src/gl/scene/gl_walls_draw.cpp | 2 +- src/gl/scene/gl_weapon.cpp | 2 +- src/gl/textures/gl_material.cpp | 113 ++++--------------------------- src/gl/textures/gl_material.h | 33 --------- src/textures/texture.cpp | 111 ++++++++++++++++++++++++++++++ src/textures/textures.h | 22 +++++- 12 files changed, 154 insertions(+), 160 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 1c87a62e8..972ffecba 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -413,22 +413,6 @@ void FGLRenderer::EndOffscreen() glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID); } -//=========================================================================== -// -// -// -//=========================================================================== - -unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h) -{ - FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - if (gltex) - { - return gltex->CreateTexBuffer(0, w, h); - } - return NULL; -} - //=========================================================================== // // Vertex buffer for 2D drawer diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index e5f420da4..c17dc6e98 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -169,7 +169,6 @@ public: void ClearBorders(); void FlushTextures(); - unsigned char *GetTextureBuffer(FTexture *tex, int &w, int &h); void SetupLevel(); void RenderView(player_t* player); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 7940672ac..74df2a074 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -146,7 +146,7 @@ public: void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) { // alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations. - if (alphatexture && gl.legacyMode) translation = INT_MAX; + if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture; if (mat->tex->bHasCanvas) { diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index b70f6cdfe..04569e285 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -418,7 +418,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG } else { - if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); @@ -470,7 +470,7 @@ inline void GLFlat::PutFlat(bool fog) // translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list. list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER; } - else if (gltexture->GetTransparent()) + else if (gltexture->tex->GetTranslucency()) { if (stack) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c7efe1eb8..91f523d7e 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -301,7 +301,7 @@ void GLSprite::Draw(int pass) gl_SetRenderStyle(RenderStyle, false, // The rest of the needed checks are done inside gl_SetRenderStyle trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor && - fullbright && gltexture && !gltexture->GetTransparent()); + fullbright && gltexture && !gltexture->tex->GetTranslucency()); if (hw_styleflags == STYLEHW_NoAlphaTest) { @@ -1063,7 +1063,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) RenderStyle.DestAlpha = STYLEALPHA_InvSrc; } } - if ((gltexture && gltexture->GetTransparent()) || (RenderStyle.Flags & STYLEF_RedIsAlpha)) + if ((gltexture && gltexture->tex->GetTranslucency()) || (RenderStyle.Flags & STYLEF_RedIsAlpha)) { if (hw_styleflags == STYLEHW_Solid) { diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 33ba19db8..92ff6c59f 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -71,7 +71,7 @@ void GLWall::PutWall(bool translucent) }; - if (gltexture && gltexture->GetTransparent() && passflag[type] == 2) + if (gltexture && gltexture->tex->GetTranslucency() && passflag[type] == 2) { translucent = true; } @@ -994,7 +994,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, case 0: RenderStyle=STYLE_Translucent; alpha = seg->linedef->alpha; - translucent =alpha < 1. || (gltexture && gltexture->GetTransparent()); + translucent =alpha < 1. || (gltexture && gltexture->tex->GetTranslucency()); break; case ML_ADDTRANS: diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 1795f1769..e22d35210 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -398,7 +398,7 @@ void GLWall::RenderTranslucentWall() { SetupLights(); } - if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); RenderTextured(RWF_TEXTURED | RWF_NOSPLIT); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 421517a26..6daefd88c 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -146,7 +146,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa } - if (tex->GetTransparent() || OverrideShader != -1) + if (tex->tex->GetTranslucency() || OverrideShader != -1) { gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); } diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index d7e722d63..5e32f855d 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -50,7 +50,6 @@ EXTERN_CVAR(Bool, gl_render_precise) EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Bool, gl_precache) -EXTERN_CVAR(Bool, gl_texture_usehires) //=========================================================================== // @@ -120,91 +119,6 @@ void FGLTexture::CleanUnused(SpriteHits &usedtranslations) } -//=========================================================================== -// -// Initializes the buffer for the texture data -// -//=========================================================================== - -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded, bool alphatrans) -{ - unsigned char * buffer; - int W, H; - int isTransparent = -1; - - - // Textures that are already scaled in the texture lump will not get replaced - // by hires textures - if (gl_texture_usehires && hirescheck != NULL && !alphatrans) - { - buffer = hirescheck->LoadHiresTexture (&w, &h); - if (buffer) - { - return buffer; - } - } - - int exx = bExpandFlag && createexpanded; - - W = w = tex->GetWidth() + 2 * exx; - H = h = tex->GetHeight() + 2 * exx; - - - buffer=new unsigned char[W*(H+1)*4]; - memset(buffer, 0, W * (H+1) * 4); - - FBitmap bmp(buffer, W*4, W, H); - - if (translation <= 0 || alphatrans || translation >= STRange_Min) - { - // Allow creation of desaturated or special-colormapped textures for the legacy renderer. - FCopyInfo inf = { OP_COPY, BLEND_NONE, {0}, 0, 0 }; - if (translation >= STRange_Desaturate && translation < STRange_Desaturate+31) // there are 31 ranges of desaturations available - { - inf.blend = (EBlend)(BLEND_DESATURATE1 + translation - STRange_Desaturate); - } - else if (translation >= STRange_Specialcolormap && translation < STRange_Specialcolormap + SpecialColormaps.Size()) - { - inf.blend = (EBlend)(BLEND_SPECIALCOLORMAP1 + translation - STRange_Specialcolormap); - } - - int trans = tex->CopyTrueColorPixels(&bmp, exx, exx, 0, translation >= STRange_Min? &inf : nullptr); - tex->CheckTrans(buffer, W*H, trans); - isTransparent = tex->bTranslucent; - // alpha texture for legacy mode - if (alphatrans) - { - for (int i = 0; i < W*H; i++) - { - int b = buffer[4 * i]; - int g = buffer[4 * i + 1]; - int r = buffer[4 * i + 2]; - int gray = Luminance(r, g, b); - buffer[4 * i] = 255; - buffer[4 * i + 1] = 255; - buffer[4 * i + 2] = 255; - buffer[4 * i + 3] = (buffer[4 * i + 3] * gray) >> 8; - } - } - } - else - { - // When using translations everything must be mapped to the base palette. - // so use CopyTrueColorTranslated - tex->CopyTrueColorTranslated(&bmp, exx, exx, 0, FUniquePalette::GetPalette(translation)); - isTransparent = 0; - // This is not conclusive for setting the texture's transparency info. - } - - // if we just want the texture for some checks there's no need for upsampling. - if (!createexpanded) return buffer; - - // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. - // [BB] Potentially upsample the buffer. - return tex->CreateUpsampledTextureBuffer (buffer, W, H, w, h, !!isTransparent); -} - - //=========================================================================== // // Create hardware texture for world use @@ -230,19 +144,15 @@ FHardwareTexture *FGLTexture::CreateHwTexture() const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) { int usebright = false; - bool alphatrans = translation == INT_MAX; // This is only needed for legacy mode because no texture combine setting allows using the color as alpha. - if (!alphatrans) + if (translation <= 0) { - if (translation <= 0) - { - translation = -translation; - } - else - { - auto remap = TranslationToTable(translation); - translation = remap == nullptr ? 0 : remap->GetUniqueIndex(); - } + translation = -translation; + } + else + { + auto remap = TranslationToTable(translation); + translation = remap == nullptr ? 0 : remap->GetUniqueIndex(); } bool needmipmap = (clampmode <= CLAMP_XY); @@ -269,7 +179,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, hirescheck, true, alphatrans); + int flags = CTF_ProcessData; + if (bExpandFlag) flags |= CTF_Expand; + if (hirescheck) flags |= CTF_CheckHires; + + buffer = tex->CreateTexBuffer(translation, w, h, flags); if (tex->bWarped && gl.legacyMode && w*h <= 256*256) // do not software-warp larger textures, especially on the old systems that still need this fallback. { // need to do software warping @@ -280,7 +194,6 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla buffer = warpbuffer; wt->GenTime[0] = screen->FrameTime; } - tex->ProcessData(buffer, w, h, false); } if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind")) { @@ -584,7 +497,7 @@ bool FMaterial::TrimBorders(uint16_t *rect) int w; int h; - unsigned char *buffer = CreateTexBuffer(0, w, h, false, false); + unsigned char *buffer = tex->CreateTexBuffer(0, w, h); if (buffer == NULL) { diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index b1a629efc..9b6647a02 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -50,13 +50,6 @@ struct FTexCoordInfo //=========================================================================== class FMaterial; -enum ESpecialTranslations : uint32_t -{ - STRange_Min = 0x10000000, - STRange_Desaturate = 0x10000000, - STRange_Specialcolormap = 0x20000000, -}; - class FGLTexture { friend class FMaterial; @@ -78,8 +71,6 @@ public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true, bool alphatrans = false); - void Clean(bool all); void CleanUnused(SpriteHits &usedtranslations); int Dump(int i); @@ -148,11 +139,6 @@ public: void Bind(int clamp, int translation); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true, bool createexpanded = true) const - { - return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL, createexpanded); - } - void Clean(bool f) { mBaseLayer->Clean(f); @@ -213,25 +199,6 @@ public: float GetSpriteVB() const { return mSpriteV[1]; } - - bool GetTransparent() const - { - if (tex->bTranslucent == -1) - { - if (!mBaseLayer->tex->bHasCanvas) - { - int w, h; - unsigned char *buffer = CreateTexBuffer(0, w, h); - delete [] buffer; - } - else - { - tex->bTranslucent = 0; - } - } - return !!tex->bTranslucent; - } - static void DeleteAll(); static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index c48c930cb..59d28e489 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -59,6 +59,7 @@ CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) TexMan.SpriteAdjustChanged(); } +EXTERN_CVAR(Bool, gl_texture_usehires) //========================================================================== // @@ -1341,6 +1342,116 @@ bool FTexture::ProcessData(unsigned char * buffer, int w, int h, bool ispatch) return true; } +//=========================================================================== +// +// Initializes the buffer for the texture data +// +//=========================================================================== + +unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int flags) +{ + unsigned char * buffer; + int W, H; + int isTransparent = -1; + + + // Textures that are already scaled in the texture lump will not get replaced + // by hires textures + if (gl_texture_usehires && (flags & CTF_CheckHires) && translation != STRange_AlphaTexture) + { + buffer = LoadHiresTexture(&w, &h); + if (buffer) + { + return buffer; + } + } + + int exx = !!(flags & CTF_Expand); + + W = w = GetWidth() + 2 * exx; + H = h = GetHeight() + 2 * exx; + + + buffer = new unsigned char[W*(H + 1) * 4]; + memset(buffer, 0, W * (H + 1) * 4); + + FBitmap bmp(buffer, W * 4, W, H); + + if (translation <= 0 || translation >= STRange_Min) + { + // Allow creation of desaturated or special-colormapped textures for the legacy renderer. + FCopyInfo inf = { OP_COPY, BLEND_NONE,{ 0 }, 0, 0 }; + if (translation >= STRange_Desaturate && translation < STRange_Desaturate + 31) // there are 31 ranges of desaturations available + { + inf.blend = (EBlend)(BLEND_DESATURATE1 + translation - STRange_Desaturate); + } + else if (translation >= STRange_Specialcolormap && translation < STRange_Specialcolormap + SpecialColormaps.Size()) + { + inf.blend = (EBlend)(BLEND_SPECIALCOLORMAP1 + translation - STRange_Specialcolormap); + } + + int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, translation >= STRange_Min ? &inf : nullptr); + CheckTrans(buffer, W*H, trans); + isTransparent = bTranslucent; + // alpha texture for legacy mode + if (translation == STRange_AlphaTexture) + { + for (int i = 0; i < W*H; i++) + { + int b = buffer[4 * i]; + int g = buffer[4 * i + 1]; + int r = buffer[4 * i + 2]; + int gray = Luminance(r, g, b); + buffer[4 * i] = 255; + buffer[4 * i + 1] = 255; + buffer[4 * i + 2] = 255; + buffer[4 * i + 3] = (buffer[4 * i + 3] * gray) >> 8; + } + } + } + else + { + // When using translations everything must be mapped to the base palette. + // so use CopyTrueColorTranslated + CopyTrueColorTranslated(&bmp, exx, exx, 0, FUniquePalette::GetPalette(translation)); + isTransparent = 0; + // This is not conclusive for setting the texture's transparency info. + } + + // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. + // [BB] Potentially upsample the buffer. + if (flags & CTF_ProcessData) + { + buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent); + ProcessData(buffer, w, h, false); + } + return buffer; +} + +//=========================================================================== +// +// Dummy texture for the 0-entry. +// +//=========================================================================== + +bool FTexture::GetTranslucency() +{ + if (bTranslucent == -1) + { + if (!bHasCanvas) + { + int w, h; + unsigned char *buffer = CreateTexBuffer(0, w, h); + delete[] buffer; + } + else + { + bTranslucent = 0; + } + } + return !!bTranslucent; +} + //=========================================================================== // // Dummy texture for the 0-entry. diff --git a/src/textures/textures.h b/src/textures/textures.h index a94dd2906..c42a1124d 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -64,6 +64,23 @@ struct FloatRect } }; +// Special translation values for CreateTexBuffer +enum ESpecialTranslations : int32_t +{ + STRange_Min = 0x10000000, + STRange_Desaturate = 0x10000000, + STRange_Specialcolormap = 0x20000000, + STRange_AlphaTexture = 0x30000000 +}; + +enum ECreateTexBufferFlags +{ + CTF_CheckHires = 1, // use external hires replacement if found + 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. +}; + + class FBitmap; struct FRemapTable; @@ -404,10 +421,13 @@ protected: public: - unsigned char *LoadHiresTexture(int *width, int *height); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, int flags = 0); + bool GetTranslucency(); + private: int CheckDDPK3(); int CheckExternalFile(bool & hascolorkey); + unsigned char *LoadHiresTexture(int *width, int *height); bool bSWSkyColorDone = false; PalEntry FloorSkyColor;