diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c650c935..891691fa8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -491,8 +491,6 @@ endif() set( PLAT_WIN32_SOURCES sound/mididevices/music_win_mididevice.cpp win32/critsec.cpp - win32/fb_d3d9.cpp - win32/fb_d3d9_wipe.cpp win32/hardware.cpp win32/helperthread.cpp win32/i_cd.cpp @@ -835,7 +833,6 @@ set( FASTMATH_SOURCES sound/timiditypp/fft4g.cpp sound/timiditypp/reverb.cpp gl/utility/gl_clock.cpp - gl/renderer/gl_2ddrawer.cpp gl/hqnx/init.cpp gl/hqnx/hq2x.cpp gl/hqnx/hq3x.cpp @@ -1084,8 +1081,6 @@ set (PCH_SOURCES gl/stereo3d/gl_interleaved3d.cpp gl/system/gl_interface.cpp gl/system/gl_framebuffer.cpp - gl/system/gl_swframebuffer.cpp - gl/system/gl_swwipe.cpp gl/system/gl_debug.cpp gl/system/gl_menu.cpp gl/system/gl_wipe.cpp diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index 6a7747e36..6fb37c43f 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -145,7 +145,6 @@ void AdjustSpriteOffsets() } tex->LeftOffset=x; tex->TopOffset=y; - tex->KillNative(); } } } diff --git a/src/gl/renderer/gl_2ddrawer.cpp b/src/gl/renderer/gl_2ddrawer.cpp deleted file mode 100644 index b58f3c22b..000000000 --- a/src/gl/renderer/gl_2ddrawer.cpp +++ /dev/null @@ -1,494 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_2ddrawer.h -** Container class for drawing 2d graphics with a vertex buffer -** -**/ - -#include "gl/system/gl_system.h" -#include "gl/system/gl_framebuffer.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/renderer/gl_2ddrawer.h" -#include "gl/textures/gl_material.h" -#include "gl/renderer/gl_renderstate.h" -#include "gl/renderer/gl_lightdata.h" -#include "gl/scene/gl_drawinfo.h" -#include "gl/textures/gl_translate.h" -#include "vectors.h" - -#if 0 -//========================================================================== -// -// -// -//========================================================================== - -int FGL2DDrawer::AddData(const FGL2DDrawer::DataGeneric *data) -{ - int addr = mData.Reserve(data->mLen); - memcpy(&mData[addr], data, data->mLen); - mLastLineCmd = -1; - return addr; -} - -//========================================================================== -// -// Draws a texture -// -//========================================================================== - -void FGL2DDrawer::AddTexture(FTexture *img, DrawParms &parms) -{ - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x = parms.x - parms.left * xscale; - double y = parms.y - parms.top * yscale; - double w = parms.destwidth; - double h = parms.destheight; - float u1, v1, u2, v2; - int light = 255; - - FMaterial * gltex = FMaterial::ValidateTexture(img, false); - if (gltex == nullptr) return; - - DataTexture dg; - - dg.mType = DrawTypeTexture; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mRenderStyle = parms.style; - dg.mMasked = !!parms.masked; - dg.mTexture = gltex; - - if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0) - { - // handle black overlays as reduced light. - light = 255 - APART(parms.colorOverlay); - parms.colorOverlay = 0; - } - dg.mVertIndex = (int)mVertices.Reserve(parms.colorOverlay == 0? 4 : 8); - dg.mColorOverlay = parms.colorOverlay; - dg.mTranslation = 0; - - if (!img->bHasCanvas) - { - dg.mAlphaTexture = !!(parms.style.Flags & STYLEF_RedIsAlpha); - - if (!dg.mAlphaTexture) - { - if (parms.remap != NULL && !parms.remap->Inactive) - { - GLTranslationPalette * pal = static_cast(parms.remap->GetNative()); - if (pal) dg.mTranslation = -pal->GetIndex(); - } - } - u1 = gltex->GetUL(); - v1 = gltex->GetVT(); - u2 = gltex->GetUR(); - v2 = gltex->GetVB(); - - } - else - { - dg.mAlphaTexture = false; - u1 = 0.f; - v1 = 1.f; - u2 = 1.f; - v2 = 0.f; - } - - if (parms.flipX) - std::swap(u1, u2); - - - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x += parms.windowleft * xscale; - w -= (parms.texwidth - wi + parms.windowleft) * xscale; - - u1 = float(u1 + parms.windowleft / parms.texwidth); - u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth); - } - - PalEntry color; - if (parms.style.Flags & STYLEF_ColorIsFixed) - { - color = parms.fillcolor; - } - else - { - color = PalEntry(light, light, light); - } - color.a = (uint8_t)(parms.Alpha * 255); - // red and blue channels are swapped to use value as vertex color - color = PalEntry((color.a * parms.color.a) / 255, (color.b * parms.color.b) / 255, (color.g * parms.color.g) / 255, (color.r * parms.color.r) / 255); - - // scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates - dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip); - dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip); - dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - dg.mScissor[0]; - dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.uclip) - dg.mScissor[1]; - - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(x, y, 0, u1, v1, color); ptr++; - ptr->Set(x, y + h, 0, u1, v2, color); ptr++; - ptr->Set(x + w, y, 0, u2, v1, color); ptr++; - ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++; - if (parms.colorOverlay != 0) - { - color = parms.colorOverlay; - std::swap(color.r, color.b); - ptr->Set(x, y, 0, u1, v1, color); ptr++; - ptr->Set(x, y + h, 0, u1, v2, color); ptr++; - ptr->Set(x + w, y, 0, u2, v1, color); ptr++; - ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++; - dg.mVertCount = 8; - } - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel) -{ - FMaterial *gltexture = FMaterial::ValidateTexture(texture, false); - - if (gltexture == nullptr) - { - return; - } - DataSimplePoly poly; - - poly.mType = DrawTypePoly; - poly.mLen = (sizeof(poly) + 7) & ~7; - poly.mTexture = gltexture; - poly.mColormap = colormap; - poly.mLightLevel = lightlevel; - poly.mVertCount = npoints; - poly.mVertIndex = (int)mVertices.Reserve(npoints); - poly.mFlatColor = flatcolor; - - bool dorotate = rotation != 0; - - float cosrot = cos(rotation.Radians()); - float sinrot = sin(rotation.Radians()); - - float uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - float vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - if (texture->bHasCanvas) - { - vscale = 0 - vscale; - } - float ox = float(originx); - float oy = float(originy); - - for (int i = 0; i < npoints; ++i) - { - 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; - } - mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); - } - AddData(&poly); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FGL2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int h) -{ - color.a = uint8_t(damount * 255); - std::swap(color.r, color.b); - - DataGeneric dg; - - dg.mType = DrawTypeDim; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mVertIndex = (int)mVertices.Reserve(4); - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(x1, y1, 0, 0, 0, color); ptr++; - ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++; - ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++; - ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++; - AddData(&dg); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - PalEntry p = palcolor == -1 || color != 0 ? (PalEntry)color : GPalette.BaseColors[palcolor]; - AddDim(p, 1.f, left, top, right - left, bottom - top); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - float fU1, fU2, fV1, fV2; - - FMaterial *gltexture = FMaterial::ValidateTexture(src, false); - - if (!gltexture) return; - - DataFlatFill dg; - - dg.mType = DrawTypeFlatFill; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mVertIndex = (int)mVertices.Reserve(4); - dg.mTexture = gltexture; - - // scaling is not used here. - if (!local_origin) - { - fU1 = float(left) / src->GetWidth(); - fV1 = float(top) / src->GetHeight(); - fU2 = float(right) / src->GetWidth(); - fV2 = float(bottom) / src->GetHeight(); - } - else - { - fU1 = 0; - fV1 = 0; - fU2 = float(right - left) / src->GetWidth(); - fV2 = float(bottom - top) / src->GetHeight(); - } - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(left, top, 0, fU1, fV1); ptr++; - ptr->Set(left, bottom, 0, fU1, fV2); ptr++; - ptr->Set(right, top, 0, fU2, fV1); ptr++; - ptr->Set(right, bottom, 0, fU2, fV2); ptr++; - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color) -{ - PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; - p.a = 255; - std::swap(p.r, p.b); - - DataGeneric dg; - - dg.mType = DrawTypeLine; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 2; - dg.mVertIndex = (int)mVertices.Reserve(2); - mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); - mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p); - - // Test if we can batch multiple line commands - if (mLastLineCmd == -1) - { - mLastLineCmd = AddData(&dg); - } - else - { - DataGeneric *dg = (DataGeneric *)&mData[mLastLineCmd]; - dg->mVertCount += 2; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color) -{ - PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; - p.a = 255; - std::swap(p.r, p.b); - - DataGeneric dg; - - dg.mType = DrawTypePixel; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 2; - dg.mVertIndex = (int)mVertices.Reserve(1); - mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FGL2DDrawer::Draw() -{ - FGL2DDrawer::EDrawType lasttype = DrawTypeTexture; - - if (mData.Size() == 0) return; - int8_t savedlightmode = glset.lightmode; - // lightmode is only relevant for automap subsectors, - // but We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering. - if (glset.lightmode == 8) glset.lightmode = 0; - - set(&mVertices[0], mVertices.Size()); - for (unsigned i = 0; i < mData.Size();) - { - DataGeneric *dg = (DataGeneric *)&mData[i]; - // DrawTypePoly may not use the color part of the vertex buffer because it needs to use gl_SetColor to produce proper output. - if (lasttype == DrawTypePoly && dg->mType != DrawTypePoly) - { - gl_RenderState.ResetColor(); // this is needed to reset the desaturation. - EnableColorArray(true); - } - else if (lasttype != DrawTypePoly && dg->mType == DrawTypePoly) - { - EnableColorArray(false); - } - lasttype = dg->mType; - - switch (dg->mType) - { - default: - break; - - case DrawTypeTexture: - { - DataTexture *dt = static_cast(dg); - - gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false); - gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture); - - glEnable(GL_SCISSOR_TEST); - glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]); - - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); - gl_RenderState.Apply(); - - glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex, 4); - - gl_RenderState.BlendEquation(GL_FUNC_ADD); - if (dt->mVertCount > 4) - { - gl_RenderState.SetTextureMode(TM_MASK); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4); - } - - const auto &viewport = GLRenderer->mScreenViewport; - glScissor(viewport.left, viewport.top, viewport.width, viewport.height); - glDisable(GL_SCISSOR_TEST); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.SetTextureMode(TM_MODULATE); - break; - } - - case DrawTypePoly: - { - DataSimplePoly *dsp = static_cast(dg); - - gl_SetColor(dsp->mLightLevel, 0, false, dsp->mColormap, 1.f); - gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false); - gl_RenderState.SetObjectColor(dsp->mFlatColor|0xff000000); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount); - gl_RenderState.SetObjectColor(0xffffffff); - break; - } - - case DrawTypeFlatFill: - { - DataFlatFill *dff = static_cast(dg); - gl_RenderState.SetMaterial(dff->mTexture, CLAMP_NONE, 0, -1, false); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_STRIP, dg->mVertIndex, dg->mVertCount); - break; - } - - case DrawTypeDim: - gl_RenderState.EnableTexture(false); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.AlphaFunc(GL_GREATER, 0); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_FAN, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - case DrawTypeLine: - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - glDrawArrays(GL_LINES, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - case DrawTypePixel: - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - glDrawArrays(GL_POINTS, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - } - i += dg->mLen; - } - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - glset.lightmode = savedlightmode; -} - -void FGL2DDrawer::Clear() -{ - mVertices.Clear(); - mData.Clear(); - mLastLineCmd = -1; -} -#endif \ No newline at end of file diff --git a/src/gl/renderer/gl_2ddrawer.h b/src/gl/renderer/gl_2ddrawer.h deleted file mode 100644 index 2b898f40c..000000000 --- a/src/gl/renderer/gl_2ddrawer.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __2DDRAWER_H -#define __2DDRAWER_H - -#include "tarray.h" -#include "gl/data/gl_vertexbuffer.h" - -class FGL2DDrawer : public FSimpleVertexBuffer -{ - enum EDrawType - { - DrawTypeTexture, - DrawTypeDim, - DrawTypeFlatFill, - DrawTypePoly, - DrawTypeLine, - DrawTypePixel - }; - - struct DataGeneric - { - EDrawType mType; - uint32_t mLen; - int mVertIndex; - int mVertCount; - }; - - struct DataTexture : public DataGeneric - { - FMaterial *mTexture; - int mScissor[4]; - uint32_t mColorOverlay; - int mTranslation; - FRenderStyle mRenderStyle; - bool mMasked; - bool mAlphaTexture; - }; - - struct DataFlatFill : public DataGeneric - { - FMaterial *mTexture; - }; - - struct DataSimplePoly : public DataGeneric - { - FMaterial *mTexture; - int mLightLevel; - FColormap mColormap; - PalEntry mFlatColor; - }; - - TArray mVertices; - TArray mData; - int mLastLineCmd = -1; // consecutive lines can be batched into a single draw call so keep this info around. - - int AddData(const DataGeneric *data); - -public: - void AddTexture(FTexture *img, DrawParms &parms); - void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h); - void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin); - - void AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel); - - void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color); - void AddPixel(int x1, int y1, int palcolor, uint32_t color); - - void Draw(); - void Clear(); -}; - - -#endif diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index ccb51b143..22854cd4d 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -63,7 +63,6 @@ #include "gl/shaders/gl_fxaashader.h" #include "gl/shaders/gl_presentshader.h" #include "gl/shaders/gl_postprocessshader.h" -#include "gl/renderer/gl_2ddrawer.h" #include "gl/stereo3d/gl_stereo3d.h" #include "r_videoscale.h" diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 28d31ca8e..d399bc066 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -46,7 +46,6 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" -#include "gl/renderer/gl_2ddrawer.h" #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_drawinfo.h" diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp deleted file mode 100644 index 96128bee2..000000000 --- a/src/gl/system/gl_swframebuffer.cpp +++ /dev/null @@ -1,2504 +0,0 @@ -/* -** gl_swframebuffer.cpp -** Code to let ZDoom use OpenGL as a simple framebuffer -** -**--------------------------------------------------------------------------- -** Copyright 1998-2011 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** This file does _not_ implement hardware-acclerated 3D rendering. It is -** just a means of getting the pixel data to the screen in a more reliable -** method on modern hardware by copying the entire frame to a texture, -** drawing that to the screen, and presenting. -** -** That said, it does implement hardware-accelerated 2D rendering. -*/ - -#include "gl/system/gl_system.h" -#include "m_swap.h" -#include "v_video.h" -#include "doomstat.h" -#include "m_png.h" -#include "m_crc32.h" -#include "vectors.h" -#include "v_palette.h" -#include "templates.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "w_wad.h" -#include "r_data/colormaps.h" - -#include "gl/system/gl_interface.h" -#include "gl/system/gl_swframebuffer.h" -#include "gl/data/gl_data.h" -#include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" -#include "gl/gl_functions.h" -#include "gl_debug.h" -#include "r_videoscale.h" - -#include "swrenderer/scene/r_light.h" - -#ifndef NO_SSE -#include -#endif - -CVAR(Int, gl_showpacks, 0, 0) -#ifndef WIN32 // Defined in fb_d3d9 for Windows -CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -#else -EXTERN_CVAR(Bool, vid_hwaalines) -#endif - -EXTERN_CVAR(Bool, fullscreen) -EXTERN_CVAR(Float, Gamma) -EXTERN_CVAR(Bool, vid_vsync) -EXTERN_CVAR(Float, transsouls) -EXTERN_CVAR(Int, vid_refreshrate) - -cycle_t BlitCycles; - -void gl_LoadExtensions(); -void gl_PrintStartupLog(); - -#ifndef WIN32 -// This has to be in this file because system headers conflict Doom headers -DFrameBuffer *CreateGLSWFrameBuffer(int width, int height, bool bgra, bool fullscreen) -{ - return new OpenGLSWFrameBuffer(NULL, width, height, 32, 60, fullscreen, bgra); -} -#endif - -const char *const OpenGLSWFrameBuffer::ShaderDefines[OpenGLSWFrameBuffer::NUM_SHADERS] = -{ - "#define ENORMALCOLOR", // NormalColor - "#define ENORMALCOLOR\n#define PALTEX", // NormalColorPal - "#define ENORMALCOLOR\n#define INVERT", // NormalColorInv - "#define ENORMALCOLOR\n#define PALTEX\n#define INVERT", // NormalColorPalInv - - "#define EREDTOALPHA", // RedToAlpha - "#define EREDTOALPHA\n#define INVERT", // RedToAlphaInv - - "#define EVERTEXCOLOR", // VertexColor - - "#define ESPECIALCOLORMAP\n", // SpecialColormap - "#define ESPECIALCOLORMAP\n#define PALTEX", // SpecialColorMapPal - - "#define EINGAMECOLORMAP", // InGameColormap - "#define EINGAMECOLORMAP\n#define DESAT", // InGameColormapDesat - "#define EINGAMECOLORMAP\n#define INVERT", // InGameColormapInv - "#define EINGAMECOLORMAP\n#define INVERT\n#define DESAT", // InGameColormapInvDesat - "#define EINGAMECOLORMAP\n#define PALTEX\n", // InGameColormapPal - "#define EINGAMECOLORMAP\n#define PALTEX\n#define DESAT", // InGameColormapPalDesat - "#define EINGAMECOLORMAP\n#define PALTEX\n#define INVERT", // InGameColormapPalInv - "#define EINGAMECOLORMAP\n#define PALTEX\n#define INVERT\n#define DESAT", // InGameColormapPalInvDesat - - "#define EBURNWIPE", // BurnWipe - "#define EGAMMACORRECTION", // GammaCorrection -}; - -OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) : - Super(hMonitor, width, height, bits, refreshHz, fullscreen, bgra) -{ - VertexBuffer = nullptr; - IndexBuffer = nullptr; - FBTexture = nullptr; - InitialWipeScreen = nullptr; - ScreenshotTexture = nullptr; - FinalWipeScreen = nullptr; - PaletteTexture = nullptr; - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i] = nullptr; - } - - BlendingRect.left = 0; - BlendingRect.top = 0; - BlendingRect.right = Width; - BlendingRect.bottom = Height; - In2D = 0; - Palettes = nullptr; - Textures = nullptr; - GatheringWipeScreen = false; - ScreenWipe = nullptr; - InScene = false; - QuadExtra = new BufferedTris[MAX_QUAD_BATCH]; - memset(QuadExtra, 0, sizeof(BufferedTris) * MAX_QUAD_BATCH); - PixelDoubling = 0; - - Gamma = 1.0; - FlashColor0 = 0; - FlashColor1 = 0xFFFFFFFF; - FlashColor = 0; - FlashAmount = 0; - - NeedGammaUpdate = false; - NeedPalUpdate = false; - - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); - - // To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState - static bool first = true; - if (first) - { - if (ogl_LoadFunctions() == ogl_LOAD_FAILED) - { - Printf("OpenGL load failed. No OpenGL acceleration will be used.\n"); - return; - } - } - - const char *glversion = (const char*)glGetString(GL_VERSION); - bool isGLES = (glversion && strlen(glversion) > 10 && memcmp(glversion, "OpenGL ES ", 10) == 0); - - if (!isGLES && ogl_IsVersionGEQ(3, 0) == 0) - { - Printf("OpenGL acceleration requires at least OpenGL 3.0. No Acceleration will be used.\n"); - return; - } - gl_LoadExtensions(); - if (gl.legacyMode) - { - Printf("Legacy OpenGL path is active. No Acceleration will be used.\n"); - return; - } - InitializeState(); - if (first) - { - gl_PrintStartupLog(); - first = false; - } - - if (!glGetString) - return; - - // SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver. - // If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed! - Super::SetVSync(vid_vsync); - - Debug = std::make_shared(); - Debug->Update(); - - //Windowed = !(static_cast(Video)->GoFullscreen(fullscreen)); - - TrueHeight = height; - - Valid = CreateResources(); - - RenderBuffer = new DSimpleCanvas(Width, Height, bgra); - if (UseMappedMemBuffer) MappedBuffer = new DCanvas(Width, Height, bgra); - else MappedBuffer = nullptr; - - if (Valid) - SetInitialState(); -} - -OpenGLSWFrameBuffer::~OpenGLSWFrameBuffer() -{ - if (RenderBuffer) delete RenderBuffer; - if (MappedBuffer) delete MappedBuffer; - ReleaseResources(); - delete[] QuadExtra; -} - -void *OpenGLSWFrameBuffer::MapBuffer(int target, int size) -{ - if (glMapBufferRange) - { - return (FBVERTEX*)glMapBufferRange(target, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - } - else - { - glBufferData(target, size, nullptr, GL_STREAM_DRAW); - return glMapBuffer(target, GL_WRITE_ONLY); - } -} - -OpenGLSWFrameBuffer::HWFrameBuffer::~HWFrameBuffer() -{ - if (Framebuffer != 0) glDeleteFramebuffers(1, (GLuint*)&Framebuffer); - Texture.reset(); -} - -OpenGLSWFrameBuffer::HWTexture::~HWTexture() -{ - if (Texture != 0) glDeleteTextures(1, (GLuint*)&Texture); - if (Buffers[0] != 0) glDeleteBuffers(2, (GLuint*)Buffers); -} - -OpenGLSWFrameBuffer::HWVertexBuffer::~HWVertexBuffer() -{ - if (VertexArray != 0) glDeleteVertexArrays(1, (GLuint*)&VertexArray); - if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer); -} - -OpenGLSWFrameBuffer::FBVERTEX *OpenGLSWFrameBuffer::HWVertexBuffer::Lock() -{ - glBindBuffer(GL_ARRAY_BUFFER, Buffer); - return (FBVERTEX*)MapBuffer(GL_ARRAY_BUFFER, Size); -} - -void OpenGLSWFrameBuffer::HWVertexBuffer::Unlock() -{ - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -OpenGLSWFrameBuffer::HWIndexBuffer::~HWIndexBuffer() -{ - if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer); -} - -uint16_t *OpenGLSWFrameBuffer::HWIndexBuffer::Lock() -{ - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &LockedOldBinding); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Buffer); - return (uint16_t*)MapBuffer(GL_ELEMENT_ARRAY_BUFFER, Size); -} - -void OpenGLSWFrameBuffer::HWIndexBuffer::Unlock() -{ - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, LockedOldBinding); -} - -OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader() -{ - if (Program != 0) glDeleteProgram(Program); - if (VertexShader != 0) glDeleteShader(VertexShader); - if (FragmentShader != 0) glDeleteShader(FragmentShader); -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height) -{ - std::unique_ptr fb(new HWFrameBuffer()); - - GLint format = GL_RGBA16F; - if (gl.es) format = GL_RGB; - - fb->Texture = CreateTexture(name, width, height, 1, format); - if (!fb->Texture) - { - return nullptr; - } - - glGenFramebuffers(1, (GLuint*)&fb->Framebuffer); - - GLint oldFramebufferBinding = 0, oldTextureBinding = 0; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding); - - glBindFramebuffer(GL_FRAMEBUFFER, fb->Framebuffer); - FGLDebug::LabelObject(GL_FRAMEBUFFER, fb->Framebuffer, name); - - glBindTexture(GL_TEXTURE_2D, fb->Texture->Texture); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->Texture->Texture, 0); - - GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - glBindFramebuffer(GL_FRAMEBUFFER, oldFramebufferBinding); - glBindTexture(GL_TEXTURE_2D, oldTextureBinding); - - if (result != GL_FRAMEBUFFER_COMPLETE) - { - Printf("Framebuffer is not complete\n"); - return nullptr; - } - - return fb; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines) -{ - std::unique_ptr shader(new HWPixelShader()); - - shader->Program = glCreateProgram(); - if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - shader->VertexShader = glCreateShader(GL_VERTEX_SHADER); - if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - - int maxGlslVersion = 330; - int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion); - - FString prefix; - prefix.AppendFormat("#version %d\n%s\n#line 0\n", shaderVersion, defines.GetChars()); - //Printf("Shader prefix: %s", prefix.GetChars()); - - vertexsrc = prefix + vertexsrc; - fragmentsrc = prefix + fragmentsrc; - - { - int lengths[1] = { (int)vertexsrc.Len() }; - const char *sources[1] = { vertexsrc.GetChars() }; - glShaderSource(shader->VertexShader, 1, sources, lengths); - glCompileShader(shader->VertexShader); - } - - { - int lengths[1] = { (int)fragmentsrc.Len() }; - const char *sources[1] = { fragmentsrc.GetChars() }; - glShaderSource(shader->FragmentShader, 1, sources, lengths); - glCompileShader(shader->FragmentShader); - } - - GLint status = 0; - int errorShader = shader->VertexShader; - glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status); - if (status != GL_FALSE) { errorShader = shader->FragmentShader; glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status); } - if (status == GL_FALSE) - { - static char buffer[10000]; - GLsizei length = 0; - buffer[0] = 0; - glGetShaderInfoLog(errorShader, 10000, &length, buffer); - //Printf("Shader compile failed: %s", buffer); - - return nullptr; - } - - glAttachShader(shader->Program, shader->VertexShader); - glAttachShader(shader->Program, shader->FragmentShader); - glBindFragDataLocation(shader->Program, 0, "FragColor"); - glBindAttribLocation(shader->Program, 0, "AttrPosition"); - glBindAttribLocation(shader->Program, 1, "AttrColor0"); - glBindAttribLocation(shader->Program, 2, "AttrColor1"); - glBindAttribLocation(shader->Program, 3, "AttrTexCoord0"); - glLinkProgram(shader->Program); - glGetProgramiv(shader->Program, GL_LINK_STATUS, &status); - if (status == GL_FALSE) - { - static char buffer[10000]; - GLsizei length = 0; - buffer[0] = 0; - glGetProgramInfoLog(shader->Program, 10000, &length, buffer); - //Printf("Shader link failed: %s", buffer); - - return nullptr; - } - - shader->ConstantLocations[PSCONST_Desaturation] = glGetUniformLocation(shader->Program, "Desaturation"); - shader->ConstantLocations[PSCONST_PaletteMod] = glGetUniformLocation(shader->Program, "PaletteMod"); - shader->ConstantLocations[PSCONST_Weights] = glGetUniformLocation(shader->Program, "Weights"); - shader->ConstantLocations[PSCONST_Gamma] = glGetUniformLocation(shader->Program, "Gamma"); - shader->ConstantLocations[PSCONST_ScreenSize] = glGetUniformLocation(shader->Program, "ScreenSize"); - shader->ImageLocation = glGetUniformLocation(shader->Program, "Image"); - shader->PaletteLocation = glGetUniformLocation(shader->Program, "Palette"); - shader->NewScreenLocation = glGetUniformLocation(shader->Program, "NewScreen"); - shader->BurnLocation = glGetUniformLocation(shader->Program, "Burn"); - - return shader; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateVertexBuffer(int size) -{ - std::unique_ptr obj(new HWVertexBuffer()); - - obj->Size = size; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - glGenVertexArrays(1, (GLuint*)&obj->VertexArray); - glGenBuffers(1, (GLuint*)&obj->Buffer); - glBindVertexArray(obj->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, obj->Buffer); - FGLDebug::LabelObject(GL_BUFFER, obj->Buffer, "VertexBuffer"); - glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateIndexBuffer(int size) -{ - std::unique_ptr obj(new HWIndexBuffer()); - - obj->Size = size; - - GLint oldBinding = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldBinding); - - glGenBuffers(1, (GLuint*)&obj->Buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, obj->Buffer); - FGLDebug::LabelObject(GL_BUFFER, obj->Buffer, "IndexBuffer"); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format) -{ - std::unique_ptr obj(new HWTexture()); - - obj->Format = format; - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - - glGenTextures(1, (GLuint*)&obj->Texture); - glBindTexture(GL_TEXTURE_2D, obj->Texture); - GLenum srcformat; - switch (format) - { - case GL_RGB: srcformat = GL_RGB; break; - case GL_R8: srcformat = GL_RED; break; - case GL_RGBA8: srcformat = gl.es ? GL_RGBA : GL_BGRA; break; - case GL_RGBA16F: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: srcformat = GL_RGB; break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: srcformat = GL_RGBA; break; - default: - I_FatalError("Unknown format passed to CreateTexture"); - return nullptr; - } - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, srcformat, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - FGLDebug::LabelObject(GL_TEXTURE, obj->Texture, name); - - glBindTexture(GL_TEXTURE_2D, oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CopyCurrentScreen() -{ - std::unique_ptr obj(new HWTexture()); - obj->Format = GL_RGBA16F; - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - - glGenTextures(1, (GLuint*)&obj->Texture); - glBindTexture(GL_TEXTURE_2D, obj->Texture); - - glCopyTexImage2D(GL_TEXTURE_2D, 0, obj->Format, 0, 0, Width, Height, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - FGLDebug::LabelObject(GL_TEXTURE, obj->Texture, "CopyCurrentScreen"); - - glBindTexture(GL_TEXTURE_2D, oldBinding); - - return obj; -} - -void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp) -{ -} - -void OpenGLSWFrameBuffer::SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount) -{ - assert(uniformIndex < NumPSCONST && vec4fcount == 1); // This emulation of d3d9 only works for very simple stuff - for (int i = 0; i < 4; i++) - ShaderConstants[uniformIndex * 4 + i] = data[i]; - if (CurrentShader && CurrentShader->ConstantLocations[uniformIndex] != -1) - glUniform4fv(CurrentShader->ConstantLocations[uniformIndex], vec4fcount, data); -} - -void OpenGLSWFrameBuffer::SetHWPixelShader(HWPixelShader *shader) -{ - if (shader != CurrentShader) - { - if (shader) - { - glUseProgram(shader->Program); - for (int i = 0; i < NumPSCONST; i++) - { - if (shader->ConstantLocations[i] != -1) - glUniform4fv(shader->ConstantLocations[i], 1, &ShaderConstants[i * 4]); - } - } - else - { - glUseProgram(0); - } - } - CurrentShader = shader; -} - -void OpenGLSWFrameBuffer::SetStreamSource(HWVertexBuffer *vertexBuffer) -{ - if (vertexBuffer) - glBindVertexArray(vertexBuffer->VertexArray); - else - glBindVertexArray(0); -} - -void OpenGLSWFrameBuffer::SetIndices(HWIndexBuffer *indexBuffer) -{ - if (indexBuffer) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->Buffer); - else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const FBVERTEX *vertices) -{ - count = 2 + count; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBuffer) - { - StreamVertexBuffer.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - } - else - { - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const BURNVERTEX *vertices) -{ - count = 2 + count; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBufferBurn) - { - StreamVertexBufferBurn.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer); - glBindVertexArray(StreamVertexBufferBurn->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBufferBurn->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(BURNVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(BURNVERTEX), (const GLvoid*)offsetof(BURNVERTEX, x)); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(BURNVERTEX), (const GLvoid*)offsetof(BURNVERTEX, tu0)); - } - else - { - glBindVertexArray(StreamVertexBufferBurn->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBufferBurn->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(BURNVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawPoints(int count, const FBVERTEX *vertices) -{ - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBuffer) - { - StreamVertexBuffer.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - } - else - { - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_POINTS, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawLineList(int count) -{ - glDrawArrays(GL_LINES, 0, count * 2); -} - -void OpenGLSWFrameBuffer::DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount) -{ - glDrawRangeElements(GL_TRIANGLES, minIndex, minIndex + numVertices - 1, primitiveCount * 3, GL_UNSIGNED_SHORT, (const void*)(startIndex * sizeof(uint16_t))); -} - -void OpenGLSWFrameBuffer::GetLetterboxFrame(int &letterboxX, int &letterboxY, int &letterboxWidth, int &letterboxHeight) -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - - float scaleX, scaleY; - if (ViewportIsScaled43()) - { - scaleX = MIN(clientWidth / (float)Width, clientHeight / (Height * 1.2f)); - scaleY = scaleX * 1.2f; - } - else - { - scaleX = MIN(clientWidth / (float)Width, clientHeight / (float)Height); - scaleY = scaleX; - } - - letterboxWidth = (int)round(Width * scaleX); - letterboxHeight = (int)round(Height * scaleY); - letterboxX = (clientWidth - letterboxWidth) / 2; - letterboxY = (clientHeight - letterboxHeight) / 2; -} - -void OpenGLSWFrameBuffer::Present() -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - if (clientWidth > 0 && clientHeight > 0) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, clientWidth, clientHeight); - - int letterboxX, letterboxY, letterboxWidth, letterboxHeight; - GetLetterboxFrame(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - DrawLetterbox(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - glViewport(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - - FBVERTEX verts[4]; - CalcFullscreenCoords(verts, false, 0, 0xFFFFFFFF); - SetTexture(0, OutputFB->Texture.get()); - - if (ViewportLinearScale()) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - SetPixelShader(Shaders[SHADER_GammaCorrection].get()); - SetAlphaBlend(0); - EnableAlphaTest(false); - DrawTriangleFans(2, verts); - } - - SwapBuffers(); - Debug->Update(); - - float screensize[4] = { (float)Width, (float)Height, 1.0f, 1.0f }; - SetPixelShaderConstantF(PSCONST_ScreenSize, screensize, 1); - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - glViewport(0, 0, Width, Height); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: SetInitialState -// -// Called after initial device creation and reset, when everything is set -// to OpenGL's defaults. -// -//========================================================================== - -void OpenGLSWFrameBuffer::SetInitialState() -{ - if (gl.es) - UseMappedMemBuffer = false; - - AlphaBlendEnabled = false; - AlphaBlendOp = GL_FUNC_ADD; - AlphaSrcBlend = 0; - AlphaDestBlend = 0; - - CurPixelShader = nullptr; - memset(Constant, 0, sizeof(Constant)); - - for (unsigned i = 0; i < countof(Texture); ++i) - { - Texture[i] = nullptr; - SamplerWrapS[i] = GL_CLAMP_TO_EDGE; - SamplerWrapT[i] = GL_CLAMP_TO_EDGE; - } - - NeedGammaUpdate = true; - NeedPalUpdate = true; - - // This constant is used for grayscaling weights (.xyz) and color inversion (.w) - float weights[4] = { 77 / 256.f, 143 / 256.f, 37 / 256.f, 1 }; - SetPixelShaderConstantF(PSCONST_Weights, weights, 1); - - float screensize[4] = { (float)Width, (float)Height, 1.0f, 1.0f }; - SetPixelShaderConstantF(PSCONST_ScreenSize, screensize, 1); - - AlphaTestEnabled = false; - - CurBorderColor = 0; - - // Clear to black, just in case it wasn't done already. - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateResources -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreateResources() -{ - if (!LoadShaders()) - return false; - - OutputFB = CreateFrameBuffer("OutputFB", Width, Height); - if (!OutputFB) - return false; - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - - if (!CreateFBTexture() || - !CreatePaletteTexture()) - { - return false; - } - if (!CreateVertexes()) - { - return false; - } - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: LoadShaders -// -// Returns true if all required shaders were loaded. (Gamma and burn wipe -// are the only ones not considered "required".) -// -//========================================================================== - -bool OpenGLSWFrameBuffer::LoadShaders() -{ - int lumpvert = Wads.CheckNumForFullName("shaders/glsl/swshader.vp"); - int lumpfrag = Wads.CheckNumForFullName("shaders/glsl/swshader.fp"); - if (lumpvert < 0 || lumpfrag < 0) - return false; - - FString vertsource = Wads.ReadLump(lumpvert).GetString(); - FString fragsource = Wads.ReadLump(lumpfrag).GetString(); - - FString shaderdir, shaderpath; - unsigned int i; - - for (i = 0; i < NUM_SHADERS; ++i) - { - shaderpath = shaderdir; - Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]); - if (!Shaders[i] && i < SHADER_BurnWipe) - { - break; - } - - glUseProgram(Shaders[i]->Program); - if (Shaders[i]->ImageLocation != -1) glUniform1i(Shaders[i]->ImageLocation, 0); - if (Shaders[i]->PaletteLocation != -1) glUniform1i(Shaders[i]->PaletteLocation, 1); - if (Shaders[i]->NewScreenLocation != -1) glUniform1i(Shaders[i]->NewScreenLocation, 0); - if (Shaders[i]->BurnLocation != -1) glUniform1i(Shaders[i]->BurnLocation, 1); - glUseProgram(0); - } - if (i == NUM_SHADERS) - { // Success! - return true; - } - // Failure. Release whatever managed to load (which is probably nothing.) - for (i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i].reset(); - } - return false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: ReleaseResources -// -//========================================================================== - -void OpenGLSWFrameBuffer::ReleaseResources() -{ -#ifdef WIN32 - I_SaveWindowedPos(); -#endif - KillNativeTexs(); - KillNativePals(); - ReleaseDefaultPoolItems(); - ScreenshotTexture.reset(); - PaletteTexture.reset(); - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i].reset(); - } - if (ScreenWipe != nullptr) - { - delete ScreenWipe; - ScreenWipe = nullptr; - } - GatheringWipeScreen = false; -} - -void OpenGLSWFrameBuffer::ReleaseDefaultPoolItems() -{ - FBTexture.reset(); - FinalWipeScreen.reset(); - InitialWipeScreen.reset(); - VertexBuffer.reset(); - IndexBuffer.reset(); - OutputFB.reset(); -} - -bool OpenGLSWFrameBuffer::Reset() -{ - ReleaseDefaultPoolItems(); - - OutputFB = CreateFrameBuffer("OutputFB", Width, Height); - if (!OutputFB || !CreateFBTexture() || !CreateVertexes()) - { - return false; - } - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - glViewport(0, 0, Width, Height); - - SetInitialState(); - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: KillNativePals -// -// Frees all native palettes. -// -//========================================================================== - -void OpenGLSWFrameBuffer::KillNativePals() -{ - while (Palettes != nullptr) - { - delete Palettes; - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: KillNativeTexs -// -// Frees all native textures. -// -//========================================================================== - -void OpenGLSWFrameBuffer::KillNativeTexs() -{ - while (Textures != nullptr) - { - delete Textures; - } -} - -bool OpenGLSWFrameBuffer::CreateFBTexture() -{ - FBTexture = CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8); - return FBTexture != nullptr; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreatePaletteTexture -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreatePaletteTexture() -{ - PaletteTexture = CreateTexture("PaletteTexture", 256, 1, 1, GL_RGBA8); - return PaletteTexture != nullptr; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateVertexes -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreateVertexes() -{ - VertexPos = -1; - IndexPos = -1; - QuadBatchPos = -1; - BatchType = BATCH_None; - VertexBuffer = CreateVertexBuffer(sizeof(FBVERTEX)*NUM_VERTS); - if (!VertexBuffer) - { - return false; - } - IndexBuffer = CreateIndexBuffer(sizeof(uint16_t)*NUM_INDEXES); - if (!IndexBuffer) - { - return false; - } - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CalcFullscreenCoords -// -//========================================================================== - -void OpenGLSWFrameBuffer::CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const -{ - float mxl, mxr, myt, myb, tmxl, tmxr, tmyt, tmyb; - - if (viewarea_only) - { // Just calculate vertices for the viewarea/BlendingRect - mxl = float(BlendingRect.left); - mxr = float(BlendingRect.right); - myt = float(BlendingRect.top); - myb = float(BlendingRect.bottom); - tmxl = float(BlendingRect.left) / float(Width); - tmxr = float(BlendingRect.right) / float(Width); - tmyt = float(BlendingRect.top) / float(Height); - tmyb = float(BlendingRect.bottom) / float(Height); - } - else - { // Calculate vertices for the whole screen - mxl = 0.0f; - mxr = float(Width); - myt = 0.0f; - myb = float(Height); - tmxl = 0; - tmxr = 1.0f; - tmyt = 0; - tmyb = 1.0f; - } - - //{ mxl, myt, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyt }, - //{ mxr, myt, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyt }, - //{ mxr, myb, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyb }, - //{ mxl, myb, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyb }, - - verts[0].x = mxl; - verts[0].y = myt; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color0; - verts[0].color1 = color1; - verts[0].tu = tmxl; - verts[0].tv = tmyt; - - verts[1].x = mxr; - verts[1].y = myt; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color0; - verts[1].color1 = color1; - verts[1].tu = tmxr; - verts[1].tv = tmyt; - - verts[2].x = mxr; - verts[2].y = myb; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color0; - verts[2].color1 = color1; - verts[2].tu = tmxr; - verts[2].tv = tmyb; - - verts[3].x = mxl; - verts[3].y = myb; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color0; - verts[3].color1 = color1; - verts[3].tu = tmxl; - verts[3].tv = tmyb; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: GetPageCount -// -//========================================================================== - -int OpenGLSWFrameBuffer::GetPageCount() -{ - return 2; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Lock -// -//========================================================================== - -bool OpenGLSWFrameBuffer::LockCanvas() -{ - if (UseMappedMemBuffer) - { - if (!MappedMemBuffer) - { - BindFBBuffer(); - - MappedMemBuffer = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); - if (MappedMemBuffer == nullptr) - return false; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - MappedBuffer->SetBuffer(Width, Height, Width, static_cast(MappedMemBuffer)); - return true; - } - return false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Unlock -// -//========================================================================== - -void OpenGLSWFrameBuffer::UnlockCanvas() -{ - if (MappedMemBuffer) - { - BindFBBuffer(); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - MappedMemBuffer = nullptr; - MappedBuffer->SetBuffer(0, 0, 0, nullptr); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Update -// -// When In2D == 0: Copy buffer to screen and present -// When In2D == 1: Copy buffer to screen but do not present -// When In2D == 2: Set up for 2D drawing but do not draw anything -// When In2D == 3: Present and set In2D to 0 -// -//========================================================================== - -void OpenGLSWFrameBuffer::Update() -{ - if (In2D == 3) - { - if (InScene) - { - DrawRateStuff(); - Draw2D(); - EndBatch(); // Make sure all batched primitives are drawn. - Flip(); - } - In2D = 0; - return; - } - - if (In2D == 0) - { - DrawRateStuff(); - } - - if (NeedGammaUpdate) - { - float psgamma[4]; - float igamma; - - NeedGammaUpdate = false; - igamma = 1 / Gamma; - if (IsFullscreen()) - { - GammaRamp ramp; - - for (int i = 0; i < 256; ++i) - { - ramp.blue[i] = ramp.green[i] = ramp.red[i] = uint16_t(65535.f * powf(i / 255.f, igamma)); - } - SetGammaRamp(&ramp); - } - psgamma[2] = psgamma[1] = psgamma[0] = igamma; - psgamma[3] = 0.5; // For SM14 version - SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1); - } - - if (NeedPalUpdate) - { - UploadPalette(); - NeedPalUpdate = false; - } - -#ifdef WIN32 - BlitCycles.Reset(); - BlitCycles.Clock(); -#endif - - Draw3DPart(In2D <= 1); - if (In2D == 0) - { - Flip(); - } - -#ifdef WIN32 - BlitCycles.Unclock(); - //LOG1 ("cycles = %d\n", BlitCycles); -#endif - -#if 0 - Buffer = nullptr; -#endif - UpdatePending = false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Flip -// -//========================================================================== - -void OpenGLSWFrameBuffer::Flip() -{ - assert(InScene); - - Present(); - InScene = false; - - if (!IsFullscreen()) - { - int clientWidth = ViewportScaledWidth(GetClientWidth(), GetClientHeight()); - int clientHeight = ViewportScaledHeight(GetClientWidth(), GetClientHeight()); - if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) - { - RenderBuffer->Resize(clientWidth, clientHeight); - - TrueHeight = Height; - PixelDoubling = 0; - Reset(); - - V_OutputResized(Width, Height); - } - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Draw3DPart -// -// The software 3D part, to be exact. -// -//========================================================================== - -void OpenGLSWFrameBuffer::BindFBBuffer() -{ - int usage = UseMappedMemBuffer ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; - - int pixelsize = IsBgra() ? 4 : 1; - int size = Width * Height * pixelsize; - - if (FBTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)FBTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, usage); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, usage); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[FBTexture->CurrentBuffer]); - } -} - -void OpenGLSWFrameBuffer::BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch) -{ - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - uint32_t r = RPART(src[x]); - uint32_t g = GPART(src[x]); - uint32_t b = BPART(src[x]); - uint32_t a = APART(src[x]); - dest[x] = r | (g << 8) | (b << 16) | (a << 24); - } - dest += width; - src += srcpitch; - } -} - -void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d) -{ - if (copy3d) - { - BindFBBuffer(); - FBTexture->CurrentBuffer = (FBTexture->CurrentBuffer + 1) & 1; - - if (!UseMappedMemBuffer) - { - int pixelsize = IsBgra() ? 4 : 1; - int size = Width * Height * pixelsize; - - auto MemBuffer = RenderBuffer->GetPixels(); - auto Pitch = RenderBuffer->GetPitch(); - uint8_t *dest = (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, size); - if (dest) - { - if (gl.es && pixelsize == 4) - { - BgraToRgba((uint32_t*)dest, (const uint32_t *)MemBuffer, Width, Height, Pitch); - } - else if (Pitch == Width) - { - memcpy(dest, MemBuffer, Width * Height * pixelsize); - } - else - { - uint8_t *src = MemBuffer; - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width * pixelsize); - dest += Width * pixelsize; - src += Pitch * pixelsize; - } - } - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - } - else if (MappedMemBuffer) - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - MappedMemBuffer = nullptr; - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, FBTexture->Texture); - if (IsBgra()) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - InScene = true; - if (vid_hwaalines) - glEnable(GL_LINE_SMOOTH); - else - glDisable(GL_LINE_SMOOTH); - - SetTexture(0, FBTexture.get()); - SetPaletteTexture(PaletteTexture.get(), 256, BorderColor); - memset(Constant, 0, sizeof(Constant)); - SetAlphaBlend(0); - EnableAlphaTest(false); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor].get()); - else - SetPixelShader(Shaders[SHADER_NormalColorPal].get()); - if (copy3d) - { - FBVERTEX verts[4]; - uint32_t color0, color1; - auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); - if (map == nullptr) - { - color0 = 0; - color1 = 0xFFFFFFF; - } - else - { - color0 = ColorValue(map->ColorizeStart[0] / 2, map->ColorizeStart[1] / 2, map->ColorizeStart[2] / 2, 0); - color1 = ColorValue(map->ColorizeEnd[0] / 2, map->ColorizeEnd[1] / 2, map->ColorizeEnd[2] / 2, 1); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_SpecialColormap].get()); - else - SetPixelShader(Shaders[SHADER_SpecialColormapPal].get()); - } - CalcFullscreenCoords(verts, true, color0, color1); - DrawTriangleFans(2, verts); - } - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor].get()); - else - SetPixelShader(Shaders[SHADER_NormalColorPal].get()); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawLetterbox -// -// Draws the black bars at the top and bottom of the screen for letterboxed -// modes. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawLetterbox(int x, int y, int width, int height) -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - if (clientWidth == 0 || clientHeight == 0) - return; - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_SCISSOR_TEST); - if (y > 0) - { - glScissor(0, 0, clientWidth, y); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientHeight - y - height > 0) - { - glScissor(0, y + height, clientWidth, clientHeight - y - height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (x > 0) - { - glScissor(0, y, x, height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientWidth - x - width > 0) - { - glScissor(x + width, y, clientWidth - x - width, height); - glClear(GL_COLOR_BUFFER_BIT); - } - glDisable(GL_SCISSOR_TEST); -} - -void OpenGLSWFrameBuffer::UploadPalette() -{ - if (PaletteTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)PaletteTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 4, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 4, nullptr, GL_STREAM_DRAW); - - if (gl.es) PaletteTexture->MapBuffer.resize(256 * 4); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[PaletteTexture->CurrentBuffer]); - PaletteTexture->CurrentBuffer = (PaletteTexture->CurrentBuffer + 1) & 1; - } - - uint8_t *pix = gl.es ? PaletteTexture->MapBuffer.data() : (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, 256 * 4); - if (pix) - { - int i; - - for (i = 0; i < 256; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = (i == 0 ? 0 : 255); - // To let masked textures work, the first palette entry's alpha is 0. - } - pix += 4; - for (; i < 255; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = 255; - } - if (gl.es) - { - uint8_t *tempbuffer = PaletteTexture->MapBuffer.data(); - BgraToRgba((uint32_t*)tempbuffer, (const uint32_t *)tempbuffer, 256, 1, 256); - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 4, tempbuffer); - } - else - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, PaletteTexture->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - BorderColor = ColorXRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b); - } - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); -} - -PalEntry *OpenGLSWFrameBuffer::GetPalette() -{ - return SourcePalette; -} - -void OpenGLSWFrameBuffer::UpdatePalette() -{ - NeedPalUpdate = true; -} - -bool OpenGLSWFrameBuffer::SetGamma(float gamma) -{ - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool OpenGLSWFrameBuffer::SetFlash(PalEntry rgb, int amount) -{ - FlashColor = rgb; - FlashAmount = amount; - - // Fill in the constants for the pixel shader to do linear interpolation between the palette and the flash: - float r = rgb.r / 255.f, g = rgb.g / 255.f, b = rgb.b / 255.f, a = amount / 256.f; - FlashColor0 = ColorValue(r * a, g * a, b * a, 0); - a = 1 - a; - FlashColor1 = ColorValue(a, a, a, 1); - return true; -} - -void OpenGLSWFrameBuffer::GetFlash(PalEntry &rgb, int &amount) -{ - rgb = FlashColor; - amount = FlashAmount; -} - -void OpenGLSWFrameBuffer::GetFlashedPalette(PalEntry pal[256]) -{ - memcpy(pal, SourcePalette, 256 * sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending(pal, pal, 256, FlashColor.r, FlashColor.g, FlashColor.b, FlashAmount); - } -} - -void OpenGLSWFrameBuffer::SetVSync(bool vsync) -{ - // Switch to the default frame buffer because Nvidia's driver associates the vsync state with the bound FB object. - GLint oldDrawFramebufferBinding = 0, oldReadFramebufferBinding = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDrawFramebufferBinding); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldReadFramebufferBinding); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - - Super::SetVSync(vsync); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDrawFramebufferBinding); - glBindFramebuffer(GL_READ_FRAMEBUFFER, oldReadFramebufferBinding); -} - -void OpenGLSWFrameBuffer::NewRefreshRate() -{ -} - -void OpenGLSWFrameBuffer::SetBlendingRect(int x1, int y1, int x2, int y2) -{ - BlendingRect.left = x1; - BlendingRect.top = y1; - BlendingRect.right = x2; - BlendingRect.bottom = y2; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: GetScreenshotBuffer -// -// Returns a pointer into a surface holding the current screen data. -// -//========================================================================== - -void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) -{ - Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma); - /* - LockedRect lrect; - - buffer = nullptr; - if ((ScreenshotTexture = GetCurrentScreen()) != nullptr) - { - if (!ScreenshotTexture->GetSurfaceLevel(0, &ScreenshotSurface)) - { - delete ScreenshotTexture; - ScreenshotTexture = nullptr; - } - else if (!ScreenshotSurface->LockRect(&lrect, nullptr, false)) - { - delete ScreenshotSurface; - ScreenshotSurface = nullptr; - delete ScreenshotTexture; - ScreenshotTexture = nullptr; - } - else - { - buffer = (const uint8_t *)lrect.pBits; - pitch = lrect.Pitch; - color_type = SS_BGRA; - gamma = Gamma; - } - } - */ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: ReleaseScreenshotBuffer -// -//========================================================================== - -void OpenGLSWFrameBuffer::ReleaseScreenshotBuffer() -{ - ScreenshotTexture.reset(); -} - -/**************************************************************************/ -/* 2D Stuff */ -/**************************************************************************/ - -//========================================================================== -// -// OpenGLTex Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLTex::OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping) - : FNativeTexture(tex, fmt) -{ - // Attach to the texture list for the OpenGLSWFrameBuffer - Next = fb->Textures; - if (Next != nullptr) - { - Next->Prev = &Next; - } - Prev = &fb->Textures; - fb->Textures = this; - - GameTex = tex; - IsGray = false; - - Create(fb, wrapping); -} - -//========================================================================== -// -// OpenGLTex Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLTex::~OpenGLTex() -{ - // Detach from the texture list - *Prev = Next; - if (Next != nullptr) - { - Next->Prev = Prev; - } - // Remove link from the game texture - if (GameTex != nullptr) - { - mGameTex->Native[mFormat] = nullptr; - } -} - -//========================================================================== -// -// OpenGLTex :: CheckWrapping -// -// Returns true if the texture is compatible with the specified wrapping -// mode. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::CheckWrapping(bool wrapping) -{ - return true; -} - -//========================================================================== -// -// OpenGLTex :: Create -// -// Creates an HWTexture for the texture and copies the image data -// to it. Note that unlike FTexture, this image is row-major. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::Create(OpenGLSWFrameBuffer *fb, bool wrapping) -{ - Tex = fb->CreateTexture("Atlas", GameTex->GetWidth(), GameTex->GetHeight(), 1, GetTexFormat()); - return Update(); -} - -//========================================================================== -// -// OpenGLTex :: Update -// -// Copies image data from the underlying FTexture to the OpenGL texture. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::Update() -{ - LTRBRect rect; - uint8_t *dest; - - assert(GameTex != nullptr); - - int format = Tex->Format; - - rect = { 0, 0, GameTex->GetWidth(), GameTex->GetHeight() }; - - if (Tex->Buffers[0] == 0) - glGenBuffers(2, (GLuint*)Tex->Buffers); - - int bytesPerPixel = 4; - switch (format) - { - case GL_R8: bytesPerPixel = 1; break; - case GL_RGBA8: bytesPerPixel = 4; break; - default: return false; - } - - int buffersize = (rect.right - rect.left) * (rect.bottom - rect.top) * bytesPerPixel; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[Tex->CurrentBuffer]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, buffersize, nullptr, GL_STREAM_DRAW); - Tex->CurrentBuffer ^= 1; - - static std::vector tempbuffer; - if (gl.es) - tempbuffer.resize(buffersize); - - int pitch = (rect.right - rect.left) * bytesPerPixel; - uint8_t *bits = gl.es ? tempbuffer.data() : (uint8_t *)MapBuffer(GL_PIXEL_UNPACK_BUFFER, buffersize); - dest = bits; - if (!dest) - { - return false; - } - GameTex->FillBuffer(dest, pitch, GameTex->GetHeight(), mFormat); - - if (gl.es && format == GL_RGBA8) - { - BgraToRgba((uint32_t*)bits, (const uint32_t *)bits, rect.right - rect.left, rect.bottom - rect.top, rect.right - rect.left); - } - - if (gl.es) - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, buffersize, bits); - else - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, Tex->Texture); - if (format == GL_RGBA8) - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - return true; -} - -//========================================================================== -// -// OpenGLTex :: GetTexFormat -// -// Returns the texture format that would best fit this texture. -// -//========================================================================== - -int OpenGLSWFrameBuffer::OpenGLTex::GetTexFormat() -{ - IsGray = false; - - switch (mFormat) - { - case TEX_Pal: return GL_R8; - case TEX_Gray: IsGray = true; return GL_R8; - case TEX_RGB: return GL_RGBA8; - default: I_FatalError("GameTex->GetFormat() returned invalid format."); - } - return GL_R8; -} - -//========================================================================== -// -// OpenGLPal Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb) - : Remap(remap) -{ - int count; - - // Attach to the palette list for the OpenGLSWFrameBuffer - Next = fb->Palettes; - if (Next != nullptr) - { - Next->Prev = &Next; - } - Prev = &fb->Palettes; - fb->Palettes = this; - - int pow2count; - - // Round up to the nearest power of 2. - for (pow2count = 1; pow2count < remap->NumEntries; pow2count <<= 1) - { - } - count = pow2count; - - BorderColor = 0; - RoundedPaletteSize = count; - Tex = fb->CreateTexture("Pal", count, 1, 1, GL_RGBA8); - if (Tex) - { - if (!Update()) - { - Tex.reset(); - } - } -} - -//========================================================================== -// -// OpenGLPal Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLPal::~OpenGLPal() -{ - Tex.reset(); - // Detach from the palette list - *Prev = Next; - if (Next != nullptr) - { - Next->Prev = Prev; - } - // Remove link from the remap table - if (Remap != nullptr) - { - Remap->Native = nullptr; - } -} - -//========================================================================== -// -// OpenGLPal :: Update -// -// Copies the palette to the texture. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLPal::Update() -{ - uint32_t *buff; - const PalEntry *pal; - int skipat, i; - - assert(Tex != nullptr); - - if (Tex->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)Tex->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, RoundedPaletteSize * 4, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, RoundedPaletteSize * 4, nullptr, GL_STREAM_DRAW); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[Tex->CurrentBuffer]); - Tex->CurrentBuffer = (Tex->CurrentBuffer + 1) & 1; - } - - int numEntries = MIN(Remap->NumEntries, RoundedPaletteSize); - - std::vector &tempbuffer = Tex->MapBuffer; - if (gl.es) - tempbuffer.resize(numEntries * 4); - - buff = gl.es ? (uint32_t*)tempbuffer.data() : (uint32_t *)MapBuffer(GL_PIXEL_UNPACK_BUFFER, numEntries * 4); - if (buff == nullptr) - { - return false; - } - pal = Remap->Palette; - - // See explanation in UploadPalette() for skipat rationale. - skipat = MIN(numEntries, 256); - -#ifndef NO_SSE - // Manual SSE vectorized version here to workaround a bug in GCC's auto-vectorizer - - int sse_count = skipat / 4 * 4; - for (i = 0; i < sse_count; i += 4) - { - _mm_storeu_si128((__m128i*)(&buff[i]), _mm_loadu_si128((__m128i*)(&pal[i]))); - } - switch (skipat - i) - { - // fall through is intentional - case 3: buff[i] = pal[i].d; i++; - case 2: buff[i] = pal[i].d; i++; - case 1: buff[i] = pal[i].d; i++; - default: i++; - } - sse_count = numEntries / 4 * 4; - __m128i alphamask = _mm_set1_epi32(0xff000000); - while (i < sse_count) - { - __m128i lastcolor = _mm_loadu_si128((__m128i*)(&pal[i - 1])); - __m128i color = _mm_loadu_si128((__m128i*)(&pal[i])); - _mm_storeu_si128((__m128i*)(&buff[i]), _mm_or_si128(_mm_and_si128(alphamask, color), _mm_andnot_si128(alphamask, lastcolor))); - i += 4; - } - switch (numEntries - i) - { - // fall through is intentional - case 3: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - case 2: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - case 1: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - default: break; - } - -#else - for (i = 0; i < skipat; ++i) - { - buff[i] = ColorARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b); - } - for (++i; i < numEntries; ++i) - { - buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); - } -#endif - if (numEntries > 1) - { - i = numEntries - 1; - BorderColor = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); - } - - if (gl.es) - { - BgraToRgba((uint32_t*)buff, (const uint32_t *)buff, numEntries, 1, numEntries); - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, numEntries * 4, buff); - } - else - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, Tex->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, numEntries, 1, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Begin2D -// -// Begins 2D mode drawing operations. In particular, DrawTexture is -// rerouted to use Direct3D instead of the software renderer. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Begin2D(bool copy3d) -{ - Super::Begin2D(copy3d); - if (In2D) - { - return true; - } - In2D = 2 - copy3d; - Update(); - In2D = 3; - - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawBlendingRect -// -// Call after Begin2D to blend the 3D view. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawBlendingRect() -{ - Dim(FlashColor, FlashAmount / 256.f, viewwindowx, viewwindowy, viewwidth, viewheight); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateTexture -// -// Returns a native texture that wraps a FTexture. -// -//========================================================================== - -FNativeTexture *OpenGLSWFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - OpenGLTex *tex = new OpenGLTex(gametex, fmt, this, wrapping); - return tex; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreatePalette -// -// Returns a native texture that contains a palette. -// -//========================================================================== - -FNativePalette *OpenGLSWFrameBuffer::CreatePalette(FRemapTable *remap) -{ - OpenGLPal *tex = new OpenGLPal(remap, this); - if (tex->Tex == nullptr) - { - delete tex; - return nullptr; - } - return tex; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: BeginLineBatch -// -//========================================================================== - -void OpenGLSWFrameBuffer::BeginLineBatch() -{ - if (In2D < 2 || !InScene || BatchType == BATCH_Lines) - { - return; - } - EndQuadBatch(); // Make sure all quads have been drawn first. - VertexData = VertexBuffer->Lock(); - VertexPos = 0; - BatchType = BATCH_Lines; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndLineBatch -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndLineBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Lines) - { - return; - } - VertexBuffer->Unlock(); - if (VertexPos > 0) - { - SetPixelShader(Shaders[SHADER_VertexColor].get()); - SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - SetStreamSource(VertexBuffer.get()); - DrawLineList(VertexPos / 2); - } - VertexPos = -1; - BatchType = BATCH_None; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawPixel -// -//========================================================================== - -#if 0 -void OpenGLSWFrameBuffer::DrawPixel(int x, int y, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawPixel(x, y, palcolor, color); - return; - } - if (!InScene) - { - return; - } - FBVERTEX pt = - { - float(x), float(y), 0, 1, color - }; - EndBatch(); // Draw out any batched operations. - SetPixelShader(Shaders[SHADER_VertexColor].get()); - SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - DrawPoints(1, &pt); -} -#endif - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CheckQuadBatch -// -// Make sure there's enough room in the batch for one more set of triangles. -// -//========================================================================== - -void OpenGLSWFrameBuffer::CheckQuadBatch(int numtris, int numverts) -{ - if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } - else if (QuadBatchPos == MAX_QUAD_BATCH || - VertexPos + numverts > NUM_VERTS || - IndexPos + numtris * 3 > NUM_INDEXES) - { - EndQuadBatch(); - } - if (QuadBatchPos < 0) - { - BeginQuadBatch(); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: BeginQuadBatch -// -// Locks the vertex buffer for quads and sets the cursor to 0. -// -//========================================================================== - -void OpenGLSWFrameBuffer::BeginQuadBatch() -{ - if (In2D < 2 || !InScene || QuadBatchPos >= 0) - { - return; - } - EndLineBatch(); // Make sure all lines have been drawn first. - VertexData = VertexBuffer->Lock(); - IndexData = IndexBuffer->Lock(); - VertexPos = 0; - IndexPos = 0; - QuadBatchPos = 0; - BatchType = BATCH_Quads; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndQuadBatch -// -// Draws all the quads that have been batched up. -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndQuadBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Quads) - { - return; - } - BatchType = BATCH_None; - VertexBuffer->Unlock(); - IndexBuffer->Unlock(); - if (QuadBatchPos == 0) - { - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; - return; - } - SetStreamSource(VertexBuffer.get()); - SetIndices(IndexBuffer.get()); - bool uv_wrapped = false; - bool uv_should_wrap; - int indexpos, vertpos; - - indexpos = vertpos = 0; - for (int i = 0; i < QuadBatchPos; ) - { - const BufferedTris *quad = &QuadExtra[i]; - int j; - - int startindex = indexpos; - int startvertex = vertpos; - - indexpos += quad->NumTris * 3; - vertpos += quad->NumVerts; - - // Quads with matching parameters should be done with a single - // DrawPrimitive call. - for (j = i + 1; j < QuadBatchPos; ++j) - { - const BufferedTris *q2 = &QuadExtra[j]; - if (quad->Texture != q2->Texture || - !quad->IsSameSetup(*q2) || - quad->Palette != q2->Palette) - { - break; - } - if (quad->ShaderNum == BQS_InGameColormap && (quad->Flags & BQF_Desaturated) && quad->Desat != q2->Desat) - { - break; - } - indexpos += q2->NumTris * 3; - vertpos += q2->NumVerts; - } - - // Set the palette (if one) - if ((quad->Flags & BQF_Paletted) == BQF_GamePalette) - { - SetPaletteTexture(PaletteTexture.get(), 256, BorderColor); - } - else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette) - { - assert(quad->Palette != nullptr); - SetPaletteTexture(quad->Palette->Tex.get(), quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor); - } - - // Set the alpha blending - SetAlphaBlend(quad->BlendOp, quad->SrcBlend, quad->DestBlend); - - // Set the alpha test - EnableAlphaTest(!(quad->Flags & BQF_DisableAlphaTest)); - - // Set the pixel shader - if (quad->ShaderNum == BQS_PalTex) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorPalInv : SHADER_NormalColorPal].get()); - } - else if (quad->ShaderNum == BQS_Plain) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorInv : SHADER_NormalColor].get()); - } - else if (quad->ShaderNum == BQS_RedToAlpha) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_RedToAlphaInv : SHADER_RedToAlpha].get()); - } - else if (quad->ShaderNum == BQS_ColorOnly) - { - SetPixelShader(Shaders[SHADER_VertexColor].get()); - } - else if (quad->ShaderNum == BQS_SpecialColormap) - { - int select; - - select = !!(quad->Flags & BQF_Paletted); - SetPixelShader(Shaders[SHADER_SpecialColormap + select].get()); - } - else if (quad->ShaderNum == BQS_InGameColormap) - { - int select; - - select = !!(quad->Flags & BQF_Desaturated); - select |= !!(quad->Flags & BQF_InvertSource) << 1; - select |= !!(quad->Flags & BQF_Paletted) << 2; - if (quad->Flags & BQF_Desaturated) - { - SetConstant(PSCONST_Desaturation, quad->Desat / 255.f, (255 - quad->Desat) / 255.f, 0, 0); - } - SetPixelShader(Shaders[SHADER_InGameColormap + select].get()); - } - - // Set the texture clamp addressing mode - uv_should_wrap = !!(quad->Flags & BQF_WrapUV); - if (uv_wrapped != uv_should_wrap) - { - uint32_t mode = uv_should_wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE; - uv_wrapped = uv_should_wrap; - SetSamplerWrapS(0, mode); - SetSamplerWrapT(0, mode); - } - - // Set the texture - if (quad->Texture != nullptr) - { - SetTexture(0, quad->Texture); - } - - // Draw the quad - DrawTriangleList( - startvertex, // MinIndex - vertpos - startvertex, // NumVertices - startindex, // StartIndex - (indexpos - startindex) / 3 // PrimitiveCount - /*4 * i, 4 * (j - i), 6 * i, 2 * (j - i)*/); - i = j; - } - if (uv_wrapped) - { - SetSamplerWrapS(0, GL_CLAMP_TO_EDGE); - SetSamplerWrapT(0, GL_CLAMP_TO_EDGE); - } - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndBatch -// -// Draws whichever type of primitive is currently being batched. -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndBatch() -{ - if (BatchType == BATCH_Quads) - { - EndQuadBatch(); - } - else if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } -} - -int OpenGLSWFrameBuffer::GetStyleAlpha(int type) -{ - switch (type) - { - case STYLEALPHA_Zero: return GL_ZERO; - case STYLEALPHA_One: return GL_ONE; - case STYLEALPHA_Src: return GL_SRC_ALPHA; - case STYLEALPHA_InvSrc: return GL_ONE_MINUS_SRC_ALPHA; - default: return GL_ZERO; - } -} - - -void OpenGLSWFrameBuffer::EnableAlphaTest(bool enabled) -{ - if (enabled != AlphaTestEnabled) - { - AlphaTestEnabled = enabled; - //glEnable(GL_ALPHA_TEST); // To do: move to shader as this is only in the compatibility profile - } -} - -void OpenGLSWFrameBuffer::SetAlphaBlend(int op, int srcblend, int destblend) -{ - if (op == 0) - { // Disable alpha blend - if (AlphaBlendEnabled) - { - AlphaBlendEnabled = false; - glDisable(GL_BLEND); - } - } - else - { // Enable alpha blend - assert(srcblend != 0); - assert(destblend != 0); - - if (!AlphaBlendEnabled) - { - AlphaBlendEnabled = true; - glEnable(GL_BLEND); - } - if (AlphaBlendOp != op) - { - AlphaBlendOp = op; - glBlendEquation(op); - } - if (AlphaSrcBlend != srcblend || AlphaDestBlend != destblend) - { - AlphaSrcBlend = srcblend; - AlphaDestBlend = destblend; - glBlendFunc(srcblend, destblend); - } - } -} - -void OpenGLSWFrameBuffer::SetConstant(int cnum, float r, float g, float b, float a) -{ - if (Constant[cnum][0] != r || - Constant[cnum][1] != g || - Constant[cnum][2] != b || - Constant[cnum][3] != a) - { - Constant[cnum][0] = r; - Constant[cnum][1] = g; - Constant[cnum][2] = b; - Constant[cnum][3] = a; - SetPixelShaderConstantF(cnum, Constant[cnum], 1); - } -} - -void OpenGLSWFrameBuffer::SetPixelShader(HWPixelShader *shader) -{ - if (CurPixelShader != shader) - { - CurPixelShader = shader; - SetHWPixelShader(shader); - } -} - -void OpenGLSWFrameBuffer::SetTexture(int tnum, HWTexture *texture) -{ - assert(unsigned(tnum) < countof(Texture)); - if (texture) - { - if (Texture[tnum] != texture || SamplerWrapS[tnum] != texture->WrapS || SamplerWrapT[tnum] != texture->WrapT) - { - Texture[tnum] = texture; - glActiveTexture(GL_TEXTURE0 + tnum); - glBindTexture(GL_TEXTURE_2D, texture->Texture); - if (Texture[tnum]->WrapS != SamplerWrapS[tnum]) - { - Texture[tnum]->WrapS = SamplerWrapS[tnum]; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, SamplerWrapS[tnum]); - } - if (Texture[tnum]->WrapT != SamplerWrapT[tnum]) - { - Texture[tnum]->WrapT = SamplerWrapT[tnum]; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, SamplerWrapT[tnum]); - } - } - } - else if (Texture[tnum] != texture) - { - Texture[tnum] = texture; - glActiveTexture(GL_TEXTURE0 + tnum); - glBindTexture(GL_TEXTURE_2D, 0); - } -} - -void OpenGLSWFrameBuffer::SetSamplerWrapS(int tnum, int mode) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] && SamplerWrapS[tnum] != mode) - { - SamplerWrapS[tnum] = mode; - Texture[tnum]->WrapS = mode; - glActiveTexture(GL_TEXTURE0 + tnum); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, SamplerWrapS[tnum]); - } -} - -void OpenGLSWFrameBuffer::SetSamplerWrapT(int tnum, int mode) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] && SamplerWrapT[tnum] != mode) - { - SamplerWrapT[tnum] = mode; - Texture[tnum]->WrapT = mode; - glActiveTexture(GL_TEXTURE0 + tnum); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, SamplerWrapT[tnum]); - } -} - -void OpenGLSWFrameBuffer::SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color) -{ - // The pixel shader receives color indexes in the range [0.0,1.0]. - // The palette texture is also addressed in the range [0.0,1.0], - // HOWEVER the coordinate 1.0 is the right edge of the texture and - // not actually the texture itself. We need to scale and shift - // the palette indexes so they lie exactly in the center of each - // texel. For a normal palette with 256 entries, that means the - // range we use should be [0.5,255.5], adjusted so the coordinate - // is still within [0.0,1.0]. - // - // The constant register c2 is used to hold the multiplier in the - // x part and the adder in the y part. - float fcount = 1 / float(count); - SetConstant(PSCONST_PaletteMod, 255 * fcount, 0.5f * fcount, 0, 0); - SetTexture(1, texture); -} - -void OpenGLSWFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - int letterboxX, letterboxY, letterboxWidth, letterboxHeight; - GetLetterboxFrame(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - - // Subtract the LB video mode letterboxing - if (IsFullscreen()) - y -= (GetTrueHeight() - VideoHeight) / 2; - - x = int16_t((x - letterboxX) * Width / letterboxWidth); - y = int16_t((y - letterboxY) * Height / letterboxHeight); -} diff --git a/src/gl/system/gl_swframebuffer.h b/src/gl/system/gl_swframebuffer.h deleted file mode 100644 index 7120b7857..000000000 --- a/src/gl/system/gl_swframebuffer.h +++ /dev/null @@ -1,456 +0,0 @@ -#ifndef __GL_SWFRAMEBUFFER -#define __GL_SWFRAMEBUFFER - -#ifdef _WIN32 -#include "win32iface.h" -#include "win32gliface.h" -#endif - -#include "SkylineBinPack.h" -#include "textures.h" - -#include - -class FGLDebug; - -#ifdef _WIN32 -class OpenGLSWFrameBuffer : public Win32GLFrameBuffer -{ - typedef Win32GLFrameBuffer Super; -#else -#include "sdlglvideo.h" -class OpenGLSWFrameBuffer : public SDLGLFB -{ - typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux -#endif - - DSimpleCanvas *RenderBuffer; - DCanvas *MappedBuffer; - -public: - - explicit OpenGLSWFrameBuffer() {} - OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); - ~OpenGLSWFrameBuffer(); - - bool LockCanvas() override; - void UnlockCanvas() override; - - virtual DCanvas *GetCanvas() { return RenderBuffer; } - void Update() override; - PalEntry *GetPalette() override; - void GetFlashedPalette(PalEntry palette[256]) override; - void UpdatePalette() override; - bool SetGamma(float gamma) override; - bool SetFlash(PalEntry rgb, int amount) override; - void GetFlash(PalEntry &rgb, int &amount) override; - int GetPageCount() override; - void SetVSync(bool vsync) override; - void NewRefreshRate() override; - void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override; - void ReleaseScreenshotBuffer() override; - void SetBlendingRect(int x1, int y1, int x2, int y2) override; - bool Begin2D(bool copy3d) override; - void DrawBlendingRect() override; - FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) override; - FNativePalette *CreatePalette(FRemapTable *remap) override; - bool WipeStartScreen(int type) override; - void WipeEndScreen() override; - bool WipeDo(int ticks) override; - void WipeCleanup() override; - -#ifdef WIN32 - int GetTrueHeight() override { return TrueHeight; } -#endif - - void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override; - -private: - struct FBVERTEX - { - float x, y, z, rhw; - uint32_t color0, color1; - float tu, tv; - }; - - struct BURNVERTEX - { - float x, y, z, rhw; - float tu0, tv0; - float tu1, tv1; - }; - - enum - { - PSCONST_Desaturation, - PSCONST_PaletteMod, - PSCONST_Weights, - PSCONST_Gamma, - PSCONST_ScreenSize, - NumPSCONST - }; - - struct GammaRamp - { - uint16_t red[256], green[256], blue[256]; - }; - - struct LTRBRect - { - int left, top, right, bottom; - }; - - class HWTexture - { - public: - HWTexture() { Buffers[0] = 0; Buffers[1] = 0; } - ~HWTexture(); - - int Texture = 0; - int Buffers[2]; - int CurrentBuffer = 0; - int WrapS = 0; - int WrapT = 0; - int Format = 0; - - std::vector MapBuffer; - }; - - class HWFrameBuffer - { - public: - ~HWFrameBuffer(); - - int Framebuffer = 0; - std::unique_ptr Texture; - }; - - - class HWVertexBuffer - { - public: - ~HWVertexBuffer(); - - FBVERTEX *Lock(); - void Unlock(); - - int VertexArray = 0; - int Buffer = 0; - int Size = 0; - }; - - class HWIndexBuffer - { - public: - ~HWIndexBuffer(); - - uint16_t *Lock(); - void Unlock(); - - int Buffer = 0; - int Size = 0; - - private: - int LockedOldBinding = 0; - }; - - class HWPixelShader - { - public: - ~HWPixelShader(); - - int Program = 0; - int VertexShader = 0; - int FragmentShader = 0; - - int ConstantLocations[NumPSCONST]; - int ImageLocation = -1; - int PaletteLocation = -1; - int NewScreenLocation = -1; - int BurnLocation = -1; - }; - - std::unique_ptr CreateFrameBuffer(const FString &name, int width, int height); - std::unique_ptr CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines); - std::unique_ptr CreateVertexBuffer(int size); - std::unique_ptr CreateIndexBuffer(int size); - std::unique_ptr CreateTexture(const FString &name, int width, int height, int levels, int format); - - void SetGammaRamp(const GammaRamp *ramp); - void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount); - void SetHWPixelShader(HWPixelShader *shader); - void SetStreamSource(HWVertexBuffer *vertexBuffer); - void SetIndices(HWIndexBuffer *indexBuffer); - void DrawTriangleFans(int count, const FBVERTEX *vertices); - void DrawTriangleFans(int count, const BURNVERTEX *vertices); - void DrawPoints(int count, const FBVERTEX *vertices); - void DrawLineList(int count); - void DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount); - void Present(); - - void GetLetterboxFrame(int &x, int &y, int &width, int &height); - - static void BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch); - - void BindFBBuffer(); - void *MappedMemBuffer = nullptr; - bool UseMappedMemBuffer = true; - - static uint32_t ColorARGB(uint32_t a, uint32_t r, uint32_t g, uint32_t b) { return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b) & 0xff); } - static uint32_t ColorRGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { return ColorARGB(a, r, g, b); } - static uint32_t ColorXRGB(uint32_t r, uint32_t g, uint32_t b) { return ColorARGB(0xff, r, g, b); } - static uint32_t ColorValue(float r, float g, float b, float a) { return ColorRGBA((uint32_t)(r * 255.0f), (uint32_t)(g * 255.0f), (uint32_t)(b * 255.0f), (uint32_t)(a * 255.0f)); } - - static void *MapBuffer(int target, int size); - - // The number of points for the vertex buffer. - enum { NUM_VERTS = 10240 }; - - // The number of indices for the index buffer. - enum { NUM_INDEXES = ((NUM_VERTS * 6) / 4) }; - - // The number of quads we can batch together. - enum { MAX_QUAD_BATCH = (NUM_INDEXES / 6) }; - - // The default size for a texture atlas. - enum { DEF_ATLAS_WIDTH = 512 }; - enum { DEF_ATLAS_HEIGHT = 512 }; - - // TYPES ------------------------------------------------------------------- - - class OpenGLTex : public FNativeTexture - { - public: - OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping); - ~OpenGLTex(); - - std::unique_ptr Tex; - - FTexture *GameTex; - - OpenGLTex **Prev; - OpenGLTex *Next; - - bool IsGray; - - bool Create(OpenGLSWFrameBuffer *fb, bool wrapping); - bool Update(); - bool CheckWrapping(bool wrapping); - int GetTexFormat(); - }; - - class OpenGLPal : public FNativePalette - { - public: - OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb); - ~OpenGLPal(); - - OpenGLPal **Prev; - OpenGLPal *Next; - - std::unique_ptr Tex; - uint32_t BorderColor; - - bool Update(); - - FRemapTable *Remap; - int RoundedPaletteSize; - }; - - // Flags for a buffered quad - enum - { - BQF_GamePalette = 1, - BQF_CustomPalette = 7, - BQF_Paletted = 7, - BQF_Bilinear = 8, - BQF_WrapUV = 16, - BQF_InvertSource = 32, - BQF_DisableAlphaTest = 64, - BQF_Desaturated = 128, - }; - - // Shaders for a buffered quad - enum - { - BQS_PalTex, - BQS_Plain, - BQS_RedToAlpha, - BQS_ColorOnly, - BQS_SpecialColormap, - BQS_InGameColormap, - }; - - struct BufferedTris - { - uint8_t Flags; - uint8_t ShaderNum; - int BlendOp; - int SrcBlend; - int DestBlend; - - uint8_t Desat; - OpenGLPal *Palette; - HWTexture *Texture; - uint16_t NumVerts; // Number of _unique_ vertices used by this set. - uint16_t NumTris; // Number of triangles used by this set. - - void ClearSetup() - { - Flags = 0; - ShaderNum = 0; - BlendOp = 0; - SrcBlend = 0; - DestBlend = 0; - } - - bool IsSameSetup(const BufferedTris &other) const - { - return Flags == other.Flags && ShaderNum == other.ShaderNum && BlendOp == other.BlendOp && SrcBlend == other.SrcBlend && DestBlend == other.DestBlend; - } - }; - - enum - { - SHADER_NormalColor, - SHADER_NormalColorPal, - SHADER_NormalColorInv, - SHADER_NormalColorPalInv, - - SHADER_RedToAlpha, - SHADER_RedToAlphaInv, - - SHADER_VertexColor, - - SHADER_SpecialColormap, - SHADER_SpecialColormapPal, - - SHADER_InGameColormap, - SHADER_InGameColormapDesat, - SHADER_InGameColormapInv, - SHADER_InGameColormapInvDesat, - SHADER_InGameColormapPal, - SHADER_InGameColormapPalDesat, - SHADER_InGameColormapPalInv, - SHADER_InGameColormapPalInvDesat, - - SHADER_BurnWipe, - SHADER_GammaCorrection, - - NUM_SHADERS - }; - static const char *const ShaderDefines[NUM_SHADERS]; - - void Flip(); - void SetInitialState(); - bool CreateResources(); - void ReleaseResources(); - bool LoadShaders(); - bool CreateFBTexture(); - bool CreatePaletteTexture(); - bool CreateVertexes(); - void UploadPalette(); - void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const; - bool Reset(); - std::unique_ptr CopyCurrentScreen(); - void ReleaseDefaultPoolItems(); - void KillNativePals(); - void KillNativeTexs(); - void DrawLetterbox(int x, int y, int width, int height); - void Draw3DPart(bool copy3d); - static int GetStyleAlpha(int type); - void CheckQuadBatch(int numtris = 2, int numverts = 4); - void BeginQuadBatch(); - void EndQuadBatch(); - void BeginLineBatch(); - void EndLineBatch(); - void EndBatch(); - - // State - void EnableAlphaTest(bool enabled); - void SetAlphaBlend(int op, int srcblend = 0, int destblend = 0); - void SetConstant(int cnum, float r, float g, float b, float a); - void SetPixelShader(HWPixelShader *shader); - void SetTexture(int tnum, HWTexture *texture); - void SetSamplerWrapS(int tnum, int mode); - void SetSamplerWrapT(int tnum, int mode); - void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color); - - bool Valid = false; - std::shared_ptr Debug; - - std::unique_ptr StreamVertexBuffer, StreamVertexBufferBurn; - float ShaderConstants[NumPSCONST * 4]; - HWPixelShader *CurrentShader = nullptr; - - std::unique_ptr OutputFB; - - bool AlphaTestEnabled = false; - bool AlphaBlendEnabled = false; - int AlphaBlendOp = 0; - int AlphaSrcBlend = 0; - int AlphaDestBlend = 0; - float Constant[3][4]; - uint32_t CurBorderColor; - HWPixelShader *CurPixelShader; - HWTexture *Texture[5]; - int SamplerWrapS[5], SamplerWrapT[5]; - - PalEntry SourcePalette[256]; - uint32_t BorderColor; - uint32_t FlashColor0, FlashColor1; - PalEntry FlashColor; - int FlashAmount; - int TrueHeight; - int PixelDoubling; - float Gamma; -#ifdef _WIN32 - bool UpdatePending; -#endif // _WIN32 - bool NeedPalUpdate; - bool NeedGammaUpdate; - LTRBRect BlendingRect; - int In2D; - bool InScene; - bool GatheringWipeScreen; - bool AALines; - uint8_t BlockNum; - OpenGLPal *Palettes = nullptr; - OpenGLTex *Textures = nullptr; - - std::unique_ptr FBTexture; - std::unique_ptr PaletteTexture; - std::unique_ptr ScreenshotTexture; - - std::unique_ptr VertexBuffer; - FBVERTEX *VertexData = nullptr; - std::unique_ptr IndexBuffer; - uint16_t *IndexData = nullptr; - BufferedTris *QuadExtra = nullptr; - int VertexPos; - int IndexPos; - int QuadBatchPos; - enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; - - std::unique_ptr Shaders[NUM_SHADERS]; - - std::unique_ptr InitialWipeScreen, FinalWipeScreen; - - class Wiper - { - public: - virtual ~Wiper(); - virtual bool Run(int ticks, OpenGLSWFrameBuffer *fb) = 0; - - void DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, int blendop = 0, uint32_t color0 = 0, uint32_t color1 = 0xFFFFFFF); - }; - - class Wiper_Melt; friend class Wiper_Melt; - class Wiper_Burn; friend class Wiper_Burn; - class Wiper_Crossfade; friend class Wiper_Crossfade; - - Wiper *ScreenWipe; -}; - - -#endif //__GL_SWFRAMEBUFFER diff --git a/src/gl/system/gl_swwipe.cpp b/src/gl/system/gl_swwipe.cpp deleted file mode 100644 index de43b6641..000000000 --- a/src/gl/system/gl_swwipe.cpp +++ /dev/null @@ -1,566 +0,0 @@ -/* -** gl_swwipe.cpp -** Implements the different screen wipes using OpenGL calls. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#include "gl/system/gl_system.h" -#include "m_swap.h" -#include "v_video.h" -#include "doomstat.h" -#include "m_png.h" -#include "m_crc32.h" -#include "vectors.h" -#include "v_palette.h" -#include "templates.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "w_wad.h" -#include "r_data/colormaps.h" - -#include "gl/system/gl_interface.h" -#include "gl/system/gl_swframebuffer.h" -#include "gl/data/gl_data.h" -#include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" -#include "gl/gl_functions.h" -#include "gl_debug.h" -#include "m_random.h" - -class OpenGLSWFrameBuffer::Wiper_Crossfade : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Crossfade(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - int Clock; -}; - -class OpenGLSWFrameBuffer::Wiper_Melt : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Melt(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - // Match the strip sizes that oldschool Doom used. - static const int WIDTH = 160, HEIGHT = 200; - int y[WIDTH]; -}; - -class OpenGLSWFrameBuffer::Wiper_Burn : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Burn(OpenGLSWFrameBuffer *fb); - ~Wiper_Burn(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - static const int WIDTH = 64, HEIGHT = 64; - uint8_t BurnArray[WIDTH * (HEIGHT + 5)]; - std::unique_ptr BurnTexture; - int Density; - int BurnTime; -}; - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeStartScreen -// -// Called before the current screen has started rendering. This needs to -// save what was drawn the previous frame so that it can be animated into -// what gets drawn this frame. -// -// In fullscreen mode, we use GetFrontBufferData() to grab the data that -// is visible on screen right now. -// -// In windowed mode, we can't do that because we'll get the whole desktop. -// Instead, we can conveniently use the TempRenderTexture, which is normally -// used for gamma-correcting copying the image to the back buffer. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::WipeStartScreen(int type) -{ - switch (type) - { - case wipe_Melt: - ScreenWipe = new Wiper_Melt; - break; - - case wipe_Burn: - ScreenWipe = new Wiper_Burn(this); - break; - - case wipe_Fade: - ScreenWipe = new Wiper_Crossfade; - break; - - default: - return false; - } - - InitialWipeScreen = CopyCurrentScreen(); - - // Make even fullscreen model render to the TempRenderTexture, so - // we can have a copy of the new screen readily available. - GatheringWipeScreen = true; - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeEndScreen -// -// The screen we want to animate to has just been drawn. This function is -// called in place of Update(), so it has not been Presented yet. -// -//========================================================================== - -void OpenGLSWFrameBuffer::WipeEndScreen() -{ - // Don't do anything if there is no starting point. - if (InitialWipeScreen == NULL) - { - return; - } - - // If the whole screen was drawn without 2D accel, get it in to - // video memory now. - if (!In2D) - { - Begin2D(true); - } - - EndBatch(); // Make sure all batched primitives have been drawn. - - FinalWipeScreen = CopyCurrentScreen(); - - // At this point, InitialWipeScreen holds the screen we are wiping from. - // FinalWipeScreen holds the screen we are wiping to, which may be the - // same texture as TempRenderTexture. -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeDo -// -// Perform the actual wipe animation. The number of tics since the last -// time this function was called is passed in. Returns true when the wipe -// is over. The first time this function has been called, the screen is -// still locked from before and EndScene() still has not been called. -// Successive times need to call BeginScene(). -// -//========================================================================== - -bool OpenGLSWFrameBuffer::WipeDo(int ticks) -{ - // Sanity checks. - if (InitialWipeScreen == NULL || FinalWipeScreen == NULL) - { - return true; - } - if (GatheringWipeScreen) - { // This is the first time we've been called for this wipe. - GatheringWipeScreen = false; - } - else - { // This is the second or later time we've been called for this wipe. - InScene = true; - } - - In2D = 3; - - EnableAlphaTest(false); - bool done = ScreenWipe->Run(ticks, this); - return done; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeCleanup -// -// Release any resources that were specifically created for the wipe. -// -//========================================================================== - -void OpenGLSWFrameBuffer::WipeCleanup() -{ - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - InitialWipeScreen.reset(); - FinalWipeScreen.reset(); - GatheringWipeScreen = false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper::~Wiper() -{ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper :: DrawScreen -// -// Draw either the initial or target screen completely to the screen. -// -//========================================================================== - -void OpenGLSWFrameBuffer::Wiper::DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, - int blendop, uint32_t color0, uint32_t color1) -{ - FBVERTEX verts[4]; - - fb->CalcFullscreenCoords(verts, false, color0, color1); - fb->SetTexture(0, tex); - fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_NormalColor].get()); - fb->DrawTriangleFans(2, verts); -} - -// WIPE: CROSSFADE --------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Crossfade Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Crossfade::Wiper_Crossfade() -: Clock(0) -{ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Crossfade :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - Clock += ticks; - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen.get()); - - // Draw the new screen on top of it. - DrawScreen(fb, fb->FinalWipeScreen.get(), GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0)); - - return Clock >= 32; -} - -// WIPE: MELT -------------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Melt Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Melt::Wiper_Melt() -{ - int i, r; - - // setup initial column positions - // (y<0 => not ready to scroll yet) - y[0] = -(M_Random() & 15); - for (i = 1; i < WIDTH; ++i) - { - r = (M_Random()%3) - 1; - y[i] = clamp(y[i-1] + r, -15, 0); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Melt :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - // Draw the new screen on the bottom. - DrawScreen(fb, fb->FinalWipeScreen.get()); - - int i, dy; - int fbwidth = fb->Width; - int fbheight = fb->Height; - bool done = true; - - // Copy the old screen in vertical strips on top of the new one. - while (ticks--) - { - done = true; - for (i = 0; i < WIDTH; i++) - { - if (y[i] < 0) - { - y[i]++; - done = false; - } - else if (y[i] < HEIGHT) - { - dy = (y[i] < 16) ? y[i]+1 : 8; - y[i] = MIN(y[i] + dy, HEIGHT); - done = false; - } - if (ticks == 0) - { // Only draw for the final tick. - LTRBRect rect; - struct Point { int x, y; } dpt; - - dpt.x = i * fbwidth / WIDTH; - dpt.y = MAX(0, y[i] * fbheight / HEIGHT); - rect.left = dpt.x; - rect.top = 0; - rect.right = (i + 1) * fbwidth / WIDTH; - rect.bottom = fbheight - dpt.y; - if (rect.bottom > rect.top) - { - fb->CheckQuadBatch(); - - BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos]; - FBVERTEX *vert = &fb->VertexData[fb->VertexPos]; - uint16_t *index = &fb->IndexData[fb->IndexPos]; - - quad->ClearSetup(); - quad->Flags = BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - quad->Palette = NULL; - quad->Texture = fb->InitialWipeScreen.get(); - quad->NumVerts = 4; - quad->NumTris = 2; - - // Fill the vertex buffer. - float u0 = rect.left / float(fb->Width); - float v0 = 0; - float u1 = rect.right / float(fb->Width); - float v1 = (rect.bottom - rect.top) / float(fb->Height); - - float x0 = float(rect.left); - float x1 = float(rect.right); - float y0 = float(dpt.y); - float y1 = float(fbheight); - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - index[0] = fb->VertexPos; - index[1] = fb->VertexPos + 1; - index[2] = fb->VertexPos + 2; - index[3] = fb->VertexPos; - index[4] = fb->VertexPos + 2; - index[5] = fb->VertexPos + 3; - - // Batch the quad. - fb->QuadBatchPos++; - fb->VertexPos += 4; - fb->IndexPos += 6; - } - } - } - } - fb->EndQuadBatch(); - return done; -} - -// WIPE: BURN -------------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb) -{ - Density = 4; - BurnTime = 0; - memset(BurnArray, 0, sizeof(BurnArray)); - if (fb->Shaders[SHADER_BurnWipe] == nullptr) - { - BurnTexture = nullptr; - } - - BurnTexture = fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn() -{ - BurnTexture.reset(); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn :: Run -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - bool done; - - BurnTime += ticks; - ticks *= 2; - - // Make the fire burn - done = false; - while (!done && ticks--) - { - Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); - done = (Density < 0); - } - - // Update the burn texture with the new burn data - - if (BurnTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)BurnTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[BurnTexture->CurrentBuffer]); - BurnTexture->CurrentBuffer = (BurnTexture->CurrentBuffer + 1) & 1; - } - - uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, WIDTH * HEIGHT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - if (dest) - { - memcpy(dest, BurnArray, WIDTH * HEIGHT); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, BurnTexture->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen.get()); - - // Burn the new screen on top of it. - float right = float(fb->Width); - float bot = float(fb->Height); - - BURNVERTEX verts[4] = - { - { 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0, 0 }, - { right, 0.f, 0.f, 1.f, 1.f, 0.f, 1, 0 }, - { right, bot, 0.f, 1.f, 1.f, 1.f, 1, 1 }, - { 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 } - }; - - fb->SetTexture(0, fb->FinalWipeScreen.get()); - fb->SetTexture(1, BurnTexture.get()); - fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe].get()); - glActiveTexture(GL_TEXTURE1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - fb->DrawTriangleFans(2, verts); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE0); - - // The fire may not always stabilize, so the wipe is forced to end - // after an arbitrary maximum time. - return done || (BurnTime > 40); -} diff --git a/src/gl/system/gl_threads.cpp b/src/gl/system/gl_threads.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 041797b17..9c3f4c960 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -44,7 +44,6 @@ #include "gl/textures/gl_samplers.h" #include "gl/utility/gl_templates.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/renderer/gl_2ddrawer.h" //=========================================================================== diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index e4bd70566..d81bf3d8e 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -521,14 +521,7 @@ DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, c DFrameBuffer* fb = NULL; - if (1 == currentrenderer) - { - fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen); - } - else - { - fb = CreateGLSWFrameBuffer(width, height, bgra, fullscreen); - } + fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen); fb->SetFlash(flashColor, flashAmount); diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index 462598500..5482b1e4c 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -170,14 +170,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b } SDLBaseFB *fb; - if (vid_renderer == 1) - { - fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen); - } - else - { - fb = (SDLBaseFB*)CreateGLSWFrameBuffer(width, height, bgra, fullscreen); - } + fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen); retry = 0; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 2d0349f86..49a87abda 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -172,7 +172,6 @@ FTexture::~FTexture () { FTexture *link = Wads.GetLinkedTexture(SourceLump); if (link == this) Wads.SetLinkedTexture(SourceLump, NULL); - KillNative(); } void FTexture::Unload() @@ -711,40 +710,6 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, } } -FNativeTexture *FTexture::GetNative(FTextureFormat fmt, bool wrapping) -{ - if (Native[fmt] != NULL) - { - if (!Native[fmt]->CheckWrapping(wrapping)) - { // Texture's wrapping mode is not compatible. - // Destroy it and get a new one. - delete Native[fmt]; - } - else - { - if (CheckModified(DefaultRenderStyle())) - { - Native[fmt]->Update(); - } - return Native[fmt]; - } - } - Native[fmt] = screen->CreateTexture(this, fmt, wrapping); - return Native[fmt]; -} - -void FTexture::KillNative() -{ - for (auto &nat : Native) - { - if (nat != nullptr) - { - delete nat; - nat = nullptr; - } - } -} - void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt) { const uint8_t *pix; diff --git a/src/textures/textures.h b/src/textures/textures.h index 68e0ab132..302f9bd2d 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -163,10 +163,6 @@ enum FTextureFormat : uint32_t TEX_Count }; -class FNativeTexture; - - - // Base texture class class FTexture { @@ -237,12 +233,6 @@ public: // Returns the native pixel format for this image virtual FTextureFormat GetFormat(); - // Returns a native 3D representation of the texture - FNativeTexture *GetNative(FTextureFormat fmt, bool wrapping); - - // Frees the native 3D representation of the texture - void KillNative(); - // Fill the native texture buffer with pixel data for this image virtual void FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt); @@ -291,7 +281,6 @@ public: protected: uint16_t Width, Height, WidthMask; static uint8_t GrayMap[256]; - FNativeTexture *Native[TEX_Count] = { nullptr }; // keep a slot for each type, because some render modes do not work with the base texture uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) { if (style.Flags & STYLEF_RedIsAlpha) @@ -380,9 +369,6 @@ public: static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); - friend class FNativeTexture; - friend class OpenGLSWFrameBuffer; - public: struct MiscGLInfo diff --git a/src/v_font.cpp b/src/v_font.cpp index d8826d11c..28b93bf24 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -965,54 +965,6 @@ void FFont::LoadTranslations() delete[] luminosity; } -//========================================================================== -// -// FFont :: Preload -// -// Loads most of the 7-bit ASCII characters. In the case of D3DFB, this -// means all the characters of a font have a better chance of being packed -// into the same hardware texture. -// -// (Note that this is a rather dumb implementation. The atlasing should -// occur at a higher level, independently of the renderer being used.) -// -//========================================================================== - -void FFont::Preload() const -{ - // First and last char are the same? Wait until it's actually needed - // since nothing is gained by preloading now. - if (FirstChar == LastChar) - { - return; - } - for (int i = MAX(FirstChar, 0x21); i < MIN(LastChar, 0x7e); ++i) - { - int foo; - FTexture *pic = GetChar(i, &foo); - if (pic != NULL) - { - pic->GetNative(pic->GetFormat(), false); - } - } -} - -//========================================================================== -// -// FFont :: StaticPreloadFonts -// -// Preloads all the defined fonts. -// -//========================================================================== - -void FFont::StaticPreloadFonts() -{ - for (FFont *font = FirstFont; font != NULL; font = font->Next) - { - font->Preload(); - } -} - //========================================================================== // // FFont :: FFont - default constructor diff --git a/src/v_font.h b/src/v_font.h index e1be6afb2..83ea5de19 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -90,11 +90,9 @@ public: int GetHeight () const { return FontHeight; } int GetDefaultKerning () const { return GlobalKerning; } virtual void LoadTranslations(); - void Preload() const; FName GetName() const { return FontName; } static FFont *FindFont(FName fontname); - static void StaticPreloadFonts(); // Return width of string in pixels (unscaled) int StringWidth (const uint8_t *str) const; diff --git a/src/v_video.cpp b/src/v_video.cpp index 0ddb8765f..1e806b1f2 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -882,21 +882,6 @@ void DFrameBuffer::DrawBlendingRect() { } -//========================================================================== -// -// DFrameBuffer :: CreateTexture -// -// Creates a native texture for a game texture, if supported. -// The hardware renderer does not use this interface because it is -// far too limited -// -//========================================================================== - -FNativeTexture *DFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - return NULL; -} - //========================================================================== // // DFrameBuffer :: CreatePalette @@ -983,20 +968,6 @@ FNativePalette::~FNativePalette() { } -FNativeTexture::~FNativeTexture() -{ - // Remove link from the game texture - if (mGameTex != nullptr) - { - mGameTex->Native[mFormat] = nullptr; - } - -} - -bool FNativeTexture::CheckWrapping(bool wrapping) -{ - return true; -} CCMD(clean) { @@ -1018,10 +989,6 @@ bool V_DoModeSetup (int width, int height, int bits) screen = buff; screen->SetGamma (Gamma); - // Load fonts now so they can be packed into textures straight away, - // if D3DFB is being used for the display. - FFont::StaticPreloadFonts(); - DisplayBits = bits; V_UpdateModeSize(screen->GetWidth(), screen->GetHeight()); diff --git a/src/v_video.h b/src/v_video.h index 0faef4402..dc2db39cf 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -259,18 +259,6 @@ public: void Resize(int width, int height); }; -// This class represents a native texture, as opposed to an FTexture. -class FNativeTexture -{ -protected: - FTexture * mGameTex; - FTextureFormat mFormat; -public: - FNativeTexture(FTexture *tex, FTextureFormat fmt) : mGameTex(tex), mFormat(fmt) {} - virtual ~FNativeTexture(); - virtual bool Update() = 0; - virtual bool CheckWrapping(bool wrapping); -}; // This class represents a texture lookup palette. class FNativePalette @@ -381,9 +369,6 @@ public: // accelerated 2D mode. virtual void DrawBlendingRect(); - // Create a native texture from a game texture. - virtual FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping); - // Create a palette texture from a remap/palette table. virtual FNativePalette *CreatePalette(FRemapTable *remap); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp deleted file mode 100644 index 4de42ac06..000000000 --- a/src/win32/fb_d3d9.cpp +++ /dev/null @@ -1,2221 +0,0 @@ -/* -** fb_d3d9.cpp -** Code to let ZDoom use Direct3D 9 as a simple framebuffer -** -**--------------------------------------------------------------------------- -** Copyright 1998-2011 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** This file does _not_ implement hardware-acclerated 3D rendering. It is -** just a means of getting the pixel data to the screen in a more reliable -** method on modern hardware by copying the entire frame to a texture, -** drawing that to the screen, and presenting. -** -** That said, it does implement hardware-accelerated 2D rendering. -*/ - -// HEADER FILES ------------------------------------------------------------ - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#define DIRECT3D_VERSION 0x0900 -#define WIN32_LEAN_AND_MEAN - -#include -#include - -#include - -#include "doomtype.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "i_input.h" -#include "v_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "win32iface.h" -#include "win32swiface.h" -#include "doomstat.h" -#include "v_palette.h" -#include "w_wad.h" -#include "textures.h" -#include "r_data/colormaps.h" -#include "SkylineBinPack.h" -#include "swrenderer/scene/r_light.h" - -// MACROS ------------------------------------------------------------------ - -// The number of points for the vertex buffer. -#define NUM_VERTS 10240 - -// The number of indices for the index buffer. -#define NUM_INDEXES ((NUM_VERTS * 6) / 4) - -// The number of quads we can batch together. -#define MAX_QUAD_BATCH (NUM_INDEXES / 6) - -// TYPES ------------------------------------------------------------------- - -class D3DTex : public FNativeTexture -{ -public: - D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping); - ~D3DTex(); - - //D3DFB::PackedTexture *Box; - - IDirect3DTexture9 *Tex; - D3DFORMAT Format; - - - D3DTex **Prev; - D3DTex *Next; - - bool IsGray; - - bool Create(D3DFB *fb, bool wrapping); - bool Update(); - bool CheckWrapping(bool wrapping); - D3DFORMAT GetTexFormat(); -}; - -class D3DPal : public FNativePalette -{ -public: - D3DPal(FRemapTable *remap, D3DFB *fb); - ~D3DPal(); - - D3DPal **Prev; - D3DPal *Next; - - IDirect3DTexture9 *Tex; - D3DCOLOR BorderColor; - - bool Update(); - - FRemapTable *Remap; - int RoundedPaletteSize; -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -extern HWND Window; -extern IVideo *Video; -extern BOOL AppActive; -extern int SessionState; -extern bool VidResizing; - -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Bool, vid_vsync) -EXTERN_CVAR (Float, transsouls) -EXTERN_CVAR (Int, vid_refreshrate) - -extern IDirect3D9 *D3D; - -extern cycle_t BlitCycles; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -const char *const D3DFB::ShaderNames[D3DFB::NUM_SHADERS] = -{ - "NormalColor.pso", - "NormalColorPal.pso", - "NormalColorD.pso", - "NormalColorPalD.pso", - "NormalColorInv.pso", - "NormalColorPalInv.pso", - "NormalColorOpaq.pso", - "NormalColorPalOpaq.pso", - "NormalColorInvOpaq.pso", - "NormalColorPalInvOpaq.pso", - - "AlphaTex.pso", - "PalAlphaTex.pso", - "Stencil.pso", - "PalStencil.pso", - - "VertexColor.pso", - - "SpecialColormap.pso", - "SpecialColorMapPal.pso", - - "BurnWipe.pso", - "GammaCorrection.pso", -}; - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -CVAR(Bool, d3d_antilag, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// D3DFB - Constructor -// -//========================================================================== - -D3DFB::D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen) - : BaseWinFB (width, height, bgra) -{ - D3DPRESENT_PARAMETERS d3dpp; - - LastHR = 0; - - Adapter = adapter; - D3DDevice = NULL; - VertexBuffer = NULL; - IndexBuffer = NULL; - FBTexture = NULL; - TempRenderTexture = NULL; - RenderTexture[0] = NULL; - RenderTexture[1] = NULL; - InitialWipeScreen = NULL; - ScreenshotTexture = NULL; - ScreenshotSurface = NULL; - FinalWipeScreen = NULL; - PaletteTexture = NULL; - GammaTexture = NULL; - FrontCopySurface = NULL; - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i] = NULL; - } - GammaShader = NULL; - BlockSurface[0] = NULL; - BlockSurface[1] = NULL; - VSync = vid_vsync; - BlendingRect.left = 0; - BlendingRect.top = 0; - BlendingRect.right = FBWidth; - BlendingRect.bottom = FBHeight; - In2D = 0; - Palettes = NULL; - Textures = NULL; - GatheringWipeScreen = false; - ScreenWipe = NULL; - InScene = false; - QuadExtra = new BufferedTris[MAX_QUAD_BATCH]; - Atlases = NULL; - PixelDoubling = 0; - SkipAt = -1; - CurrRenderTexture = 0; - RenderTextureToggle = 0; - - Gamma = 1.0; - FlashColor0 = 0; - FlashColor1 = 0xFFFFFFFF; - FlashColor = 0; - FlashAmount = 0; - - NeedGammaUpdate = false; - NeedPalUpdate = false; - - RenderBuffer = new DSimpleCanvas(width, height, bgra); - - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - - Windowed = !(static_cast(Video)->GoFullscreen(fullscreen)); - - TrueHeight = height; - if (fullscreen) - { - for (Win32Video::ModeInfo *mode = static_cast(Video)->m_Modes; mode != NULL; mode = mode->next) - { - if (mode->width == Width && mode->height == Height) - { - TrueHeight = mode->realheight; - PixelDoubling = mode->doubling; - break; - } - } - } - // Offset from top of screen to top of letterboxed screen - LBOffsetI = (TrueHeight - Height) / 2; - LBOffset = float(LBOffsetI); - - FillPresentParameters(&d3dpp, fullscreen, VSync); - - HRESULT hr; - - LOG("CreateDevice attempt 1 hwvp\n"); - if (FAILED(hr = D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - LOG2("CreateDevice returned hr %08x dev %p; attempt 2 swvp\n", hr, D3DDevice); - if (FAILED(D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - if (d3dpp.FullScreen_RefreshRateInHz != 0) - { - d3dpp.FullScreen_RefreshRateInHz = 0; - LOG2("CreateDevice returned hr %08x dev %p; attempt 3 (hwvp, default Hz)\n", hr, D3DDevice); - if (FAILED(hr = D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - LOG2("CreateDevice returned hr %08x dev %p; attempt 4 (swvp, default Hz)\n", hr, D3DDevice); - if (FAILED(D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - hr != D3DERR_DEVICELOST) - { - D3DDevice = NULL; - } - } - } - } - } - LOG2("Final CreateDevice returned HR %08x and device %p\n", hr, D3DDevice); - LastHR = hr; - if (D3DDevice != NULL) - { - D3DADAPTER_IDENTIFIER9 adapter_id; - D3DDEVICE_CREATION_PARAMETERS create_params; - - if (FAILED(hr = D3DDevice->GetDeviceCaps(&DeviceCaps))) - { - memset(&DeviceCaps, 0, sizeof(DeviceCaps)); - } - if (SUCCEEDED(hr = D3DDevice->GetCreationParameters(&create_params)) && - SUCCEEDED(hr = D3D->GetAdapterIdentifier(create_params.AdapterOrdinal, 0, &adapter_id))) - { - // NVidia's drivers lie, claiming they don't support - // antialiased lines when, really, they do. - if (adapter_id.VendorId == 0x10de) - { - DeviceCaps.LineCaps |= D3DLINECAPS_ANTIALIAS; - } - // ATI's drivers apparently also lie, so screw this caps bit. - } - CreateResources(); - SetInitialState(); - } -} - -//========================================================================== -// -// D3DFB - Destructor -// -//========================================================================== - -D3DFB::~D3DFB () -{ - ReleaseResources(); - SAFE_RELEASE( D3DDevice ); - delete[] QuadExtra; -} - -//========================================================================== -// -// D3DFB :: SetInitialState -// -// Called after initial device creation and reset, when everything is set -// to D3D's defaults. -// -//========================================================================== - -void D3DFB::SetInitialState() -{ - AlphaBlendEnabled = FALSE; - AlphaBlendOp = D3DBLENDOP_ADD; - AlphaSrcBlend = D3DBLEND(0); - AlphaDestBlend = D3DBLEND(0); - - CurPixelShader = NULL; - memset(Constant, 0, sizeof(Constant)); - - for (unsigned i = 0; i < countof(Texture); ++i) - { - Texture[i] = NULL; - D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - if (i > 1) - { - // Set linear filtering for the SM14 gamma texture. - D3DDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - } - - NeedGammaUpdate = true; - NeedPalUpdate = true; - OldRenderTarget = NULL; - - // This constant is used for grayscaling weights (.xyz) and color inversion (.w) - float weights[4] = { 77/256.f, 143/256.f, 37/256.f, 1 }; - D3DDevice->SetPixelShaderConstantF(PSCONST_Weights, weights, 1); - - // D3DRS_ALPHATESTENABLE defaults to FALSE - // D3DRS_ALPHAREF defaults to 0 - D3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL); - AlphaTestEnabled = FALSE; - - CurBorderColor = 0; - - // Clear to black, just in case it wasn't done already. - D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 0, 0); -} - -//========================================================================== -// -// D3DFB :: FillPresentParameters -// -//========================================================================== - -void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync) -{ - memset (pp, 0, sizeof(*pp)); - pp->Windowed = !fullscreen; - pp->SwapEffect = D3DSWAPEFFECT_DISCARD; - pp->BackBufferWidth = Width << PixelDoubling; - pp->BackBufferHeight = TrueHeight << PixelDoubling; - pp->BackBufferFormat = fullscreen ? D3DFMT_A8R8G8B8 : D3DFMT_UNKNOWN; - pp->BackBufferCount = 1; - pp->hDeviceWindow = Window; - pp->PresentationInterval = vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - if (fullscreen) - { - pp->FullScreen_RefreshRateInHz = vid_refreshrate; - } -} - -//========================================================================== -// -// D3DFB :: CreateResources -// -//========================================================================== - -bool D3DFB::CreateResources() -{ - Atlases = NULL; - if (!Windowed) - { - // Remove the window border in fullscreen mode - SetWindowLong (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU); - } - else - { - // Resize the window to match desired dimensions - RECT rect = { 0, 0, Width, Height }; - AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); - int sizew = rect.right - rect.left; - int sizeh = rect.bottom - rect.top; - LOG2 ("Resize window to %dx%d\n", sizew, sizeh); - VidResizing = true; - // Make sure the window has a border in windowed mode - SetWindowLong(Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); - if (GetWindowLong(Window, GWL_EXSTYLE) & WS_EX_TOPMOST) - { - // Direct3D 9 will apparently add WS_EX_TOPMOST to fullscreen windows, - // and removing it is a little tricky. Using SetWindowLongPtr to clear it - // will not do the trick, but sending the window behind everything will. - SetWindowPos(Window, HWND_BOTTOM, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE); - SetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); - } - else - { - SetWindowPos(Window, NULL, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER); - } - I_RestoreWindowedPos(); - VidResizing = false; - } - if (!LoadShaders()) - { - return false; - } - if (!CreateFBTexture() || - !CreatePaletteTexture()) - { - return false; - } - if (!CreateVertexes(NUM_VERTS, NUM_INDEXES)) - { - return false; - } - CreateBlockSurfaces(); - return true; -} - -//========================================================================== -// -// D3DFB :: LoadShaders -// -// Returns true if all required shaders were loaded. (Gamma and burn wipe -// are the only ones not considered "required".) -// -//========================================================================== - -bool D3DFB::LoadShaders() -{ - static const char models[][4] = { "30/", "20/" }; - FString shaderdir, shaderpath; - unsigned model, i; - int lump; - - // We determine the best available model simply by trying them all in - // order of decreasing preference. - for (model = 0; model < countof(models); ++model) - { - shaderdir = "shaders/d3d/sm"; - shaderdir += models[model]; - for (i = 0; i < NUM_SHADERS; ++i) - { - shaderpath = shaderdir; - shaderpath += ShaderNames[i]; - lump = Wads.CheckNumForFullName(shaderpath); - if (lump >= 0) - { - FMemLump data = Wads.ReadLump(lump); - if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) && - i < SHADER_BurnWipe) - { - break; - } - } - } - if (i == NUM_SHADERS) - { // Success! - return true; - } - // Failure. Release whatever managed to load (which is probably nothing.) - for (i = 0; i < NUM_SHADERS; ++i) - { - SAFE_RELEASE( Shaders[i] ); - } - } - return false; -} - -//========================================================================== -// -// D3DFB :: ReleaseResources -// -//========================================================================== - -void D3DFB::ReleaseResources () -{ - I_SaveWindowedPos (); - KillNativeTexs(); - KillNativePals(); - ReleaseDefaultPoolItems(); - SAFE_RELEASE( ScreenshotSurface ); - SAFE_RELEASE( ScreenshotTexture ); - SAFE_RELEASE( PaletteTexture ); - for (int i = 0; i < NUM_SHADERS; ++i) - { - SAFE_RELEASE( Shaders[i] ); - } - GammaShader = NULL; - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - GatheringWipeScreen = false; -} - -//========================================================================== -// -// D3DFB :: ReleaseDefaultPoolItems -// -// Free resources created with D3DPOOL_DEFAULT. -// -//========================================================================== - -void D3DFB::ReleaseDefaultPoolItems() -{ - SAFE_RELEASE( FBTexture ); - SAFE_RELEASE( FinalWipeScreen ); - SAFE_RELEASE( RenderTexture[0] ); - SAFE_RELEASE( RenderTexture[1] ); - SAFE_RELEASE( InitialWipeScreen ); - SAFE_RELEASE( VertexBuffer ); - SAFE_RELEASE( IndexBuffer ); - SAFE_RELEASE( BlockSurface[0] ); - SAFE_RELEASE( BlockSurface[1] ); - SAFE_RELEASE( FrontCopySurface ); -} - -//========================================================================== -// -// D3DFB :: Reset -// -//========================================================================== - -bool D3DFB::Reset () -{ - D3DPRESENT_PARAMETERS d3dpp; - - ReleaseDefaultPoolItems(); - FillPresentParameters (&d3dpp, !Windowed, VSync); - if (!SUCCEEDED(D3DDevice->Reset (&d3dpp))) - { - if (d3dpp.FullScreen_RefreshRateInHz != 0) - { - d3dpp.FullScreen_RefreshRateInHz = 0; - if (!SUCCEEDED(D3DDevice->Reset (&d3dpp))) - { - return false; - } - } - else - { - return false; - } - } - LOG("Device was reset\n"); - if (!CreateFBTexture() || !CreateVertexes(NUM_VERTS, NUM_INDEXES)) - { - return false; - } - CreateBlockSurfaces(); - SetInitialState(); - return true; -} - -//========================================================================== -// -// D3DFB :: CreateBlockSurfaces -// -// Create blocking surfaces for antilag. It's okay if these can't be -// created; antilag just won't work. -// -//========================================================================== - -void D3DFB::CreateBlockSurfaces() -{ - BlockNum = 0; - if (SUCCEEDED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, &BlockSurface[0], 0))) - { - if (FAILED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, &BlockSurface[1], 0))) - { - BlockSurface[0]->Release(); - BlockSurface[0] = NULL; - } - } -} - -//========================================================================== -// -// D3DFB :: KillNativePals -// -// Frees all native palettes. -// -//========================================================================== - -void D3DFB::KillNativePals() -{ - while (Palettes != NULL) - { - delete Palettes; - } -} - -//========================================================================== -// -// D3DFB :: KillNativeTexs -// -// Frees all native textures. -// -//========================================================================== - -void D3DFB::KillNativeTexs() -{ - while (Textures != NULL) - { - delete Textures; - } -} - -//========================================================================== -// -// D3DFB :: CreateFBTexture -// -// Creates the "Framebuffer" texture. With the advent of hardware-assisted -// 2D, this is something of a misnomer now. The FBTexture is only used for -// uploading the software 3D image to video memory so that it can be drawn -// to the real frame buffer. -// -// It also creates the TempRenderTexture, since this seemed like a -// convenient place to do so. -// -//========================================================================== - -bool D3DFB::CreateFBTexture () -{ - FBFormat = IsBgra() ? D3DFMT_A8R8G8B8 : D3DFMT_L8; - - if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) - { - int pow2width, pow2height, i; - - for (i = 1; i < Width; i <<= 1) {} pow2width = i; - for (i = 1; i < Height; i <<= 1) {} pow2height = i; - - if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) - { - return false; - } - else - { - FBWidth = pow2width; - FBHeight = pow2height; - } - } - else - { - FBWidth = Width; - FBHeight = Height; - } - RenderTextureToggle = 0; - RenderTexture[0] = NULL; - RenderTexture[1] = NULL; - if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[0], NULL))) - { - return false; - } - if (Windowed || PixelDoubling) - { - // Windowed or pixel doubling: Create another render texture so we can flip between them. - RenderTextureToggle = 1; - if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[1], NULL))) - { - return false; - } - } - else - { - // Fullscreen and not pixel doubling: Create a render target to have the back buffer copied to. - if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL))) - { - return false; - } - } - // Initialize the TempRenderTextures to black. - for (int i = 0; i <= RenderTextureToggle; ++i) - { - IDirect3DSurface9 *surf; - if (SUCCEEDED(RenderTexture[i]->GetSurfaceLevel(0, &surf))) - { - D3DDevice->ColorFill(surf, NULL, D3DCOLOR_XRGB(0,0,0)); - surf->Release(); - } - } - TempRenderTexture = RenderTexture[0]; - CurrRenderTexture = 0; - return true; -} - -//========================================================================== -// -// D3DFB :: CreatePaletteTexture -// -//========================================================================== - -bool D3DFB::CreatePaletteTexture () -{ - if (FAILED(D3DDevice->CreateTexture (256, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &PaletteTexture, NULL))) - { - return false; - } - return true; -} - -//========================================================================== -// -// D3DFB :: CreateVertexes -// -//========================================================================== - -bool D3DFB::CreateVertexes (int numverts, int numindices) -{ - SAFE_RELEASE(VertexBuffer); - SAFE_RELEASE(IndexBuffer); - NumVertices = numverts; - NumIndices = numindices; - if (FAILED(D3DDevice->CreateVertexBuffer(sizeof(FBVERTEX)*numverts, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_FBVERTEX, D3DPOOL_DEFAULT, &VertexBuffer, NULL))) - { - return false; - } - if (FAILED(D3DDevice->CreateIndexBuffer(sizeof(uint16_t)*numindices, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &IndexBuffer, NULL))) - { - return false; - } - return true; -} - -//========================================================================== -// -// D3DFB :: CalcFullscreenCoords -// -//========================================================================== - -void D3DFB::CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const -{ - float offset = OldRenderTarget != NULL ? 0 : LBOffset; - float top = offset - 0.5f; - float texright = float(Width) / float(FBWidth); - float texbot = float(Height) / float(FBHeight); - float mxl, mxr, myt, myb, tmxl, tmxr, tmyt, tmyb; - - if (viewarea_only) - { // Just calculate vertices for the viewarea/BlendingRect - mxl = float(BlendingRect.left) - 0.5f; - mxr = float(BlendingRect.right) - 0.5f; - myt = float(BlendingRect.top) + top; - myb = float(BlendingRect.bottom) + top; - tmxl = float(BlendingRect.left) / float(Width) * texright; - tmxr = float(BlendingRect.right) / float(Width) * texright; - tmyt = float(BlendingRect.top) / float(Height) * texbot; - tmyb = float(BlendingRect.bottom) / float(Height) * texbot; - } - else - { // Calculate vertices for the whole screen - mxl = -0.5f; - mxr = float(Width << (can_double ? PixelDoubling : 0)) - 0.5f; - myt = top; - myb = float(Height << (can_double ? PixelDoubling : 0)) + top; - tmxl = 0; - tmxr = texright; - tmyt = 0; - tmyb = texbot; - } - - //{ mxl, myt, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyt }, - //{ mxr, myt, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyt }, - //{ mxr, myb, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyb }, - //{ mxl, myb, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyb }, - - verts[0].x = mxl; - verts[0].y = myt; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color0; - verts[0].color1 = color1; - verts[0].tu = tmxl; - verts[0].tv = tmyt; - - verts[1].x = mxr; - verts[1].y = myt; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color0; - verts[1].color1 = color1; - verts[1].tu = tmxr; - verts[1].tv = tmyt; - - verts[2].x = mxr; - verts[2].y = myb; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color0; - verts[2].color1 = color1; - verts[2].tu = tmxr; - verts[2].tv = tmyb; - - verts[3].x = mxl; - verts[3].y = myb; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color0; - verts[3].color1 = color1; - verts[3].tu = tmxl; - verts[3].tv = tmyb; -} - -//========================================================================== -// -// D3DFB :: GetPageCount -// -//========================================================================== - -int D3DFB::GetPageCount () -{ - return 1; -} - -//========================================================================== -// -// D3DFB :: IsFullscreen -// -//========================================================================== - -bool D3DFB::IsFullscreen () -{ - return !Windowed; -} - -//========================================================================== -// -// D3DFB :: Update -// -// When In2D == 0: Copy buffer to screen and present -// When In2D == 1: Copy buffer to screen but do not present -// When In2D == 2: Set up for 2D drawing but do not draw anything -// When In2D == 3: Present and set In2D to 0 -// -//========================================================================== - -void D3DFB::Update() -{ - if (In2D == 3) - { - if (InScene) - { - DrawRateStuff(); - Draw2D(); - EndQuadBatch(); // Make sure all batched primitives are drawn. - In2D = 0; - Flip(); - } - In2D = 0; - return; - } - - if (In2D == 0) - { - DrawRateStuff(); - } - - if (NeedGammaUpdate) - { - float psgamma[4]; - float igamma; - - NeedGammaUpdate = false; - igamma = 1 / Gamma; - if (!Windowed) - { - D3DGAMMARAMP ramp; - - for (int i = 0; i < 256; ++i) - { - ramp.blue[i] = ramp.green[i] = ramp.red[i] = WORD(65535.f * powf(i / 255.f, igamma)); - } - LOG("SetGammaRamp\n"); - D3DDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &ramp); - } - else - { - if (igamma != 1) - { - UpdateGammaTexture(igamma); - GammaShader = Shaders[SHADER_GammaCorrection]; - } - else - { - GammaShader = NULL; - } - } - psgamma[2] = psgamma[1] = psgamma[0] = igamma; - psgamma[3] = 0.5; // For SM14 version - D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1); - } - - if (NeedPalUpdate) - { - UploadPalette(); - } - - BlitCycles.Reset(); - BlitCycles.Clock(); - - HRESULT hr = D3DDevice->TestCooperativeLevel(); - if (FAILED(hr) && (hr != D3DERR_DEVICENOTRESET || !Reset())) - { - Sleep(1); - return; - } - Draw3DPart(In2D <= 1); - if (In2D == 0) - { - Flip(); - } - - BlitCycles.Unclock(); - //LOG1 ("cycles = %d\n", BlitCycles); - -#if 0 - Buffer = NULL; -#endif - UpdatePending = false; -} - -//========================================================================== -// -// D3DFB :: Flip -// -//========================================================================== - -void D3DFB::Flip() -{ - assert(InScene); - - DrawLetterbox(); - DoWindowedGamma(); - D3DDevice->EndScene(); - - CopyNextFrontBuffer(); - - // Attempt to counter input lag. - if (d3d_antilag && BlockSurface[0] != NULL) - { - D3DLOCKED_RECT lr; - volatile int dummy; - D3DDevice->ColorFill(BlockSurface[BlockNum], NULL, D3DCOLOR_ARGB(0xFF,0,0x20,0x50)); - BlockNum ^= 1; - if (!FAILED((BlockSurface[BlockNum]->LockRect(&lr, NULL, D3DLOCK_READONLY)))) - { - dummy = *(int *)lr.pBits; - BlockSurface[BlockNum]->UnlockRect(); - } - } - // Limiting the frame rate is as simple as waiting for the timer to signal this event. - I_FPSLimit(); - D3DDevice->Present(NULL, NULL, NULL, NULL); - InScene = false; - - if (RenderTextureToggle) - { - // Flip the TempRenderTexture to the other one now. - CurrRenderTexture ^= RenderTextureToggle; - TempRenderTexture = RenderTexture[CurrRenderTexture]; - } - - if (Windowed) - { - RECT box; - GetClientRect(Window, &box); - if (box.right > 0 && box.bottom > 0 && (Width != box.right || Height != box.bottom)) - { - RenderBuffer->Resize(box.right, box.bottom); - - TrueHeight = Height; - PixelDoubling = 0; - LBOffsetI = 0; - LBOffset = 0.0f; - Reset(); - - V_OutputResized(Width, Height); - } - } -} - -//========================================================================== -// -// D3DFB :: CopyNextFrontBuffer -// -// Duplicates the contents of the back buffer that will become the front -// buffer upon Present into FrontCopySurface so that we can get the -// contents of the display without wasting time in GetFrontBufferData(). -// -//========================================================================== - -void D3DFB::CopyNextFrontBuffer() -{ - IDirect3DSurface9 *backbuff; - - if (Windowed || PixelDoubling) - { - // Windowed mode or pixel doubling: TempRenderTexture has what we want - SAFE_RELEASE( FrontCopySurface ); - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &backbuff))) - { - FrontCopySurface = backbuff; - } - } - else - { - // Fullscreen, not pixel doubled: The back buffer has what we want, - // but it might be letter boxed. - if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuff))) - { - RECT srcrect = { 0, LBOffsetI, Width, LBOffsetI + Height }; - D3DDevice->StretchRect(backbuff, &srcrect, FrontCopySurface, NULL, D3DTEXF_NONE); - backbuff->Release(); - } - } -} - -//========================================================================== -// -// D3DFB :: Draw3DPart -// -// The software 3D part, to be exact. -// -//========================================================================== - -void D3DFB::Draw3DPart(bool copy3d) -{ - if (copy3d) - { - RECT texrect = { 0, 0, Width, Height }; - D3DLOCKED_RECT lockrect; - - if ((FBWidth == Width && FBHeight == Height && - SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) || - SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0))) - { - auto MemBuffer = RenderBuffer->GetPixels(); - auto Pitch = RenderBuffer->GetPitch(); - - if (IsBgra() && FBFormat == D3DFMT_A8R8G8B8) - { - - if (lockrect.Pitch == Pitch * sizeof(uint32_t) && Pitch == Width) - { - memcpy(lockrect.pBits, MemBuffer, Width * Height * sizeof(uint32_t)); - } - else - { - uint32_t *dest = (uint32_t *)lockrect.pBits; - uint32_t *src = (uint32_t*)MemBuffer; - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width * sizeof(uint32_t)); - dest = reinterpret_cast(reinterpret_cast(dest) + lockrect.Pitch); - src += Pitch; - } - } - } - else if (!IsBgra() && FBFormat == D3DFMT_L8) - { - if (lockrect.Pitch == Pitch && Pitch == Width) - { - memcpy(lockrect.pBits, MemBuffer, Width * Height); - } - else - { - uint8_t *dest = (uint8_t *)lockrect.pBits; - uint8_t *src = RenderBuffer->GetPixels(); - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width); - dest = reinterpret_cast(reinterpret_cast(dest) + lockrect.Pitch); - src += RenderBuffer->GetPitch(); - } - } - } - else - { - memset(lockrect.pBits, 0, lockrect.Pitch * Height); - } - FBTexture->UnlockRect (0); - } - } - InScene = true; - D3DDevice->BeginScene(); - D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines); - assert(OldRenderTarget == NULL); - if (TempRenderTexture != NULL && - ((Windowed && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling)) - { - IDirect3DSurface9 *targetsurf; - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf))) - { - if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget))) - { - if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf))) - { - // Setting the render target failed. - } - } - targetsurf->Release(); - } - } - - SetTexture(0, FBTexture); - SetPaletteTexture(PaletteTexture, 256, BorderColor); - D3DDevice->SetFVF (D3DFVF_FBVERTEX); - memset(Constant, 0, sizeof(Constant)); - SetAlphaBlend(D3DBLENDOP(0)); - EnableAlphaTest(FALSE); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor]); - else - SetPixelShader(Shaders[SHADER_NormalColorPal]); - if (copy3d) - { - FBVERTEX verts[4]; - D3DCOLOR color0, color1; - auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); - if (map == NULL) - { - color0 = 0; - color1 = 0xFFFFFFF; - } - else - { - color0 = D3DCOLOR_COLORVALUE(map->ColorizeStart[0]/2, map->ColorizeStart[1]/2, map->ColorizeStart[2]/2, 0); - color1 = D3DCOLOR_COLORVALUE(map->ColorizeEnd[0]/2, map->ColorizeEnd[1]/2, map->ColorizeEnd[2]/2, 1); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_SpecialColormap]); - else - SetPixelShader(Shaders[SHADER_SpecialColormapPal]); - } - CalcFullscreenCoords(verts, true, false, color0, color1); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - } - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor]); - else - SetPixelShader(Shaders[SHADER_NormalColorPal]); -} - -//========================================================================== -// -// D3DFB :: DrawLetterbox -// -// Draws the black bars at the top and bottom of the screen for letterboxed -// modes. -// -//========================================================================== - -void D3DFB::DrawLetterbox() -{ - if (LBOffsetI != 0) - { - D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } }; - D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0); - } -} - -//========================================================================== -// -// D3DFB :: DoWindowedGamma -// -// Draws the render target texture to the real back buffer using a gamma- -// correcting pixel shader. -// -//========================================================================== - -void D3DFB::DoWindowedGamma() -{ - if (OldRenderTarget != NULL) - { - FBVERTEX verts[4]; - - CalcFullscreenCoords(verts, false, true, 0, 0xFFFFFFFF); - D3DDevice->SetRenderTarget(0, OldRenderTarget); - D3DDevice->SetFVF(D3DFVF_FBVERTEX); - SetTexture(0, TempRenderTexture); - SetPixelShader(Windowed && GammaShader ? GammaShader : Shaders[SHADER_NormalColor]); - SetAlphaBlend(D3DBLENDOP(0)); - EnableAlphaTest(FALSE); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - OldRenderTarget->Release(); - OldRenderTarget = NULL; - } -} - -//========================================================================== -// -// D3DFB :: UpdateGammaTexture -// -// Updates the gamma texture used by the PS14 shader. We only use the first -// half of the texture so that we needn't worry about imprecision causing -// it to grab from the border. -// -//========================================================================== - -void D3DFB::UpdateGammaTexture(float igamma) -{ - D3DLOCKED_RECT lockrect; - - if (GammaTexture != NULL && SUCCEEDED(GammaTexture->LockRect(0, &lockrect, NULL, 0))) - { - uint8_t *pix = (uint8_t *)lockrect.pBits; - for (int i = 0; i <= 128; ++i) - { - pix[i*4+2] = pix[i*4+1] = pix[i*4] = uint8_t(255.f * powf(i / 128.f, igamma)); - pix[i*4+3] = 255; - } - GammaTexture->UnlockRect(0); - } -} - -void D3DFB::UploadPalette () -{ - D3DLOCKED_RECT lockrect; - - if (SUCCEEDED(PaletteTexture->LockRect(0, &lockrect, NULL, 0))) - { - uint8_t *pix = (uint8_t *)lockrect.pBits; - int i; - - for (i = 0; i < 256; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = (i == 0 ? 0 : 255); - // To let masked textures work, the first palette entry's alpha is 0. - } - PaletteTexture->UnlockRect(0); - BorderColor = D3DCOLOR_XRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b); - } -} - -PalEntry *D3DFB::GetPalette () -{ - return SourcePalette; -} - -void D3DFB::UpdatePalette () -{ - NeedPalUpdate = true; -} - -bool D3DFB::SetGamma (float gamma) -{ - LOG1 ("SetGamma %g\n", gamma); - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool D3DFB::SetFlash (PalEntry rgb, int amount) -{ - FlashColor = rgb; - FlashAmount = amount; - - // Fill in the constants for the pixel shader to do linear interpolation between the palette and the flash: - float r = rgb.r / 255.f, g = rgb.g / 255.f, b = rgb.b / 255.f, a = amount / 256.f; - FlashColor0 = D3DCOLOR_COLORVALUE(r * a, g * a, b * a, 0); - a = 1 - a; - FlashColor1 = D3DCOLOR_COLORVALUE(a, a, a, 1); - return true; -} - -void D3DFB::GetFlash (PalEntry &rgb, int &amount) -{ - rgb = FlashColor; - amount = FlashAmount; -} - -void D3DFB::GetFlashedPalette (PalEntry pal[256]) -{ - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending (pal, pal, 256, FlashColor.r, FlashColor.g, FlashColor.b, FlashAmount); - } -} - -void D3DFB::SetVSync (bool vsync) -{ - if (VSync != vsync) - { - VSync = vsync; - Reset(); - } -} - -void D3DFB::NewRefreshRate () -{ - if (!Windowed) - { - Reset(); - } -} - -void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2) -{ - BlendingRect.left = x1; - BlendingRect.top = y1; - BlendingRect.right = x2; - BlendingRect.bottom = y2; -} - -//========================================================================== -// -// D3DFB :: GetScreenshotBuffer -// -// Returns a pointer into a surface holding the current screen data. -// -//========================================================================== - -void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) -{ - D3DLOCKED_RECT lrect; - - buffer = NULL; - if ((ScreenshotTexture = GetCurrentScreen()) != NULL) - { - if (FAILED(ScreenshotTexture->GetSurfaceLevel(0, &ScreenshotSurface))) - { - ScreenshotTexture->Release(); - ScreenshotTexture = NULL; - } - else if (FAILED(ScreenshotSurface->LockRect(&lrect, NULL, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) - { - ScreenshotSurface->Release(); - ScreenshotSurface = NULL; - ScreenshotTexture->Release(); - ScreenshotTexture = NULL; - } - else - { - buffer = (const uint8_t *)lrect.pBits; - pitch = lrect.Pitch; - color_type = SS_BGRA; - gamma = Gamma; - } - } -} - -//========================================================================== -// -// D3DFB :: ReleaseScreenshotBuffer -// -//========================================================================== - -void D3DFB::ReleaseScreenshotBuffer() -{ - if (ScreenshotSurface != NULL) - { - ScreenshotSurface->UnlockRect(); - ScreenshotSurface->Release(); - ScreenshotSurface = NULL; - } - SAFE_RELEASE( ScreenshotTexture ); -} - -//========================================================================== -// -// D3DFB :: GetCurrentScreen -// -// Returns a texture containing the pixels currently visible on-screen. -// -//========================================================================== - -IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool) -{ - IDirect3DTexture9 *tex; - IDirect3DSurface9 *surf; - D3DSURFACE_DESC desc; - HRESULT hr; - - assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT); - - if (FrontCopySurface == NULL || FAILED(FrontCopySurface->GetDesc(&desc))) - { - return NULL; - } - if (pool == D3DPOOL_SYSTEMMEM) - { - hr = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL); - } - else - { - hr = D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &tex, NULL); - } - if (FAILED(hr)) - { - return NULL; - } - if (FAILED(tex->GetSurfaceLevel(0, &surf))) - { - tex->Release(); - return NULL; - } - if (pool == D3DPOOL_SYSTEMMEM) - { - // Video -> System memory : use GetRenderTargetData - hr = D3DDevice->GetRenderTargetData(FrontCopySurface, surf); - } - else - { - // Video -> Video memory : use StretchRect - RECT destrect = { 0, 0, Width, Height }; - hr = D3DDevice->StretchRect(FrontCopySurface, NULL, surf, &destrect, D3DTEXF_POINT); - } - surf->Release(); - if (FAILED(hr)) - { - tex->Release(); - return NULL; - } - return tex; -} - -/**************************************************************************/ -/* 2D Stuff */ -/**************************************************************************/ - - -//========================================================================== -// -// D3DTex Constructor -// -//========================================================================== - -D3DTex::D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping) - : FNativeTexture(tex, fmt) -{ - // Attach to the texture list for the D3DFB - Next = fb->Textures; - if (Next != NULL) - { - Next->Prev = &Next; - } - Prev = &fb->Textures; - fb->Textures = this; - - IsGray = false; - Format = GetTexFormat(); - - Create(fb, wrapping); -} - -//========================================================================== -// -// D3DTex Destructor -// -//========================================================================== - -D3DTex::~D3DTex() -{ - // Detach from the texture list - *Prev = Next; - if (Next != NULL) - { - Next->Prev = Prev; - } - SAFE_RELEASE(Tex); - -} - -//========================================================================== -// -// D3DTex :: CheckWrapping -// -// Returns true if the texture is compatible with the specified wrapping -// mode. -// -//========================================================================== - -bool D3DTex::CheckWrapping(bool wrapping) -{ - return true; // we no longer use atlases -} - -//========================================================================== -// -// D3DTex :: Create -// -// Creates an IDirect3DTexture9 for the texture and copies the image data -// to it. Note that unlike FTexture, this image is row-major. -// -//========================================================================== - -bool D3DTex::Create(D3DFB *fb, bool wrapping) -{ - if (SUCCEEDED(fb->D3DDevice->CreateTexture(mGameTex->GetWidth(), mGameTex->GetHeight(), 1, 0, Format, D3DPOOL_MANAGED, &Tex, NULL))) - { - return Update(); - } - return false; -} - -//========================================================================== -// -// D3DTex :: Update -// -// Copies image data from the underlying FTexture to the D3D texture. -// -//========================================================================== - -bool D3DTex::Update() -{ - D3DSURFACE_DESC desc; - D3DLOCKED_RECT lrect; - RECT rect; - uint8_t *dest; - - assert(mGameTex != NULL); - - if (FAILED(Tex->GetLevelDesc(0, &desc))) - { - return false; - } - rect = { 0, 0, (LONG)desc.Width, (LONG)desc.Height }; - if (FAILED(Tex->LockRect(0, &lrect, &rect, 0))) - { - return false; - } - dest = (uint8_t *)lrect.pBits; - - mGameTex->FillBuffer(dest, lrect.Pitch, mGameTex->GetHeight(), mFormat); - Tex->UnlockRect(0); - return true; -} - -//========================================================================== -// -// D3DTex :: GetTexFormat -// -// Returns the texture format that would best fit this texture. -// -//========================================================================== - -D3DFORMAT D3DTex::GetTexFormat() -{ - IsGray = false; - - switch (mFormat) - { - case TEX_Pal: return D3DFMT_L8; - case TEX_Gray: IsGray = true; return D3DFMT_L8; - case TEX_RGB: return D3DFMT_A8R8G8B8; - default: I_FatalError ("GameTex->GetFormat() returned invalid format."); - } - return D3DFMT_A8R8G8B8; -} - -//========================================================================== -// -// D3DPal Constructor -// -//========================================================================== - -D3DPal::D3DPal(FRemapTable *remap, D3DFB *fb) - : Tex(NULL), Remap(remap) -{ - int count; - - // Attach to the palette list for the D3DFB - Next = fb->Palettes; - if (Next != NULL) - { - Next->Prev = &Next; - } - Prev = &fb->Palettes; - fb->Palettes = this; - - int pow2count; - - // Round up to the nearest power of 2. - for (pow2count = 1; pow2count < remap->NumEntries; pow2count <<= 1) - { } - count = pow2count; - BorderColor = 0; - RoundedPaletteSize = count; - if (SUCCEEDED(fb->D3DDevice->CreateTexture(count, 1, 1, 0, - D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Tex, NULL))) - { - if (!Update()) - { - Tex->Release(); - Tex = NULL; - } - } -} - -//========================================================================== -// -// D3DPal Destructor -// -//========================================================================== - -D3DPal::~D3DPal() -{ - SAFE_RELEASE( Tex ); - // Detach from the palette list - *Prev = Next; - if (Next != NULL) - { - Next->Prev = Prev; - } - // Remove link from the remap table - if (Remap != NULL) - { - Remap->Native = NULL; - } -} - -//========================================================================== -// -// D3DPal :: Update -// -// Copies the palette to the texture. -// -//========================================================================== - -bool D3DPal::Update() -{ - D3DLOCKED_RECT lrect; - - assert(Tex != NULL); - - if (FAILED(Tex->LockRect(0, &lrect, NULL, 0))) - { - return false; - } - auto buff = (D3DCOLOR *)lrect.pBits; - auto pal = Remap->Palette; - - auto maxidx = MIN(Remap->NumEntries, 256); - - for (int i = 0; i < maxidx; ++i) - { - buff[i] = D3DCOLOR_ARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b); - } - BorderColor = D3DCOLOR_ARGB(pal[maxidx].a, pal[maxidx-1].r, pal[maxidx-1].g, pal[maxidx-1].b); - - Tex->UnlockRect(0); - return true; -} - -//========================================================================== -// -// D3DFB :: Begin2D -// -// Begins 2D mode drawing operations. In particular, DrawTexture is -// rerouted to use Direct3D instead of the software renderer. -// -//========================================================================== - -bool D3DFB::Begin2D(bool copy3d) -{ - Super::Begin2D(copy3d); - if (In2D) - { - return true; - } - In2D = 2 - copy3d; - Update(); - In2D = 3; - - return true; -} - -//========================================================================== -// -// D3DFB :: DrawBlendingRect -// -// Call after Begin2D to blend the 3D view. -// -//========================================================================== - -void D3DFB::DrawBlendingRect() -{ - Dim(FlashColor, FlashAmount / 256.f, viewwindowx, viewwindowy, viewwidth, viewheight); -} - -//========================================================================== -// -// D3DFB :: CreateTexture -// -// Returns a native texture that wraps a FTexture. -// -//========================================================================== - -FNativeTexture *D3DFB::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - D3DTex *tex = new D3DTex(gametex, fmt, this, wrapping); - return tex; -} - -//========================================================================== -// -// D3DFB :: CreatePalette -// -// Returns a native texture that contains a palette. -// -//========================================================================== - -FNativePalette *D3DFB::CreatePalette(FRemapTable *remap) -{ - D3DPal *tex = new D3DPal(remap, this); - if (tex->Tex == NULL) - { - delete tex; - return NULL; - } - return tex; -} - -//========================================================================== -// -// D3DFB :: Draw2D -// -//========================================================================== - -static D3DBLENDOP OpToD3D(int op) -{ - switch (op) - { - // STYLEOP_None can never get here. - default: - return D3DBLENDOP_ADD; - case STYLEOP_Sub: - return D3DBLENDOP_SUBTRACT; - case STYLEOP_RevSub: - return D3DBLENDOP_REVSUBTRACT; - } -} - - -void D3DFB::Draw2D() -{ - auto &vertices = m2DDrawer.mVertices; - auto &indices = m2DDrawer.mIndices; - auto &commands = m2DDrawer.mData; - - auto vc = vertices.Size(); - auto ic = indices.Size(); - if (vc > NumVertices || ic > NumIndices) - { - // We got more vertices than the current buffer can take so resize it. - if (!CreateVertexes(MAX(vc, NumVertices), MAX(ic, NumIndices))) - { - I_FatalError("Unable to resize vertex buffer"); - } - } - IndexBuffer->Lock(0, 0, (void **)&IndexData, D3DLOCK_DISCARD); - memcpy(IndexData, &indices[0], sizeof(*IndexData) * ic); - IndexBuffer->Unlock(); - VertexBuffer->Lock(0, 0, (void **)&VertexData, D3DLOCK_DISCARD); - auto yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; - - for (auto &vt : vertices) - { - VertexData->x = vt.x; - VertexData->y = vt.y + yoffs; - VertexData->z = vt.z; - VertexData->rhw = 1; - VertexData->color0 = vt.color0; - VertexData->color1 = 0; - VertexData->tu = vt.u; - VertexData->tv = vt.v; - } - VertexBuffer->Unlock(); - D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); - D3DDevice->SetIndices(IndexBuffer); - - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - bool uv_wrapped = false; - bool scissoring = false; - EnableAlphaTest(true); - - for (auto &cmd : commands) - { - //Set blending mode - SetAlphaBlend(OpToD3D(cmd.mRenderStyle.BlendOp), GetStyleAlpha(cmd.mRenderStyle.SrcAlpha), GetStyleAlpha(cmd.mRenderStyle.DestAlpha)); - int index = -1; - - if (cmd.mTexture == nullptr) - { - index = SHADER_VertexColor; - } - else - { - // set texture wrapping - bool uv_should_wrap = !!(cmd.mFlags & F2DDrawer::DTF_Wrap); - if (uv_wrapped != uv_should_wrap) - { - DWORD mode = uv_should_wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_BORDER; - uv_wrapped = uv_should_wrap; - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mode); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mode); - } - - auto textype = cmd.mTexture->GetFormat(); // This never returns TEX_Gray. - if (cmd.mTranslation) textype = TEX_Pal; // Translation requires a paletted texture, regardless of the source format. - - if (cmd.mSpecialColormap != nullptr) - { - index = textype == TEX_Pal ? SHADER_SpecialColormapPal : SHADER_SpecialColormap; - SetConstant(PSCONST_Color1, cmd.mSpecialColormap->ColorizeStart[0] / 2.f, cmd.mSpecialColormap->ColorizeStart[1] / 2.f, cmd.mSpecialColormap->ColorizeStart[2] / 2.f, 0); - SetConstant(PSCONST_Color2, cmd.mSpecialColormap->ColorizeEnd[0] / 2.f, cmd.mSpecialColormap->ColorizeEnd[1] / 2.f, cmd.mSpecialColormap->ColorizeEnd[2] / 2.f, 0); - } - else - { - SetConstant(PSCONST_Desaturation, cmd.mDesaturate / 255.f, (255 - cmd.mDesaturate) / 255.f, 0, 0); - SetConstant(PSCONST_Color1, cmd.mColor1.r / 255.f, cmd.mColor1.g / 255.f, cmd.mColor1.b / 255.f, 0); - switch (cmd.mDrawMode) - { - default: - case F2DDrawer::DTM_Normal: - if (cmd.mDesaturate) index = textype == TEX_Pal ? SHADER_NormalColorPalD : SHADER_NormalColorD; - else index = textype == TEX_Pal ? SHADER_NormalColorPal : SHADER_NormalColor; - break; - - case F2DDrawer::DTM_Invert: - index = textype == TEX_Pal ? SHADER_NormalColorPalInv : SHADER_NormalColorInv; - break; - - case F2DDrawer::DTM_InvertOpaque: - index = textype == TEX_Pal ? SHADER_NormalColorPalInvOpaq : SHADER_NormalColorInvOpaq; - break; - - case F2DDrawer::DTM_AlphaTexture: - index = textype == TEX_Pal ? SHADER_PalAlphaTex : SHADER_AlphaTex; - break; - - case F2DDrawer::DTM_Opaque: - index = textype == TEX_Pal ? SHADER_NormalColorPalOpaq : SHADER_NormalColorOpaq; - break; - - case F2DDrawer::DTM_Stencil: - index = textype == TEX_Pal ? SHADER_PalStencil : SHADER_Stencil; - break; - - } - } - - auto tex = cmd.mTexture; - D3DTex *d3dtex = static_cast(tex->GetNative(textype, uv_should_wrap)); - if (d3dtex == nullptr) continue; - SetTexture(0, d3dtex->Tex); - - if (textype == TEX_Pal) - { - if (!cmd.mTranslation) - { - SetPaletteTexture(PaletteTexture, 256, BorderColor); - } - else - { - auto ptex = static_cast(cmd.mTranslation->GetNative()); - if (ptex != nullptr) - { - SetPaletteTexture(ptex->Tex, ptex->RoundedPaletteSize, ptex->BorderColor); - } - } - } - } - if (index == -1) continue; - SetPixelShader(Shaders[index]); - - if (cmd.mFlags & F2DDrawer::DTF_Scissor) - { - scissoring = true; - RECT scissor = { cmd.mScissor[0], cmd.mScissor[1] + LBOffsetI, cmd.mScissor[2], cmd.mScissor[3] + LBOffsetI }; - D3DDevice->SetScissorRect(&scissor); - D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - } - else if (scissoring) D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); - - switch (cmd.mType) - { - case F2DDrawer::DrawTypeTriangles: - D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, cmd.mVertIndex, cmd.mVertCount, cmd.mIndexIndex, cmd.mIndexCount / 3); - break; - - case F2DDrawer::DrawTypeLines: - D3DDevice->DrawPrimitive(D3DPT_LINELIST, cmd.mVertIndex, cmd.mVertCount); - break; - - case F2DDrawer::DrawTypePoints: - D3DDevice->DrawPrimitive(D3DPT_POINTLIST, cmd.mVertIndex, cmd.mVertCount); - break; - - } - } - if (uv_wrapped) - { - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - } -} - -//========================================================================== -// -// D3DFB :: CheckQuadBatch -// -// Make sure there's enough room in the batch for one more set of triangles. -// -//========================================================================== - -void D3DFB::CheckQuadBatch(int numtris, int numverts) -{ - if (QuadBatchPos == MAX_QUAD_BATCH || - VertexPos + numverts > NUM_VERTS || - IndexPos + numtris * 3 > NUM_INDEXES) - { - EndQuadBatch(); - } - if (QuadBatchPos < 0) - { - BeginQuadBatch(); - } -} - -//========================================================================== -// -// D3DFB :: BeginQuadBatch -// -// Locks the vertex buffer for quads and sets the cursor to 0. -// -//========================================================================== - -void D3DFB::BeginQuadBatch() -{ - if (In2D < 2 || !InScene || QuadBatchPos >= 0) - { - return; - } - VertexBuffer->Lock(0, 0, (void **)&VertexData, D3DLOCK_DISCARD); - IndexBuffer->Lock(0, 0, (void **)&IndexData, D3DLOCK_DISCARD); - VertexPos = 0; - IndexPos = 0; - QuadBatchPos = 0; - BatchType = BATCH_Quads; -} - -//========================================================================== -// -// D3DFB :: EndQuadBatch -// -// Draws all the quads that have been batched up. -// This is still needed by the wiper and has been stripped off everything unneeded. -// -//========================================================================== - -void D3DFB::EndQuadBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Quads) - { - return; - } - BatchType = BATCH_None; - VertexBuffer->Unlock(); - IndexBuffer->Unlock(); - if (QuadBatchPos == 0) - { - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; - return; - } - D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); - D3DDevice->SetIndices(IndexBuffer); - int indexpos, vertpos; - - indexpos = vertpos = 0; - for (int i = 0; i < QuadBatchPos; ) - { - const BufferedTris *quad = &QuadExtra[i]; - int j; - - int startindex = indexpos; - int startvertex = vertpos; - - indexpos += quad->NumTris * 3; - vertpos += quad->NumVerts; - - // Quads with matching parameters should be done with a single - // DrawPrimitive call. - for (j = i + 1; j < QuadBatchPos; ++j) - { - const BufferedTris *q2 = &QuadExtra[j]; - if (quad->Texture != q2->Texture || - quad->Group1 != q2->Group1 || - quad->Palette != q2->Palette) - { - break; - } - indexpos += q2->NumTris * 3; - vertpos += q2->NumVerts; - } - - // Set the alpha blending - SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO); - - // Set the alpha test - EnableAlphaTest(false); - - SetPixelShader(Shaders[SHADER_NormalColor]); - - // Set the texture - if (quad->Texture != NULL) - { - SetTexture(0, quad->Texture); - } - - // Draw the quad - D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, - startvertex, // MinIndex - vertpos - startvertex, // NumVertices - startindex, // StartIndex - (indexpos - startindex) / 3 // PrimitiveCount - /*4 * i, 4 * (j - i), 6 * i, 2 * (j - i)*/); - i = j; - } - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; -} - -//========================================================================== -// -// D3DFB :: EndBatch -// -// Draws whichever type of primitive is currently being batched. -// -//========================================================================== - -D3DBLEND D3DFB::GetStyleAlpha(int type) -{ - switch (type) - { - case STYLEALPHA_Zero: return D3DBLEND_ZERO; - case STYLEALPHA_One: return D3DBLEND_ONE; - case STYLEALPHA_Src: return D3DBLEND_SRCALPHA; - case STYLEALPHA_InvSrc: return D3DBLEND_INVSRCALPHA; - default: return D3DBLEND_ZERO; - } -} - - -void D3DFB::EnableAlphaTest(BOOL enabled) -{ - if (enabled != AlphaTestEnabled) - { - AlphaTestEnabled = enabled; - D3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, enabled); - } -} - -void D3DFB::SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend, D3DBLEND destblend) -{ - if (op == 0) - { // Disable alpha blend - if (AlphaBlendEnabled) - { - AlphaBlendEnabled = FALSE; - D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - else - { // Enable alpha blend - assert(srcblend != 0); - assert(destblend != 0); - - if (!AlphaBlendEnabled) - { - AlphaBlendEnabled = TRUE; - D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - } - if (AlphaBlendOp != op) - { - AlphaBlendOp = op; - D3DDevice->SetRenderState(D3DRS_BLENDOP, op); - } - if (AlphaSrcBlend != srcblend) - { - AlphaSrcBlend = srcblend; - D3DDevice->SetRenderState(D3DRS_SRCBLEND, srcblend); - } - if (AlphaDestBlend != destblend) - { - AlphaDestBlend = destblend; - D3DDevice->SetRenderState(D3DRS_DESTBLEND, destblend); - } - } -} - -void D3DFB::SetConstant(int cnum, float r, float g, float b, float a) -{ - if (Constant[cnum][0] != r || - Constant[cnum][1] != g || - Constant[cnum][2] != b || - Constant[cnum][3] != a) - { - Constant[cnum][0] = r; - Constant[cnum][1] = g; - Constant[cnum][2] = b; - Constant[cnum][3] = a; - D3DDevice->SetPixelShaderConstantF(cnum, Constant[cnum], 1); - } -} - -void D3DFB::SetPixelShader(IDirect3DPixelShader9 *shader) -{ - if (CurPixelShader != shader) - { - CurPixelShader = shader; - D3DDevice->SetPixelShader(shader); - } -} - -void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] != texture) - { - Texture[tnum] = texture; - D3DDevice->SetTexture(tnum, texture); - } -} - -void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color) -{ - // The pixel shader receives color indexes in the range [0.0,1.0]. - // The palette texture is also addressed in the range [0.0,1.0], - // HOWEVER the coordinate 1.0 is the right edge of the texture and - // not actually the texture itself. We need to scale and shift - // the palette indexes so they lie exactly in the center of each - // texel. For a normal palette with 256 entries, that means the - // range we use should be [0.5,255.5], adjusted so the coordinate - // is still within [0.0,1.0]. - // - // The constant register c2 is used to hold the multiplier in the - // x part and the adder in the y part. - float fcount = 1 / float(count); - SetConstant(PSCONST_PaletteMod, 255 * fcount, 0.5f * fcount, 0, 0); - SetTexture(1, texture); -} - diff --git a/src/win32/fb_d3d9_wipe.cpp b/src/win32/fb_d3d9_wipe.cpp deleted file mode 100644 index e7f1f1307..000000000 --- a/src/win32/fb_d3d9_wipe.cpp +++ /dev/null @@ -1,627 +0,0 @@ -/* -** fb_d3d9_wipe.cpp -** Implements the different screen wipes using Direct3D calls. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#define DIRECT3D_VERSION 0x0900 -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include - -#include "doomtype.h" -#include "f_wipe.h" -#include "win32iface.h" -#include "win32swiface.h" -#include "templates.h" -#include "m_random.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -class D3DFB::Wiper_Crossfade : public D3DFB::Wiper -{ -public: - Wiper_Crossfade(); - bool Run(int ticks, D3DFB *fb); - -private: - int Clock; -}; - -class D3DFB::Wiper_Melt : public D3DFB::Wiper -{ -public: - Wiper_Melt(); - bool Run(int ticks, D3DFB *fb); - -private: - // Match the strip sizes that oldschool Doom used. - static const int WIDTH = 160, HEIGHT = 200; - int y[WIDTH]; -}; - -class D3DFB::Wiper_Burn : public D3DFB::Wiper -{ -public: - Wiper_Burn(D3DFB *fb); - ~Wiper_Burn(); - bool Run(int ticks, D3DFB *fb); - -private: - static const int WIDTH = 64, HEIGHT = 64; - uint8_t BurnArray[WIDTH * (HEIGHT + 5)]; - IDirect3DTexture9 *BurnTexture; - int Density; - int BurnTime; - - struct BURNVERTEX - { - FLOAT x, y, z, rhw; - FLOAT tu0, tv0; - FLOAT tu1, tv1; - }; -#define D3DFVF_BURNVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX2) -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: WipeStartScreen -// -// Called before the current screen has started rendering. This needs to -// save what was drawn the previous frame so that it can be animated into -// what gets drawn this frame. -// -// In fullscreen mode, we use GetFrontBufferData() to grab the data that -// is visible on screen right now. -// -// In windowed mode, we can't do that because we'll get the whole desktop. -// Instead, we can conveniently use the TempRenderTexture, which is normally -// used for gamma-correcting copying the image to the back buffer. -// -//========================================================================== - -bool D3DFB::WipeStartScreen(int type) -{ - IDirect3DSurface9 *tsurf; - D3DSURFACE_DESC desc; - - switch (type) - { - case wipe_Melt: - ScreenWipe = new Wiper_Melt; - break; - - case wipe_Burn: - ScreenWipe = new Wiper_Burn(this); - break; - - case wipe_Fade: - ScreenWipe = new Wiper_Crossfade; - break; - - default: - return false; - } - - InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT); - - // Create another texture to copy the final wipe screen to so - // we can still gamma correct the wipe. Since this is just for - // gamma correction, it's okay to fail (though not desirable.) - if (PixelDoubling || Windowed) - { - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf))) - { - if (FAILED(tsurf->GetDesc(&desc)) || - FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height, - 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, - &FinalWipeScreen, NULL))) - { - (FinalWipeScreen = TempRenderTexture)->AddRef(); - } - tsurf->Release(); - } - } - else - { - (FinalWipeScreen = TempRenderTexture)->AddRef(); - } - - // Make even fullscreen model render to the TempRenderTexture, so - // we can have a copy of the new screen readily available. - GatheringWipeScreen = true; - return true; -} - -//========================================================================== -// -// D3DFB :: WipeEndScreen -// -// The screen we want to animate to has just been drawn. This function is -// called in place of Update(), so it has not been Presented yet. -// -//========================================================================== - -void D3DFB::WipeEndScreen() -{ - // Don't do anything if there is no starting point. - if (InitialWipeScreen == NULL) - { - return; - } - - // If the whole screen was drawn without 2D accel, get it in to - // video memory now. - if (!In2D) - { - Begin2D(true); - } - - EndQuadBatch(); // Make sure all batched primitives have been drawn. - - // Don't do anything if there is no ending point. - if (OldRenderTarget == NULL) - { - return; - } - - // If these are different, reverse their roles so we don't need to - // waste time copying from TempRenderTexture to FinalWipeScreen. - if (FinalWipeScreen != TempRenderTexture) - { - swapvalues(RenderTexture[CurrRenderTexture], FinalWipeScreen); - TempRenderTexture = RenderTexture[CurrRenderTexture]; - } - - // At this point, InitialWipeScreen holds the screen we are wiping from. - // FinalWipeScreen holds the screen we are wiping to, which may be the - // same texture as TempRenderTexture. -} - -//========================================================================== -// -// D3DFB :: WipeDo -// -// Perform the actual wipe animation. The number of tics since the last -// time this function was called is passed in. Returns true when the wipe -// is over. The first time this function has been called, the screen is -// still locked from before and EndScene() still has not been called. -// Successive times need to call BeginScene(). -// -//========================================================================== - -bool D3DFB::WipeDo(int ticks) -{ - // Sanity checks. - if (InitialWipeScreen == NULL || FinalWipeScreen == NULL) - { - return true; - } - if (GatheringWipeScreen) - { // This is the first time we've been called for this wipe. - GatheringWipeScreen = false; - - if (OldRenderTarget == NULL) - { - return true; - } - D3DDevice->SetRenderTarget(0, OldRenderTarget); - } - else - { // This is the second or later time we've been called for this wipe. - D3DDevice->BeginScene(); - InScene = true; - } - SAFE_RELEASE( OldRenderTarget ); - if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen) - { - IDirect3DSurface9 *targetsurf; - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf))) - { - if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget))) - { - if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf))) - { - // Setting the render target failed. - } - } - targetsurf->Release(); - } - } - In2D = 3; - - EnableAlphaTest(FALSE); - bool done = ScreenWipe->Run(ticks, this); - DrawLetterbox(); - return done; -} - -//========================================================================== -// -// D3DFB :: WipeCleanup -// -// Release any resources that were specifically created for the wipe. -// -//========================================================================== - -void D3DFB::WipeCleanup() -{ - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - SAFE_RELEASE( InitialWipeScreen ); - SAFE_RELEASE( FinalWipeScreen ); - GatheringWipeScreen = false; -} - -//========================================================================== -// -// D3DFB :: Wiper Constructor -// -//========================================================================== - -D3DFB::Wiper::~Wiper() -{ -} - -//========================================================================== -// -// D3DFB :: Wiper :: DrawScreen -// -// Draw either the initial or target screen completely to the screen. -// -//========================================================================== - -void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex, - D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1) -{ - FBVERTEX verts[4]; - - fb->CalcFullscreenCoords(verts, false, false, color0, color1); - fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); - fb->SetTexture(0, tex); - fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]); - fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); -} - -// WIPE: CROSSFADE --------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Crossfade Constructor -// -//========================================================================== - -D3DFB::Wiper_Crossfade::Wiper_Crossfade() -: Clock(0) -{ -} - -//========================================================================== -// -// D3DFB :: Wiper_Crossfade :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb) -{ - Clock += ticks; - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen); - - // Draw the new screen on top of it. - DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD, - D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0)); - - return Clock >= 32; -} - -// WIPE: MELT -------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Melt Constructor -// -//========================================================================== - -D3DFB::Wiper_Melt::Wiper_Melt() -{ - int i, r; - - // setup initial column positions - // (y<0 => not ready to scroll yet) - y[0] = -(M_Random() & 15); - for (i = 1; i < WIDTH; ++i) - { - r = (M_Random()%3) - 1; - y[i] = clamp(y[i-1] + r, -15, 0); - } -} - -//========================================================================== -// -// D3DFB :: Wiper_Melt :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb) -{ - // Draw the new screen on the bottom. - DrawScreen(fb, fb->FinalWipeScreen); - - int i, dy; - int fbwidth = fb->Width; - int fbheight = fb->Height; - bool done = true; - - // Copy the old screen in vertical strips on top of the new one. - while (ticks--) - { - done = true; - for (i = 0; i < WIDTH; i++) - { - if (y[i] < 0) - { - y[i]++; - done = false; - } - else if (y[i] < HEIGHT) - { - dy = (y[i] < 16) ? y[i]+1 : 8; - y[i] = MIN(y[i] + dy, HEIGHT); - done = false; - } - if (ticks == 0) - { // Only draw for the final tick. - RECT rect; - POINT dpt; - - dpt.x = i * fbwidth / WIDTH; - dpt.y = MAX(0, y[i] * fbheight / HEIGHT); - rect.left = dpt.x; - rect.top = 0; - rect.right = (i + 1) * fbwidth / WIDTH; - rect.bottom = fbheight - dpt.y; - if (rect.bottom > rect.top) - { - fb->CheckQuadBatch(); - - BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos]; - FBVERTEX *vert = &fb->VertexData[fb->VertexPos]; - uint16_t *index = &fb->IndexData[fb->IndexPos]; - - quad->Group1 = 0; - quad->Flags = BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - quad->Palette = NULL; - quad->Texture = fb->InitialWipeScreen; - quad->NumVerts = 4; - quad->NumTris = 2; - - // Fill the vertex buffer. - float u0 = rect.left / float(fb->FBWidth); - float v0 = 0; - float u1 = rect.right / float(fb->FBWidth); - float v1 = (rect.bottom - rect.top) / float(fb->FBHeight); - - float x0 = float(rect.left) - 0.5f; - float x1 = float(rect.right) - 0.5f; - float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f; - float y1 = float(fbheight + fb->LBOffsetI) - 0.5f; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - 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 = 0xFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - index[0] = fb->VertexPos; - index[1] = fb->VertexPos + 1; - index[2] = fb->VertexPos + 2; - index[3] = fb->VertexPos; - index[4] = fb->VertexPos + 2; - index[5] = fb->VertexPos + 3; - - // Batch the quad. - fb->QuadBatchPos++; - fb->VertexPos += 4; - fb->IndexPos += 6; - } - } - } - } - fb->EndQuadBatch(); - return done; -} - -// WIPE: BURN -------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Burn Constructor -// -//========================================================================== - -D3DFB::Wiper_Burn::Wiper_Burn(D3DFB *fb) -{ - Density = 4; - BurnTime = 0; - memset(BurnArray, 0, sizeof(BurnArray)); - if (fb->Shaders[SHADER_BurnWipe] == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1, - D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &BurnTexture, NULL))) - { - BurnTexture = NULL; - } -} - -//========================================================================== -// -// D3DFB :: Wiper_Burn Destructor -// -//========================================================================== - -D3DFB::Wiper_Burn::~Wiper_Burn() -{ - SAFE_RELEASE( BurnTexture ); -} - -//========================================================================== -// -// D3DFB :: Wiper_Burn :: Run -// -//========================================================================== - -bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb) -{ - bool done; - - BurnTime += ticks; - ticks *= 2; - - // Make the fire burn - done = false; - while (!done && ticks--) - { - Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); - done = (Density < 0); - } - - // Update the burn texture with the new burn data - D3DLOCKED_RECT lrect; - if (SUCCEEDED(BurnTexture->LockRect(0, &lrect, NULL, D3DLOCK_DISCARD))) - { - const uint8_t *src = BurnArray; - uint8_t *dest = (uint8_t *)lrect.pBits; - for (int y = HEIGHT; y != 0; --y) - { - for (int x = WIDTH; x != 0; --x) - { - *dest++ = *src++; - } - dest += lrect.Pitch - WIDTH; - } - BurnTexture->UnlockRect(0); - } - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen); - - // Burn the new screen on top of it. - float top = fb->LBOffset - 0.5f; - float right = float(fb->Width) - 0.5f; - float bot = float(fb->Height) + top; - float texright = float(fb->Width) / float(fb->FBWidth); - float texbot = float(fb->Height) / float(fb->FBHeight); - - BURNVERTEX verts[4] = - { - { -0.5f, top, 0.5f, 1.f, 0.f, 0.f, 0, 0 }, - { right, top, 0.5f, 1.f, texright, 0.f, 1, 0 }, - { right, bot, 0.5f, 1.f, texright, texbot, 1, 1 }, - { -0.5f, bot, 0.5f, 1.f, 0.f, texbot, 0, 1 } - }; - - fb->D3DDevice->SetFVF(D3DFVF_BURNVERTEX); - fb->SetTexture(0, fb->FinalWipeScreen); - fb->SetTexture(1, BurnTexture); - fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(BURNVERTEX)); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); - - // The fire may not always stabilize, so the wipe is forced to end - // after an arbitrary maximum time. - return done || (BurnTime > 40); -} diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index 22449988c..58882748c 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -178,13 +178,7 @@ void I_InitGraphics () val.Bool = !!Args->CheckParm ("-devparm"); ticker.SetGenericRepDefault (val, CVAR_Bool); - if (currentcanvas == 0) // Software Canvas: 0 = D3D or DirectDraw, 1 = OpenGL - if (currentrenderer == 1) - Video = gl_CreateVideo(); - else - Video = new Win32Video(0); - else - Video = gl_CreateVideo(); + Video = gl_CreateVideo(); if (Video == NULL) I_FatalError ("Failed to initialize display"); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index d66a44847..fa72310e7 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -58,7 +58,6 @@ #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" -#include "gl/system/gl_swframebuffer.h" extern HWND Window; extern BOOL AppActive; @@ -501,10 +500,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra, //old->GetFlash(flashColor, flashAmount); delete old; } - if (vid_renderer == 1) - fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs); - else - fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs, bgra); + fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs); return fb; } diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 72ed51ab0..7128b9c25 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -39,64 +39,8 @@ EXTERN_CVAR (Bool, vid_vsync) -class D3DTex; -class D3DPal; struct FSoftwareRenderer; -class Win32Video : public IVideo -{ - public: - Win32Video (int parm); - ~Win32Video (); - - bool InitD3D9(); - - EDisplayType GetDisplayType () { return DISPLAY_Both; } - void SetWindowedScale (float scale); - - DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old); - - void StartModeIterator (int bits, bool fs); - bool NextMode (int *width, int *height, bool *letterbox); - - bool GoFullscreen (bool yes); - - void DumpAdapters (); - void AddMode(int x, int y, int bits, int baseHeight, int doubling); - - private: - struct ModeInfo - { - ModeInfo (int inX, int inY, int inBits, int inRealY, int inDoubling) - : next (NULL), - width (inX), - height (inY), - bits (inBits), - realheight (inRealY), - doubling (inDoubling) - {} - - ModeInfo *next; - int width, height, bits; - int realheight; - int doubling; - } *m_Modes; - - ModeInfo *m_IteratorMode; - int m_IteratorBits; - bool m_IteratorFS; - bool m_IsFullscreen; - unsigned int m_Adapter; - - void FreeModes (); - - void AddD3DModes (unsigned adapter); - void AddLowResModes (); - void AddLetterboxModes (); - void ScaleModes (int doubling); - - friend class D3DFB; -}; class BaseWinFB : public DFrameBuffer { diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h deleted file mode 100644 index 099441736..000000000 --- a/src/win32/win32swiface.h +++ /dev/null @@ -1,304 +0,0 @@ -#pragma once - -#ifndef DIRECTDRAW_VERSION -#define DIRECTDRAW_VERSION 0x0300 -#endif -#ifndef DIRECT3D_VERSION -#define DIRECT3D_VERSION 0x0900 -#endif - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#define SAFE_RELEASE(x) { if (x != NULL) { x->Release(); x = NULL; } } - -extern HANDLE FPSLimitEvent; - - -class D3DFB : public BaseWinFB -{ - typedef BaseWinFB Super; - - DSimpleCanvas *RenderBuffer = nullptr; - -public: - D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen); - ~D3DFB (); - virtual DCanvas *GetCanvas() { return RenderBuffer; } - - void Update (); - void Flip (); - PalEntry *GetPalette (); - void GetFlashedPalette (PalEntry palette[256]); - void UpdatePalette (); - bool SetGamma (float gamma); - bool SetFlash (PalEntry rgb, int amount); - void GetFlash (PalEntry &rgb, int &amount); - int GetPageCount (); - bool IsFullscreen (); - void SetVSync (bool vsync); - void NewRefreshRate(); - void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override; - void ReleaseScreenshotBuffer(); - void SetBlendingRect (int x1, int y1, int x2, int y2); - bool Begin2D (bool copy3d); - void DrawBlendingRect (); - FNativeTexture *CreateTexture (FTexture *gametex, FTextureFormat fmt, bool wrapping); - FNativePalette *CreatePalette (FRemapTable *remap); - bool WipeStartScreen(int type); - void WipeEndScreen(); - bool WipeDo(int ticks); - void WipeCleanup(); - virtual int GetTrueHeight() { return TrueHeight; } - -private: - friend class D3DTex; - friend class D3DPal; - - struct PackedTexture; - struct Atlas; - - struct FBVERTEX - { - FLOAT x, y, z, rhw; - D3DCOLOR color0, color1; - FLOAT tu, tv; - }; -#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1) - - struct BufferedTris - { - union - { - struct - { - uint8_t Flags; - uint8_t ShaderNum:4; - uint8_t BlendOp:4; - uint8_t SrcBlend, DestBlend; - }; - DWORD Group1; - }; - uint8_t Desat; - D3DPal *Palette; - IDirect3DTexture9 *Texture; - int NumVerts; // Number of _unique_ vertices used by this set. - int NumTris; // Number of triangles used by this set. - }; - - enum - { - PSCONST_Desaturation = 1, - PSCONST_PaletteMod = 2, - PSCONST_Color1 = 3, - PSCONST_Color2 = 4, - PSCONST_BUFFERED_MAX, - PSCONST_Weights = 6, - PSCONST_Gamma = 7, - - }; - enum - { - SHADER_NormalColor, - SHADER_NormalColorPal, - SHADER_NormalColorD, - SHADER_NormalColorPalD, - SHADER_NormalColorInv, - SHADER_NormalColorPalInv, - SHADER_NormalColorOpaq, - SHADER_NormalColorPalOpaq, - SHADER_NormalColorInvOpaq, - SHADER_NormalColorPalInvOpaq, - - SHADER_AlphaTex, - SHADER_PalAlphaTex, - SHADER_Stencil, - SHADER_PalStencil, - - SHADER_VertexColor, - - SHADER_SpecialColormap, - SHADER_SpecialColormapPal, - - SHADER_BurnWipe, - SHADER_GammaCorrection, - - NUM_SHADERS - }; - static const char *const ShaderNames[NUM_SHADERS]; - - void SetInitialState(); - bool CreateResources(); - void ReleaseResources(); - bool LoadShaders(); - void CreateBlockSurfaces(); - bool CreateFBTexture(); - bool CreatePaletteTexture(); - bool CreateGammaTexture(); - bool CreateVertexes(int numv, int numi); - void UploadPalette(); - void UpdateGammaTexture(float igamma); - void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync); - void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const; - bool Reset(); - IDirect3DTexture9 *GetCurrentScreen(D3DPOOL pool=D3DPOOL_SYSTEMMEM); - void ReleaseDefaultPoolItems(); - void KillNativePals(); - void KillNativeTexs(); - PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, D3DFORMAT format); - void DrawLetterbox(); - void Draw3DPart(bool copy3d); - static D3DBLEND GetStyleAlpha(int type); - void DoWindowedGamma(); - void CheckQuadBatch(int numtris=2, int numverts=4); - void BeginQuadBatch(); - void EndQuadBatch(); - void CopyNextFrontBuffer(); - void Draw2D() override; - - D3DCAPS9 DeviceCaps; - - // State - void EnableAlphaTest(BOOL enabled); - void SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0)); - void SetConstant(int cnum, float r, float g, float b, float a); - void SetPixelShader(IDirect3DPixelShader9 *shader); - void SetTexture(int tnum, IDirect3DTexture9 *texture); - void SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color); - - BOOL AlphaTestEnabled; - BOOL AlphaBlendEnabled; - D3DBLENDOP AlphaBlendOp; - D3DBLEND AlphaSrcBlend; - D3DBLEND AlphaDestBlend; - float Constant[PSCONST_BUFFERED_MAX][4]; - D3DCOLOR CurBorderColor; - IDirect3DPixelShader9 *CurPixelShader; - IDirect3DTexture9 *Texture[5]; - - PalEntry SourcePalette[256]; - D3DCOLOR BorderColor; - D3DCOLOR FlashColor0, FlashColor1; - PalEntry FlashColor; - int FlashAmount; - int TrueHeight; - int PixelDoubling; - int SkipAt; - int LBOffsetI; - int RenderTextureToggle; - int CurrRenderTexture; - float LBOffset; - float Gamma; - bool UpdatePending; - bool NeedPalUpdate; - bool NeedGammaUpdate; - int FBWidth, FBHeight; - D3DFORMAT FBFormat; - bool VSync; - RECT BlendingRect; - int In2D; - bool InScene; - bool GatheringWipeScreen; - bool AALines; - uint8_t BlockNum; - D3DPal *Palettes; - D3DTex *Textures; - Atlas *Atlases; - HRESULT LastHR; - - UINT Adapter; - IDirect3DDevice9 *D3DDevice; - IDirect3DTexture9 *FBTexture; - IDirect3DTexture9 *TempRenderTexture, *RenderTexture[2]; - IDirect3DTexture9 *PaletteTexture; - IDirect3DTexture9 *GammaTexture; - IDirect3DTexture9 *ScreenshotTexture; - IDirect3DSurface9 *ScreenshotSurface; - IDirect3DSurface9 *FrontCopySurface; - - IDirect3DVertexBuffer9 *VertexBuffer; - FBVERTEX *VertexData; - IDirect3DIndexBuffer9 *IndexBuffer; - uint16_t *IndexData; - - // This stuff is still needed for the Wiper (which will be refactored later) - BufferedTris *QuadExtra; - int VertexPos; - int IndexPos; - int QuadBatchPos; - enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; - - unsigned int NumVertices = 0; - unsigned int NumIndices = 0; - - IDirect3DPixelShader9 *Shaders[NUM_SHADERS]; - IDirect3DPixelShader9 *GammaShader; - - IDirect3DSurface9 *BlockSurface[2]; - IDirect3DSurface9 *OldRenderTarget; - IDirect3DTexture9 *InitialWipeScreen, *FinalWipeScreen; - - D3DFB() {} - - class Wiper - { - public: - virtual ~Wiper(); - virtual bool Run(int ticks, D3DFB *fb) = 0; - - void DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex, - D3DBLENDOP blendop=D3DBLENDOP(0), D3DCOLOR color0=0, D3DCOLOR color1=0xFFFFFFF); - }; - - class Wiper_Melt; friend class Wiper_Melt; - class Wiper_Burn; friend class Wiper_Burn; - class Wiper_Crossfade; friend class Wiper_Crossfade; - - Wiper *ScreenWipe; -}; - -// Flags for a buffered quad -enum -{ - BQF_GamePalette = 1, - BQF_CustomPalette = 7, - BQF_Paletted = 7, - BQF_Bilinear = 8, - BQF_WrapUV = 16, - BQF_InvertSource = 32, - BQF_DisableAlphaTest= 64, - BQF_Desaturated = 128, -}; - -// Shaders for a buffered quad -enum -{ - BQS_PalTex, - BQS_Plain, - BQS_RedToAlpha, - BQS_ColorOnly, - BQS_SpecialColormap, - BQS_InGameColormap, -}; - -#if _DEBUG && 0 -#define STARTLOG -#define STOPLOG -#define LOG(x) { OutputDebugString(x); } -#define LOG1(x,y) { char poo[1024]; mysnprintf(poo, countof(poo), x, y); OutputDebugString(poo); } -#define LOG2(x,y,z) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z); OutputDebugString(poo); } -#define LOG3(x,y,z,zz) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, zz); OutputDebugString(poo); } -#define LOG4(x,y,z,a,b) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b); OutputDebugString(poo); } -#define LOG5(x,y,z,a,b,c) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b, c); OutputDebugString(poo); } -#else -#define STARTLOG -#define STOPLOG -#define LOG(x) -#define LOG1(x,y) -#define LOG2(x,y,z) -#define LOG3(x,y,z,zz) -#define LOG4(x,y,z,a,b) -#define LOG5(x,y,z,a,b,c) -#endif diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 20c04d4fe..936db0be0 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -68,11 +68,9 @@ #include "m_argv.h" #include "r_defs.h" #include "v_text.h" -#include "swrenderer/r_swrenderer.h" #include "version.h" #include "win32iface.h" -#include "win32swiface.h" #include "optwin32.h" @@ -80,488 +78,26 @@ // TYPES ------------------------------------------------------------------- -typedef IDirect3D9 *(WINAPI *DIRECT3DCREATE9FUNC)(UINT SDKVersion); -typedef HRESULT (WINAPI *DIRECTDRAWCREATEFUNC)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter); - // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- -void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); - // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static void StopFPSLimit(); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -extern HWND Window; -extern IVideo *Video; -extern BOOL AppActive; -extern int SessionState; -extern bool FullscreenReset; -extern bool VidResizing; - -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Bool, cl_capfps) EXTERN_CVAR(Int, vid_maxfps) // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static HMODULE D3D9_dll; static UINT FPSLimitTimer; // PUBLIC DATA DEFINITIONS ------------------------------------------------- -IDirect3D9 *D3D; -IDirect3DDevice9 *D3Device; HANDLE FPSLimitEvent; CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -#if VID_FILE_DEBUG -FILE *dbg; -#endif - -// CODE -------------------------------------------------------------------- - -Win32Video::Win32Video (int parm) -: m_Modes (NULL), - m_IsFullscreen (false), - m_Adapter (D3DADAPTER_DEFAULT) -{ - I_SetWndProc(); - InitD3D9(); -} - -Win32Video::~Win32Video () -{ - FreeModes (); - - if (D3D != NULL) - { - D3D->Release(); - D3D = NULL; - } - - STOPLOG; -} - -bool Win32Video::InitD3D9 () -{ - DIRECT3DCREATE9FUNC direct3d_create_9; - - // Load the Direct3D 9 library. - if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL) - { - Printf("Unable to load d3d9.dll! Falling back to DirectDraw...\n"); - return false; - } - - // Obtain an IDirect3D interface. - if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL) - { - goto closelib; - } - if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL) - { - goto closelib; - } - - // Select adapter. - m_Adapter = (vid_adapter < 1 || (UINT)vid_adapter > D3D->GetAdapterCount()) - ? D3DADAPTER_DEFAULT : (UINT)vid_adapter - 1u; - - // Check that we have at least PS 1.4 available. - D3DCAPS9 devcaps; - if (FAILED(D3D->GetDeviceCaps (m_Adapter, D3DDEVTYPE_HAL, &devcaps))) - { - goto d3drelease; - } - if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104) - { - goto d3drelease; - } - if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES)) - { - goto d3drelease; - } - - // Enumerate available display modes. - FreeModes (); - AddD3DModes (m_Adapter); - AddD3DModes (m_Adapter); - if (Args->CheckParm ("-2")) - { // Force all modes to be pixel-doubled. - ScaleModes (1); - } - else if (Args->CheckParm ("-4")) - { // Force all modes to be pixel-quadrupled. - ScaleModes (2); - } - else - { - AddLowResModes (); - } - AddLetterboxModes (); - if (m_Modes == NULL) - { // Too bad. We didn't find any modes for D3D9. We probably won't find any - // for DDraw either... - goto d3drelease; - } - return true; - -d3drelease: - D3D->Release(); - D3D = NULL; -closelib: - FreeLibrary (D3D9_dll); - Printf("Direct3D acceleration failed! Falling back to DirectDraw...\n"); - return false; -} - -static HRESULT WINAPI EnumDDModesCB(LPDDSURFACEDESC desc, void *data) -{ - ((Win32Video *)data)->AddMode(desc->dwWidth, desc->dwHeight, 8, desc->dwHeight, 0); - return DDENUMRET_OK; -} - - -// Returns true if fullscreen, false otherwise -bool Win32Video::GoFullscreen (bool yes) -{ - // FIXME: Do this right for D3D. - return yes; -} - -//========================================================================== -// -// Win32Video :: DumpAdapters -// -// Dumps the list of display adapters to the console. Only meaningful for -// Direct3D. -// -//========================================================================== - -void Win32Video::DumpAdapters() -{ - using OptWin32::GetMonitorInfoA; - - if (D3D == NULL) - { - Printf("Multi-monitor support requires Direct3D.\n"); - return; - } - - UINT num_adapters = D3D->GetAdapterCount(); - - for (UINT i = 0; i < num_adapters; ++i) - { - D3DADAPTER_IDENTIFIER9 ai; - char moreinfo[64] = ""; - - if (FAILED(D3D->GetAdapterIdentifier(i, 0, &ai))) - { - continue; - } - // Strip trailing whitespace from adapter description. - for (char *p = ai.Description + strlen(ai.Description) - 1; - p >= ai.Description && isspace(*p); - --p) - { - *p = '\0'; - } - HMONITOR hm = D3D->GetAdapterMonitor(i); - MONITORINFOEX mi; - mi.cbSize = sizeof(mi); - - assert(GetMonitorInfo); // Missing in NT4, but so is D3D - if (GetMonitorInfo(hm, &mi)) - { - mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", - mi.rcMonitor.right - mi.rcMonitor.left, - mi.rcMonitor.bottom - mi.rcMonitor.top, - mi.rcMonitor.left, mi.rcMonitor.top, - mi.dwFlags & MONITORINFOF_PRIMARY ? " (Primary)" : ""); - } - Printf("%s%u. %s%s\n", - i == m_Adapter ? TEXTCOLOR_BOLD : "", - i + 1, ai.Description, moreinfo); - } -} - -// Mode enumeration -------------------------------------------------------- - -void Win32Video::AddD3DModes (unsigned adapter) -{ - for (D3DFORMAT format : { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5}) - { - UINT modecount, i; - D3DDISPLAYMODE mode; - - modecount = D3D->GetAdapterModeCount(adapter, format); - for (i = 0; i < modecount; ++i) - { - if (D3D_OK == D3D->EnumAdapterModes(adapter, format, i, &mode)) - { - AddMode(mode.Width, mode.Height, 8, mode.Height, 0); - } - } - } -} - -//========================================================================== -// -// Win32Video :: AddLowResModes -// -// Recent NVidia drivers no longer support resolutions below 640x480, even -// if you try to add them as a custom resolution. With D3DFB, pixel doubling -// is quite easy to do and hardware-accelerated. If you have 1280x800, then -// you can have 320x200, but don't be surprised if it shows up as widescreen -// on a widescreen monitor, since that's what it is. -// -//========================================================================== - -void Win32Video::AddLowResModes() -{ - ModeInfo *mode, *nextmode; - - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && - mode->doubling == 0 && - mode->height >= 200*2 && - mode->height <= 480*2 && - mode->width >= 320*2 && - mode->width <= 640*2) - { - AddMode (mode->width / 2, mode->height / 2, mode->bits, mode->height / 2, 1); - } - } - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && - mode->doubling == 0 && - mode->height >= 200*4 && - mode->height <= 480*4 && - mode->width >= 320*4 && - mode->width <= 640*4) - { - AddMode (mode->width / 4, mode->height / 4, mode->bits, mode->height / 4, 2); - } - } -} - -// Add 16:9 and 16:10 resolutions you can use in a window or letterboxed -void Win32Video::AddLetterboxModes () -{ - ModeInfo *mode, *nextmode; - - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && mode->height * 4/3 == mode->width) - { - if (mode->width >= 360) - { - AddMode (mode->width, mode->width * 9/16, mode->bits, mode->height, mode->doubling); - } - if (mode->width > 640) - { - AddMode (mode->width, mode->width * 10/16, mode->bits, mode->height, mode->doubling); - } - } - } -} - -void Win32Video::AddMode (int x, int y, int bits, int y2, int doubling) -{ - // Reject modes that do not meet certain criteria. - if ((x & 1) != 0 || - y > MAXHEIGHT || - x > MAXWIDTH || - y < 200 || - x < 320) - { - return; - } - - ModeInfo **probep = &m_Modes; - ModeInfo *probe = m_Modes; - - // This mode may have been already added to the list because it is - // enumerated multiple times at different refresh rates. If it's - // not present, add it to the right spot in the list; otherwise, do nothing. - // Modes are sorted first by width, then by height, then by depth. In each - // case the order is ascending. - for (; probe != 0; probep = &probe->next, probe = probe->next) - { - if (probe->width > x) break; - if (probe->width < x) continue; - // Width is equal - if (probe->height > y) break; - if (probe->height < y) continue; - // Height is equal - if (probe->bits > bits) break; - if (probe->bits < bits) continue; - // Bits is equal - return; - } - - *probep = new ModeInfo (x, y, bits, y2, doubling); - (*probep)->next = probe; -} - -void Win32Video::FreeModes () -{ - ModeInfo *mode = m_Modes; - - while (mode) - { - ModeInfo *tempmode = mode; - mode = mode->next; - delete tempmode; - } - m_Modes = NULL; -} - -// For every mode, set its scaling factor. Modes that end up with too -// small a display area are discarded. - -void Win32Video::ScaleModes (int doubling) -{ - ModeInfo *mode, **prev; - - prev = &m_Modes; - mode = m_Modes; - - while (mode != NULL) - { - assert(mode->doubling == 0); - mode->width >>= doubling; - mode->height >>= doubling; - mode->realheight >>= doubling; - mode->doubling = doubling; - if ((mode->width & 7) != 0 || mode->width < 320 || mode->height < 200) - { // Mode became too small. Delete it. - *prev = mode->next; - delete mode; - } - else - { - prev = &mode->next; - } - mode = *prev; - } -} - -void Win32Video::StartModeIterator (int bits, bool fs) -{ - m_IteratorMode = m_Modes; - m_IteratorBits = bits; - m_IteratorFS = fs; -} - -bool Win32Video::NextMode (int *width, int *height, bool *letterbox) -{ - if (m_IteratorMode) - { - while (m_IteratorMode && m_IteratorMode->bits != m_IteratorBits) - { - m_IteratorMode = m_IteratorMode->next; - } - - if (m_IteratorMode) - { - *width = m_IteratorMode->width; - *height = m_IteratorMode->height; - if (letterbox != NULL) *letterbox = m_IteratorMode->realheight != m_IteratorMode->height; - m_IteratorMode = m_IteratorMode->next; - return true; - } - } - return false; -} - -DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool bgra, bool fullscreen, DFrameBuffer *old) -{ - static int retry = 0; - static int owidth, oheight; - - BaseWinFB *fb; - PalEntry flashColor; - int flashAmount; - - if (fullscreen) - { - I_ClosestResolution(&width, &height, D3D ? 32 : 8); - } - - LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old); - - if (old != NULL) - { // Reuse the old framebuffer if its attributes are the same - BaseWinFB *fb = static_cast (old); - if (fb->Width == width && - fb->Height == height && - fb->Windowed == !fullscreen && - fb->Bgra == bgra) - { - return old; - } - old->GetFlash (flashColor, flashAmount); - if (old == screen) screen = nullptr; - delete old; - } - else - { - flashColor = 0; - flashAmount = 0; - } - - if (D3D != NULL) - { - fb = new D3DFB (m_Adapter, width, height, bgra, fullscreen); - } - else - { - I_FatalError("Unable to create framebuffer. Direct3D not found"); - } - - LOG1 ("New fb created @ %p\n", fb); - - fb->SetFlash (flashColor, flashAmount); - return fb; -} - -void Win32Video::SetWindowedScale (float scale) -{ - // FIXME -} - -//========================================================================== -// -// BaseWinFB :: ScaleCoordsFromWindow -// -// Given coordinates in window space, return coordinates in what the game -// thinks screen space is. -// -//========================================================================== - -void BaseWinFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - RECT rect; - - int TrueHeight = GetTrueHeight(); - if (GetClientRect(Window, &rect)) - { - x = int16_t(x * Width / (rect.right - rect.left)); - y = int16_t(y * TrueHeight / (rect.bottom - rect.top)); - } - // Subtract letterboxing borders - y -= (TrueHeight - Height) / 2; -} //========================================================================== // @@ -641,4 +177,28 @@ void I_FPSLimit() { WaitForSingleObject(FPSLimitEvent, 1000); } -} \ No newline at end of file +} + +//========================================================================== +// +// BaseWinFB :: ScaleCoordsFromWindow +// +// Given coordinates in window space, return coordinates in what the game +// thinks screen space is. +// +//========================================================================== +extern HWND Window; + +void BaseWinFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y) +{ + RECT rect; + + int TrueHeight = GetTrueHeight(); + if (GetClientRect(Window, &rect)) + { + x = int16_t(x * Width / (rect.right - rect.left)); + y = int16_t(y * TrueHeight / (rect.bottom - rect.top)); + } + // Subtract letterboxing borders + y -= (TrueHeight - Height) / 2; +} diff --git a/wadsrc/static/shaders/d3d/build.bat b/wadsrc/static/shaders/d3d/build.bat deleted file mode 100644 index b56c18b2d..000000000 --- a/wadsrc/static/shaders/d3d/build.bat +++ /dev/null @@ -1,7 +0,0 @@ -cd ..\sm20 -call build.bat - -cd ..\sm30 -call build.bat - -cd .. diff --git a/wadsrc/static/shaders/d3d/shaders.ps b/wadsrc/static/shaders/d3d/shaders.ps deleted file mode 100644 index f94082d80..000000000 --- a/wadsrc/static/shaders/d3d/shaders.ps +++ /dev/null @@ -1,99 +0,0 @@ -sampler2D Image : register(s0); -sampler1D Palette : register(s1); - -float4 Desaturation : register(c1); // { Desat, 1 - Desat } -float4 PaletteMod : register(c2); -float4 Color1 : register(c3); -float4 Color2 : register(c4); -float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 } -float4 Gamma : register(c7); - -float4 TextureLookup(float2 tex_coord) -{ -#if PALTEX - float index = tex2D(Image, tex_coord).x; - index = index * PaletteMod.x + PaletteMod.y; - return tex1D(Palette, index); -#else - return tex2D(Image, tex_coord); -#endif -} - -float Grayscale(float4 rgb) -{ - return dot(rgb.rgb, Weights.rgb); -} - -float4 SampleTexture(float2 tex_coord) -{ - float4 texel = TextureLookup(tex_coord); -#if INVERT - texel.rgb = Weights.www - texel.xyz; -#endif -#if OPAQUE - texel.a = 1.0; -#endif -#if STENCIL - texel.rgb = Weights.www; -#endif -#if ALPHATEX - texel.a *= Grayscale(texel); - texel.rgb = Weights.www; -#endif -#if DESAT - float3 intensity; - intensity.rgb = Grayscale(texel) * Desaturation.x; - texel.rgb = intensity.rgb + texel.rgb * Desaturation.y; -#endif - return texel; -} - -// Normal color calculation for most drawing modes. - -float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 VertexColor : COLOR0) : COLOR -{ - return Color1 + SampleTexture(tex_coord) * VertexColor; -} - - -// Just return the value of c0. - -float4 VertexColor(float4 color : COLOR0) : COLOR -{ - return color; -} - -// Emulate one of the special colormaps. (Invulnerability, gold, etc.) - -float4 SpecialColormap(float2 tex_coord : TEXCOORD0) : COLOR -{ - float4 color = SampleTexture(tex_coord); - float4 range = Color2 - Color1; - // We can't store values greater than 1.0 in a color register, so we multiply - // the final result by 2 and expect the caller to divide the start and end by 2. - color.rgb = 2 * (Color1 + Grayscale(color) * range).rgb; - return color; -} - - -// Windowed gamma correction. - -float4 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR -{ - float4 color = tex2D(Image, tex_coord); - color.rgb = pow(color.rgb, Gamma.rgb); - return color; -} - -// The burn wipe effect. - -sampler2D NewScreen : register(s0); -sampler2D Burn : register(s1); - -float4 BurnWipe(float2 coord[2] : TEXCOORD0) : COLOR -{ - float4 color = tex2D(NewScreen, coord[0]); - float4 alpha = tex2D(Burn, coord[1]); - color.a = alpha.r * 2; - return color; -} diff --git a/wadsrc/static/shaders/d3d/sm20/AlphaTex.pso b/wadsrc/static/shaders/d3d/sm20/AlphaTex.pso deleted file mode 100644 index 2dcc640bc..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/AlphaTex.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso deleted file mode 100644 index c2a99031f..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso deleted file mode 100644 index 8fdeb2e9d..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColor.pso b/wadsrc/static/shaders/d3d/sm20/NormalColor.pso deleted file mode 100644 index 0797f9af1..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorD.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorD.pso deleted file mode 100644 index 909c41140..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorD.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso deleted file mode 100644 index b77b0e33f..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorInvOpaq.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorInvOpaq.pso deleted file mode 100644 index 34ec06995..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorInvOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorOpaq.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorOpaq.pso deleted file mode 100644 index 4568a9292..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso deleted file mode 100644 index 126f92209..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalD.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalD.pso deleted file mode 100644 index a8b99c88a..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPalD.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso deleted file mode 100644 index da4cc5094..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInvOpaq.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalInvOpaq.pso deleted file mode 100644 index f7b73e6d0..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInvOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalOpaq.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalOpaq.pso deleted file mode 100644 index 1e401a296..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPalOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/PalAlphaTex.pso b/wadsrc/static/shaders/d3d/sm20/PalAlphaTex.pso deleted file mode 100644 index bde6402dc..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/PalAlphaTex.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/PalStencil.pso b/wadsrc/static/shaders/d3d/sm20/PalStencil.pso deleted file mode 100644 index 789ba95f1..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/PalStencil.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso deleted file mode 100644 index ffcc858bf..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso deleted file mode 100644 index 8ef66d513..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/Stencil.pso b/wadsrc/static/shaders/d3d/sm20/Stencil.pso deleted file mode 100644 index c0a0fffdd..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/Stencil.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/VertexColor.pso b/wadsrc/static/shaders/d3d/sm20/VertexColor.pso deleted file mode 100644 index 39c678df2..000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/VertexColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/build.bat b/wadsrc/static/shaders/d3d/sm20/build.bat deleted file mode 100644 index b23e9ee79..000000000 --- a/wadsrc/static/shaders/d3d/sm20/build.bat +++ /dev/null @@ -1,29 +0,0 @@ -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColor.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColorPal.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInv.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInv.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorOpaq.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalOpaq.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInvOpaq.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInvOpaq.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoStencil.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoPalStencil.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoAlphaTex.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoPalAlphaTex.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorD.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalD.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EVertexColor /FoVertexColor.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormap.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormapPal.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EBurnWipe /FoBurnWipe.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/d3d/sm30/AlphaTex.pso b/wadsrc/static/shaders/d3d/sm30/AlphaTex.pso deleted file mode 100644 index ea21caf83..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/AlphaTex.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso deleted file mode 100644 index f5da9efd4..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso deleted file mode 100644 index 41bdb3fda..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColor.pso b/wadsrc/static/shaders/d3d/sm30/NormalColor.pso deleted file mode 100644 index fbe83fa23..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorD.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorD.pso deleted file mode 100644 index 7c2917619..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorD.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso deleted file mode 100644 index f0311f4a1..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorInvOpaq.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorInvOpaq.pso deleted file mode 100644 index 04b199b92..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorInvOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorOpaq.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorOpaq.pso deleted file mode 100644 index e575c71f8..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso deleted file mode 100644 index 251dbbe1e..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalD.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalD.pso deleted file mode 100644 index 5fa38d476..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPalD.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso deleted file mode 100644 index 7678d1668..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInvOpaq.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalInvOpaq.pso deleted file mode 100644 index 2330d802d..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInvOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalOpaq.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalOpaq.pso deleted file mode 100644 index b5dd95bc0..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPalOpaq.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/PalAlphaTex.pso b/wadsrc/static/shaders/d3d/sm30/PalAlphaTex.pso deleted file mode 100644 index f511d4d2d..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/PalAlphaTex.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/PalStencil.pso b/wadsrc/static/shaders/d3d/sm30/PalStencil.pso deleted file mode 100644 index da7a0ad54..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/PalStencil.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso deleted file mode 100644 index 1e0dd3502..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso deleted file mode 100644 index 7260951af..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/Stencil.pso b/wadsrc/static/shaders/d3d/sm30/Stencil.pso deleted file mode 100644 index e864d735e..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/Stencil.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/VertexColor.pso b/wadsrc/static/shaders/d3d/sm30/VertexColor.pso deleted file mode 100644 index cb7f43bed..000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/VertexColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/build.bat b/wadsrc/static/shaders/d3d/sm30/build.bat deleted file mode 100644 index a5b193cfe..000000000 --- a/wadsrc/static/shaders/d3d/sm30/build.bat +++ /dev/null @@ -1,29 +0,0 @@ -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColor.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColorPal.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInv.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInv.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorOpaq.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalOpaq.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInvOpaq.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInvOpaq.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoStencil.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoPalStencil.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoAlphaTex.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoPalAlphaTex.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorD.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalD.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EVertexColor /FoVertexColor.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormap.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormapPal.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EBurnWipe /FoBurnWipe.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/glsl/swshader.fp b/wadsrc/static/shaders/glsl/swshader.fp deleted file mode 100644 index e33389f29..000000000 --- a/wadsrc/static/shaders/glsl/swshader.fp +++ /dev/null @@ -1,148 +0,0 @@ - -precision mediump float; - -in vec4 PixelColor0; -in vec4 PixelColor1; -in vec4 PixelTexCoord0; - -out vec4 FragColor; - -uniform sampler2D Image; -uniform sampler2D Palette; -uniform sampler2D NewScreen; -uniform sampler2D Burn; - -uniform vec4 Desaturation; // { Desat, 1 - Desat } -uniform vec4 PaletteMod; -uniform vec4 Weights; // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 } -uniform vec4 Gamma; - -vec4 TextureLookup(vec2 tex_coord) -{ -#if defined(PALTEX) - float index = texture(Image, tex_coord).x; - index = index * PaletteMod.x + PaletteMod.y; - return texture(Palette, vec2(index, 0.5)); -#else - return texture(Image, tex_coord); -#endif -} - -vec4 Invert(vec4 rgb) -{ -#if defined(INVERT) - rgb.rgb = Weights.www - rgb.xyz; -#endif - return rgb; -} - -float Grayscale(vec4 rgb) -{ - return dot(rgb.rgb, Weights.rgb); -} - -vec4 SampleTexture(vec2 tex_coord) -{ - return Invert(TextureLookup(tex_coord)); -} - -// Normal color calculation for most drawing modes. - -vec4 NormalColor(vec2 tex_coord, vec4 Flash, vec4 InvFlash) -{ - return Flash + SampleTexture(tex_coord) * InvFlash; -} - -// Copy the red channel to the alpha channel. Pays no attention to palettes. - -vec4 RedToAlpha(vec2 tex_coord, vec4 Flash, vec4 InvFlash) -{ - vec4 color = Invert(texture(Image, tex_coord)); - color.a = color.r; - return Flash + color * InvFlash; -} - -// Just return the value of c0. - -vec4 VertexColor(vec4 color) -{ - return color; -} - -// Emulate one of the special colormaps. (Invulnerability, gold, etc.) - -vec4 SpecialColormap(vec2 tex_coord, vec4 start, vec4 end) -{ - vec4 color = SampleTexture(tex_coord); - vec4 range = end - start; - // We can't store values greater than 1.0 in a color register, so we multiply - // the final result by 2 and expect the caller to divide the start and end by 2. - color.rgb = 2.0 * (start + Grayscale(color) * range).rgb; - // Duplicate alpha semantics of NormalColor. - color.a = start.a + color.a * end.a; - return color; -} - -// In-game colormap effect: fade to a particular color and multiply by another, with -// optional desaturation of the original color. Desaturation is stored in c1. -// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha. -// Overall alpha is in color.a. -vec4 InGameColormap(vec2 tex_coord, vec4 color, vec4 fade) -{ - vec4 rgb = SampleTexture(tex_coord); - - // Desaturate -#if defined(DESAT) - vec3 intensity; - intensity.rgb = vec3(Grayscale(rgb) * Desaturation.x); - rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y; -#endif - - // Fade - rgb.rgb = rgb.rgb * fade.aaa + fade.rgb; - - // Shade and Alpha - rgb = rgb * color; - - return rgb; -} - -// Windowed gamma correction. - -vec4 GammaCorrection(vec2 tex_coord) -{ - vec4 color = texture(Image, tex_coord); - color.rgb = pow(color.rgb, Gamma.rgb); - return color; -} - -// The burn wipe effect. - -vec4 BurnWipe(vec4 coord) -{ - vec4 color = texture(NewScreen, coord.xy); - vec4 alpha = texture(Burn, coord.zw); - color.a = alpha.r * 2.0; - return color; -} - -void main() -{ -#if defined(ENORMALCOLOR) - FragColor = NormalColor(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EREDTOALPHA) - FragColor = RedToAlpha(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EVERTEXCOLOR) - FragColor = VertexColor(PixelColor0); -#elif defined(ESPECIALCOLORMAP) - FragColor = SpecialColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EINGAMECOLORMAP) - FragColor = InGameColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EBURNWIPE) - FragColor = BurnWipe(PixelTexCoord0); -#elif defined(EGAMMACORRECTION) - FragColor = GammaCorrection(PixelTexCoord0.xy); -#else - #error Entry point define is missing -#endif -} diff --git a/wadsrc/static/shaders/glsl/swshader.vp b/wadsrc/static/shaders/glsl/swshader.vp deleted file mode 100644 index a317025aa..000000000 --- a/wadsrc/static/shaders/glsl/swshader.vp +++ /dev/null @@ -1,22 +0,0 @@ - -in vec4 AttrPosition; -in vec4 AttrColor0; -in vec4 AttrColor1; -in vec4 AttrTexCoord0; - -out vec4 PixelColor0; -out vec4 PixelColor1; -out vec4 PixelTexCoord0; - -uniform vec4 ScreenSize; - -void main() -{ - gl_Position = vec4(AttrPosition.xy / ScreenSize.xy * 2.0 - 1.0, 1.0, 1.0); -#if defined(EGAMMACORRECTION) - gl_Position.y = -gl_Position.y; -#endif - PixelColor0 = AttrColor0.bgra; - PixelColor1 = AttrColor1.bgra; - PixelTexCoord0 = AttrTexCoord0; -}