feat: added phong and basic shaders, updated mesh format
This commit is contained in:
@@ -27,8 +27,6 @@ target_include_directories(glad
|
|||||||
${VENDOR_DIR}
|
${VENDOR_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
# KHR
|
|
||||||
|
|
||||||
# STB
|
# STB
|
||||||
add_library(loaders
|
add_library(loaders
|
||||||
STATIC
|
STATIC
|
||||||
@@ -55,6 +53,8 @@ target_sources(${PROJECT_NAME}
|
|||||||
${SRC_DIR}/gfx/Mesh.cpp
|
${SRC_DIR}/gfx/Mesh.cpp
|
||||||
${SRC_DIR}/gfx/Shader.h
|
${SRC_DIR}/gfx/Shader.h
|
||||||
${SRC_DIR}/gfx/Shader.cpp
|
${SRC_DIR}/gfx/Shader.cpp
|
||||||
|
${SRC_DIR}/gfx/Color.h
|
||||||
|
${SRC_DIR}/gfx/Color.cpp
|
||||||
${SRC_DIR}/gfx/geometry.h
|
${SRC_DIR}/gfx/geometry.h
|
||||||
${SRC_DIR}/gfx/geometry.cpp
|
${SRC_DIR}/gfx/geometry.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
out vec4 FragColor;
|
out vec4 frag_color;
|
||||||
|
|
||||||
uniform sampler2D ourTexture;
|
uniform sampler2D texture;
|
||||||
|
|
||||||
in vec2 TexCoord;
|
in vec2 uv;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragColor = texture(ourTexture, TexCoord);
|
frag_color = texture(texture, uv);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
layout (location = 0) in vec3 aPos;
|
layout (location = 0) in vec3 xyz;
|
||||||
layout (location = 1) in vec2 aTexCoord;
|
layout (location = 1) in vec2 uv;
|
||||||
|
layout (location = 1) in vec2 normal;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
|
|
||||||
out vec2 TexCoord;
|
out vec2 tex_coord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
gl_Position = projection * view * model * vec4(xyz, 1.0);
|
||||||
TexCoord = aTexCoord;
|
tex_coord = uv;
|
||||||
}
|
}
|
||||||
|
|||||||
35
assets/shaders/phong-solid.fragment.glsl
Normal file
35
assets/shaders/phong-solid.fragment.glsl
Normal file
@@ -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;
|
||||||
|
};
|
||||||
26
assets/shaders/phong-solid.vertex.glsl
Normal file
26
assets/shaders/phong-solid.vertex.glsl
Normal file
@@ -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);
|
||||||
|
}
|
||||||
46
src/gfx/Color.cpp
Normal file
46
src/gfx/Color.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <glm/ext/vector_float3.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <math.h>
|
||||||
|
#include <iostream>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
5
src/gfx/Color.h
Normal file
5
src/gfx/Color.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <glm/ext/vector_float3.hpp>
|
||||||
|
|
||||||
|
namespace Color {
|
||||||
|
auto color_from_index(int index) -> glm::vec3;
|
||||||
|
};
|
||||||
@@ -6,33 +6,58 @@ auto Mesh::init(const char* obj_file) -> void {
|
|||||||
auto reader = tinyobj::ObjReader();
|
auto reader = tinyobj::ObjReader();
|
||||||
auto success = reader.ParseFromFile(obj_file);
|
auto success = reader.ParseFromFile(obj_file);
|
||||||
std::cout << reader.Error() << std::endl;
|
std::cout << reader.Error() << std::endl;
|
||||||
|
|
||||||
auto attrib = reader.GetAttrib();
|
auto attrib = reader.GetAttrib();
|
||||||
|
|
||||||
auto indices_t = reader.GetShapes().at(0).mesh.indices;
|
auto indices_t = reader.GetShapes().at(0).mesh.indices;
|
||||||
auto indices = std::vector<unsigned int>(indices_t.size());
|
auto indices = std::vector<unsigned int>(indices_t.size());
|
||||||
|
|
||||||
|
auto vertices = std::vector<float>(3*indices_t.size());
|
||||||
|
auto normals = std::vector<float>(3*indices_t.size());
|
||||||
|
auto texcoords = std::vector<float>(2*indices_t.size());
|
||||||
|
|
||||||
for (int i = 0; i < indices_t.size(); i++) {
|
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);
|
glGenVertexArrays(1, &vao);
|
||||||
glGenBuffers(1, &vbo_xyz);
|
glGenBuffers(1, &vbo_xyz);
|
||||||
glGenBuffers(1, &vbo_uv);
|
glGenBuffers(1, &vbo_uv);
|
||||||
glGenBuffers(1, &ebo);
|
glGenBuffers(1, &vbo_norm);
|
||||||
|
//glGenBuffers(1, &ebo);
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_xyz);
|
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);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_uv);
|
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);
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_norm);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
|
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 {
|
auto Mesh::init(const LeddaGeometry::Shape* shape) -> void {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ struct Mesh {
|
|||||||
unsigned int vao;
|
unsigned int vao;
|
||||||
unsigned int vbo_xyz;
|
unsigned int vbo_xyz;
|
||||||
unsigned int vbo_uv;
|
unsigned int vbo_uv;
|
||||||
|
unsigned int vbo_norm;
|
||||||
unsigned int ebo;
|
unsigned int ebo;
|
||||||
unsigned int num_indices;
|
unsigned int num_indices;
|
||||||
auto init(const char* obj_file) -> void;
|
auto init(const char* obj_file) -> void;
|
||||||
|
|||||||
325
src/main.cpp
325
src/main.cpp
@@ -7,6 +7,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@@ -20,9 +21,27 @@
|
|||||||
#include "gfx/Texture.h"
|
#include "gfx/Texture.h"
|
||||||
#include "gfx/Mesh.h"
|
#include "gfx/Mesh.h"
|
||||||
#include "gfx/Shader.h"
|
#include "gfx/Shader.h"
|
||||||
|
#include "gfx/Color.h"
|
||||||
#include "VoxelSpace.h"
|
#include "VoxelSpace.h"
|
||||||
#include "SomaSolve.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 {
|
struct Camera {
|
||||||
glm::mat4 view;
|
glm::mat4 view;
|
||||||
glm::mat4 proj;
|
glm::mat4 proj;
|
||||||
@@ -33,7 +52,7 @@ struct Camera {
|
|||||||
auto init(float aspect_ratio = 800.0f / 600.0f) -> void {
|
auto init(float aspect_ratio = 800.0f / 600.0f) -> void {
|
||||||
view = glm::mat4();
|
view = glm::mat4();
|
||||||
proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
|
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);
|
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<Polycube> polycubes;
|
||||||
|
};
|
||||||
|
GlobalAppState app_state;
|
||||||
|
|
||||||
struct WindowDims {
|
struct WindowDims {
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
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::vec3 translation;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
glm::vec3 scale;
|
glm::vec3 scale;
|
||||||
|
std::vector<int> children;
|
||||||
|
std::optional<int> entity;
|
||||||
|
|
||||||
auto reset() -> void {
|
auto reset() -> void {
|
||||||
scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||||
translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
rotation = glm::quat(0.0f, 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 {
|
auto init() -> void {
|
||||||
trs.reset();
|
reset();
|
||||||
local = glm::mat4(1.0f);
|
local = glm::mat4(1.0f);
|
||||||
|
world = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto update_model_mat() -> void {
|
auto update_local() -> void {
|
||||||
local = glm::mat4(1.0f);
|
|
||||||
local = glm::scale(
|
local = glm::scale(
|
||||||
glm::translate(
|
glm::translate(
|
||||||
local,
|
glm::mat4(1.0f),
|
||||||
trs.translation
|
translation
|
||||||
) * glm::toMat4(trs.rotation),
|
) * glm::toMat4(rotation),
|
||||||
trs.scale
|
scale
|
||||||
);
|
);
|
||||||
world = local;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Polycube {
|
struct Polycube {
|
||||||
std::vector<Entity*>* entities;
|
int graph_node;
|
||||||
uint8_t color;
|
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 {
|
struct Frame {
|
||||||
@@ -111,20 +169,6 @@ auto framebuffer_size_callback(GLFWwindow* window, int width, int height) -> voi
|
|||||||
glViewport(0, 0, width, height);
|
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* {
|
auto init_window_and_gl(WindowDims* window_dims) -> GLFWwindow* {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
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);
|
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 cube_mesh = Mesh{};
|
||||||
auto wall_tex = Texture{};
|
auto wall_tex = Texture{};
|
||||||
auto entities = std::vector<Entity>();
|
auto entities = std::vector<Entity>();
|
||||||
|
auto scene_graph_nodes = std::vector<SceneGraphNode>();
|
||||||
|
|
||||||
|
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 draw_entity(Entity* entity) -> void {
|
||||||
auto modelUniformLoc = glGetUniformLocation(active_shader.prog_id, "model");
|
auto modelUniformLoc = glGetUniformLocation(app_state.active_shader->prog_id, "model");
|
||||||
glUniformMatrix4fv(modelUniformLoc, 1, GL_FALSE, glm::value_ptr(entity->world));
|
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);
|
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
|
||||||
glBindVertexArray(entity->mesh->vao);
|
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 {
|
auto create_polycube_from_repr(Voxel::Space* repr) -> Polycube {
|
||||||
glUseProgram(active_shader.prog_id);
|
auto polycube_id = new_graph_node();
|
||||||
auto viewUniformLoc = glGetUniformLocation(active_shader.prog_id, "view");
|
get_scene_graph_node(polycube_id)->init();
|
||||||
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<Entity*> {
|
|
||||||
auto result = std::vector<Entity*>(Voxel::size(repr->space));
|
|
||||||
for (int x = 0; x < repr->dim_x; x++) {
|
for (int x = 0; x < repr->dim_x; x++) {
|
||||||
for (int y = 0; y < repr->dim_y; y++) {
|
for (int y = 0; y < repr->dim_y; y++) {
|
||||||
for (int z = 0; z < repr->dim_z; z++) {
|
for (int z = 0; z < repr->dim_z; z++) {
|
||||||
if (Voxel::filledAt(repr, x, y, z)) {
|
if (Voxel::filledAt(repr, x, y, z)) {
|
||||||
entities.push_back({
|
auto polycube_segment = get_entity(new_entity());
|
||||||
.mesh=&cube_mesh,
|
polycube_segment->mesh=&cube_mesh,
|
||||||
.tex=&wall_tex,
|
polycube_segment->tex=&wall_tex;
|
||||||
});
|
auto graph_node = get_scene_graph_node(polycube_segment->scene_graph_node);
|
||||||
auto polycube_segment = &entities.back();
|
graph_node->init();
|
||||||
polycube_segment->init();
|
graph_node->translation = glm::vec3(
|
||||||
polycube_segment->trs.translation = glm::vec3(
|
-((repr->dim_z - 1)/2.0f) + z,
|
||||||
-((repr->dim_z - 1)/2) + z,
|
((repr->dim_x - 1)/2.0f) - x,
|
||||||
((repr->dim_x - 1)/2) - x,
|
-((repr->dim_y - 1)/2.0f) + y
|
||||||
-((repr->dim_y - 1)/2) + 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;
|
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 main() -> int {
|
||||||
auto window_dims = WindowDims{ 800, 600 };
|
auto window_dims = WindowDims{ 800, 600 };
|
||||||
auto window = init_window_and_gl(&window_dims);
|
auto window = init_window_and_gl(&window_dims);
|
||||||
@@ -221,6 +311,20 @@ auto main() -> int {
|
|||||||
return -1;
|
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 little_frame = Frame{ .width=80, .height=60, .x=20, .y=20 };
|
||||||
auto big_frame = Frame{ .width=800, .height=600, .x=0, .y=0 };
|
auto big_frame = Frame{ .width=800, .height=600, .x=0, .y=0 };
|
||||||
auto main_cam = Camera{};
|
auto main_cam = Camera{};
|
||||||
@@ -229,37 +333,62 @@ auto main() -> int {
|
|||||||
big_frame.init(&main_cam);
|
big_frame.init(&main_cam);
|
||||||
auto frames = std::vector{ &big_frame, &little_frame };
|
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");
|
for (int i = 0; i < SomaSolve::STD_SOMA.size(); i++) {
|
||||||
wall_tex.init("../assets/textures/brick-wall.jpg");
|
auto voxel_space = Voxel::Space{ SomaSolve::STD_SOMA[i], 3, 3, 3 };
|
||||||
|
Voxel::cullEmptySpace(&voxel_space);
|
||||||
auto voxel_space = Voxel::Space{
|
auto polycube = create_polycube_from_repr(&voxel_space);
|
||||||
.space=SomaSolve::STD_SOMA[0],
|
polycube.color = Color::color_from_index(i);
|
||||||
.dim_x=3,
|
app_state.polycubes.push_back(polycube);
|
||||||
.dim_y=3,
|
root_node.children.push_back(app_state.polycubes.back().graph_node);
|
||||||
.dim_z=3
|
|
||||||
};
|
|
||||||
Voxel::cullEmptySpace(&voxel_space);
|
|
||||||
auto polycube1 = create_polycube_from_repr(&voxel_space);
|
|
||||||
for (auto &entity : entities) {
|
|
||||||
entity.update_model_mat();
|
|
||||||
}
|
}
|
||||||
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);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
use_default_shader(big_frame.cam);
|
|
||||||
gl_update_viewport(&window_dims, &big_frame);
|
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) {
|
for (auto &entity : entities) {
|
||||||
entity.update_model_mat();
|
if (entity.visible) {
|
||||||
auto scale = glm::mat4(1.0f);
|
glUniformMatrix4fv(model_uniform_loc, 1, GL_FALSE, glm::value_ptr(get_scene_graph_node(entity.scene_graph_node)->world));
|
||||||
entity.world = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f) * abs((float)sin(glfwGetTime()))) * entity.world;
|
glDrawArrays(GL_TRIANGLES, 0, entity.mesh->num_indices);
|
||||||
draw_entity(&entity);
|
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|||||||
Reference in New Issue
Block a user