diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 29013f280..a02762eb8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -142,7 +142,11 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend int blendequation = renderops[style.BlendOp&15]; int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE; - if (style.Flags & STYLEF_ColorIsFixed) + if (style.Flags & STYLEF_RedIsAlpha) + { + texturemode = TM_REDTOALPHA; + } + else if (style.Flags & STYLEF_ColorIsFixed) { texturemode = TM_MASK; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 236b5d551..e0f5406dd 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -8,6 +8,7 @@ #include "gl/textures/gl_material.h" #include "c_cvars.h" #include "r_defs.h" +#include "r_data/r_translate.h" class FVertexBuffer; class FShader; @@ -100,9 +101,16 @@ public: void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) { + // textures without their own palette are a special case for use as an alpha texture: + // They use the color index directly as an alpha value instead of using the palette's red. + // To handle this case, we need to set a special translation for such textures. + if (alphatexture) + { + if (mat->tex->UseBasePalette()) translation = TRANSLATION(TRANSLATION_Standard, 8); + } mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; mShaderTimer = mat->tex->gl_info.shaderspeed; - mat->Bind(clampmode, translation, alphatexture); + mat->Bind(clampmode, translation); } void Apply(); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index af4c4f7c2..2d2e26d51 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -16,9 +16,10 @@ enum RenderFlags enum TexMode { TM_MODULATE = 0, // (r, g, b, a) - TM_MASK = 1, // (1, 1, 1, a) - TM_OPAQUE = 2, // (r, g, b, 1) - TM_INVERSE = 3, // (1-r, 1-g, 1-b, a) + TM_MASK, // (1, 1, 1, a) + TM_OPAQUE, // (r, g, b, 1) + TM_INVERSE, // (1-r, 1-g, 1-b, a) + TM_REDTOALPHA, // (1, 1, 1, r) }; struct RenderContext diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 564dd1e03..30a996816 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -148,11 +148,11 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) } wipestartscreen = new FHardwareTexture(Width, Height, true); - wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE); glFinish(); - wipestartscreen->Bind(0, false, false, false); + wipestartscreen->Bind(0, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -171,10 +171,10 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) void OpenGLFrameBuffer::WipeEndScreen() { wipeendscreen = new FHardwareTexture(Width, Height, true); - wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); glFinish(); - wipeendscreen->Bind(0, false, false, false); + wipeendscreen->Bind(0, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -286,7 +286,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); FFlatVertex *ptr; unsigned int offset, count; @@ -301,7 +301,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); - fb->wipeendscreen->Bind(0, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false); gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f)); gl_RenderState.Apply(); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); @@ -348,7 +348,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipeendscreen->Bind(0, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false); FFlatVertex *ptr; ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(0, 0, 0, 0, vb); @@ -364,7 +364,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) int i, dy; bool done = false; - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); // Copy the old screen in vertical strips on top of the new one. while (ticks--) { @@ -496,7 +496,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); FFlatVertex *ptr; unsigned int offset, count; ptr = GLRenderer->mVBO->GetBuffer(); @@ -516,9 +516,9 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.Apply(); // Burn the new screen on top of it. - fb->wipeendscreen->Bind(0, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0, false); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.SetEffect(EFF_NONE); diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index 0c74c9ae7..a2319f67c 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -51,7 +51,7 @@ // //=========================================================================== template -void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step) +void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step) { int i; @@ -69,7 +69,7 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, } } -typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step); +typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int count, int step); static CopyFunc copyfuncs[]={ iCopyColors, @@ -99,7 +99,7 @@ void FGLBitmap::CopyPixelDataRGB(int originx, int originy, BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; for (int y=0;y 0) + if (translation > 0) { PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); if (ptrans) diff --git a/src/gl/textures/gl_bitmap.h b/src/gl/textures/gl_bitmap.h index 98addb51d..6aea6d008 100644 --- a/src/gl/textures/gl_bitmap.h +++ b/src/gl/textures/gl_bitmap.h @@ -7,34 +7,25 @@ class FGLBitmap : public FBitmap { - bool alphatex; int translation; public: FGLBitmap() { - alphatex = false; translation = 0; } FGLBitmap(BYTE *buffer, int pitch, int width, int height) : FBitmap(buffer, pitch, width, height) { - alphatex = false; translation = 0; } void SetTranslationInfo(int _trans) { - if (_trans == -1) alphatex = true; - else if (_trans != -1337) translation = _trans; + if (_trans != -1337) translation = _trans; } - void SetAlphaTex() - { - alphatex = true; - } - virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth, int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL); virtual void CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight, diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index f491169b4..c855ef285 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -184,18 +184,13 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un // //=========================================================================== -unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture) +unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation) { int rh,rw; int texformat=TexFormat[gl_texture_format]; bool deletebuffer=false; - if (alphatexture) - { - texformat = GL_R8; - translation = TRANS_Alpha; - } - else if (forcenocompression) + if (forcenocompression) { texformat = GL_RGBA8; } @@ -245,11 +240,6 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int glTex->mipmapped = true; } - if (alphatexture) - { - static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } if (texunit != 0) glActiveTexture(GL_TEXTURE0); return glTex->glTexID; } @@ -362,9 +352,8 @@ FHardwareTexture::TranslatedTexture *FHardwareTexture::GetTexID(int translation) // Binds this patch // //=========================================================================== -unsigned int FHardwareTexture::Bind(int texunit, int translation, bool alphatexture, bool needmipmap) +unsigned int FHardwareTexture::Bind(int texunit, int translation, bool needmipmap) { - if (alphatexture) translation = TRANS_Alpha; TranslatedTexture *pTex = GetTexID(translation); if (pTex->glTexID != 0) diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index eabc7a6ef..7fa0f0580 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -20,11 +20,6 @@ enum EInvalid Invalid = 0 }; -enum ETranslation -{ - TRANS_Alpha = INT_MAX -}; - enum { GLT_CLAMPX=1, @@ -66,7 +61,6 @@ private: TArray glTex_Translated; unsigned int glDepthID; // only used by camera textures - void LoadImage(unsigned char * buffer,int w, int h, TranslatedTexture *glTex, bool mipmap, bool alphatexture, int texunit); TranslatedTexture * GetTexID(int translation); int GetDepthBuffer(); @@ -81,8 +75,8 @@ public: void BindToFrameBuffer(); - unsigned int Bind(int texunit, int translation, bool alphatexture, bool needmipmap); - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture); + unsigned int Bind(int texunit, int translation, bool needmipmap); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation); void Clean(bool all); }; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 063f948c0..6b22e0a5e 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -109,7 +109,7 @@ FGLTexture::~FGLTexture() // Checks for the presence of a hires texture replacement and loads it // //========================================================================== -unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height, bool alphatexture) +unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height) { if (HiresLump==-1) { @@ -131,8 +131,6 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig memset(buffer, 0, w * (h+1) * 4); FGLBitmap bmp(buffer, w*4, w, h); - if (alphatexture) bmp.SetAlphaTex(); - int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); hirestexture->CheckTrans(buffer, w*h, trans); @@ -181,7 +179,7 @@ void FGLTexture::Clean(bool all) // //=========================================================================== -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture) +unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck) { unsigned char * buffer; int W, H; @@ -191,7 +189,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F // by hires textures if (gl_texture_usehires && hirescheck != NULL) { - buffer = LoadHiresTexture (hirescheck, &w, &h, alphatexture); + buffer = LoadHiresTexture (hirescheck, &w, &h); if (buffer) { return buffer; @@ -207,7 +205,6 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F FGLBitmap bmp(buffer, W*4, W, H); bmp.SetTranslationInfo(translation); - if (alphatexture) bmp.SetAlphaTex(); if (tex->bComplex) { @@ -241,7 +238,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. // [BB] Potentially upsample the buffer. - return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || alphatexture); + return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, !!bIsTransparent); } @@ -267,7 +264,7 @@ FHardwareTexture *FGLTexture::CreateHwTexture() // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, bool alphatexture, FTexture *hirescheck) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) { int usebright = false; @@ -288,7 +285,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla } // Bind it to the system. - if (!hwtex->Bind(texunit, translation, alphatexture, needmipmap)) + if (!hwtex->Bind(texunit, translation, needmipmap)) { int w=0, h=0; @@ -298,10 +295,10 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, hirescheck, alphatexture); + buffer = CreateTexBuffer(translation, w, h, hirescheck); tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, alphatexture)) + if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation)) { // could not create texture delete[] buffer; @@ -614,16 +611,14 @@ outl: static FMaterial *last; static int lastclamp; static int lasttrans; -static bool lastalpha; -void FMaterial::Bind(int clampmode, int translation, bool alphatexture) +void FMaterial::Bind(int clampmode, int translation) { // avoid rebinding the same texture multiple times. - if (this == last && lastclamp == clampmode && translation == lasttrans && lastalpha == alphatexture) return; + if (this == last && lastclamp == clampmode && translation == lasttrans) return; last = this; lastclamp = clampmode; - lastalpha = alphatexture; lasttrans = translation; int usebright = false; @@ -633,7 +628,7 @@ void FMaterial::Bind(int clampmode, int translation, bool alphatexture) if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL); + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); if (gltexture != NULL) { for(unsigned i=0;igl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, false, NULL); + layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL); maxbound = i+1; } } @@ -669,7 +664,7 @@ void FMaterial::Bind(int clampmode, int translation, bool alphatexture) //=========================================================================== void FMaterial::Precache() { - Bind(0, 0, false); + Bind(0, 0); } //=========================================================================== @@ -749,7 +744,7 @@ void FMaterial::BindToFrameBuffer() if (mBaseLayer->mHwTexture == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, 0, 0, false, NULL); + mBaseLayer->Bind(0, 0, 0, NULL); FHardwareTexture::Unbind(0); ClearLastTexture(); } diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 6d3015a52..b5f055d24 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -67,18 +67,17 @@ private: bool bHasColorkey; // only for hires bool bExpand; - unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); + unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height); FHardwareTexture *CreateHwTexture(); - const FHardwareTexture *Bind(int texunit, int clamp, int translation, bool alphatexture, FTexture *hirescheck); - const FHardwareTexture *BindPatch(int texunit, int translation, bool alphatexture); - + const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck); void Clean(bool all); int Dump(int i); @@ -138,12 +137,11 @@ public: return mTextureLayers.Size() + 1; } - //void Bind(int clamp = 0, int translation = 0, int overrideshader = 0, bool alphatexture = false); - void Bind(int clamp, int translation, bool alphatexture); + void Bind(int clamp, int translation); unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true) const { - return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex:NULL, 0); + return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL); } void Clean(bool f) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index d11388e6e..8d867f25f 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -824,6 +824,15 @@ void R_InitTranslationTables () remap->Remap[i] = IcePaletteRemap[v]; remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]); } + + // The alphatexture translation. Since alphatextures use the red channel this is just a standard grayscale mapping. + PushIdentityTable(TRANSLATION_Standard); + remap = translationtables[TRANSLATION_Standard][8]; + for (i = 0; i < 256; i++) + { + remap->Remap[i] = i; + remap->Palette[i] = PalEntry(255, i, i, i); + } } //---------------------------------------------------------------------------- diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 532529f0b..c77a058c2 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -60,17 +60,21 @@ vec4 getTexel(vec2 st) // switch (uTextureMode) { - case 1: + case 1: // TM_MASK texel.rgb = vec3(1.0,1.0,1.0); break; - case 2: + case 2: // TM_OPAQUE texel.a = 1.0; break; - case 3: + case 3: // TM_INVERSE texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); break; + + case 4: // TM_REDTOALPHA + texel = vec4(1.0, 1.0, 1.0, texel.r); + break; } texel *= uObjectColor;