This commit is contained in:
Daniel Ledda
2025-02-16 23:43:10 +01:00
parent f250254ae3
commit a89ef8ddde
7 changed files with 215 additions and 66 deletions

View File

@@ -1,10 +1,8 @@
#version 330 core #version 330 core
out vec4 frag_color; out vec4 frag_color;
uniform vec3 color; in vec4 fragment_color;
in vec2 uv;
void main() { void main() {
frag_color = vec4(color, 0.0); frag_color = fragment_color;
}; };

View File

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

View File

@@ -60,24 +60,21 @@ Mesh createMesh(const char* obj_file) {
result.num_indices = attrib.num_faces*3; result.num_indices = attrib.num_faces*3;
glGenVertexArrays(1, &result.vao); glGenVertexArrays(1, &result.vao);
glGenBuffers(1, &result.vbo_xyz); glGenBuffers(3, result.vbos);
glGenBuffers(1, &result.vbo_uv);
glGenBuffers(1, &result.vbo_norm);
//glGenBuffers(1, &ebo);
glBindVertexArray(result.vao); 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); 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); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(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); 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); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1); 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); 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); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
@@ -94,23 +91,21 @@ Mesh createMesh(const Shape* shape) {
result.num_indices = shape->indices_size; result.num_indices = shape->indices_size;
glGenVertexArrays(1, &result.vao); glGenVertexArrays(1, &result.vao);
glGenBuffers(1, &result.vbo_xyz); glGenBuffers(3, result.vbos);
glGenBuffers(1, &result.vbo_uv);
glGenBuffers(1, &result.ebo);
glBindVertexArray(result.vao); 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); 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); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(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); 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); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1); 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); glBufferData(GL_ELEMENT_ARRAY_BUFFER, shape->indices_size * sizeof(unsigned int), shape->indices, GL_STATIC_DRAW);
return result; return result;

View File

@@ -7,10 +7,15 @@
struct Mesh { struct Mesh {
uint32 vao; uint32 vao;
uint32 vbo_xyz; union {
uint32 vbo_uv; struct {
uint32 vbo_norm; uint32 xyz;
uint32 ebo; uint32 uv;
uint32 normals;
uint32 elements;
} buffers;
uint32 vbos[4];
};
uint64 num_indices; uint64 num_indices;
}; };

View File

@@ -116,6 +116,7 @@ struct Frame {
struct Polycube { struct Polycube {
int graph_node; int graph_node;
Space repr;
glm::vec3 color; 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); glViewport(frame->x, window_dims->height - frame->y - frame->height, frame->width, frame->height);
} }
Mesh sprite_mesh = {0};
Mesh cube_mesh = {0}; Mesh cube_mesh = {0};
Texture wall_tex = {0}; Texture wall_tex = {0};
Shader solid_color_shader;
Shader phong_shader;
std::vector<Entity> entities = std::vector<Entity>(); std::vector<Entity> entities = std::vector<Entity>();
std::vector<SceneGraphNode> scene_graph_nodes = std::vector<SceneGraphNode>(); std::vector<SceneGraphNode> scene_graph_nodes = std::vector<SceneGraphNode>();
@@ -371,6 +375,7 @@ Polycube create_polycube_from_repr(Space *repr) {
Polycube result = {}; Polycube result = {};
result.graph_node = polycube_id; result.graph_node = polycube_id;
result.color = glm::vec3(1.0f); result.color = glm::vec3(1.0f);
result.repr = *repr;
return result; 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) { struct RenderObjects_Rectangle {
setUniform3fv(app_state.active_shader, "color", &color); uint32 vao;
glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0); list<Vector2<real32>> p0;
setUniformMat4fv(app_state.active_shader, "projection", &ortho); uint32 p0BufferId;
glBindVertexArray(sprite_mesh.vao); list<Vector2<real32>> p1;
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)sprite_mesh.num_indices); uint32 p1BufferId;
list<Vector4<real32>> 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<real32>, count);
result.p1 = PushFullList(arena, Vector2<real32>, count);
result.color = PushFullList(arena, Vector4<real32>, 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<real32>), 0, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2<real32>), (void*)0);
glVertexAttribDivisor(0, 1);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, result.p1BufferId);
glBufferData(GL_ARRAY_BUFFER, result.p1.length * sizeof(Vector2<real32>), 0, GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2<real32>), (void*)0);
glVertexAttribDivisor(1, 1);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, result.colorBufferId);
glBufferData(GL_ARRAY_BUFFER, result.color.length * sizeof(Vector4<real32>), 0, GL_DYNAMIC_DRAW);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4<real32>), (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<real32>), r->rects.p0.data);
glBindBuffer(GL_ARRAY_BUFFER, r->rects.p1BufferId);
glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.p1.head * sizeof(Vector2<real32>), r->rects.p1.data);
glBindBuffer(GL_ARRAY_BUFFER, r->rects.colorBufferId);
glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.color.head * sizeof(Vector4<real32>), 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", &current_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); 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<real32> color) {
appendList(&r->rects.p0, vec2<real32>(x, y));
appendList(&r->rects.p1, vec2<real32>(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<real32>(currentPolycube.color.x, currentPolycube.color.y, currentPolycube.color.z, 1);
Vector4 white = vec4<real32>(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(&currentPolycube.repr, x, y, z) ? currPolycubeColor : white);
currX += paddingBetween + boxSize;
}
currY += paddingBetween + boxSize;
}
currY += padding;
}
} }
int main_cmd() { int main_cmd() {
@@ -413,7 +558,7 @@ int main_gfx() {
return -1; 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.current_polycube = 0;
app_state.last_polycube_visible = 6; app_state.last_polycube_visible = 6;
@@ -431,22 +576,20 @@ int main_gfx() {
"./assets/shaders/2d-tex.fragment.glsl"_s); "./assets/shaders/2d-tex.fragment.glsl"_s);
*/ */
Shader solid_color_shader = createShader( solid_color_shader = createShader(
"./assets/shaders/2d.vertex.glsl"_s, "./assets/shaders/2d-solid.vertex.glsl"_s,
"./assets/shaders/2d-solid.fragment.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.vertex.glsl"_s,
"./assets/shaders/phong-solid.fragment.glsl"_s); "./assets/shaders/phong-solid.fragment.glsl"_s);
app_state.active_shader = &phong_shader; app_state.active_shader = &phong_shader;
sprite_mesh = createMesh(&SQUARE);
cube_mesh = createMesh("./assets/models/cube.obj"); cube_mesh = createMesh("./assets/models/cube.obj");
wall_tex = createTexture("./assets/textures/brick-wall.jpg"); wall_tex = createTexture("./assets/textures/brick-wall.jpg");
SceneGraphNode root_node = {}; Renderer renderer = createRenderer(arena);
init_sg_node(&root_node);
for (int i = 0; i < ArrayCount(STD_SOMA); i++) { for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
Space voxel_space = { STD_SOMA[i], 3, 3, 3 }; 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 polycube = create_polycube_from_repr(&voxel_space);
polycube.color = color_from_index(i); polycube.color = color_from_index(i);
app_state.polycubes.push_back(polycube); 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); 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); glUseProgram(app_state.active_shader->prog_id);
setUniformMat4fv(app_state.active_shader, "projection", &main_frame.cam->proj); setUniformMat4fv(app_state.active_shader, "projection", &main_frame.cam->proj);
setUniformMat4fv(app_state.active_shader, "view", &main_frame.cam->view); setUniformMat4fv(app_state.active_shader, "view", &main_frame.cam->view);
real64 last_frame = glfwGetTime(); real64 last_frame = glfwGetTime();
real64 time_delta = 1.0f/60.0f; real64 time_delta = 1.0f/60.0f;
recalculate_scene_graph(&root_node);
glm::vec3 lastLightPos = {}; glm::vec3 lastLightPos = {};
Input prevInput = {}; Input prevInput = {};
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
@@ -491,8 +631,8 @@ int main_gfx() {
glUseProgram(app_state.active_shader->prog_id); glUseProgram(app_state.active_shader->prog_id);
SceneGraphNode *light_graph_node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node); 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(&phong_shader, "light_pos", &light_graph_node->translation);
setUniform3fv(app_state.active_shader, "camera", &main_frame.cam->pos); setUniform3fv(&phong_shader, "camera", &main_frame.cam->pos);
if (app_state.last_polycube_visible != app_state.current_polycube) { if (app_state.last_polycube_visible != app_state.current_polycube) {
hide_polycube(&app_state.polycubes[app_state.last_polycube_visible]); 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; 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); 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]; renderBegin(&renderer);
drawUI(&renderer);
glBindVertexArray(cube_mesh.vao); renderEnd(&renderer);
recalculate_scene_graph(&root_node);
setUniform3fv(app_state.active_shader, "solid_color", &current_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;
glfwSwapBuffers(window); glfwSwapBuffers(window);
prevInput = input; prevInput = input;