This commit is contained in:
Daniel Ledda
2025-01-04 22:51:33 +01:00
parent 50f4501c86
commit 2daee71548
11 changed files with 277 additions and 245 deletions

View File

@@ -2,20 +2,24 @@
#include <vector>
#include <optional>
#include "lib/glad/glad.h"
#include <glm/ext/matrix_transform.hpp>
#include "lib/djstdlib/core.h"
#include "lib/glad/glad.c"
#include <GLFW/glfw3.h>
#include <glm/ext/matrix_transform.hpp>
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "lib/loaders/stb_image.h"
#include "gfx/main.cpp"
#include "gfx/gfx.cpp"
#include "VoxelSpace.cpp"
#include "SomaSolve.cpp"
#include "lib/djstdlib/core.cpp"
#define STB_IMAGE_IMPLEMENTATION
#include "lib/loaders/stb_image.h"
struct Entity;
struct Polycube;
struct SceneGraphNode;
@@ -39,42 +43,45 @@ struct Camera {
glm::vec3 pos;
glm::vec3 up;
glm::vec3 target;
void init(float aspect_ratio = 800.0f / 600.0f) {
view = glm::mat4();
proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
pos = glm::vec3(0.0f);
up = glm::vec3(0.0f, 1.0f, 0.0f);
}
void look_at(float x, float y, float z) {
target = glm::vec3(x, y, z);
view = glm::lookAt(pos, target, up);
}
void set_up(float up_x, float up_y, float up_z) {
up = glm::vec3(up_x, up_y, up_z);
}
};
Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) {
Camera *result = PushStruct(arena, Camera);
result->view = glm::mat4();
result->proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
result->pos = glm::vec3(0.0f);
result->up = glm::vec3(0.0f, 1.0f, 0.0f);
return result;
}
void camera_look_at(Camera *c, float x, float y, float z) {
c->target = glm::vec3(x, y, z);
c->view = glm::lookAt(c->pos, c->target, c->up);
}
void camera_set_up(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
c->up = glm::vec3(up_x, up_y, up_z);
}
struct GlobalAppState {
int current_polycube;
int last_polycube_visible;
uint32 current_polycube;
uint32 last_polycube_visible;
Shader *active_shader;
std::vector<Polycube> polycubes;
};
GlobalAppState app_state;
struct WindowDims {
unsigned int width;
unsigned int height;
uint32 width;
uint32 height;
};
struct Entity {
Mesh *mesh;
Texture *tex;
bool visible;
int scene_graph_node;
uint32 scene_graph_node;
};
struct SceneGraphNode {
@@ -83,79 +90,80 @@ struct SceneGraphNode {
glm::vec3 translation;
glm::quat rotation;
glm::vec3 scale;
std::vector<int> children;
std::optional<int> entity;
void reset() {
scale = glm::vec3(1.0f, 1.0f, 1.0f);
translation = glm::vec3(0.0f, 0.0f, 0.0f);
rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
}
void init() {
reset();
local = glm::mat4(1.0f);
world = local;
}
void update_local() {
local = glm::scale(
glm::translate(
glm::mat4(1.0f),
translation
) * glm::toMat4(rotation),
scale
);
}
std::vector<uint32> children;
std::optional<uint32> entity;
};
void init_sg_node(SceneGraphNode *n) {
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
n->rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
n->local = glm::mat4(1.0f);
n->world = n->local;
}
void recalculate_sg_node(SceneGraphNode *n) {
n->local = glm::scale(
glm::translate(
glm::mat4(1.0f),
n->translation
) * glm::toMat4(n->rotation),
n->scale
);
}
struct Polycube {
int graph_node;
glm::vec3 color;
void show() {
SceneGraphNode *node = get_scene_graph_node(graph_node);
for (auto &child : node->children) {
auto node = get_scene_graph_node(child);
if (node->entity) {
get_entity(*node->entity)->visible = true;
}
}
}
void hide() {
SceneGraphNode *node = get_scene_graph_node(graph_node);
for (int &child : node->children) {
SceneGraphNode *node = get_scene_graph_node(child);
if (node->entity) {
get_entity(*node->entity)->visible = false;
}
}
}
glm::vec3 get_centre() {
glm::vec3 centre = glm::vec3(0.0f);
for (int &child : get_scene_graph_node(graph_node)->children) {
centre += get_scene_graph_node(child)->translation;
}
centre /= get_scene_graph_node(graph_node)->children.size();
return centre;
}
};
void show_polycube(Polycube *p) {
SceneGraphNode *node = get_scene_graph_node(p->graph_node);
for (uint32 &child : node->children) {
SceneGraphNode *node = get_scene_graph_node(child);
if (node->entity) {
get_entity(*node->entity)->visible = true;
}
}
}
void hide_polycube(Polycube *p) {
SceneGraphNode *node = get_scene_graph_node(p->graph_node);
for (uint32 &child : node->children) {
SceneGraphNode *node = get_scene_graph_node(child);
if (node->entity) {
get_entity(*node->entity)->visible = false;
}
}
}
glm::vec3 centreFromPolycube(Polycube *p) {
glm::vec3 centre = glm::vec3(0.0f);
for (uint32 &child : get_scene_graph_node(p->graph_node)->children) {
centre += get_scene_graph_node(child)->translation;
}
centre /= get_scene_graph_node(p->graph_node)->children.size();
return centre;
}
struct Frame {
unsigned int width;
unsigned int height;
int x;
int y;
uint32 width;
uint32 height;
int32 x;
int32 y;
Camera* cam;
void init(Camera* camera) {
camera->init((float)width / (float)height);
cam = camera;
}
};
Frame createFrame(Arena *arena, uint32 width, uint32 height, real32 x, real32 y) {
Frame result = {0};
result.width = width;
result.height = height;
result.x = x;
result.y = y;
result.cam = createCamera(arena, (real32)result.width / (real32)result.height);
return result;
}
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height);
}
@@ -165,7 +173,7 @@ GLFWwindow *init_window_and_gl(WindowDims *window_dims) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
auto window = glfwCreateWindow(window_dims->width, window_dims->height, "Somaesque", NULL, NULL);
GLFWwindow *window = glfwCreateWindow(window_dims->width, window_dims->height, "Somaesque", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
@@ -244,18 +252,9 @@ int new_graph_node() {
return scene_graph_nodes.size();
}
void draw_entity(Entity *entity) {
GLint modelUniformLoc = glGetUniformLocation(app_state.active_shader->prog_id, "model");
glUniformMatrix4fv(modelUniformLoc, 1, GL_FALSE, glm::value_ptr(get_scene_graph_node(entity->scene_graph_node)->world));
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
glBindVertexArray(entity->mesh->vao);
glDrawArrays(GL_TRIANGLES, 0, entity->mesh->num_indices);
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
}
Polycube create_polycube_from_repr(Space *repr) {
int polycube_id = new_graph_node();
get_scene_graph_node(polycube_id)->init();
init_sg_node(get_scene_graph_node(polycube_id));
for (int x = 0; x < repr->dim_x; x++) {
for (int y = 0; y < repr->dim_y; y++) {
for (int z = 0; z < repr->dim_z; z++) {
@@ -264,13 +263,13 @@ Polycube create_polycube_from_repr(Space *repr) {
polycube_segment->mesh=&cube_mesh,
polycube_segment->tex=&wall_tex;
SceneGraphNode *graph_node = get_scene_graph_node(polycube_segment->scene_graph_node);
graph_node->init();
init_sg_node(graph_node);
graph_node->translation = glm::vec3(
-((repr->dim_z - 1)/2.0f) + z,
((repr->dim_x - 1)/2.0f) - x,
-((repr->dim_y - 1)/2.0f) + y
);
graph_node->update_local();
recalculate_sg_node(graph_node);
get_scene_graph_node(polycube_id)->children.push_back(polycube_segment->scene_graph_node);
}
}
@@ -287,9 +286,9 @@ void recalculate_scene_graph(SceneGraphNode *top) {
if (top->children.size() == 0) {
return;
}
for (int &node_id : top->children) {
for (uint32 &node_id : top->children) {
SceneGraphNode *graph_node = get_scene_graph_node(node_id);
graph_node->update_local();
recalculate_sg_node(graph_node);
graph_node->world = top->world * graph_node->local;
recalculate_scene_graph(graph_node);
}
@@ -307,6 +306,8 @@ int main_gfx() {
return -1;
}
Arena *arena = arenaAlloc(Megabytes(128));
app_state = {
.current_polycube=0,
.last_polycube_visible=6,
@@ -314,26 +315,21 @@ int main_gfx() {
.polycubes={},
};
Shader phong_shader = {0};
phong_shader.init("../assets/shaders/phong-solid.vertex.glsl", "../assets/shaders/phong-solid.fragment.glsl");
Shader phong_shader = createShader("../assets/shaders/phong-solid.vertex.glsl", "../assets/shaders/phong-solid.fragment.glsl");
app_state.active_shader = &phong_shader;
cube_mesh.init("../assets/models/c000000.obj");
wall_tex.init("../assets/textures/brick-wall.jpg");
cube_mesh = createMesh("../assets/models/c000000.obj");
wall_tex = createTexture("../assets/textures/brick-wall.jpg");
Frame little_frame = { .width=80, .height=60, .x=20, .y=20 };
Frame big_frame = { .width=800, .height=600, .x=0, .y=0 };
Camera main_cam = {};
Camera other_cam = {};
little_frame.init(&other_cam);
big_frame.init(&main_cam);
std::vector<Frame> frames = { &big_frame, &little_frame };
Frame little_frame = createFrame(arena, 80, 60, 20, 20);
Frame big_frame = createFrame(arena, 800, 600, 0, 0);
Frame *frames[] = { &big_frame, &little_frame };
SceneGraphNode root_node = {};
root_node.init();
init_sg_node(&root_node);
for (int i = 0; i < STD_SOMA.size(); i++) {
auto voxel_space = Space{ STD_SOMA[i], 3, 3, 3 };
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
Space voxel_space = { STD_SOMA[i], 3, 3, 3 };
cullEmptySpace(&voxel_space);
Polycube polycube = create_polycube_from_repr(&voxel_space);
polycube.color = color_from_index(i);
@@ -341,18 +337,21 @@ int main_gfx() {
root_node.children.push_back(app_state.polycubes.back().graph_node);
}
main_cam.pos = glm::vec3(4.0f, 4.0f, 4.0f);
main_cam.look_at(0.0f, 0.0f, 0.0f);
big_frame.cam->pos = glm::vec3(0.0f, 4.0f, 4.0f);
camera_look_at(big_frame.cam, 0.0f, 0.0f, 0.0f);
glm::vec3 light_pos = glm::vec3(6.0f);
glm::vec3 light_pos = glm::vec3(4.0f, 12.0f, 2.0f);
glUseProgram(app_state.active_shader->prog_id);
GLint view_loc = glGetUniformLocation(app_state.active_shader->prog_id, "view");
GLint proj_loc = glGetUniformLocation(app_state.active_shader->prog_id, "projection");
GLint light_pos_loc = glGetUniformLocation(app_state.active_shader->prog_id, "light_pos");
glUniform3fv(light_pos_loc, 1, glm::value_ptr(light_pos));
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(main_cam.proj));
glUniformMatrix4fv(view_loc, 1, GL_FALSE, glm::value_ptr(main_cam.view));
glUniform3fv(
glGetUniformLocation(app_state.active_shader->prog_id, "light_pos"),
1, glm::value_ptr(light_pos));
glUniformMatrix4fv(
glGetUniformLocation(app_state.active_shader->prog_id, "projection"),
1, GL_FALSE, glm::value_ptr(big_frame.cam->proj));
glUniformMatrix4fv(
glGetUniformLocation(app_state.active_shader->prog_id, "view"),
1, GL_FALSE, glm::value_ptr(big_frame.cam->view));
real32 last_frame = glfwGetTime();
real32 time_delta = 1.0f/60.0f;
@@ -361,8 +360,8 @@ int main_gfx() {
process_input(window);
if (app_state.last_polycube_visible != app_state.current_polycube) {
app_state.polycubes[app_state.last_polycube_visible].hide();
app_state.polycubes[app_state.current_polycube].show();
hide_polycube(&app_state.polycubes[app_state.last_polycube_visible]);
show_polycube(&app_state.polycubes[app_state.current_polycube]);
app_state.last_polycube_visible = app_state.current_polycube;
}
@@ -374,14 +373,16 @@ int main_gfx() {
get_scene_graph_node(current_polycube->graph_node)->rotation = glm::quat(glm::vec3(0, glfwGetTime() / 2, 0));
glBindVertexArray(cube_mesh.vao);
//glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id);
recalculate_scene_graph(&root_node);
GLint model_uniform_loc = glGetUniformLocation(app_state.active_shader->prog_id, "model");
GLint solid_color_loc = glGetUniformLocation(app_state.active_shader->prog_id, "solid_color");
glUniform3fv(solid_color_loc, 1, glm::value_ptr(current_polycube->color));
glUniform3fv(
glGetUniformLocation(app_state.active_shader->prog_id, "solid_color"),
1, glm::value_ptr(current_polycube->color));
for (Entity &entity : entities) {
if (entity.visible) {
glUniformMatrix4fv(model_uniform_loc, 1, GL_FALSE, glm::value_ptr(get_scene_graph_node(entity.scene_graph_node)->world));
glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id);
glDrawArrays(GL_TRIANGLES, 0, entity.mesh->num_indices);
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
}
@@ -396,6 +397,7 @@ int main_gfx() {
}
int main() {
initialiseCore();
return main_cmd();
}