- removed the old OpenGL interface.

This commit is contained in:
Christoph Oelckers 2020-06-12 00:25:52 +02:00
parent ba397f5ca1
commit 6a9f1e9da1
15 changed files with 9 additions and 1335 deletions

View file

@ -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

View file

@ -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();
}

View file

@ -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);
}

View file

@ -36,7 +36,6 @@
#include "templates.h"
#include "hw_vrmodes.h"
#include "v_draw.h"
#include "i_interface.h"
extern bool vid_hdr_active;

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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);
}
};

View file

@ -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
});

View file

@ -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;

View file

@ -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.
}

View file

@ -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);
};

View file

@ -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);
}

View file

@ -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;
}