working renderering

main
Brett 2023-12-28 16:14:12 -05:00
parent cec16931f2
commit f9766d1a84
10 changed files with 265 additions and 99 deletions

View File

@ -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<typename T>
void allocate(GLsizeiptr size, const T* data, GLint mem_type = GL_STATIC_DRAW)
{
allocate(size, mem_type, static_cast<const void*>(data));
}
void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data);
@ -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();
};

View File

@ -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();
};
}

View File

@ -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<unsigned char*>(STBI_MALLOC(width * height * channels));
m_data = static_cast<unsigned char*>(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

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -29,21 +29,19 @@ namespace blt::gfx
if (std::holds_alternative<vbo_t*>(data_))
{
auto* ptr = std::get<vbo_t*>(data_);
std::memcpy(new_data, ptr, size_);
std::memcpy(new_data, ptr, sizeof(vbo_t) * size_);
delete[] ptr;
} else {
} else
{
auto data = std::get<array_t>(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<array_t>(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();
}
}

View File

@ -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;

View File

@ -21,20 +21,25 @@
#define STB_PERLIN_IMPLEMENTATION
#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>
#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_perlin.h>
#include <blt/gfx/texture.h>
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<int*>(&m_texture.m_width), reinterpret_cast<int*>(&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);
}

View File

@ -0,0 +1,23 @@
#ifdef __cplusplus
#include <string>
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

View File

@ -0,0 +1,29 @@
#ifdef __cplusplus
#include <string>
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

View File

@ -1,12 +1,65 @@
#include <iostream>
#include <blt/gfx/window.h>
#include <blt/gfx/shader.h>
#include <blt/gfx/texture.h>
#include <blt/gfx/model.h>
#include <blt/std/logging.h>
#include <imgui.h>
#include "blt/gfx/imgui/IconsFontAwesome5.h"
#include <shaders/test.vert>
#include <shaders/test.frag>
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;
}