- moved CreateTexBuffer out of the GL code.

This is merely a buffer creation function with no dependencies on the renderer.
This commit is contained in:
Christoph Oelckers 2018-04-01 14:38:48 +02:00
parent 711a88bab3
commit 8b79eedfea
12 changed files with 154 additions and 160 deletions

View file

@ -413,22 +413,6 @@ void FGLRenderer::EndOffscreen()
glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID); 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 // Vertex buffer for 2D drawer

View file

@ -169,7 +169,6 @@ public:
void ClearBorders(); void ClearBorders();
void FlushTextures(); void FlushTextures();
unsigned char *GetTextureBuffer(FTexture *tex, int &w, int &h);
void SetupLevel(); void SetupLevel();
void RenderView(player_t* player); void RenderView(player_t* player);

View file

@ -146,7 +146,7 @@ public:
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) 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. // 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) if (mat->tex->bHasCanvas)
{ {

View file

@ -418,7 +418,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
} }
else 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); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
gl_SetPlaneTextureRotation(&plane, gltexture); 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. // 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; list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
} }
else if (gltexture->GetTransparent()) else if (gltexture->tex->GetTranslucency())
{ {
if (stack) if (stack)
{ {

View file

@ -301,7 +301,7 @@ void GLSprite::Draw(int pass)
gl_SetRenderStyle(RenderStyle, false, gl_SetRenderStyle(RenderStyle, false,
// The rest of the needed checks are done inside gl_SetRenderStyle // The rest of the needed checks are done inside gl_SetRenderStyle
trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor && 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) if (hw_styleflags == STYLEHW_NoAlphaTest)
{ {
@ -1063,7 +1063,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
RenderStyle.DestAlpha = STYLEALPHA_InvSrc; 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) if (hw_styleflags == STYLEHW_Solid)
{ {

View file

@ -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; translucent = true;
} }
@ -994,7 +994,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
case 0: case 0:
RenderStyle=STYLE_Translucent; RenderStyle=STYLE_Translucent;
alpha = seg->linedef->alpha; alpha = seg->linedef->alpha;
translucent =alpha < 1. || (gltexture && gltexture->GetTransparent()); translucent =alpha < 1. || (gltexture && gltexture->tex->GetTranslucency());
break; break;
case ML_ADDTRANS: case ML_ADDTRANS:

View file

@ -398,7 +398,7 @@ void GLWall::RenderTranslucentWall()
{ {
SetupLights(); 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); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
RenderTextured(RWF_TEXTURED | RWF_NOSPLIT); RenderTextured(RWF_TEXTURED | RWF_NOSPLIT);

View file

@ -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); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
} }

View file

@ -50,7 +50,6 @@
EXTERN_CVAR(Bool, gl_render_precise) EXTERN_CVAR(Bool, gl_render_precise)
EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Int, gl_lightmode)
EXTERN_CVAR(Bool, gl_precache) 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 // 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) const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck)
{ {
int usebright = false; 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;
{ }
translation = -translation; else
} {
else auto remap = TranslationToTable(translation);
{ translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
auto remap = TranslationToTable(translation);
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
}
} }
bool needmipmap = (clampmode <= CLAMP_XY); bool needmipmap = (clampmode <= CLAMP_XY);
@ -269,7 +179,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
if (!tex->bHasCanvas) 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. 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 // need to do software warping
@ -280,7 +194,6 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
buffer = warpbuffer; buffer = warpbuffer;
wt->GenTime[0] = screen->FrameTime; wt->GenTime[0] = screen->FrameTime;
} }
tex->ProcessData(buffer, w, h, false);
} }
if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind")) if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind"))
{ {
@ -584,7 +497,7 @@ bool FMaterial::TrimBorders(uint16_t *rect)
int w; int w;
int h; int h;
unsigned char *buffer = CreateTexBuffer(0, w, h, false, false); unsigned char *buffer = tex->CreateTexBuffer(0, w, h);
if (buffer == NULL) if (buffer == NULL)
{ {

View file

@ -50,13 +50,6 @@ struct FTexCoordInfo
//=========================================================================== //===========================================================================
class FMaterial; class FMaterial;
enum ESpecialTranslations : uint32_t
{
STRange_Min = 0x10000000,
STRange_Desaturate = 0x10000000,
STRange_Specialcolormap = 0x20000000,
};
class FGLTexture class FGLTexture
{ {
friend class FMaterial; friend class FMaterial;
@ -78,8 +71,6 @@ public:
FGLTexture(FTexture * tx, bool expandpatches); FGLTexture(FTexture * tx, bool expandpatches);
~FGLTexture(); ~FGLTexture();
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true, bool alphatrans = false);
void Clean(bool all); void Clean(bool all);
void CleanUnused(SpriteHits &usedtranslations); void CleanUnused(SpriteHits &usedtranslations);
int Dump(int i); int Dump(int i);
@ -148,11 +139,6 @@ public:
void Bind(int clamp, int translation); 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) void Clean(bool f)
{ {
mBaseLayer->Clean(f); mBaseLayer->Clean(f);
@ -213,25 +199,6 @@ public:
float GetSpriteVB() const { return mSpriteV[1]; } 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 DeleteAll();
static void FlushAll(); static void FlushAll();
static FMaterial *ValidateTexture(FTexture * tex, bool expand); static FMaterial *ValidateTexture(FTexture * tex, bool expand);

View file

@ -59,6 +59,7 @@ CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
TexMan.SpriteAdjustChanged(); 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; 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. // Dummy texture for the 0-entry.

View file

@ -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; class FBitmap;
struct FRemapTable; struct FRemapTable;
@ -404,10 +421,13 @@ protected:
public: public:
unsigned char *LoadHiresTexture(int *width, int *height); unsigned char * CreateTexBuffer(int translation, int & w, int & h, int flags = 0);
bool GetTranslucency();
private: private:
int CheckDDPK3(); int CheckDDPK3();
int CheckExternalFile(bool & hascolorkey); int CheckExternalFile(bool & hascolorkey);
unsigned char *LoadHiresTexture(int *width, int *height);
bool bSWSkyColorDone = false; bool bSWSkyColorDone = false;
PalEntry FloorSkyColor; PalEntry FloorSkyColor;