From 010b41d3526c33ebc7866ee84d9bcc3470c96b74 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Wed, 1 Jan 2025 20:50:30 +1300 Subject: [PATCH] Embed shaders directly into executable --- CMakeLists.txt | 11 +++++++ README.md | 7 ---- src/{point_light.h => point_light.in.h} | 2 +- src/renderer.h | 2 +- src/{renderer.cpp => renderer.in.cpp} | 7 +++- src/shader.cpp | 43 +++++++------------------ src/shader.h | 1 - 7 files changed, 31 insertions(+), 42 deletions(-) rename src/{point_light.h => point_light.in.h} (91%) rename src/{renderer.cpp => renderer.in.cpp} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87ce308..ff2abe3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,3 +26,14 @@ add_executable(perlin-shadows src/renderable.cpp src/renderable.h ) + +file(READ src/phong.vert PHONG_VERT) +file(READ src/phong.frag PHONG_FRAG) +configure_file(src/renderer.in.cpp src/renderer.cpp @ONLY) + +file(READ src/shadow.vert SHADOW_VERT) +file(READ src/shadow.frag SHADOW_FRAG) +file(READ src/shadow.geom SHADOW_GEOM) +configure_file(src/point_light.in.h src/point_light.h @ONLY) + +target_include_directories(perlin-shadows PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/src") \ No newline at end of file diff --git a/README.md b/README.md index 5567e91..24bd256 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,6 @@ Generates several tiles of grids containing Perlin noise, and then renders them with shadows. -## Running - -The shader files (`src/*.{frag,vert,geom}`) are referenced within the code by assuming they are located in the current -working directory. -It is therefore necessary to set the CWD when running the program to the `src/` directory, or copy/symlink the files to -whatever your actual CWD is. - ## Control Sample from console output: diff --git a/src/point_light.h b/src/point_light.in.h similarity index 91% rename from src/point_light.h rename to src/point_light.in.h index 18c3c00..d04de69 100644 --- a/src/point_light.h +++ b/src/point_light.in.h @@ -37,7 +37,7 @@ class PointLight final : public Renderable { float specularPower_{20}; glm::vec3 pos_; - Shader shadow_{"shadow.vert", "shadow.frag", "shadow.geom"}; + Shader shadow_{R"(@SHADOW_VERT@)", R"(@SHADOW_FRAG@)", R"(@SHADOW_GEOM@)"}; GLuint fbo_{0}; GLuint depth_{0}; }; diff --git a/src/renderer.h b/src/renderer.h index 43f38ce..b68420f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -3,7 +3,7 @@ #include #include "camera.h" -#include "point_light.h" +#include "point_light.in.h" #include "shader.h" constexpr auto kInitialWidth = 1280; diff --git a/src/renderer.cpp b/src/renderer.in.cpp similarity index 99% rename from src/renderer.cpp rename to src/renderer.in.cpp index d610395..92b35c7 100644 --- a/src/renderer.cpp +++ b/src/renderer.in.cpp @@ -51,7 +51,12 @@ Renderer::Renderer(int argc, char *argv[]) { } CheckGLError(); - shader_ = new Shader("phong.vert", "phong.frag"); + shader_ = new Shader(R"( +@PHONG_VERT@ +)", + R"( +@PHONG_FRAG@ +)"); light_ = new PointLight({kGeographyShort * kGeographyCountShort / 2, kGeographyLong * kGeographyCountLong / 2, kHeightMultiplier * kGeographyCountShort / 2}); diff --git a/src/shader.cpp b/src/shader.cpp index 387e552..1a3d507 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -8,11 +8,11 @@ using namespace std; -Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, - const string &geometryShaderFile) { - const auto vertexShaderId = CompileShader(vertexShaderFile, GL_VERTEX_SHADER); +Shader::Shader(const string &vertexShader, const string &fragmentShader, + const string &geometryShader) { + const auto vertexShaderId = CompileShader(vertexShader, GL_VERTEX_SHADER); const auto fragmentShaderId = - CompileShader(fragmentShaderFile, GL_FRAGMENT_SHADER); + CompileShader(fragmentShader, GL_FRAGMENT_SHADER); GLuint geometryShaderId{0}; id_ = glCreateProgram(); @@ -22,8 +22,8 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, glAttachShader(id_, fragmentShaderId); CheckGLError("Error in attaching the fragment shader"); - if (!geometryShaderFile.empty()) { - geometryShaderId = CompileShader(geometryShaderFile, GL_GEOMETRY_SHADER); + if (!geometryShader.empty()) { + geometryShaderId = CompileShader(geometryShader, GL_GEOMETRY_SHADER); glAttachShader(id_, geometryShaderId); CheckGLError("Error in attaching the geometry shader"); } @@ -34,7 +34,7 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); - if (!geometryShaderFile.empty()) { + if (geometryShaderId != 0) { glDeleteShader(geometryShaderId); } @@ -114,33 +114,14 @@ bool Shader::CopyDataToUniform(const bool data, const string &name) const { return true; } -string Shader::ReadFile(const string &filename) { - string data; - ifstream file; - file.open(filename, std::ios::binary); - if (file.is_open()) { - string line; - while (getline(file, line)) { - data += line + '\n'; - } - if (data.empty()) { - data.pop_back(); - } - } else { - throw runtime_error("Could not open " + filename); - } - return data; -} - -GLuint Shader::CompileShader(const std::string &filename, - const GLenum shader_type) { - const GLuint id = glCreateShader(shader_type); - const auto shaderString = ReadFile(filename); - const auto shaderC_str = shaderString.c_str(); +GLuint Shader::CompileShader(const std::string &shaderSource, + const GLenum shaderType) { + const GLuint id = glCreateShader(shaderType); + const auto shaderC_str = shaderSource.c_str(); glShaderSource(id, 1, &shaderC_str, nullptr); glCompileShader(id); CheckShaderivError(id, GL_COMPILE_STATUS, - "Error when creating shader file " + filename); + "Error when compiling shader file:\n" + shaderSource); return id; } diff --git a/src/shader.h b/src/shader.h index 42ad1e5..49554c0 100644 --- a/src/shader.h +++ b/src/shader.h @@ -30,7 +30,6 @@ class Shader { private: GLuint id_; - static std::string ReadFile(const std::string &); static GLuint CompileShader(const std::string &, GLenum); static void CheckGLError(const std::string &);