- moved 2 more modules to 'common'.
This commit is contained in:
parent
f8dcb09ff0
commit
1346787e29
13 changed files with 23 additions and 23 deletions
|
|
@ -55,7 +55,7 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderstate.h"
|
||||
#include "gl_renderbuffers.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "menu/menu.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "md5.h"
|
||||
#include "m_misc.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "hwrenderer/utility/hw_shaderpatcher.h"
|
||||
#include "hw_shaderpatcher.h"
|
||||
#include "hwrenderer/data/shaderuniforms.h"
|
||||
#include "hwrenderer/scene/hw_viewpointuniforms.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
|
|
|
|||
|
|
@ -1,363 +0,0 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "gl_system.h"
|
||||
#include "v_video.h"
|
||||
#include "gl_interface.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gl_debug.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "hwrenderer/utility/hw_shaderpatcher.h"
|
||||
#include "filesystem.h"
|
||||
#include "printf.h"
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
bool IsShaderCacheActive();
|
||||
TArray<uint8_t> LoadCachedProgramBinary(const FString &vertex, const FString &fragment, uint32_t &binaryFormat);
|
||||
void SaveCachedProgramBinary(const FString &vertex, const FString &fragment, const TArray<uint8_t> &binary, uint32_t binaryFormat);
|
||||
|
||||
FShaderProgram::FShaderProgram()
|
||||
{
|
||||
for (int i = 0; i < NumShaderTypes; i++)
|
||||
mShaders[i] = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Free shader program resources
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderProgram::~FShaderProgram()
|
||||
{
|
||||
if (mProgram != 0)
|
||||
glDeleteProgram(mProgram);
|
||||
|
||||
for (int i = 0; i < NumShaderTypes; i++)
|
||||
{
|
||||
if (mShaders[i] != 0)
|
||||
glDeleteShader(mShaders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates an OpenGL shader object for the specified type of shader
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::CreateShader(ShaderType type)
|
||||
{
|
||||
GLenum gltype = 0;
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
case Vertex: gltype = GL_VERTEX_SHADER; break;
|
||||
case Fragment: gltype = GL_FRAGMENT_SHADER; break;
|
||||
}
|
||||
mShaders[type] = glCreateShader(gltype);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Compiles a shader and attaches it the program object
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
int lump = fileSystem.CheckNumForFullName(lumpName);
|
||||
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
|
||||
FString code = fileSystem.ReadFile(lump).GetString().GetChars();
|
||||
Compile(type, lumpName, code, defines, maxGlslVersion);
|
||||
}
|
||||
|
||||
void FShaderProgram::Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
mShaderNames[type] = name;
|
||||
mShaderSources[type] = PatchShader(type, code, defines, maxGlslVersion);
|
||||
}
|
||||
|
||||
void FShaderProgram::CompileShader(ShaderType type)
|
||||
{
|
||||
CreateShader(type);
|
||||
|
||||
const auto &handle = mShaders[type];
|
||||
|
||||
FGLDebug::LabelObject(GL_SHADER, handle, mShaderNames[type]);
|
||||
|
||||
const FString &patchedCode = mShaderSources[type];
|
||||
int lengths[1] = { (int)patchedCode.Len() };
|
||||
const char *sources[1] = { patchedCode.GetChars() };
|
||||
glShaderSource(handle, 1, sources, lengths);
|
||||
|
||||
glCompileShader(handle);
|
||||
|
||||
GLint status = 0;
|
||||
glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
I_FatalError("Compile Shader '%s':\n%s\n", mShaderNames[type].GetChars(), GetShaderInfoLog(handle).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mProgram == 0)
|
||||
mProgram = glCreateProgram();
|
||||
glAttachShader(mProgram, handle);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Links a program with the compiled shaders
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Link(const char *name)
|
||||
{
|
||||
FGLDebug::LabelObject(GL_PROGRAM, mProgram, name);
|
||||
|
||||
uint32_t binaryFormat = 0;
|
||||
TArray<uint8_t> binary;
|
||||
if (IsShaderCacheActive())
|
||||
binary = LoadCachedProgramBinary(mShaderSources[Vertex], mShaderSources[Fragment], binaryFormat);
|
||||
|
||||
bool loadedFromBinary = false;
|
||||
if (binary.Size() > 0 && glProgramBinary)
|
||||
{
|
||||
if (mProgram == 0)
|
||||
mProgram = glCreateProgram();
|
||||
glProgramBinary(mProgram, binaryFormat, binary.Data(), binary.Size());
|
||||
GLint status = 0;
|
||||
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
|
||||
loadedFromBinary = (status == GL_TRUE);
|
||||
}
|
||||
|
||||
if (!loadedFromBinary)
|
||||
{
|
||||
CompileShader(Vertex);
|
||||
CompileShader(Fragment);
|
||||
|
||||
glLinkProgram(mProgram);
|
||||
|
||||
GLint status = 0;
|
||||
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
I_FatalError("Link Shader '%s':\n%s\n", name, GetProgramInfoLog(mProgram).GetChars());
|
||||
}
|
||||
else if (glProgramBinary && IsShaderCacheActive())
|
||||
{
|
||||
int binaryLength = 0;
|
||||
glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
|
||||
binary.Resize(binaryLength);
|
||||
glGetProgramBinary(mProgram, binary.Size(), &binaryLength, &binaryFormat, binary.Data());
|
||||
binary.Resize(binaryLength);
|
||||
SaveCachedProgramBinary(mShaderSources[Vertex], mShaderSources[Fragment], binary, binaryFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// This is only for old OpenGL which didn't allow to set the binding from within the shader.
|
||||
if (screen->glslversion < 4.20)
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
for (auto &uni : samplerstobind)
|
||||
{
|
||||
auto index = glGetUniformLocation(mProgram, uni.first);
|
||||
if (index >= 0)
|
||||
{
|
||||
glUniform1i(index, uni.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
samplerstobind.Clear();
|
||||
samplerstobind.ShrinkToFit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Set uniform buffer location (only useful for GL 3.3)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::SetUniformBufferLocation(int index, const char *name)
|
||||
{
|
||||
if (screen->glslversion < 4.20)
|
||||
{
|
||||
GLuint uniformBlockIndex = glGetUniformBlockIndex(mProgram, name);
|
||||
if (uniformBlockIndex != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(mProgram, uniformBlockIndex, index);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the shader the active program
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Bind()
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the shader info log (warnings and compile errors)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::GetShaderInfoLog(GLuint handle)
|
||||
{
|
||||
static char buffer[10000];
|
||||
GLsizei length = 0;
|
||||
buffer[0] = 0;
|
||||
glGetShaderInfoLog(handle, 10000, &length, buffer);
|
||||
return FString(buffer);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the program info log (warnings and compile errors)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::GetProgramInfoLog(GLuint handle)
|
||||
{
|
||||
static char buffer[10000];
|
||||
GLsizei length = 0;
|
||||
buffer[0] = 0;
|
||||
glGetProgramInfoLog(handle, 10000, &length, buffer);
|
||||
return FString(buffer);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Patches a shader to be compatible with the version of OpenGL in use
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
FString patchedCode;
|
||||
|
||||
// If we have 4.2, always use it because it adds important new syntax.
|
||||
if (maxGlslVersion < 420 && gl.glslversion >= 4.2f) maxGlslVersion = 420;
|
||||
int shaderVersion = std::min((int)round(gl.glslversion * 10) * 10, maxGlslVersion);
|
||||
patchedCode.AppendFormat("#version %d\n", shaderVersion);
|
||||
|
||||
// TODO: Find some way to add extension requirements to the patching
|
||||
//
|
||||
// #extension GL_ARB_uniform_buffer_object : require
|
||||
// #extension GL_ARB_shader_storage_buffer_object : require
|
||||
|
||||
if (defines)
|
||||
patchedCode << defines;
|
||||
|
||||
// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here.
|
||||
patchedCode << "precision highp int;\n";
|
||||
patchedCode << "precision highp float;\n";
|
||||
|
||||
patchedCode << "#line 1\n";
|
||||
patchedCode << RemoveLayoutLocationDecl(code, type == Vertex ? "out" : "in");
|
||||
|
||||
if (maxGlslVersion < 420)
|
||||
{
|
||||
// Here we must strip out all layout(binding) declarations for sampler uniforms and store them in 'samplerstobind' which can then be processed by the link function.
|
||||
patchedCode = RemoveSamplerBindings(patchedCode, samplerstobind);
|
||||
}
|
||||
|
||||
return patchedCode;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name)
|
||||
{
|
||||
FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc());
|
||||
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders/pp/screenquad.vp", prolog, 330);
|
||||
mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330);
|
||||
mShader->Link(program_name);
|
||||
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
|
||||
Uniforms.Init();
|
||||
}
|
||||
|
||||
void FPresentShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/pp/present.fp", "shaders/pp/present");
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FPresent3DCheckerShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/pp/present_checker3d.fp", "shaders/pp/presentChecker3d");
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
void FPresent3DColumnShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/pp/present_column3d.fp", "shaders/pp/presentColumn3d");
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
void FPresent3DRowShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/pp/present_row3d.fp", "shaders/pp/presentRow3d");
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FShadowMapShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
FString prolog = Uniforms.CreateDeclaration("Uniforms", ShadowMapUniforms::Desc());
|
||||
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders/pp/screenquad.vp", "", 430);
|
||||
mShader->Compile(FShaderProgram::Fragment, "shaders/pp/shadowmap.fp", prolog, 430);
|
||||
mShader->Link("shaders/glsl/shadowmap");
|
||||
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
|
||||
Uniforms.Init();
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gl_system.h"
|
||||
#include "gl_shader.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
class FShaderProgram : public PPShaderBackend
|
||||
{
|
||||
public:
|
||||
FShaderProgram();
|
||||
~FShaderProgram();
|
||||
|
||||
enum ShaderType
|
||||
{
|
||||
Vertex,
|
||||
Fragment,
|
||||
NumShaderTypes
|
||||
};
|
||||
|
||||
void Compile(ShaderType type, const char *lumpName, const char *defines, int maxGlslVersion);
|
||||
void Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion);
|
||||
void Link(const char *name);
|
||||
void SetUniformBufferLocation(int index, const char *name);
|
||||
|
||||
void Bind();
|
||||
|
||||
GLuint Handle() { return mProgram; }
|
||||
//explicit operator bool() const { return mProgram != 0; }
|
||||
|
||||
std::unique_ptr<IDataBuffer> Uniforms;
|
||||
|
||||
private:
|
||||
FShaderProgram(const FShaderProgram &) = delete;
|
||||
FShaderProgram &operator=(const FShaderProgram &) = delete;
|
||||
|
||||
void CompileShader(ShaderType type);
|
||||
FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion);
|
||||
|
||||
void CreateShader(ShaderType type);
|
||||
FString GetShaderInfoLog(GLuint handle);
|
||||
FString GetProgramInfoLog(GLuint handle);
|
||||
|
||||
GLuint mProgram = 0;
|
||||
GLuint mShaders[NumShaderTypes];
|
||||
FString mShaderSources[NumShaderTypes];
|
||||
FString mShaderNames[NumShaderTypes];
|
||||
TArray<std::pair<FString, int>> samplerstobind;
|
||||
};
|
||||
|
||||
class FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
virtual ~FPresentShaderBase() {}
|
||||
virtual void Bind() = 0;
|
||||
|
||||
ShaderUniforms<PresentUniforms, POSTPROCESS_BINDINGPOINT> Uniforms;
|
||||
|
||||
protected:
|
||||
virtual void Init(const char * vtx_shader_name, const char * program_name);
|
||||
std::unique_ptr<FShaderProgram> mShader;
|
||||
};
|
||||
|
||||
class FPresentShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
|
||||
};
|
||||
|
||||
class FPresent3DCheckerShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
class FPresent3DColumnShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
class FPresent3DRowShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
class FShadowMapShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
ShaderUniforms<ShadowMapUniforms, POSTPROCESS_BINDINGPOINT> Uniforms;
|
||||
|
||||
private:
|
||||
std::unique_ptr<FShaderProgram> mShader;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "gl_debug.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "gl_buffers.h"
|
||||
|
|
|
|||
|
|
@ -1,299 +0,0 @@
|
|||
/*
|
||||
** hw_shaderpatcher.cpp
|
||||
** Modifies shader source to account for different syntax versions or engine changes.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright(C) 2004-2018 Christoph Oelckers
|
||||
** Copyright(C) 2016-2018 Magnus Norddahl
|
||||
** 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 "hw_shaderpatcher.h"
|
||||
|
||||
|
||||
static bool IsGlslWhitespace(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case '\f':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static FString NextGlslToken(const char *chars, long len, long &pos)
|
||||
{
|
||||
// Eat whitespace
|
||||
long tokenStart = pos;
|
||||
while (tokenStart != len && IsGlslWhitespace(chars[tokenStart]))
|
||||
tokenStart++;
|
||||
|
||||
// Find token end
|
||||
long tokenEnd = tokenStart;
|
||||
while (tokenEnd != len && !IsGlslWhitespace(chars[tokenEnd]) && chars[tokenEnd] != ';')
|
||||
tokenEnd++;
|
||||
|
||||
pos = tokenEnd;
|
||||
return FString(chars + tokenStart, tokenEnd - tokenStart);
|
||||
}
|
||||
|
||||
static bool isShaderType(const char *name)
|
||||
{
|
||||
return !strcmp(name, "sampler1D") || !strcmp(name, "sampler2D") || !strcmp(name, "sampler3D") || !strcmp(name, "samplerCube") || !strcmp(name, "sampler2DMS");
|
||||
}
|
||||
|
||||
FString RemoveLegacyUserUniforms(FString code)
|
||||
{
|
||||
// User shaders must declare their uniforms via the GLDEFS file.
|
||||
|
||||
code.Substitute("uniform sampler2D tex;", " ");
|
||||
code.Substitute("uniform float timer;", " ");
|
||||
|
||||
// The following code searches for legacy uniform declarations in the shader itself and replaces them with whitespace.
|
||||
|
||||
long len = (long)code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("uniform", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
bool isLegacyUniformName = false;
|
||||
|
||||
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
|
||||
bool isKeywordEnd = matchIndex + 7 == len || IsGlslWhitespace(chars[matchIndex + 7]);
|
||||
if (isKeywordStart && isKeywordEnd)
|
||||
{
|
||||
long pos = matchIndex + 7;
|
||||
FString type = NextGlslToken(chars, len, pos);
|
||||
FString identifier = NextGlslToken(chars, len, pos);
|
||||
|
||||
isLegacyUniformName = type.Compare("float") == 0 && identifier.Compare("timer") == 0;
|
||||
}
|
||||
|
||||
if (isLegacyUniformName)
|
||||
{
|
||||
long statementEndIndex = code.IndexOf(';', matchIndex + 7);
|
||||
if (statementEndIndex == -1)
|
||||
statementEndIndex = len;
|
||||
for (long i = matchIndex; i <= statementEndIndex; i++)
|
||||
{
|
||||
if (!IsGlslWhitespace(chars[i]))
|
||||
chars[i] = ' ';
|
||||
}
|
||||
startIndex = statementEndIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = matchIndex + 7;
|
||||
}
|
||||
}
|
||||
|
||||
// Also remove all occurences of the token 'texture2d'. Some shaders may still use this deprecated function to access a sampler.
|
||||
// Modern GLSL only allows use of 'texture'.
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("texture2d", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
// Check if this is a real token.
|
||||
bool isKeywordStart = matchIndex == 0 || !isalnum(chars[matchIndex - 1] & 255);
|
||||
bool isKeywordEnd = matchIndex + 9 == len || !isalnum(chars[matchIndex + 9] & 255);
|
||||
if (isKeywordStart && isKeywordEnd)
|
||||
{
|
||||
chars[matchIndex + 7] = chars[matchIndex + 8] = ' ';
|
||||
}
|
||||
startIndex = matchIndex + 9;
|
||||
}
|
||||
|
||||
code.UnlockBuffer();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &samplerstobind)
|
||||
{
|
||||
long len = (long)code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
long startpos, endpos;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("layout(binding", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
bool isSamplerUniformName = false;
|
||||
|
||||
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
|
||||
bool isKeywordEnd = matchIndex + 14 == len || IsGlslWhitespace(chars[matchIndex + 14]) || chars[matchIndex + 14] == '=';
|
||||
if (isKeywordStart && isKeywordEnd)
|
||||
{
|
||||
long pos = matchIndex + 14;
|
||||
startpos = matchIndex;
|
||||
while (IsGlslWhitespace(chars[pos])) pos++;
|
||||
if (chars[pos] == '=')
|
||||
{
|
||||
char *p;
|
||||
pos++;
|
||||
auto val = strtol(&chars[pos], &p, 0);
|
||||
if (p != &chars[pos])
|
||||
{
|
||||
pos = long(p - chars);
|
||||
while (IsGlslWhitespace(chars[pos])) pos++;
|
||||
if (chars[pos] == ')')
|
||||
{
|
||||
endpos = ++pos;
|
||||
FString uniform = NextGlslToken(chars, len, pos);
|
||||
FString type = NextGlslToken(chars, len, pos);
|
||||
FString identifier = NextGlslToken(chars, len, pos);
|
||||
|
||||
isSamplerUniformName = uniform.Compare("uniform") == 0 && isShaderType(type);
|
||||
if (isSamplerUniformName)
|
||||
{
|
||||
samplerstobind.Push(std::make_pair(identifier, val));
|
||||
for (auto pos = startpos; pos < endpos; pos++)
|
||||
{
|
||||
if (!IsGlslWhitespace(chars[pos]))
|
||||
chars[pos] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isSamplerUniformName)
|
||||
{
|
||||
startIndex = endpos;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = matchIndex + 7;
|
||||
}
|
||||
}
|
||||
|
||||
code.UnlockBuffer();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword)
|
||||
{
|
||||
long len = (long)code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("layout(location", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
long endIndex = matchIndex;
|
||||
|
||||
// Find end of layout declaration
|
||||
while (chars[endIndex] != ')' && chars[endIndex] != 0)
|
||||
endIndex++;
|
||||
|
||||
if (chars[endIndex] == ')')
|
||||
endIndex++;
|
||||
else if (chars[endIndex] == 0)
|
||||
break;
|
||||
|
||||
// Skip whitespace
|
||||
while (IsGlslWhitespace(chars[endIndex]))
|
||||
endIndex++;
|
||||
|
||||
// keyword following the declaration?
|
||||
bool keywordFound = true;
|
||||
long i;
|
||||
for (i = 0; inoutkeyword[i] != 0; i++)
|
||||
{
|
||||
if (chars[endIndex + i] != inoutkeyword[i])
|
||||
{
|
||||
keywordFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keywordFound && IsGlslWhitespace(chars[endIndex + i]))
|
||||
{
|
||||
// yes - replace declaration with spaces
|
||||
for (long i = matchIndex; i < endIndex; i++)
|
||||
chars[i] = ' ';
|
||||
}
|
||||
|
||||
startIndex = endIndex;
|
||||
}
|
||||
|
||||
code.UnlockBuffer();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Note: the MaterialShaderIndex enum in gl_shader.h needs to be updated whenever this array is modified.
|
||||
const FDefaultShader defaultshaders[] =
|
||||
{
|
||||
{"Default", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Warp 1", "shaders/glsl/func_warp1.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Warp 2", "shaders/glsl/func_warp2.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Specular", "shaders/glsl/func_spec.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"},
|
||||
{"PBR","shaders/glsl/func_pbr.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"},
|
||||
{"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""},
|
||||
{"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", "#define NO_LAYERS\n"},
|
||||
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Noise Fuzz", "shaders/glsl/fuzz_noise.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{"Software Fuzz", "shaders/glsl/fuzz_software.fp", "shaders/glsl/material_normal.fp", ""},
|
||||
{nullptr,nullptr,nullptr,nullptr}
|
||||
};
|
||||
|
||||
const FEffectShader effectshaders[] =
|
||||
{
|
||||
{ "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", nullptr, nullptr, "#define NO_ALPHATEST\n" },
|
||||
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
|
||||
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "tarray.h"
|
||||
#include "zstring.h"
|
||||
#include "utility"
|
||||
|
||||
FString RemoveLegacyUserUniforms(FString code);
|
||||
FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &samplerstobind); // For GL 3.3 compatibility which cannot declare sampler bindings in the sampler source.
|
||||
FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword);
|
||||
|
||||
struct FDefaultShader
|
||||
{
|
||||
const char * ShaderName;
|
||||
const char * gettexelfunc;
|
||||
const char * lightfunc;
|
||||
const char * Defines;
|
||||
};
|
||||
|
||||
struct FEffectShader
|
||||
{
|
||||
const char *ShaderName;
|
||||
const char *vp;
|
||||
const char *fp1;
|
||||
const char *fp2;
|
||||
const char *fp3;
|
||||
const char *defines;
|
||||
};
|
||||
|
||||
extern const FDefaultShader defaultshaders[];
|
||||
extern const FEffectShader effectshaders[];
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "vk_shader.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
#include "hwrenderer/utility/hw_shaderpatcher.h"
|
||||
#include "hw_shaderpatcher.h"
|
||||
#include "filesystem.h"
|
||||
#include "engineerrors.h"
|
||||
#include <ShaderLang.h>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue