add 'do-trace-shaders' setting and fix shaders recompiling
This commit is contained in:
parent
5e3373313b
commit
a621b179d3
@ -71,8 +71,8 @@ static auto process_program(const ResPaths& paths, const std::string& filename)
|
|||||||
|
|
||||||
auto& preprocessor = *Shader::preprocessor;
|
auto& preprocessor = *Shader::preprocessor;
|
||||||
|
|
||||||
auto vertex = preprocessor.process(vertexFile, vertexSource);
|
auto vertex = preprocessor.process(vertexFile, vertexSource, false, {});
|
||||||
auto fragment = preprocessor.process(fragmentFile, fragmentSource);
|
auto fragment = preprocessor.process(fragmentFile, fragmentSource, false, {});
|
||||||
return std::make_pair(vertex, fragment);
|
return std::make_pair(vertex, fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ assetload::postfunc assetload::posteffect(
|
|||||||
|
|
||||||
auto& preprocessor = *Shader::preprocessor;
|
auto& preprocessor = *Shader::preprocessor;
|
||||||
preprocessor.addHeader(
|
preprocessor.addHeader(
|
||||||
"__effect__", preprocessor.process(effectFile, effectSource, true)
|
"__effect__", preprocessor.process(effectFile, effectSource, true, {})
|
||||||
);
|
);
|
||||||
|
|
||||||
auto [vertex, fragment] = process_program(paths, SHADERS_FOLDER + "/effect");
|
auto [vertex, fragment] = process_program(paths, SHADERS_FOLDER + "/effect");
|
||||||
|
|||||||
@ -22,6 +22,10 @@ void GLSLExtension::setPaths(const ResPaths* paths) {
|
|||||||
this->paths = paths;
|
this->paths = paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::setTraceOutput(bool enabled) {
|
||||||
|
this->traceOutput = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void GLSLExtension::loadHeader(const std::string& name) {
|
void GLSLExtension::loadHeader(const std::string& name) {
|
||||||
if (paths == nullptr) {
|
if (paths == nullptr) {
|
||||||
return;
|
return;
|
||||||
@ -29,7 +33,7 @@ void GLSLExtension::loadHeader(const std::string& name) {
|
|||||||
io::path file = paths->find("shaders/lib/" + name + ".glsl");
|
io::path file = paths->find("shaders/lib/" + name + ".glsl");
|
||||||
std::string source = io::read_string(file);
|
std::string source = io::read_string(file);
|
||||||
addHeader(name, {});
|
addHeader(name, {});
|
||||||
addHeader(name, process(file, source, true));
|
addHeader(name, process(file, source, true, {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSLExtension::addHeader(const std::string& name, ProcessingResult header) {
|
void GLSLExtension::addHeader(const std::string& name, ProcessingResult header) {
|
||||||
@ -123,13 +127,22 @@ static Value default_value_for(Type type) {
|
|||||||
|
|
||||||
class GLSLParser : public BasicParser<char> {
|
class GLSLParser : public BasicParser<char> {
|
||||||
public:
|
public:
|
||||||
GLSLParser(GLSLExtension& glsl, std::string_view file, std::string_view source, bool header)
|
GLSLParser(
|
||||||
|
GLSLExtension& glsl,
|
||||||
|
std::string_view file,
|
||||||
|
std::string_view source,
|
||||||
|
bool header,
|
||||||
|
const std::vector<std::string>& defines
|
||||||
|
)
|
||||||
: BasicParser(file, source), glsl(glsl) {
|
: BasicParser(file, source), glsl(glsl) {
|
||||||
if (!header) {
|
if (!header) {
|
||||||
ss << "#version " << GLSLExtension::VERSION << '\n';
|
ss << "#version " << GLSLExtension::VERSION << '\n';
|
||||||
}
|
for (auto& entry : defines) {
|
||||||
for (auto& entry : glsl.getDefines()) {
|
ss << "#define " << entry << '\n';
|
||||||
ss << "#define " << entry.first << " " << entry.second << '\n';
|
}
|
||||||
|
for (auto& entry : defines) {
|
||||||
|
ss << "#define " << entry << '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uint linenum = 1;
|
uint linenum = 1;
|
||||||
source_line(ss, linenum);
|
source_line(ss, linenum);
|
||||||
@ -289,10 +302,34 @@ private:
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void trace_output(
|
||||||
|
const io::path& file,
|
||||||
|
const std::string& source,
|
||||||
|
const GLSLExtension::ProcessingResult& result
|
||||||
|
) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "export:trace/" << file.name();
|
||||||
|
io::path outfile = ss.str();
|
||||||
|
try {
|
||||||
|
io::create_directories(outfile.parent());
|
||||||
|
io::write_string(outfile, result.code);
|
||||||
|
} catch (const std::runtime_error& err) {
|
||||||
|
logger.error() << "error on saving GLSLExtension::preprocess output ("
|
||||||
|
<< outfile.string() << "): " << err.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GLSLExtension::ProcessingResult GLSLExtension::process(
|
GLSLExtension::ProcessingResult GLSLExtension::process(
|
||||||
const io::path& file, const std::string& source, bool header
|
const io::path& file,
|
||||||
|
const std::string& source,
|
||||||
|
bool header,
|
||||||
|
const std::vector<std::string>& defines
|
||||||
) {
|
) {
|
||||||
std::string filename = file.string();
|
std::string filename = file.string();
|
||||||
GLSLParser parser(*this, filename, source, header);
|
GLSLParser parser(*this, filename, source, header, defines);
|
||||||
return parser.process();
|
auto result = parser.process();
|
||||||
|
if (traceOutput) {
|
||||||
|
trace_output(file, source, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "io/io.hpp"
|
#include "io/io.hpp"
|
||||||
|
#include "data/setting.hpp"
|
||||||
#include "graphics/core/PostEffect.hpp"
|
#include "graphics/core/PostEffect.hpp"
|
||||||
|
|
||||||
class ResPaths;
|
class ResPaths;
|
||||||
@ -19,6 +20,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void setPaths(const ResPaths* paths);
|
void setPaths(const ResPaths* paths);
|
||||||
|
void setTraceOutput(bool enabled);
|
||||||
|
|
||||||
void define(const std::string& name, std::string value);
|
void define(const std::string& name, std::string value);
|
||||||
void undefine(const std::string& name);
|
void undefine(const std::string& name);
|
||||||
@ -37,7 +39,8 @@ public:
|
|||||||
ProcessingResult process(
|
ProcessingResult process(
|
||||||
const io::path& file,
|
const io::path& file,
|
||||||
const std::string& source,
|
const std::string& source,
|
||||||
bool header = false
|
bool header,
|
||||||
|
const std::vector<std::string>& defines
|
||||||
);
|
);
|
||||||
|
|
||||||
static inline std::string VERSION = "330 core";
|
static inline std::string VERSION = "330 core";
|
||||||
@ -46,4 +49,5 @@ private:
|
|||||||
std::unordered_map<std::string, std::string> defines;
|
std::unordered_map<std::string, std::string> defines;
|
||||||
|
|
||||||
const ResPaths* paths = nullptr;
|
const ResPaths* paths = nullptr;
|
||||||
|
bool traceOutput = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -143,6 +143,12 @@ void Engine::initializeClient() {
|
|||||||
},
|
},
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
|
keepAlive(settings.debug.doTraceShaders.observe(
|
||||||
|
[](bool value) {
|
||||||
|
Shader::preprocessor->setTraceOutput(value);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initialize(CoreParameters coreParameters) {
|
void Engine::initialize(CoreParameters coreParameters) {
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
@ -138,15 +137,21 @@ glshader compile_shader(GLenum type, const GLchar* source, const std::string& fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GLuint compile_program(
|
static GLuint compile_program(
|
||||||
const Shader::Source& vertexSource, const Shader::Source& fragmentSource
|
const Shader::Source& vertexSource,
|
||||||
|
const Shader::Source& fragmentSource,
|
||||||
|
const std::vector<std::string>& defines
|
||||||
) {
|
) {
|
||||||
auto& preprocessor = *Shader::preprocessor;
|
auto& preprocessor = *Shader::preprocessor;
|
||||||
|
|
||||||
auto vertexCode = std::move(
|
auto vertexCode = std::move(
|
||||||
preprocessor.process(vertexSource.file, vertexSource.code).code
|
preprocessor
|
||||||
|
.process(vertexSource.file, vertexSource.code, false, defines)
|
||||||
|
.code
|
||||||
);
|
);
|
||||||
auto fragmentCode = std::move(
|
auto fragmentCode = std::move(
|
||||||
preprocessor.process(fragmentSource.file, fragmentSource.code).code
|
preprocessor
|
||||||
|
.process(fragmentSource.file, fragmentSource.code, false, defines)
|
||||||
|
.code
|
||||||
);
|
);
|
||||||
|
|
||||||
const GLchar* vCode = vertexCode.c_str();
|
const GLchar* vCode = vertexCode.c_str();
|
||||||
@ -176,8 +181,8 @@ static GLuint compile_program(
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::recompile() {
|
void Shader::recompile(const std::vector<std::string>& defines) {
|
||||||
GLuint newProgram = compile_program(vertexSource, fragmentSource);
|
GLuint newProgram = compile_program(vertexSource, fragmentSource, defines);
|
||||||
glDeleteProgram(id);
|
glDeleteProgram(id);
|
||||||
id = newProgram;
|
id = newProgram;
|
||||||
uniformLocations.clear();
|
uniformLocations.clear();
|
||||||
@ -188,7 +193,7 @@ std::unique_ptr<Shader> Shader::create(
|
|||||||
Source&& vertexSource, Source&& fragmentSource
|
Source&& vertexSource, Source&& fragmentSource
|
||||||
) {
|
) {
|
||||||
return std::make_unique<Shader>(
|
return std::make_unique<Shader>(
|
||||||
compile_program(vertexSource, fragmentSource),
|
compile_program(vertexSource, fragmentSource, {}),
|
||||||
std::move(vertexSource),
|
std::move(vertexSource),
|
||||||
std::move(fragmentSource)
|
std::move(fragmentSource)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ public:
|
|||||||
void uniform4v(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
|
/// @brief Re-preprocess source code and re-compile shader program
|
||||||
void recompile();
|
void recompile(const std::vector<std::string>& defines);
|
||||||
|
|
||||||
/// @brief Create shader program using vertex and fragment shaders source.
|
/// @brief Create shader program using vertex and fragment shaders source.
|
||||||
/// @return linked shader program containing vertex and fragment shaders
|
/// @return linked shader program containing vertex and fragment shaders
|
||||||
|
|||||||
@ -321,11 +321,13 @@ void WorldRenderer::renderFrame(
|
|||||||
prevCTShaderSettings.shadows != currentSettings.shadows ||
|
prevCTShaderSettings.shadows != currentSettings.shadows ||
|
||||||
prevCTShaderSettings.ssao != currentSettings.ssao
|
prevCTShaderSettings.ssao != currentSettings.ssao
|
||||||
) {
|
) {
|
||||||
Shader::preprocessor->setDefined("ENABLE_SHADOWS", currentSettings.shadows);
|
std::vector<std::string> defines;
|
||||||
Shader::preprocessor->setDefined("ENABLE_SSAO", currentSettings.ssao);
|
if (currentSettings.shadows) defines.emplace_back("ENABLE_SHADOWS");
|
||||||
Shader::preprocessor->setDefined("ADVANCED_RENDER", currentSettings.advancedRender);
|
if (currentSettings.ssao) defines.emplace_back("ENABLE_SSAO");
|
||||||
|
if (currentSettings.advancedRender) defines.emplace_back("ADVANCED_RENDER");
|
||||||
|
|
||||||
for (auto shader : affectedShaders) {
|
for (auto shader : affectedShaders) {
|
||||||
shader->recompile();
|
shader->recompile(defines);
|
||||||
}
|
}
|
||||||
prevCTShaderSettings = currentSettings;
|
prevCTShaderSettings = currentSettings;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,6 +89,7 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) {
|
|||||||
builder.section("debug");
|
builder.section("debug");
|
||||||
builder.add("generator-test-mode", &settings.debug.generatorTestMode);
|
builder.add("generator-test-mode", &settings.debug.generatorTestMode);
|
||||||
builder.add("do-write-lights", &settings.debug.doWriteLights);
|
builder.add("do-write-lights", &settings.debug.doWriteLights);
|
||||||
|
builder.add("do-trace-shaders", &settings.debug.doTraceShaders);
|
||||||
builder.add("enable-experimental", &settings.debug.enableExperimental);
|
builder.add("enable-experimental", &settings.debug.enableExperimental);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,8 @@ struct DebugSettings {
|
|||||||
FlagSetting generatorTestMode {false};
|
FlagSetting generatorTestMode {false};
|
||||||
/// @brief Write lights cache
|
/// @brief Write lights cache
|
||||||
FlagSetting doWriteLights {true};
|
FlagSetting doWriteLights {true};
|
||||||
|
/// @brief Write preprocessed shaders code to user:export
|
||||||
|
FlagSetting doTraceShaders {false};
|
||||||
/// @brief Enable experimental optimizations and features
|
/// @brief Enable experimental optimizations and features
|
||||||
FlagSetting enableExperimental {false};
|
FlagSetting enableExperimental {false};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,7 +11,7 @@ TEST(GLSLExtension, processing) {
|
|||||||
"float sum(float a, float b) {\n"
|
"float sum(float a, float b) {\n"
|
||||||
" return a + b;\n"
|
" return a + b;\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
true
|
true, {}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
@ -27,7 +27,7 @@ TEST(GLSLExtension, processing) {
|
|||||||
" vec4 color = texture(u_screen, v_uv);\n"
|
" vec4 color = texture(u_screen, v_uv);\n"
|
||||||
" return mix(color, 1.0 - color, p_intensity);\n"
|
" return mix(color, 1.0 - color, p_intensity);\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
false);
|
false, {});
|
||||||
std::cout << processed.code << std::endl;
|
std::cout << processed.code << std::endl;
|
||||||
} catch (const parsing_error& err) {
|
} catch (const parsing_error& err) {
|
||||||
std::cerr << err.errorLog() << std::endl;
|
std::cerr << err.errorLog() << std::endl;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user