move shader functions to cpp file. shaders now produce a warning when a uniform variable cannot be found

main
Brett 2023-12-29 12:34:35 -05:00
parent f94ecb2e1e
commit d6c05fa236
2 changed files with 149 additions and 58 deletions

View File

@ -77,18 +77,22 @@ namespace blt::gfx
struct IntDefaultedToMinusOne struct IntDefaultedToMinusOne
{ {
GLint i = -1; GLint i = -1;
inline explicit operator bool() const
{
return i != -1;
}
inline operator int() const
{
return i;
}
}; };
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars; std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
GLuint programID = 0; GLuint programID = 0;
inline GLint getUniformLocation(const std::string& name) IntDefaultedToMinusOne getUniformLocation(const std::string& name);
{
if (uniformVars[name].i != -1)
return uniformVars[name].i;
int loc = glGetUniformLocation(programID, name.c_str());
uniformVars[name].i = loc;
return loc;
}
public: public:
inline const shader_base_t& bind() const inline const shader_base_t& bind() const
@ -103,51 +107,25 @@ namespace blt::gfx
return *this; return *this;
} }
inline shader_base_t& setBool(const std::string& name, bool value) shader_base_t& setBool(const std::string& name, bool value);
{
glUniform1i(getUniformLocation(name), (int) value);
return *this;
}
inline void setInt(const std::string& name, int value) shader_base_t& setInt(const std::string& name, int value);
{
glUniform1i(getUniformLocation(name), value);
}
inline void setFloat(const std::string& name, float value) shader_base_t& setFloat(const std::string& name, float value);
{
glUniform1f(getUniformLocation(name), value);
}
inline void setMatrix(const std::string& name, blt::mat4x4& matrix) shader_base_t& setMatrix(const std::string& name, blt::mat4x4& matrix);
{
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, matrix.ptr());
}
inline void setVec3(const std::string& name, const blt::vec3& vec) shader_base_t& setVec2(const std::string& name, const blt::vec2& vec);
{
glUniform3f(getUniformLocation(name), vec.x(), vec.y(), vec.z());
}
inline void setVec4(const std::string& name, const blt::vec4& vec) shader_base_t& setVec3(const std::string& name, const blt::vec3& vec);
{
glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w());
}
inline void setVec2(const std::string& name, float x, float y) shader_base_t& setVec4(const std::string& name, const blt::vec4& vec);
{
glUniform2f(getUniformLocation(name), x, y);
}
inline void setVec3(const std::string& name, float x, float y, float z) shader_base_t& setVec2(const std::string& name, float x, float y);
{
glUniform3f(getUniformLocation(name), x, y, z);
}
inline void setVec4(const std::string& name, float x, float y, float z, float w) shader_base_t& setVec3(const std::string& name, float x, float y, float z);
{
glUniform4f(getUniformLocation(name), x, y, z, w); shader_base_t& setVec4(const std::string& name, float x, float y, float z, float w);
}
}; };
/** /**

View File

@ -22,11 +22,14 @@
namespace blt::gfx namespace blt::gfx
{ {
static std::string removeEmptyFirstLines(const std::string& string){ static std::string removeEmptyFirstLines(const std::string& string)
{
auto lines = blt::string::split(string, "\n"); auto lines = blt::string::split(string, "\n");
std::string new_source_string; std::string new_source_string;
for (const auto& line : lines) { for (const auto& line : lines)
if (!line.empty() && !blt::string::contains(line, "\"")) { {
if (!line.empty() && !blt::string::contains(line, "\""))
{
new_source_string += line; new_source_string += line;
new_source_string += "\n"; new_source_string += "\n";
} }
@ -34,7 +37,8 @@ namespace blt::gfx
return new_source_string; return new_source_string;
} }
unsigned int shader_t::createShader(const std::string& source, int type) { unsigned int shader_t::createShader(const std::string& source, int type)
{
const char* shader_code = source.c_str(); const char* shader_code = source.c_str();
// creates a Shader // creates a Shader
unsigned int shaderID = glCreateShader(type); unsigned int shaderID = glCreateShader(type);
@ -49,7 +53,8 @@ namespace blt::gfx
// the TODO: maybe find a way of lexing the output to give suggestions about fixing the error? default error messages can be unhelpful at times. // the TODO: maybe find a way of lexing the output to give suggestions about fixing the error? default error messages can be unhelpful at times.
GLint success; GLint success;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success); glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if (!success) { if (!success)
{
int log_length = 0; int log_length = 0;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &log_length); glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &log_length);
@ -68,15 +73,18 @@ namespace blt::gfx
return shaderID; return shaderID;
} }
shader_t::shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string) { shader_t::shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string)
{
// load shader sources // load shader sources
std::string vertex_source = vertex; std::string vertex_source = vertex;
std::string fragment_source = fragment; std::string fragment_source = fragment;
if (!load_as_string){ if (!load_as_string)
{
// BLT provides a recursive file loader for glsl shaders. It's pretty much just a recursive function looking for include statements. // BLT provides a recursive file loader for glsl shaders. It's pretty much just a recursive function looking for include statements.
vertex_source = blt::fs::loadShaderFile(vertex); vertex_source = blt::fs::loadShaderFile(vertex);
fragment_source = blt::fs::loadShaderFile(fragment); fragment_source = blt::fs::loadShaderFile(fragment);
} else { } else
{
vertex_source = removeEmptyFirstLines(vertex_source); vertex_source = removeEmptyFirstLines(vertex_source);
fragment_source = removeEmptyFirstLines(fragment_source); fragment_source = removeEmptyFirstLines(fragment_source);
} }
@ -95,7 +103,8 @@ namespace blt::gfx
GLint success; GLint success;
glGetProgramiv(programID, GL_LINK_STATUS, &success); glGetProgramiv(programID, GL_LINK_STATUS, &success);
if (!success) { if (!success)
{
int log_length = 0; int log_length = 0;
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &log_length); glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &log_length);
@ -118,12 +127,14 @@ namespace blt::gfx
glUseProgram(0); glUseProgram(0);
} }
void shader_t::bindAttribute(int attribute, const std::string &name) const { void shader_t::bindAttribute(int attribute, const std::string& name) const
{
bind(); bind();
glBindAttribLocation(programID, attribute, name.c_str()); glBindAttribLocation(programID, attribute, name.c_str());
} }
void shader_t::setUniformBlockLocation(const std::string &name, int location) const { void shader_t::setUniformBlockLocation(const std::string& name, int location) const
{
bind(); bind();
auto blockID = glGetUniformBlockIndex(programID, name.c_str()); auto blockID = glGetUniformBlockIndex(programID, name.c_str());
if (blockID != GL_INVALID_INDEX) if (blockID != GL_INVALID_INDEX)
@ -132,7 +143,8 @@ namespace blt::gfx
BLT_WARN("Unable to find uniform buffer '%s'. Did you forget to declare it?", name.c_str()); BLT_WARN("Unable to find uniform buffer '%s'. Did you forget to declare it?", name.c_str());
} }
shader_t::~shader_t() { shader_t::~shader_t()
{
glUseProgram(0); glUseProgram(0);
// shader was moved // shader was moved
if (programID <= 0) if (programID <= 0)
@ -149,7 +161,8 @@ namespace blt::gfx
glDeleteProgram(programID); glDeleteProgram(programID);
} }
shader_t::shader_t(shader_t&& move) noexcept { shader_t::shader_t(shader_t&& move) noexcept
{
// the move constructor doesn't need to construct a new shader but it does need to ensure all old variables are moved over // the move constructor doesn't need to construct a new shader but it does need to ensure all old variables are moved over
programID = move.programID; programID = move.programID;
vertexShaderID = move.vertexShaderID; vertexShaderID = move.vertexShaderID;
@ -207,4 +220,104 @@ namespace blt::gfx
{ {
glDeleteBuffers(1, &uboID); glDeleteBuffers(1, &uboID);
} }
shader_base_t& shader_base_t::setBool(const std::string& name, bool value)
{
if (auto i = getUniformLocation(name))
glUniform1i(i.i, (int) value);
else
BLT_WARN("Unable to find boolean uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setInt(const std::string& name, int value)
{
if (auto i = getUniformLocation(name))
glUniform1i(i.i, value);
else
BLT_WARN("Unable to find integer uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setFloat(const std::string& name, float value)
{
if (auto i = getUniformLocation(name))
glUniform1f(i.i, value);
else
BLT_WARN("Unable to find float uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setMatrix(const std::string& name, mat4x4& matrix)
{
if (auto i = getUniformLocation(name))
glUniformMatrix4fv(i.i, 1, GL_FALSE, matrix.ptr());
else
BLT_WARN("Unable to find matrix uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec2(const std::string& name, const vec2& vec)
{
if (auto i = getUniformLocation(name))
glUniform2f(i.i, vec.x(), vec.y());
else
BLT_WARN("Unable to find vec3 uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec3(const std::string& name, const vec3& vec)
{
if (auto i = getUniformLocation(name))
glUniform3f(i.i, vec.x(), vec.y(), vec.z());
else
BLT_WARN("Unable to find vec3 uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec4(const std::string& name, const vec4& vec)
{
if (auto i = getUniformLocation(name))
glUniform4f(i.i, vec.x(), vec.y(), vec.z(), vec.w());
else
BLT_WARN("Unable to find vec4 uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec2(const std::string& name, float x, float y)
{
if (auto i = getUniformLocation(name))
glUniform2f(i.i, x, y);
else
BLT_WARN("Unable to find vec2 uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec3(const std::string& name, float x, float y, float z)
{
if (auto i = getUniformLocation(name))
glUniform3f(i.i, x, y, z);
else
BLT_WARN("Unable to find vec3 uniform variable %s", name.c_str());
return *this;
}
shader_base_t& shader_base_t::setVec4(const std::string& name, float x, float y, float z, float w)
{
if (auto i = getUniformLocation(name))
glUniform4f(i.i, x, y, z, w);
else
BLT_WARN("Unable to find vec4 uniform variable %s", name.c_str());
return *this;
}
shader_base_t::IntDefaultedToMinusOne shader_base_t::getUniformLocation(const std::string& name)
{
if (uniformVars[name])
return uniformVars[name];
int loc = glGetUniformLocation(programID, name.c_str());
auto& v = uniformVars[name];
v.i = loc;
return v;
}
} }