From f9766d1a84b912d3bb561c0fd949181d6721f440 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 28 Dec 2023 16:14:12 -0500 Subject: [PATCH] working renderering --- include/blt/gfx/model.h | 35 +++++++++++-- include/blt/gfx/shader.h | 16 +++--- include/blt/gfx/texture.h | 82 +++++-------------------------- resources/textures/cumdollar.jpg | Bin 0 -> 18583 bytes src/blt/gfx/model.cpp | 18 ++++--- src/blt/gfx/shader.cpp | 12 ++--- src/blt/gfx/texture.cpp | 76 ++++++++++++++++++++++++++++ tests/include/shaders/test.frag | 23 +++++++++ tests/include/shaders/test.vert | 29 +++++++++++ tests/src/main.cpp | 73 +++++++++++++++++++++++++-- 10 files changed, 265 insertions(+), 99 deletions(-) create mode 100644 resources/textures/cumdollar.jpg create mode 100644 tests/include/shaders/test.frag create mode 100644 tests/include/shaders/test.vert diff --git a/include/blt/gfx/model.h b/include/blt/gfx/model.h index 222a9f7..93c7dcc 100644 --- a/include/blt/gfx/model.h +++ b/include/blt/gfx/model.h @@ -41,14 +41,20 @@ namespace blt::gfx { GLuint bufferID_ = 0; GLsizeiptr size_ = 0; - GLint buffer_type; - GLint memory_type; + GLint buffer_type = 0; + GLint memory_type = 0; - void create(GLint type); + void create(GLint type = GL_ARRAY_BUFFER); void bind() const; - void allocate(GLsizeiptr size, GLint memory_type = GL_STATIC_DRAW, void* data = nullptr); + void allocate(GLsizeiptr size, GLint mem_type = GL_STATIC_DRAW, const void* data = nullptr); + + template + void allocate(GLsizeiptr size, const T* data, GLint mem_type = GL_STATIC_DRAW) + { + allocate(size, mem_type, static_cast(data)); + } void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data); @@ -105,7 +111,7 @@ namespace blt::gfx private: GLuint vaoID; static_dynamic_array VBOs; - HASHSET used_attributes; + HASHSET used_attributes; vbo_t element; public: vertex_array(); @@ -125,10 +131,24 @@ namespace blt::gfx * @param coordinate_size size of the data (number of * @param type type of data * @param stride how many bytes this data takes (for the entire per-vertex data structure) 0 will assume packed data + * This is in effect how many bytes until the next block of data * @param offset offset into the data structure to where the data is stored */ void bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset); + inline void bindElement(const vbo_t& vbo) + { + bind(); + element = vbo; + vbo.bind(); + unbind(); + } + + inline vbo_t& getElement() + { + return element; + } + /** * Returns a non-owning reference to a vbo allowing for updating the VBO * The VBO is considered invalid if its ID is 0 @@ -143,6 +163,11 @@ namespace blt::gfx glBindVertexArray(vaoID); } + static inline void unbind() + { + glBindVertexArray(0); + } + ~vertex_array(); }; diff --git a/include/blt/gfx/shader.h b/include/blt/gfx/shader.h index 11fac50..9e44c03 100644 --- a/include/blt/gfx/shader.h +++ b/include/blt/gfx/shader.h @@ -64,7 +64,7 @@ namespace blt::gfx } }; - class shader_base + class shader_base_t { friend uniform_buffer; protected: @@ -139,12 +139,12 @@ namespace blt::gfx /** * a basic computer shader class, contains the functions and resources required to use compute shaders! */ - class compute_shader : public shader_base + class compute_shader_t : public shader_base_t { private: GLuint shaderID = 0; public: - explicit compute_shader(const std::string& shader_source, bool loadAsString = true); + explicit compute_shader_t(const std::string& shader_source, bool loadAsString = true); inline void execute(int x, int y, int z) const { @@ -152,10 +152,10 @@ namespace blt::gfx glDispatchCompute(x, y, z); } - ~compute_shader(); + ~compute_shader_t(); }; - class shader : public shader_base + class shader_t : public shader_base_t { private: GLuint vertexShaderID = 0; @@ -171,9 +171,9 @@ namespace blt::gfx * @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) */ - shader(const std::string& vertex, const std::string& fragment, bool load_as_string = true); + shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string = true); - shader(shader&& move) noexcept; + shader_t(shader_t&& move) noexcept; // used to set the location of VAOs to the in variables in opengl shaders. void bindAttribute(int attribute, const std::string& name) const; @@ -181,7 +181,7 @@ namespace blt::gfx // used to set location of shared UBOs like the perspective and view matrix void setUniformBlockLocation(const std::string& name, int location) const; - ~shader(); + ~shader_t(); }; } diff --git a/include/blt/gfx/texture.h b/include/blt/gfx/texture.h index e85d5d3..02feefe 100644 --- a/include/blt/gfx/texture.h +++ b/include/blt/gfx/texture.h @@ -42,7 +42,7 @@ namespace blt::gfx texture_data(int width, int height, int channels = 4): m_width(width), m_height(height), m_channels(channels) { - m_data = static_cast(STBI_MALLOC(width * height * channels)); + m_data = static_cast(std::malloc(width * height * channels)); } texture_data() = default; @@ -74,7 +74,7 @@ namespace blt::gfx ~texture_data() { - STBI_FREE(m_data); + std::free(m_data); } }; @@ -127,12 +127,8 @@ namespace blt::gfx GLint textureColorMode; int m_width, m_height; - texture_gl( - int width, int height, GLint bind_type = GL_TEXTURE_2D, - GLint color_mode = GL_RGBA - ): - textureBindType(bind_type), textureColorMode(color_mode), m_width(width), - m_height(height) + texture_gl(int width, int height, GLint bind_type = GL_TEXTURE_2D, GLint color_mode = GL_RGBA): + textureBindType(bind_type), textureColorMode(color_mode), m_width(width), m_height(height) { glGenTextures(1, &textureID); } @@ -144,6 +140,7 @@ namespace blt::gfx { glGenerateMipmap(textureBindType); } + public: inline void bind() const { @@ -169,51 +166,19 @@ namespace blt::gfx struct texture_gl2D : public texture_gl { public: - texture_gl2D(int width, int height, GLint colorMode = GL_RGBA): - texture_gl(width, height, GL_TEXTURE_2D, colorMode) - { - bind(); - setDefaults(); - // TODO: - const int MIPMAP_LEVELS = 4; - glTexStorage2D( - textureBindType, MIPMAP_LEVELS, colorMode, - width, height - ); - } + texture_gl2D(const texture_data& data); + + texture_gl2D(int width, int height, GLint colorMode = GL_RGBA8); void upload(void* data, GLint dataColorMode = GL_RGBA, int level = 0, int x_offset = 0, int y_offset = 0, int sub_width = -1, - int sub_height = -1) const - { - if (sub_width < 0) - sub_width = m_width; - if (sub_height < 0) - sub_height = m_height; - bind(); - glTexSubImage2D( - textureBindType, level, x_offset, y_offset, sub_width, sub_height, - dataColorMode, GL_UNSIGNED_BYTE, data - ); - generateMipmaps(); - unbind(); - } + int sub_height = -1) const; - void upload(const texture_file& tex_file) const - { - upload(tex_file.texture().data(), tex_file.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, tex_file.width(), tex_file.height()); - } + void upload(const texture_file& tex_file) const; /** * Resizes the internal memory for the texture but does NOT resize the texture image stored */ - inline void resize(int width, int height) - { - m_width = width; - m_height = height; - bind(); - glTexStorage2D(textureBindType, 0, textureColorMode, m_width, m_height); - unbind(); - } + inline void resize(int width, int height); }; struct gl_texture2D_array : public texture_gl @@ -221,31 +186,10 @@ namespace blt::gfx protected: int m_layers; public: - gl_texture2D_array(int width, int height, int layers, GLint colorMode = GL_RGBA8): - texture_gl(width, height, GL_TEXTURE_2D_ARRAY, colorMode), m_layers(layers) - { - bind(); - setDefaults(); - // 6+ mipmaps is about where I stop noticing any difference (size is 4x4 pixels, so that makes sense) - glTexStorage3D(textureBindType, 6, colorMode, width, height, layers); - BLT_DEBUG("Creating 2D Texture Array with ID: %d", textureID); - } + gl_texture2D_array(int width, int height, int layers, GLint colorMode = GL_RGBA8); void upload(void* data, int index, GLint dataColorMode = GL_RGBA, int level = 0, int x_offset = 0, int y_offset = 0, int sub_width = -1, - int sub_height = -1) const - { - if (sub_width < 0) - sub_width = m_width; - if (sub_height < 0) - sub_height = m_height; - bind(); - glTexSubImage3D( - textureBindType, level, x_offset, y_offset, index, sub_width, sub_height, 1, - dataColorMode, GL_UNSIGNED_BYTE, data - ); - generateMipmaps(); - unbind(); - } + int sub_height = -1) const; }; class gl_buffer_texture : public texture_gl2D diff --git a/resources/textures/cumdollar.jpg b/resources/textures/cumdollar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6069363de6ae337fad69ebf8705a9add09d2cd48 GIT binary patch literal 18583 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 X000000HFWc00;pC0SP|<03ZL^{X}sO literal 0 HcmV?d00001 diff --git a/src/blt/gfx/model.cpp b/src/blt/gfx/model.cpp index 94febf6..20576f0 100644 --- a/src/blt/gfx/model.cpp +++ b/src/blt/gfx/model.cpp @@ -29,21 +29,19 @@ namespace blt::gfx if (std::holds_alternative(data_)) { auto* ptr = std::get(data_); - std::memcpy(new_data, ptr, size_); + std::memcpy(new_data, ptr, sizeof(vbo_t) * size_); delete[] ptr; - } else { + } else + { auto data = std::get(data_); - std::memcpy(new_data, data.data(), DATA_SIZE); + std::memcpy(new_data, data.data(), sizeof(vbo_t) * DATA_SIZE); } data_ = new_data; size_ = next_size; } static_dynamic_array::static_dynamic_array() - { - auto ptr = std::get(data_); - std::memset(ptr.data(), 0, DATA_SIZE); - } + {} vbo_t& static_dynamic_array::operator[](size_t index) { @@ -72,8 +70,9 @@ namespace blt::gfx glDeleteBuffers(1, &bufferID_); } - void vbo_t::allocate(GLsizeiptr size, GLint mem_type, void* data) + void vbo_t::allocate(GLsizeiptr size, GLint mem_type, const void* data) { + bind(); size_ = size; glBufferData(buffer_type, size, data, mem_type); memory_type = mem_type; @@ -90,6 +89,7 @@ namespace blt::gfx void vbo_t::sub_update(GLsizeiptr offset, GLsizeiptr size, void* data) { + bind(); glBufferSubData(buffer_type, offset, size, data); } @@ -131,5 +131,7 @@ namespace blt::gfx glEnableVertexAttribArray(attribute_number); VBOs[attribute_number] = vbo; + + unbind(); } } \ No newline at end of file diff --git a/src/blt/gfx/shader.cpp b/src/blt/gfx/shader.cpp index 78463f1..50b3edb 100644 --- a/src/blt/gfx/shader.cpp +++ b/src/blt/gfx/shader.cpp @@ -34,7 +34,7 @@ namespace blt::gfx return new_source_string; } - unsigned int shader::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(); // creates a Shader unsigned int shaderID = glCreateShader(type); @@ -68,7 +68,7 @@ namespace blt::gfx return shaderID; } - shader::shader(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 std::string vertex_source = vertex; std::string fragment_source = fragment; @@ -118,12 +118,12 @@ namespace blt::gfx glUseProgram(0); } - void shader::bindAttribute(int attribute, const std::string &name) const { + void shader_t::bindAttribute(int attribute, const std::string &name) const { bind(); glBindAttribLocation(programID, attribute, name.c_str()); } - void shader::setUniformBlockLocation(const std::string &name, int location) const { + void shader_t::setUniformBlockLocation(const std::string &name, int location) const { bind(); auto blockID = glGetUniformBlockIndex(programID, name.c_str()); if (blockID != GL_INVALID_INDEX) @@ -132,7 +132,7 @@ namespace blt::gfx BLT_WARN("Unable to find uniform buffer '%s'. Did you forget to declare it?", name.c_str()); } - shader::~shader() { + shader_t::~shader_t() { glUseProgram(0); // shader was moved if (programID <= 0) @@ -149,7 +149,7 @@ namespace blt::gfx glDeleteProgram(programID); } - shader::shader(shader&& 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 programID = move.programID; vertexShaderID = move.vertexShaderID; diff --git a/src/blt/gfx/texture.cpp b/src/blt/gfx/texture.cpp index a93d487..c2ec470 100644 --- a/src/blt/gfx/texture.cpp +++ b/src/blt/gfx/texture.cpp @@ -21,20 +21,25 @@ #define STB_PERLIN_IMPLEMENTATION #include + #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" + #include + #pragma GCC diagnostic pop #else #include #endif + #include #include #include blt::gfx::texture_file::texture_file(const std::string& path, const std::string& name): m_name(name.empty() ? path : name), m_path(path) { + stbi_set_flip_vertically_on_load(true); m_texture.m_data = stbi_load( m_path.c_str(), reinterpret_cast(&m_texture.m_width), reinterpret_cast(&m_texture.m_height), @@ -89,3 +94,74 @@ void blt::gfx::texture_gl::setDefaults() const glTexParameterf(textureBindType, GL_TEXTURE_MAX_ANISOTROPY_EXT, a); #endif } + +void blt::gfx::texture_gl2D::upload(void* data, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, int sub_height) const +{ + if (sub_width < 0) + sub_width = m_width; + if (sub_height < 0) + sub_height = m_height; + bind(); + glTexSubImage2D(textureBindType, level, x_offset, y_offset, sub_width, sub_height, dataColorMode, GL_UNSIGNED_BYTE, data); + unbind(); +} + +void blt::gfx::texture_gl2D::upload(const blt::gfx::texture_file& tex_file) const +{ + upload(tex_file.texture().data(), tex_file.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, tex_file.width(), tex_file.height()); +} + +void blt::gfx::texture_gl2D::resize(int width, int height) +{ + m_width = width; + m_height = height; + bind(); + glTexStorage2D(textureBindType, 0, textureColorMode, m_width, m_height); + unbind(); +} + +blt::gfx::texture_gl2D::texture_gl2D(int width, int height, GLint colorMode): texture_gl(width, height, GL_TEXTURE_2D, colorMode) +{ + bind(); + setDefaults(); + // TODO: + const int MIPMAP_LEVELS = 4; + glTexStorage2D(textureBindType, MIPMAP_LEVELS, colorMode, width, height); +} + +blt::gfx::texture_gl2D::texture_gl2D(const blt::gfx::texture_data& data): texture_gl(data.width(), data.height(), GL_TEXTURE_2D, GL_RGBA8) +{ + bind(); + setDefaults(); + glTexStorage2D(textureBindType, 4, GL_RGBA8, data.width(), data.height()); + upload((void*) data.data(), data.channels() == 4 ? GL_RGBA : GL_RGB, 0, 0, 0, data.width(), data.height()); + bind(); + //glTexImage2D(textureBindType, 0, GL_RGBA, data.width(), data.height(), 0, data.channels() == 4 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (void*)data.data()); + generateMipmaps(); + unbind(); +} + +void blt::gfx::gl_texture2D_array::upload(void* data, int index, GLint dataColorMode, int level, int x_offset, int y_offset, int sub_width, + int sub_height) const +{ + if (sub_width < 0) + sub_width = m_width; + if (sub_height < 0) + sub_height = m_height; + bind(); + glTexSubImage3D( + textureBindType, level, x_offset, y_offset, index, sub_width, sub_height, 1, + dataColorMode, GL_UNSIGNED_BYTE, data + ); + generateMipmaps(); + unbind(); +} + +blt::gfx::gl_texture2D_array::gl_texture2D_array(int width, int height, int layers, GLint colorMode): texture_gl(width, height, layers, colorMode) +{ + bind(); + setDefaults(); + // 6+ mipmaps is about where I stop noticing any difference (size is 4x4 pixels, so that makes sense) + glTexStorage3D(textureBindType, 6, colorMode, width, height, layers); + BLT_DEBUG("Creating 2D Texture Array with ID: %d", textureID); +} diff --git a/tests/include/shaders/test.frag b/tests/include/shaders/test.frag new file mode 100644 index 0000000..069fa53 --- /dev/null +++ b/tests/include/shaders/test.frag @@ -0,0 +1,23 @@ +#ifdef __cplusplus +#include +std::string shader_test_frag = R"(" +#version 300 es +precision mediump float; + +out vec4 FragColor; +in vec2 uv; +in vec2 pos; + +uniform sampler2D tex; + +vec4 linear_iter(vec4 i, vec4 p, float factor){ + return (i + p) * factor; +} + +void main() { + //FragColor = vec4(pos, 0.0, 1.0f); + FragColor = linear_iter(texture(tex, uv), vec4(pos, 0.0, 1.0), (uv.x + uv.y + 1.0) / 3.0); +} + +")"; +#endif \ No newline at end of file diff --git a/tests/include/shaders/test.vert b/tests/include/shaders/test.vert new file mode 100644 index 0000000..4fffb2d --- /dev/null +++ b/tests/include/shaders/test.vert @@ -0,0 +1,29 @@ +#ifdef __cplusplus +#include +std::string shader_test_vert = R"(" +#version 300 es +precision mediump float; + +layout (location = 0) in vec3 vertex; +layout (location = 1) in vec2 uv_in; + +out vec2 pos; +out vec2 uv; + +layout (std140) uniform GlobalMatrices +{ + mat4 projection; + mat4 view; +// projection view matrix + mat4 pvm; +}; + +void main() { + //gl_Position = projection * view * vec4(vertex.x, vertex.y, vertex.z, 1.0); + gl_Position = vec4(vertex, 1.0); + pos = vertex.xy; + uv = uv_in; +} + +")"; +#endif \ No newline at end of file diff --git a/tests/src/main.cpp b/tests/src/main.cpp index f5ea90e..993c3f0 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,12 +1,65 @@ -#include - #include +#include +#include +#include +#include #include #include "blt/gfx/imgui/IconsFontAwesome5.h" +#include +#include + +const float raw_vertices[18] = { + // first triangle + 0.5f, 0.5f, 0.0f, // top right + 0.5f, -0.5f, 0.0f, // bottom right + -0.5f, 0.5f, 0.0f, // top left + // second triangle + 0.5f, -0.5f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, // bottom left + -0.5f, 0.5f, 0.0f // top left +}; + +float vertices[20] = { + // positions // texture coords + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left + -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left +}; +const unsigned int indices[6] = { // note that we start from 0! + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle +}; + +blt::gfx::vertex_array* vao; +blt::gfx::shader_t* shader; +blt::gfx::texture_gl2D* texture; + void init() { - + using namespace blt::gfx; + + vbo_t vertices_vbo; + vbo_t indices_vbo; + + vertices_vbo.create(); + indices_vbo.create(GL_ELEMENT_ARRAY_BUFFER); + + vertices_vbo.allocate(sizeof(vertices), vertices); + indices_vbo.allocate(sizeof(indices), indices); + + vao = new vertex_array(); + vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0); + vao->bindVBO(vertices_vbo, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float)); + vao->bindElement(indices_vbo); + + shader = new shader_t(shader_test_vert, shader_test_frag); + shader->bindAttribute(0, "vertex"); + shader->bindAttribute(1, "uv_in"); + + texture_file file("../resources/textures/cumdollar.jpg"); + texture = new texture_gl2D(file.texture()); } void update(std::int32_t width, std::int32_t height) @@ -15,11 +68,25 @@ void update(std::int32_t width, std::int32_t height) ImGui::Text("%s among %d items", ICON_FA_FILE, 0); ImGui::Button(ICON_FA_SEARCH " Search"); ImGui::End(); + + + shader->bind(); + + glActiveTexture(GL_TEXTURE0); + texture->bind(); + + vao->bind(); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } int main() { blt::gfx::init(blt::gfx::window_data{"My Sexy Window", init, update}.setSyncInterval(1)); + delete vao; + delete shader; + delete texture; blt::gfx::cleanup(); return 0; }