From a89ef8ddde58158c13567ce351e878cb2bfaa449 Mon Sep 17 00:00:00 2001 From: Daniel Ledda Date: Sun, 16 Feb 2025 23:43:10 +0100 Subject: [PATCH] update --- assets/shaders/2d-solid.fragment.glsl | 6 +- assets/shaders/2d-solid.vertex.glsl | 29 +++ .../{2d.vertex.glsl => 2d-tex.vertex.glsl} | 0 src/gfx/Mesh.cpp | 21 +- src/gfx/Mesh.h | 13 +- src/lib/djstdlib | 2 +- src/main.cpp | 210 ++++++++++++++---- 7 files changed, 215 insertions(+), 66 deletions(-) create mode 100644 assets/shaders/2d-solid.vertex.glsl rename assets/shaders/{2d.vertex.glsl => 2d-tex.vertex.glsl} (100%) diff --git a/assets/shaders/2d-solid.fragment.glsl b/assets/shaders/2d-solid.fragment.glsl index 1d43329..2995a9d 100644 --- a/assets/shaders/2d-solid.fragment.glsl +++ b/assets/shaders/2d-solid.fragment.glsl @@ -1,10 +1,8 @@ #version 330 core out vec4 frag_color; -uniform vec3 color; - -in vec2 uv; +in vec4 fragment_color; void main() { - frag_color = vec4(color, 0.0); + frag_color = fragment_color; }; diff --git a/assets/shaders/2d-solid.vertex.glsl b/assets/shaders/2d-solid.vertex.glsl new file mode 100644 index 0000000..1e5308e --- /dev/null +++ b/assets/shaders/2d-solid.vertex.glsl @@ -0,0 +1,29 @@ +#version 330 core +layout (location = 0) in vec2 p0; +layout (location = 1) in vec2 p1; +layout (location = 2) in vec4 color; + +uniform mat4 projection; + +out vec4 fragment_color; + +const vec2 rectangle_vertices[4] = vec2[]( + vec2(-1, -1), + vec2(-1, 1), + vec2( 1, -1), + vec2( 1, 1) +); + +void main() { + vec2 dest_half_size = (p1 - p0) / 2; + vec2 dest_center = (p1 + p0) / 2; + vec2 dest_position = rectangle_vertices[gl_VertexID] * dest_half_size + dest_center; + + gl_Position = projection * vec4( + dest_position, + 0, + 1 + ); + + fragment_color = color; +} diff --git a/assets/shaders/2d.vertex.glsl b/assets/shaders/2d-tex.vertex.glsl similarity index 100% rename from assets/shaders/2d.vertex.glsl rename to assets/shaders/2d-tex.vertex.glsl diff --git a/src/gfx/Mesh.cpp b/src/gfx/Mesh.cpp index 03c0108..f1bf9b3 100644 --- a/src/gfx/Mesh.cpp +++ b/src/gfx/Mesh.cpp @@ -60,24 +60,21 @@ Mesh createMesh(const char* obj_file) { result.num_indices = attrib.num_faces*3; glGenVertexArrays(1, &result.vao); - glGenBuffers(1, &result.vbo_xyz); - glGenBuffers(1, &result.vbo_uv); - glGenBuffers(1, &result.vbo_norm); - //glGenBuffers(1, &ebo); + glGenBuffers(3, result.vbos); glBindVertexArray(result.vao); - glBindBuffer(GL_ARRAY_BUFFER, result.vbo_xyz); + glBindBuffer(GL_ARRAY_BUFFER, result.buffers.xyz); glBufferData(GL_ARRAY_BUFFER, vertices.length * sizeof(float), vertices.data, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, result.vbo_uv); + glBindBuffer(GL_ARRAY_BUFFER, result.buffers.uv); glBufferData(GL_ARRAY_BUFFER, texcoords.length * sizeof(float), texcoords.data, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, result.vbo_norm); + glBindBuffer(GL_ARRAY_BUFFER, result.buffers.normals); glBufferData(GL_ARRAY_BUFFER, normals.length * sizeof(float), normals.data, GL_STATIC_DRAW); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(2); @@ -94,23 +91,21 @@ Mesh createMesh(const Shape* shape) { result.num_indices = shape->indices_size; glGenVertexArrays(1, &result.vao); - glGenBuffers(1, &result.vbo_xyz); - glGenBuffers(1, &result.vbo_uv); - glGenBuffers(1, &result.ebo); + glGenBuffers(3, result.vbos); glBindVertexArray(result.vao); - glBindBuffer(GL_ARRAY_BUFFER, result.vbo_xyz); + glBindBuffer(GL_ARRAY_BUFFER, result.buffers.xyz); glBufferData(GL_ARRAY_BUFFER, shape->xyz_size * sizeof(float), shape->xyz, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, result.vbo_uv); + glBindBuffer(GL_ARRAY_BUFFER, result.buffers.uv); glBufferData(GL_ARRAY_BUFFER, shape->uv_size * sizeof(float), shape->uv, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.buffers.elements); glBufferData(GL_ELEMENT_ARRAY_BUFFER, shape->indices_size * sizeof(unsigned int), shape->indices, GL_STATIC_DRAW); return result; diff --git a/src/gfx/Mesh.h b/src/gfx/Mesh.h index d010bc3..91ba60a 100644 --- a/src/gfx/Mesh.h +++ b/src/gfx/Mesh.h @@ -7,10 +7,15 @@ struct Mesh { uint32 vao; - uint32 vbo_xyz; - uint32 vbo_uv; - uint32 vbo_norm; - uint32 ebo; + union { + struct { + uint32 xyz; + uint32 uv; + uint32 normals; + uint32 elements; + } buffers; + uint32 vbos[4]; + }; uint64 num_indices; }; diff --git a/src/lib/djstdlib b/src/lib/djstdlib index f12b409..ea2ddf6 160000 --- a/src/lib/djstdlib +++ b/src/lib/djstdlib @@ -1 +1 @@ -Subproject commit f12b4091d7245f20405ea0b9deddf2ace6775262 +Subproject commit ea2ddf60f3f249eb0decd204bc0b325389404964 diff --git a/src/main.cpp b/src/main.cpp index 3b05702..62d99c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,6 +116,7 @@ struct Frame { struct Polycube { int graph_node; + Space repr; glm::vec3 color; }; @@ -223,9 +224,12 @@ void update_viewport_from_frame(WindowDims* window_dims, Frame* frame) { glViewport(frame->x, window_dims->height - frame->y - frame->height, frame->width, frame->height); } -Mesh sprite_mesh = {0}; Mesh cube_mesh = {0}; Texture wall_tex = {0}; + +Shader solid_color_shader; +Shader phong_shader; + std::vector entities = std::vector(); std::vector scene_graph_nodes = std::vector(); @@ -371,6 +375,7 @@ Polycube create_polycube_from_repr(Space *repr) { Polycube result = {}; result.graph_node = polycube_id; result.color = glm::vec3(1.0f); + result.repr = *repr; return result; } @@ -386,17 +391,157 @@ void recalculate_scene_graph(SceneGraphNode *top) { } } -void draw_rectangle(int x, int y, int width, int height, glm::vec3 color) { - setUniform3fv(app_state.active_shader, "color", &color); - glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0); - setUniformMat4fv(app_state.active_shader, "projection", &ortho); - glBindVertexArray(sprite_mesh.vao); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)sprite_mesh.num_indices); +struct RenderObjects_Rectangle { + uint32 vao; + list> p0; + uint32 p0BufferId; + list> p1; + uint32 p1BufferId; + list> color; + uint32 colorBufferId; + uint64 count; +}; + +struct Renderer { + uint32 scene_root; + RenderObjects_Rectangle rects; +}; + +RenderObjects_Rectangle createRectangleObjects(Arena *arena, size_t count) { + RenderObjects_Rectangle result = {0}; + result.count = count; + + result.p0 = PushFullList(arena, Vector2, count); + result.p1 = PushFullList(arena, Vector2, count); + result.color = PushFullList(arena, Vector4, count); + + glGenVertexArrays(1, &result.vao); + + uint32 p0Buffer; + uint32 p1Buffer; + uint32 colorBuffer; + + glGenBuffers(1, &result.p0BufferId); + glGenBuffers(1, &result.p1BufferId); + glGenBuffers(1, &result.colorBufferId); + + glBindVertexArray(result.vao); + + glBindBuffer(GL_ARRAY_BUFFER, result.p0BufferId); + glBufferData(GL_ARRAY_BUFFER, result.p0.length * sizeof(Vector2), 0, GL_DYNAMIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), (void*)0); + glVertexAttribDivisor(0, 1); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, result.p1BufferId); + glBufferData(GL_ARRAY_BUFFER, result.p1.length * sizeof(Vector2), 0, GL_DYNAMIC_DRAW); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), (void*)0); + glVertexAttribDivisor(1, 1); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, result.colorBufferId); + glBufferData(GL_ARRAY_BUFFER, result.color.length * sizeof(Vector4), 0, GL_DYNAMIC_DRAW); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4), (void*)0); + glVertexAttribDivisor(2, 1); + glEnableVertexAttribArray(2); + + return result; } -void draw_ui() { +void reinitRectangleObjectBuffers(Renderer *r) { + glBindVertexArray(r->rects.vao); + + glBindBuffer(GL_ARRAY_BUFFER, r->rects.p0BufferId); + glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.p0.head * sizeof(Vector2), r->rects.p0.data); + + glBindBuffer(GL_ARRAY_BUFFER, r->rects.p1BufferId); + glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.p1.head * sizeof(Vector2), r->rects.p1.data); + + glBindBuffer(GL_ARRAY_BUFFER, r->rects.colorBufferId); + glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.color.head * sizeof(Vector4), r->rects.color.data); +} + +Renderer createRenderer(Arena *arena) { + Renderer result = {0}; + result.rects = createRectangleObjects(arena, 100); + result.scene_root = new_graph_node(); + init_sg_node(get_scene_graph_node(result.scene_root)); + return result; +} + +void renderBegin(Renderer *r) { + r->rects.p0.head = 0; + r->rects.p1.head = 0; + r->rects.color.head = 0; +} + +void renderEnd(Renderer *r) { + // 3D Entities + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube]; + glBindVertexArray(cube_mesh.vao); + + setUniform3fv(app_state.active_shader, "solid_color", ¤t_polycube->color); + int model_uniform = getUniformLocation(app_state.active_shader, "model"); + for (Entity &entity : entities) { + if (entity.visible) { + setUniformMat4fv(model_uniform, &get_scene_graph_node(entity.scene_graph_node)->world); + glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices); + } + } + + // 2D overlay + Shader *last_shader = app_state.active_shader; + app_state.active_shader = &solid_color_shader; + glUseProgram(app_state.active_shader->prog_id); - draw_rectangle(20, 20, 100, 100, glm::vec3( 1, 0, 0 )); + + reinitRectangleObjectBuffers(r); + + glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0); + setUniformMat4fv(app_state.active_shader, "projection", &ortho); + + glBindVertexArray(r->rects.vao); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->rects.p0.head); + + app_state.active_shader = last_shader; +} + +void placeRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, Vector4 color) { + appendList(&r->rects.p0, vec2(x, y)); + appendList(&r->rects.p1, vec2(x + width, y + height)); + appendList(&r->rects.color, color); +} + +void drawUI(Renderer *renderer) { + Polycube currentPolycube = app_state.polycubes[app_state.current_polycube]; + Vector4 currPolycubeColor = vec4(currentPolycube.color.x, currentPolycube.color.y, currentPolycube.color.z, 1); + Vector4 white = vec4(1, 1, 1, 1); + + Space repr = currentPolycube.repr; + int boxSize = 30; + int padding = 20; + int paddingBetween = 5; + int currY = padding; + for (int x = 0; x < repr.dim_x; x++) { + for (int y = 0; y < repr.dim_y; y++) { + int currX = padding; + for (int z = 0; z < repr.dim_z; z++) { + placeRectangle(renderer, + currX, + currY, + boxSize, + boxSize, + filledAt(¤tPolycube.repr, x, y, z) ? currPolycubeColor : white); + currX += paddingBetween + boxSize; + } + currY += paddingBetween + boxSize; + } + currY += padding; + } } int main_cmd() { @@ -413,7 +558,7 @@ int main_gfx() { return -1; } - Frame main_frame = createFrame(arena, 800, 600, 0, 0); + Frame main_frame = createFrame(arena, window_dims.width, window_dims.height, 0, 0); app_state.current_polycube = 0; app_state.last_polycube_visible = 6; @@ -431,22 +576,20 @@ int main_gfx() { "./assets/shaders/2d-tex.fragment.glsl"_s); */ - Shader solid_color_shader = createShader( - "./assets/shaders/2d.vertex.glsl"_s, + solid_color_shader = createShader( + "./assets/shaders/2d-solid.vertex.glsl"_s, "./assets/shaders/2d-solid.fragment.glsl"_s); - Shader phong_shader = createShader( + phong_shader = createShader( "./assets/shaders/phong-solid.vertex.glsl"_s, "./assets/shaders/phong-solid.fragment.glsl"_s); app_state.active_shader = &phong_shader; - sprite_mesh = createMesh(&SQUARE); cube_mesh = createMesh("./assets/models/cube.obj"); wall_tex = createTexture("./assets/textures/brick-wall.jpg"); - SceneGraphNode root_node = {}; - init_sg_node(&root_node); + Renderer renderer = createRenderer(arena); for (int i = 0; i < ArrayCount(STD_SOMA); i++) { Space voxel_space = { STD_SOMA[i], 3, 3, 3 }; @@ -454,7 +597,7 @@ int main_gfx() { Polycube polycube = create_polycube_from_repr(&voxel_space); polycube.color = color_from_index(i); app_state.polycubes.push_back(polycube); - root_node.children.push_back(app_state.polycubes.back().graph_node); + get_scene_graph_node(renderer.scene_root)->children.push_back(app_state.polycubes.back().graph_node); } app_state.camera->pos = glm::vec3(0.0f, 0.0f, 8.0f); @@ -472,15 +615,12 @@ int main_gfx() { } glUseProgram(app_state.active_shader->prog_id); - setUniformMat4fv(app_state.active_shader, "projection", &main_frame.cam->proj); setUniformMat4fv(app_state.active_shader, "view", &main_frame.cam->view); real64 last_frame = glfwGetTime(); real64 time_delta = 1.0f/60.0f; - recalculate_scene_graph(&root_node); - glm::vec3 lastLightPos = {}; Input prevInput = {}; while (!glfwWindowShouldClose(window)) { @@ -491,8 +631,8 @@ int main_gfx() { glUseProgram(app_state.active_shader->prog_id); SceneGraphNode *light_graph_node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node); - setUniform3fv(app_state.active_shader, "light_pos", &light_graph_node->translation); - setUniform3fv(app_state.active_shader, "camera", &main_frame.cam->pos); + setUniform3fv(&phong_shader, "light_pos", &light_graph_node->translation); + setUniform3fv(&phong_shader, "camera", &main_frame.cam->pos); if (app_state.last_polycube_visible != app_state.current_polycube) { hide_polycube(&app_state.polycubes[app_state.last_polycube_visible]); @@ -500,30 +640,12 @@ int main_gfx() { app_state.last_polycube_visible = app_state.current_polycube; } - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - update_viewport_from_frame(&window_dims, &main_frame); + recalculate_scene_graph(get_scene_graph_node(renderer.scene_root)); - Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube]; - - glBindVertexArray(cube_mesh.vao); - recalculate_scene_graph(&root_node); - - setUniform3fv(app_state.active_shader, "solid_color", ¤t_polycube->color); - int model_uniform = getUniformLocation(app_state.active_shader, "model"); - for (Entity &entity : entities) { - if (entity.visible) { - setUniformMat4fv(model_uniform, &get_scene_graph_node(entity.scene_graph_node)->world); - glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices); - } - } - - app_state.active_shader = &solid_color_shader; - draw_ui(); - app_state.active_shader = &phong_shader; - + renderBegin(&renderer); + drawUI(&renderer); + renderEnd(&renderer); glfwSwapBuffers(window); prevInput = input;