From e360e95dcbdc8868e50cfb515942d796619aca21 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 17 Feb 2021 01:01:55 +0000 Subject: Support multiple shader programs, set by model --- application/main.cpp | 2 +- gfx/gl/shader.cpp | 38 +++++++++++++++++++++++++++----------- gfx/gl/shader.h | 19 ++++++++++++++----- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/application/main.cpp b/application/main.cpp index 72da726..41bc15a 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -83,8 +83,8 @@ public: Camera camera({-1250.0F, 35.0F, -1250.0F}, 70.0F, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.1F, 10000.0F); camera.Pitch(0.24); camera.RotateY(0.7854); - shader.Bind(); shader.setView(camera.GetViewProjection()); + shader.setLight(glm::normalize(glm::vec3 {1, -1, 0})); auto t_start = std::chrono::high_resolution_clock::now(); const auto framelen = std::chrono::milliseconds {1000} / 120; diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index 7fcdefe..979d57e 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -6,10 +6,12 @@ #include #include -Shader::Shader() : viewProjection_uniform {}, model_uniform {}, lightDir_uniform {} +Shader::ProgramHandle::ProgramHandle(std::initializer_list srcs) : + viewProjection_uniform {}, model_uniform {}, lightDir_uniform {} { - glAttachShader(m_program, Source {{basicShader_vs, basicShader_vs_len}, GL_VERTEX_SHADER}.id); - glAttachShader(m_program, Source {{basicShader_fs, basicShader_fs_len}, GL_FRAGMENT_SHADER}.id); + for (const auto & srcId : srcs) { + glAttachShader(m_program, srcId); + } glBindAttribLocation(m_program, 0, "position"); glBindAttribLocation(m_program, 1, "texCoord"); @@ -26,24 +28,38 @@ Shader::Shader() : viewProjection_uniform {}, model_uniform {}, lightDir_uniform lightDir_uniform = glGetUniformLocation(m_program, "lightDirection"); } -void -Shader::Bind() const +Shader::Shader() : + programs {{{ + Source {{basicShader_vs, basicShader_vs_len}, GL_VERTEX_SHADER}.id, + Source {{basicShader_fs, basicShader_fs_len}, GL_FRAGMENT_SHADER}.id, + }}} { - glUseProgram(m_program); } void Shader::setView(glm::mat4 proj) const { - glUniformMatrix4fv(viewProjection_uniform, 1, GL_FALSE, &proj[0][0]); - const glm::vec3 lightDir = glm::normalize(glm::vec3 {1, -1, 0}); - glUniform3fv(lightDir_uniform, 1, &lightDir[0]); + for (const auto & prog : programs) { + glUseProgram(prog.m_program); + glUniformMatrix4fv(prog.viewProjection_uniform, 1, GL_FALSE, &proj[0][0]); + } +} + +void +Shader::setLight(glm::vec3 lightDir) const +{ + for (const auto & prog : programs) { + glUseProgram(prog.m_program); + glUniform3fv(prog.lightDir_uniform, 1, &lightDir[0]); + } } void -Shader::setModel(glm::mat4 model) const +Shader::setModel(glm::mat4 model, Program pid) const { - glUniformMatrix4fv(model_uniform, 1, GL_FALSE, &model[0][0]); + auto & prog = programs[(int)pid]; + glUseProgram(prog.m_program); + glUniformMatrix4fv(prog.model_uniform, 1, GL_FALSE, &model[0][0]); } void diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index a839b9b..98e0348 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -2,17 +2,20 @@ #define SHADER_INCLUDED_H #include +#include #include #include #include class Shader { public: + enum class Program { Basic = 0 }; + Shader(); - void Bind() const; void setView(glm::mat4 view) const; - void setModel(glm::mat4 model) const; + void setModel(glm::mat4 model, Program = Program::Basic) const; + void setLight(glm::vec3 dir) const; private: class Source { @@ -27,10 +30,16 @@ private: static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage); - using ProgramRef = glRef; + class ProgramHandle { + public: + ProgramHandle(std::initializer_list); + using ProgramRef = glRef; + + ProgramRef m_program; + GLint viewProjection_uniform, model_uniform, lightDir_uniform; + }; - ProgramRef m_program; - GLint viewProjection_uniform, model_uniform, lightDir_uniform; + std::array programs; }; #endif -- cgit v1.2.3