pre refactor

This commit is contained in:
Jay Robson 2024-07-10 15:35:19 +10:00
parent 52dd65b64e
commit c68d2967d3
39 changed files with 352 additions and 61 deletions

View File

@ -9,18 +9,11 @@ if(NOT WIN32)
endif() endif()
if(NOT WIN32) if(NOT WIN32)
if(NOT DEFINED SIGFPE_ENABLED)
set(SIGFPE_ENABLED 1)
endif()
set(libs stdc++ m GLEW glfw GL freetype assimp jsoncpp openal vorbisfile alut atomic) set(libs stdc++ m GLEW glfw GL freetype assimp jsoncpp openal vorbisfile alut atomic)
else() else()
set(libs stdc++ m brotlidec assimp-5 glew32 opengl32 glfw3 freetype jsoncpp zlibstatic soft_oal vorbisfile vorbis ogg alut atomic) set(libs stdc++ m brotlidec assimp-5 glew32 opengl32 glfw3 freetype jsoncpp zlibstatic soft_oal vorbisfile vorbis ogg alut atomic)
endif() endif()
if(SIGFPE_ENABLED)
add_compile_definitions(SIGFPE_ENABLED=1)
endif()
if(DEBUG_ENABLED) if(DEBUG_ENABLED)
message("-- Enabled: Runtime debug checks") message("-- Enabled: Runtime debug checks")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

BIN
assets/image/missing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

BIN
assets/image/white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

View File

@ -2,5 +2,12 @@
#version 430 core #version 430 core
#define SSBO_ATLAS_BUFFER 1 #define SSBO_ATLAS_BUFFER 1
#define SSBO_PARTICLES_IN 2
#define SSBO_PARTICLES_OUT 3
#define UBO_PARTICLES_INFO 4
#define TEX_ATLAS 1 #define TEX_ATLAS 1
#define TEXID_MISSING 0
#define TEXID_WHITE 1

View File

@ -1,5 +1,5 @@
float Map(float x, float i_min, float i_max, float o_min, float o_max) { float map(float x, float i_min, float i_max, float o_min, float o_max) {
return (x - i_min) * (o_max - o_min) / (i_max - i_min) + o_min; return (x - i_min) * (o_max - o_min) / (i_max - i_min) + o_min;
} }

View File

@ -0,0 +1,62 @@
#include "header.glsl"
#include "random.glsl"
layout (local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
struct VertType {
vec4 pos;
vec4 colour;
vec2 uv;
float texid;
};
struct ParticleType {
vec4 pos; // xyz: pos, w: vel random scale
vec4 velocity; // xyz: vel, w: colour random scale
vec4 colour;
float time_start;
float duration;
float size;
int seed;
};
layout (binding = SSBO_PARTICLES_IN) readonly buffer ParticleBufferIn {
ParticleType particles_in[];
};
layout (binding = SSBO_PARTICLES_OUT) writeonly buffer ParticleBufferOut {
VertType vertices_out[];
};
layout (binding = UBO_PARTICLES_INFO) uniform ParticleInfo {
float p_time;
int p_size;
};
void main() {
ParticleType particle = particles_in[gl_WorkGroupID.x];
int seed = particle.seed;
rand_mix(seed, int(gl_LocalInvocationID.x));
float duration = clamp((p_time - particle.time_start) / particle.duration, 0, 1);
vec3 velocity = normalize(vec3(
rand_float(seed) * 2 - 1,
rand_float(seed) * 2 - 1,
rand_float(seed) * 2 - 1
)) * particle.pos.w + particle.velocity.xyz;
vec4 colour = normalize(vec4(
rand_float(seed) * 2 - 1,
rand_float(seed) * 2 - 1,
rand_float(seed) * 2 - 1,
rand_float(seed) * 2 - 1
)) * particle.velocity.w + particle.colour;
vec3 pos = particle.pos.xyz + velocity * duration;
colour.a *= (1 - duration);
uint v_id = gl_GlobalInvocationID.x;
vertices_out[v_id].pos = vec4(pos, 1);
vertices_out[v_id].colour = colour;
vertices_out[v_id].texid = TEXID_WHITE;
}

15
assets/shader/random.glsl Normal file
View File

@ -0,0 +1,15 @@
int rand_gen(in int n) {
n = (n << 13) ^ n;
return (n * (n*n*15731+789221) + 1376312589) & 0x7fffffff;
}
float rand_float(inout int n) {
n = rand_gen(n);
return float(n) / float(0x7fffffff);
}
void rand_mix(inout int n, int v) {
n = rand_gen(n ^ v);
}

View File

@ -7,7 +7,7 @@
using Graphics::GL::ArrayBuffer; using Graphics::GL::ArrayBuffer;
ArrayBuffer::ArrayBuffer() { ArrayBuffer::ArrayBuffer() {
glGenBuffers(1, &m_handle); glCreateBuffers(1, &m_handle);
} }
ArrayBuffer::ArrayBuffer(ArrayBuffer&& o) : BufferBase(std::move(o)) { ArrayBuffer::ArrayBuffer(ArrayBuffer&& o) : BufferBase(std::move(o)) {

View File

@ -0,0 +1,18 @@
#include <GL/glew.h>
#include <vector>
#include "array_model.hpp"
using Graphics::GL::ArrayModel;
void ArrayModel::set(const std::vector<Vertex>& vertices, int usage) {
Vertex::set_vertex_attribs(m_vao, m_vbo);
glNamedBufferData(m_vbo, vertices.size() * sizeof(vertices[0]), vertices.data(), usage);
m_size = vertices.size();
}
void ArrayModel::render(int mode) const {
glBindVertexArray(m_vao);
glDrawArrays(mode, 0, m_size);
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "array_buffer.hpp"
#include "vertex_array.hpp"
#include "../vertex.hpp"
#include <vector>
namespace Graphics::GL {
struct ArrayModel {
VertexArray m_vao;
ArrayBuffer m_vbo;
unsigned int m_size;
void set(const std::vector<Vertex>& vertices, int usage);
void render(int mode) const;
};
};

View File

@ -1,4 +1,5 @@
#include <GL/glew.h>
#include "buffer_base.hpp" #include "buffer_base.hpp"
using Graphics::GL::BufferBase; using Graphics::GL::BufferBase;
@ -12,3 +13,9 @@ BufferBase::operator unsigned int() const {
return m_handle; return m_handle;
} }
bool BufferBase::check_binding(int mode) {
int binding;
glGetIntegerv(mode, &binding);
return binding == 0;
}

View File

@ -9,6 +9,8 @@ namespace Graphics::GL {
BufferBase(const BufferBase& o) = delete; BufferBase(const BufferBase& o) = delete;
operator unsigned int() const; operator unsigned int() const;
static bool check_binding(int mode);
protected: protected:
BufferBase(BufferBase&& o); BufferBase(BufferBase&& o);
}; };

View File

@ -6,7 +6,7 @@
using Graphics::GL::FrameBuffer; using Graphics::GL::FrameBuffer;
FrameBuffer::FrameBuffer() { FrameBuffer::FrameBuffer() {
glGenFramebuffers(1, &m_handle); glCreateFramebuffers(1, &m_handle);
} }
FrameBuffer::FrameBuffer(FrameBuffer&& o) : BufferBase(std::move(o)) { FrameBuffer::FrameBuffer(FrameBuffer&& o) : BufferBase(std::move(o)) {

View File

@ -5,18 +5,15 @@
using Graphics::GL::Model; using Graphics::GL::Model;
void Model::set(const Mesh& mesh, int usage) { void Model::set(const Mesh& mesh, int usage) {
glBufferData(GL_ARRAY_BUFFER, mesh.m_vertices.size() * sizeof(mesh.m_vertices[0]), mesh.m_vertices.data(), usage); Vertex::set_vertex_attribs(m_vao, m_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.m_indices.size() * sizeof(mesh.m_indices[0]), mesh.m_indices.data(), usage); glVertexArrayElementBuffer(m_vao, m_ebo);
glNamedBufferData(m_vbo, mesh.m_vertices.size() * sizeof(mesh.m_vertices[0]), mesh.m_vertices.data(), usage);
glNamedBufferData(m_ebo, mesh.m_indices.size() * sizeof(mesh.m_indices[0]), mesh.m_indices.data(), usage);
m_size = mesh.m_indices.size(); m_size = mesh.m_indices.size();
} }
void Model::bind() const {
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
}
void Model::render(int mode) const { void Model::render(int mode) const {
glBindVertexArray(m_vao);
glDrawElements(mode, m_size, GL_UNSIGNED_INT, 0); glDrawElements(mode, m_size, GL_UNSIGNED_INT, 0);
} }

View File

@ -12,7 +12,6 @@ namespace Graphics::GL {
ArrayBuffer m_ebo; ArrayBuffer m_ebo;
unsigned int m_size; unsigned int m_size;
void bind() const;
void set(const Mesh& mesh, int usage); void set(const Mesh& mesh, int usage);
void render(int mode) const; void render(int mode) const;
}; };

View File

@ -6,7 +6,7 @@
using Graphics::GL::RenderBuffer; using Graphics::GL::RenderBuffer;
RenderBuffer::RenderBuffer() { RenderBuffer::RenderBuffer() {
glGenRenderbuffers(1, &m_handle); glCreateRenderbuffers(1, &m_handle);
} }
RenderBuffer::RenderBuffer(RenderBuffer&& o) : BufferBase(std::move(o)) { RenderBuffer::RenderBuffer(RenderBuffer&& o) : BufferBase(std::move(o)) {

View File

@ -5,8 +5,8 @@
using Graphics::GL::Texture; using Graphics::GL::Texture;
Texture::Texture() { Texture::Texture(int type) {
glGenTextures(1, &m_handle); glCreateTextures(type, 1, &m_handle);
} }
Texture::Texture(Texture&& o) : BufferBase(std::move(o)) { Texture::Texture(Texture&& o) : BufferBase(std::move(o)) {

View File

@ -4,7 +4,7 @@
#include "buffer_base.hpp" #include "buffer_base.hpp"
namespace Graphics::GL { namespace Graphics::GL {
struct Texture : BufferBase { struct Texture : BufferBase {
Texture(); Texture(int type);
Texture(Texture&& o); Texture(Texture&& o);
~Texture(); ~Texture();
}; };

View File

@ -6,7 +6,7 @@
using Graphics::GL::VertexArray; using Graphics::GL::VertexArray;
VertexArray::VertexArray() { VertexArray::VertexArray() {
glGenVertexArrays(1, &m_handle); glCreateVertexArrays(1, &m_handle);
} }
VertexArray::VertexArray(VertexArray&& o) : BufferBase(std::move(o)) { VertexArray::VertexArray(VertexArray&& o) : BufferBase(std::move(o)) {

View File

@ -0,0 +1,76 @@
#include "particles.hpp"
#include "context.hpp"
#include "pipeline.hpp"
#include "shader.hpp"
#include "vertex.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using Graphics::Particles;
struct InfoType {
float m_time;
int m_size;
};
Particles::Particles() {
m_time_started = glfwGetTime();
glNamedBufferStorage(m_ssbo_particles, sizeof(Type) * MAX_PARTICLES, nullptr, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
glNamedBufferData(m_ssbo_vertices, sizeof(Vertex) * MAX_PARTICLES, nullptr, GL_DYNAMIC_COPY);
glNamedBufferData(m_ubo_info, sizeof(InfoType), nullptr, GL_DYNAMIC_DRAW);
m_particles_mapping = (Type*)glMapNamedBuffer(m_ssbo_particles, GL_READ_WRITE);
auto b = m_vao.bind();
glBindBuffer(GL_ARRAY_BUFFER, m_ssbo_vertices);
Vertex::set_vertex_attribs();
}
void Particles::update(const Pipeline& pipeline) {
double now = get_time_diff();
int j = 0;
for(int i = 0; i < m_particles_mapping_size; i++) {
Type& p = m_particles_mapping[i];
if(p.m_time_start + p.m_duration < now) {
if(i > j) {
m_particles_mapping[j] = m_particles_mapping[i];
}
j++;
}
}
m_particles_mapping_size = j;
InfoType info {
.m_time = (float)now,
.m_size = m_particles_mapping_size,
};
glNamedBufferSubData(m_ubo_info, 0, sizeof(InfoType), &info);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_IN, m_ssbo_particles);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_OUT, m_ssbo_vertices);
glBindBufferBase(GL_UNIFORM_BUFFER, Shader::UBO_PARTICLES_INFO, m_ubo_info);
glUseProgram(pipeline.m_program_particles);
glDispatchCompute(m_particles_mapping_size, 1, 1);
}
void Particles::render(const Context& ctx) const {
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
ctx.set_colour_matrix(glm::mat4(1));
ctx.set_model_matrix(glm::mat4(1));
auto b = m_vao.bind();
glDrawArrays(GL_POINTS, 0, m_particles_mapping_size);
}
void Particles::add(const Type& type) {
if(m_particles_mapping_size < MAX_PARTICLES) {
m_particles_mapping[m_particles_mapping_size++] = type;
}
}
double Particles::get_time_diff() {
return m_time_started - glfwGetTime();
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "context.hpp"
#include "gl/array_buffer.hpp"
#include "gl/vertex_array.hpp"
#include <glm/matrix.hpp>
namespace Graphics {
struct Pipeline;
struct Particles {
struct Type {
glm::vec3 m_pos;
float m_random_velocity_scale;
glm::vec3 m_velocity;
float m_random_colour_scale;
glm::vec4 m_colour;
float m_time_start;
float m_duration;
float m_size;
int m_seed;
};
static_assert(sizeof(Type) == 64);
static constexpr int MAX_PARTICLES = 1024;
GL::VertexArray m_vao;
GL::ArrayBuffer m_ssbo_particles;
GL::ArrayBuffer m_ssbo_vertices;
GL::ArrayBuffer m_ubo_info;
Type* m_particles_mapping;
int m_particles_mapping_size = 0;
double m_time_started;
Particles();
void add(const Type& type);
double get_time_diff();
void update(const Pipeline& pipeline);
void render(const Context& ctx) const;
};
};

View File

@ -10,28 +10,30 @@
using Graphics::Pipeline; using Graphics::Pipeline;
Pipeline::Pipeline() { Pipeline::Pipeline() {
Graphics::GL::Shader model_vert(GL_VERTEX_SHADER); Graphics::GL::Shader model_vert = Graphics::Shader::compile_new(GL_VERTEX_SHADER, "model.vert");
Graphics::GL::Shader model_frag(GL_FRAGMENT_SHADER); Graphics::GL::Shader model_frag = Graphics::Shader::compile_new(GL_FRAGMENT_SHADER, "model.frag");
Graphics::Shader::compile(model_vert, "model.vert"); Graphics::GL::Shader particles_comp = Graphics::Shader::compile_new(GL_COMPUTE_SHADER, "particles.comp");
Graphics::Shader::compile(model_frag, "model.frag");
Graphics::Shader::link(m_program_model, {model_vert, model_frag}); Graphics::Shader::link(m_program_model, {model_vert, model_frag});
Graphics::Shader::link(m_program_particles, {particles_comp});
} }
bool Pipeline::should_close() const { bool Pipeline::should_close() const {
return m_window.should_close(); return m_window.should_close();
} }
void Pipeline::update() const { void Pipeline::update() {
m_window.update(); m_window.update();
m_particles.update(*this);
} }
void Pipeline::render(const World::State& state, const Context& ctx) const { void Pipeline::render(const World::State& state, const Context& ctx) const {
glUseProgram(m_program_model); glUseProgram(m_program_model);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClearColor(0.1, 0.1, 0.12, 1); glClearColor(0.1, 0.1, 0.12, 1);
state.render(ctx); state.render(ctx);
m_particles.render(ctx);
m_window.swap_buffers(); m_window.swap_buffers();
} }

View File

@ -3,16 +3,19 @@
#include "context.hpp" #include "context.hpp"
#include "gl/program.hpp" #include "gl/program.hpp"
#include "particles.hpp"
#include "window.hpp" #include "window.hpp"
#include "../world/state.hpp" #include "../world/state.hpp"
namespace Graphics { namespace Graphics {
struct Pipeline { struct Pipeline {
Window m_window; Window m_window;
Particles m_particles;
GL::Program m_program_model; GL::Program m_program_model;
GL::Program m_program_particles;
Pipeline(); Pipeline();
void update() const; void update();
void render(const World::State& state, const Context& ctx) const; void render(const World::State& state, const Context& ctx) const;
bool should_close() const; bool should_close() const;

View File

@ -3,6 +3,9 @@
namespace Graphics::Shader { namespace Graphics::Shader {
constexpr int SSBO_ATLAS_BUFFER = 1; constexpr int SSBO_ATLAS_BUFFER = 1;
constexpr int SSBO_PARTICLES_IN = 2;
constexpr int SSBO_PARTICLES_OUT = 3;
constexpr int UBO_PARTICLES_INFO = 4;
constexpr int TEX_ATLAS = 1; constexpr int TEX_ATLAS = 1;
}; };

View File

@ -142,3 +142,9 @@ void Graphics::Shader::compile(unsigned int shader, const char* filename) {
} }
} }
Graphics::GL::Shader Graphics::Shader::compile_new(int type, const char* filename) {
GL::Shader shader(type);
compile(shader, filename);
return shader;
}

View File

@ -1,7 +1,10 @@
#pragma once #pragma once
#include "../gl/shader.hpp"
namespace Graphics::Shader { namespace Graphics::Shader {
void compile(unsigned int shader, const char* path); void compile(unsigned int shader, const char* path);
GL::Shader compile_new(int type, const char* path);
}; };

View File

@ -21,3 +21,9 @@ void Graphics::Shader::link(unsigned int program, const std::vector<unsigned int
} }
} }
Graphics::GL::Program Graphics::Shader::link_new(const std::vector<unsigned int> &shaders) {
GL::Program program;
link(program, shaders);
return program;
}

View File

@ -2,8 +2,10 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "../gl/program.hpp"
namespace Graphics::Shader { namespace Graphics::Shader {
void link(unsigned int program, const std::vector<unsigned int>& shaders); void link(unsigned int program, const std::vector<unsigned int>& shaders);
GL::Program link_new(const std::vector<unsigned int>& shaders);
} }

View File

@ -4,12 +4,14 @@
#include "texture/image.hpp" #include "texture/image.hpp"
namespace Graphics::Texture { namespace Graphics::Texture {
inline Image YELLOW_BRICK_WALL {"yellow_brick_wall.png", Image::Edge::CLAMP}; inline Image MISSING {"missing.png", Image::Edge::REPEATING};
inline Image WHITE {"white.png", Image::Edge::REPEATING};
inline Image YELLOW_BRICK_WALL {"yellow_brick_wall.png", Image::Edge::REPEATING};
inline Image* const IMAGES[] { inline Image* const IMAGES[] {
&MISSING,
&WHITE,
&YELLOW_BRICK_WALL, &YELLOW_BRICK_WALL,
}; };
void generate_atlas();
}; };

View File

@ -71,13 +71,11 @@ void Graphics::Texture::generate_atlas() {
} }
} }
static GL::ArrayBuffer ssbo_id;
static GL::Texture tex_id;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_id);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(UV) * uvs.size(), uvs.data(), GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Graphics::Shader::SSBO_ATLAS_BUFFER, ssbo_id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Graphics::Shader::SSBO_ATLAS_BUFFER, ssbo_id);
glNamedBufferData(ssbo_id, sizeof(UV) * uvs.size(), uvs.data(), GL_STATIC_DRAW);
glTextureStorage2D(tex_id,
glActiveTexture(GL_TEXTURE0 + Graphics::Shader::TEX_ATLAS); glActiveTexture(GL_TEXTURE0 + Graphics::Shader::TEX_ATLAS);
glBindTexture(GL_TEXTURE_2D_ARRAY, tex_id); glBindTexture(GL_TEXTURE_2D_ARRAY, tex_id);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, atlas.m_size.x, atlas.m_size.y, atlas.m_size.z, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas.m_data.data()); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, atlas.m_size.x, atlas.m_size.y, atlas.m_size.z, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas.m_data.data());

View File

@ -0,0 +1,15 @@
#pragma once
#include "../gl/array_buffer.hpp"
#include "../gl/texture.hpp"
namespace Graphics::Texture {
struct GeneratedAtlas {
GL::ArrayBuffer m_ssbo_id;
GL::Texture m_tex_id;
};
GeneratedAtlas generate_atlas();
};

View File

@ -1,6 +1,6 @@
#include "image.hpp" #include "image.hpp"
#include <cassert> #include "../../util/debug.hpp"
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <stb/stb_image.h> #include <stb/stb_image.h>
@ -46,13 +46,13 @@ unsigned char* Image::get(glm::vec<2, int> pos) const {
} }
void Image::clear_host() { void Image::clear_host() {
assert(m_data); CHECK(m_data);
free(m_data); free(m_data);
m_data = nullptr; m_data = nullptr;
} }
Image::operator unsigned int() { Image::operator unsigned int() {
assert(m_id != -1); CHECK(m_id != -1);
return m_id; return m_id;
} }

View File

@ -6,8 +6,8 @@
namespace Graphics::Texture { namespace Graphics::Texture {
struct Image { struct Image {
enum Edge : int { enum Edge : int {
CLAMP = 0, REPEATING = 0,
REPEATING = 1, CLAMP = 1,
}; };
unsigned char* m_data; unsigned char* m_data;

View File

@ -5,16 +5,17 @@
using Graphics::Vertex; using Graphics::Vertex;
void Vertex::set_vertex_attribs() { void Vertex::set_vertex_attribs(unsigned int vao, unsigned int vbo) {
Vertex v; Vertex v;
glVertexAttribPointer(0, 4, GL_FLOAT, false, sizeof(v), (void*)Util::pointer_diff(&v, &v.m_pos)); glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(v));
glVertexAttribPointer(1, 4, GL_FLOAT, false, sizeof(v), (void*)Util::pointer_diff(&v, &v.m_colour)); glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_pos));
glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(v), (void*)Util::pointer_diff(&v, &v.m_uv)); glVertexArrayAttribFormat(vao, 1, 4, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_pos));
glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, sizeof(v), (void*)Util::pointer_diff(&v, &v.m_texid)); glVertexArrayAttribFormat(vao, 2, 2, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_pos));
glVertexArrayAttribIFormat(vao, 3, 1, GL_UNSIGNED_INT, Util::pointer_diff(&v, &v.m_pos));
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
glEnableVertexAttribArray(i); glVertexArrayAttribBinding(vao, i, 0);
} }
} }

View File

@ -9,8 +9,11 @@ namespace Graphics {
glm::vec4 m_colour = {1, 1, 1, 1}; glm::vec4 m_colour = {1, 1, 1, 1};
glm::vec2 m_uv; glm::vec2 m_uv;
unsigned int m_texid = 0; unsigned int m_texid = 0;
int _padding_1 = 0;
static void set_vertex_attribs(); static void set_vertex_attribs(unsigned int vao, unsigned int vbo);
}; };
static_assert(sizeof(Vertex) == 48);
}; };

16
src/util/debug.hpp Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <cassert>
#ifdef NO_DEBUG
#define DEBUG(f)
#define CHECK(f) f
#define CHECK_DEBUG(f)
#else
#define DEBUG(f) f
#define CHECK(f) assert(f)
#define CHECK_DEBUG(f) assert(f)
#endif

View File

@ -1,12 +1,12 @@
#include "pointer_diff.hpp" #include "pointer_diff.hpp"
#include <cassert> #include "debug.hpp"
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
uint64_t Util::pointer_diff(void* a, void* b) { uint64_t Util::pointer_diff(void* a, void* b) {
assert(a); CHECK(a);
assert(b); CHECK(b);
return std::abs((int64_t)a - (int64_t)b); return std::abs((int64_t)a - (int64_t)b);
} }

View File

@ -27,9 +27,7 @@ Builder::Builder() {
mesh.add_primitive(prim); mesh.add_primitive(prim);
} }
m_model.bind();
m_model.set(mesh, GL_STATIC_DRAW); m_model.set(mesh, GL_STATIC_DRAW);
Graphics::Vertex::set_vertex_attribs();
} }
void Builder::update(Map& map, const Graphics::Context& ctx) { void Builder::update(Map& map, const Graphics::Context& ctx) {
@ -92,7 +90,6 @@ void Builder::render(const Graphics::Context& ctx) const {
break; break;
} }
m_model.bind();
m_model.render(GL_TRIANGLES); m_model.render(GL_TRIANGLES);
} }

View File

@ -19,8 +19,6 @@ constexpr glm::vec<2, int> get_pos_mod(glm::vec<2, int> pos) {
Chunk::Chunk(glm::vec<2, int> pos) { Chunk::Chunk(glm::vec<2, int> pos) {
m_pos = pos; m_pos = pos;
m_model.bind();
Graphics::Vertex::set_vertex_attribs();
} }
TileBase* Chunk::get(glm::vec<2, int> p) { TileBase* Chunk::get(glm::vec<2, int> p) {
@ -81,7 +79,7 @@ void Chunk::update(Map& map) {
auto prim = PRIMITIVE_B; auto prim = PRIMITIVE_B;
prim.m_offset = {t_off, 0, 0}; prim.m_offset = {t_off, 0, 0};
prim.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; prim.m_texid = Graphics::Texture::MISSING;
mesh.add_primitive(prim); mesh.add_primitive(prim);
for(int i = 0; i < std::size(neighbours); i++) { for(int i = 0; i < std::size(neighbours); i++) {
@ -105,7 +103,6 @@ void Chunk::update(Map& map) {
} }
} }
} }
m_model.bind();
m_model.set(mesh, GL_DYNAMIC_DRAW); m_model.set(mesh, GL_DYNAMIC_DRAW);
m_dirty = false; m_dirty = false;
} }
@ -113,8 +110,8 @@ void Chunk::update(Map& map) {
void Chunk::render(const Graphics::Context& ctx) const { void Chunk::render(const Graphics::Context& ctx) const {
ctx.set_model_matrix(glm::translate(glm::mat4(1), {glm::vec<2, double>(m_pos) - ctx.m_transform, 0})); ctx.set_model_matrix(glm::translate(glm::mat4(1), {glm::vec<2, double>(m_pos) - ctx.m_transform, 0}));
ctx.set_colour_matrix(glm::mat4(1)); ctx.set_colour_matrix(glm::mat4(1));
m_model.bind();
m_model.render(GL_TRIANGLES); m_model.render(GL_TRIANGLES);
for(auto& tile : m_tiles) { for(auto& tile : m_tiles) {
if(tile) { if(tile) {
tile->render(); tile->render();