mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- refactored all 2D drawing to use its own vertex buffer which does not need to be mapped permanently.
This commit is contained in:
parent
9a5cbbe6d8
commit
def3ad7533
10 changed files with 632 additions and 394 deletions
|
@ -1060,6 +1060,7 @@ set( FASTMATH_SOURCES
|
|||
gl/utility/gl_clock.cpp
|
||||
gl/utility/gl_cycler.cpp
|
||||
gl/utility/gl_geometric.cpp
|
||||
gl/renderer/gl_2ddrawer.cpp
|
||||
gl/renderer/gl_renderer.cpp
|
||||
gl/renderer/gl_renderstate.cpp
|
||||
gl/renderer/gl_renderbuffers.cpp
|
||||
|
|
|
@ -77,22 +77,26 @@ void FSimpleVertexBuffer::BindVBO()
|
|||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
if (gl.glslversion > 0)
|
||||
{
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
|
||||
glDisableVertexAttribArray(VATTR_COLOR);
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->u);
|
||||
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &VSiO->color);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glDisableVertexAttribArray(VATTR_VERTEX2);
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(FSimpleVertex), &VSiO->x);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(FSimpleVertex), &VSiO->u);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSimpleVertex), &VSiO->color);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
void FSimpleVertexBuffer::set(FFlatVertex *verts, int count)
|
||||
void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
gl_RenderState.SetVertexBuffer(this);
|
||||
|
|
|
@ -36,20 +36,37 @@ struct FFlatVertex
|
|||
u = uu;
|
||||
v = vv;
|
||||
}
|
||||
void BindVBO();
|
||||
};
|
||||
|
||||
struct FSimpleVertex
|
||||
{
|
||||
float x, z, y; // world position
|
||||
float u, v; // texture coordinates
|
||||
PalEntry color;
|
||||
|
||||
void Set(float xx, float zz, float yy, float uu = 0, float vv = 0, PalEntry col = 0xffffffff)
|
||||
{
|
||||
x = xx;
|
||||
z = zz;
|
||||
y = yy;
|
||||
u = uu;
|
||||
v = vv;
|
||||
color = col;
|
||||
}
|
||||
};
|
||||
|
||||
#define VTO ((FFlatVertex*)NULL)
|
||||
#define VSiO ((FSimpleVertex*)NULL)
|
||||
|
||||
class FSimpleVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
TArray<FFlatVertex> mBuffer;
|
||||
TArray<FSimpleVertex> mBuffer;
|
||||
public:
|
||||
FSimpleVertexBuffer()
|
||||
{
|
||||
}
|
||||
void BindVBO();
|
||||
void set(FFlatVertex *verts, int count);
|
||||
void set(FSimpleVertex *verts, int count);
|
||||
};
|
||||
|
||||
class FFlatVertexBuffer : public FVertexBuffer
|
||||
|
|
488
src/gl/renderer/gl_2ddrawer.cpp
Normal file
488
src/gl/renderer/gl_2ddrawer.cpp
Normal file
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
** gl_2ddrawer.h
|
||||
** Container class for drawing 2d graphics with a vertex buffer
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2016 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU Lesser General Public License as published
|
||||
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
** your option) any later version.
|
||||
** 5. Full disclosure of the entire project's source code, except for third
|
||||
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "vectors.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int F2DDrawer::AddData(const F2DDrawer::DataGeneric *data)
|
||||
{
|
||||
int addr = mData.Reserve(data->mLen);
|
||||
memcpy(&mData[addr], data, data->mLen);
|
||||
mLastLineCmd = -1;
|
||||
return addr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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;
|
||||
float u1, v1, u2, v2;
|
||||
int light = 255;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
|
||||
if (gltex == nullptr) return;
|
||||
|
||||
DataTexture dg;
|
||||
|
||||
dg.mType = DrawTypeTexture;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mRenderStyle = parms.style;
|
||||
dg.mMasked = !!parms.masked;
|
||||
dg.mTexture = gltex;
|
||||
|
||||
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
|
||||
{
|
||||
// handle black overlays as reduced light.
|
||||
light = 255 - APART(parms.colorOverlay);
|
||||
parms.colorOverlay = 0;
|
||||
}
|
||||
dg.mVertIndex = (int)mVertices.Reserve(parms.colorOverlay == 0? 4 : 8);
|
||||
dg.mColorOverlay = parms.colorOverlay;
|
||||
dg.mTranslation = 0;
|
||||
|
||||
if (!img->bHasCanvas)
|
||||
{
|
||||
if (!parms.alphaChannel)
|
||||
{
|
||||
if (parms.remap != NULL && !parms.remap->Inactive)
|
||||
{
|
||||
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
|
||||
if (pal) dg.mTranslation = -pal->GetIndex();
|
||||
}
|
||||
}
|
||||
dg.mAlphaTexture = !!(parms.style.Flags & STYLEF_RedIsAlpha);
|
||||
u1 = gltex->GetUL();
|
||||
v1 = gltex->GetVT();
|
||||
u2 = gltex->GetUR();
|
||||
v2 = gltex->GetVB();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
dg.mAlphaTexture = false;
|
||||
u1 = 0.f;
|
||||
v1 = 1.f;
|
||||
u2 = 1.f;
|
||||
v2 = 0.f;
|
||||
}
|
||||
|
||||
if (parms.flipX)
|
||||
std::swap(u1, u2);
|
||||
|
||||
|
||||
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
||||
{
|
||||
double wi = MIN(parms.windowright, parms.texwidth);
|
||||
x += parms.windowleft * xscale;
|
||||
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
|
||||
|
||||
u1 = float(u1 + parms.windowleft / parms.texwidth);
|
||||
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
|
||||
}
|
||||
|
||||
PalEntry color;
|
||||
if (parms.style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
color = parms.fillcolor;
|
||||
std::swap(color.r, color.b);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = PalEntry(light, light, light);
|
||||
}
|
||||
color.a = (BYTE)(parms.Alpha * 255);
|
||||
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
|
||||
btm = SCREENHEIGHT - btm;
|
||||
|
||||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight() - screen->GetHeight()) / 2;
|
||||
dg.mScissor[0] = parms.lclip;
|
||||
dg.mScissor[1] = btm - parms.dclip + space;
|
||||
dg.mScissor[2] = parms.rclip - parms.lclip;
|
||||
dg.mScissor[3] = parms.dclip - parms.uclip;
|
||||
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
|
||||
if (parms.colorOverlay != 0)
|
||||
{
|
||||
color = parms.colorOverlay;
|
||||
std::swap(color.r, color.b);
|
||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
|
||||
}
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel)
|
||||
{
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
|
||||
|
||||
if (gltexture == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DataSimplePoly poly;
|
||||
|
||||
poly.mType = DrawTypePoly;
|
||||
poly.mLen = (sizeof(poly) + 7) & ~7;
|
||||
poly.mTexture = gltexture;
|
||||
poly.mColormap = colormap;
|
||||
poly.mLightLevel = lightlevel;
|
||||
poly.mVertCount = npoints;
|
||||
poly.mVertIndex = (int)mVertices.Reserve(npoints);
|
||||
|
||||
bool dorotate = rotation != 0;
|
||||
|
||||
float cosrot = cos(rotation.Radians());
|
||||
float sinrot = sin(rotation.Radians());
|
||||
|
||||
float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
|
||||
float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
|
||||
if (texture->bHasCanvas)
|
||||
{
|
||||
vscale = 0 - vscale;
|
||||
}
|
||||
float ox = float(originx);
|
||||
float oy = float(originy);
|
||||
|
||||
for (int i = 0; i < npoints; ++i)
|
||||
{
|
||||
float u = points[i].X - 0.5f - ox;
|
||||
float v = points[i].Y - 0.5f - oy;
|
||||
if (dorotate)
|
||||
{
|
||||
float t = u;
|
||||
u = t * cosrot - v * sinrot;
|
||||
v = v * cosrot + t * sinrot;
|
||||
}
|
||||
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
|
||||
}
|
||||
AddData(&poly);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void F2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
color.a = uint8_t(damount * 255);
|
||||
std::swap(color.r, color.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypeDim;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(x1, y1, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++;
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32 color)
|
||||
{
|
||||
PalEntry p = palcolor == -1 || color != 0 ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
AddDim(p, 1.f, left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||
{
|
||||
float fU1, fU2, fV1, fV2;
|
||||
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(src, false);
|
||||
|
||||
if (!gltexture) return;
|
||||
|
||||
DataFlatFill dg;
|
||||
|
||||
dg.mType = DrawTypeFlatFill;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
dg.mTexture = gltexture;
|
||||
|
||||
// scaling is not used here.
|
||||
if (!local_origin)
|
||||
{
|
||||
fU1 = float(left) / src->GetWidth();
|
||||
fV1 = float(top) / src->GetHeight();
|
||||
fU2 = float(right) / src->GetWidth();
|
||||
fV2 = float(bottom) / src->GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
fU1 = 0;
|
||||
fV1 = 0;
|
||||
fU2 = float(right - left) / src->GetWidth();
|
||||
fV2 = float(bottom - top) / src->GetHeight();
|
||||
}
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(left, top, 0, fU1, fV1); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1); ptr++;
|
||||
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color)
|
||||
{
|
||||
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
p.a = 255;
|
||||
std::swap(p.r, p.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypeLine;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 2;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(2);
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p);
|
||||
|
||||
// Test if we can batch multiple line commands
|
||||
if (mLastLineCmd == -1)
|
||||
{
|
||||
mLastLineCmd = AddData(&dg);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataGeneric *dg = (DataGeneric *)&mData[mLastLineCmd];
|
||||
dg->mVertCount += 2;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32 color)
|
||||
{
|
||||
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
p.a = 255;
|
||||
std::swap(p.r, p.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypePixel;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 2;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(1);
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::Flush()
|
||||
{
|
||||
if (mData.Size() == 0) return;
|
||||
SBYTE savedlightmode = glset.lightmode;
|
||||
// lightmode is only relevant for automap subsectors,
|
||||
// but We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering.
|
||||
if (glset.lightmode == 8) glset.lightmode = 0;
|
||||
|
||||
set(&mVertices[0], mVertices.Size());
|
||||
for (unsigned i = 0; i < mData.Size();)
|
||||
{
|
||||
DataGeneric *dg = (DataGeneric *)&mData[i];
|
||||
switch (dg->mType)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case DrawTypeTexture:
|
||||
{
|
||||
DataTexture *dt = static_cast<DataTexture*>(dg);
|
||||
|
||||
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
|
||||
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
|
||||
if (dt->mTexture->tex->bHasCanvas) gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex, 4);
|
||||
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
if (dt->mVertCount > 4)
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4);
|
||||
}
|
||||
|
||||
glScissor(0, 0, screen->GetWidth(), screen->GetHeight());
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypePoly:
|
||||
{
|
||||
DataSimplePoly *dsp = static_cast<DataSimplePoly*>(dg);
|
||||
|
||||
FColormap cm;
|
||||
cm = dsp->mColormap;
|
||||
gl_SetColor(dsp->mLightLevel, 0, cm, 1.f);
|
||||
gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypeFlatFill:
|
||||
{
|
||||
DataFlatFill *dff = static_cast<DataFlatFill*>(dg);
|
||||
gl_RenderState.SetMaterial(dff->mTexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dg->mVertIndex, dg->mVertCount);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypeDim:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER, 0);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
case DrawTypeLine:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_LINES, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
case DrawTypePixel:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_POINTS, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
}
|
||||
i += dg->mLen;
|
||||
}
|
||||
mVertices.Clear();
|
||||
mData.Clear();
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
glset.lightmode = savedlightmode;
|
||||
}
|
||||
|
||||
|
73
src/gl/renderer/gl_2ddrawer.h
Normal file
73
src/gl/renderer/gl_2ddrawer.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#ifndef __2DDRAWER_H
|
||||
#define __2DDRAWER_H
|
||||
|
||||
#include "tarray.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
class F2DDrawer : public FSimpleVertexBuffer
|
||||
{
|
||||
enum EDrawType
|
||||
{
|
||||
DrawTypeTexture,
|
||||
DrawTypeDim,
|
||||
DrawTypeFlatFill,
|
||||
DrawTypePoly,
|
||||
DrawTypeLine,
|
||||
DrawTypePixel
|
||||
};
|
||||
|
||||
struct DataGeneric
|
||||
{
|
||||
EDrawType mType;
|
||||
uint32_t mLen;
|
||||
int mVertIndex;
|
||||
int mVertCount;
|
||||
};
|
||||
|
||||
struct DataTexture : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
int mScissor[4];
|
||||
uint32_t mColorOverlay;
|
||||
int mTranslation;
|
||||
FRenderStyle mRenderStyle;
|
||||
bool mMasked;
|
||||
bool mAlphaTexture;
|
||||
};
|
||||
|
||||
struct DataFlatFill : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
};
|
||||
|
||||
struct DataSimplePoly : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
int mLightLevel;
|
||||
FDynamicColormap *mColormap;
|
||||
};
|
||||
|
||||
TArray<FSimpleVertex> mVertices;
|
||||
TArray<uint8_t> mData;
|
||||
int mLastLineCmd = -1; // consecutive lines can be batched into a single draw call so keep this info around.
|
||||
|
||||
int AddData(const DataGeneric *data);
|
||||
|
||||
public:
|
||||
void AddTexture(FTexture *img, DrawParms &parms);
|
||||
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
|
||||
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32 color);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin);
|
||||
|
||||
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel);
|
||||
|
||||
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
||||
void AddPixel(int x1, int y1, int palcolor, uint32 color);
|
||||
|
||||
void Flush();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -71,6 +71,7 @@
|
|||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
#include "gl/shaders/gl_lensshader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -283,6 +284,7 @@ void FGLRenderer::LensDistortScene()
|
|||
|
||||
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||
{
|
||||
m2DDrawer->Flush(); // draw all pending 2D stuff before copying the buffer
|
||||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
@ -106,6 +107,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mShaderManager = NULL;
|
||||
gllight = glpart2 = glpart = mirrortexture = NULL;
|
||||
mLights = NULL;
|
||||
m2DDrawer = nullptr;
|
||||
}
|
||||
|
||||
void gl_LoadModels();
|
||||
|
@ -120,6 +122,7 @@ void FGLRenderer::Initialize()
|
|||
mTonemapShader = new FTonemapShader();
|
||||
mLensShader = new FLensShader();
|
||||
mPresentShader = new FPresentShader();
|
||||
m2DDrawer = new F2DDrawer;
|
||||
|
||||
// Only needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||
if (gl.version >= 4.0)
|
||||
|
@ -153,6 +156,7 @@ FGLRenderer::~FGLRenderer()
|
|||
gl_FlushModels();
|
||||
gl_DeleteAllAttachedLights();
|
||||
FMaterial::FlushAll();
|
||||
if (m2DDrawer != nullptr) delete m2DDrawer;
|
||||
if (mShaderManager != NULL) delete mShaderManager;
|
||||
if (mSamplerManager != NULL) delete mSamplerManager;
|
||||
if (mVBO != NULL) delete mVBO;
|
||||
|
@ -378,366 +382,13 @@ void FGLRenderer::ClearBorders()
|
|||
int borderHeight = (trueHeight - height) / 2;
|
||||
|
||||
glViewport(0, 0, width, trueHeight);
|
||||
gl_RenderState.mProjectionMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.ortho(0.0f, width * 1.0f, 0.0f, trueHeight, -1.0f, 1.0f);
|
||||
gl_RenderState.SetColor(0.f ,0.f ,0.f ,1.f);
|
||||
gl_RenderState.Set2DMode(true);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(0, 0, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, 0, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, borderHeight, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
ptr->Set(0, trueHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, trueHeight, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(0, 0, width, borderHeight);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glScissor(0, trueHeight-borderHeight, width, borderHeight);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glViewport(0, (trueHeight - height) / 2, width, height);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Draws a texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::DrawTexture(FTexture *img, DrawParms &parms)
|
||||
{
|
||||
double xscale = parms.destwidth / parms.texwidth;
|
||||
double yscale = parms.destheight / parms.texheight;
|
||||
double x = parms.x - parms.left * xscale;
|
||||
double y = parms.y - parms.top * yscale;
|
||||
double w = parms.destwidth;
|
||||
double h = parms.destheight;
|
||||
float u1, v1, u2, v2;
|
||||
int light = 255;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
|
||||
|
||||
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
|
||||
{
|
||||
// Right now there's only black. Should be implemented properly later
|
||||
light = 255 - APART(parms.colorOverlay);
|
||||
parms.colorOverlay = 0;
|
||||
}
|
||||
|
||||
gl_SetRenderStyle(parms.style, !parms.masked, false);
|
||||
if (!img->bHasCanvas)
|
||||
{
|
||||
int translation = 0;
|
||||
if (!parms.alphaChannel)
|
||||
{
|
||||
if (parms.remap != NULL && !parms.remap->Inactive)
|
||||
{
|
||||
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
|
||||
if (pal) translation = -pal->GetIndex();
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, -1, !!(parms.style.Flags & STYLEF_RedIsAlpha));
|
||||
|
||||
u1 = gltex->GetUL();
|
||||
v1 = gltex->GetVT();
|
||||
u2 = gltex->GetUR();
|
||||
v2 = gltex->GetVB();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false);
|
||||
u1 = 0.f;
|
||||
v1 = 1.f;
|
||||
u2 = 1.f;
|
||||
v2 = 0.f;
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
}
|
||||
|
||||
if (parms.flipX)
|
||||
{
|
||||
float temp = u1;
|
||||
u1 = u2;
|
||||
u2 = temp;
|
||||
}
|
||||
|
||||
|
||||
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
||||
{
|
||||
double wi = MIN(parms.windowright, parms.texwidth);
|
||||
x += parms.windowleft * xscale;
|
||||
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
|
||||
|
||||
u1 = float(u1 + parms.windowleft / parms.texwidth);
|
||||
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
|
||||
}
|
||||
|
||||
PalEntry color;
|
||||
if (parms.style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
color = parms.fillcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = PalEntry(light, light, light);
|
||||
}
|
||||
color.a = (BYTE)(parms.Alpha * 255);
|
||||
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
|
||||
btm = SCREENHEIGHT - btm;
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2;
|
||||
glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip);
|
||||
|
||||
gl_RenderState.SetColor(color);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x, y, 0, u1, v1); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
if (parms.colorOverlay)
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
gl_RenderState.SetColor(PalEntry(parms.colorOverlay));
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x, y, 0, u1, v1); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
glScissor(0, 0, screen->GetWidth(), screen->GetHeight());
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color)
|
||||
{
|
||||
PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.SetColorAlpha(p, 1.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
ptr->Set(x2, y2, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_LINES);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
|
||||
{
|
||||
PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.SetColorAlpha(p, 1.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER,0);
|
||||
gl_RenderState.SetColorAlpha(color, damount);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1, y1+h, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1+w, y1, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||
{
|
||||
float fU1,fU2,fV1,fV2;
|
||||
|
||||
FMaterial *gltexture=FMaterial::ValidateTexture(src, false);
|
||||
|
||||
if (!gltexture) return;
|
||||
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
// 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();
|
||||
}
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(left, top, 0, fU1, fV1); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1); ptr++;
|
||||
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderer::Clear(int left, int top, int right, int bottom, int palcolor, uint32 color)
|
||||
{
|
||||
int rt;
|
||||
int offY = 0;
|
||||
PalEntry p = palcolor==-1 || color != 0? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
int width = right-left;
|
||||
int height= bottom-top;
|
||||
|
||||
|
||||
rt = screen->GetHeight() - top;
|
||||
|
||||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2; // ugh...
|
||||
rt += space;
|
||||
/*
|
||||
if (!m_windowed && (m_trueHeight != m_height))
|
||||
{
|
||||
offY = (m_trueHeight - m_height) / 2;
|
||||
rt += offY;
|
||||
}
|
||||
*/
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(left, rt - height, width, height);
|
||||
|
||||
glClearColor(p.r/255.0f, p.g/255.0f, p.b/255.0f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: FillSimplePoly
|
||||
//
|
||||
// Here, "simple" means that a simple triangle fan can draw it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel)
|
||||
{
|
||||
if (npoints < 3)
|
||||
{ // This is no polygon.
|
||||
return;
|
||||
}
|
||||
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
|
||||
|
||||
if (gltexture == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FColormap cm;
|
||||
cm = colormap;
|
||||
|
||||
// We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering.
|
||||
SBYTE savedlightmode = glset.lightmode;
|
||||
if (glset.lightmode == 8) glset.lightmode = 0;
|
||||
|
||||
gl_SetColor(lightlevel, 0, cm, 1.f);
|
||||
|
||||
glset.lightmode = savedlightmode;
|
||||
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
int i;
|
||||
bool dorotate = rotation != 0;
|
||||
|
||||
float cosrot = cos(rotation.Radians());
|
||||
float sinrot = sin(rotation.Radians());
|
||||
|
||||
//float yoffs = GatheringWipeScreen ? 0 : LBOffset;
|
||||
float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
|
||||
float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
|
||||
if (gltexture->tex->bHasCanvas)
|
||||
{
|
||||
vscale = 0 - vscale;
|
||||
}
|
||||
float ox = float(originx);
|
||||
float oy = float(originy);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (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;
|
||||
}
|
||||
ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
|
||||
ptr++;
|
||||
}
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ class FBlurShader;
|
|||
class FTonemapShader;
|
||||
class FLensShader;
|
||||
class FPresentShader;
|
||||
class F2DDrawer;
|
||||
|
||||
inline float DEG2RAD(float deg)
|
||||
{
|
||||
|
@ -107,6 +108,7 @@ public:
|
|||
FFlatVertexBuffer *mVBO;
|
||||
FSkyVertexBuffer *mSkyVBO;
|
||||
FLightBuffer *mLights;
|
||||
F2DDrawer *m2DDrawer;
|
||||
|
||||
GL_IRECT mScreenViewport;
|
||||
GL_IRECT mOutputViewportLB;
|
||||
|
@ -142,12 +144,6 @@ public:
|
|||
|
||||
void Begin2D();
|
||||
void ClearBorders();
|
||||
void DrawTexture(FTexture *img, DrawParms &parms);
|
||||
void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
||||
void DrawPixel(int x1, int y1, int palcolor, uint32 color);
|
||||
void Dim(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);
|
||||
void Clear(int left, int top, int right, int bottom, int palcolor, uint32 color);
|
||||
|
||||
void ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector);
|
||||
void ProcessSprite(AActor *thing, sector_t *sector, bool thruportal);
|
||||
|
@ -175,6 +171,9 @@ public:
|
|||
bool StartOffscreen();
|
||||
void EndOffscreen();
|
||||
|
||||
void StartSimplePolys();
|
||||
void FinishSimplePolys();
|
||||
|
||||
void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel);
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
|
||||
IMPLEMENT_CLASS(OpenGLFrameBuffer)
|
||||
EXTERN_CVAR (Float, vid_brightness)
|
||||
|
@ -386,7 +387,8 @@ bool OpenGLFrameBuffer::Begin2D(bool)
|
|||
|
||||
void OpenGLFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||
{
|
||||
if (GLRenderer != NULL) GLRenderer->DrawTexture(img, parms);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddTexture(img, parms);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -396,8 +398,8 @@ void OpenGLFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms)
|
|||
//==========================================================================
|
||||
void OpenGLFrameBuffer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color)
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->DrawLine(x1, y1, x2, y2, palcolor, color);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddLine(x1, y1, x2, y2, palcolor, color);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -407,8 +409,8 @@ void OpenGLFrameBuffer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, u
|
|||
//==========================================================================
|
||||
void OpenGLFrameBuffer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->DrawPixel(x1, y1, palcolor, color);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddPixel(x1, y1, palcolor, color);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -425,8 +427,8 @@ void OpenGLFrameBuffer::Dim(PalEntry)
|
|||
|
||||
void OpenGLFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->Dim(color, damount, x1, y1, w, h);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -437,8 +439,8 @@ void OpenGLFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w
|
|||
void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||
{
|
||||
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->FlatFill(left, top, right, bottom, src, local_origin);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddFlatFill(left, top, right, bottom, src, local_origin);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -448,8 +450,8 @@ void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTex
|
|||
//==========================================================================
|
||||
void OpenGLFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32 color)
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->Clear(left, top, right, bottom, palcolor, color);
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -464,10 +466,9 @@ void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int
|
|||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, FDynamicColormap *colormap, int lightlevel)
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr && npoints >= 3)
|
||||
{
|
||||
GLRenderer->FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley,
|
||||
rotation, colormap, lightlevel);
|
||||
GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
struct POINT {
|
||||
|
@ -187,6 +188,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
|
||||
void OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->m2DDrawer->Flush();
|
||||
wipeendscreen = new FHardwareTexture(Width, Height, true);
|
||||
wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
||||
|
@ -288,8 +290,8 @@ OpenGLFrameBuffer::Wiper::~Wiper()
|
|||
|
||||
void OpenGLFrameBuffer::Wiper::MakeVBO(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
FFlatVertex make[4];
|
||||
FFlatVertex *ptr = make;
|
||||
FSimpleVertex make[4];
|
||||
FSimpleVertex *ptr = make;
|
||||
|
||||
float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
|
@ -380,8 +382,8 @@ OpenGLFrameBuffer::Wiper_Melt::Wiper_Melt()
|
|||
|
||||
int OpenGLFrameBuffer::Wiper_Melt::MakeVBO(int ticks, OpenGLFrameBuffer *fb, bool &done)
|
||||
{
|
||||
FFlatVertex *make = new FFlatVertex[321*4];
|
||||
FFlatVertex *ptr = make;
|
||||
FSimpleVertex *make = new FSimpleVertex[321*4];
|
||||
FSimpleVertex *ptr = make;
|
||||
int dy;
|
||||
|
||||
float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
|
|
Loading…
Reference in a new issue