mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 23:01:59 +00:00
- looks like the 2D drawer sources did not get committed...
- This also adds the missing draw modes to the GLSL shader.
This commit is contained in:
parent
16480a3f4b
commit
25999c1c6a
3 changed files with 679 additions and 4 deletions
516
src/v_2ddrawer.cpp
Normal file
516
src/v_2ddrawer.cpp
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2016-2018 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/
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
** v_2ddrawer.h
|
||||||
|
** Device independent 2D draw list
|
||||||
|
**
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "doomtype.h"
|
||||||
|
#include "templates.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Float, transsouls)
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int F2DDrawer::AddCommand(const RenderCommand *data)
|
||||||
|
{
|
||||||
|
if (mData.Size() > 0 && data->isCompatible(mData.Last()))
|
||||||
|
{
|
||||||
|
// Merge with the last command.
|
||||||
|
mData.Last().mIndexCount += data->mIndexCount;
|
||||||
|
return mData.Size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mData.Push(*data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::AddIndices(int firstvert, int count, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, count);
|
||||||
|
int addr = mIndices.Reserve(count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
mIndices[addr + i] = firstvert + va_arg(ap, int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// SetStyle
|
||||||
|
//
|
||||||
|
// Patterned after R_SetPatchStyle.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor, RenderCommand &quad)
|
||||||
|
{
|
||||||
|
auto fmt = tex->GetFormat();
|
||||||
|
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.BlendOp == STYLEOP_Fuzz)
|
||||||
|
{
|
||||||
|
style = LegacyRenderStyles[STYLE_TranslucentStencil];
|
||||||
|
alpha = 0.3f;
|
||||||
|
parms.fillcolor = 0;
|
||||||
|
}
|
||||||
|
else if (style.BlendOp == STYLEOP_FuzzOrAdd)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (style.Flags & STYLEF_InvertOverlay)
|
||||||
|
{
|
||||||
|
// Only the overlay color is inverted, not the overlay alpha.
|
||||||
|
parms.colorOverlay.r = 255 - parms.colorOverlay.r;
|
||||||
|
parms.colorOverlay.g = 255 - parms.colorOverlay.g;
|
||||||
|
parms.colorOverlay.b = 255 - parms.colorOverlay.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetColorOverlay(parms.colorOverlay, alpha, vertexcolor, quad.mColor1);
|
||||||
|
quad.mColorOverlay = parms.colorOverlay;
|
||||||
|
|
||||||
|
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.r = 255 - parms.fillcolor.r;
|
||||||
|
parms.fillcolor.g = 255 - parms.fillcolor.g;
|
||||||
|
parms.fillcolor.b = 255 - parms.fillcolor.b;
|
||||||
|
}
|
||||||
|
// Set up the color mod to replace the color from the image data.
|
||||||
|
vertexcolor.r = parms.fillcolor.r;
|
||||||
|
vertexcolor.g = parms.fillcolor.g;
|
||||||
|
vertexcolor.b = parms.fillcolor.b;
|
||||||
|
|
||||||
|
if (style.Flags & STYLEF_RedIsAlpha)
|
||||||
|
{
|
||||||
|
quad.mDrawMode = DTM_AlphaTexture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quad.mDrawMode = DTM_Stencil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (style.Flags & STYLEF_RedIsAlpha)
|
||||||
|
{
|
||||||
|
quad.mDrawMode = DTM_AlphaTexture;
|
||||||
|
}
|
||||||
|
else if (style.Flags & STYLEF_InvertSource)
|
||||||
|
{
|
||||||
|
quad.mDrawMode = DTM_Invert;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parms.specialcolormap != nullptr)
|
||||||
|
{ // Emulate an invulnerability or similar colormap.
|
||||||
|
float *start, *end;
|
||||||
|
start = parms.specialcolormap->ColorizeStart;
|
||||||
|
end = parms.specialcolormap->ColorizeEnd;
|
||||||
|
if (quad.mDrawMode == DTM_Invert)
|
||||||
|
{
|
||||||
|
quad.mDrawMode = DTM_Normal;
|
||||||
|
std::swap(start, end);
|
||||||
|
}
|
||||||
|
quad.mFlags |= DTF_SpecialColormap;
|
||||||
|
// SpecialColormap uses the two color uniforms to set its ramp.
|
||||||
|
quad.mColor1.r = (uint8_t)(start[0] * (255 / 2));
|
||||||
|
quad.mColor1.g = (uint8_t)(start[1] * (255 / 2));
|
||||||
|
quad.mColor1.b = (uint8_t)(start[2] * (255 / 2));
|
||||||
|
quad.mColor2.r = (uint8_t)(end[0] * (255 / 2));
|
||||||
|
quad.mColor2.g = (uint8_t)(end[1] * (255 / 2));
|
||||||
|
quad.mColor2.b = (uint8_t)(end[2] * (255 / 2));
|
||||||
|
}
|
||||||
|
else if (parms.colormapstyle != nullptr)
|
||||||
|
{
|
||||||
|
// Emulate the fading from an in-game colormap (colorized, faded, and desaturated)
|
||||||
|
// This only gets used to render the weapon sprite for the software renderer.
|
||||||
|
quad.mDesaturate = parms.colormapstyle->Desaturate;
|
||||||
|
vertexcolor.r = parms.colormapstyle->Color.r;
|
||||||
|
vertexcolor.g = parms.colormapstyle->Color.g;
|
||||||
|
vertexcolor.b = parms.colormapstyle->Color.b;
|
||||||
|
|
||||||
|
// fade uses premultiplied alpha. This uses mColor2 so that it can be combined with color overlays.
|
||||||
|
double fadelevel = parms.colormapstyle->FadeLevel;
|
||||||
|
quad.mColor2.r = uint8_t(parms.colormapstyle->Fade.r * fadelevel);
|
||||||
|
quad.mColor2.g = uint8_t(parms.colormapstyle->Fade.g * fadelevel);
|
||||||
|
quad.mColor2.b = uint8_t(parms.colormapstyle->Fade.b * fadelevel);
|
||||||
|
quad.mFlags |= DTF_IngameLighting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// apply the element's own color. This is being blended with anything that came before.
|
||||||
|
vertexcolor = PalEntry((vertexcolor.a * parms.color.a) / 255, (vertexcolor.r * parms.color.r) / 255, (vertexcolor.g * parms.color.g) / 255, (vertexcolor.b * parms.color.b) / 255);
|
||||||
|
|
||||||
|
if (!parms.masked)
|
||||||
|
{
|
||||||
|
// For DTM_AlphaTexture and DTM_Stencil the mask cannot be turned off because it would not yield a usable result.
|
||||||
|
if (quad.mDrawMode == DTM_Normal) quad.mDrawMode = DTM_Opaque;
|
||||||
|
else if (quad.mDrawMode == DTM_Invert) quad.mDrawMode = DTM_InvertOpaque;
|
||||||
|
}
|
||||||
|
quad.mRenderStyle = parms.style; // this contains the blend mode and blend equation settings.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Draws a texture
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor)
|
||||||
|
{
|
||||||
|
if (APART(color) != 0)
|
||||||
|
{
|
||||||
|
// overlay color uses premultiplied alpha. The alpha channel is what the main color gets multiplied with in the blending.
|
||||||
|
int a = APART(color) * 256 / 255;
|
||||||
|
overlaycolor.r = (color.r * a) >> 8;
|
||||||
|
overlaycolor.g = (color.g * a) >> 8;
|
||||||
|
overlaycolor.b = (color.b * a) >> 8;
|
||||||
|
overlaycolor.a = 255 - color.a;
|
||||||
|
|
||||||
|
vertexcolor = PalEntry(int(alpha * 255), color.a, color.a, color.a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
overlaycolor = 0;
|
||||||
|
vertexcolor = PalEntry(int(alpha * 255), 255, 255, 255);
|
||||||
|
}
|
||||||
|
// The real color gets multiplied into vertexcolor later.
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Draws a texture
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::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;
|
||||||
|
double u1, v1, u2, v2;
|
||||||
|
int light = 255;
|
||||||
|
PalEntry vertexcolor;
|
||||||
|
|
||||||
|
RenderCommand dg;
|
||||||
|
|
||||||
|
dg.mType = DrawTypeTriangles;
|
||||||
|
dg.mVertCount = 4;
|
||||||
|
dg.mTexture = img;
|
||||||
|
|
||||||
|
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
|
||||||
|
{
|
||||||
|
// handle black overlays as reduced light.
|
||||||
|
light = 255 - APART(parms.colorOverlay);
|
||||||
|
parms.colorOverlay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dg.mTranslation = 0;
|
||||||
|
SetStyle(img, parms, vertexcolor, dg);
|
||||||
|
|
||||||
|
if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive)
|
||||||
|
{
|
||||||
|
dg.mTranslation = parms.remap;
|
||||||
|
}
|
||||||
|
u1 = parms.srcx;
|
||||||
|
v1 = parms.srcy;
|
||||||
|
u2 = parms.srcx + parms.srcwidth;
|
||||||
|
v2 = parms.srcy + parms.srcheight;
|
||||||
|
|
||||||
|
if (parms.flipX)
|
||||||
|
std::swap(u1, u2);
|
||||||
|
|
||||||
|
if (parms.flipY)
|
||||||
|
std::swap(v1, v2);
|
||||||
|
|
||||||
|
// This is crap. Only kept for backwards compatibility with scripts that may have used it.
|
||||||
|
// Note that this only works for unflipped full textures.
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < (double)parms.lclip || y < (double)parms.uclip || x + w >(double)parms.lclip || y + h >(double)parms.dclip)
|
||||||
|
{
|
||||||
|
dg.mScissor[0] = parms.lclip;
|
||||||
|
dg.mScissor[1] = parms.uclip;
|
||||||
|
dg.mScissor[2] = parms.rclip;
|
||||||
|
dg.mScissor[3] = parms.dclip;
|
||||||
|
dg.mFlags |= DTF_Scissor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(dg.mScissor, 0, sizeof(dg.mScissor));
|
||||||
|
}
|
||||||
|
|
||||||
|
dg.mVertCount = 4;
|
||||||
|
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||||
|
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
||||||
|
ptr->Set(x, y, 0, u1, v1, vertexcolor); ptr++;
|
||||||
|
ptr->Set(x, y + h, 0, u1, v2, vertexcolor); ptr++;
|
||||||
|
ptr->Set(x + w, y, 0, u2, v1, vertexcolor); ptr++;
|
||||||
|
ptr->Set(x + w, y + h, 0, u2, v2, vertexcolor); ptr++;
|
||||||
|
AddIndices(6, dg.mVertIndex, 0, 1, 2, 1, 3, 2);
|
||||||
|
AddCommand(&dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||||
|
double originx, double originy, double scalex, double scaley,
|
||||||
|
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel)
|
||||||
|
{
|
||||||
|
// Use an equation similar to player sprites to determine shade
|
||||||
|
|
||||||
|
// Convert a light level into an unbounded colormap index (shade).
|
||||||
|
// Why the +12? I wish I knew, but experimentation indicates it
|
||||||
|
// is necessary in order to best reproduce Doom's original lighting.
|
||||||
|
double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.));
|
||||||
|
double fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0);
|
||||||
|
|
||||||
|
RenderCommand poly;
|
||||||
|
|
||||||
|
poly.mType = DrawTypeTriangles;
|
||||||
|
poly.mTexture = texture;
|
||||||
|
poly.mRenderStyle = DefaultRenderStyle();
|
||||||
|
poly.mFlags |= DTF_Wrap | DTF_IngameLighting;
|
||||||
|
poly.mDesaturate = colormap.Desaturation;
|
||||||
|
|
||||||
|
PalEntry color0 = colormap.LightColor; color0.a = 255;
|
||||||
|
|
||||||
|
poly.mColor2.a = uint8_t((1 - fadelevel) * 255);
|
||||||
|
poly.mColor2.r = uint8_t(colormap.FadeColor.r * fadelevel);
|
||||||
|
poly.mColor2.g = uint8_t(colormap.FadeColor.g * fadelevel);
|
||||||
|
poly.mColor2.b = uint8_t(colormap.FadeColor.b * fadelevel);
|
||||||
|
|
||||||
|
bool dorotate = rotation != 0;
|
||||||
|
|
||||||
|
float cosrot = (float)cos(rotation.Radians());
|
||||||
|
float sinrot = (float)sin(rotation.Radians());
|
||||||
|
|
||||||
|
float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
|
||||||
|
float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
|
||||||
|
float ox = float(originx);
|
||||||
|
float oy = float(originy);
|
||||||
|
|
||||||
|
poly.mVertCount = npoints;
|
||||||
|
poly.mVertIndex = (int)mVertices.Reserve(npoints);
|
||||||
|
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, color0);
|
||||||
|
}
|
||||||
|
for (int i = 2; i < npoints; ++i)
|
||||||
|
{
|
||||||
|
AddIndices(poly.mVertIndex, 3, 0, i - 1, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCommand(&poly);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||||
|
{
|
||||||
|
float fU1, fU2, fV1, fV2;
|
||||||
|
|
||||||
|
RenderCommand dg;
|
||||||
|
|
||||||
|
dg.mType = DrawTypeTriangles;
|
||||||
|
dg.mRenderStyle = DefaultRenderStyle();
|
||||||
|
dg.mTexture = src;
|
||||||
|
dg.mVertCount = 4;
|
||||||
|
dg.mTexture = src;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||||
|
auto ptr = &mVertices[dg.mVertIndex];
|
||||||
|
|
||||||
|
ptr->Set(left, top, 0, fU1, fV1, 0xffffffff); ptr++;
|
||||||
|
ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++;
|
||||||
|
ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++;
|
||||||
|
ptr->Set(right, bottom, 0, fU2, fV2, 0xffffffff); ptr++;
|
||||||
|
AddIndices(6, dg.mVertIndex, 0, 1, 2, 1, 3, 2);
|
||||||
|
AddCommand(&dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color)
|
||||||
|
{
|
||||||
|
RenderCommand dg;
|
||||||
|
|
||||||
|
dg.mType = DrawTypeTriangles;
|
||||||
|
dg.mVertCount = 4;
|
||||||
|
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||||
|
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||||
|
auto 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++;
|
||||||
|
AddIndices(6, dg.mVertIndex, 0, 1, 2, 1, 3, 2);
|
||||||
|
AddCommand(&dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::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;
|
||||||
|
|
||||||
|
RenderCommand dg;
|
||||||
|
|
||||||
|
dg.mType = DrawTypeLines;
|
||||||
|
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);
|
||||||
|
AddCommand(&dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color)
|
||||||
|
{
|
||||||
|
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||||
|
p.a = 255;
|
||||||
|
|
||||||
|
RenderCommand dg;
|
||||||
|
|
||||||
|
dg.mType = DrawTypePoints;
|
||||||
|
dg.mVertCount = 1;
|
||||||
|
dg.mVertIndex = (int)mVertices.Reserve(1);
|
||||||
|
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||||
|
AddCommand(&dg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void F2DDrawer::Clear()
|
||||||
|
{
|
||||||
|
mVertices.Clear();
|
||||||
|
mIndices.Clear();
|
||||||
|
mData.Clear();
|
||||||
|
}
|
141
src/v_2ddrawer.h
Normal file
141
src/v_2ddrawer.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#ifndef __2DDRAWER_H
|
||||||
|
#define __2DDRAWER_H
|
||||||
|
|
||||||
|
#include "tarray.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/renderstyle.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
|
struct DrawParms;
|
||||||
|
|
||||||
|
class F2DDrawer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum EDrawType : uint8_t
|
||||||
|
{
|
||||||
|
DrawTypeTriangles,
|
||||||
|
DrawTypeLines,
|
||||||
|
DrawTypePoints,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ETextureDrawMode : uint8_t
|
||||||
|
{
|
||||||
|
DTM_Normal = 0,
|
||||||
|
DTM_Stencil = 1,
|
||||||
|
DTM_Opaque = 2,
|
||||||
|
DTM_AlphaTexture = 3,
|
||||||
|
DTM_Invert = 4,
|
||||||
|
DTM_InvertOpaque = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ETextureFlags : uint8_t
|
||||||
|
{
|
||||||
|
DTF_Wrap = 1,
|
||||||
|
DTF_Scissor = 2,
|
||||||
|
DTF_SpecialColormap = 4,
|
||||||
|
DTF_IngameLighting = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// This vertex type is hardware independent and needs conversion when put into a buffer.
|
||||||
|
struct TwoDVertex
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
float u, v;
|
||||||
|
PalEntry color0;
|
||||||
|
|
||||||
|
void Set(float xx, float zz, float yy)
|
||||||
|
{
|
||||||
|
x = xx;
|
||||||
|
z = zz;
|
||||||
|
y = yy;
|
||||||
|
u = 0;
|
||||||
|
v = 0;
|
||||||
|
color0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(double xx, double zz, double yy, double uu, double vv, PalEntry col)
|
||||||
|
{
|
||||||
|
x = (float)xx;
|
||||||
|
z = (float)zz;
|
||||||
|
y = (float)yy;
|
||||||
|
u = (float)uu;
|
||||||
|
v = (float)vv;
|
||||||
|
color0 = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderCommand
|
||||||
|
{
|
||||||
|
EDrawType mType;
|
||||||
|
int mVertIndex;
|
||||||
|
int mVertCount;
|
||||||
|
int mIndexIndex;
|
||||||
|
int mIndexCount;
|
||||||
|
|
||||||
|
FTexture *mTexture;
|
||||||
|
FRemapTable *mTranslation;
|
||||||
|
int mScissor[4];
|
||||||
|
uint32_t mColorOverlay;
|
||||||
|
int mDesaturate;
|
||||||
|
FRenderStyle mRenderStyle;
|
||||||
|
PalEntry mColor1, mColor2; // Can either be the overlay color or the special colormap ramp. Both features can not be combined.
|
||||||
|
ETextureDrawMode mDrawMode;
|
||||||
|
uint8_t mFlags;
|
||||||
|
|
||||||
|
RenderCommand()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If these fields match, two draw commands can be batched.
|
||||||
|
bool isCompatible(const RenderCommand &other) const
|
||||||
|
{
|
||||||
|
return mTexture == other.mTexture &&
|
||||||
|
mType == other.mType &&
|
||||||
|
mTranslation == other.mTranslation &&
|
||||||
|
!memcmp(mScissor, other.mScissor, sizeof(mScissor)) &&
|
||||||
|
other.mColorOverlay == 0 && mColorOverlay == 0 &&
|
||||||
|
mDesaturate == other.mDesaturate &&
|
||||||
|
mRenderStyle == other.mRenderStyle &&
|
||||||
|
mDrawMode == other.mDrawMode &&
|
||||||
|
mFlags == other.mFlags &&
|
||||||
|
mColor1 == other.mColor1 &&
|
||||||
|
mColor2 == other.mColor2;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TArray<int> mIndices;
|
||||||
|
TArray<TwoDVertex> mVertices;
|
||||||
|
TArray<RenderCommand> mData;
|
||||||
|
|
||||||
|
int AddCommand(const RenderCommand *data);
|
||||||
|
void AddIndices(int firstvert, int count, ...);
|
||||||
|
bool SetStyle(FTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad);
|
||||||
|
void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void AddTexture(FTexture *img, DrawParms &parms);
|
||||||
|
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 AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin);
|
||||||
|
|
||||||
|
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color);
|
||||||
|
|
||||||
|
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 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 Clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -74,6 +74,10 @@ vec4 getTexel(vec2 st)
|
||||||
texel.a = 0.0;
|
texel.a = 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 6: // TM_OPAQUEINVERSE
|
||||||
|
texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, 1.0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (uObjectColor2.a == 0.0) texel *= uObjectColor;
|
if (uObjectColor2.a == 0.0) texel *= uObjectColor;
|
||||||
else texel *= mix(uObjectColor, uObjectColor2, glowdist.z);
|
else texel *= mix(uObjectColor, uObjectColor2, glowdist.z);
|
||||||
|
@ -415,7 +419,7 @@ void main()
|
||||||
|
|
||||||
switch (uFixedColormap)
|
switch (uFixedColormap)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0: // in-game rendering.
|
||||||
{
|
{
|
||||||
float fogdist = 0.0;
|
float fogdist = 0.0;
|
||||||
float fogfactor = 0.0;
|
float fogfactor = 0.0;
|
||||||
|
@ -451,7 +455,7 @@ void main()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1: // special colormap
|
||||||
{
|
{
|
||||||
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
|
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
|
||||||
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
|
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
|
||||||
|
@ -459,13 +463,13 @@ void main()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2: // fullscreen tint.
|
||||||
{
|
{
|
||||||
frag = vColor * frag * uFixedColormapStart;
|
frag = vColor * frag * uFixedColormapStart;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 3:
|
case 3: // fog layer
|
||||||
{
|
{
|
||||||
float fogdist;
|
float fogdist;
|
||||||
float fogfactor;
|
float fogfactor;
|
||||||
|
@ -486,6 +490,20 @@ void main()
|
||||||
frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a);
|
frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 4: // simple 2D
|
||||||
|
{
|
||||||
|
frag = uObjectColor + frag * vColor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5: // 2D with in-game lighting (for textured automap)
|
||||||
|
{
|
||||||
|
frag = frag * vColor;
|
||||||
|
frag.rgb = uObjectColor.rgb + frag.rgb * uObjectColor2.aaa + uObjectColor2.rgb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
FragColor = frag;
|
FragColor = frag;
|
||||||
#ifdef GBUFFER_PASS
|
#ifdef GBUFFER_PASS
|
||||||
|
|
Loading…
Reference in a new issue