Embed shaders directly into executable

This commit is contained in:
Michael Bradley 2025-01-01 20:50:30 +13:00
parent 440b666a56
commit 010b41d352
Signed by: MichaelBradley
SSH key fingerprint: SHA256:cj/YZ5VT+QOKncqSkx+ibKTIn0Obg7OIzwzl9BL8EO8
7 changed files with 31 additions and 42 deletions

View file

@ -26,3 +26,14 @@ add_executable(perlin-shadows
src/renderable.cpp src/renderable.cpp
src/renderable.h 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")

View file

@ -2,13 +2,6 @@
Generates several tiles of grids containing Perlin noise, and then renders them with shadows. 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 ## Control
Sample from console output: Sample from console output:

View file

@ -37,7 +37,7 @@ class PointLight final : public Renderable {
float specularPower_{20}; float specularPower_{20};
glm::vec3 pos_; 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 fbo_{0};
GLuint depth_{0}; GLuint depth_{0};
}; };

View file

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include "camera.h" #include "camera.h"
#include "point_light.h" #include "point_light.in.h"
#include "shader.h" #include "shader.h"
constexpr auto kInitialWidth = 1280; constexpr auto kInitialWidth = 1280;

View file

@ -51,7 +51,12 @@ Renderer::Renderer(int argc, char *argv[]) {
} }
CheckGLError(); CheckGLError();
shader_ = new Shader("phong.vert", "phong.frag"); shader_ = new Shader(R"(
@PHONG_VERT@
)",
R"(
@PHONG_FRAG@
)");
light_ = new PointLight({kGeographyShort * kGeographyCountShort / 2, light_ = new PointLight({kGeographyShort * kGeographyCountShort / 2,
kGeographyLong * kGeographyCountLong / 2, kGeographyLong * kGeographyCountLong / 2,
kHeightMultiplier * kGeographyCountShort / 2}); kHeightMultiplier * kGeographyCountShort / 2});

View file

@ -8,11 +8,11 @@
using namespace std; using namespace std;
Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, Shader::Shader(const string &vertexShader, const string &fragmentShader,
const string &geometryShaderFile) { const string &geometryShader) {
const auto vertexShaderId = CompileShader(vertexShaderFile, GL_VERTEX_SHADER); const auto vertexShaderId = CompileShader(vertexShader, GL_VERTEX_SHADER);
const auto fragmentShaderId = const auto fragmentShaderId =
CompileShader(fragmentShaderFile, GL_FRAGMENT_SHADER); CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
GLuint geometryShaderId{0}; GLuint geometryShaderId{0};
id_ = glCreateProgram(); id_ = glCreateProgram();
@ -22,8 +22,8 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile,
glAttachShader(id_, fragmentShaderId); glAttachShader(id_, fragmentShaderId);
CheckGLError("Error in attaching the fragment shader"); CheckGLError("Error in attaching the fragment shader");
if (!geometryShaderFile.empty()) { if (!geometryShader.empty()) {
geometryShaderId = CompileShader(geometryShaderFile, GL_GEOMETRY_SHADER); geometryShaderId = CompileShader(geometryShader, GL_GEOMETRY_SHADER);
glAttachShader(id_, geometryShaderId); glAttachShader(id_, geometryShaderId);
CheckGLError("Error in attaching the geometry shader"); CheckGLError("Error in attaching the geometry shader");
} }
@ -34,7 +34,7 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile,
glDeleteShader(vertexShaderId); glDeleteShader(vertexShaderId);
glDeleteShader(fragmentShaderId); glDeleteShader(fragmentShaderId);
if (!geometryShaderFile.empty()) { if (geometryShaderId != 0) {
glDeleteShader(geometryShaderId); glDeleteShader(geometryShaderId);
} }
@ -114,33 +114,14 @@ bool Shader::CopyDataToUniform(const bool data, const string &name) const {
return true; return true;
} }
string Shader::ReadFile(const string &filename) { GLuint Shader::CompileShader(const std::string &shaderSource,
string data; const GLenum shaderType) {
ifstream file; const GLuint id = glCreateShader(shaderType);
file.open(filename, std::ios::binary); const auto shaderC_str = shaderSource.c_str();
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();
glShaderSource(id, 1, &shaderC_str, nullptr); glShaderSource(id, 1, &shaderC_str, nullptr);
glCompileShader(id); glCompileShader(id);
CheckShaderivError(id, GL_COMPILE_STATUS, CheckShaderivError(id, GL_COMPILE_STATUS,
"Error when creating shader file " + filename); "Error when compiling shader file:\n" + shaderSource);
return id; return id;
} }

View file

@ -30,7 +30,6 @@ class Shader {
private: private:
GLuint id_; GLuint id_;
static std::string ReadFile(const std::string &);
static GLuint CompileShader(const std::string &, GLenum); static GLuint CompileShader(const std::string &, GLenum);
static void CheckGLError(const std::string &); static void CheckGLError(const std::string &);