chore: changed shader compilation slightly so they're passed onto glsl just once

This commit is contained in:
Almamu 2025-04-06 20:13:45 +02:00
parent 1e0a9cca91
commit 7bff63c037
6 changed files with 66 additions and 62 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <iostream>
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
@ -17,70 +18,49 @@ class CLog {
void addError (std::ostream* stream); void addError (std::ostream* stream);
template <typename... Data> void out (Data... data) { template <typename... Data> void out (Data... data) {
// buffer the string first std::string str = this->buildBuffer (data...);
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
// then send it to all the outputs configured // then send it to all the outputs configured
for (const auto cur : this->mOutputs) for (const auto cur : this->mOutputs)
*cur << buffer.str () << std::endl; *cur << str << std::endl;
} }
template <typename... Data> void debug (Data... data) { template <typename... Data> void debug (Data... data) {
#if (!NDEBUG) && (!ERRORONLY) #if (!NDEBUG) && (!ERRORONLY)
// buffer the string first std::string str = this->buildBuffer (data...);
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
// then send it to all the outputs configured // then send it to all the outputs configured
for (const auto cur : this->mOutputs) for (const auto cur : this->mOutputs)
*cur << buffer.str () << std::endl; *cur << str << std::endl;
#endif /* DEBUG */ #endif /* DEBUG */
} }
template <typename... Data> void debugerror (Data... data) { template <typename... Data> void debugerror (Data... data) {
#if (!NDEBUG) && (ERRORONLY) #if (!NDEBUG) && (ERRORONLY)
// buffer the string first std::string str = this->buildBuffer (data...);
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
// then send it to all the outputs configured // then send it to all the outputs configured
for (const auto cur : this->mOutputs) for (const auto cur : this->mOutputs)
*cur << buffer.str () << std::endl; *cur << str << std::endl;
#endif /* DEBUG */ #endif /* DEBUG */
} }
template <typename... Data> void error (Data... data) { template <typename... Data> void error (Data... data) {
// buffer the string first std::string str = this->buildBuffer (data...);
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
// then send it to all the outputs configured // then send it to all the outputs configured
for (const auto cur : this->mErrors) for (const auto cur : this->mErrors)
*cur << buffer.str () << std::endl; *cur << str << std::endl;
} }
template <class EX, typename... Data> [[noreturn]] void exception (Data... data) { template <class EX, typename... Data> [[noreturn]] void exception (Data... data) {
// buffer the string first std::string str = this->buildBuffer (data...);
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
// then send it to all the outputs configured // then send it to all the outputs configured
for (const auto cur : this->mErrors) for (const auto cur : this->mErrors)
*cur << buffer.str () << std::endl; *cur << str << std::endl;
// now throw the exception // now throw the exception
throw EX (buffer.str ()); throw EX (str);
} }
template <typename... Data> [[noreturn]] void exception (Data... data) { template <typename... Data> [[noreturn]] void exception (Data... data) {
@ -90,6 +70,16 @@ class CLog {
static CLog& get (); static CLog& get ();
private: private:
template <typename... Data> std::string buildBuffer (Data... data) {
// buffer the string first
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
((bufferStream << std::forward<Data> (data)), ...);
return buffer.str ();
}
std::vector<std::ostream*> mOutputs; std::vector<std::ostream*> mOutputs;
std::vector<std::ostream*> mErrors; std::vector<std::ostream*> mErrors;
static std::shared_ptr<CLog> sInstance; static std::shared_ptr<CLog> sInstance;

View File

@ -282,14 +282,11 @@ Core::Objects::Images::Materials::CPass* CPass::getPass () {
return this->m_pass; return this->m_pass;
} }
GLuint CPass::compileShader (Render::Shaders::CCompiler* shader, GLuint type) { GLuint CPass::compileShader (const char* shader, GLuint type) {
// reserve shaders in OpenGL // reserve shaders in OpenGL
const GLuint shaderID = glCreateShader (type); const GLuint shaderID = glCreateShader (type);
// give shader's source code to OpenGL to be compiled glShaderSource (shaderID, 1, &shader, nullptr);
const char* sourcePointer = shader->getCompiled ().c_str ();
glShaderSource (shaderID, 1, &sourcePointer, nullptr);
glCompileShader (shaderID); glCompileShader (shaderID);
GLint result = GL_FALSE; GLint result = GL_FALSE;
@ -307,7 +304,7 @@ GLuint CPass::compileShader (Render::Shaders::CCompiler* shader, GLuint type) {
glGetShaderInfoLog (shaderID, infoLogLength, nullptr, logBuffer); glGetShaderInfoLog (shaderID, infoLogLength, nullptr, logBuffer);
// throw an exception about the issue // throw an exception about the issue
std::stringstream buffer; std::stringstream buffer;
buffer << logBuffer << std::endl << "Compiled source code:" << std::endl << shader->getCompiled (); buffer << logBuffer << std::endl << "Compiled source code:" << std::endl << shader;
// free the buffer // free the buffer
delete [] logBuffer; delete [] logBuffer;
// throw an exception // throw an exception
@ -335,19 +332,24 @@ void CPass::setupShaders () {
this->m_fragShader = new Render::Shaders::CCompiler ( this->m_fragShader = new Render::Shaders::CCompiler (
this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Pixel, this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Pixel,
this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ()); this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ());
this->m_fragShader->compile ();
this->m_vertShader = new Render::Shaders::CCompiler ( this->m_vertShader = new Render::Shaders::CCompiler (
this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Vertex, this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Vertex,
this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ()); this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ());
this->m_vertShader->compile ();
// they're re-compiled to ensure they are using the latest constants available // precompile shaders once so all the data is discovered
this->m_fragShader->compile (); this->m_fragShader->precompile ();
this->m_vertShader->compile (); this->m_vertShader->precompile ();
// precompile them again once all the data is available
this->m_fragShader->precompile ();
this->m_vertShader->precompile ();
std::string fragmentCode = this->m_fragShader->compile ();
std::string vertexCode = this->m_vertShader->compile ();
// compile the shaders // compile the shaders
const GLuint vertexShaderID = compileShader (this->m_vertShader, GL_VERTEX_SHADER); const GLuint vertexShaderID = compileShader (vertexCode.c_str (), GL_VERTEX_SHADER);
const GLuint fragmentShaderID = compileShader (this->m_fragShader, GL_FRAGMENT_SHADER); const GLuint fragmentShaderID = compileShader (fragmentCode.c_str (), GL_FRAGMENT_SHADER);
// create the final program // create the final program
this->m_programID = glCreateProgram (); this->m_programID = glCreateProgram ();
// link the shaders together // link the shaders together

View File

@ -95,7 +95,7 @@ class CPass final : public Helpers::CContextAware {
const GLuint* value; const GLuint* value;
}; };
static GLuint compileShader (Render::Shaders::CCompiler* shader, GLuint type); static GLuint compileShader (const char* shader, GLuint type);
void setupTextures (); void setupTextures ();
void setupShaders (); void setupShaders ();
void setupShaderVariables (); void setupShaderVariables ();

View File

@ -64,11 +64,7 @@ std::string CCompiler::lookupShaderFile (const std::string& filename) {
} }
} }
std::string& CCompiler::getCompiled () { void CCompiler::precompile () {
return this->m_compiledContent;
}
void CCompiler::compile () {
// reset include contents as the compilation requires this to be re-processed // reset include contents as the compilation requires this to be re-processed
this->m_includeContent = ""; this->m_includeContent = "";
std::string precompile = "#version 330\n" std::string precompile = "#version 330\n"
@ -189,6 +185,20 @@ void CCompiler::compile () {
end = start; end = start;
} }
// reset end so we start from the beginning
end = 0;
// comment out requires
while((start = precompile.find("#require", end)) != std::string::npos) {
// TODO: CHECK FOR ERRORS HERE
size_t lineEnd = precompile.find_first_of('\n', start);
sLog.out("Shader has a require block ", precompile.substr (start, lineEnd - start));
// replace the first two letters with a comment so the filelength doesn't change
precompile = precompile.replace(start, 2, "//");
// go to the end of the line
end = lineEnd;
}
// include content might have more includes, so also handle those // include content might have more includes, so also handle those
/*end = 0; /*end = 0;
@ -232,8 +242,12 @@ void CCompiler::compile () {
end = end + this->m_includeContent.length () + 1; end = end + this->m_includeContent.length () + 1;
}*/ }*/
this->m_processedContent = precompile;
}
std::string CCompiler::compile () {
// content should be ready, finally ask glslang to compile the shader // content should be ready, finally ask glslang to compile the shader
this->m_compiledContent = CGLSLContext::get().toGlsl (precompile, this->m_type); return CGLSLContext::get().toGlsl (this->m_processedContent, this->m_type);
} }
void CCompiler::parseComboConfiguration (const std::string& content, int defaultValue) { void CCompiler::parseComboConfiguration (const std::string& content, int defaultValue) {

View File

@ -40,17 +40,14 @@ class CCompiler {
std::map<std::string, bool>* foundCombos, const std::vector<std::string>& textures, std::map<std::string, bool>* foundCombos, const std::vector<std::string>& textures,
const std::map<std::string, CShaderConstant*>& constants); const std::map<std::string, CShaderConstant*>& constants);
/** /**
* Performs the actual pre-compilation/pre-processing over the shader files * Pre-processes the shader to detect variables, process includes and other small things WallpaperEngine
* This step is kinda big, replaces variables names on sVariableReplacement, * does to shaders before actually using them
* ensures #include directives are correctly handled
* and takes care of attribute comments for the wallpaper engine specifics
*/ */
void compile (); void precompile ();
/** /**
* @return The compiled shader's text (if available) * Performs the final processing of the shader doing a few last transformations through glslang
*/ */
std::string& getCompiled (); std::string compile ();
/** /**
* Searches the list of parameters available for the parameter with the given value * Searches the list of parameters available for the parameter with the given value
* *
@ -58,7 +55,6 @@ class CCompiler {
* @return The shader information * @return The shader information
*/ */
Variables::CShaderVariable* findParameter (const std::string& identifier); Variables::CShaderVariable* findParameter (const std::string& identifier);
/** /**
* @return The list of parameters available for this shader with their default values * @return The list of parameters available for this shader with their default values
*/ */
@ -108,7 +104,7 @@ class CCompiler {
/** /**
* The final, compiled content ready to be used by OpenGL * The final, compiled content ready to be used by OpenGL
*/ */
std::string m_compiledContent; std::string m_processedContent;
/** /**
* The contents of all the included files * The contents of all the included files
*/ */

View File

@ -50,6 +50,7 @@ int main (int argc, char* argv[]) {
// attach signals to gracefully stop // attach signals to gracefully stop
std::signal (SIGINT, signalhandler); std::signal (SIGINT, signalhandler);
std::signal (SIGTERM, signalhandler); std::signal (SIGTERM, signalhandler);
std::signal (SIGKILL, signalhandler);
// show the wallpaper application // show the wallpaper application
app->show (); app->show ();
@ -57,6 +58,7 @@ int main (int argc, char* argv[]) {
// remove signal handlers before destroying app // remove signal handlers before destroying app
std::signal (SIGINT, SIG_DFL); std::signal (SIGINT, SIG_DFL);
std::signal (SIGTERM, SIG_DFL); std::signal (SIGTERM, SIG_DFL);
std::signal (SIGKILL, SIG_DFL);
delete app; delete app;