diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f56c7c2e3..9c650c935 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1015,6 +1015,7 @@ set (PCH_SOURCES stringtable.cpp teaminfo.cpp umapinfo.cpp + v_2ddrawer.cpp v_blend.cpp v_collection.cpp v_draw.cpp diff --git a/src/gl/renderer/gl_2ddrawer.cpp b/src/gl/renderer/gl_2ddrawer.cpp index c0e485a1f..b58f3c22b 100644 --- a/src/gl/renderer/gl_2ddrawer.cpp +++ b/src/gl/renderer/gl_2ddrawer.cpp @@ -36,6 +36,7 @@ #include "gl/textures/gl_translate.h" #include "vectors.h" +#if 0 //========================================================================== // // @@ -490,3 +491,4 @@ void FGL2DDrawer::Clear() mData.Clear(); mLastLineCmd = -1; } +#endif \ No newline at end of file diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 463895e8c..ccb51b143 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -798,10 +798,10 @@ void FGLRenderer::Flush() mBuffers->BindEyeFB(eye_ix); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); - m2DDrawer->Draw(); + screen->Draw2D(); FGLDebug::PopGroup(); } - m2DDrawer->Clear(); + screen->Clear2D(); FGLPostProcessState savedState; FGLDebug::PushGroup("PresentEyes"); @@ -818,8 +818,8 @@ void FGLRenderer::Flush() void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) { - m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer - m2DDrawer->Clear(); + screen->Draw2D(); // draw all pending 2D stuff before copying the buffer + screen->Clear2D(); mCustomPostProcessShaders->Run("screen"); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 57927bc10..db7e8bb00 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -105,7 +105,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) gl_spriteindex = 0; mShaderManager = nullptr; mLights = nullptr; - m2DDrawer = nullptr; mTonemapPalette = nullptr; mBuffers = nullptr; mPresentShader = nullptr; @@ -160,7 +159,6 @@ void FGLRenderer::Initialize(int width, int height) mPresent3dRowShader = new FPresent3DRowShader(); mShadowMapShader = new FShadowMapShader(); mCustomPostProcessShaders = new FCustomPostProcessShaders(); - m2DDrawer = new FGL2DDrawer; GetSpecialTextures(); @@ -196,7 +194,6 @@ FGLRenderer::~FGLRenderer() gl_FlushModels(); AActor::DeleteAllAttachedLights(); FMaterial::FlushAll(); - if (m2DDrawer != nullptr) delete m2DDrawer; if (mShaderManager != NULL) delete mShaderManager; if (mSamplerManager != NULL) delete mSamplerManager; if (mVBO != NULL) delete mVBO; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index ffae874d8..fc913b45d 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -146,7 +146,6 @@ public: FFlatVertexBuffer *mVBO; FSkyVertexBuffer *mSkyVBO; FLightBuffer *mLights; - FGL2DDrawer *m2DDrawer; GL_IRECT mScreenViewport; GL_IRECT mSceneViewport; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 8a638e435..f3687b1e7 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -49,7 +49,7 @@ #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" #include "gl/gl_functions.h" -#include "gl/renderer/gl_2ddrawer.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl_debug.h" #include "r_videoscale.h" @@ -384,100 +384,6 @@ bool OpenGLFrameBuffer::Begin2D(bool copy3d) return true; } -//========================================================================== -// -// Draws a texture -// -//========================================================================== - -void OpenGLFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddTexture(img, parms); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddLine(x1, y1, x2, y2, palcolor, color); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DrawPixel(int x1, int y1, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddPixel(x1, y1, palcolor, color); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::Dim(PalEntry) -{ - // Unlike in the software renderer the color is being ignored here because - // view blending only affects the actual view with the GL renderer. - Super::Dim(0); -} - -void OpenGLFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddFlatFill(left, top, right, bottom, src, local_origin); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color); -} - -//========================================================================== -// -// D3DFB :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -//========================================================================== - -void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr && npoints >= 3) - { - GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel); - } -} - - //=========================================================================== // // Takes a screenshot diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index b8b4bd21f..3b34b4104 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -56,19 +56,6 @@ public: // Releases the screenshot buffer. virtual void ReleaseScreenshotBuffer(); - // 2D drawing - void DrawTextureParms(FTexture *img, DrawParms &parms); - void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color); - void DrawPixel(int x1, int y1, int palcolor, uint32_t color); - void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - void Dim(PalEntry color=0); - void DoDim (PalEntry color, float damount, int x1, int y1, int w, int h); - void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false); - - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - FNativePalette *CreatePalette(FRemapTable *remap); bool WipeStartScreen(int type); diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index 169b21c27..025a3dae2 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -2046,65 +2046,6 @@ FNativePalette *OpenGLSWFrameBuffer::CreatePalette(FRemapTable *remap) return tex; } -//========================================================================== -// -// OpenGLSWFrameBuffer :: Clear -// -// Fills the specified region with a color. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DoClear(left, top, right, bottom, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (palcolor >= 0 && color == 0) - { - color = GPalette.BaseColors[palcolor]; - } - else if (APART(color) < 255) - { - Dim(color, APART(color) / 255.f, left, top, right - left, bottom - top); - return; - } - AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Dim -// -//========================================================================== - -void OpenGLSWFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) -{ - if (amount <= 0) - { - return; - } - if (In2D < 2) - { - Super::DoDim(color, amount, x1, y1, w, h); - return; - } - if (!InScene) - { - return; - } - if (amount > 1) - { - amount = 1; - } - AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); -} - //========================================================================== // // OpenGLSWFrameBuffer :: BeginLineBatch @@ -2147,60 +2088,13 @@ void OpenGLSWFrameBuffer::EndLineBatch() BatchType = BATCH_None; } -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawLine -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawLine(int x0, int y0, int x1, int y1, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawLine(x0, y0, x1, y1, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (BatchType != BATCH_Lines) - { - BeginLineBatch(); - } - if (VertexPos == NUM_VERTS) - { // Flush the buffer and refill it. - EndLineBatch(); - BeginLineBatch(); - } - // Add the endpoints to the vertex buffer. - VertexData[VertexPos].x = float(x0); - VertexData[VertexPos].y = float(y0); - VertexData[VertexPos].z = 0; - VertexData[VertexPos].rhw = 1; - VertexData[VertexPos].color0 = color; - VertexData[VertexPos].color1 = 0; - VertexData[VertexPos].tu = 0; - VertexData[VertexPos].tv = 0; - - VertexData[VertexPos + 1].x = float(x1); - VertexData[VertexPos + 1].y = float(y1); - VertexData[VertexPos + 1].z = 0; - VertexData[VertexPos + 1].rhw = 1; - VertexData[VertexPos + 1].color0 = color; - VertexData[VertexPos + 1].color1 = 0; - VertexData[VertexPos + 1].tu = 0; - VertexData[VertexPos + 1].tv = 0; - - VertexPos += 2; -} - //========================================================================== // // OpenGLSWFrameBuffer :: DrawPixel // //========================================================================== +#if 0 void OpenGLSWFrameBuffer::DrawPixel(int x, int y, int palcolor, uint32_t color) { if (In2D < 2) @@ -2221,485 +2115,7 @@ void OpenGLSWFrameBuffer::DrawPixel(int x, int y, int palcolor, uint32_t color) SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); DrawPoints(1, &pt); } - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawTextureV -// -// If not in 2D mode, just call the normal software version. -// If in 2D mode, then use Direct3D calls to perform the drawing. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) -{ - if (In2D < 2) - { - Super::DrawTextureParms(img, parms); - return; - } - if (!InScene) - { - return; - } - - 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) - { - assert(tex != nullptr); - return; - } - - CheckQuadBatch(); - - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x0 = parms.x - parms.left * xscale; - double y0 = parms.y - parms.top * yscale; - double x1 = x0 + parms.destwidth; - double y1 = y0 + parms.destheight; - float u0 = 0; - float v0 = 0; - float u1 = 1; - float v1 = 1; - double uscale = 1.f; - bool scissoring = false; - FBVERTEX *vert; - - if (parms.flipX) - { - swapvalues(u0, u1); - } - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x0 += parms.windowleft * xscale; - u0 = float(u0 + parms.windowleft * uscale); - x1 -= (parms.texwidth - wi) * xscale; - u1 = float(u1 - (parms.texwidth - wi) * uscale); - } - - // Use a scissor test because the math above introduces some jitter - // that is noticeable at low resolutions. - if (y0 < parms.uclip || y1 > parms.dclip || x0 < parms.lclip || x1 > parms.rclip) - { - scissoring = true; - if (QuadBatchPos > 0) - { - EndQuadBatch(); - BeginQuadBatch(); - } - glEnable(GL_SCISSOR_TEST); - glScissor(parms.lclip, parms.uclip, parms.rclip - parms.lclip, parms.dclip - parms.uclip); - } - parms.bilinear = false; - - uint32_t color0, color1; - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - - if (!SetStyle(tex, parms, color0, color1, *quad)) - { - goto done; - } - - quad->Texture = tex->Tex.get(); - if (parms.bilinear) - { - quad->Flags |= BQF_Bilinear; - } - quad->NumTris = 2; - quad->NumVerts = 4; - - vert = &VertexData[VertexPos]; - - { - PalEntry color = color1; - color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); - color1 = color; - } - - // Fill the vertex buffer. - vert[0].x = float(x0); - vert[0].y = float(y0); - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = color0; - vert[0].color1 = color1; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = float(x1); - vert[1].y = float(y0); - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = color0; - vert[1].color1 = color1; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = float(x1); - vert[2].y = float(y1); - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = color0; - vert[2].color1 = color1; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = float(x0); - vert[3].y = float(y1); - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = color0; - vert[3].color1 = color1; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - // Batch the quad. - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -done: - if (scissoring) - { - EndQuadBatch(); - glDisable(GL_SCISSOR_TEST); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: FlatFill -// -// Fills an area with a repeating copy of the texture. -// -//========================================================================== - -void OpenGLSWFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - if (In2D < 2) - { - Super::FlatFill(left, top, right, bottom, src, local_origin); - return; - } - if (!InScene) - { - return; - } - OpenGLTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); - if (tex == nullptr) - { - return; - } - float x0 = float(left); - float y0 = float(top); - float x1 = float(right); - float y1 = float(bottom); - float itw = 1.f / float(src->GetWidth()); - float ith = 1.f / float(src->GetHeight()); - float xo = local_origin ? x0 : 0; - float yo = local_origin ? y0 : 0; - float u0 = (x0 - xo) * itw; - float v0 = (y0 - yo) * ith; - float u1 = (x1 - xo) * itw; - float v1 = (y1 - yo) * ith; - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->ClearSetup(); - if (tex->GetTexFormat() == GL_R8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = nullptr; - quad->Texture = tex->Tex.get(); - quad->NumVerts = 4; - quad->NumTris = 2; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -//========================================================================== - -void OpenGLSWFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - // Use an equation similar to player sprites to determine shade - double fadelevel = clamp((swrenderer::LightVisibility::LightLevelToShade(lightlevel, true) / 65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); - - BufferedTris *quad; - FBVERTEX *verts; - OpenGLTex *tex; - float uscale, vscale; - int i, ipos; - uint32_t color0, color1; - float ox, oy; - float cosrot, sinrot; - bool dorotate = rotation != 0; - - if (npoints < 3) - { // This is no polygon. - return; - } - if (In2D < 2) - { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel, flatcolor, bottomclip); - return; - } - if (!InScene) - { - return; - } - tex = static_cast(texture->GetNative(texture->GetFormat(), true)); - if (tex == nullptr) - { - return; - } - - cosrot = (float)cos(rotation.Radians()); - sinrot = (float)sin(rotation.Radians()); - - CheckQuadBatch(npoints - 2, npoints); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - color0 = 0; - color1 = 0xFFFFFFFF; - - quad->ClearSetup(); - if (tex->GetTexFormat() == GL_R8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - if (colormap.Desaturation != 0) - { - quad->Flags |= BQF_Desaturated; - } - quad->ShaderNum = BQS_InGameColormap; - quad->Desat = colormap.Desaturation; - color0 = ColorARGB(255, colormap.LightColor.r, colormap.LightColor.g, colormap.LightColor.b); - color1 = ColorARGB(uint32_t((1 - fadelevel) * 255), - uint32_t(colormap.FadeColor.r * fadelevel), - uint32_t(colormap.FadeColor.g * fadelevel), - uint32_t(colormap.FadeColor.b * fadelevel)); - } - else - { - quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = nullptr; - quad->Texture = tex->Tex.get(); - quad->NumVerts = npoints; - quad->NumTris = npoints - 2; - - uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - ox = float(originx); - oy = float(originy); - - for (i = 0; i < npoints; ++i) - { - verts[i].x = points[i].X; - verts[i].y = points[i].Y; - verts[i].z = 0; - verts[i].rhw = 1; - verts[i].color0 = color0; - verts[i].color1 = color1; - float u = points[i].X - ox; - float v = points[i].Y - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - verts[i].tu = u * uscale; - verts[i].tv = v * vscale; - } - for (ipos = IndexPos, i = 2; i < npoints; ++i, ipos += 3) - { - IndexData[ipos] = VertexPos; - IndexData[ipos + 1] = VertexPos + i - 1; - IndexData[ipos + 2] = VertexPos + i; - } - - QuadBatchPos++; - VertexPos += npoints; - IndexPos = ipos; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: AddColorOnlyQuad -// -// Adds a single-color, untextured quad to the batch. -// -//========================================================================== - -void OpenGLSWFrameBuffer::AddColorOnlyQuad(int left, int top, int width, int height, uint32_t color) -{ - BufferedTris *quad; - FBVERTEX *verts; - - CheckQuadBatch(); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - float x = float(left); - float y = float(top); - - quad->ClearSetup(); - quad->ShaderNum = BQS_ColorOnly; - if ((color & 0xFF000000) != 0xFF000000) - { - quad->BlendOp = GL_FUNC_ADD; - quad->SrcBlend = GL_SRC_ALPHA; - quad->DestBlend = GL_ONE_MINUS_SRC_ALPHA; - } - quad->Palette = nullptr; - quad->Texture = nullptr; - quad->NumVerts = 4; - quad->NumTris = 2; - - verts[0].x = x; - verts[0].y = y; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color; - verts[0].color1 = 0; - verts[0].tu = 0; - verts[0].tv = 0; - - verts[1].x = x + width; - verts[1].y = y; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color; - verts[1].color1 = 0; - verts[1].tu = 0; - verts[1].tv = 0; - - verts[2].x = x + width; - verts[2].y = y + height; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color; - verts[2].color1 = 0; - verts[2].tu = 0; - verts[2].tv = 0; - - verts[3].x = x; - verts[3].y = y + height; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color; - verts[3].color1 = 0; - verts[3].tu = 0; - verts[3].tv = 0; - - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: AddColorOnlyRect -// -// Like AddColorOnlyQuad, except it's hollow. -// -//========================================================================== - -void OpenGLSWFrameBuffer::AddColorOnlyRect(int left, int top, int width, int height, uint32_t color) -{ - AddColorOnlyQuad(left, top, width - 1, 1, color); // top - AddColorOnlyQuad(left + width - 1, top, 1, height - 1, color); // right - AddColorOnlyQuad(left + 1, top + height - 1, width - 1, 1, color); // bottom - AddColorOnlyQuad(left, top + 1, 1, height - 1, color); // left -} +#endif //========================================================================== // @@ -2921,199 +2337,6 @@ void OpenGLSWFrameBuffer::EndBatch() } } -//========================================================================== -// -// OpenGLSWFrameBuffer :: SetStyle -// -// Patterned after R_SetPatchStyle. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::SetStyle(OpenGLTex *tex, DrawParms &parms, uint32_t &color0, uint32_t &color1, BufferedTris &quad) -{ - int fmt = tex->GetTexFormat(); - FRenderStyle style = parms.style; - float alpha; - bool stencilling; - - if (style.Flags & STYLEF_TransSoulsAlpha) - { - alpha = transsouls; - } - else if (style.Flags & STYLEF_Alpha1) - { - alpha = 1; - } - else - { - alpha = clamp(parms.Alpha, 0.f, 1.f); - } - - style.CheckFuzz(); - if (style.BlendOp == STYLEOP_Shadow) - { - style = LegacyRenderStyles[STYLE_TranslucentStencil]; - alpha = 0.3f; - parms.fillcolor = 0; - } - - // FIXME: Fuzz effect is not written - if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz) - { - style.BlendOp = STYLEOP_Add; - } - else if (style.BlendOp == STYLEOP_FuzzOrSub) - { - style.BlendOp = STYLEOP_Sub; - } - else if (style.BlendOp == STYLEOP_FuzzOrRevSub) - { - style.BlendOp = STYLEOP_RevSub; - } - - stencilling = false; - quad.Palette = nullptr; - quad.Flags = 0; - quad.Desat = 0; - - switch (style.BlendOp) - { - default: - case STYLEOP_Add: quad.BlendOp = GL_FUNC_ADD; break; - case STYLEOP_Sub: quad.BlendOp = GL_FUNC_SUBTRACT; break; - case STYLEOP_RevSub: quad.BlendOp = GL_FUNC_REVERSE_SUBTRACT; break; - case STYLEOP_None: return false; - } - quad.SrcBlend = GetStyleAlpha(style.SrcAlpha); - quad.DestBlend = GetStyleAlpha(style.DestAlpha); - - if (style.Flags & STYLEF_InvertOverlay) - { - // Only the overlay color is inverted, not the overlay alpha. - parms.colorOverlay = ColorARGB(APART(parms.colorOverlay), - 255 - RPART(parms.colorOverlay), 255 - GPART(parms.colorOverlay), - 255 - BPART(parms.colorOverlay)); - } - - SetColorOverlay(parms.colorOverlay, alpha, color0, color1); - - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { // Since the source color is a constant, we can invert it now - // without spending time doing it in the shader. - parms.fillcolor = ColorXRGB(255 - RPART(parms.fillcolor), - 255 - GPART(parms.fillcolor), 255 - BPART(parms.fillcolor)); - } - // Set up the color mod to replace the color from the image data. - color0 = (color0 & ColorRGBA(0, 0, 0, 255)) | (parms.fillcolor & ColorRGBA(255, 255, 255, 0)); - color1 &= ColorRGBA(0, 0, 0, 255); - - if (style.Flags & STYLEF_RedIsAlpha) - { - // Note that if the source texture is paletted, the palette is ignored. - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == GL_R8) - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - } - else - { - if (style.Flags & STYLEF_RedIsAlpha) - { - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == GL_R8) - { - if (parms.remap != nullptr) - { - quad.Flags = BQF_CustomPalette; - quad.Palette = reinterpret_cast(parms.remap->GetNative()); - quad.ShaderNum = BQS_PalTex; - } - else if (tex->IsGray) - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - else - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - if (style.Flags & STYLEF_InvertSource) - { - quad.Flags |= BQF_InvertSource; - } - - if (parms.specialcolormap != nullptr) - { // Emulate an invulnerability or similar colormap. - float *start, *end; - start = parms.specialcolormap->ColorizeStart; - end = parms.specialcolormap->ColorizeEnd; - if (quad.Flags & BQF_InvertSource) - { - quad.Flags &= ~BQF_InvertSource; - swapvalues(start, end); - } - quad.ShaderNum = BQS_SpecialColormap; - color0 = ColorRGBA(uint32_t(start[0] / 2 * 255), uint32_t(start[1] / 2 * 255), uint32_t(start[2] / 2 * 255), color0 >> 24); - color1 = ColorRGBA(uint32_t(end[0] / 2 * 255), uint32_t(end[1] / 2 * 255), uint32_t(end[2] / 2 * 255), color1 >> 24); - } - else if (parms.colormapstyle != nullptr) - { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) - if (parms.colormapstyle->Desaturate != 0) - { - quad.Flags |= BQF_Desaturated; - } - quad.ShaderNum = BQS_InGameColormap; - quad.Desat = parms.colormapstyle->Desaturate; - color0 = ColorARGB(color1 >> 24, - parms.colormapstyle->Color.r, - parms.colormapstyle->Color.g, - parms.colormapstyle->Color.b); - double fadelevel = parms.colormapstyle->FadeLevel; - color1 = ColorARGB(uint32_t((1 - fadelevel) * 255), - uint32_t(parms.colormapstyle->Fade.r * fadelevel), - uint32_t(parms.colormapstyle->Fade.g * fadelevel), - uint32_t(parms.colormapstyle->Fade.b * fadelevel)); - } - } - - // For unmasked images, force the alpha from the image data to be ignored. - if (!parms.masked && quad.ShaderNum != BQS_InGameColormap) - { - color0 = (color0 & ColorRGBA(255, 255, 255, 0)) | ColorValue(0, 0, 0, alpha); - color1 &= ColorRGBA(255, 255, 255, 0); - - // If our alpha is one and we are doing normal adding, then we can turn the blend off completely. - if (quad.BlendOp == GL_FUNC_ADD && - ((alpha == 1 && quad.SrcBlend == GL_SRC_ALPHA) || quad.SrcBlend == GL_ONE) && - ((alpha == 1 && quad.DestBlend == GL_ONE_MINUS_SRC_ALPHA) || quad.DestBlend == GL_ZERO)) - { - quad.BlendOp = 0; - } - quad.Flags |= BQF_DisableAlphaTest; - } - return true; -} - int OpenGLSWFrameBuffer::GetStyleAlpha(int type) { switch (type) @@ -3127,26 +2350,6 @@ int OpenGLSWFrameBuffer::GetStyleAlpha(int type) } -void OpenGLSWFrameBuffer::SetColorOverlay(uint32_t color, float alpha, uint32_t &color0, uint32_t &color1) -{ - if (APART(color) != 0) - { - int a = APART(color) * 256 / 255; - color0 = ColorRGBA( - (RPART(color) * a) >> 8, - (GPART(color) * a) >> 8, - (BPART(color) * a) >> 8, - 0); - a = 256 - a; - color1 = ColorRGBA(a, a, a, int(alpha * 255)); - } - else - { - color0 = 0; - color1 = ColorValue(1, 1, 1, alpha); - } -} - void OpenGLSWFrameBuffer::EnableAlphaTest(bool enabled) { if (enabled != AlphaTestEnabled) diff --git a/src/gl/system/gl_swframebuffer.h b/src/gl/system/gl_swframebuffer.h index d8f1eec31..7120b7857 100644 --- a/src/gl/system/gl_swframebuffer.h +++ b/src/gl/system/gl_swframebuffer.h @@ -54,13 +54,6 @@ public: void DrawBlendingRect() 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; - void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) override; - void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) override; - void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) override; - void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor) override; - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override; bool WipeStartScreen(int type) override; void WipeEndScreen() override; bool WipeDo(int ticks) override; @@ -365,11 +358,7 @@ private: void KillNativeTexs(); void DrawLetterbox(int x, int y, int width, int height); void Draw3DPart(bool copy3d); - bool SetStyle(OpenGLTex *tex, DrawParms &parms, uint32_t &color0, uint32_t &color1, BufferedTris &quad); static int GetStyleAlpha(int type); - static void SetColorOverlay(uint32_t color, float alpha, uint32_t &color0, uint32_t &color1); - void AddColorOnlyQuad(int left, int top, int width, int height, uint32_t color); - void AddColorOnlyRect(int left, int top, int width, int height, uint32_t color); void CheckQuadBatch(int numtris = 2, int numverts = 4); void BeginQuadBatch(); void EndQuadBatch(); diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 36b8ca815..805e031eb 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -169,8 +169,8 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) void OpenGLFrameBuffer::WipeEndScreen() { - GLRenderer->m2DDrawer->Draw(); - GLRenderer->m2DDrawer->Clear(); + screen->Draw2D(); + screen->Clear2D(); const auto &viewport = GLRenderer->mScreenViewport; wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index eedf6848c..8ed935dd4 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -74,6 +74,20 @@ CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) CVAR(Int, m_use_mouse, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Float, dimamount, -1.f, CVAR_ARCHIVE) +{ + if (self < 0.f && self != -1.f) + { + self = -1.f; + } + else if (self > 1.f) + { + self = 1.f; + } +} +CVAR(Color, dimcolor, 0xffd700, CVAR_ARCHIVE) + + DEFINE_ACTION_FUNCTION(DMenu, GetCurrentMenu) { @@ -766,6 +780,41 @@ void M_Ticker (void) } } +//========================================================================== +// +// M_Dim +// +// Applies a colored overlay to the entire screen, with the opacity +// determined by the dimamount cvar. +// +//========================================================================== + +static void M_Dim() +{ + PalEntry dimmer; + float amount; + + if (dimamount >= 0) + { + dimmer = PalEntry(dimcolor); + amount = dimamount; + } + else + { + dimmer = gameinfo.dimcolor; + amount = gameinfo.dimamount; + } + + if (gameinfo.gametype == GAME_Hexen && gamestate == GS_DEMOSCREEN) + { // On the Hexen title screen, the default dimming is not + // enough to make the menus readable. + amount = MIN(1.f, amount*2.f); + } + + screen->Dim(dimmer, amount, 0, 0, screen->GetWidth(), screen->GetHeight()); +} + + //============================================================================= // // @@ -784,7 +833,7 @@ void M_Drawer (void) GLRenderer->BlurScene(gameinfo.bluramount); if (!CurrentMenu->DontDim) { - screen->Dim(fade); + M_Dim(); V_SetBorderNeedRefresh(); } CurrentMenu->CallDrawer(); diff --git a/src/textures/textures.h b/src/textures/textures.h index 410f28ea2..68e0ab132 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -38,7 +38,7 @@ #include "doomtype.h" #include "vectors.h" #include "v_palette.h" -#include "v_video.h" +#include "v_colortables.h" #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" diff --git a/src/v_colortables.h b/src/v_colortables.h new file mode 100644 index 000000000..42135229b --- /dev/null +++ b/src/v_colortables.h @@ -0,0 +1,52 @@ +#pragma once + +// extracted from v_video.h because this caused circular dependencies between v_video.h and textures.h + +// Translucency tables + +// RGB32k is a normal R5G5B5 -> palette lookup table. + +// Use a union so we can "overflow" without warnings. +// Otherwise, we get stuff like this from Clang (when compiled +// with -fsanitize=bounds) while running: +// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'uint8_t [32]' +// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'uint8_t [32]' +union ColorTable32k +{ + uint8_t RGB[32][32][32]; + uint8_t All[32 *32 *32]; +}; +extern ColorTable32k RGB32k; + +// [SP] RGB666 support +union ColorTable256k +{ + uint8_t RGB[64][64][64]; + uint8_t All[64 *64 *64]; +}; +extern ColorTable256k RGB256k; + +// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a +// special R10B10G10 format for efficient blending computation. +// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 +// --------rrrr------bbbb------gggg at level 1 +extern uint32_t Col2RGB8[65][256]; + +// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red +// and blue are forced to zero, so if the blend overflows, it won't spill +// over into the next component's value. +// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 +// --------rrr#------bbb#------gggg at level 1 +extern uint32_t *Col2RGB8_LessPrecision[65]; + +// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source +// palette has been inverted. +extern uint32_t Col2RGB8_Inverse[65][256]; + +// "Magic" numbers used during the blending: +// --000001111100000111110000011111 = 0x01f07c1f +// -0111111111011111111101111111111 = 0x3FEFFBFF +// -1000000000100000000010000000000 = 0x40100400 +// ------10000000001000000000100000 = 0x40100400 >> 5 +// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" +// --111111111111111111111111111111 = 0x3FFFFFFF diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 0029e124c..04e16ff42 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -59,19 +59,6 @@ #include "textures.h" #include "vm.h" -CUSTOM_CVAR(Float, dimamount, -1.f, CVAR_ARCHIVE) -{ - if (self < 0.f && self != -1.f) - { - self = -1.f; - } - else if (self > 1.f) - { - self = 1.f; - } -} -CVAR(Color, dimcolor, 0xffd700, CVAR_ARCHIVE) - CUSTOM_CVAR(Int, uiscale, 0, CVAR_ARCHIVE | CVAR_NOINITCALL) { if (self < 0) @@ -476,6 +463,7 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 parms->colorOverlay = 0; parms->alphaChannel = false; parms->flipX = false; + parms->flipY = false; parms->color = 0xffffffff; //parms->shadowAlpha = 0; parms->shadowColor = 0; @@ -492,6 +480,10 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 parms->cellx = parms->celly = 0; parms->maxstrlen = INT_MAX; parms->virtBottom = false; + parms->srcx = 0.; + parms->srcy = 0.; + parms->srcwidth = 1.; + parms->srcheight = 1.; // Parse the tag list for attributes. (For floating point attributes, // consider that the C ABI dictates that all floats be promoted to @@ -661,6 +653,26 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 parms->flipX = ListGetInt(tags); break; + case DTA_FlipY: + parms->flipY = ListGetInt(tags); + break; + + case DTA_SrcX: + parms->srcx = ListGetDouble(tags) / img->GetScaledWidthDouble(); + break; + + case DTA_SrcY: + parms->srcy = ListGetDouble(tags) / img->GetScaledHeightDouble(); + break; + + case DTA_SrcWidth: + parms->srcwidth = ListGetDouble(tags) / img->GetScaledWidthDouble(); + break; + + case DTA_SrcHeight: + parms->srcheight = ListGetDouble(tags) / img->GetScaledHeightDouble(); + break; + case DTA_TopOffset: assert(fortext == false); if (fortext) return false; @@ -1029,6 +1041,7 @@ void DFrameBuffer::FillBorder (FTexture *img) void DFrameBuffer::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) { + m2DDrawer.AddLine(x0, y0, x1, y1, palColor, realcolor); } DEFINE_ACTION_FUNCTION(_Screen, DrawLine) @@ -1052,6 +1065,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawLine) void DFrameBuffer::DrawPixel(int x, int y, int palColor, uint32_t realcolor) { + m2DDrawer.AddPixel(x, y, palColor, realcolor); } //========================================================================== @@ -1062,10 +1076,6 @@ void DFrameBuffer::DrawPixel(int x, int y, int palColor, uint32_t realcolor) // //========================================================================== -void DFrameBuffer::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ -} - void DFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) { if (clipwidth >= 0 && clipheight >= 0) @@ -1090,7 +1100,12 @@ void DFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, right = left + w; bottom = top + h; } - DoClear(left, top, right, bottom, palcolor, color); + + if (palcolor >= 0 && color == 0) + { + color = GPalette.BaseColors[palcolor] | 0xff000000; + } + m2DDrawer.AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); } DEFINE_ACTION_FUNCTION(_Screen, Clear) @@ -1115,8 +1130,17 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear) // //========================================================================== -void DFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h) +void DFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) { + if (amount <= 0) + { + return; + } + if (amount > 1) + { + amount = 1; + } + m2DDrawer.AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); } void DFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h) @@ -1175,6 +1199,7 @@ void DFrameBuffer::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) { + m2DDrawer.AddPoly(tex, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel); } //========================================================================== @@ -1188,68 +1213,9 @@ void DFrameBuffer::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, void DFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) { - int w = src->GetWidth(); - int h = src->GetHeight(); - - // Repeatedly draw the texture, left-to-right, top-to-bottom. - for (int y = local_origin ? top : (top / h * h); y < bottom; y += h) - { - for (int x = local_origin ? left : (left / w * w); x < right; x += w) - { - DrawTexture(src, x, y, - DTA_ClipLeft, left, - DTA_ClipRight, right, - DTA_ClipTop, top, - DTA_ClipBottom, bottom, - DTA_TopOffset, 0, - DTA_LeftOffset, 0, - TAG_DONE); - } - } + m2DDrawer.AddFlatFill(left, top, right, bottom, src, local_origin); } -//========================================================================== -// -// DCanvas :: Dim -// -// Applies a colored overlay to the entire screen, with the opacity -// determined by the dimamount cvar. -// -//========================================================================== - -void DFrameBuffer::Dim(PalEntry color) -{ - PalEntry dimmer; - float amount; - - if (dimamount >= 0) - { - dimmer = PalEntry(dimcolor); - amount = dimamount; - } - else - { - dimmer = gameinfo.dimcolor; - amount = gameinfo.dimamount; - } - - if (gameinfo.gametype == GAME_Hexen && gamestate == GS_DEMOSCREEN) - { // On the Hexen title screen, the default dimming is not - // enough to make the menus readable. - amount = MIN(1.f, amount*2.f); - } - // Add the cvar's dimming on top of the color passed to the function - if (color.a != 0) - { - float dim[4] = { color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f }; - V_AddBlend(dimmer.r / 255.f, dimmer.g / 255.f, dimmer.b / 255.f, amount, dim); - dimmer = PalEntry(uint8_t(dim[0] * 255), uint8_t(dim[1] * 255), uint8_t(dim[2] * 255)); - amount = dim[3]; - } - Dim(dimmer, amount, 0, 0, Width, Height); -} - - //========================================================================== // // V_SetBorderNeedRefresh diff --git a/src/v_video.h b/src/v_video.h index cd2b8420e..56d62f799 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -41,6 +41,8 @@ #include "dobject.h" #include "r_data/renderstyle.h" #include "c_cvars.h" +#include "v_colortables.h" +#include "v_2ddrawer.h" extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac; extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1; @@ -129,6 +131,12 @@ enum // New additions. DTA_Color, + DTA_FlipY, // bool: flip image vertically + DTA_SrcX, // specify a source rectangle (this supersedes the poorly implemented DTA_WindowLeft/Right + DTA_SrcY, + DTA_SrcWidth, + DTA_SrcHeight + }; enum @@ -162,12 +170,13 @@ struct DrawParms double top; double left; float Alpha; - uint32_t fillcolor; + PalEntry fillcolor; FRemapTable *remap; - uint32_t colorOverlay; + PalEntry colorOverlay; PalEntry color; INTBOOL alphaChannel; INTBOOL flipX; + INTBOOL flipY; //float shadowAlpha; int shadowColor; INTBOOL keepratio; @@ -181,6 +190,8 @@ struct DrawParms int maxstrlen; bool fortext; bool virtBottom; + double srcx, srcy; + double srcwidth, srcheight; }; struct Va_List @@ -276,10 +287,11 @@ public: class DFrameBuffer { typedef DSimpleCanvas Super; + F2DDrawer m2DDrawer; protected: void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete; - virtual void DrawTextureParms(FTexture *img, DrawParms &parms); + void DrawTextureParms(FTexture *img, DrawParms &parms); template bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const; @@ -394,30 +406,30 @@ public: void SetClipRect(int x, int y, int w, int h); void GetClipRect(int *x, int *y, int *w, int *h); - // Dim the entire canvas for the menus - virtual void Dim(PalEntry color = 0); + virtual void Draw2D() {} + void Clear2D() { m2DDrawer.Clear(); } // Dim part of the canvas - virtual void Dim(PalEntry color, float amount, int x1, int y1, int w, int h) final; - virtual void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h); + void Dim(PalEntry color, float amount, int x1, int y1, int w, int h); + void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h); // Fill an area with a texture - virtual void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false); + void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false); // Fill a simple polygon with a texture - virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, + void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); // Set an area to a specified color - virtual void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) final; - virtual void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); + void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color); // Draws a line - virtual void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); + void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); // Draws a single pixel - virtual void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); + void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); + bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; void DrawTexture(FTexture *img, double x, double y, int tags, ...); @@ -482,54 +494,6 @@ extern DFrameBuffer *screen; EXTERN_CVAR (Float, Gamma) -// Translucency tables - -// RGB32k is a normal R5G5B5 -> palette lookup table. - -// Use a union so we can "overflow" without warnings. -// Otherwise, we get stuff like this from Clang (when compiled -// with -fsanitize=bounds) while running: -// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'uint8_t [32]' -// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'uint8_t [32]' -union ColorTable32k -{ - uint8_t RGB[32][32][32]; - uint8_t All[32 *32 *32]; -}; -extern ColorTable32k RGB32k; - -// [SP] RGB666 support -union ColorTable256k -{ - uint8_t RGB[64][64][64]; - uint8_t All[64 *64 *64]; -}; -extern ColorTable256k RGB256k; - -// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a -// special R10B10G10 format for efficient blending computation. -// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 -// --------rrrr------bbbb------gggg at level 1 -extern uint32_t Col2RGB8[65][256]; - -// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red -// and blue are forced to zero, so if the blend overflows, it won't spill -// over into the next component's value. -// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 -// --------rrr#------bbb#------gggg at level 1 -extern uint32_t *Col2RGB8_LessPrecision[65]; - -// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source -// palette has been inverted. -extern uint32_t Col2RGB8_Inverse[65][256]; - -// "Magic" numbers used during the blending: -// --000001111100000111110000011111 = 0x01f07c1f -// -0111111111011111111101111111111 = 0x3FEFFBFF -// -1000000000100000000010000000000 = 0x40100400 -// ------10000000001000000000100000 = 0x40100400 >> 5 -// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" -// --111111111111111111111111111111 = 0x3FFFFFFF // Allocates buffer screens, call before R_Init. void V_Init (bool restart); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index e38b66a15..44ddcc7b3 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1785,65 +1785,6 @@ FNativePalette *D3DFB::CreatePalette(FRemapTable *remap) return tex; } -//========================================================================== -// -// D3DFB :: Clear -// -// Fills the specified region with a color. -// -//========================================================================== - -void D3DFB::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DoClear(left, top, right, bottom, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (palcolor >= 0 && color == 0) - { - color = GPalette.BaseColors[palcolor]; - } - else if (APART(color) < 255) - { - Dim(color, APART(color)/255.f, left, top, right - left, bottom - top); - return; - } - AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); -} - -//========================================================================== -// -// D3DFB :: Dim -// -//========================================================================== - -void D3DFB::DoDim (PalEntry color, float amount, int x1, int y1, int w, int h) -{ - if (amount <= 0) - { - return; - } - if (In2D < 2) - { - Super::DoDim(color, amount, x1, y1, w, h); - return; - } - if (!InScene) - { - return; - } - if (amount > 1) - { - amount = 1; - } - AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); -} - //========================================================================== // // D3DFB :: BeginLineBatch @@ -1886,53 +1827,6 @@ void D3DFB::EndLineBatch() BatchType = BATCH_None; } -//========================================================================== -// -// D3DFB :: DrawLine -// -//========================================================================== - -void D3DFB::DrawLine(int x0, int y0, int x1, int y1, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawLine(x0, y0, x1, y1, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (BatchType != BATCH_Lines) - { - BeginLineBatch(); - } - if (VertexPos == NUM_VERTS) - { // Flush the buffer and refill it. - EndLineBatch(); - BeginLineBatch(); - } - // Add the endpoints to the vertex buffer. - VertexData[VertexPos].x = float(x0); - VertexData[VertexPos].y = float(y0) + LBOffset; - VertexData[VertexPos].z = 0; - VertexData[VertexPos].rhw = 1; - VertexData[VertexPos].color0 = color; - VertexData[VertexPos].color1 = 0; - VertexData[VertexPos].tu = 0; - VertexData[VertexPos].tv = 0; - - VertexData[VertexPos+1].x = float(x1); - VertexData[VertexPos+1].y = float(y1) + LBOffset; - VertexData[VertexPos+1].z = 0; - VertexData[VertexPos+1].rhw = 1; - VertexData[VertexPos+1].color0 = color; - VertexData[VertexPos+1].color1 = 0; - VertexData[VertexPos+1].tu = 0; - VertexData[VertexPos+1].tv = 0; - - VertexPos += 2; -} //========================================================================== // @@ -1940,6 +1834,7 @@ void D3DFB::DrawLine(int x0, int y0, int x1, int y1, int palcolor, uint32_t colo // //========================================================================== +#if 0 void D3DFB::DrawPixel(int x, int y, int palcolor, uint32_t color) { if (In2D < 2) @@ -1960,512 +1855,7 @@ void D3DFB::DrawPixel(int x, int y, int palcolor, uint32_t color) SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); D3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &pt, sizeof(FBVERTEX)); } - -//========================================================================== -// -// D3DFB :: DrawTextureV -// -// If not in 2D mode, just call the normal software version. -// If in 2D mode, then use Direct3D calls to perform the drawing. -// -//========================================================================== - -void D3DFB::DrawTextureParms (FTexture *img, DrawParms &parms) -{ - if (In2D < 2) - { - Super::DrawTextureParms(img, parms); - return; - } - if (!InScene) - { - return; - } - - 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) - { - assert(tex != NULL); - return; - } - - CheckQuadBatch(); - - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x0 = parms.x - parms.left * xscale; - double y0 = parms.y - parms.top * yscale; - double x1 = x0 + parms.destwidth; - double y1 = y0 + parms.destheight; - float u0 = 0; - float v0 = 0; - float u1 = 1; - float v1 = 1; - double uscale = 1.f; - bool scissoring = false; - FBVERTEX *vert; - float yoffs; - - if (parms.flipX) - { - swapvalues(u0, u1); - } - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x0 += parms.windowleft * xscale; - u0 = float(u0 + parms.windowleft * uscale); - x1 -= (parms.texwidth - wi) * xscale; - u1 = float(u1 - (parms.texwidth - wi) * uscale); - } - - // Use a scissor test because the math above introduces some jitter - // that is noticeable at low resolutions. - - if (y0 < parms.uclip || y1 > parms.dclip || x0 < parms.lclip || x1 > parms.rclip) - { - scissoring = true; - if (QuadBatchPos > 0) - { - EndQuadBatch(); - BeginQuadBatch(); - } - RECT scissor = { - parms.lclip, parms.uclip + LBOffsetI, - parms.rclip, parms.dclip + LBOffsetI - }; - D3DDevice->SetScissorRect(&scissor); - D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - } - - parms.bilinear = false; - - D3DCOLOR color0, color1; - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - - if (!SetStyle(tex, parms, color0, color1, *quad)) - { - goto done; - } - - quad->Texture = tex->Tex; - if (parms.bilinear) - { - quad->Flags |= BQF_Bilinear; - } - quad->NumTris = 2; - quad->NumVerts = 4; - - yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; - - x0 = x0 - 0.5f; - y0 = y0 - yoffs; - x1 = x1 - 0.5f; - y1 = y1 - yoffs; - - vert = &VertexData[VertexPos]; - - { - PalEntry color = color1; - color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); - color1 = color; - } - - // Fill the vertex buffer. - vert[0].x = float(x0); - vert[0].y = float(y0); - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = color0; - vert[0].color1 = color1; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = float(x1); - vert[1].y = float(y0); - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = color0; - vert[1].color1 = color1; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = float(x1); - vert[2].y = float(y1); - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = color0; - vert[2].color1 = color1; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = float(x0); - vert[3].y = float(y1); - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = color0; - vert[3].color1 = color1; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - // Batch the quad. - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -done: - if (scissoring) - { - EndQuadBatch(); - D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - } -} - -//========================================================================== -// -// D3DFB :: FlatFill -// -// Fills an area with a repeating copy of the texture. -// -//========================================================================== - -void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - if (In2D < 2) - { - Super::FlatFill(left, top, right, bottom, src, local_origin); - return; - } - if (!InScene) - { - return; - } - - D3DTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); - if (tex == NULL) - { - return; - } - float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; - float x0 = float(left); - float y0 = float(top); - float x1 = float(right); - float y1 = float(bottom); - float itw = 1.f / float(src->GetWidth()); - float ith = 1.f / float(src->GetHeight()); - float xo = local_origin ? x0 : 0; - float yo = local_origin ? y0 : 0; - float u0 = (x0 - xo) * itw; - float v0 = (y0 - yo) * ith; - float u1 = (x1 - xo) * itw; - float v1 = (y1 - yo) * ith; - x0 -= 0.5f; - y0 -= yoffs; - x1 -= 0.5f; - y1 -= yoffs; - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->Group1 = 0; - if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = NULL; - quad->Texture = tex->Tex; - quad->NumVerts = 4; - quad->NumTris = 2; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// D3DFB :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -// Bottomclip is ignored by this implementation, since the hardware renderer -// will unconditionally draw the status bar border every frame on top of the -// polygons, so there's no need to waste time setting up a special scissor -// rectangle here and needlessly forcing separate batches. -// -//========================================================================== - -void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - // Use an equation similar to player sprites to determine shade - double fadelevel = clamp((swrenderer::LightVisibility::LightLevelToShade(lightlevel, true)/65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); - - BufferedTris *quad; - FBVERTEX *verts; - D3DTex *tex; - float yoffs, uscale, vscale; - int i, ipos; - D3DCOLOR color0, color1; - float ox, oy; - float cosrot, sinrot; - bool dorotate = rotation != 0; - - if (npoints < 3) - { // This is no polygon. - return; - } - if (In2D < 2) - { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel, bottomclip); - return; - } - if (!InScene) - { - return; - } - - tex = static_cast(texture->GetNative(texture->GetFormat(), true)); - if (tex == NULL) - { - return; - } - - cosrot = (float)cos(rotation.Radians()); - sinrot = (float)sin(rotation.Radians()); - - CheckQuadBatch(npoints - 2, npoints); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - color0 = 0; - color1 = 0xFFFFFFFF; - - quad->Group1 = 0; - if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - if (colormap.Desaturation != 0) - { - quad->Flags |= BQF_Desaturated; - } - quad->ShaderNum = BQS_InGameColormap; - quad->Desat = colormap.Desaturation; - color0 = D3DCOLOR_ARGB(255, colormap.LightColor.r, colormap.LightColor.g, colormap.LightColor.b); - color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), - DWORD(colormap.FadeColor.r * fadelevel), - DWORD(colormap.FadeColor.g * fadelevel), - DWORD(colormap.FadeColor.b * fadelevel)); - } - else - { - quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = NULL; - quad->Texture = tex->Tex; - quad->NumVerts = npoints; - quad->NumTris = npoints - 2; - - yoffs = GatheringWipeScreen ? 0 : LBOffset; - uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - ox = float(originx); - oy = float(originy); - - for (i = 0; i < npoints; ++i) - { - verts[i].x = points[i].X; - verts[i].y = points[i].Y + yoffs; - verts[i].z = 0; - verts[i].rhw = 1; - verts[i].color0 = color0; - verts[i].color1 = color1; - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - verts[i].tu = u * uscale; - verts[i].tv = v * vscale; - } - for (ipos = IndexPos, i = 2; i < npoints; ++i, ipos += 3) - { - IndexData[ipos ] = VertexPos; - IndexData[ipos + 1] = VertexPos + i - 1; - IndexData[ipos + 2] = VertexPos + i; - } - - QuadBatchPos++; - VertexPos += npoints; - IndexPos = ipos; -} - -//========================================================================== -// -// D3DFB :: AddColorOnlyQuad -// -// Adds a single-color, untextured quad to the batch. -// -//========================================================================== - -void D3DFB::AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color) -{ - BufferedTris *quad; - FBVERTEX *verts; - - CheckQuadBatch(); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - float x = float(left) - 0.5f; - float y = float(top) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset); - - quad->Group1 = 0; - quad->ShaderNum = BQS_ColorOnly; - if ((color & 0xFF000000) != 0xFF000000) - { - quad->BlendOp = D3DBLENDOP_ADD; - quad->SrcBlend = D3DBLEND_SRCALPHA; - quad->DestBlend = D3DBLEND_INVSRCALPHA; - } - quad->Palette = NULL; - quad->Texture = NULL; - quad->NumVerts = 4; - quad->NumTris = 2; - - verts[0].x = x; - verts[0].y = y; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color; - verts[0].color1 = 0; - verts[0].tu = 0; - verts[0].tv = 0; - - verts[1].x = x + width; - verts[1].y = y; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color; - verts[1].color1 = 0; - verts[1].tu = 0; - verts[1].tv = 0; - - verts[2].x = x + width; - verts[2].y = y + height; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color; - verts[2].color1 = 0; - verts[2].tu = 0; - verts[2].tv = 0; - - verts[3].x = x; - verts[3].y = y + height; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color; - verts[3].color1 = 0; - verts[3].tu = 0; - verts[3].tv = 0; - - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// D3DFB :: AddColorOnlyRect -// -// Like AddColorOnlyQuad, except it's hollow. -// -//========================================================================== - -void D3DFB::AddColorOnlyRect(int left, int top, int width, int height, D3DCOLOR color) -{ - AddColorOnlyQuad(left, top, width - 1, 1, color); // top - AddColorOnlyQuad(left + width - 1, top, 1, height - 1, color); // right - AddColorOnlyQuad(left + 1, top + height - 1, width - 1, 1, color); // bottom - AddColorOnlyQuad(left, top + 1, 1, height - 1, color); // left -} +#endif //========================================================================== // @@ -2690,199 +2080,6 @@ void D3DFB::EndBatch() } } -//========================================================================== -// -// D3DFB :: SetStyle -// -// Patterned after R_SetPatchStyle. -// -//========================================================================== - -bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedTris &quad) -{ - D3DFORMAT fmt = tex->GetTexFormat(); - FRenderStyle style = parms.style; - float alpha; - bool stencilling; - - if (style.Flags & STYLEF_TransSoulsAlpha) - { - alpha = transsouls; - } - else if (style.Flags & STYLEF_Alpha1) - { - alpha = 1; - } - else - { - alpha = clamp(parms.Alpha, 0.f, 1.f); - } - - style.CheckFuzz(); - if (style.BlendOp == STYLEOP_Shadow) - { - style = LegacyRenderStyles[STYLE_TranslucentStencil]; - alpha = 0.3f; - parms.fillcolor = 0; - } - - // FIXME: Fuzz effect is not written - if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz) - { - style.BlendOp = STYLEOP_Add; - } - else if (style.BlendOp == STYLEOP_FuzzOrSub) - { - style.BlendOp = STYLEOP_Sub; - } - else if (style.BlendOp == STYLEOP_FuzzOrRevSub) - { - style.BlendOp = STYLEOP_RevSub; - } - - stencilling = false; - quad.Palette = NULL; - quad.Flags = 0; - quad.Desat = 0; - - switch (style.BlendOp) - { - default: - case STYLEOP_Add: quad.BlendOp = D3DBLENDOP_ADD; break; - case STYLEOP_Sub: quad.BlendOp = D3DBLENDOP_SUBTRACT; break; - case STYLEOP_RevSub: quad.BlendOp = D3DBLENDOP_REVSUBTRACT; break; - case STYLEOP_None: return false; - } - quad.SrcBlend = GetStyleAlpha(style.SrcAlpha); - quad.DestBlend = GetStyleAlpha(style.DestAlpha); - - if (style.Flags & STYLEF_InvertOverlay) - { - // Only the overlay color is inverted, not the overlay alpha. - parms.colorOverlay = D3DCOLOR_ARGB(APART(parms.colorOverlay), - 255 - RPART(parms.colorOverlay), 255 - GPART(parms.colorOverlay), - 255 - BPART(parms.colorOverlay)); - } - - SetColorOverlay(parms.colorOverlay, alpha, color0, color1); - - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { // Since the source color is a constant, we can invert it now - // without spending time doing it in the shader. - parms.fillcolor = D3DCOLOR_XRGB(255 - RPART(parms.fillcolor), - 255 - GPART(parms.fillcolor), 255 - BPART(parms.fillcolor)); - } - // Set up the color mod to replace the color from the image data. - color0 = (color0 & D3DCOLOR_RGBA(0,0,0,255)) | (parms.fillcolor & D3DCOLOR_RGBA(255,255,255,0)); - color1 &= D3DCOLOR_RGBA(0,0,0,255); - - if (style.Flags & STYLEF_RedIsAlpha) - { - // Note that if the source texture is paletted, the palette is ignored. - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == D3DFMT_L8) - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - } - else - { - if (style.Flags & STYLEF_RedIsAlpha) - { - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == D3DFMT_L8) - { - if (parms.remap != NULL) - { - quad.Flags = BQF_CustomPalette; - quad.Palette = reinterpret_cast(parms.remap->GetNative()); - quad.ShaderNum = BQS_PalTex; - } - else if (tex->IsGray) - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - else - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - if (style.Flags & STYLEF_InvertSource) - { - quad.Flags |= BQF_InvertSource; - } - - if (parms.specialcolormap != NULL) - { // Emulate an invulnerability or similar colormap. - float *start, *end; - start = parms.specialcolormap->ColorizeStart; - end = parms.specialcolormap->ColorizeEnd; - if (quad.Flags & BQF_InvertSource) - { - quad.Flags &= ~BQF_InvertSource; - swapvalues(start, end); - } - quad.ShaderNum = BQS_SpecialColormap; - color0 = D3DCOLOR_RGBA(DWORD(start[0]/2*255), DWORD(start[1]/2*255), DWORD(start[2]/2*255), color0 >> 24); - color1 = D3DCOLOR_RGBA(DWORD(end[0]/2*255), DWORD(end[1]/2*255), DWORD(end[2]/2*255), color1 >> 24); - } - else if (parms.colormapstyle != NULL) - { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) - if (parms.colormapstyle->Desaturate != 0) - { - quad.Flags |= BQF_Desaturated; - } - quad.ShaderNum = BQS_InGameColormap; - quad.Desat = parms.colormapstyle->Desaturate; - color0 = D3DCOLOR_ARGB(color1 >> 24, - parms.colormapstyle->Color.r, - parms.colormapstyle->Color.g, - parms.colormapstyle->Color.b); - double fadelevel = parms.colormapstyle->FadeLevel; - color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), - DWORD(parms.colormapstyle->Fade.r * fadelevel), - DWORD(parms.colormapstyle->Fade.g * fadelevel), - DWORD(parms.colormapstyle->Fade.b * fadelevel)); - } - } - - // For unmasked images, force the alpha from the image data to be ignored. - if (!parms.masked && quad.ShaderNum != BQS_InGameColormap) - { - color0 = (color0 & D3DCOLOR_RGBA(255, 255, 255, 0)) | D3DCOLOR_COLORVALUE(0, 0, 0, alpha); - color1 &= D3DCOLOR_RGBA(255, 255, 255, 0); - - // If our alpha is one and we are doing normal adding, then we can turn the blend off completely. - if (quad.BlendOp == D3DBLENDOP_ADD && - ((alpha == 1 && quad.SrcBlend == D3DBLEND_SRCALPHA) || quad.SrcBlend == D3DBLEND_ONE) && - ((alpha == 1 && quad.DestBlend == D3DBLEND_INVSRCALPHA) || quad.DestBlend == D3DBLEND_ZERO)) - { - quad.BlendOp = D3DBLENDOP(0); - } - quad.Flags |= BQF_DisableAlphaTest; - } - return true; -} - D3DBLEND D3DFB::GetStyleAlpha(int type) { switch (type) @@ -2896,26 +2093,6 @@ D3DBLEND D3DFB::GetStyleAlpha(int type) } -void D3DFB::SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1) -{ - if (APART(color) != 0) - { - int a = APART(color) * 256 / 255; - color0 = D3DCOLOR_RGBA( - (RPART(color) * a) >> 8, - (GPART(color) * a) >> 8, - (BPART(color) * a) >> 8, - 0); - a = 256 - a; - color1 = D3DCOLOR_RGBA(a, a, a, int(alpha * 255)); - } - else - { - color0 = 0; - color1 = D3DCOLOR_COLORVALUE(1, 1, 1, alpha); - } -} - void D3DFB::EnableAlphaTest(BOOL enabled) { if (enabled != AlphaTestEnabled) diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h index 68ef58058..428aafae4 100644 --- a/src/win32/win32swiface.h +++ b/src/win32/win32swiface.h @@ -47,15 +47,6 @@ public: void DrawBlendingRect (); 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); - void DoDim (PalEntry color, float amount, int x1, int y1, int w, int h); - void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin); - void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); - void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override; bool WipeStartScreen(int type); void WipeEndScreen(); bool WipeDo(int ticks); @@ -156,12 +147,9 @@ private: PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, D3DFORMAT format); void DrawLetterbox(); void Draw3DPart(bool copy3d); - bool SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedTris &quad); static D3DBLEND GetStyleAlpha(int type); - static void SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1); void DoWindowedGamma(); void AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color); - void AddColorOnlyRect(int left, int top, int width, int height, D3DCOLOR color); void CheckQuadBatch(int numtris=2, int numverts=4); void BeginQuadBatch(); void EndQuadBatch(); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index acaa831b5..46e9e222e 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -155,6 +155,14 @@ enum DrawTextureTags DTA_TextLen, // stop after this many characters, even if \0 not hit DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell + + DTA_Color, + DTA_FlipY, // bool: flip image vertically + DTA_SrcX, // specify a source rectangle (this supersedes the poorly implemented DTA_WindowLeft/Right + DTA_SrcY, + DTA_SrcWidth, + DTA_SrcHeight + }; struct Screen native