mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 04:00:42 +00:00
- removed the old OpenGL interface.
This commit is contained in:
parent
ba397f5ca1
commit
6a9f1e9da1
15 changed files with 9 additions and 1335 deletions
|
@ -759,11 +759,9 @@ set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${POLYBACKEND_SOURCES})
|
|||
|
||||
set (PCH_SOURCES
|
||||
|
||||
glbackend/gl_shader.cpp
|
||||
glbackend/glbackend.cpp
|
||||
glbackend/gl_palmanager.cpp
|
||||
glbackend/gl_texture.cpp
|
||||
glbackend/hw_draw2d.cpp
|
||||
|
||||
thirdparty/src/base64.cpp
|
||||
thirdparty/src/fix16.cpp
|
||||
|
|
|
@ -122,12 +122,6 @@ float sectorVisibility(int sectnum)
|
|||
|
||||
void gltexapplyprops(void)
|
||||
{
|
||||
if (GLInterface.glinfo.maxanisotropy > 1.f)
|
||||
{
|
||||
if (gl_texture_filter_anisotropic <= 0 || gl_texture_filter_anisotropic > GLInterface.glinfo.maxanisotropy)
|
||||
gl_texture_filter_anisotropic = (int32_t)GLInterface.glinfo.maxanisotropy;
|
||||
}
|
||||
|
||||
screen->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
|
|
|
@ -518,6 +518,7 @@ void OpenGLFrameBuffer::Draw2D()
|
|||
|
||||
void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
{
|
||||
if (!swscene) GLRenderer->mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
|
||||
GLRenderer->PostProcessScene(fixedcm, flash, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "templates.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "v_draw.h"
|
||||
#include "i_interface.h"
|
||||
|
||||
extern bool vid_hdr_active;
|
||||
|
||||
|
|
|
@ -96,17 +96,8 @@ public:
|
|||
|
||||
CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
|
||||
|
||||
EXTERN_CVAR(Bool, hw_use_backend);
|
||||
#include "glbackend/glbackend.h"
|
||||
|
||||
void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||
{
|
||||
// This is still needed for testing until things are working.
|
||||
if (!hw_use_backend)
|
||||
{
|
||||
GLInterface.Draw2D(drawer);
|
||||
return;
|
||||
}
|
||||
twoD.Clock();
|
||||
|
||||
const auto &mScreenViewport = screen->mScreenViewport;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "gamecontrol.h"
|
||||
#include "printf.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
|
@ -63,7 +64,7 @@ static FileWriter *opennextfile(const char *fn)
|
|||
|
||||
void getScreen(uint8_t* imgBuf)
|
||||
{
|
||||
GLInterface.ReadPixels(xdim, ydim, imgBuf);
|
||||
screen->CopyScreenToBuffer(xdim, ydim, imgBuf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
** gl_shader.cpp
|
||||
**
|
||||
** GLSL shader handling
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2004-2019 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.
|
||||
**
|
||||
** 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 <memory>
|
||||
#include "gl_load.h"
|
||||
#include "glbackend.h"
|
||||
#include "gl_shader.h"
|
||||
#include "zstring.h"
|
||||
#include "shaderuniforms.h"
|
||||
|
||||
#include "baselayer.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FShader::Load(const char * name, const char * vert_prog, const char * frag_prog)
|
||||
{
|
||||
FString error;
|
||||
static char buffer[10000];
|
||||
|
||||
hVertProg = glCreateShader(GL_VERTEX_SHADER);
|
||||
hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
glShaderSource(hVertProg, 1, &vert_prog, nullptr);
|
||||
glShaderSource(hFragProg, 1, &frag_prog, nullptr);
|
||||
|
||||
glCompileShader(hVertProg);
|
||||
glCompileShader(hFragProg);
|
||||
|
||||
hShader = glCreateProgram();
|
||||
|
||||
glAttachShader(hShader, hVertProg);
|
||||
glAttachShader(hShader, hFragProg);
|
||||
|
||||
glLinkProgram(hShader);
|
||||
|
||||
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Vertex shader:\n" << buffer << "\n";
|
||||
}
|
||||
glGetShaderInfoLog(hFragProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Fragment shader:\n" << buffer << "\n";
|
||||
}
|
||||
|
||||
glGetProgramInfoLog(hShader, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Linking:\n" << buffer << "\n";
|
||||
}
|
||||
int linked;
|
||||
glGetProgramiv(hShader, GL_LINK_STATUS, &linked);
|
||||
if (linked == 0)
|
||||
{
|
||||
// only print message if there's an error.
|
||||
I_Error("Init Shader '%s':\n%s\n", name, error.GetChars());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader::~FShader()
|
||||
{
|
||||
glDeleteProgram(hShader);
|
||||
glDeleteShader(hVertProg);
|
||||
glDeleteShader(hFragProg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FShader::Bind()
|
||||
{
|
||||
glUseProgram(hShader);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool PolymostShader::Load(const char * name, const char * vert_prog, const char * frag_prog)
|
||||
{
|
||||
if (!FShader::Load(name, vert_prog, frag_prog)) return false;
|
||||
|
||||
int tempindex = glGetUniformBlockIndex(hShader, "ViewpointUBO");
|
||||
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, VIEWPOINT_BINDINGPOINT);
|
||||
|
||||
Flags.Init(hShader, "u_flags");
|
||||
|
||||
NPOTEmulation.Init(hShader, "uNpotEmulation");
|
||||
TextureMode.Init(hShader, "uTextureMode");
|
||||
FogColor.Init(hShader, "uFogColor");
|
||||
muFogEnabled.Init(hShader, "uFogEnabled");
|
||||
muLightParms.Init(hShader, "uLightAttr");
|
||||
AlphaThreshold.Init(hShader, "uAlphaThreshold");
|
||||
DetailParms.Init(hShader, "uDetailParms");
|
||||
ModelMatrix.Init(hShader, "ModelMatrix");
|
||||
TextureMatrix.Init(hShader, "TextureMatrix");
|
||||
muTextureAddColor.Init(hShader, "uTextureAddColor");
|
||||
muTextureModulateColor.Init(hShader, "uTextureModulateColor");
|
||||
muTextureBlendColor.Init(hShader, "uTextureBlendColor");
|
||||
|
||||
|
||||
|
||||
glUseProgram(hShader);
|
||||
|
||||
VSMatrix identity(0);
|
||||
TextureMatrix.Set(identity.get());
|
||||
|
||||
int SamplerLoc;
|
||||
SamplerLoc = glGetUniformLocation(hShader, "s_texture");
|
||||
glUniform1i(SamplerLoc, 0);
|
||||
SamplerLoc = glGetUniformLocation(hShader, "brighttexture");
|
||||
glUniform1i(SamplerLoc, 1);
|
||||
SamplerLoc = glGetUniformLocation(hShader, "detailtexture");
|
||||
glUniform1i(SamplerLoc, 2);
|
||||
SamplerLoc = glGetUniformLocation(hShader, "glowtexture");
|
||||
glUniform1i(SamplerLoc, 3);
|
||||
SamplerLoc = glGetUniformLocation(hShader, "s_palette");
|
||||
glUniform1i(SamplerLoc, 4);
|
||||
SamplerLoc = glGetUniformLocation(hShader, "s_palswap");
|
||||
glUniform1i(SamplerLoc, 5);
|
||||
|
||||
glUseProgram(0);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "gl_uniform.h"
|
||||
|
||||
class FShader
|
||||
{
|
||||
friend class FShaderManager;
|
||||
friend class FRenderState;
|
||||
|
||||
unsigned int hVertProg = 0;
|
||||
unsigned int hFragProg = 0;
|
||||
|
||||
protected:
|
||||
unsigned int hShader = 0;
|
||||
|
||||
|
||||
public:
|
||||
FShader() = default;
|
||||
virtual ~FShader();
|
||||
|
||||
virtual bool Load(const char * name, const char * vert_prog_lump, const char * fragprog); //, const char * fragprog2, const char *defines);
|
||||
bool Bind();
|
||||
unsigned int GetHandle() const { return hShader; }
|
||||
};
|
||||
|
||||
class PolymostShader : public FShader
|
||||
{
|
||||
public:
|
||||
FBufferedUniform1i Flags;
|
||||
FBufferedUniform2f NPOTEmulation;
|
||||
FBufferedUniformPalEntry FogColor;
|
||||
|
||||
FBufferedUniform1i TextureMode;
|
||||
FBufferedUniform4f DetailParms;
|
||||
FBufferedUniform1f AlphaThreshold;
|
||||
FBufferedUniform1i muFogEnabled;
|
||||
FBufferedUniform4f muLightParms;
|
||||
FUniformMatrix4f ModelMatrix;
|
||||
FUniformMatrix4f TextureMatrix;
|
||||
FBufferedUniform4f muTextureBlendColor;
|
||||
FBufferedUniform4f muTextureModulateColor;
|
||||
FBufferedUniform4f muTextureAddColor;
|
||||
|
||||
public:
|
||||
|
||||
PolymostShader() = default;
|
||||
virtual bool Load(const char * name, const char * vert_prog_lump, const char * fragprog); //, const char * fragprog2, const char *defines);
|
||||
};
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
class FBufferedUniform1i
|
||||
{
|
||||
int mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar* name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(int newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1i(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FBufferedUniform1f
|
||||
{
|
||||
float mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(float newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1f(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform2f
|
||||
{
|
||||
float mBuffer[2];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform2fv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
void Set(float f1, float f2)
|
||||
{
|
||||
if (mBuffer[0] != f1 || mBuffer[1] != f2)
|
||||
{
|
||||
mBuffer[0] = f1;
|
||||
mBuffer[1] = f2;
|
||||
glUniform2fv(mIndex, 1, mBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FBufferedUniform4f
|
||||
{
|
||||
float mBuffer[4];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform4fv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniformPalEntry
|
||||
{
|
||||
PalEntry mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar* name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(PalEntry newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform4f(mIndex,
|
||||
newvalue.r * (1 / 255.f),
|
||||
newvalue.g * (1 / 255.f),
|
||||
newvalue.b * (1 / 255.f),
|
||||
newvalue.a * (1 / 255.f));
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FUniformMatrix4f
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
glUniformMatrix4fv(mIndex, 1, false, newvalue);
|
||||
}
|
||||
};
|
|
@ -34,40 +34,25 @@
|
|||
*/
|
||||
#include <memory>
|
||||
#include <assert.h>
|
||||
#include "gl_load.h"
|
||||
#include "glbackend.h"
|
||||
#include "gl_samplers.h"
|
||||
#include "gl_shader.h"
|
||||
#include "textures.h"
|
||||
#include "palette.h"
|
||||
//#include "imgui.h"
|
||||
#include "gamecontrol.h"
|
||||
//#include "imgui_impl_sdl.h"
|
||||
//#include "imgui_impl_opengl3.h"
|
||||
#include "baselayer.h"
|
||||
#include "gl_interface.h"
|
||||
#include "v_2ddrawer.h"
|
||||
#include "v_video.h"
|
||||
#include "flatvertices.h"
|
||||
#include "gl_renderer.h"
|
||||
#include "build.h"
|
||||
#include "v_draw.h"
|
||||
#include "v_font.h"
|
||||
#include "hw_viewpointuniforms.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
#include "gl_renderstate.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_cvars.h"
|
||||
|
||||
F2DDrawer twodpsp;
|
||||
static int BufferLock = 0;
|
||||
|
||||
CVAR(Bool, hw_use_backend, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
|
||||
static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
|
||||
static int renderops[] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT };
|
||||
int depthf[] = { GL_ALWAYS, GL_LESS, GL_EQUAL, GL_LEQUAL };
|
||||
|
||||
TArray<VSMatrix> matrixArray;
|
||||
|
||||
FileReader GetResource(const char* fn)
|
||||
|
@ -95,95 +80,18 @@ TArray<uint8_t> ttf;
|
|||
|
||||
void GLInstance::Init(int ydim)
|
||||
{
|
||||
//glinfo.bufferstorage = !!strstr(glinfo.extensions, "GL_ARB_buffer_storage");
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy);
|
||||
|
||||
new(&renderState) PolymostRenderState; // reset to defaults.
|
||||
LoadPolymostShader();
|
||||
}
|
||||
|
||||
auto i_data = R"(
|
||||
#version 330
|
||||
// This must match the HWViewpointUniforms struct
|
||||
layout(std140) uniform ViewpointUBO {
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 ViewMatrix;
|
||||
mat4 NormalViewMatrix;
|
||||
|
||||
vec4 uCameraPos;
|
||||
vec4 uClipLine;
|
||||
|
||||
float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
|
||||
int uPalLightLevels;
|
||||
int uViewHeight; // Software fuzz scaling
|
||||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uShadowmapFilter;
|
||||
};
|
||||
uniform sampler2D detailtexture;
|
||||
uniform sampler2D glowtexture;
|
||||
uniform sampler2D brighttexture;
|
||||
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 NormalModelMatrix;
|
||||
uniform mat4 TextureMatrix;
|
||||
uniform vec4 uDetailParms;
|
||||
|
||||
uniform vec4 uTextureBlendColor;
|
||||
uniform vec4 uTextureModulateColor;
|
||||
uniform vec4 uTextureAddColor;
|
||||
|
||||
uniform float uAlphaThreshold;
|
||||
uniform vec4 uLightAttr;
|
||||
#define uLightLevel uLightAttr.a
|
||||
#define uFogDensity uLightAttr.b
|
||||
#define uLightFactor uLightAttr.g
|
||||
#define uLightDist uLightAttr.r
|
||||
uniform int uFogEnabled;
|
||||
uniform vec4 uFogColor;
|
||||
uniform int uTextureMode;
|
||||
uniform vec2 uNpotEmulation;
|
||||
|
||||
)";
|
||||
|
||||
void GLInstance::LoadPolymostShader()
|
||||
{
|
||||
auto fr1 = GetResource("engine/shaders/glsl/polymost.vp");
|
||||
TArray<uint8_t> Vert = fr1.Read();
|
||||
fr1 = GetResource("engine/shaders/glsl/polymost.fp");
|
||||
TArray<uint8_t> Frag = fr1.Read();
|
||||
// Zero-terminate both strings.
|
||||
Vert.Push(0);
|
||||
Frag.Push(0);
|
||||
FStringf VertS("%s\n%s", i_data, Vert.Data());
|
||||
FStringf FragS("%s\n%s", i_data, Frag.Data());
|
||||
polymostShader = new PolymostShader();
|
||||
polymostShader->Load("PolymostShader", (const char*)VertS.GetChars(), (const char*)FragS.GetChars());
|
||||
SetPolymostShader();
|
||||
}
|
||||
|
||||
void GLInstance::InitGLState(int fogmode, int multisample)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (multisample > 0 )
|
||||
{
|
||||
//glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
// This is a bad place to call this but without deconstructing the entire render loops in all front ends there is no way to have a well defined spot for this stuff.
|
||||
// Before doing that the backend needs to work in some fashion, so we have to make sure everything is set up when the first render call is performed.
|
||||
screen->BeginFrame();
|
||||
bool useSSAO = (gl_ssao != 0);
|
||||
OpenGLRenderer::GLRenderer->mBuffers->BindSceneFB(useSSAO);
|
||||
ClearBufferState();
|
||||
}
|
||||
|
||||
void GLInstance::Deinit()
|
||||
{
|
||||
if (polymostShader) delete polymostShader;
|
||||
polymostShader = nullptr;
|
||||
activeShader = nullptr;
|
||||
palmanager.DeleteAll();
|
||||
lastPalswapIndex = -1;
|
||||
}
|
||||
|
@ -201,28 +109,6 @@ void GLInstance::ResetFrame()
|
|||
|
||||
}
|
||||
|
||||
void GLInstance::SetVertexBuffer(IVertexBuffer* vb, int offset1, int offset2)
|
||||
{
|
||||
int o[] = { offset1, offset2 };
|
||||
static_cast<OpenGLRenderer::GLVertexBuffer*>(vb)->Bind(o);
|
||||
}
|
||||
|
||||
void GLInstance::SetIndexBuffer(IIndexBuffer* vb)
|
||||
{
|
||||
if (vb) static_cast<OpenGLRenderer::GLIndexBuffer*>(vb)->Bind();
|
||||
else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GLInstance::ClearBufferState()
|
||||
{
|
||||
SetVertexBuffer(screen->mVertexData->GetBufferObjects().first, 0, 0);
|
||||
SetIndexBuffer(nullptr);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
assert (BufferLock > 0);
|
||||
|
@ -235,41 +121,12 @@ void GLInstance::Draw(EDrawType type, size_t start, size_t count)
|
|||
renderState.StateFlags &= ~(STF_CLEARCOLOR | STF_CLEARDEPTH | STF_VIEWPORTSET | STF_SCISSORSET);
|
||||
}
|
||||
|
||||
void GLInstance::DrawElement(EDrawType type, size_t start, size_t count, PolymostRenderState &renderState)
|
||||
{
|
||||
if (activeShader == polymostShader)
|
||||
{
|
||||
glVertexAttrib4fv(2, renderState.Color);
|
||||
renderState.Apply(polymostShader, lastState);
|
||||
}
|
||||
if (type != DT_Lines)
|
||||
{
|
||||
glDrawElements(primtypes[type], count, GL_UNSIGNED_INT, (void*)(intptr_t)(start * sizeof(uint32_t)));
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawArrays(primtypes[type], start, count);
|
||||
}
|
||||
}
|
||||
|
||||
void GLInstance::DoDraw()
|
||||
{
|
||||
if (hw_use_backend)
|
||||
for (auto& rs : rendercommands)
|
||||
{
|
||||
for (auto& rs : rendercommands)
|
||||
{
|
||||
rs.Apply(*screen->RenderState(), lastState);
|
||||
screen->RenderState()->Draw(rs.primtype, rs.vindex, rs.vcount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& rs : rendercommands)
|
||||
{
|
||||
glVertexAttrib4fv(2, rs.Color);
|
||||
rs.Apply(polymostShader, lastState);
|
||||
glDrawArrays(primtypes[rs.primtype], rs.vindex, rs.vcount);
|
||||
}
|
||||
rs.Apply(*screen->RenderState(), lastState);
|
||||
screen->RenderState()->Draw(rs.primtype, rs.vindex, rs.vcount);
|
||||
}
|
||||
rendercommands.Clear();
|
||||
matrixArray.Resize(1);
|
||||
|
@ -290,17 +147,6 @@ void GLInstance::SetIdentityMatrix(int num)
|
|||
}
|
||||
|
||||
|
||||
void GLInstance::ReadPixels(int xdim, int ydim, uint8_t* buffer)
|
||||
{
|
||||
glReadPixels(0, 0, xdim, ydim, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
||||
}
|
||||
|
||||
void GLInstance::SetPolymostShader()
|
||||
{
|
||||
polymostShader->Bind();
|
||||
activeShader = polymostShader;
|
||||
}
|
||||
|
||||
void GLInstance::SetPalette(int index)
|
||||
{
|
||||
palmanager.BindPalette(index);
|
||||
|
@ -313,250 +159,6 @@ void GLInstance::SetPalswap(int index)
|
|||
renderState.ShadeDiv = lookups.tables[index].ShadeFactor;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a texture to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void PolymostRenderState::ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader, PolymostShader* shader)
|
||||
{
|
||||
auto tex = mat->Source();
|
||||
clampmode = tex->GetClampMode(clampmode);
|
||||
|
||||
// avoid rebinding the same texture multiple times.
|
||||
//if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return;
|
||||
#if 0
|
||||
lastMaterial = mat;
|
||||
lastClamp = clampmode;
|
||||
lastTranslation = translation;
|
||||
#endif
|
||||
|
||||
int scf = 0;
|
||||
if (Flags & RF_UsePalette)
|
||||
{
|
||||
scf |= CTF_Indexed;
|
||||
translation = -1;
|
||||
}
|
||||
|
||||
int usebright = false;
|
||||
int maxbound = 0;
|
||||
|
||||
int numLayers = mat->NumLayers();
|
||||
MaterialLayerInfo* layer;
|
||||
auto base = static_cast<OpenGLRenderer::FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
|
||||
scf |= layer->scaleFlags;
|
||||
if (base->BindOrCreate(layer->layerTexture, 0, layer->clampflags == -1? clampmode : layer->clampflags, translation, scf))
|
||||
{
|
||||
int LayerFlags = 0;
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
auto systex = static_cast<OpenGLRenderer::FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
// fixme: Upscale flags must be disabled for certain layers.
|
||||
systex->BindOrCreate(layer->layerTexture, i, layer->clampflags == -1 ? clampmode : layer->clampflags, 0, layer->scaleFlags);
|
||||
maxbound = i;
|
||||
LayerFlags |= 32768 << i;
|
||||
}
|
||||
shader->TextureMode.Set(LayerFlags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PolymostRenderState::Apply(PolymostShader* shader, GLState& oldState)
|
||||
{
|
||||
if (!OpenGLRenderer::GLRenderer) return;
|
||||
auto sm = OpenGLRenderer::GLRenderer->mSamplerManager;
|
||||
|
||||
bool reset = false;
|
||||
if (mMaterial.mChanged)
|
||||
{
|
||||
mMaterial.mChanged = false;
|
||||
ApplyMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader, shader);
|
||||
float buffer[] = { mMaterial.mMaterial->GetDetailScale().X, mMaterial.mMaterial->GetDetailScale().Y, 1.f, 0.f };
|
||||
shader->DetailParms.Set(buffer);
|
||||
}
|
||||
|
||||
if (PaletteTexture != nullptr)
|
||||
{
|
||||
PaletteTexture->Bind(4, false);
|
||||
sm->Bind(4, CLAMP_NOFILTER, -1);
|
||||
}
|
||||
if (LookupTexture != nullptr)
|
||||
{
|
||||
LookupTexture->Bind(5, false);
|
||||
sm->Bind(5, CLAMP_NOFILTER, -1);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
|
||||
if (StateFlags != oldState.Flags)
|
||||
{
|
||||
if ((StateFlags ^ oldState.Flags) & STF_DEPTHTEST)
|
||||
{
|
||||
if (StateFlags & STF_DEPTHTEST) glEnable(GL_DEPTH_TEST);
|
||||
else glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & STF_BLEND)
|
||||
{
|
||||
if (StateFlags & STF_BLEND) glEnable(GL_BLEND);
|
||||
else glDisable(GL_BLEND);
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & STF_MULTISAMPLE)
|
||||
{
|
||||
if (StateFlags & STF_MULTISAMPLE) glEnable(GL_MULTISAMPLE);
|
||||
else glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & (STF_STENCILTEST | STF_STENCILWRITE))
|
||||
{
|
||||
if (StateFlags & STF_STENCILWRITE)
|
||||
{
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 1/*value*/, 0xFF);
|
||||
}
|
||||
else if (StateFlags & STF_STENCILTEST)
|
||||
{
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_EQUAL, 1/*value*/, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & (STF_CULLCW | STF_CULLCCW))
|
||||
{
|
||||
if (StateFlags & (STF_CULLCW | STF_CULLCCW))
|
||||
{
|
||||
glFrontFace(StateFlags & STF_CULLCW ? GL_CW : GL_CCW);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK); // Cull_Front is not being used.
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & STF_COLORMASK)
|
||||
{
|
||||
if (StateFlags & STF_COLORMASK) glColorMask(1, 1, 1, 1);
|
||||
else glColorMask(0, 0, 0, 0);
|
||||
}
|
||||
if ((StateFlags ^ oldState.Flags) & STF_DEPTHMASK)
|
||||
{
|
||||
if (StateFlags & STF_DEPTHMASK) glDepthMask(1);
|
||||
else glDepthMask(0);
|
||||
}
|
||||
if (StateFlags & (STF_CLEARCOLOR | STF_CLEARDEPTH))
|
||||
{
|
||||
glClearColor(ClearColor.r / 255.f, ClearColor.g / 255.f, ClearColor.b / 255.f, 1.f);
|
||||
int bit = 0;
|
||||
if (StateFlags & STF_CLEARCOLOR) bit |= GL_COLOR_BUFFER_BIT;
|
||||
if (StateFlags & STF_CLEARDEPTH) bit |= GL_DEPTH_BUFFER_BIT;
|
||||
glClear(bit);
|
||||
}
|
||||
if (StateFlags & STF_VIEWPORTSET)
|
||||
{
|
||||
glViewport(vp_x, vp_y, vp_w, vp_h);
|
||||
}
|
||||
if (StateFlags & STF_SCISSORSET)
|
||||
{
|
||||
if (sc_x > SHRT_MIN)
|
||||
{
|
||||
glScissor(sc_x, sc_y, sc_w, sc_h);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
else
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
if (mBias.mChanged)
|
||||
{
|
||||
if (mBias.mFactor == 0 && mBias.mUnits == 0)
|
||||
{
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
glPolygonOffset(mBias.mFactor, mBias.mUnits);
|
||||
mBias.mChanged = false;
|
||||
}
|
||||
|
||||
StateFlags &= ~(STF_CLEARCOLOR | STF_CLEARDEPTH | STF_VIEWPORTSET | STF_SCISSORSET);
|
||||
oldState.Flags = StateFlags;
|
||||
}
|
||||
if (Style != oldState.Style)
|
||||
{
|
||||
glBlendFunc(blendstyles[Style.SrcAlpha], blendstyles[Style.DestAlpha]);
|
||||
if (Style.BlendOp != oldState.Style.BlendOp) glBlendEquation(renderops[Style.BlendOp]);
|
||||
oldState.Style = Style;
|
||||
// Flags are not being checked yet, the current shader has no implementation for them.
|
||||
}
|
||||
if (DepthFunc != oldState.DepthFunc)
|
||||
{
|
||||
glDepthFunc(depthf[DepthFunc]);
|
||||
oldState.DepthFunc = DepthFunc;
|
||||
}
|
||||
// Disable brightmaps if non-black fog is used.
|
||||
if (!(Flags & RF_FogDisabled) && ShadeDiv >= 1 / 1000.f)
|
||||
{
|
||||
if (!FogColor.isBlack())
|
||||
{
|
||||
//Flags &= ~RF_Brightmapping;
|
||||
shader->muFogEnabled.Set(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->muFogEnabled.Set(1);
|
||||
}
|
||||
}
|
||||
else shader->muFogEnabled.Set(0);
|
||||
|
||||
shader->Flags.Set(Flags);
|
||||
shader->NPOTEmulation.Set(&NPOTEmulation.X);
|
||||
shader->AlphaThreshold.Set(AlphaTest ? AlphaThreshold : -1.f);
|
||||
shader->FogColor.Set((Flags& RF_MapFog)? PalEntry(0x999999) : FogColor);
|
||||
float lightattr[] = { ShadeDiv / (numshades - 2), VisFactor, (Flags & RF_MapFog) ? -5.f : 0.f , ShadeDiv >= 1 / 1000.f? Shade : 0 };
|
||||
shader->muLightParms.Set(lightattr);
|
||||
|
||||
FVector4 addcol(0, 0, 0, 0);
|
||||
FVector4 modcol(fullscreenTint.r / 255.f, fullscreenTint.g / 255.f, fullscreenTint.b / 255.f, 0);
|
||||
FVector4 blendcol(0, 0, 0, 0);
|
||||
int flags = 0;
|
||||
if (fullscreenTint != 0xffffff) flags |= 16;
|
||||
if (hictint_flags != -1)
|
||||
{
|
||||
flags |= 16;
|
||||
if (hictint_flags & TINTF_COLORIZE)
|
||||
{
|
||||
modcol.X *= hictint.r / 64.f;
|
||||
modcol.Y *= hictint.g / 64.f;
|
||||
modcol.Z *= hictint.b / 64.f;
|
||||
}
|
||||
if (hictint_flags & TINTF_GRAYSCALE)
|
||||
modcol.W = 1.f;
|
||||
|
||||
if (hictint_flags & TINTF_INVERT)
|
||||
flags |= 8;
|
||||
|
||||
if (hictint_flags & TINTF_BLENDMASK)
|
||||
flags |= ((hictint_flags & TINTF_BLENDMASK) >> 6) + 1;
|
||||
|
||||
addcol.W = flags;
|
||||
}
|
||||
shader->muTextureAddColor.Set(&addcol[0]);
|
||||
shader->muTextureModulateColor.Set(&modcol[0]);
|
||||
shader->muTextureBlendColor.Set(&blendcol[0]);
|
||||
if (matrixIndex[Matrix_Model] != -1)
|
||||
shader->ModelMatrix.Set(matrixArray[matrixIndex[Matrix_Model]].get());
|
||||
|
||||
memset(matrixIndex, -1, sizeof(matrixIndex));
|
||||
}
|
||||
|
||||
void PolymostRenderState::Apply(FRenderState& state, GLState& oldState)
|
||||
{
|
||||
if (Flags & RF_ColorOnly)
|
||||
|
@ -714,7 +316,7 @@ void WriteSavePic(FileWriter* file, int width, int height)
|
|||
auto& RenderState = *screen->RenderState();
|
||||
|
||||
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
||||
glFinish();
|
||||
screen->WaitForCommands(false);
|
||||
screen->mVertexData->Reset();
|
||||
|
||||
// Switch to render buffers dimensioned for the savepic
|
||||
|
@ -787,7 +389,7 @@ void renderBeginScene()
|
|||
assert(BufferLock == 0);
|
||||
|
||||
vp.mPalLightLevels = numshades | (static_cast<int>(gl_fogmode) << 8) | ((int)5 << 16);
|
||||
screen->mViewpoints->SetViewpoint(OpenGLRenderer::gl_RenderState, &vp);
|
||||
screen->mViewpoints->SetViewpoint(*screen->RenderState(), &vp);
|
||||
|
||||
if (BufferLock++ == 0)
|
||||
{
|
||||
|
@ -851,7 +453,6 @@ void videoShowFrame(int32_t w)
|
|||
|
||||
float Brightness = 8.f / (r_scenebrightness + 8.f);
|
||||
|
||||
OpenGLRenderer::GLRenderer->mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
|
||||
screen->PostProcessScene(false, 0, Brightness, []() {
|
||||
Draw2D(&twodpsp, *screen->RenderState()); // draws the weapon sprites
|
||||
});
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "pm_renderstate.h"
|
||||
|
||||
class FShader;
|
||||
class PolymostShader;
|
||||
class FGameTexture;
|
||||
class GLInstance;
|
||||
class F2DDrawer;
|
||||
|
@ -79,7 +78,6 @@ struct GLState
|
|||
int Flags = STF_COLORMASK | STF_DEPTHMASK;
|
||||
FRenderStyle Style{};
|
||||
int DepthFunc = -1;
|
||||
int TexId[MAX_TEXTURES] = {}, SamplerId[MAX_TEXTURES] = {};
|
||||
};
|
||||
|
||||
class GLInstance
|
||||
|
@ -96,18 +94,14 @@ public:
|
|||
GLState lastState;
|
||||
|
||||
PolymostRenderState renderState;
|
||||
FShader* activeShader;
|
||||
|
||||
|
||||
public:
|
||||
float mProjectionM5 = 1.0f; // needed by ssao
|
||||
PolymostShader* polymostShader;
|
||||
glinfo_t glinfo;
|
||||
|
||||
void Init(int y);
|
||||
void InitGLState(int fogmode, int multisample);
|
||||
void LoadPolymostShader();
|
||||
void Draw2D(F2DDrawer* drawer);
|
||||
void ResetFrame();
|
||||
|
||||
void Deinit();
|
||||
|
@ -121,14 +115,9 @@ public:
|
|||
GLInstance();
|
||||
void Draw(EDrawType type, size_t start, size_t count);
|
||||
void DoDraw();
|
||||
void DrawElement(EDrawType type, size_t start, size_t count, PolymostRenderState& renderState);
|
||||
|
||||
OpenGLRenderer::FHardwareTexture* NewTexture(int numchannels = 4);
|
||||
|
||||
void SetVertexBuffer(IVertexBuffer* vb, int offset1, int offset2);
|
||||
void SetIndexBuffer(IIndexBuffer* vb);
|
||||
void ClearBufferState();
|
||||
|
||||
float GetProjectionM5() { return mProjectionM5; }
|
||||
int SetMatrix(int num, const VSMatrix *mat );
|
||||
int SetMatrix(int num, const float *mat)
|
||||
|
@ -141,11 +130,8 @@ public:
|
|||
renderState.matrixIndex[num] = index;
|
||||
}
|
||||
|
||||
void SetPolymostShader();
|
||||
void SetPalette(int palette);
|
||||
|
||||
void ReadPixels(int w, int h, uint8_t* buffer);
|
||||
|
||||
void SetTextureMode(int m)
|
||||
{
|
||||
renderState.TextureMode = m;
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
** hw_draw2d.cpp
|
||||
** 2d drawer Renderer interface
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2018-2019 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.
|
||||
**
|
||||
** 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_load.h"
|
||||
#include "cmdlib.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "v_2ddrawer.h"
|
||||
#include "c_cvars.h"
|
||||
#include "glbackend.h"
|
||||
#include "v_draw.h"
|
||||
#include "palette.h"
|
||||
#include "flatvertices.h"
|
||||
#include "build.h"
|
||||
#include "v_video.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
#include "gl_renderstate.h"
|
||||
|
||||
extern int16_t numshades;
|
||||
extern TArray<VSMatrix> matrixArray;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer for 2D drawer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
class F2DVertexBuffer
|
||||
{
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
IIndexBuffer *mIndexBuffer;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
F2DVertexBuffer()
|
||||
{
|
||||
mVertexBuffer = new OpenGLRenderer::GLVertexBuffer();
|
||||
mIndexBuffer = new OpenGLRenderer::GLIndexBuffer();
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(F2DDrawer::TwoDVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(F2DDrawer::TwoDVertex, u) },
|
||||
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(F2DDrawer::TwoDVertex, color0) }
|
||||
};
|
||||
mVertexBuffer->SetFormat(1, 3, sizeof(F2DDrawer::TwoDVertex), format);
|
||||
}
|
||||
~F2DVertexBuffer()
|
||||
{
|
||||
delete mIndexBuffer;
|
||||
delete mVertexBuffer;
|
||||
}
|
||||
|
||||
void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount)
|
||||
{
|
||||
mVertexBuffer->SetData(vertcount * sizeof(*vertices), vertices, false);
|
||||
mIndexBuffer->SetData(indexcount * sizeof(unsigned int), indices, false);
|
||||
}
|
||||
|
||||
std::pair<IVertexBuffer *, IIndexBuffer *> GetBufferObjects() const
|
||||
{
|
||||
return std::make_pair(mVertexBuffer, mIndexBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
|
||||
//
|
||||
//===========================================================================
|
||||
void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid);
|
||||
|
||||
void GLInstance::Draw2D(F2DDrawer *drawer)
|
||||
{
|
||||
VSMatrix mat(0);
|
||||
screen->mViewpoints->Set2D(OpenGLRenderer::gl_RenderState, xdim, ydim, numshades);
|
||||
SetViewport(0, 0, xdim, ydim);
|
||||
EnableDepthTest(false);
|
||||
EnableMultisampling(false);
|
||||
EnableBlend(true);
|
||||
EnableAlphaTest(true);
|
||||
SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
||||
|
||||
auto &vertices = drawer->mVertices;
|
||||
auto &indices = drawer->mIndices;
|
||||
auto &commands = drawer->mData;
|
||||
|
||||
if (commands.Size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawer->mIsFirstPass)
|
||||
{
|
||||
for (auto &v : vertices)
|
||||
{
|
||||
// Change from BGRA to RGBA
|
||||
std::swap(v.color0.r, v.color0.b);
|
||||
}
|
||||
}
|
||||
F2DVertexBuffer vb;
|
||||
vb.UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
|
||||
assert(vb.GetBufferObjects().first && vb.GetBufferObjects().second);
|
||||
SetVertexBuffer(vb.GetBufferObjects().first, 0, 0);
|
||||
SetIndexBuffer(vb.GetBufferObjects().second);
|
||||
SetFadeDisable(true);
|
||||
|
||||
for(auto &cmd : commands)
|
||||
{
|
||||
|
||||
|
||||
int gltrans = -1;
|
||||
|
||||
SetRenderStyle(cmd.mRenderStyle);
|
||||
//state.EnableBrightmap(!(cmd.mRenderStyle.Flags & STYLEF_ColorIsFixed));
|
||||
//state.SetTextureMode(cmd.mDrawMode);
|
||||
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Scissor)
|
||||
{
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
// Note that the origin here is the lower left corner!
|
||||
int sciX = screen->ScreenToWindowX(cmd.mScissor[0]);
|
||||
int sciY = screen->ScreenToWindowY(cmd.mScissor[3]);
|
||||
int sciW = screen->ScreenToWindowX(cmd.mScissor[2]) - sciX;
|
||||
int sciH = screen->ScreenToWindowY(cmd.mScissor[1]) - sciY;
|
||||
if (sciX < 0) sciW += sciX, sciX = 0;
|
||||
if (sciY < 0) sciH += sciY, sciY = 0;
|
||||
SetScissor(sciX, sciY, sciW, sciH);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableScissor();
|
||||
}
|
||||
|
||||
auto tex = cmd.mTexture;
|
||||
if (tex != nullptr && tex->isValid())
|
||||
{
|
||||
auto tex = cmd.mTexture;
|
||||
|
||||
SetFadeDisable(cmd.mLightLevel == 0);
|
||||
SetShade(cmd.mLightLevel, numshades);
|
||||
|
||||
SetTexture(TileFiles.GetTileIndex(tex), tex, cmd.mTranslationId, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY);
|
||||
EnableBlend(!(cmd.mRenderStyle.Flags & STYLEF_Alpha1));
|
||||
UseColorOnly(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UseColorOnly(true);
|
||||
}
|
||||
|
||||
switch (cmd.mType)
|
||||
{
|
||||
case F2DDrawer::DrawTypeTriangles:
|
||||
DrawElement(DT_Triangles, cmd.mIndexIndex, cmd.mIndexCount, renderState);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypeLines:
|
||||
DrawElement(DT_Lines, cmd.mVertIndex, cmd.mVertCount, renderState);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypePoints:
|
||||
//Draw(DT_POINTS, cmd.mVertIndex, cmd.mVertCount);
|
||||
break;
|
||||
|
||||
}
|
||||
/*
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.SetObjectColor2(0);
|
||||
state.SetAddColor(0);
|
||||
state.EnableTextureMatrix(false);
|
||||
state.SetEffect(EFF_NONE);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
//state.SetRenderStyle(STYLE_Translucent);
|
||||
ClearBufferState();
|
||||
UseColorOnly(false);
|
||||
//state.EnableBrightmap(true);
|
||||
//state.SetTextureMode(TM_NORMAL);
|
||||
SetShade(0, numshades);
|
||||
SetFadeDisable(false);
|
||||
SetColor(1, 1, 1);
|
||||
DisableScissor();
|
||||
//drawer->mIsFirstPass = false;
|
||||
EnableBlend(true);
|
||||
EnableMultisampling(true);
|
||||
matrixArray.Resize(1);
|
||||
renderState.Apply(polymostShader, lastState); // actually set the desired state before returning.
|
||||
}
|
||||
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
#include "palentry.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "renderstyle.h"
|
||||
class PolymostShader;
|
||||
struct GLState;
|
||||
class FMaterial;
|
||||
|
||||
|
@ -74,7 +73,5 @@ struct PolymostRenderState
|
|||
|
||||
PalEntry FogColor;
|
||||
|
||||
void ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader, PolymostShader *shader);
|
||||
void Apply(PolymostShader *shader, GLState &oldstate);
|
||||
void Apply(FRenderState & state, GLState& oldState);
|
||||
};
|
||||
|
|
|
@ -1,268 +0,0 @@
|
|||
const int RF_ColorOnly = 1;
|
||||
const int RF_UsePalette = 2;
|
||||
const int RF_ShadeInterpolate = 64;
|
||||
|
||||
const int TEXF_Brightmap = 0x10000;
|
||||
const int TEXF_Detailmap = 0x20000;
|
||||
const int TEXF_Glowmap = 0x40000;
|
||||
|
||||
|
||||
struct Material
|
||||
{
|
||||
vec4 Base;
|
||||
vec4 Bright;
|
||||
vec4 Glow;
|
||||
vec3 Normal;
|
||||
vec3 Specular;
|
||||
float Glossiness;
|
||||
float SpecularLevel;
|
||||
float Metallic;
|
||||
float Roughness;
|
||||
float AO;
|
||||
};
|
||||
|
||||
Material material;
|
||||
|
||||
|
||||
//s_texture points to an indexed color texture
|
||||
uniform sampler2D s_texture;
|
||||
//s_palswap is the palette swap texture where u is the color index and v is the shade
|
||||
uniform sampler2D s_palswap;
|
||||
//s_palette is the base palette texture where u is the color index
|
||||
uniform sampler2D s_palette;
|
||||
|
||||
uniform int u_flags;
|
||||
|
||||
in vec4 v_color;
|
||||
in float v_distance;
|
||||
in vec4 v_texCoord;
|
||||
in vec4 v_detailCoord;
|
||||
in float v_fogCoord;
|
||||
in vec4 v_eyeCoordPosition;
|
||||
in vec4 v_worldPosition;
|
||||
|
||||
layout(location=0) out vec4 fragColor;
|
||||
layout(location=1) out vec4 fragFog;
|
||||
layout(location=2) out vec4 fragNormal;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Color to grayscale
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float grayscale(vec4 color)
|
||||
{
|
||||
return dot(color.rgb, vec3(0.3, 0.56, 0.14));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Desaturate a color
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
vec4 dodesaturate(vec4 texel, float factor)
|
||||
{
|
||||
if (factor != 0.0)
|
||||
{
|
||||
float gray = grayscale(texel);
|
||||
return mix (texel, vec4(gray,gray,gray,texel.a), factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return texel;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Texture tinting code originally from JFDuke but with a few more options
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
const int Tex_Blend_Alpha = 1;
|
||||
const int Tex_Blend_Screen = 2;
|
||||
const int Tex_Blend_Overlay = 3;
|
||||
const int Tex_Blend_Hardlight = 4;
|
||||
|
||||
vec4 ApplyTextureManipulation(vec4 texel, int blendflags)
|
||||
{
|
||||
// Step 1: desaturate according to the material's desaturation factor.
|
||||
texel = dodesaturate(texel, uTextureModulateColor.a);
|
||||
|
||||
// Step 2: Invert if requested
|
||||
if ((blendflags & 8) != 0)
|
||||
{
|
||||
texel.rgb = vec3(1.0 - texel.r, 1.0 - texel.g, 1.0 - texel.b);
|
||||
}
|
||||
|
||||
// Step 3: Apply additive color
|
||||
texel.rgb += uTextureAddColor.rgb;
|
||||
|
||||
// Step 4: Colorization, including gradient if set.
|
||||
texel.rgb *= uTextureModulateColor.rgb;
|
||||
|
||||
// Before applying the blend the value needs to be clamped to [0..1] range.
|
||||
texel.rgb = clamp(texel.rgb, 0.0, 1.0);
|
||||
|
||||
// Step 5: Apply a blend. This may just be a translucent overlay or one of the blend modes present in current Build engines.
|
||||
if ((blendflags & 7) != 0)
|
||||
{
|
||||
vec3 tcol = texel.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math.
|
||||
vec4 tint = uTextureBlendColor * 255.0;
|
||||
|
||||
switch (blendflags & 7)
|
||||
{
|
||||
default:
|
||||
tcol.b = tcol.b * (1.0 - uTextureBlendColor.a) + tint.b * uTextureBlendColor.a;
|
||||
tcol.g = tcol.g * (1.0 - uTextureBlendColor.a) + tint.g * uTextureBlendColor.a;
|
||||
tcol.r = tcol.r * (1.0 - uTextureBlendColor.a) + tint.r * uTextureBlendColor.a;
|
||||
break;
|
||||
// The following 3 are taken 1:1 from the Build engine
|
||||
case Tex_Blend_Screen:
|
||||
tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 256.0);
|
||||
tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 256.0);
|
||||
tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 256.0);
|
||||
break;
|
||||
case Tex_Blend_Overlay:
|
||||
tcol.b = tcol.b < 128.0? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0);
|
||||
tcol.g = tcol.g < 128.0? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0);
|
||||
tcol.r = tcol.r < 128.0? (tcol.r * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.r)) / 128.0);
|
||||
break;
|
||||
case Tex_Blend_Hardlight:
|
||||
tcol.b = tint.b < 128.0 ? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0);
|
||||
tcol.g = tint.g < 128.0 ? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0);
|
||||
tcol.r = tint.r < 128.0 ? (tcol.r * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.r)) / 128.0);
|
||||
break;
|
||||
}
|
||||
texel.rgb = tcol / 255.0;
|
||||
}
|
||||
return texel;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void main()
|
||||
{
|
||||
float fullbright = 0.0;
|
||||
vec4 color;
|
||||
if ((u_flags & RF_ColorOnly) == 0)
|
||||
{
|
||||
float coordX = v_texCoord.x;
|
||||
float coordY = v_texCoord.y;
|
||||
vec2 newCoord;
|
||||
|
||||
// Coordinate adjustment for NPOT textures. It is somehow fitting that Build games exploited this texture wrapping quirk of the software rendering engine...
|
||||
if (uNpotEmulation.y != 0.0)
|
||||
{
|
||||
float period = floor(coordY / uNpotEmulation.y);
|
||||
coordX += uNpotEmulation.x * floor(mod(coordY, uNpotEmulation.y));
|
||||
coordY = period + mod(coordY, uNpotEmulation.y);
|
||||
}
|
||||
newCoord = vec2(coordX, coordY);
|
||||
|
||||
color = texture(s_texture, newCoord);
|
||||
|
||||
float visibility = max(uGlobVis * uLightFactor * v_distance - ((u_flags & RF_ShadeInterpolate) != 0.0? 0.5 : 0.0), 0.0);
|
||||
float numShades = float(uPalLightLevels & 255);
|
||||
float shade = clamp((uLightLevel + visibility), 0.0, numShades - 1.0);
|
||||
|
||||
|
||||
if ((u_flags & RF_UsePalette) != 0)
|
||||
{
|
||||
int palindex = int(color.r * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
|
||||
int shadeindex = int(floor(shade));
|
||||
float colorIndexF = texelFetch(s_palswap, ivec2(palindex, shadeindex), 0).r;
|
||||
int colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
|
||||
vec4 palettedColor = texelFetch(s_palette, ivec2(colorIndex, 0), 0);
|
||||
|
||||
if ((u_flags & RF_ShadeInterpolate) != 0)
|
||||
{
|
||||
// Get the next shaded palette index for interpolation
|
||||
colorIndexF = texelFetch(s_palswap, ivec2(palindex, shadeindex+1), 0).r;
|
||||
colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
|
||||
vec4 palettedColorNext = texelFetch(s_palette, ivec2(colorIndex, 0), 0);
|
||||
float shadeFrac = mod(shade, 1.0);
|
||||
palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac);
|
||||
}
|
||||
|
||||
palettedColor.a = color.r == 0.0? 0.0 : 1.0;// 1.0-floor(color.r);
|
||||
color.rgb = palettedColor.rgb * v_color.rgb;
|
||||
color.a = palettedColor.a;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This was further down but it really should be done before applying any kind of depth fading, not afterward.
|
||||
if ((uTextureMode & TEXF_Detailmap) != 0)
|
||||
{
|
||||
vec4 detailColor = texture(detailtexture, newCoord * uDetailParms.xy) * uDetailParms.z;
|
||||
detailColor = mix(vec4(1.0), 2.0 * detailColor, detailColor.a);
|
||||
color.rgb *= detailColor.rgb;
|
||||
}
|
||||
|
||||
// Apply the texture modification colors.
|
||||
int blendflags = int(uTextureAddColor.a); // this alpha is unused otherwise
|
||||
if (blendflags != 0)
|
||||
{
|
||||
// only apply the texture manipulation if it contains something.
|
||||
color = ApplyTextureManipulation(color, blendflags);
|
||||
}
|
||||
|
||||
if (uFogEnabled != 0) // Right now this code doesn't care about the fog modes yet.
|
||||
{
|
||||
shade = clamp(shade * uLightDist, 0.0, 1.0);
|
||||
vec3 lightcolor = v_color.rgb * (1.0 - shade);
|
||||
|
||||
if ((uTextureMode & TEXF_Brightmap) != 0)
|
||||
{
|
||||
lightcolor = clamp(lightcolor + texture(brighttexture, v_texCoord.xy).rgb, 0.0, 1.0);
|
||||
}
|
||||
color.rgb *= lightcolor;
|
||||
if (uFogDensity == 0.0) color.rgb += uFogColor.rgb * shade;
|
||||
}
|
||||
else color.rgb *= v_color.rgb;
|
||||
|
||||
if ((uTextureMode & TEXF_Glowmap) != 0)
|
||||
{
|
||||
vec4 glowColor = texture(glowtexture, v_texCoord.xy);
|
||||
color.rgb = mix(color.rgb, glowColor.rgb, glowColor.a);
|
||||
}
|
||||
|
||||
}
|
||||
if (uFogDensity != 0.0) // fog hack for RRRA E2L1. Needs to be done better, this is gross, but still preferable to the broken original implementation.
|
||||
{
|
||||
float fogfactor = 0.55 + 0.3 * exp2 (uFogDensity * v_fogCoord / 1024.0);
|
||||
color.rgb = uFogColor.rgb * (1.0-fogfactor) + color.rgb * fogfactor;// mix(vec3(0.6), color.rgb, fogfactor);
|
||||
}
|
||||
if (color.a < uAlphaThreshold) discard; // it's only here that we have the alpha value available to be able to perform the alpha test.
|
||||
color.a *= v_color.a;
|
||||
}
|
||||
else
|
||||
{
|
||||
// untextured rendering
|
||||
color = v_color;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int ix = int (v_worldPosition.x);
|
||||
int iy = int (v_worldPosition.z);
|
||||
int iz = int (v_worldPosition.y);
|
||||
if ((ix & 64) == 1) color.r = 0;
|
||||
if ((iy & 64) == 1) color.g = 0;
|
||||
if ((iz & 64) == 1) color.b = 0;
|
||||
*/
|
||||
|
||||
fragColor = color;
|
||||
fragFog = vec4(0.0, 0.0, 0.0, 1.0); // Does build have colored fog?
|
||||
vec3 normal = normalize(cross(dFdx(v_eyeCoordPosition.xyz), dFdy(v_eyeCoordPosition.xyz)));
|
||||
normal.x = -normal.x;
|
||||
normal.y = -normal.y;
|
||||
fragNormal = vec4(normal * 0.5 + 0.5, 1.0);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
out vec4 v_color;
|
||||
out float v_distance;
|
||||
out vec4 v_texCoord;
|
||||
out float v_fogCoord;
|
||||
out vec4 v_eyeCoordPosition;
|
||||
out vec4 v_worldPosition;
|
||||
|
||||
layout(location = 0) in vec4 i_vertPos;
|
||||
layout(location = 1) in vec4 i_texCoord;
|
||||
layout(location = 2) in vec4 i_color;
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 vertex = ModelMatrix * i_vertPos;
|
||||
vec4 eyeCoordPosition = ViewMatrix * vertex;
|
||||
v_eyeCoordPosition = eyeCoordPosition;
|
||||
gl_Position = ProjectionMatrix * eyeCoordPosition;
|
||||
|
||||
eyeCoordPosition.xyz /= eyeCoordPosition.w;
|
||||
|
||||
v_texCoord = TextureMatrix * i_texCoord;
|
||||
|
||||
v_fogCoord = abs(eyeCoordPosition.z);
|
||||
|
||||
v_color = i_color;
|
||||
v_distance = eyeCoordPosition.z;
|
||||
v_worldPosition = vertex;
|
||||
}
|
Loading…
Reference in a new issue