main
Brett 2023-12-26 15:14:24 -05:00
parent c4097f1c9b
commit 3bb0ca1193
9 changed files with 16581 additions and 77 deletions

View File

@ -27,59 +27,111 @@
namespace blt::gfx namespace blt::gfx
{ {
class shader_base { class uniform_buffer
{
private:
GLuint uboID;
size_t size_;
GLuint location_;
public:
uniform_buffer(size_t size, GLuint location = 0);
uniform_buffer(void* data, size_t size, GLuint location = 0);
/**
* Resizes the internal UBO
* @param newSize new size for the UBO
*/
uniform_buffer& resize(size_t newSize);
/**
* Uploads data to the UBO. This can be an arbitrary locations and does not need to be the whole UBO.
*/
uniform_buffer& upload(void* data, size_t size, size_t offset = 0);
/**
* Binds the UBO to a binding location
*/
uniform_buffer& bind(GLuint location);
~uniform_buffer();
[[nodiscard]] inline size_t size() const
{
return size_;
}
[[nodiscard]] inline GLuint location() const
{
return location_;
}
};
class shader_base
{
friend uniform_buffer;
protected: protected:
struct IntDefaultedToMinusOne { struct IntDefaultedToMinusOne
{
GLint i = -1; GLint i = -1;
}; };
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) { inline GLint getUniformLocation(const std::string& name)
{
if (uniformVars[name].i != -1) if (uniformVars[name].i != -1)
return uniformVars[name].i; return uniformVars[name].i;
int loc = glGetUniformLocation(programID, name.c_str()); int loc = glGetUniformLocation(programID, name.c_str());
uniformVars[name].i = loc; uniformVars[name].i = loc;
return loc; return loc;
} }
public: public:
inline void bind() const { inline void bind() const
{
glUseProgram(programID); glUseProgram(programID);
} }
inline void setBool(const std::string &name, bool value) { inline void setBool(const std::string& name, bool value)
{
glUniform1i(getUniformLocation(name), (int) value); glUniform1i(getUniformLocation(name), (int) value);
} }
inline void setInt(const std::string &name, int value) { inline void setInt(const std::string& name, int value)
{
glUniform1i(getUniformLocation(name), value); glUniform1i(getUniformLocation(name), value);
} }
inline void setFloat(const std::string &name, float value) { inline void setFloat(const std::string& name, float value)
{
glUniform1f(getUniformLocation(name), value); glUniform1f(getUniformLocation(name), value);
} }
inline void setMatrix(const std::string &name, blt::mat4x4 &matrix) { inline void setMatrix(const std::string& name, blt::mat4x4& matrix)
{
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, matrix.ptr()); glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, matrix.ptr());
} }
inline void setVec3(const std::string &name, const blt::vec3 &vec) { inline void setVec3(const std::string& name, const blt::vec3& vec)
{
glUniform3f(getUniformLocation(name), vec.x(), vec.y(), vec.z()); glUniform3f(getUniformLocation(name), vec.x(), vec.y(), vec.z());
} }
inline void setVec4(const std::string &name, const blt::vec4 &vec) { inline void setVec4(const std::string& name, const blt::vec4& vec)
{
glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w()); glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w());
} }
inline void setVec2(const std::string &name, float x, float y) { inline void setVec2(const std::string& name, float x, float y)
{
glUniform2f(getUniformLocation(name), x, y); glUniform2f(getUniformLocation(name), x, y);
} }
inline void setVec3(const std::string &name, float x, float y, float z) { inline void setVec3(const std::string& name, float x, float y, float z)
{
glUniform3f(getUniformLocation(name), x, y, z); glUniform3f(getUniformLocation(name), x, y, z);
} }
inline void setVec4(const std::string &name, float x, float y, float z, float w) { inline void setVec4(const std::string& name, float x, float y, float z, float w)
{
glUniform4f(getUniformLocation(name), x, y, z, w); glUniform4f(getUniformLocation(name), x, y, z, w);
} }
}; };
@ -87,13 +139,15 @@ namespace blt::gfx
/** /**
* a basic computer shader class, contains the functions and resources required to use compute shaders! * a basic computer shader class, contains the functions and resources required to use compute shaders!
*/ */
class compute_shader : public shader_base { class compute_shader : public shader_base
{
private: private:
GLuint shaderID = 0; GLuint shaderID = 0;
public: public:
explicit compute_shader(const std::string& shader_source, bool loadAsString = true); explicit compute_shader(const std::string& shader_source, bool loadAsString = true);
inline void execute(int x, int y, int z) const { inline void execute(int x, int y, int z) const
{
bind(); bind();
glDispatchCompute(x, y, z); glDispatchCompute(x, y, z);
} }
@ -101,18 +155,14 @@ namespace blt::gfx
~compute_shader(); ~compute_shader();
}; };
class shader : public shader_base { class shader : public shader_base
{
private: private:
GLuint vertexShaderID = 0; GLuint vertexShaderID = 0;
GLuint fragmentShaderID = 0; GLuint fragmentShaderID = 0;
// while these will remain unused. (Webgl2 apparently doesn't support them despite being based on GL4.3? that's a TODO!)
GLuint geometryShaderID = 0;
// this would be very useful however it is highly unlikely webgl will support it
// im leaving some of this stuff in here because I might expand the native application to use some of it.
// im trying to keep the web and native versions the same though
GLuint tessellationShaderID = 0;
static unsigned int createShader(const std::string& source, int type); static unsigned int createShader(const std::string& source, int type);
public: public:
/** /**
* Creates a shader * Creates a shader
@ -121,7 +171,7 @@ namespace blt::gfx
* @param geometry geometry shader source or file (optional) * @param geometry geometry shader source or file (optional)
* @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false) * @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false)
*/ */
shader(const std::string &vertex, const std::string &fragment, const std::string &geometry = "", bool load_as_string = true); shader(const std::string& vertex, const std::string& fragment, bool load_as_string = true);
shader(shader&& move) noexcept; shader(shader&& move) noexcept;
@ -132,12 +182,6 @@ namespace blt::gfx
void setUniformBlockLocation(const std::string& name, int location) const; void setUniformBlockLocation(const std::string& name, int location) const;
~shader(); ~shader();
static void updateProjectionMatrix(const blt::mat4x4& projectionMatrix);
static void updateOrthographicMatrix(const blt::mat4x4& orthoMatrix);
static void updateViewMatrix(const blt::mat4x4& viewMatrix);
// returns the perspective view matrix which is calculated per frame. (This is for optimization)
static const blt::mat4x4& getPVM();
}; };
} }

View File

@ -1,3 +1,6 @@
#if defined(_MSC_VER)
#pragma warning
#endif
/* stb_image_resize2 - v2.04 - public domain image resizing /* stb_image_resize2 - v2.04 - public domain image resizing
by Jeff Roberts (v2) and Jorge L Rodriguez by Jeff Roberts (v2) and Jorge L Rodriguez
@ -2876,12 +2879,12 @@ static float stbir__filter_mitchell(float x, float s, void * user_data)
return (0.0f); return (0.0f);
} }
//static float stbir__support_zero(float s, void * user_data) static float stbir__support_zero(float s, void * user_data)
//{ {
// STBIR__UNUSED(s); STBIR__UNUSED(s);
// STBIR__UNUSED(user_data); STBIR__UNUSED(user_data);
// return 0; return 0;
//} }
static float stbir__support_zeropoint5(float s, void * user_data) static float stbir__support_zeropoint5(float s, void * user_data)
{ {

View File

@ -52,7 +52,7 @@ namespace blt::gfx
return m_data; return m_data;
} }
[[nodiscard]] inline unsigned char* data() const [[nodiscard]] inline const unsigned char* data() const
{ {
return m_data; return m_data;
} }

File diff suppressed because it is too large Load Diff

5765
include/glad/gl_old.h Normal file

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit bc8134e3a2c69877ff008d84e81df3e06729d679 Subproject commit b135e5b915e0efaae2f8d9dc30d4752726b74bb4

@ -1 +1 @@
Subproject commit 0d582dabf34e9e31f072b1ee5c353c18351b4424 Subproject commit 4a2426449a4c65028c65c68ed9426495dec251e4

View File

@ -68,37 +68,28 @@ namespace blt::gfx
return shaderID; return shaderID;
} }
shader::shader(const std::string& vertex, const std::string& fragment, const std::string& geometry, bool load_as_string) { shader::shader(const std::string& vertex, const std::string& fragment, bool load_as_string) {
// load shader sources // load shader sources
bool load_geometry = !geometry.empty();
std::string vertex_source = vertex; std::string vertex_source = vertex;
std::string fragment_source = fragment; std::string fragment_source = fragment;
std::string geometry_source = geometry;
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);
if (load_geometry)
geometry_source = blt::fs::loadShaderFile(geometry);
} else { } else {
vertex_source = removeEmptyFirstLines(vertex_source); vertex_source = removeEmptyFirstLines(vertex_source);
fragment_source = removeEmptyFirstLines(fragment_source); fragment_source = removeEmptyFirstLines(fragment_source);
geometry_source = removeEmptyFirstLines(geometry_source);
} }
// create the shaders // create the shaders
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER); vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER); fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER);
if (load_geometry)
geometryShaderID = createShader(geometry_source, GL_GEOMETRY_SHADER);
// bind them to a program // bind them to a program
programID = glCreateProgram(); programID = glCreateProgram();
// attach the loaded shaders to the Shader program // attach the loaded shaders to the Shader program
glAttachShader(programID, vertexShaderID); glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID); glAttachShader(programID, fragmentShaderID);
if (load_geometry)
glAttachShader(programID, geometryShaderID);
// link and make sure that our program is valid. // link and make sure that our program is valid.
glLinkProgram(programID); glLinkProgram(programID);
@ -116,7 +107,6 @@ namespace blt::gfx
BLT_ERROR("Unable to link program of ID: %d", programID); BLT_ERROR("Unable to link program of ID: %d", programID);
BLT_ERROR(vertex_source); BLT_ERROR(vertex_source);
BLT_ERROR(fragment_source); BLT_ERROR(fragment_source);
BLT_ERROR(geometry_source);
BLT_ERROR("I have an log of %d length", log_length); BLT_ERROR("I have an log of %d length", log_length);
BLT_ERROR(infoLog.data()); BLT_ERROR(infoLog.data());
BLT_ERROR("--- --- --- --- --- --- --- --- ---"); BLT_ERROR("--- --- --- --- --- --- --- --- ---");
@ -124,7 +114,7 @@ namespace blt::gfx
glValidateProgram(programID); glValidateProgram(programID);
bind(); bind();
setUniformBlockLocation("StandardMatrices", 0); setUniformBlockLocation("GlobalMatrices", 0);
glUseProgram(0); glUseProgram(0);
} }
@ -135,7 +125,11 @@ namespace blt::gfx
void shader::setUniformBlockLocation(const std::string &name, int location) const { void shader::setUniformBlockLocation(const std::string &name, int location) const {
bind(); bind();
glUniformBlockBinding(programID, glGetUniformBlockIndex(programID, name.c_str()), location); auto blockID = glGetUniformBlockIndex(programID, name.c_str());
if (blockID != GL_INVALID_INDEX)
glUniformBlockBinding(programID, blockID, location);
else
BLT_WARN("Unable to find uniform buffer '%s'. Did you forget to declare it?", name.c_str());
} }
shader::~shader() { shader::~shader() {
@ -145,46 +139,54 @@ namespace blt::gfx
return; return;
// remove all the shaders from the program // remove all the shaders from the program
glDetachShader(programID, vertexShaderID); glDetachShader(programID, vertexShaderID);
if (geometryShaderID)
glDetachShader(programID, geometryShaderID);
if (tessellationShaderID)
glDetachShader(programID, tessellationShaderID);
glDetachShader(programID, fragmentShaderID); glDetachShader(programID, fragmentShaderID);
// delete the shaders // delete the shaders
glDeleteShader(vertexShaderID); glDeleteShader(vertexShaderID);
if (geometryShaderID)
glDeleteShader(geometryShaderID);
if (tessellationShaderID)
glDeleteShader(tessellationShaderID);
glDeleteShader(fragmentShaderID); glDeleteShader(fragmentShaderID);
// delete the Shader program // delete the Shader program
glDeleteProgram(programID); glDeleteProgram(programID);
} }
void shader::updateProjectionMatrix(const blt::mat4x4& projectionMatrix) {
}
void shader::updateViewMatrix(const blt::mat4x4& viewMatrix) {
}
void shader::updateOrthographicMatrix(const blt::mat4x4& orthoMatrix) {
}
shader::shader(shader&& move) noexcept { shader::shader(shader&& 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;
fragmentShaderID = move.fragmentShaderID; fragmentShaderID = move.fragmentShaderID;
geometryShaderID = move.geometryShaderID;
tessellationShaderID = move.tessellationShaderID;
for (const auto& pair : move.uniformVars) for (const auto& pair : move.uniformVars)
uniformVars.insert(pair); uniformVars.insert(pair);
// by setting the program ID to -1 we tell the shader it has been moved. // by setting the program ID to -1 we tell the shader it has been moved.
move.programID = -1; move.programID = -1;
} }
uniform_buffer::uniform_buffer(size_t size, GLuint location)
{
}
uniform_buffer::uniform_buffer(void* data, size_t size, GLuint location)
{
}
uniform_buffer& uniform_buffer::resize(size_t newSize)
{
return *this;
}
uniform_buffer& uniform_buffer::upload(void* data, size_t size, size_t offset)
{
return *this;
}
uniform_buffer& uniform_buffer::bind(GLuint location)
{
return *this;
}
uniform_buffer::~uniform_buffer()
{
}
} }

View File

@ -21,7 +21,14 @@
#define STB_PERLIN_IMPLEMENTATION #define STB_PERLIN_IMPLEMENTATION
#include <blt/gfx/stb/stb_image_write.h> #include <blt/gfx/stb/stb_image_write.h>
#if defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#include <blt/gfx/stb/stb_image_resize2.h> #include <blt/gfx/stb/stb_image_resize2.h>
#pragma GCC diagnostic pop
#else
#include <blt/gfx/stb/stb_image_resize2.h>
#endif
#include <blt/gfx/stb/stb_image.h> #include <blt/gfx/stb/stb_image.h>
#include <blt/gfx/stb/stb_perlin.h> #include <blt/gfx/stb/stb_perlin.h>
#include <blt/gfx/texture.h> #include <blt/gfx/texture.h>