mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- another backend update, pulling in the sky renderer.
This commit is contained in:
parent
efa1cd3048
commit
1d15fe63a6
19 changed files with 1197 additions and 126 deletions
|
@ -883,6 +883,7 @@ set (PCH_SOURCES
|
|||
common/rendering/hwrenderer/data/hw_vrmodes.cpp
|
||||
common/rendering/hwrenderer/data/hw_lightbuffer.cpp
|
||||
common/rendering/hwrenderer/data/hw_aabbtree.cpp
|
||||
common/rendering/hwrenderer/data/hw_skydome.cpp
|
||||
common/rendering/hwrenderer/data/hw_shadowmap.cpp
|
||||
common/rendering/hwrenderer/data/hw_shaderpatcher.cpp
|
||||
common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp
|
||||
|
@ -938,6 +939,7 @@ set (PCH_SOURCES
|
|||
core/input/m_joy.cpp
|
||||
|
||||
core/rendering/gl/renderer/gl_renderer.cpp
|
||||
core/rendering/gl/renderer/gl_stereo3d.cpp
|
||||
core/rendering/gl/system/gl_framebuffer.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "v_video.h"
|
||||
#include "flatvertices.h"
|
||||
#include "texturemanager.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
static int32_t curextra=MAXTILES;
|
||||
|
@ -1475,7 +1476,7 @@ static void md3draw_handle_triangles(const md3surf_t *s, uint16_t *indexhandle,
|
|||
vt->SetVertex(vertlist[k].x, vertlist[k].y);
|
||||
}
|
||||
}
|
||||
GLInterface.Draw(DT_TRIANGLES, data.second, s->numtris *3);
|
||||
GLInterface.Draw(DT_Triangles, data.second, s->numtris *3);
|
||||
|
||||
#ifndef USE_GLEXT
|
||||
UNREFERENCED_PARAMETER(texunits);
|
||||
|
|
|
@ -20,7 +20,7 @@ Ken Silverman's official web site: http://www.advsys.net/ken
|
|||
#include "flatvertices.h"
|
||||
#include "palettecontainer.h"
|
||||
#include "texturemanager.h"
|
||||
#include "gamecontrol.h"
|
||||
#include "hw_renderstate.h"
|
||||
|
||||
CVAR(Bool, hw_detailmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, hw_glowmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -479,7 +479,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
|
|||
r * (1.f / 1024.f));
|
||||
|
||||
}
|
||||
GLInterface.Draw(DT_TRIANGLE_FAN, data.second, npoints);
|
||||
GLInterface.Draw(DT_TriangleFan, data.second, npoints);
|
||||
|
||||
GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
|
||||
GLInterface.UseDetailMapping(false);
|
||||
|
@ -491,7 +491,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
|
|||
vec3d_t const bxtex = xtex, bytex = ytex, botex = otex;
|
||||
xtex = xtex2, ytex = ytex2, otex = otex2;
|
||||
GLInterface.SetColorMask(false);
|
||||
GLInterface.Draw(DT_TRIANGLE_FAN, data.second, npoints);
|
||||
GLInterface.Draw(DT_TriangleFan, data.second, npoints);
|
||||
GLInterface.SetColorMask(true);
|
||||
xtex = bxtex, ytex = bytex, otex = botex;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mdsprite.h"
|
||||
#include "v_video.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
#include "palette.h"
|
||||
|
@ -1174,7 +1175,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
|
|||
f = 1 /*clut[fi++]*/;
|
||||
if (qdone > 0)
|
||||
{
|
||||
GLInterface.Draw(DT_TRIANGLES, qstart, qdone * 6);
|
||||
GLInterface.Draw(DT_Triangles, qstart, qdone * 6);
|
||||
qstart += qdone * 6;
|
||||
qdone = 0;
|
||||
}
|
||||
|
@ -1205,7 +1206,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
|
|||
qdone++;
|
||||
}
|
||||
|
||||
GLInterface.Draw(DT_TRIANGLES, qstart, qdone * 6);
|
||||
GLInterface.Draw(DT_Triangles, qstart, qdone * 6);
|
||||
GLInterface.SetClamp(prevClamp);
|
||||
//------------
|
||||
GLInterface.SetCull(Cull_None);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
#pragma once
|
||||
#include "renderstyle.h"
|
||||
#include "matrix.h"
|
||||
#include "model.h"
|
||||
|
|
|
@ -87,7 +87,7 @@ struct FStateVec4
|
|||
|
||||
struct FMaterialState
|
||||
{
|
||||
FMaterial *mMaterial;
|
||||
FMaterial *mMaterial = nullptr;
|
||||
int mClampMode;
|
||||
int mTranslation;
|
||||
int mOverrideShader;
|
||||
|
|
482
source/common/rendering/hwrenderer/data/hw_skydome.cpp
Normal file
482
source/common/rendering/hwrenderer/data/hw_skydome.cpp
Normal file
|
@ -0,0 +1,482 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2003-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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
**
|
||||
** Draws the sky. Loosely based on the JDoom sky and the ZDoomGL 0.66.2 sky.
|
||||
**
|
||||
** for FSkyVertexBuffer::SkyVertex only:
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2003 Tim Stump
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
#include "bitmap.h"
|
||||
#include "skyboxtexture.h"
|
||||
#include "hw_material.h"
|
||||
#include "hw_skydome.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "v_video.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
|
||||
// 57 world units roughly represent one sky texel for the glTranslate call.
|
||||
enum
|
||||
{
|
||||
skyoffsetfactor = 57
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Shamelessly lifted from Doomsday (written by Jaakko Keränen)
|
||||
// also shamelessly lifted from ZDoomGL! ;)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVAR(Float, skyoffset, 0, 0) // for testing
|
||||
|
||||
|
||||
struct SkyColor
|
||||
{
|
||||
FTextureID Texture;
|
||||
std::pair<PalEntry, PalEntry> Colors;
|
||||
};
|
||||
|
||||
static TArray<SkyColor> SkyColors;
|
||||
|
||||
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex)
|
||||
{
|
||||
for (auto& sky : SkyColors)
|
||||
{
|
||||
if (sky.Texture == tex->GetID()) return sky.Colors;
|
||||
}
|
||||
|
||||
auto itex = tex->GetTexture();
|
||||
SkyColor sky;
|
||||
|
||||
FBitmap bitmap = itex->GetBgraBitmap(nullptr);
|
||||
int w = bitmap.GetWidth();
|
||||
int h = bitmap.GetHeight();
|
||||
|
||||
const uint32_t* buffer = (const uint32_t*)bitmap.GetPixels();
|
||||
if (buffer)
|
||||
{
|
||||
sky.Colors.first = averageColor((uint32_t*)buffer, w * MIN(30, h), 0);
|
||||
if (h > 30)
|
||||
{
|
||||
sky.Colors.second = averageColor(((uint32_t*)buffer) + (h - 30) * w, w * 30, 0);
|
||||
}
|
||||
else sky.Colors.second = sky.Colors.first;
|
||||
}
|
||||
sky.Texture = tex->GetID();
|
||||
SkyColors.Push(sky);
|
||||
|
||||
return SkyColors.Last().Colors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FSkyVertexBuffer::FSkyVertexBuffer()
|
||||
{
|
||||
CreateDome();
|
||||
mVertexBuffer = screen->CreateVertexBuffer();
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FSkyVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FSkyVertex, u) },
|
||||
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) }
|
||||
};
|
||||
mVertexBuffer->SetFormat(1, 3, sizeof(FSkyVertex), format);
|
||||
mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], true);
|
||||
}
|
||||
|
||||
FSkyVertexBuffer::~FSkyVertexBuffer()
|
||||
{
|
||||
delete mVertexBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
||||
{
|
||||
static const FAngle maxSideAngle = 60.f;
|
||||
static const float scale = 10000.;
|
||||
|
||||
FAngle topAngle = (c / (float)mColumns * 360.f);
|
||||
FAngle sideAngle = maxSideAngle * float(mRows - r) / float(mRows);
|
||||
float height = sideAngle.Sin();
|
||||
float realRadius = scale * sideAngle.Cos();
|
||||
FVector2 pos = topAngle.ToVector(realRadius);
|
||||
float z = (!zflip) ? scale * height : -scale * height;
|
||||
|
||||
FSkyVertex vert;
|
||||
|
||||
vert.color = r == 0 ? 0xffffff : 0xffffffff;
|
||||
|
||||
// And the texture coordinates.
|
||||
if (!zflip) // Flipped Y is for the lower hemisphere.
|
||||
{
|
||||
vert.u = (-c / (float)mColumns);
|
||||
vert.v = (r / (float)mRows);
|
||||
}
|
||||
else
|
||||
{
|
||||
vert.u = (-c / (float)mColumns);
|
||||
vert.v = 1.0f + ((mRows - r) / (float)mRows);
|
||||
}
|
||||
|
||||
if (r != 4) z += 300;
|
||||
// And finally the vertex.
|
||||
vert.x = -pos.X; // Doom mirrors the sky vertically!
|
||||
vert.y = z - 1.f;
|
||||
vert.z = pos.Y;
|
||||
|
||||
mVertices.Push(vert);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::CreateSkyHemisphere(int hemi)
|
||||
{
|
||||
int r, c;
|
||||
bool zflip = !!(hemi & SKYHEMI_LOWER);
|
||||
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
|
||||
for (c = 0; c < mColumns; c++)
|
||||
{
|
||||
SkyVertex(1, c, zflip);
|
||||
}
|
||||
|
||||
// The total number of triangles per hemisphere can be calculated
|
||||
// as follows: rows * columns * 2 + 2 (for the top cap).
|
||||
for (r = 0; r < mRows; r++)
|
||||
{
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
for (c = 0; c <= mColumns; c++)
|
||||
{
|
||||
SkyVertex(r + zflip, c, zflip);
|
||||
SkyVertex(r + 1 - zflip, c, zflip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::CreateDome()
|
||||
{
|
||||
// the first thing we put into the buffer is the fog layer object which is just 4 triangles around the viewpoint.
|
||||
|
||||
mVertices.Reserve(12);
|
||||
mVertices[0].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[1].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[2].Set(-1.0f, 0.0f, -1.0f);
|
||||
|
||||
mVertices[3].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[4].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[5].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[6].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[7].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[8].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[9].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[10].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[11].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mColumns = 128;
|
||||
mRows = 4;
|
||||
CreateSkyHemisphere(SKYHEMI_UPPER);
|
||||
CreateSkyHemisphere(SKYHEMI_LOWER);
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
|
||||
mSideStart = mVertices.Size();
|
||||
mFaceStart[0] = mSideStart + 10;
|
||||
mFaceStart[1] = mFaceStart[0] + 4;
|
||||
mFaceStart[2] = mFaceStart[1] + 4;
|
||||
mFaceStart[3] = mFaceStart[2] + 4;
|
||||
mFaceStart[4] = mFaceStart[3] + 4;
|
||||
mFaceStart[5] = mFaceStart[4] + 4;
|
||||
mFaceStart[6] = mFaceStart[5] + 4;
|
||||
mVertices.Reserve(10 + 7*4);
|
||||
FSkyVertex *ptr = &mVertices[mSideStart];
|
||||
|
||||
// all sides
|
||||
ptr[0].SetXYZ(128.f, 128.f, -128.f, 0, 0);
|
||||
ptr[1].SetXYZ(128.f, -128.f, -128.f, 0, 1);
|
||||
ptr[2].SetXYZ(-128.f, 128.f, -128.f, 0.25f, 0);
|
||||
ptr[3].SetXYZ(-128.f, -128.f, -128.f, 0.25f, 1);
|
||||
ptr[4].SetXYZ(-128.f, 128.f, 128.f, 0.5f, 0);
|
||||
ptr[5].SetXYZ(-128.f, -128.f, 128.f, 0.5f, 1);
|
||||
ptr[6].SetXYZ(128.f, 128.f, 128.f, 0.75f, 0);
|
||||
ptr[7].SetXYZ(128.f, -128.f, 128.f, 0.75f, 1);
|
||||
ptr[8].SetXYZ(128.f, 128.f, -128.f, 1, 0);
|
||||
ptr[9].SetXYZ(128.f, -128.f, -128.f, 1, 1);
|
||||
|
||||
// north face
|
||||
ptr[10].SetXYZ(128.f, 128.f, -128.f, 0, 0);
|
||||
ptr[11].SetXYZ(-128.f, 128.f, -128.f, 1, 0);
|
||||
ptr[12].SetXYZ(128.f, -128.f, -128.f, 0, 1);
|
||||
ptr[13].SetXYZ(-128.f, -128.f, -128.f, 1, 1);
|
||||
|
||||
// east face
|
||||
ptr[14].SetXYZ(-128.f, 128.f, -128.f, 0, 0);
|
||||
ptr[15].SetXYZ(-128.f, 128.f, 128.f, 1, 0);
|
||||
ptr[16].SetXYZ(-128.f, -128.f, -128.f, 0, 1);
|
||||
ptr[17].SetXYZ(-128.f, -128.f, 128.f, 1, 1);
|
||||
|
||||
// south face
|
||||
ptr[18].SetXYZ(-128.f, 128.f, 128.f, 0, 0);
|
||||
ptr[19].SetXYZ(128.f, 128.f, 128.f, 1, 0);
|
||||
ptr[20].SetXYZ(-128.f, -128.f, 128.f, 0, 1);
|
||||
ptr[21].SetXYZ(128.f, -128.f, 128.f, 1, 1);
|
||||
|
||||
// west face
|
||||
ptr[22].SetXYZ(128.f, 128.f, 128.f, 0, 0);
|
||||
ptr[23].SetXYZ(128.f, 128.f, -128.f, 1, 0);
|
||||
ptr[24].SetXYZ(128.f, -128.f, 128.f, 0, 1);
|
||||
ptr[25].SetXYZ(128.f, -128.f, -128.f, 1, 1);
|
||||
|
||||
// bottom face
|
||||
ptr[26].SetXYZ(128.f, -128.f, -128.f, 0, 0);
|
||||
ptr[27].SetXYZ(-128.f, -128.f, -128.f, 1, 0);
|
||||
ptr[28].SetXYZ(128.f, -128.f, 128.f, 0, 1);
|
||||
ptr[29].SetXYZ(-128.f, -128.f, 128.f, 1, 1);
|
||||
|
||||
// top face
|
||||
ptr[30].SetXYZ(128.f, 128.f, -128.f, 0, 0);
|
||||
ptr[31].SetXYZ(-128.f, 128.f, -128.f, 1, 0);
|
||||
ptr[32].SetXYZ(128.f, 128.f, 128.f, 0, 1);
|
||||
ptr[33].SetXYZ(-128.f, 128.f, 128.f, 1, 1);
|
||||
|
||||
// top face flipped
|
||||
ptr[34].SetXYZ(128.f, 128.f, -128.f, 0, 1);
|
||||
ptr[35].SetXYZ(-128.f, 128.f, -128.f, 1, 1);
|
||||
ptr[36].SetXYZ(128.f, 128.f, 128.f, 0, 0);
|
||||
ptr[37].SetXYZ(-128.f, 128.f, 128.f, 1, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelMatrix, VSMatrix &textureMatrix, bool tiled)
|
||||
{
|
||||
float texw = tex->GetDisplayWidth();
|
||||
float texh = tex->GetDisplayHeight();
|
||||
|
||||
modelMatrix.loadIdentity();
|
||||
modelMatrix.rotate(-180.0f + x_offset, 0.f, 1.f, 0.f);
|
||||
|
||||
float xscale = texw < 1024.f ? floor(1024.f / float(texw)) : 1.f;
|
||||
float yscale = 1.f;
|
||||
auto texskyoffset = tex->GetSkyOffset() + skyoffset;
|
||||
if (texh <= 128 && tiled)
|
||||
{
|
||||
modelMatrix.translate(0.f, (-40 + texskyoffset)*skyoffsetfactor, 0.f);
|
||||
modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f);
|
||||
yscale = 240.f / texh;
|
||||
}
|
||||
else if (texh < 128)
|
||||
{
|
||||
// smaller sky textures must be tiled. We restrict it to 128 sky pixels, though
|
||||
modelMatrix.translate(0.f, -1250.f, 0.f);
|
||||
modelMatrix.scale(1.f, 128 / 230.f, 1.f);
|
||||
yscale = float(128 / texh); // intentionally left as integer.
|
||||
}
|
||||
else if (texh < 200)
|
||||
{
|
||||
modelMatrix.translate(0.f, -1250.f, 0.f);
|
||||
modelMatrix.scale(1.f, texh / 230.f, 1.f);
|
||||
}
|
||||
else if (texh <= 240)
|
||||
{
|
||||
modelMatrix.translate(0.f, (200 - texh + texskyoffset)*skyoffsetfactor, 0.f);
|
||||
modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
modelMatrix.translate(0.f, (-40 + texskyoffset)*skyoffsetfactor, 0.f);
|
||||
modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f);
|
||||
yscale = 240.f / texh;
|
||||
}
|
||||
textureMatrix.loadIdentity();
|
||||
textureMatrix.scale(mirror ? -xscale : xscale, yscale, 1.f);
|
||||
textureMatrix.translate(1.f, y_offset / texh, 1.f);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, bool apply)
|
||||
{
|
||||
state.Draw(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled)
|
||||
{
|
||||
if (tex)
|
||||
{
|
||||
state.SetMaterial(tex, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||
state.EnableModelMatrix(true);
|
||||
state.EnableTextureMatrix(true);
|
||||
|
||||
SetupMatrices(tex, x_offset, y_offset, mirror, mode, state.mModelMatrix, state.mTextureMatrix, tiled);
|
||||
}
|
||||
|
||||
int rc = mRows + 1;
|
||||
|
||||
// The caps only get drawn for the main layer but not for the overlay.
|
||||
if (mode == FSkyVertexBuffer::SKYMODE_MAINLAYER && tex != NULL)
|
||||
{
|
||||
auto& col = R_GetSkyCapColor(tex);
|
||||
state.SetObjectColor(col.first);
|
||||
state.EnableTexture(false);
|
||||
RenderRow(state, DT_TriangleFan, 0);
|
||||
|
||||
state.SetObjectColor(col.second);
|
||||
RenderRow(state, DT_TriangleFan, rc);
|
||||
state.EnableTexture(true);
|
||||
}
|
||||
state.SetObjectColor(0xffffffff);
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(state, DT_TriangleStrip, i, i == 1);
|
||||
RenderRow(state, DT_TriangleStrip, rc + i, false);
|
||||
}
|
||||
|
||||
state.EnableTextureMatrix(false);
|
||||
state.EnableModelMatrix(false);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderBox(FRenderState& state, FTextureID texno, FSkyBox* tex, float x_offset, bool sky2, float stretch, const FVector3& skyrotatevector, const FVector3& skyrotatevector2)
|
||||
{
|
||||
int faces;
|
||||
|
||||
state.EnableModelMatrix(true);
|
||||
state.mModelMatrix.loadIdentity();
|
||||
state.mModelMatrix.scale(1, 1 / stretch, 1); // Undo the map's vertical scaling as skyboxes are true cubes.
|
||||
|
||||
if (!sky2)
|
||||
state.mModelMatrix.rotate(-180.0f + x_offset, skyrotatevector.X, skyrotatevector.Z, skyrotatevector.Y);
|
||||
else
|
||||
state.mModelMatrix.rotate(-180.0f + x_offset, skyrotatevector2.X, skyrotatevector2.Z, skyrotatevector2.Y);
|
||||
|
||||
if (tex->GetSkyFace(5))
|
||||
{
|
||||
faces = 4;
|
||||
|
||||
// north
|
||||
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(0), 4);
|
||||
|
||||
// east
|
||||
state.SetMaterial(tex->GetSkyFace(1), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(1), 4);
|
||||
|
||||
// south
|
||||
state.SetMaterial(tex->GetSkyFace(2), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(2), 4);
|
||||
|
||||
// west
|
||||
state.SetMaterial(tex->GetSkyFace(3), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(3), 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
faces = 1;
|
||||
state.SetMaterial(tex->GetSkyFace(0), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(-1), 10);
|
||||
}
|
||||
|
||||
// top
|
||||
state.SetMaterial(tex->GetSkyFace(faces), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(tex->GetSkyFlip() ? 6 : 5), 4);
|
||||
|
||||
// bottom
|
||||
state.SetMaterial(tex->GetSkyFace(faces + 1), UF_Texture, 0, CLAMP_XY, 0, -1);
|
||||
state.Draw(DT_TriangleStrip, FaceStart(4), 4);
|
||||
|
||||
state.EnableModelMatrix(false);
|
||||
}
|
||||
|
90
source/common/rendering/hwrenderer/data/hw_skydome.h
Normal file
90
source/common/rendering/hwrenderer/data/hw_skydome.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include "matrix.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "skyboxtexture.h"
|
||||
|
||||
class FGameTexture;
|
||||
class FRenderState;
|
||||
class IVertexBuffer;
|
||||
struct HWSkyPortal;
|
||||
struct HWDrawInfo;
|
||||
|
||||
struct FSkyVertex
|
||||
{
|
||||
float x, y, z, u, v;
|
||||
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;
|
||||
}
|
||||
|
||||
void SetXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0, PalEntry col = 0xffffffff)
|
||||
{
|
||||
x = xx;
|
||||
y = yy;
|
||||
z = zz;
|
||||
u = uu;
|
||||
v = vv;
|
||||
color = col;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FSkyVertexBuffer
|
||||
{
|
||||
friend struct HWSkyPortal;
|
||||
public:
|
||||
static const int SKYHEMI_UPPER = 1;
|
||||
static const int SKYHEMI_LOWER = 2;
|
||||
|
||||
enum
|
||||
{
|
||||
SKYMODE_MAINLAYER = 0,
|
||||
SKYMODE_SECONDLAYER = 1,
|
||||
SKYMODE_FOGLAYER = 2
|
||||
};
|
||||
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
|
||||
TArray<FSkyVertex> mVertices;
|
||||
TArray<unsigned int> mPrimStart;
|
||||
|
||||
int mRows, mColumns;
|
||||
|
||||
// indices for sky cubemap faces
|
||||
int mFaceStart[7];
|
||||
int mSideStart;
|
||||
|
||||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(int hemi);
|
||||
void CreateDome();
|
||||
|
||||
public:
|
||||
|
||||
FSkyVertexBuffer();
|
||||
~FSkyVertexBuffer();
|
||||
void SetupMatrices(FGameTexture *tex, float x_offset, float y_offset, bool mirror, int mode, VSMatrix &modelmatrix, VSMatrix &textureMatrix, bool tiled);
|
||||
std::pair<IVertexBuffer *, IIndexBuffer *> GetBufferObjects() const
|
||||
{
|
||||
return std::make_pair(mVertexBuffer, nullptr);
|
||||
}
|
||||
|
||||
int FaceStart(int i)
|
||||
{
|
||||
if (i >= 0 && i < 7) return mFaceStart[i];
|
||||
else return mSideStart;
|
||||
}
|
||||
|
||||
void RenderRow(FRenderState& state, EDrawType prim, int row, bool apply = true);
|
||||
void RenderDome(FRenderState& state, FGameTexture* tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled);
|
||||
void RenderBox(FRenderState& state, FTextureID texno, FSkyBox* tex, float x_offset, bool sky2, float stretch, const FVector3& skyrotatevector, const FVector3& skyrotatevector2);
|
||||
|
||||
};
|
|
@ -39,15 +39,10 @@
|
|||
#include "filesystem.h"
|
||||
#include "i_time.h"
|
||||
#include "cmdlib.h"
|
||||
#include "m_png.h"
|
||||
#include "version.h"
|
||||
#include "texturemanager.h"
|
||||
#include "model.h"
|
||||
//#include "hwrenderer/utility/hw_clock.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gamecvars.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gl_debug.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderstate.h"
|
||||
|
@ -56,18 +51,14 @@
|
|||
#include "flatvertices.h"
|
||||
#include "gl_samplers.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
//#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "r_videoscale.h"
|
||||
//#include "r_data/models/models.h"
|
||||
#include "model.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "gl_hwtexture.h"
|
||||
#include "build.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
||||
extern bool NoInterpolateView;
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
@ -195,9 +186,4 @@ void FGLRenderer::BeginFrame()
|
|||
mSaveBuffers->Setup(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
|
||||
}
|
||||
|
||||
void FGLRenderer::PresentStereo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,6 @@ public:
|
|||
void CopyToBackbuffer(const IntRect *bounds, bool applyGamma);
|
||||
void DrawPresentTexture(const IntRect &box, bool applyGamma);
|
||||
void Flush();
|
||||
//void Draw2D(F2DDrawer *data);
|
||||
void BeginFrame();
|
||||
|
||||
bool StartOffscreen();
|
||||
|
|
388
source/core/rendering/gl/renderer/gl_stereo3d.cpp
Normal file
388
source/core/rendering/gl/renderer/gl_stereo3d.cpp
Normal file
|
@ -0,0 +1,388 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2015 Christopher Bruns
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_stereo3d.cpp
|
||||
** Stereoscopic 3D API
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_system.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderbuffers.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "templates.h"
|
||||
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
EXTERN_CVAR(Float, vid_saturation)
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Int, gl_satformula)
|
||||
EXTERN_CVAR(Int, gl_dither_bpc)
|
||||
|
||||
void UpdateVRModes(bool considerQuadBuffered = true);
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentAnaglyph(bool r, bool g, bool b)
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
glColorMask(r, g, b, 1);
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glColorMask(!r, !g, !b, 1);
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentSideBySide()
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
// Compute screen regions to use for left and right eye views
|
||||
int leftWidth = screen->mOutputLetterbox.width / 2;
|
||||
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
|
||||
IntRect leftHalfScreen = screen->mOutputLetterbox;
|
||||
leftHalfScreen.width = leftWidth;
|
||||
IntRect rightHalfScreen = screen->mOutputLetterbox;
|
||||
rightHalfScreen.width = rightWidth;
|
||||
rightHalfScreen.left += leftWidth;
|
||||
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(leftHalfScreen, true);
|
||||
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(rightHalfScreen, true);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentTopBottom()
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
// Compute screen regions to use for left and right eye views
|
||||
int topHeight = screen->mOutputLetterbox.height / 2;
|
||||
int bottomHeight = screen->mOutputLetterbox.height - topHeight;
|
||||
IntRect topHalfScreen = screen->mOutputLetterbox;
|
||||
topHalfScreen.height = topHeight;
|
||||
topHalfScreen.top = topHeight;
|
||||
IntRect bottomHalfScreen = screen->mOutputLetterbox;
|
||||
bottomHalfScreen.height = bottomHeight;
|
||||
bottomHalfScreen.top = 0;
|
||||
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(topHalfScreen, true);
|
||||
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(bottomHalfScreen, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
|
||||
// Bind each eye texture, for composition in the shader
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
mBuffers->BindEyeTexture(1, 1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
const IntRect& box = screen->mOutputLetterbox;
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
shader.Bind();
|
||||
|
||||
if (framebuffer->IsHWGammaActive())
|
||||
{
|
||||
shader.Uniforms->InvGamma = 1.0f;
|
||||
shader.Uniforms->Contrast = 1.0f;
|
||||
shader.Uniforms->Brightness = 0.0f;
|
||||
shader.Uniforms->Saturation = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader.Uniforms->InvGamma = 1.0f / clamp<float>(vid_gamma, 0.1f, 4.f);
|
||||
shader.Uniforms->Contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
|
||||
shader.Uniforms->Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f);
|
||||
shader.Uniforms->Saturation = clamp<float>(vid_saturation, -15.0f, 15.0f);
|
||||
shader.Uniforms->GrayFormula = static_cast<int>(gl_satformula);
|
||||
}
|
||||
shader.Uniforms->HdrMode = 0;
|
||||
shader.Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1);
|
||||
shader.Uniforms->Scale = {
|
||||
screen->mScreenViewport.width / (float)mBuffers->GetWidth(),
|
||||
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
||||
};
|
||||
shader.Uniforms->Offset = { 0.0f, 0.0f };
|
||||
shader.Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(shader.Uniforms.GetBuffer())->BindBase();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentColumnInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dColumnShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
|
||||
// Todo:
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowHOffset = clientoffset.X % 2;
|
||||
int windowHOffset = 0;
|
||||
|
||||
mPresent3dColumnShader->Uniforms->WindowPositionParity = windowHOffset;
|
||||
mPresent3dColumnShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dColumnShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentRowInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dRowShader);
|
||||
|
||||
// Todo:
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowVOffset = clientoffset.Y % 2;
|
||||
int windowVOffset = 0;
|
||||
|
||||
mPresent3dRowShader->Uniforms->WindowPositionParity =
|
||||
(windowVOffset
|
||||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2;
|
||||
|
||||
mPresent3dRowShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dRowShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentCheckerInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dCheckerShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowHOffset = clientoffset.X % 2;
|
||||
//auto windowVOffset = clientoffset.Y % 2;
|
||||
int windowHOffset = 0;
|
||||
int windowVOffset = 0;
|
||||
|
||||
mPresent3dCheckerShader->Uniforms->WindowPositionParity =
|
||||
(windowVOffset
|
||||
+ windowHOffset
|
||||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2; // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
|
||||
mPresent3dCheckerShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dCheckerShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sometimes the stereo render context is not ready immediately at start up
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderer::QuadStereoCheckInitialRenderContextState()
|
||||
{
|
||||
// Keep trying until we see at least one good OpenGL context to render to
|
||||
bool bQuadStereoSupported = false;
|
||||
bool bDecentContextWasFound = false;
|
||||
int contextCheckCount = 0;
|
||||
if ((!bDecentContextWasFound) && (contextCheckCount < 200))
|
||||
{
|
||||
contextCheckCount += 1;
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // This question is about the main screen display context
|
||||
GLboolean supportsStereo, supportsBuffered;
|
||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||
if (supportsBuffered) // Finally, a useful OpenGL context
|
||||
{
|
||||
// This block will be executed exactly ONCE during a game run
|
||||
bDecentContextWasFound = true; // now we can stop checking every frame...
|
||||
// Now check whether this context supports hardware stereo
|
||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||
if (! bQuadStereoSupported)
|
||||
UpdateVRModes(false);
|
||||
}
|
||||
}
|
||||
return bQuadStereoSupported;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentQuadStereo()
|
||||
{
|
||||
if (QuadStereoCheckInitialRenderContextState())
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
|
||||
glDrawBuffer(GL_BACK_LEFT);
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glDrawBuffer(GL_BACK_RIGHT);
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGLRenderer::PresentStereo()
|
||||
{
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
const int eyeCount = vrmode->mEyeCount;
|
||||
// Don't invalidate the bound framebuffer (..., false)
|
||||
if (eyeCount > 1)
|
||||
mBuffers->BlitToEyeTexture(mBuffers->CurrentEye(), false);
|
||||
|
||||
switch (vr_mode)
|
||||
{
|
||||
default:
|
||||
return;
|
||||
|
||||
case VR_GREENMAGENTA:
|
||||
PresentAnaglyph(false, true, false);
|
||||
break;
|
||||
|
||||
case VR_REDCYAN:
|
||||
PresentAnaglyph(true, false, false);
|
||||
break;
|
||||
|
||||
case VR_AMBERBLUE:
|
||||
PresentAnaglyph(true, true, false);
|
||||
break;
|
||||
|
||||
case VR_SIDEBYSIDEFULL:
|
||||
case VR_SIDEBYSIDESQUISHED:
|
||||
PresentSideBySide();
|
||||
break;
|
||||
|
||||
case VR_TOPBOTTOM:
|
||||
PresentTopBottom();
|
||||
break;
|
||||
|
||||
case VR_ROWINTERLEAVED:
|
||||
PresentRowInterleaved();
|
||||
break;
|
||||
|
||||
case VR_COLUMNINTERLEAVED:
|
||||
PresentColumnInterleaved();
|
||||
break;
|
||||
|
||||
case VR_CHECKERINTERLEAVED:
|
||||
PresentCheckerInterleaved();
|
||||
break;
|
||||
|
||||
case VR_QUADSTEREO:
|
||||
PresentQuadStereo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -41,28 +41,24 @@
|
|||
#include "templates.h"
|
||||
#include "palette.h"
|
||||
#include "build.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderstate.h"
|
||||
#include "gl_renderbuffers.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
/*
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||
#include "hwrenderer/models/hw_models.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
*/
|
||||
#include "hw_vrmodes.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "hw_skydome.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gl_debug.h"
|
||||
#include "r_videoscale.h"
|
||||
//#include "gl_buffers.h"
|
||||
|
||||
//#include "hwrenderer/data/flatvertices.h"
|
||||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
|
@ -97,11 +93,9 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) :
|
|||
Super::SetVSync(vid_vsync);
|
||||
FHardwareTexture::InitGlobalState();
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
// Make sure all global variables tracking OpenGL context state are reset..
|
||||
|
||||
gl_RenderState.Reset();
|
||||
#endif
|
||||
|
||||
GLRenderer = nullptr;
|
||||
}
|
||||
|
@ -111,10 +105,8 @@ OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
|||
PPResource::ResetAll();
|
||||
|
||||
if (mVertexData != nullptr) delete mVertexData;
|
||||
#ifdef IMPLEMENT_IT
|
||||
if (mSkyData != nullptr) delete mSkyData;
|
||||
if (mViewpoints != nullptr) delete mViewpoints;
|
||||
#endif
|
||||
if (mLights != nullptr) delete mLights;
|
||||
mShadowMap.Reset();
|
||||
|
||||
|
@ -177,10 +169,8 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
SetViewportRects(nullptr);
|
||||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
#ifdef IMPLEMENT_IT
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
#endif
|
||||
mLights = new FLightBuffer();
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
|
@ -212,12 +202,50 @@ void OpenGLFrameBuffer::Update()
|
|||
screen->mVertexData->Reset();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::CopyScreenToBuffer(int width, int height, uint8_t* scr)
|
||||
{
|
||||
IntRect bounds;
|
||||
bounds.left = 0;
|
||||
bounds.top = 0;
|
||||
bounds.width = width;
|
||||
bounds.height = height;
|
||||
GLRenderer->CopyToBackbuffer(&bounds, false);
|
||||
|
||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
glFinish();
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
// Camera texture rendering
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc)
|
||||
{
|
||||
#if 0
|
||||
GLRenderer->StartOffscreen();
|
||||
GLRenderer->BindToFrameBuffer(tex);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
bounds.width = FHardwareTexture::GetTexDimension(tex->GetWidth());
|
||||
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
|
||||
|
||||
renderFunc(bounds);
|
||||
GLRenderer->EndOffscreen();
|
||||
|
||||
tex->SetUpdated(true);
|
||||
static_cast<OpenGLFrameBuffer*>(screen)->camtexcount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
const char* OpenGLFrameBuffer::DeviceName() const
|
||||
{
|
||||
|
@ -283,38 +311,28 @@ void OpenGLFrameBuffer::SetTextureFilterMode()
|
|||
if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
||||
{
|
||||
auto tex = mat->tex;
|
||||
if (tex->isSWCanvas()) return;
|
||||
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (!tex->isScaled()) ? CTF_CheckHires : 0;
|
||||
int numLayers = mat->GetLayers();
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
int flags = mat->GetScaleFlags();
|
||||
int numLayers = mat->NumLayers();
|
||||
MaterialLayerInfo* layer;
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
|
||||
|
||||
if (base->BindOrCreate(tex, 0, CLAMP_NONE, translation, flags))
|
||||
if (base->BindOrCreate(layer->layerTexture, 0, CLAMP_NONE, translation, layer->scaleFlags))
|
||||
{
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
FTexture *layer;
|
||||
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0);
|
||||
systex->BindOrCreate(layer->layerTexture, i, CLAMP_NONE, 0, layer->scaleFlags);
|
||||
}
|
||||
}
|
||||
// unbind everything.
|
||||
FHardwareTexture::UnbindAll();
|
||||
}
|
||||
|
||||
FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli)
|
||||
{
|
||||
return new FHWModelRenderer(nullptr, gl_RenderState, mli);
|
||||
}
|
||||
#endif
|
||||
|
||||
IVertexBuffer *OpenGLFrameBuffer::CreateVertexBuffer()
|
||||
{
|
||||
return new GLVertexBuffer;
|
||||
|
@ -335,13 +353,95 @@ void OpenGLFrameBuffer::BlurScene(float amount)
|
|||
GLRenderer->BlurScene(amount);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds)
|
||||
{
|
||||
Super::SetViewportRects(bounds);
|
||||
if (!bounds)
|
||||
{
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
vrmode->AdjustViewport(this);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::UpdatePalette()
|
||||
{
|
||||
if (GLRenderer)
|
||||
GLRenderer->ClearTonemapPalette();
|
||||
}
|
||||
#endif
|
||||
|
||||
FRenderState* OpenGLFrameBuffer::RenderState()
|
||||
{
|
||||
return &gl_RenderState;
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::AmbientOccludeScene(float m5)
|
||||
{
|
||||
gl_RenderState.EnableDrawBuffers(1);
|
||||
GLRenderer->AmbientOccludeScene(m5);
|
||||
glViewport(screen->mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
|
||||
GLRenderer->mBuffers->BindSceneFB(true);
|
||||
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::FirstEye()
|
||||
{
|
||||
GLRenderer->mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::NextEye(int eyecount)
|
||||
{
|
||||
GLRenderer->mBuffers->NextEye(eyecount);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::SetSceneRenderTarget(bool useSSAO)
|
||||
{
|
||||
GLRenderer->mBuffers->BindSceneFB(useSSAO);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::UpdateShadowMap()
|
||||
{
|
||||
if (mShadowMap.PerformUpdate())
|
||||
{
|
||||
FGLDebug::PushGroup("ShadowMap");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLightList)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mNodesBuffer)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLinesBuffer)->BindBase();
|
||||
|
||||
GLRenderer->mBuffers->BindShadowMapFB();
|
||||
|
||||
GLRenderer->mShadowMapShader->Bind();
|
||||
GLRenderer->mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality;
|
||||
GLRenderer->mShadowMapShader->Uniforms->NodesCount = screen->mShadowMap.NodesCount();
|
||||
GLRenderer->mShadowMapShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(GLRenderer->mShadowMapShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
glViewport(0, 0, gl_shadowmap_quality, 1024);
|
||||
GLRenderer->RenderScreenQuad();
|
||||
|
||||
const auto& viewport = screen->mScreenViewport;
|
||||
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
|
||||
GLRenderer->mBuffers->BindShadowMapTexture(16);
|
||||
FGLDebug::PopGroup();
|
||||
screen->mShadowMap.FinishUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::WaitForCommands(bool finish)
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::SetSaveBuffers(bool yes)
|
||||
{
|
||||
if (!GLRenderer) return;
|
||||
if (yes) GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
|
||||
else GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -403,6 +503,8 @@ TArray<uint8_t> OpenGLFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
|
|||
|
||||
// Screenshot should not use gamma correction if it was already applied to rendered image
|
||||
gamma = 1;
|
||||
if (vid_hdr_active && vid_fullscreen)
|
||||
gamma *= 2.2f;
|
||||
return ScreenshotBuffer;
|
||||
}
|
||||
|
||||
|
@ -428,6 +530,49 @@ void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, const std::f
|
|||
GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, "WipeStartScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->Flush();
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, "WipeEndScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,10 +28,6 @@ public:
|
|||
IHardwareTexture *CreateHardwareTexture(int numchannels) override;
|
||||
void SetTextureFilterMode() override;
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
||||
FModelRenderer *CreateModelRenderer(int mli) override;
|
||||
#endif
|
||||
void BeginFrame() override;
|
||||
//void SetViewportRects(IntRect *bounds) override;
|
||||
void BlurScene(float amount) override;
|
||||
|
@ -49,6 +45,24 @@ public:
|
|||
|
||||
void SetVSync(bool vsync) override;
|
||||
|
||||
void SetViewportRects(IntRect* bounds) override;
|
||||
void UpdatePalette() override;
|
||||
void AmbientOccludeScene(float m5) override;
|
||||
void FirstEye() override;
|
||||
void NextEye(int eyecount) override;
|
||||
void SetSceneRenderTarget(bool useSSAO) override;
|
||||
void UpdateShadowMap() override;
|
||||
void WaitForCommands(bool finish) override;
|
||||
void SetSaveBuffers(bool yes) override;
|
||||
void CopyScreenToBuffer(int width, int height, uint8_t* buffer) override;
|
||||
bool FlipSavePic() const override { return true; }
|
||||
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect&)> renderFunc) override;
|
||||
void PrecacheMaterial(FMaterial* mat, int translation) override;
|
||||
FRenderState* RenderState() override;
|
||||
|
||||
FTexture* WipeStartScreen() override;
|
||||
FTexture* WipeEndScreen() override;
|
||||
|
||||
//void Draw2D() override;
|
||||
void PostProcessScene(bool swscene, int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||
|
||||
|
|
|
@ -125,3 +125,8 @@ void InitBuildTiles()
|
|||
}
|
||||
|
||||
TArray<UserShaderDesc> usershaders;
|
||||
|
||||
void UpdateVRModes(bool considerQuadBuffered = true)
|
||||
{
|
||||
// should update the menu.
|
||||
}
|
||||
|
|
|
@ -184,13 +184,7 @@ void GLInstance::ClearBufferState()
|
|||
}
|
||||
|
||||
|
||||
static GLint primtypes[] =
|
||||
{
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_LINES
|
||||
};
|
||||
static GLint primtypes[] ={ GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP };
|
||||
|
||||
|
||||
void GLInstance::Draw(EDrawType type, size_t start, size_t count)
|
||||
|
@ -214,7 +208,7 @@ void GLInstance::DrawElement(EDrawType type, size_t start, size_t count, Polymos
|
|||
if (renderState.Color[3] != 1.f) renderState.Flags &= ~RF_Brightmapping; // The way the colormaps are set up means that brightmaps cannot be used on translucent content at all.
|
||||
renderState.Apply(polymostShader, lastState);
|
||||
}
|
||||
if (type != DT_LINES)
|
||||
if (type != DT_Lines)
|
||||
{
|
||||
glDrawElements(primtypes[type], count, GL_UNSIGNED_INT, (void*)(intptr_t)(start * sizeof(uint32_t)));
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
#include <map>
|
||||
#include "gl_samplers.h"
|
||||
#include "gl_hwtexture.h"
|
||||
#include "gl_renderstate.h"
|
||||
#include "matrix.h"
|
||||
#include "palentry.h"
|
||||
#include "renderstyle.h"
|
||||
#include "hw_material.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "pm_renderstate.h"
|
||||
|
||||
class FShader;
|
||||
class PolymostShader;
|
||||
|
@ -66,22 +67,13 @@ struct glinfo_t {
|
|||
float maxanisotropy;
|
||||
};
|
||||
|
||||
enum EDrawType
|
||||
enum ECullSide
|
||||
{
|
||||
DT_TRIANGLES,
|
||||
DT_TRIANGLE_STRIP,
|
||||
DT_TRIANGLE_FAN,
|
||||
DT_LINES
|
||||
};
|
||||
|
||||
enum ECull
|
||||
{
|
||||
Cull_None,
|
||||
Cull_Front,
|
||||
Cull_Back
|
||||
};
|
||||
|
||||
enum EDepthFunc
|
||||
enum EDepthFunct
|
||||
{
|
||||
Depth_Always,
|
||||
Depth_Less,
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "flatvertices.h"
|
||||
#include "build.h"
|
||||
#include "v_video.h"
|
||||
#include "hw_renderstate.h"
|
||||
|
||||
extern int16_t numshades;
|
||||
extern TArray<VSMatrix> matrixArray;
|
||||
|
@ -182,11 +183,11 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
|
|||
switch (cmd.mType)
|
||||
{
|
||||
case F2DDrawer::DrawTypeTriangles:
|
||||
DrawElement(DT_TRIANGLES, cmd.mIndexIndex, cmd.mIndexCount, renderState);
|
||||
DrawElement(DT_Triangles, cmd.mIndexIndex, cmd.mIndexCount, renderState);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypeLines:
|
||||
DrawElement(DT_LINES, cmd.mVertIndex, cmd.mVertCount, renderState);
|
||||
DrawElement(DT_Lines, cmd.mVertIndex, cmd.mVertCount, renderState);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypePoints:
|
||||
|
@ -241,18 +242,18 @@ void DrawFullscreenBlends()
|
|||
// Todo: reroute to the 2D drawer
|
||||
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
||||
GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadergb.a);
|
||||
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
GLInterface.Draw(DT_TriangleStrip, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
}
|
||||
if (tint_blood_r | tint_blood_g | tint_blood_b)
|
||||
{
|
||||
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Add]);
|
||||
|
||||
GLInterface.SetColorub(max(tint_blood_r, 0), max(tint_blood_g, 0), max(tint_blood_b, 0), 255);
|
||||
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
GLInterface.Draw(DT_TriangleStrip, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
|
||||
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Subtract]);
|
||||
GLInterface.SetColorub(max(-tint_blood_r, 0), max(-tint_blood_g, 0), max(-tint_blood_b, 0), 255);
|
||||
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
GLInterface.Draw(DT_TriangleStrip, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
|
||||
GLInterface.SetColorub(255, 255, 255, 255);
|
||||
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
||||
|
|
|
@ -57,38 +57,6 @@ enum PRSFlags
|
|||
|
||||
};
|
||||
|
||||
struct FDepthBiasState
|
||||
{
|
||||
float mFactor;
|
||||
float mUnits;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mFactor = 0;
|
||||
mUnits = 0;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct FMaterialState
|
||||
{
|
||||
FMaterial* mMaterial;
|
||||
int mClampMode;
|
||||
int mTranslation;
|
||||
int mOverrideShader;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mMaterial = nullptr;
|
||||
mTranslation = 0;
|
||||
mClampMode = 0/*CLAMP_NONE*/;
|
||||
mOverrideShader = -1;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct PolymostRenderState
|
||||
{
|
||||
int vindex, vcount, primtype;
|
|
@ -29,6 +29,9 @@ CRC
|
|||
RRRA_CRC 0x958018C6
|
||||
RRDEER_CRC 0xA6BE8B16
|
||||
|
||||
BLOOD10_CRC 0xB291418f
|
||||
BLOOD11_CRC 0xC3A99936
|
||||
BLOOD_CRC 0xA8FDDA84
|
||||
BLOOD_CRC 0xA8FDDA84
|
||||
SWREG12_CRC 0x7545319F
|
||||
SWWD_CRC 0xA9AAA7B7
|
||||
|
|
Loading…
Reference in a new issue