update
This commit is contained in:
@@ -3,11 +3,33 @@ out vec4 frag_color;
|
|||||||
|
|
||||||
uniform vec3 light_pos;
|
uniform vec3 light_pos;
|
||||||
uniform vec3 solid_color;
|
uniform vec3 solid_color;
|
||||||
|
uniform vec3 camera;
|
||||||
|
|
||||||
in vec3 normal;
|
in vec3 normal;
|
||||||
in vec3 frag_position;
|
in vec3 frag_position;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
vec3 light_color = vec3(1, 1, 1);
|
||||||
|
vec3 normal_norm = normalize(normal);
|
||||||
|
vec3 light_direction_norm = normalize(light_pos - frag_position);
|
||||||
|
|
||||||
|
float ambient_strength = 0.2;
|
||||||
|
vec3 ambient = ambient_strength * light_color;
|
||||||
|
|
||||||
|
float diffuse_strength = max(dot(normal_norm, light_direction_norm), 0.0);
|
||||||
|
vec3 diffuse = diffuse_strength * light_color;
|
||||||
|
|
||||||
|
float specular_strength = 0.5;
|
||||||
|
vec3 view_direction_norm = normalize(camera - frag_position);
|
||||||
|
vec3 reflect_dir = reflect(-light_direction_norm, normal_norm);
|
||||||
|
float spec = pow(max(dot(view_direction_norm, reflect_dir), 0.0), 32);
|
||||||
|
vec3 specular = specular_strength * spec * light_color;
|
||||||
|
|
||||||
|
vec3 phong = specular + (ambient + diffuse) * solid_color;
|
||||||
|
frag_color = vec4(phong, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_old() {
|
||||||
vec3 light_color = vec3(1, 1, 1);
|
vec3 light_color = vec3(1, 1, 1);
|
||||||
vec3 light_direction_norm = normalize(light_pos - frag_position);
|
vec3 light_direction_norm = normalize(light_pos - frag_position);
|
||||||
vec3 normal_norm = normalize(normal);
|
vec3 normal_norm = normalize(normal);
|
||||||
@@ -25,6 +47,6 @@ void main() {
|
|||||||
float spec = pow(max(dot(view_direction_norm, reflect_dir), 0.0), 32);
|
float spec = pow(max(dot(view_direction_norm, reflect_dir), 0.0), 32);
|
||||||
vec3 specular = specular_strength * spec * light_color;
|
vec3 specular = specular_strength * spec * light_color;
|
||||||
|
|
||||||
vec3 result = specular * (solid_color + 2 * light_color) / 2 + (ambient + diffuse) * solid_color;
|
vec3 result = specular + (ambient + diffuse) * solid_color;
|
||||||
frag_color = vec4(result, 1.0);
|
frag_color = vec4(result, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
4
build
4
build
@@ -2,7 +2,5 @@
|
|||||||
|
|
||||||
LIB_INCLUDE="-lglfw -lGL"
|
LIB_INCLUDE="-lglfw -lGL"
|
||||||
g++ -g -g3 -DOS_LINUX=1 -DENABLE_ASSERT=1 ./src/main.cpp -o ./target/somaesque $LIB_INCLUDE
|
g++ -g -g3 -DOS_LINUX=1 -DENABLE_ASSERT=1 ./src/main.cpp -o ./target/somaesque $LIB_INCLUDE
|
||||||
pushd target
|
./target/somaesque
|
||||||
./somaesque
|
|
||||||
popd
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "VoxelSpace.h"
|
#include "VoxelSpace.h"
|
||||||
#include "lib/djstdlib/core.h"
|
|
||||||
|
|
||||||
void get_dims_input(int dims[3]) {
|
void get_dims_input(int dims[3]) {
|
||||||
std::cout << "Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n";
|
std::cout << "Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n";
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdint>
|
|
||||||
#include "VoxelSpace.h"
|
#include "VoxelSpace.h"
|
||||||
#include "lib/djstdlib/core.h"
|
|
||||||
|
|
||||||
int index(int dim_y, int dim_z, int x, int y, int z) {
|
int index(int dim_y, int dim_z, int x, int y, int z) {
|
||||||
return dim_y * dim_z * x + dim_z * y + z;
|
return dim_y * dim_z * x + dim_z * y + z;
|
||||||
|
|||||||
@@ -1,40 +1,39 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#define TINYOBJLOADER_IMPLEMENTATION
|
|
||||||
#include "../lib/loaders/tinyobj.h"
|
#include "../lib/loaders/tinyobj.h"
|
||||||
#include "../lib/djstdlib/core.h"
|
|
||||||
|
|
||||||
Mesh createMesh(const char* obj_file) {
|
Mesh createMesh(const char* obj_file) {
|
||||||
|
Scratch temp = scratchStart(0, 0);
|
||||||
|
|
||||||
Mesh result = {0};
|
Mesh result = {0};
|
||||||
|
|
||||||
tinyobj::ObjReader reader = tinyobj::ObjReader();
|
tinyobj::ObjReader reader = tinyobj::ObjReader();
|
||||||
bool success = reader.ParseFromFile(obj_file);
|
bool success = reader.ParseFromFile(obj_file);
|
||||||
std::cout << reader.Error() << std::endl;
|
log("%s\n", reader.Error().c_str());
|
||||||
|
|
||||||
const tinyobj::attrib_t attrib = reader.GetAttrib();
|
const tinyobj::attrib_t attrib = reader.GetAttrib();
|
||||||
|
|
||||||
std::vector<tinyobj::index_t> indices_t = reader.GetShapes().at(0).mesh.indices;
|
std::vector<tinyobj::index_t> indices_t = reader.GetShapes().at(0).mesh.indices;
|
||||||
std::vector<uint32> indices = std::vector<uint32>(indices_t.size());
|
list<uint32> indices = PushFullList(temp.arena, uint32, indices_t.size());
|
||||||
|
|
||||||
std::vector<real32> vertices = std::vector<real32>(3*indices_t.size());
|
list<real32> vertices = PushFullList(temp.arena, real32, 3*indices_t.size());
|
||||||
std::vector<real32> normals = std::vector<real32>(3*indices_t.size());
|
list<real32> normals = PushFullList(temp.arena, real32, 3*indices_t.size());
|
||||||
std::vector<real32> texcoords = std::vector<real32>(2*indices_t.size());
|
list<real32> texcoords = PushFullList(temp.arena, real32, 2*indices_t.size());
|
||||||
|
|
||||||
for (int i = 0; i < indices_t.size(); i++) {
|
for (int i = 0; i < indices_t.size(); i++) {
|
||||||
tinyobj::index_t vertex_data = indices_t[i];
|
tinyobj::index_t vertex_data = indices_t[i];
|
||||||
vertices[3*i] = attrib.vertices[3*vertex_data.vertex_index];
|
vertices.data[3*i] = attrib.vertices[3*vertex_data.vertex_index];
|
||||||
vertices[3*i+1] = attrib.vertices[3*vertex_data.vertex_index + 1];
|
vertices.data[3*i+1] = attrib.vertices[3*vertex_data.vertex_index + 1];
|
||||||
vertices[3*i+2] = attrib.vertices[3*vertex_data.vertex_index + 2];
|
vertices.data[3*i+2] = attrib.vertices[3*vertex_data.vertex_index + 2];
|
||||||
|
|
||||||
normals[3*i] = attrib.normals[3*vertex_data.normal_index];
|
normals.data[3*i] = attrib.normals[3*vertex_data.normal_index];
|
||||||
normals[3*i+1] = attrib.normals[3*vertex_data.normal_index + 1];
|
normals.data[3*i+1] = attrib.normals[3*vertex_data.normal_index + 1];
|
||||||
normals[3*i+2] = attrib.normals[3*vertex_data.normal_index + 2];
|
normals.data[3*i+2] = attrib.normals[3*vertex_data.normal_index + 2];
|
||||||
|
|
||||||
texcoords[2*i] = attrib.texcoords[2*vertex_data.texcoord_index];
|
texcoords.data[2*i] = attrib.texcoords[2*vertex_data.texcoord_index];
|
||||||
texcoords[2*i+1] = attrib.texcoords[2*vertex_data.texcoord_index + 1];
|
texcoords.data[2*i+1] = attrib.texcoords[2*vertex_data.texcoord_index + 1];
|
||||||
|
|
||||||
indices[i] = i;
|
indices.data[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.num_indices = indices_t.size();
|
result.num_indices = indices_t.size();
|
||||||
@@ -47,22 +46,24 @@ Mesh createMesh(const char* obj_file) {
|
|||||||
glBindVertexArray(result.vao);
|
glBindVertexArray(result.vao);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, result.vbo_xyz);
|
glBindBuffer(GL_ARRAY_BUFFER, result.vbo_xyz);
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * 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.vbo_uv);
|
||||||
glBufferData(GL_ARRAY_BUFFER, texcoords.size() * 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.vbo_norm);
|
||||||
glBufferData(GL_ARRAY_BUFFER, normals.size() * 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);
|
||||||
|
|
||||||
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
|
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
scratchEnd(temp);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "../lib/djstdlib/core.h"
|
#include "../lib/djstdlib/core.h"
|
||||||
#include "../lib/glad/glad.h"
|
#include "../lib/glad/glad.h"
|
||||||
@@ -58,3 +59,32 @@ Shader createShader(string vertex_path, string fragment_path) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix) {
|
||||||
|
glUniformMatrix4fv(
|
||||||
|
glGetUniformLocation(s->prog_id, uniformName),
|
||||||
|
1, GL_FALSE, glm::value_ptr(*matrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix) {
|
||||||
|
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(*matrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector) {
|
||||||
|
glUniform4fv(glGetUniformLocation(s->prog_id, uniformName), 1, glm::value_ptr(*vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniform4fv(int uniformLocation, glm::vec4 *vector) {
|
||||||
|
glUniform4fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector) {
|
||||||
|
glUniform3fv(glGetUniformLocation(s->prog_id, uniformName), 1, glm::value_ptr(*vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUniform3fv(int uniformLocation, glm::vec3 *vector) {
|
||||||
|
glUniform3fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
int getUniformLocation(Shader *s, const char *uniformName) {
|
||||||
|
return glGetUniformLocation(s->prog_id, uniformName);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define LEDDA_SHADER_H
|
#define LEDDA_SHADER_H
|
||||||
|
|
||||||
#include "../lib/djstdlib/core.h"
|
#include "../lib/djstdlib/core.h"
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
uint32 prog_id;
|
uint32 prog_id;
|
||||||
@@ -9,4 +10,15 @@ struct Shader {
|
|||||||
|
|
||||||
Shader createShader(string vertex_path, string fragment_path);
|
Shader createShader(string vertex_path, string fragment_path);
|
||||||
|
|
||||||
|
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix);
|
||||||
|
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix);
|
||||||
|
|
||||||
|
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector);
|
||||||
|
void setUniform4fv(int uniformLocation, glm::vec4 *vector);
|
||||||
|
|
||||||
|
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector);
|
||||||
|
void setUniform3fv(int uniformLocation, glm::vec3 *vector);
|
||||||
|
|
||||||
|
int getUniformLocation(Shader *s, const char *uniformName);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include <iostream>
|
|
||||||
#include "../lib/loaders/stb_image.h"
|
#include "../lib/loaders/stb_image.h"
|
||||||
#include "../lib/glad/glad.h"
|
#include "../lib/glad/glad.h"
|
||||||
|
#include "../lib/djstdlib/core.h"
|
||||||
|
|
||||||
Texture createTexture(const char* source_path) {
|
Texture createTexture(const char* source_path) {
|
||||||
Texture result = {0};
|
Texture result = {0};
|
||||||
@@ -18,7 +18,7 @@ Texture createTexture(const char* source_path) {
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, result.width, result.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, result.width, result.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Failed to load texture." << std::endl;
|
log("Failed to load texture.");
|
||||||
}
|
}
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
|||||||
225
src/main.cpp
225
src/main.cpp
@@ -1,9 +1,9 @@
|
|||||||
#include <iostream>
|
// stdlib TODO(djledda): get rid of this
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// Graphics bindings and libs
|
||||||
#include "lib/glad/glad.c"
|
#include "lib/glad/glad.c"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@@ -11,31 +11,49 @@
|
|||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
// Project
|
||||||
|
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global`
|
||||||
#include "gfx/gfx.cpp"
|
#include "gfx/gfx.cpp"
|
||||||
#include "VoxelSpace.cpp"
|
#include "VoxelSpace.cpp"
|
||||||
#include "SomaSolve.cpp"
|
#include "./tests.cpp"
|
||||||
#include "lib/djstdlib/core.cpp"
|
#include "lib/djstdlib/core.cpp"
|
||||||
|
|
||||||
|
// Library initialisation
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "lib/loaders/stb_image.h"
|
#include "lib/loaders/stb_image.h"
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
#include "./tests.cpp"
|
#include "lib/loaders/tinyobj.h"
|
||||||
|
|
||||||
struct Entity;
|
struct Entity;
|
||||||
struct Polycube;
|
struct Polycube;
|
||||||
struct SceneGraphNode;
|
struct SceneGraphNode;
|
||||||
uint32 new_entity();
|
uint32 new_entity();
|
||||||
Entity *get_entity(int id);
|
Entity *get_entity(uint32 id);
|
||||||
SceneGraphNode *get_scene_graph_node(int id);
|
SceneGraphNode *get_scene_graph_node(int id);
|
||||||
uint32 new_graph_node();
|
uint32 new_graph_node();
|
||||||
|
|
||||||
void print_mat(glm::mat4* matrix) {
|
void log(glm::vec3* vector) {
|
||||||
|
glm::vec3 vec = *vector;
|
||||||
|
log(
|
||||||
|
"┌ ┐\n"
|
||||||
|
"│%7.2f%, %7.2f, %7.2f │\n"
|
||||||
|
"└ ┘\n",
|
||||||
|
vec[0], vec[1], vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log(glm::mat4* matrix) {
|
||||||
glm::mat4 mat = *matrix;
|
glm::mat4 mat = *matrix;
|
||||||
std::cout << mat[0][0] << mat[0][1] << mat[0][2] << mat[0][3] << std::endl;
|
log(
|
||||||
std::cout << mat[1][0] << mat[1][1] << mat[1][2] << mat[1][3] << std::endl;
|
"┌ ┐\n"
|
||||||
std::cout << mat[2][0] << mat[2][1] << mat[2][2] << mat[2][3] << std::endl;
|
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||||
std::cout << mat[3][0] << mat[3][1] << mat[3][2] << mat[3][3] << std::endl;
|
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||||
std::cout << std::endl;
|
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||||
|
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||||
|
"└ ┘\n",
|
||||||
|
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
|
||||||
|
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
|
||||||
|
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
|
||||||
|
mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Camera {
|
struct Camera {
|
||||||
@@ -64,15 +82,6 @@ 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);
|
c->up = glm::vec3(up_x, up_y, up_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GlobalAppState {
|
|
||||||
uint32 current_polycube;
|
|
||||||
uint32 last_polycube_visible;
|
|
||||||
Shader *active_shader;
|
|
||||||
std::vector<Polycube> polycubes;
|
|
||||||
};
|
|
||||||
|
|
||||||
GlobalAppState app_state = {};
|
|
||||||
|
|
||||||
struct WindowDims {
|
struct WindowDims {
|
||||||
uint32 width;
|
uint32 width;
|
||||||
uint32 height;
|
uint32 height;
|
||||||
@@ -95,10 +104,21 @@ struct SceneGraphNode {
|
|||||||
uint32 entity;
|
uint32 entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GlobalAppState {
|
||||||
|
bool wireframe = false;
|
||||||
|
uint32 current_polycube;
|
||||||
|
uint32 last_polycube_visible;
|
||||||
|
uint32 light;
|
||||||
|
Shader *active_shader;
|
||||||
|
std::vector<Polycube> polycubes;
|
||||||
|
};
|
||||||
|
|
||||||
|
GlobalAppState app_state = {};
|
||||||
|
|
||||||
void init_sg_node(SceneGraphNode *n) {
|
void init_sg_node(SceneGraphNode *n) {
|
||||||
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||||
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
n->rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
n->rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
n->local = glm::mat4(1.0f);
|
n->local = glm::mat4(1.0f);
|
||||||
n->world = n->local;
|
n->world = n->local;
|
||||||
}
|
}
|
||||||
@@ -189,11 +209,12 @@ GLFWwindow *init_window_and_gl(WindowDims *window_dims) {
|
|||||||
|
|
||||||
glViewport(0, 0, 800, 600);
|
glViewport(0, 0, 800, 600);
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_update_viewport(WindowDims* window_dims, Frame* frame) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,32 +223,96 @@ Texture wall_tex = {0};
|
|||||||
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>();
|
||||||
|
|
||||||
void process_input(GLFWwindow *window) {
|
struct Input {
|
||||||
local_persist bool wireframe = false;
|
struct {
|
||||||
local_persist bool last_frame_state_press_enter = false;
|
bool escape;
|
||||||
local_persist bool last_frame_state_press = false;
|
bool enter;
|
||||||
|
bool space;
|
||||||
|
bool lshift;
|
||||||
|
bool x;
|
||||||
|
bool y;
|
||||||
|
bool z;
|
||||||
|
} keyboard;
|
||||||
|
struct {
|
||||||
|
real64 x;
|
||||||
|
real64 y;
|
||||||
|
bool btnLeft;
|
||||||
|
bool btnRight;
|
||||||
|
bool btnMiddle;
|
||||||
|
} mouse;
|
||||||
|
};
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
inline bool glfwMouse(GLFWwindow *window, int mouseBtnCode) {
|
||||||
|
switch (glfwGetMouseButton(window, mouseBtnCode)) {
|
||||||
|
case GLFW_RELEASE: return false;
|
||||||
|
case GLFW_PRESS: return true;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool glfwKey(GLFWwindow *window, int keyCode) {
|
||||||
|
switch (glfwGetKey(window, keyCode)) {
|
||||||
|
case GLFW_RELEASE: return false;
|
||||||
|
case GLFW_PRESS: return true;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Input get_current_input(GLFWwindow *window) {
|
||||||
|
Input input = {0};
|
||||||
|
|
||||||
|
input.keyboard.escape = glfwKey(window, GLFW_KEY_ESCAPE);
|
||||||
|
input.keyboard.enter = glfwKey(window, GLFW_KEY_ENTER);
|
||||||
|
input.keyboard.space = glfwKey(window, GLFW_KEY_SPACE);
|
||||||
|
input.keyboard.lshift = glfwKey(window, GLFW_KEY_LEFT_SHIFT);
|
||||||
|
input.keyboard.x = glfwKey(window, GLFW_KEY_X);
|
||||||
|
input.keyboard.y = glfwKey(window, GLFW_KEY_Y);
|
||||||
|
input.keyboard.z = glfwKey(window, GLFW_KEY_Z);
|
||||||
|
|
||||||
|
input.mouse.btnLeft = glfwMouse(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
input.mouse.btnRight = glfwMouse(window, GLFW_MOUSE_BUTTON_RIGHT);
|
||||||
|
input.mouse.btnMiddle = glfwMouse(window, GLFW_MOUSE_BUTTON_MIDDLE);
|
||||||
|
|
||||||
|
glfwGetCursorPos(window, &input.mouse.x, &input.mouse.y);
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_input(GLFWwindow *window, Input *input, Input *prevInput) {
|
||||||
|
if (input->keyboard.escape) {
|
||||||
glfwSetWindowShouldClose(window, true);
|
glfwSetWindowShouldClose(window, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && !last_frame_state_press) {
|
if (input->keyboard.space && !prevInput->keyboard.space) {
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, !wireframe ? GL_LINE : GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, !app_state.wireframe ? GL_LINE : GL_FILL);
|
||||||
wireframe = !wireframe;
|
app_state.wireframe = !app_state.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) {
|
SceneGraphNode *node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node);
|
||||||
|
int shiftMultiplier = input->keyboard.lshift ? -1 : 1;
|
||||||
|
node->translation.x += 1.0 * input->keyboard.x * shiftMultiplier;
|
||||||
|
node->translation.y += 1.0 * input->keyboard.y * shiftMultiplier;
|
||||||
|
node->translation.z += 1.0 * input->keyboard.z * shiftMultiplier;
|
||||||
|
|
||||||
|
if (input->keyboard.enter && !prevInput->keyboard.enter) {
|
||||||
if (app_state.current_polycube == 6) {
|
if (app_state.current_polycube == 6) {
|
||||||
app_state.current_polycube = 0;
|
app_state.current_polycube = 0;
|
||||||
} else {
|
} else {
|
||||||
app_state.current_polycube += 1;
|
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;
|
if (input->mouse.btnLeft) {
|
||||||
|
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.006;
|
||||||
|
Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube];
|
||||||
|
SceneGraphNode *polycube_graph_node = get_scene_graph_node(current_polycube->graph_node);
|
||||||
|
if (deltaX > 0.00000001 || deltaX < -0.00000001) {
|
||||||
|
polycube_graph_node->rotation = glm::quat(glm::vec3(0, deltaX, 0)) * polycube_graph_node->rotation;
|
||||||
|
}
|
||||||
|
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.006;
|
||||||
|
if (deltaY > 0.00000001 || deltaY < -0.00000001) {
|
||||||
|
polycube_graph_node->rotation = polycube_graph_node->rotation * glm::quat(glm::vec3(deltaY, 0, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +325,7 @@ uint32 new_entity() {
|
|||||||
return (uint32)entities.size();
|
return (uint32)entities.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *get_entity(int id) {
|
Entity *get_entity(uint32 id) {
|
||||||
return &entities[id - 1];
|
return &entities[id - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,16 +397,20 @@ int main_gfx() {
|
|||||||
app_state.last_polycube_visible = 6;
|
app_state.last_polycube_visible = 6;
|
||||||
app_state.active_shader = 0;
|
app_state.active_shader = 0;
|
||||||
app_state.polycubes = {};
|
app_state.polycubes = {};
|
||||||
|
app_state.light = new_entity();
|
||||||
|
|
||||||
Shader phong_shader = createShader("../assets/shaders/phong-solid.vertex.glsl"_s, "../assets/shaders/phong-solid.fragment.glsl"_s);
|
SceneGraphNode *light_graph_node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node);
|
||||||
|
light_graph_node->translation = glm::vec3(4.0f, 24.0f, 6.0f);
|
||||||
|
|
||||||
|
Shader phong_shader = createShader(
|
||||||
|
"./assets/shaders/phong-solid.vertex.glsl"_s,
|
||||||
|
"./assets/shaders/phong-solid.fragment.glsl"_s);
|
||||||
app_state.active_shader = &phong_shader;
|
app_state.active_shader = &phong_shader;
|
||||||
|
|
||||||
cube_mesh = createMesh("../assets/models/c000000.obj");
|
cube_mesh = createMesh("./assets/models/c000000.obj");
|
||||||
wall_tex = createTexture("../assets/textures/brick-wall.jpg");
|
wall_tex = createTexture("./assets/textures/brick-wall.jpg");
|
||||||
|
|
||||||
Frame little_frame = createFrame(arena, 80, 60, 20, 20);
|
Frame main_frame = createFrame(arena, 800, 600, 0, 0);
|
||||||
Frame big_frame = createFrame(arena, 800, 600, 0, 0);
|
|
||||||
Frame *frames[] = { &big_frame, &little_frame };
|
|
||||||
|
|
||||||
SceneGraphNode root_node = {};
|
SceneGraphNode root_node = {};
|
||||||
init_sg_node(&root_node);
|
init_sg_node(&root_node);
|
||||||
@@ -335,27 +424,28 @@ int main_gfx() {
|
|||||||
root_node.children.push_back(app_state.polycubes.back().graph_node);
|
root_node.children.push_back(app_state.polycubes.back().graph_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
big_frame.cam->pos = glm::vec3(0.0f, 4.0f, 4.0f);
|
main_frame.cam->pos = glm::vec3(4.0f, 4.0f, 4.0f);
|
||||||
camera_look_at(big_frame.cam, 0.0f, 0.0f, 0.0f);
|
camera_look_at(main_frame.cam, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
glm::vec3 light_pos = glm::vec3(-15.0f, 10.0f, 6.0f);
|
|
||||||
|
|
||||||
glUseProgram(app_state.active_shader->prog_id);
|
glUseProgram(app_state.active_shader->prog_id);
|
||||||
glUniform3fv(
|
|
||||||
glGetUniformLocation(app_state.active_shader->prog_id, "light_pos"),
|
setUniformMat4fv(app_state.active_shader, "projection", &main_frame.cam->proj);
|
||||||
1, glm::value_ptr(light_pos));
|
setUniformMat4fv(app_state.active_shader, "view", &main_frame.cam->view);
|
||||||
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));
|
|
||||||
|
|
||||||
real64 last_frame = glfwGetTime();
|
real64 last_frame = glfwGetTime();
|
||||||
real64 time_delta = 1.0f/60.0f;
|
real64 time_delta = 1.0f/60.0f;
|
||||||
|
|
||||||
|
glm::vec3 lastLightPos = {};
|
||||||
|
Input prevInput = {};
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
time_delta = glfwGetTime() - last_frame;
|
time_delta = glfwGetTime() - last_frame;
|
||||||
process_input(window);
|
glfwPollEvents();
|
||||||
|
Input input = get_current_input(window);
|
||||||
|
process_input(window, &input, &prevInput);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
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]);
|
||||||
@@ -366,20 +456,19 @@ int main_gfx() {
|
|||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
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);
|
||||||
|
|
||||||
gl_update_viewport(&window_dims, &big_frame);
|
update_viewport_from_frame(&window_dims, &main_frame);
|
||||||
|
|
||||||
Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube];
|
Polycube *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);
|
glBindVertexArray(cube_mesh.vao);
|
||||||
recalculate_scene_graph(&root_node);
|
recalculate_scene_graph(&root_node);
|
||||||
GLint model_uniform_loc = glGetUniformLocation(app_state.active_shader->prog_id, "model");
|
|
||||||
glUniform3fv(
|
|
||||||
glGetUniformLocation(app_state.active_shader->prog_id, "solid_color"),
|
|
||||||
1, glm::value_ptr(current_polycube->color));
|
|
||||||
|
|
||||||
|
setUniform3fv(app_state.active_shader, "solid_color", ¤t_polycube->color);
|
||||||
|
|
||||||
|
int model_uniform = getUniformLocation(app_state.active_shader, "model");
|
||||||
for (Entity &entity : entities) {
|
for (Entity &entity : entities) {
|
||||||
if (entity.visible) {
|
if (entity.visible) {
|
||||||
glUniformMatrix4fv(model_uniform_loc, 1, GL_FALSE, glm::value_ptr(get_scene_graph_node(entity.scene_graph_node)->world));
|
setUniformMat4fv(model_uniform, &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);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices);
|
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices);
|
||||||
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
|
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
|
||||||
@@ -387,7 +476,7 @@ int main_gfx() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
prevInput = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|||||||
Reference in New Issue
Block a user