diff --git a/CMakeLists.txt b/CMakeLists.txt index 620e5e5..28b3018 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,6 @@ target_include_directories(glad ${VENDOR_DIR} ) -# KHR - # STB add_library(loaders STATIC @@ -55,6 +53,8 @@ target_sources(${PROJECT_NAME} ${SRC_DIR}/gfx/Mesh.cpp ${SRC_DIR}/gfx/Shader.h ${SRC_DIR}/gfx/Shader.cpp + ${SRC_DIR}/gfx/Color.h + ${SRC_DIR}/gfx/Color.cpp ${SRC_DIR}/gfx/geometry.h ${SRC_DIR}/gfx/geometry.cpp ) diff --git a/assets/shaders/basic.fragment.glsl b/assets/shaders/basic.fragment.glsl index 3f86a0f..01e771a 100644 --- a/assets/shaders/basic.fragment.glsl +++ b/assets/shaders/basic.fragment.glsl @@ -1,10 +1,10 @@ #version 330 core -out vec4 FragColor; +out vec4 frag_color; -uniform sampler2D ourTexture; +uniform sampler2D texture; -in vec2 TexCoord; +in vec2 uv; void main() { - FragColor = texture(ourTexture, TexCoord); + frag_color = texture(texture, uv); }; diff --git a/assets/shaders/basic.vertex.glsl b/assets/shaders/basic.vertex.glsl index 5aff12e..2106071 100644 --- a/assets/shaders/basic.vertex.glsl +++ b/assets/shaders/basic.vertex.glsl @@ -1,14 +1,15 @@ #version 330 core -layout (location = 0) in vec3 aPos; -layout (location = 1) in vec2 aTexCoord; +layout (location = 0) in vec3 xyz; +layout (location = 1) in vec2 uv; +layout (location = 1) in vec2 normal; uniform mat4 model; uniform mat4 view; uniform mat4 projection; -out vec2 TexCoord; +out vec2 tex_coord; void main() { - gl_Position = projection * view * model * vec4(aPos, 1.0); - TexCoord = aTexCoord; + gl_Position = projection * view * model * vec4(xyz, 1.0); + tex_coord = uv; } diff --git a/assets/shaders/phong-solid.fragment.glsl b/assets/shaders/phong-solid.fragment.glsl new file mode 100644 index 0000000..559f155 --- /dev/null +++ b/assets/shaders/phong-solid.fragment.glsl @@ -0,0 +1,35 @@ +#version 330 core +out vec4 frag_color; + +uniform vec3 light_pos; +uniform vec3 solid_color; + +in vec3 normal_cameraspace; +in vec3 light_direction_cameraspace; +in vec3 eye_direction_cameraspace; +in vec3 position_worldspace; + +void main() { + vec4 material_diffuse_color = vec4(solid_color, 1); + vec4 material_ambient_color = vec4(0.1, 0.1, 0.1, 1.0) * material_diffuse_color; + vec4 material_specular_color = vec4(1.0, 1.0, 1.0, 1.0); + + vec3 normal = normalize(normal_cameraspace); + vec3 light_dir = normalize(light_direction_cameraspace); + float cos_theta = clamp(dot(normal, light_dir), 0, 1); + + vec3 eye = normalize(eye_direction_cameraspace); + vec3 reflected = reflect(-light_dir, normal); + float cos_alpha = clamp(dot(eye, reflected), 0, 1); + + vec4 light_color = vec4(1, 1, 1, 1); + float light_power = 60; + + float distance = length(light_pos - position_worldspace); + float dist_sq = pow(distance, 2); + + vec4 diffuse = material_diffuse_color * light_color * light_power * cos_theta / dist_sq; + vec4 specular = material_specular_color * light_color * light_power * pow(cos_alpha, 10) / dist_sq; + + frag_color = material_ambient_color + diffuse + specular; +}; diff --git a/assets/shaders/phong-solid.vertex.glsl b/assets/shaders/phong-solid.vertex.glsl new file mode 100644 index 0000000..e3922dd --- /dev/null +++ b/assets/shaders/phong-solid.vertex.glsl @@ -0,0 +1,26 @@ +#version 330 core +layout (location = 0) in vec3 a_xyz; +layout (location = 1) in vec2 a_uv; +layout (location = 2) in vec3 a_normal; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +uniform vec3 light_pos; + +out vec3 normal_cameraspace; +out vec3 light_direction_cameraspace; +out vec3 eye_direction_cameraspace; +out vec3 position_worldspace; + +void main() { + vec3 vertex_cameraspace = (view * model * vec4(a_xyz, 1)).xyz; + vec3 light_pos_cameraspace = (view * vec4(light_pos, 1)).xyz; + + normal_cameraspace = (transpose(inverse(view * model)) * vec4(a_normal, 0)).xyz; + light_direction_cameraspace = light_pos_cameraspace + eye_direction_cameraspace; + eye_direction_cameraspace = vec3(0, 0, 0) - vertex_cameraspace; + position_worldspace = (model * vec4(a_xyz, 1)).xyz; + + gl_Position = projection * view * model * vec4(a_xyz, 1); +} diff --git a/src/gfx/Color.cpp b/src/gfx/Color.cpp new file mode 100644 index 0000000..b408234 --- /dev/null +++ b/src/gfx/Color.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include "Color.h" + +auto hue_to_rgb(float p, float q, float t) -> float { + if (t < 0) { + t += 1; + } else if (t > 1) { + t -= 1; + } + if (t < 1.0f / 6) return p + (q - p) * 6 * t; + if (t < 1.0f / 2) return q; + if (t < 2.0f / 3) return p + (q - p) * (2.0f / 3 - t) * 6; + return p; +}; + +auto hsl_to_hex(float h, float s, float l) -> glm::vec3 { + h /= 360; + s /= 100; + l /= 100; + float r, g, b; + if (s == 0) { + r = g = b = l; + } else { + auto q = l < 0.5f ? l * (1 + s) : l + s - l * s; + auto p = 2 * l - q; + r = hue_to_rgb(p, q, h + 1.0f / 3); + g = hue_to_rgb(p, q, h); + b = hue_to_rgb(p, q, h - 1.0f / 3); + } + return glm::vec3(r, g, b); +} + +auto Color::color_from_index(int index) -> glm::vec3 { + auto color_wheel_cycle = floorf(index / 6.0f); + auto darkness_cycle = floorf(index / 12.0f); + auto spacing = (360.0f / 6.0f); + auto offset = color_wheel_cycle == 0 ? 0 : spacing / (color_wheel_cycle + 2); + auto hue = spacing * (index % 6) + offset; + auto saturation = 100.0f; + auto lightness = 1.0f / (2 + darkness_cycle) * 100; + return hsl_to_hex(hue, saturation, lightness); +} diff --git a/src/gfx/Color.h b/src/gfx/Color.h new file mode 100644 index 0000000..60781bb --- /dev/null +++ b/src/gfx/Color.h @@ -0,0 +1,5 @@ +#include + +namespace Color { + auto color_from_index(int index) -> glm::vec3; +}; diff --git a/src/gfx/Mesh.cpp b/src/gfx/Mesh.cpp index 543be8d..4d5daa2 100644 --- a/src/gfx/Mesh.cpp +++ b/src/gfx/Mesh.cpp @@ -6,33 +6,58 @@ auto Mesh::init(const char* obj_file) -> void { auto reader = tinyobj::ObjReader(); auto success = reader.ParseFromFile(obj_file); std::cout << reader.Error() << std::endl; + auto attrib = reader.GetAttrib(); + auto indices_t = reader.GetShapes().at(0).mesh.indices; auto indices = std::vector(indices_t.size()); + + auto vertices = std::vector(3*indices_t.size()); + auto normals = std::vector(3*indices_t.size()); + auto texcoords = std::vector(2*indices_t.size()); + for (int i = 0; i < indices_t.size(); i++) { - indices[i] = indices_t[i].vertex_index; + auto vertex_data = indices_t[i]; + vertices[3*i] = attrib.vertices[3*vertex_data.vertex_index]; + vertices[3*i+1] = attrib.vertices[3*vertex_data.vertex_index + 1]; + vertices[3*i+2] = attrib.vertices[3*vertex_data.vertex_index + 2]; + + normals[3*i] = attrib.normals[3*vertex_data.normal_index]; + normals[3*i+1] = attrib.normals[3*vertex_data.normal_index + 1]; + normals[3*i+2] = attrib.normals[3*vertex_data.normal_index + 2]; + + texcoords[2*i] = attrib.texcoords[2*vertex_data.texcoord_index]; + texcoords[2*i+1] = attrib.texcoords[2*vertex_data.texcoord_index + 1]; + + indices[i] = i; } - num_indices = indices.size(); + num_indices = indices_t.size(); glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo_xyz); glGenBuffers(1, &vbo_uv); - glGenBuffers(1, &ebo); + glGenBuffers(1, &vbo_norm); + //glGenBuffers(1, &ebo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo_xyz); - glBufferData(GL_ARRAY_BUFFER, attrib.vertices.size() * sizeof(float), attrib.vertices.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * 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, vbo_uv); - glBufferData(GL_ARRAY_BUFFER, attrib.texcoords.size() * sizeof(float), attrib.texcoords.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(float), texcoords.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, vbo_norm); + glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(2); + + //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + //glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); } auto Mesh::init(const LeddaGeometry::Shape* shape) -> void { diff --git a/src/gfx/Mesh.h b/src/gfx/Mesh.h index 9a41ee5..5a435bf 100644 --- a/src/gfx/Mesh.h +++ b/src/gfx/Mesh.h @@ -8,6 +8,7 @@ struct Mesh { unsigned int vao; unsigned int vbo_xyz; unsigned int vbo_uv; + unsigned int vbo_norm; unsigned int ebo; unsigned int num_indices; auto init(const char* obj_file) -> void; diff --git a/src/main.cpp b/src/main.cpp index db9e249..b88847c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "glad/glad.h" #include @@ -20,9 +21,27 @@ #include "gfx/Texture.h" #include "gfx/Mesh.h" #include "gfx/Shader.h" +#include "gfx/Color.h" #include "VoxelSpace.h" #include "SomaSolve.h" +struct Entity; +struct Polycube; +struct SceneGraphNode; +auto new_entity() -> int; +auto get_entity(int id) -> Entity*; +auto get_scene_graph_node(int id) -> SceneGraphNode*; +auto new_graph_node() -> int; + +auto print_mat(glm::mat4* matrix) -> void { + auto mat = *matrix; + std::cout << mat[0][0] << mat[0][1] << mat[0][2] << mat[0][3] << std::endl; + std::cout << mat[1][0] << mat[1][1] << mat[1][2] << mat[1][3] << std::endl; + std::cout << mat[2][0] << mat[2][1] << mat[2][2] << mat[2][3] << std::endl; + std::cout << mat[3][0] << mat[3][1] << mat[3][2] << mat[3][3] << std::endl; + std::cout << std::endl; +} + struct Camera { glm::mat4 view; glm::mat4 proj; @@ -33,7 +52,7 @@ struct Camera { auto init(float aspect_ratio = 800.0f / 600.0f) -> void { view = glm::mat4(); proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f); - pos = glm::vec3(0.0f, 5.0f, 0.0f); + pos = glm::vec3(0.0f); up = glm::vec3(0.0f, 1.0f, 0.0f); } @@ -47,51 +66,90 @@ struct Camera { } }; +struct GlobalAppState { + int current_polycube; + int last_polycube_visible; + Shader* active_shader; + std::vector polycubes; +}; +GlobalAppState app_state; + struct WindowDims { unsigned int width; unsigned int height; }; -struct TrsSpecs { +struct Entity { + Mesh* mesh; + Texture* tex; + bool visible; + int scene_graph_node; +}; + +struct SceneGraphNode { + glm::mat4 local; + glm::mat4 world; glm::vec3 translation; glm::quat rotation; glm::vec3 scale; + std::vector children; + std::optional entity; auto reset() -> void { 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); } -}; - -struct Entity { - glm::mat4 local; - glm::mat4 world; - TrsSpecs trs; - Mesh* mesh; - Texture* tex; - + auto init() -> void { - trs.reset(); + reset(); local = glm::mat4(1.0f); + world = local; } - auto update_model_mat() -> void { - local = glm::mat4(1.0f); + auto update_local() -> void { local = glm::scale( glm::translate( - local, - trs.translation - ) * glm::toMat4(trs.rotation), - trs.scale + glm::mat4(1.0f), + translation + ) * glm::toMat4(rotation), + scale ); - world = local; } }; struct Polycube { - std::vector* entities; - uint8_t color; + int graph_node; + glm::vec3 color; + + auto show() -> void { + auto 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; + } + } + } + + auto hide() -> void { + auto 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 = false; + } + } + } + + auto get_centre() -> glm::vec3 { + auto centre = glm::vec3(0.0f); + for (auto &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; + } }; struct Frame { @@ -111,20 +169,6 @@ auto framebuffer_size_callback(GLFWwindow* window, int width, int height) -> voi glViewport(0, 0, width, height); } -auto process_input(GLFWwindow *window) -> void { - static auto wireframe = false; - static auto last_frame_state_press = false; - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { - glfwSetWindowShouldClose(window, true); - } else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && !last_frame_state_press) { - glPolygonMode(GL_FRONT_AND_BACK, !wireframe ? GL_LINE : GL_FILL); - wireframe = !wireframe; - last_frame_state_press = true; - } else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE) { - last_frame_state_press = false; - } -} - auto init_window_and_gl(WindowDims* window_dims) -> GLFWwindow* { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -153,67 +197,113 @@ auto gl_update_viewport(WindowDims* window_dims, Frame* frame) -> void { glViewport(frame->x, window_dims->height - frame->y - frame->height, frame->width, frame->height); } -auto rotate_cam_around_centre(Camera* cam, int radius) -> void { - cam->pos.x = sin(glfwGetTime()) * radius; - cam->pos.z = cos(glfwGetTime()) * radius; - cam->look_at(0.0f, 0.0f, 0.0f); -} - -auto active_shader = Shader{}; auto cube_mesh = Mesh{}; auto wall_tex = Texture{}; auto entities = std::vector(); +auto scene_graph_nodes = std::vector(); + +auto process_input(GLFWwindow *window) -> void { + static auto wireframe = false; + static auto last_frame_state_press_enter = false; + static auto last_frame_state_press = false; + + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { + glfwSetWindowShouldClose(window, true); + } + + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && !last_frame_state_press) { + glPolygonMode(GL_FRONT_AND_BACK, !wireframe ? GL_LINE : GL_FILL); + wireframe = !wireframe; + last_frame_state_press = true; + } else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE) { + last_frame_state_press = false; + } + + if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS && !last_frame_state_press_enter) { + if (app_state.current_polycube == 6) { + app_state.current_polycube = 0; + } else { + app_state.current_polycube += 1; + } + last_frame_state_press_enter = true; + } else if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_RELEASE) { + last_frame_state_press_enter = false; + } +} + + +auto new_entity() -> int { + entities.emplace_back(); + scene_graph_nodes.emplace_back(); + entities.back().scene_graph_node = scene_graph_nodes.size(); + scene_graph_nodes.back().entity = entities.size(); + return entities.size(); +} + +auto get_entity(int id) -> Entity* { + return &entities[id - 1]; +} + +auto get_scene_graph_node(int id) -> SceneGraphNode* { + return &scene_graph_nodes[id - 1]; +} + +auto new_graph_node() -> int { + scene_graph_nodes.emplace_back(); + return scene_graph_nodes.size(); +} auto draw_entity(Entity* entity) -> void { - auto modelUniformLoc = glGetUniformLocation(active_shader.prog_id, "model"); - glUniformMatrix4fv(modelUniformLoc, 1, GL_FALSE, glm::value_ptr(entity->world)); + auto 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); - glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0); + glDrawArrays(GL_TRIANGLES, 0, entity->mesh->num_indices); + //glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0); } -auto use_default_shader(Camera* cam) -> void { - glUseProgram(active_shader.prog_id); - auto viewUniformLoc = glGetUniformLocation(active_shader.prog_id, "view"); - auto projectionUniformLoc = glGetUniformLocation(active_shader.prog_id, "projection"); - glUniformMatrix4fv(projectionUniformLoc, 1, GL_FALSE, glm::value_ptr(cam->proj)); - glUniformMatrix4fv(viewUniformLoc, 1, GL_FALSE, glm::value_ptr(cam->view)); -} - -auto print_mat(glm::mat4* matrix) -> void { - auto mat = *matrix; - std::cout << mat[0][0] << mat[0][1] << mat[0][2] << mat[0][3] << std::endl; - std::cout << mat[1][0] << mat[1][1] << mat[1][2] << mat[1][3] << std::endl; - std::cout << mat[2][0] << mat[2][1] << mat[2][2] << mat[2][3] << std::endl; - std::cout << mat[3][0] << mat[3][1] << mat[3][2] << mat[3][3] << std::endl; - std::cout << std::endl; -} - -auto create_polycube_from_repr(Voxel::Space* repr) -> std::vector { - auto result = std::vector(Voxel::size(repr->space)); +auto create_polycube_from_repr(Voxel::Space* repr) -> Polycube { + auto polycube_id = new_graph_node(); + get_scene_graph_node(polycube_id)->init(); 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++) { if (Voxel::filledAt(repr, x, y, z)) { - entities.push_back({ - .mesh=&cube_mesh, - .tex=&wall_tex, - }); - auto polycube_segment = &entities.back(); - polycube_segment->init(); - polycube_segment->trs.translation = glm::vec3( - -((repr->dim_z - 1)/2) + z, - ((repr->dim_x - 1)/2) - x, - -((repr->dim_y - 1)/2) + y + auto polycube_segment = get_entity(new_entity()); + polycube_segment->mesh=&cube_mesh, + polycube_segment->tex=&wall_tex; + auto graph_node = get_scene_graph_node(polycube_segment->scene_graph_node); + graph_node->init(); + 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 ); - result.push_back(polycube_segment); + graph_node->update_local(); + get_scene_graph_node(polycube_id)->children.push_back(polycube_segment->scene_graph_node); } } } } + auto result = Polycube{ + .graph_node=polycube_id, + .color=glm::vec3(1.0f), + }; return result; } +auto recalculate_scene_graph(SceneGraphNode* top) -> void { + if (top->children.size() == 0) { + return; + } + for (auto &node_id : top->children) { + auto graph_node = get_scene_graph_node(node_id); + graph_node->update_local(); + graph_node->world = top->world * graph_node->local; + recalculate_scene_graph(graph_node); + } +} + auto main() -> int { auto window_dims = WindowDims{ 800, 600 }; auto window = init_window_and_gl(&window_dims); @@ -221,6 +311,20 @@ auto main() -> int { return -1; } + app_state = GlobalAppState{ + .current_polycube=0, + .last_polycube_visible=6, + .active_shader=nullptr, + .polycubes={}, + }; + + auto phong_shader = Shader{}; + phong_shader.init("../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"); + auto little_frame = Frame{ .width=80, .height=60, .x=20, .y=20 }; auto big_frame = Frame{ .width=800, .height=600, .x=0, .y=0 }; auto main_cam = Camera{}; @@ -229,37 +333,62 @@ auto main() -> int { big_frame.init(&main_cam); auto frames = std::vector{ &big_frame, &little_frame }; - active_shader.init("../assets/shaders/basic.vertex.glsl", "../assets/shaders/basic.fragment.glsl"); + auto root_node = SceneGraphNode{}; + root_node.init(); - cube_mesh.init("../assets/models/c000000.obj"); - wall_tex.init("../assets/textures/brick-wall.jpg"); - - auto voxel_space = Voxel::Space{ - .space=SomaSolve::STD_SOMA[0], - .dim_x=3, - .dim_y=3, - .dim_z=3 - }; - Voxel::cullEmptySpace(&voxel_space); - auto polycube1 = create_polycube_from_repr(&voxel_space); - for (auto &entity : entities) { - entity.update_model_mat(); + for (int i = 0; i < SomaSolve::STD_SOMA.size(); i++) { + auto voxel_space = Voxel::Space{ SomaSolve::STD_SOMA[i], 3, 3, 3 }; + Voxel::cullEmptySpace(&voxel_space); + auto polycube = create_polycube_from_repr(&voxel_space); + polycube.color = Color::color_from_index(i); + app_state.polycubes.push_back(polycube); + root_node.children.push_back(app_state.polycubes.back().graph_node); } - while (!glfwWindowShouldClose(window)) { - process_input(window); - rotate_cam_around_centre(big_frame.cam, 10.0f); - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + main_cam.pos = glm::vec3(4.0f, 4.0f, 4.0f); + main_cam.look_at(0.0f, 0.0f, 0.0f); + + auto light_pos = glm::vec3(6.0f); + + glUseProgram(app_state.active_shader->prog_id); + auto view_loc = glGetUniformLocation(app_state.active_shader->prog_id, "view"); + auto proj_loc = glGetUniformLocation(app_state.active_shader->prog_id, "projection"); + auto 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)); + + auto last_frame = glfwGetTime(); + auto time_delta = 1.0f/60.0f; + while (!glfwWindowShouldClose(window)) { + time_delta = glfwGetTime() - last_frame; + 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(); + 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); - use_default_shader(big_frame.cam); gl_update_viewport(&window_dims, &big_frame); + auto current_polycube = &app_state.polycubes[app_state.current_polycube]; + 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); + auto model_uniform_loc = glGetUniformLocation(app_state.active_shader->prog_id, "model"); + auto solid_color_loc = glGetUniformLocation(app_state.active_shader->prog_id, "solid_color"); + glUniform3fv(solid_color_loc, 1, glm::value_ptr(current_polycube->color)); for (auto &entity : entities) { - entity.update_model_mat(); - auto scale = glm::mat4(1.0f); - entity.world = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f) * abs((float)sin(glfwGetTime()))) * entity.world; - draw_entity(&entity); + if (entity.visible) { + glUniformMatrix4fv(model_uniform_loc, 1, GL_FALSE, glm::value_ptr(get_scene_graph_node(entity.scene_graph_node)->world)); + glDrawArrays(GL_TRIANGLES, 0, entity.mesh->num_indices); + //glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0); + } } glfwSwapBuffers(window);