feat: recompiling shaders
This commit is contained in:
parent
5751802da2
commit
96a94aa33c
@ -11,10 +11,7 @@ uniform float u_shadowsOpacity;
|
||||
uniform float u_shadowsSoftness;
|
||||
|
||||
float calc_shadow() {
|
||||
if (!u_enableShadows) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SHADOWS
|
||||
float step = 1.0 / float(u_shadowsRes);
|
||||
float s = pow(abs(cos(u_dayTime * PI2)), 0.25) * u_shadowsOpacity;
|
||||
vec3 normalOffset = a_realnormal * (a_distance > 64.0 ? 0.2 : 0.04);
|
||||
@ -39,6 +36,9 @@ float calc_shadow() {
|
||||
shadow = 0.5;
|
||||
}
|
||||
return 0.5 * (1.0 + s * shadow);
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // SHADOWS_GLSL_
|
||||
|
||||
@ -76,6 +76,14 @@ static auto process_program(const ResPaths& paths, const std::string& filename)
|
||||
return std::make_pair(vertex, fragment);
|
||||
}
|
||||
|
||||
static auto read_program(const ResPaths& paths, const std::string& filename) {
|
||||
io::path vertexFile = paths.find(filename + ".glslv");
|
||||
io::path fragmentFile = paths.find(filename + ".glslf");
|
||||
return std::make_pair(
|
||||
io::read_string(vertexFile), io::read_string(fragmentFile)
|
||||
);
|
||||
}
|
||||
|
||||
assetload::postfunc assetload::shader(
|
||||
AssetsLoader*,
|
||||
const ResPaths& paths,
|
||||
@ -83,21 +91,18 @@ assetload::postfunc assetload::shader(
|
||||
const std::string& name,
|
||||
const std::shared_ptr<AssetCfg>&
|
||||
) {
|
||||
auto [vertex, fragment] = process_program(paths, filename);
|
||||
auto result = read_program(paths, filename);
|
||||
auto vertex = result.first;
|
||||
auto fragment = result.second;
|
||||
|
||||
io::path vertexFile = paths.find(filename + ".glslv");
|
||||
io::path fragmentFile = paths.find(filename + ".glslf");
|
||||
|
||||
std::string vertexSource = std::move(vertex.code);
|
||||
std::string fragmentSource = std::move(fragment.code);
|
||||
|
||||
return [=](auto assets) {
|
||||
assets->store(
|
||||
Shader::create(
|
||||
vertexFile.string(),
|
||||
fragmentFile.string(),
|
||||
vertexSource,
|
||||
fragmentSource
|
||||
{vertexFile.string(), vertex},
|
||||
{fragmentFile.string(), fragment}
|
||||
),
|
||||
name
|
||||
);
|
||||
@ -127,10 +132,8 @@ assetload::postfunc assetload::posteffect(
|
||||
|
||||
return [=](auto assets) {
|
||||
auto program = Shader::create(
|
||||
effectFile.string(),
|
||||
effectFile.string(),
|
||||
vertexSource,
|
||||
fragmentSource
|
||||
{effectFile.string(), vertexSource},
|
||||
{effectFile.string(), fragmentSource}
|
||||
);
|
||||
bool advanced = false;
|
||||
if (settings) {
|
||||
|
||||
@ -12,20 +12,25 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "coders/GLSLExtension.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
static debug::Logger logger("gl-shader");
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
GLSLExtension* Shader::preprocessor = new GLSLExtension();
|
||||
Shader* Shader::used = nullptr;
|
||||
|
||||
Shader::Shader(uint id) : id(id){
|
||||
}
|
||||
Shader::Shader(uint id, Source&& vertexSource, Source&& fragmentSource)
|
||||
: id(id),
|
||||
vertexSource(std::move(vertexSource)),
|
||||
fragmentSource(std::move(fragmentSource)) {}
|
||||
|
||||
Shader::~Shader(){
|
||||
Shader::~Shader() {
|
||||
glDeleteProgram(id);
|
||||
}
|
||||
|
||||
void Shader::use(){
|
||||
void Shader::use() {
|
||||
used = this;
|
||||
glUseProgram(id);
|
||||
}
|
||||
@ -40,8 +45,10 @@ uint Shader::getUniformLocation(const std::string& name) {
|
||||
return found->second;
|
||||
}
|
||||
|
||||
void Shader::uniformMatrix(const std::string& name, const glm::mat4& matrix){
|
||||
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix));
|
||||
void Shader::uniformMatrix(const std::string& name, const glm::mat4& matrix) {
|
||||
glUniformMatrix4fv(
|
||||
getUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix)
|
||||
);
|
||||
}
|
||||
|
||||
void Shader::uniform1i(const std::string& name, int x){
|
||||
@ -96,7 +103,7 @@ void Shader::uniform4v(const std::string& name, int length, const float* v) {
|
||||
glUniform4fv(getUniformLocation(name), length, v);
|
||||
}
|
||||
|
||||
inline auto shader_deleter = [](GLuint* shader) {
|
||||
static inline auto shader_deleter = [](GLuint* shader) {
|
||||
glDeleteShader(*shader);
|
||||
delete shader;
|
||||
};
|
||||
@ -112,45 +119,73 @@ glshader compile_shader(GLenum type, const GLchar* source, const std::string& fi
|
||||
glShaderSource(shader, 1, &source, nullptr);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success){
|
||||
if (!success) {
|
||||
GLchar infoLog[GL_LOG_LEN];
|
||||
glGetShaderInfoLog(shader, GL_LOG_LEN, nullptr, infoLog);
|
||||
glDeleteShader(shader);
|
||||
throw std::runtime_error(
|
||||
"vertex shader compilation failed ("+file+"):\n"+std::string(infoLog)
|
||||
"vertex shader compilation failed (" + file + "):\n" +
|
||||
std::string(infoLog)
|
||||
);
|
||||
}
|
||||
}
|
||||
return glshader(new GLuint(shader), shader_deleter); //-V508
|
||||
}
|
||||
|
||||
std::unique_ptr<Shader> Shader::create(
|
||||
const std::string& vertexFile,
|
||||
const std::string& fragmentFile,
|
||||
const std::string& vertexCode,
|
||||
const std::string& fragmentCode
|
||||
static GLuint compile_program(
|
||||
const Shader::Source& vertexSource, const Shader::Source& fragmentSource
|
||||
) {
|
||||
auto& preprocessor = *Shader::preprocessor;
|
||||
|
||||
auto vertexCode = std::move(
|
||||
preprocessor.process(vertexSource.file, vertexSource.code).code
|
||||
);
|
||||
auto fragmentCode = std::move(
|
||||
preprocessor.process(fragmentSource.file, fragmentSource.code).code
|
||||
);
|
||||
|
||||
const GLchar* vCode = vertexCode.c_str();
|
||||
const GLchar* fCode = fragmentCode.c_str();
|
||||
|
||||
glshader vertex = compile_shader(GL_VERTEX_SHADER, vCode, vertexFile);
|
||||
glshader fragment = compile_shader(GL_FRAGMENT_SHADER, fCode, fragmentFile);
|
||||
glshader vertex =
|
||||
compile_shader(GL_VERTEX_SHADER, vCode, vertexSource.file);
|
||||
glshader fragment =
|
||||
compile_shader(GL_FRAGMENT_SHADER, fCode, fragmentSource.file);
|
||||
|
||||
// Shader Program
|
||||
GLint success;
|
||||
GLuint id = glCreateProgram();
|
||||
glAttachShader(id, *vertex);
|
||||
glAttachShader(id, *fragment);
|
||||
glLinkProgram(id);
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, *vertex);
|
||||
glAttachShader(program, *fragment);
|
||||
glLinkProgram(program);
|
||||
|
||||
glGetProgramiv(id, GL_LINK_STATUS, &success);
|
||||
if (!success){
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||
|
||||
if (!success) {
|
||||
GLchar infoLog[GL_LOG_LEN];
|
||||
glGetProgramInfoLog(id, GL_LOG_LEN, nullptr, infoLog);
|
||||
glGetProgramInfoLog(program, GL_LOG_LEN, nullptr, infoLog);
|
||||
throw std::runtime_error(
|
||||
"shader program linking failed:\n"+std::string(infoLog)
|
||||
"shader program linking failed:\n" + std::string(infoLog)
|
||||
);
|
||||
}
|
||||
return std::make_unique<Shader>(id);
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader::recompile() {
|
||||
GLuint newProgram = compile_program(vertexSource, fragmentSource);
|
||||
glDeleteProgram(id);
|
||||
id = newProgram;
|
||||
uniformLocations.clear();
|
||||
logger.info() << "shader " << id << " has been recompiled";
|
||||
}
|
||||
|
||||
std::unique_ptr<Shader> Shader::create(
|
||||
Source&& vertexSource, Source&& fragmentSource
|
||||
) {
|
||||
return std::make_unique<Shader>(
|
||||
compile_program(vertexSource, fragmentSource),
|
||||
std::move(vertexSource),
|
||||
std::move(fragmentSource)
|
||||
);
|
||||
}
|
||||
|
||||
Shader& Shader::getUsed() {
|
||||
|
||||
@ -10,15 +10,25 @@
|
||||
class GLSLExtension;
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
struct Source {
|
||||
std::string file;
|
||||
std::string code;
|
||||
};
|
||||
private:
|
||||
static Shader* used;
|
||||
uint id;
|
||||
std::unordered_map<std::string, uint> uniformLocations;
|
||||
|
||||
// source code used for re-compiling shaders after updating defines
|
||||
Source vertexSource;
|
||||
Source fragmentSource;
|
||||
|
||||
uint getUniformLocation(const std::string& name);
|
||||
public:
|
||||
static GLSLExtension* preprocessor;
|
||||
|
||||
Shader(uint id);
|
||||
Shader(uint id, Source&& vertexSource, Source&& fragmentSource);
|
||||
~Shader();
|
||||
|
||||
void use();
|
||||
@ -38,17 +48,13 @@ public:
|
||||
void uniform3v(const std::string& name, int length, const float* v);
|
||||
void uniform4v(const std::string& name, int length, const float* v);
|
||||
|
||||
/// @brief Re-preprocess source code and re-compile shader program
|
||||
void recompile();
|
||||
|
||||
/// @brief Create shader program using vertex and fragment shaders source.
|
||||
/// @param vertexFile vertex shader file name
|
||||
/// @param fragmentFile fragment shader file name
|
||||
/// @param vertexSource vertex shader source code
|
||||
/// @param fragmentSource fragment shader source code
|
||||
/// @return linked shader program containing vertex and fragment shaders
|
||||
static std::unique_ptr<Shader> create(
|
||||
const std::string& vertexFile,
|
||||
const std::string& fragmentFile,
|
||||
const std::string& vertexSource,
|
||||
const std::string& fragmentSource
|
||||
Source&& vertexSource, Source&& fragmentSource
|
||||
);
|
||||
|
||||
static Shader& getUsed();
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "assets/assets_util.hpp"
|
||||
#include "content/Content.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "coders/GLSLExtension.hpp"
|
||||
#include "frontend/LevelFrontend.hpp"
|
||||
#include "frontend/ContentGfxCache.hpp"
|
||||
#include "items/Inventory.hpp"
|
||||
@ -434,6 +435,7 @@ void WorldRenderer::draw(
|
||||
const auto& vp = pctx.getViewport();
|
||||
camera.setAspectRatio(vp.x / static_cast<float>(vp.y));
|
||||
|
||||
auto& mainShader = assets.require<Shader>("main");
|
||||
const auto& settings = engine.getSettings();
|
||||
gbufferPipeline = settings.graphics.advancedRender.get();
|
||||
int shadowsQuality = settings.graphics.shadowsQuality.get();
|
||||
@ -442,10 +444,14 @@ void WorldRenderer::draw(
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
wideShadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
shadows = true;
|
||||
} else if (shadowsQuality == 0) {
|
||||
Shader::preprocessor->define("ENABLE_SHADOWS", "true");
|
||||
mainShader.recompile();
|
||||
} else if (shadowsQuality == 0 && shadows) {
|
||||
shadowMap.reset();
|
||||
wideShadowMap.reset();
|
||||
shadows = false;
|
||||
Shader::preprocessor->undefine("ENABLE_SHADOWS");
|
||||
mainShader.recompile();
|
||||
}
|
||||
if (shadows && shadowMap->getResolution() != resolution) {
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user