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