update
This commit is contained in:
@@ -2,29 +2,28 @@
|
|||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
uniform vec3 light_pos;
|
uniform vec3 light_pos;
|
||||||
uniform vec3 solid_color;
|
uniform vec4 solid_color;
|
||||||
uniform vec3 camera;
|
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);
|
vec4 light_color = vec4(1, 1, 1, 1);
|
||||||
vec3 normal_norm = normalize(normal);
|
vec3 normal_norm = normalize(normal);
|
||||||
vec3 light_direction_norm = normalize(light_pos - frag_position);
|
vec3 light_direction_norm = normalize(light_pos - frag_position);
|
||||||
|
|
||||||
float ambient_strength = 0.15;
|
float ambient_strength = 0.15;
|
||||||
vec3 ambient = ambient_strength * light_color;
|
vec4 ambient = ambient_strength * light_color;
|
||||||
|
|
||||||
float diffuse_strength = max(dot(normal_norm, light_direction_norm), 0.0);
|
float diffuse_strength = max(dot(normal_norm, light_direction_norm), 0.0);
|
||||||
vec3 diffuse = diffuse_strength * light_color;
|
vec4 diffuse = diffuse_strength * light_color;
|
||||||
|
|
||||||
float specular_strength = 0.9;
|
float specular_strength = 0.9;
|
||||||
vec3 view_direction_norm = normalize(camera - frag_position);
|
vec3 view_direction_norm = normalize(camera - frag_position);
|
||||||
vec3 reflect_dir = reflect(-light_direction_norm, normal_norm);
|
vec3 reflect_dir = reflect(-light_direction_norm, normal_norm);
|
||||||
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;
|
vec4 specular = specular_strength * spec * light_color;
|
||||||
|
|
||||||
vec3 phong = specular + (ambient + diffuse) * solid_color;
|
frag_color = specular + (ambient + diffuse) * solid_color;
|
||||||
frag_color = vec4(phong, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ layout (location = 2) in vec3 a_normal;
|
|||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform vec3 light_pos;
|
|
||||||
|
|
||||||
out vec3 normal;
|
out vec3 normal;
|
||||||
out vec3 frag_position;
|
out vec3 frag_position;
|
||||||
|
|||||||
@@ -296,3 +296,23 @@ int size(uint64 space) {
|
|||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool spaceValueAt(Space *space, int x, int y, int z) {
|
||||||
|
uint64 mask = 1 << (space->dim_y * space->dim_z * x + space->dim_z * y + z);
|
||||||
|
return (space->space & mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spaceToggle(Space *space, int x, int y, int z) {
|
||||||
|
uint64 mask = 1 << (space->dim_y * space->dim_z * x + space->dim_z * y + z);
|
||||||
|
space->space ^= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spaceSet(Space *space, bool val, int x, int y, int z) {
|
||||||
|
uint64 mask = 1 << (space->dim_y * space->dim_z * x + space->dim_z * y + z);
|
||||||
|
if (val) {
|
||||||
|
space->space |= mask;
|
||||||
|
} else {
|
||||||
|
space->space &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,4 +63,10 @@ list<uint64> getAllPermutationsInPrism(Arena *arena, Space *space, int prism_dim
|
|||||||
|
|
||||||
int size(uint64 space);
|
int size(uint64 space);
|
||||||
|
|
||||||
|
bool spaceValueAt(Space *space, int x, int y, int z);
|
||||||
|
|
||||||
|
void spaceToggle(Space *space, int x, int y, int z);
|
||||||
|
|
||||||
|
void spaceSet(Space *space, bool val, int x, int y, int z);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#include <glm/ext/vector_float3.hpp>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "../lib/djstdlib/core.h"
|
#include "Color.h"
|
||||||
|
|
||||||
real32 hue_to_rgb(real32 p, real32 q, real32 t) {
|
real32 hueToRGB(real32 p, real32 q, real32 t) {
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
t += 1;
|
t += 1;
|
||||||
} else if (t > 1) {
|
} else if (t > 1) {
|
||||||
@@ -14,7 +13,7 @@ real32 hue_to_rgb(real32 p, real32 q, real32 t) {
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
glm::vec3 hsl_to_hex(real32 h, real32 s, real32 l) {
|
Vector4<real32> hslToHex(real32 h, real32 s, real32 l) {
|
||||||
h /= 360;
|
h /= 360;
|
||||||
s /= 100;
|
s /= 100;
|
||||||
l /= 100;
|
l /= 100;
|
||||||
@@ -24,14 +23,14 @@ glm::vec3 hsl_to_hex(real32 h, real32 s, real32 l) {
|
|||||||
} else {
|
} else {
|
||||||
real32 q = l < 0.5f ? l * (1 + s) : l + s - l * s;
|
real32 q = l < 0.5f ? l * (1 + s) : l + s - l * s;
|
||||||
real32 p = 2 * l - q;
|
real32 p = 2 * l - q;
|
||||||
r = hue_to_rgb(p, q, h + 1.0f / 3);
|
r = hueToRGB(p, q, h + 1.0f / 3);
|
||||||
g = hue_to_rgb(p, q, h);
|
g = hueToRGB(p, q, h);
|
||||||
b = hue_to_rgb(p, q, h - 1.0f / 3);
|
b = hueToRGB(p, q, h - 1.0f / 3);
|
||||||
}
|
}
|
||||||
return glm::vec3(r, g, b);
|
return vec4<real32>(r, g, b, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 color_from_index(int index) {
|
Vector4<real32> colorFromIndex(int index) {
|
||||||
real32 color_wheel_cycle = floorf(index / 6.0f);
|
real32 color_wheel_cycle = floorf(index / 6.0f);
|
||||||
real32 darkness_cycle = floorf(index / 12.0f);
|
real32 darkness_cycle = floorf(index / 12.0f);
|
||||||
real32 spacing = (360.0f / 6.0f);
|
real32 spacing = (360.0f / 6.0f);
|
||||||
@@ -39,5 +38,5 @@ glm::vec3 color_from_index(int index) {
|
|||||||
real32 hue = spacing * (index % 6) + offset;
|
real32 hue = spacing * (index % 6) + offset;
|
||||||
real32 saturation = 100.0f;
|
real32 saturation = 100.0f;
|
||||||
real32 lightness = 1.0f / (2 + darkness_cycle) * 100;
|
real32 lightness = 1.0f / (2 + darkness_cycle) * 100;
|
||||||
return hsl_to_hex(hue, saturation, lightness);
|
return hslToHex(hue, saturation, lightness);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
#include <glm/ext/vector_float3.hpp>
|
#ifndef COLOR_H
|
||||||
|
#define COLOR_H
|
||||||
|
|
||||||
glm::vec3 color_from_index(int index);
|
#include "../lib/djstdlib/core.h"
|
||||||
|
|
||||||
|
#define COLOR_BLACK vec4<real32>(0, 0, 0, 1)
|
||||||
|
#define COLOR_RED vec4<real32>(1, 0, 0, 1)
|
||||||
|
#define COLOR_GREEN vec4<real32>(0, 1, 0, 1)
|
||||||
|
#define COLOR_BLUE vec4<real32>(0, 0, 1, 1)
|
||||||
|
#define COLOR_MAGENTA vec4<real32>(1, 0, 1, 1)
|
||||||
|
#define COLOR_YELLOW vec4<real32>(1, 1, 0, 1)
|
||||||
|
#define COLOR_CYAN vec4<real32>(0, 1, 1, 1)
|
||||||
|
#define COLOR_WHITE vec4<real32>(1, 1, 1, 1)
|
||||||
|
|
||||||
|
Vector4<real32> colorFromIndex(int index);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -38,18 +38,18 @@ Shader createShader(string vertex_path, string fragment_path) {
|
|||||||
uint32 vertex_shader = createGlShader(vertex_path, ShaderType::vertex);
|
uint32 vertex_shader = createGlShader(vertex_path, ShaderType::vertex);
|
||||||
uint32 fragment_shader = createGlShader(fragment_path, ShaderType::fragment);
|
uint32 fragment_shader = createGlShader(fragment_path, ShaderType::fragment);
|
||||||
|
|
||||||
result.prog_id = glCreateProgram();
|
result.progId = glCreateProgram();
|
||||||
glAttachShader(result.prog_id, vertex_shader);
|
glAttachShader(result.progId, vertex_shader);
|
||||||
glAttachShader(result.prog_id, fragment_shader);
|
glAttachShader(result.progId, fragment_shader);
|
||||||
glLinkProgram(result.prog_id);
|
glLinkProgram(result.progId);
|
||||||
|
|
||||||
int success;
|
int success;
|
||||||
glGetProgramiv(result.prog_id, GL_LINK_STATUS, &success);
|
glGetProgramiv(result.progId, GL_LINK_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
GLint info_log_length;
|
GLint info_log_length;
|
||||||
glGetShaderiv(result.prog_id, GL_INFO_LOG_LENGTH, &info_log_length);
|
glGetShaderiv(result.progId, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||||
string info_log_prog = PushString(temp.arena, (size_t)info_log_length + 1);
|
string info_log_prog = PushString(temp.arena, (size_t)info_log_length + 1);
|
||||||
glGetProgramInfoLog(result.prog_id, info_log_length, NULL, info_log_prog.str);
|
glGetProgramInfoLog(result.progId, info_log_length, NULL, info_log_prog.str);
|
||||||
print("Shader program link error:\n%S", info_log_prog);
|
print("Shader program link error:\n%S", info_log_prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,38 +62,43 @@ Shader createShader(string vertex_path, string fragment_path) {
|
|||||||
|
|
||||||
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix) {
|
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix) {
|
||||||
glUniformMatrix4fv(
|
glUniformMatrix4fv(
|
||||||
glGetUniformLocation(s->prog_id, uniformName),
|
glGetUniformLocation(s->progId, uniformName),
|
||||||
1, GL_FALSE, glm::value_ptr(*matrix));
|
1, GL_FALSE, glm::value_ptr(*matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix) {
|
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix) {
|
||||||
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(*matrix));
|
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(*matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector) {
|
void setUniform4fv(Shader *s, const char *uniformName, Vector4<real32> *vector) {
|
||||||
glUniform4fv(glGetUniformLocation(s->prog_id, uniformName), 1, glm::value_ptr(*vector));
|
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||||
|
}
|
||||||
|
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector) {
|
||||||
|
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform4fv(int uniformLocation, glm::vec4 *vector) {
|
void setUniform4fv(int uniformLocation, glm::vec4 *vector) {
|
||||||
glUniform4fv(uniformLocation, 1, glm::value_ptr(*vector));
|
glUniform4fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector) {
|
void setUniform3fv(Shader *s, const char *uniformName, Vector3<real32> *vector) {
|
||||||
glUniform3fv(glGetUniformLocation(s->prog_id, uniformName), 1, glm::value_ptr(*vector));
|
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||||
|
}
|
||||||
|
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector) {
|
||||||
|
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform3fv(int uniformLocation, glm::vec3 *vector) {
|
void setUniform3fv(int uniformLocation, glm::vec3 *vector) {
|
||||||
glUniform3fv(uniformLocation, 1, glm::value_ptr(*vector));
|
glUniform3fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector) {
|
void setUniform2fv(Shader *s, const char *uniformName, Vector2<real32> *vector) {
|
||||||
glUniform2fv(glGetUniformLocation(s->prog_id, uniformName), 1, glm::value_ptr(*vector));
|
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||||
|
}
|
||||||
|
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector) {
|
||||||
|
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUniform2fv(int uniformLocation, glm::vec2 *vector) {
|
void setUniform2fv(int uniformLocation, glm::vec2 *vector) {
|
||||||
glUniform2fv(uniformLocation, 1, glm::value_ptr(*vector));
|
glUniform2fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||||
}
|
}
|
||||||
|
|
||||||
int getUniformLocation(Shader *s, const char *uniformName) {
|
int getUniformLocation(Shader *s, const char *uniformName) {
|
||||||
return glGetUniformLocation(s->prog_id, uniformName);
|
return glGetUniformLocation(s->progId, uniformName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "../lib/djstdlib/core.h"
|
#include "../lib/djstdlib/core.h"
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
uint32 prog_id;
|
uint32 progId;
|
||||||
};
|
};
|
||||||
|
|
||||||
Shader createShader(string vertex_path, string fragment_path);
|
Shader createShader(string vertex_path, string fragment_path);
|
||||||
|
|||||||
10
src/gfx/gfx.h
Normal file
10
src/gfx/gfx.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef GFX_H
|
||||||
|
#define GFX_H
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
5079
src/lib/loaders/stb_truetype.h
Normal file
5079
src/lib/loaders/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
575
src/main.cpp
575
src/main.cpp
@@ -15,6 +15,7 @@
|
|||||||
// Project
|
// Project
|
||||||
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global`
|
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global`
|
||||||
#include "gfx/gfx.cpp"
|
#include "gfx/gfx.cpp"
|
||||||
|
#include "world/world.cpp"
|
||||||
#include "VoxelSpace.cpp"
|
#include "VoxelSpace.cpp"
|
||||||
#include "./tests.cpp"
|
#include "./tests.cpp"
|
||||||
#include "lib/djstdlib/core.cpp"
|
#include "lib/djstdlib/core.cpp"
|
||||||
@@ -27,13 +28,6 @@
|
|||||||
|
|
||||||
#define PI (real32)3.14159265358979323846264338327950288
|
#define PI (real32)3.14159265358979323846264338327950288
|
||||||
|
|
||||||
struct Entity;
|
|
||||||
struct SceneGraphNode;
|
|
||||||
uint32 new_entity();
|
|
||||||
Entity *get_entity(uint32 id);
|
|
||||||
SceneGraphNode *get_scene_graph_node(int id);
|
|
||||||
uint32 new_graph_node();
|
|
||||||
|
|
||||||
void print(glm::vec3* vector) {
|
void print(glm::vec3* vector) {
|
||||||
glm::vec3 vec = *vector;
|
glm::vec3 vec = *vector;
|
||||||
print(
|
print(
|
||||||
@@ -75,7 +69,7 @@ Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void camera_look_at(Camera *c, float x, float y, float z) {
|
void cameraLookAt(Camera *c, float x, float y, float z) {
|
||||||
c->target = glm::vec3(x, y, z);
|
c->target = glm::vec3(x, y, z);
|
||||||
c->view = glm::lookAt(c->pos, c->target, c->up);
|
c->view = glm::lookAt(c->pos, c->target, c->up);
|
||||||
}
|
}
|
||||||
@@ -84,28 +78,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 WindowDims {
|
|
||||||
uint32 width;
|
|
||||||
uint32 height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Entity {
|
|
||||||
Mesh *mesh;
|
|
||||||
Texture *tex;
|
|
||||||
bool visible;
|
|
||||||
uint32 scene_graph_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SceneGraphNode {
|
|
||||||
glm::mat4 local;
|
|
||||||
glm::mat4 world;
|
|
||||||
glm::vec3 translation;
|
|
||||||
glm::quat rotation;
|
|
||||||
glm::vec3 scale;
|
|
||||||
std::vector<uint32> children;
|
|
||||||
uint32 entity;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
uint32 width;
|
uint32 width;
|
||||||
uint32 height;
|
uint32 height;
|
||||||
@@ -115,69 +87,108 @@ struct Frame {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Polycube {
|
struct Polycube {
|
||||||
int graph_node;
|
uint32 entityHandle;
|
||||||
Space repr;
|
Space repr;
|
||||||
glm::vec3 color;
|
Vector4<real32> color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GlobalAppState {
|
struct RenderObjects_Rectangle {
|
||||||
bool wireframe = false;
|
uint32 vao;
|
||||||
uint32 current_polycube;
|
list<Vector2<real32>> p0;
|
||||||
uint32 last_polycube_visible;
|
uint32 p0BufferId;
|
||||||
|
list<Vector2<real32>> p1;
|
||||||
|
uint32 p1BufferId;
|
||||||
|
list<Vector4<real32>> color;
|
||||||
|
uint32 colorBufferId;
|
||||||
|
uint64 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Input {
|
||||||
|
struct {
|
||||||
|
bool escape;
|
||||||
|
bool enter;
|
||||||
|
bool space;
|
||||||
|
bool lshift;
|
||||||
|
bool x;
|
||||||
|
bool y;
|
||||||
|
bool z;
|
||||||
|
} keyboard;
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
real32 x;
|
||||||
|
real32 y;
|
||||||
|
};
|
||||||
|
Vector2<real32> point;
|
||||||
|
};
|
||||||
|
bool btnLeft;
|
||||||
|
bool btnRight;
|
||||||
|
bool btnMiddle;
|
||||||
|
} mouse;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Renderer {
|
||||||
|
Scene *scene;
|
||||||
|
RenderObjects_Rectangle rects;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PolycubeInput {
|
||||||
|
Space repr;
|
||||||
|
Vector4<real32> color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SomaState {
|
||||||
|
bool wireframe;
|
||||||
|
bool polycubeDirty;
|
||||||
|
uint32 currentPolycube;
|
||||||
|
uint32 lastPolycubeVisible;
|
||||||
uint32 light;
|
uint32 light;
|
||||||
Shader *active_shader;
|
list<Polycube> polycubes;
|
||||||
std::vector<Polycube> polycubes;
|
|
||||||
Camera* camera;
|
Camera* camera;
|
||||||
glm::vec3 rotAxisX;
|
glm::vec3 rotAxisX;
|
||||||
glm::vec3 rotAxisY;
|
glm::vec3 rotAxisY;
|
||||||
|
list<PolycubeInput> polycubeInput;
|
||||||
};
|
};
|
||||||
|
|
||||||
GlobalAppState app_state = {};
|
struct Soma {
|
||||||
|
Scene *scene;
|
||||||
|
Renderer *renderer;
|
||||||
|
SomaState state;
|
||||||
|
Input currInput;
|
||||||
|
Input prevInput;
|
||||||
|
struct {
|
||||||
|
GLFWwindow *handle;
|
||||||
|
uint32 width;
|
||||||
|
uint32 height;
|
||||||
|
} window;
|
||||||
|
};
|
||||||
|
|
||||||
void init_sg_node(SceneGraphNode *n) {
|
void showEntity(Scene *scene, uint32 entityHandle) {
|
||||||
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
|
||||||
n->translation = glm::vec3(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->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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void show_polycube(Polycube *p) {
|
|
||||||
SceneGraphNode *node = get_scene_graph_node(p->graph_node);
|
|
||||||
for (uint32 &child : node->children) {
|
for (uint32 &child : node->children) {
|
||||||
SceneGraphNode *subNode = get_scene_graph_node(child);
|
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
|
||||||
if (subNode->entity) {
|
if (subNode->entityHandle) {
|
||||||
get_entity(subNode->entity)->visible = true;
|
getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hide_polycube(Polycube *p) {
|
void hideEntity(Scene *scene, uint32 entityHandle) {
|
||||||
SceneGraphNode *node = get_scene_graph_node(p->graph_node);
|
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
|
||||||
for (uint32 &child : node->children) {
|
for (uint32 &child : node->children) {
|
||||||
SceneGraphNode *subNode = get_scene_graph_node(child);
|
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
|
||||||
if (subNode->entity) {
|
if (subNode->entityHandle) {
|
||||||
get_entity(subNode->entity)->visible = false;
|
getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 centreFromPolycube(Polycube *p) {
|
glm::vec3 centreFromPolycube(Scene *scene, Polycube *p) {
|
||||||
glm::vec3 centre = glm::vec3(0.0f);
|
glm::vec3 centre = glm::vec3(0.0f);
|
||||||
for (uint32 &child : get_scene_graph_node(p->graph_node)->children) {
|
for (uint32 &child : getSceneGraphNode(scene, p->entityHandle)->children) {
|
||||||
centre += get_scene_graph_node(child)->translation;
|
centre += getSceneGraphNode(scene, child)->translation;
|
||||||
}
|
}
|
||||||
centre /= get_scene_graph_node(p->graph_node)->children.size();
|
centre /= getSceneGraphNodeForEntity(scene, p->entityHandle)->children.size();
|
||||||
return centre;
|
return centre;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,67 +202,61 @@ Frame createFrame(Arena *arena, uint32 width, uint32 height, uint32 x, uint32 y)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
|
void framebufferSizeCallback(GLFWwindow *window, int width, int height) {
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWwindow *init_window_and_gl(WindowDims *window_dims) {
|
GLFWwindow *initWindowAndGL(uint32 windowWidth, uint32 windowHeight) {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
GLFWwindow *window = glfwCreateWindow(window_dims->width, window_dims->height, "Somaesque", NULL, NULL);
|
GLFWwindow *window = glfwCreateWindow(windowWidth, windowHeight, "Somaesque", NULL, NULL);
|
||||||
if (window == NULL) {
|
if (window == NULL) {
|
||||||
std::cout << "Failed to create GLFW window" << std::endl;
|
print("Failed to create GLFW window\n");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||||
std::cout << "Failed to initilaize GLAD" << std::endl;
|
print("Failed to initilaize GLAD\n");
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, 800, 600);
|
glViewport(0, 0, 800, 600);
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
|
||||||
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_viewport_from_frame(WindowDims* window_dims, Frame* frame) {
|
void updateViewportFromFrame(uint32 windowWidth, uint32 windowHeight, Frame* frame) {
|
||||||
glViewport(frame->x, window_dims->height - frame->y - frame->height, frame->width, frame->height);
|
glViewport(frame->x, windowHeight - frame->y - frame->height, frame->width, frame->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh cube_mesh = {0};
|
struct UI_Context {
|
||||||
Texture wall_tex = {0};
|
Renderer *renderer;
|
||||||
|
Input *prevInput;
|
||||||
Shader solid_color_shader;
|
Input *input;
|
||||||
Shader phong_shader;
|
bool cursorIsPointer;
|
||||||
|
|
||||||
std::vector<Entity> entities = std::vector<Entity>();
|
|
||||||
std::vector<SceneGraphNode> scene_graph_nodes = std::vector<SceneGraphNode>();
|
|
||||||
|
|
||||||
struct Input {
|
|
||||||
struct {
|
|
||||||
bool escape;
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UI_Rect {
|
||||||
|
real32 x;
|
||||||
|
real32 y;
|
||||||
|
real32 width;
|
||||||
|
real32 height;
|
||||||
|
real32 borderRadius;
|
||||||
|
Vector4<real32> color;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mesh cubeMesh = {0};
|
||||||
|
Texture wallTex = {0};
|
||||||
|
|
||||||
|
Shader solidColorShader;
|
||||||
|
Shader phongShader;
|
||||||
|
|
||||||
inline bool glfwMouse(GLFWwindow *window, int mouseBtnCode) {
|
inline bool glfwMouse(GLFWwindow *window, int mouseBtnCode) {
|
||||||
switch (glfwGetMouseButton(window, mouseBtnCode)) {
|
switch (glfwGetMouseButton(window, mouseBtnCode)) {
|
||||||
case GLFW_RELEASE: return false;
|
case GLFW_RELEASE: return false;
|
||||||
@@ -268,7 +273,7 @@ inline bool glfwKey(GLFWwindow *window, int keyCode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Input get_current_input(GLFWwindow *window) {
|
Input getCurrentInput(GLFWwindow *window) {
|
||||||
Input input = {0};
|
Input input = {0};
|
||||||
|
|
||||||
input.keyboard.escape = glfwKey(window, GLFW_KEY_ESCAPE);
|
input.keyboard.escape = glfwKey(window, GLFW_KEY_ESCAPE);
|
||||||
@@ -283,130 +288,87 @@ Input get_current_input(GLFWwindow *window) {
|
|||||||
input.mouse.btnRight = glfwMouse(window, GLFW_MOUSE_BUTTON_RIGHT);
|
input.mouse.btnRight = glfwMouse(window, GLFW_MOUSE_BUTTON_RIGHT);
|
||||||
input.mouse.btnMiddle = glfwMouse(window, GLFW_MOUSE_BUTTON_MIDDLE);
|
input.mouse.btnMiddle = glfwMouse(window, GLFW_MOUSE_BUTTON_MIDDLE);
|
||||||
|
|
||||||
glfwGetCursorPos(window, &input.mouse.x, &input.mouse.y);
|
real64 mouseX;
|
||||||
|
real64 mouseY;
|
||||||
|
glfwGetCursorPos(window, &mouseX, &mouseY);
|
||||||
|
input.mouse.point = vec2<real32>((real32)mouseX, (real32)mouseY);
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_input(GLFWwindow *window, Input *input, Input *prevInput) {
|
void processInput(Soma *soma) {
|
||||||
|
Input *input = &soma->currInput;
|
||||||
|
Input *prevInput = &soma->prevInput;
|
||||||
|
|
||||||
if (input->keyboard.escape) {
|
if (input->keyboard.escape) {
|
||||||
glfwSetWindowShouldClose(window, true);
|
glfwSetWindowShouldClose(soma->window.handle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->keyboard.space && !prevInput->keyboard.space) {
|
if (input->keyboard.space && !prevInput->keyboard.space) {
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, !app_state.wireframe ? GL_LINE : GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, !soma->state.wireframe ? GL_LINE : GL_FILL);
|
||||||
app_state.wireframe = !app_state.wireframe;
|
soma->state.wireframe = !soma->state.wireframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneGraphNode *node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node);
|
SceneGraphNode *node = getSceneGraphNode(soma->scene, getEntity(soma->scene, soma->state.light)->graphNodeHandle);
|
||||||
int shiftMultiplier = input->keyboard.lshift ? -1 : 1;
|
int shiftMultiplier = input->keyboard.lshift ? -1 : 1;
|
||||||
node->translation.x += 1.0 * input->keyboard.x * shiftMultiplier;
|
node->translation.x += 1.0 * input->keyboard.x * shiftMultiplier;
|
||||||
node->translation.y += 1.0 * input->keyboard.y * shiftMultiplier;
|
node->translation.y += 1.0 * input->keyboard.y * shiftMultiplier;
|
||||||
node->translation.z += 1.0 * input->keyboard.z * shiftMultiplier;
|
node->translation.z += 1.0 * input->keyboard.z * shiftMultiplier;
|
||||||
|
|
||||||
if (input->keyboard.enter && !prevInput->keyboard.enter) {
|
if (input->keyboard.enter && !prevInput->keyboard.enter) {
|
||||||
if (app_state.current_polycube == 6) {
|
if (soma->state.currentPolycube == 6) {
|
||||||
app_state.current_polycube = 0;
|
soma->state.currentPolycube = 0;
|
||||||
} else {
|
} else {
|
||||||
app_state.current_polycube += 1;
|
soma->state.currentPolycube += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dragScene = false;
|
||||||
if (input->mouse.btnLeft) {
|
if (input->mouse.btnLeft) {
|
||||||
Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube];
|
Polycube *current_polycube = &soma->state.polycubes.data[soma->state.currentPolycube];
|
||||||
SceneGraphNode *polycube_graph_node = get_scene_graph_node(current_polycube->graph_node);
|
SceneGraphNode *polycubeGraphNode = getSceneGraphNodeForEntity(soma->scene, current_polycube->entityHandle);
|
||||||
|
|
||||||
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005;
|
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005;
|
||||||
if (deltaX > 0.00000001 || deltaX < -0.00000001) {
|
if (deltaX > 0.00000001 || deltaX < -0.00000001) {
|
||||||
polycube_graph_node->rotation *= glm::angleAxis((real32)deltaX, app_state.rotAxisY);
|
polycubeGraphNode->rotation *= glm::angleAxis((real32)deltaX, soma->state.rotAxisY);
|
||||||
}
|
}
|
||||||
|
|
||||||
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005;
|
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005;
|
||||||
if (deltaY > 0.00000001 || deltaY < -0.00000001) {
|
if (deltaY > 0.00000001 || deltaY < -0.00000001) {
|
||||||
polycube_graph_node->rotation = glm::angleAxis(-(real32)deltaY, app_state.rotAxisX) * polycube_graph_node->rotation;
|
polycubeGraphNode->rotation = glm::angleAxis(-(real32)deltaY, soma->state.rotAxisX) * polycubeGraphNode->rotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 new_entity() {
|
Polycube createPolycubeFromRepr(Soma *soma, Space *repr, Vector4<real32> color) {
|
||||||
entities.emplace_back();
|
uint32 polycubeMainEntityHandle = createEntity(soma->scene);
|
||||||
scene_graph_nodes.emplace_back();
|
Entity *polycubeMainEntity = getEntity(soma->scene, polycubeMainEntityHandle);
|
||||||
entities.back().scene_graph_node = (uint32)scene_graph_nodes.size();
|
|
||||||
scene_graph_nodes.back().entity = (uint32)entities.size();
|
|
||||||
return (uint32)entities.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity *get_entity(uint32 id) {
|
|
||||||
return &entities[id - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneGraphNode *get_scene_graph_node(int id) {
|
|
||||||
return &scene_graph_nodes[id - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 new_graph_node() {
|
|
||||||
scene_graph_nodes.emplace_back();
|
|
||||||
return (uint32)scene_graph_nodes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
Polycube create_polycube_from_repr(Space *repr) {
|
|
||||||
uint32 polycube_id = new_graph_node();
|
|
||||||
init_sg_node(get_scene_graph_node(polycube_id));
|
|
||||||
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 (filledAt(repr, x, y, z)) {
|
if (filledAt(repr, x, y, z)) {
|
||||||
Entity *polycube_segment = get_entity(new_entity());
|
uint32 segmentEntityHandle = createEntity(soma->scene);
|
||||||
polycube_segment->mesh = &cube_mesh;
|
Entity *polycubeSegment = getEntity(soma->scene, segmentEntityHandle);
|
||||||
polycube_segment->tex = &wall_tex;
|
polycubeSegment->mesh = &cubeMesh;
|
||||||
SceneGraphNode *graph_node = get_scene_graph_node(polycube_segment->scene_graph_node);
|
polycubeSegment->tex = &wallTex;
|
||||||
init_sg_node(graph_node);
|
SceneGraphNode *graphNode = getSceneGraphNode(soma->scene, polycubeSegment->graphNodeHandle);
|
||||||
graph_node->translation = glm::vec3(
|
graphNode->translation = glm::vec3(
|
||||||
-((repr->dim_z - 1)/2.0f) + z,
|
-((repr->dim_z - 1)/2.0f) + z,
|
||||||
((repr->dim_x - 1)/2.0f) - x,
|
((repr->dim_x - 1)/2.0f) - x,
|
||||||
-((repr->dim_y - 1)/2.0f) + y
|
-((repr->dim_y - 1)/2.0f) + y
|
||||||
);
|
);
|
||||||
recalculate_sg_node(graph_node);
|
sceneNodeAddEntity(soma->scene, polycubeMainEntity->graphNodeHandle, segmentEntityHandle);
|
||||||
get_scene_graph_node(polycube_id)->children.push_back(polycube_segment->scene_graph_node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Polycube result = {};
|
Polycube result = {};
|
||||||
result.graph_node = polycube_id;
|
result.entityHandle = polycubeMainEntityHandle;
|
||||||
result.color = glm::vec3(1.0f);
|
result.color = color;
|
||||||
result.repr = *repr;
|
result.repr = *repr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void recalculate_scene_graph(SceneGraphNode *top) {
|
|
||||||
if (top->children.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (uint32 &node_id : top->children) {
|
|
||||||
SceneGraphNode *graph_node = get_scene_graph_node(node_id);
|
|
||||||
recalculate_sg_node(graph_node);
|
|
||||||
graph_node->world = top->world * graph_node->local;
|
|
||||||
recalculate_scene_graph(graph_node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderObjects_Rectangle {
|
|
||||||
uint32 vao;
|
|
||||||
list<Vector2<real32>> p0;
|
|
||||||
uint32 p0BufferId;
|
|
||||||
list<Vector2<real32>> p1;
|
|
||||||
uint32 p1BufferId;
|
|
||||||
list<Vector4<real32>> color;
|
|
||||||
uint32 colorBufferId;
|
|
||||||
uint64 count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Renderer {
|
|
||||||
uint32 scene_root;
|
|
||||||
RenderObjects_Rectangle rects;
|
|
||||||
};
|
|
||||||
|
|
||||||
RenderObjects_Rectangle createRectangleObjects(Arena *arena, size_t count) {
|
RenderObjects_Rectangle createRectangleObjects(Arena *arena, size_t count) {
|
||||||
RenderObjects_Rectangle result = {0};
|
RenderObjects_Rectangle result = {0};
|
||||||
result.count = count;
|
result.count = count;
|
||||||
@@ -461,11 +423,12 @@ void reinitRectangleObjectBuffers(Renderer *r) {
|
|||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.color.head * sizeof(Vector4<real32>), r->rects.color.data);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, r->rects.color.head * sizeof(Vector4<real32>), r->rects.color.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer createRenderer(Arena *arena) {
|
Renderer createRenderer(Arena *arena, Scene *scene) {
|
||||||
Renderer result = {0};
|
Renderer result = {0};
|
||||||
|
result.scene = scene;
|
||||||
|
result.scene->sceneRoot = createSceneGraphNode(scene);
|
||||||
result.rects = createRectangleObjects(arena, 100);
|
result.rects = createRectangleObjects(arena, 100);
|
||||||
result.scene_root = new_graph_node();
|
initGraphNode(getSceneGraphNode(scene, scene->sceneRoot));
|
||||||
init_sg_node(get_scene_graph_node(result.scene_root));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,67 +438,93 @@ void renderBegin(Renderer *r) {
|
|||||||
r->rects.color.head = 0;
|
r->rects.color.head = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderEnd(Renderer *r) {
|
void renderEnd(Soma *soma, Renderer *renderer) {
|
||||||
// 3D Entities
|
// 3D Entities
|
||||||
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);
|
||||||
|
|
||||||
Polycube *current_polycube = &app_state.polycubes[app_state.current_polycube];
|
glUseProgram(phongShader.progId);
|
||||||
glBindVertexArray(cube_mesh.vao);
|
setUniformMat4fv(&phongShader, "projection", &soma->state.camera->proj);
|
||||||
|
setUniformMat4fv(&phongShader, "view", &soma->state.camera->view);
|
||||||
|
|
||||||
setUniform3fv(app_state.active_shader, "solid_color", ¤t_polycube->color);
|
SceneGraphNode *lightGraphNode = getSceneGraphNode(soma->scene, getEntity(soma->scene, soma->state.light)->graphNodeHandle);
|
||||||
int model_uniform = getUniformLocation(app_state.active_shader, "model");
|
setUniform3fv(&phongShader, "light_pos", &lightGraphNode->translation);
|
||||||
for (Entity &entity : entities) {
|
setUniform3fv(&phongShader, "camera", &soma->state.camera->pos);
|
||||||
if (entity.visible) {
|
|
||||||
setUniformMat4fv(model_uniform, &get_scene_graph_node(entity.scene_graph_node)->world);
|
Polycube *currentPolycube = &soma->state.polycubes.data[soma->state.currentPolycube];
|
||||||
|
glBindVertexArray(cubeMesh.vao);
|
||||||
|
|
||||||
|
setUniform4fv(&phongShader, "solid_color", ¤tPolycube->color);
|
||||||
|
|
||||||
|
int model_uniform = getUniformLocation(&phongShader, "model");
|
||||||
|
for (Entity &entity : renderer->scene->entities) {
|
||||||
|
if (entity.flags & EntityFlags_Render && entity.flags & EntityFlags_Visible) {
|
||||||
|
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity.graphNodeHandle)->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);
|
||||||
|
entity.flags &= ~EntityFlags_Render;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2D overlay
|
// 2D overlay
|
||||||
Shader *last_shader = app_state.active_shader;
|
glUseProgram(solidColorShader.progId);
|
||||||
app_state.active_shader = &solid_color_shader;
|
|
||||||
|
|
||||||
glUseProgram(app_state.active_shader->prog_id);
|
reinitRectangleObjectBuffers(renderer);
|
||||||
|
|
||||||
reinitRectangleObjectBuffers(r);
|
|
||||||
|
|
||||||
glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
|
glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
|
||||||
setUniformMat4fv(app_state.active_shader, "projection", &ortho);
|
setUniformMat4fv(&solidColorShader, "projection", &ortho);
|
||||||
|
|
||||||
glBindVertexArray(r->rects.vao);
|
glBindVertexArray(renderer->rects.vao);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->rects.p0.head);
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, renderer->rects.p0.head);
|
||||||
|
|
||||||
app_state.active_shader = last_shader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void placeRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, Vector4<real32> color) {
|
void rendererPlaceRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, Vector4<real32> color) {
|
||||||
appendList(&r->rects.p0, vec2<real32>(x, y));
|
appendList(&r->rects.p0, vec2<real32>(x, y));
|
||||||
appendList(&r->rects.p1, vec2<real32>(x + width, y + height));
|
appendList(&r->rects.p1, vec2<real32>(x + width, y + height));
|
||||||
appendList(&r->rects.color, color);
|
appendList(&r->rects.color, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawUI(Renderer *renderer) {
|
inline bool pointInRect(Vector2<real32> point, UI_Rect rect) {
|
||||||
Polycube currentPolycube = app_state.polycubes[app_state.current_polycube];
|
return point.x > rect.x && point.y > rect.y && point.x < (rect.x + rect.width) && point.y < (rect.y + rect.height);
|
||||||
Vector4 currPolycubeColor = vec4<real32>(currentPolycube.color.x, currentPolycube.color.y, currentPolycube.color.z, 1);
|
}
|
||||||
Vector4 white = vec4<real32>(1, 1, 1, 1);
|
|
||||||
|
|
||||||
Space repr = currentPolycube.repr;
|
bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
|
||||||
int boxSize = 30;
|
bool clicked = false;
|
||||||
int padding = 20;
|
if (pointInRect(ui->input->mouse.point, rect)) {
|
||||||
int paddingBetween = 5;
|
ui->cursorIsPointer = true;
|
||||||
int currY = padding;
|
if (ui->prevInput->mouse.btnLeft && !ui->input->mouse.btnLeft) {
|
||||||
for (int x = 0; x < repr.dim_x; x++) {
|
*value = !*value;
|
||||||
for (int y = 0; y < repr.dim_y; y++) {
|
clicked = true;
|
||||||
int currX = padding;
|
}
|
||||||
for (int z = 0; z < repr.dim_z; z++) {
|
}
|
||||||
placeRectangle(renderer,
|
rendererPlaceRectangle(ui->renderer, rect.x, rect.y, rect.width, rect.height, *value ? rect.color : vec4<real32>(1, 1, 1, 1));
|
||||||
|
return clicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
|
||||||
|
PolycubeInput *currentPolycube = &soma->state.polycubeInput.data[soma->state.currentPolycube];
|
||||||
|
|
||||||
|
real32 boxSize = 30;
|
||||||
|
real32 padding = 20;
|
||||||
|
real32 paddingBetween = 5;
|
||||||
|
real32 currY = padding;
|
||||||
|
for (int x = 0; x < currentPolycube->repr.dim_x; x++) {
|
||||||
|
for (int y = 0; y < currentPolycube->repr.dim_y; y++) {
|
||||||
|
real32 currX = padding;
|
||||||
|
for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
|
||||||
|
bool cellActive = filledAt(¤tPolycube->repr, x, y, z);
|
||||||
|
UI_Rect rect = {
|
||||||
currX,
|
currX,
|
||||||
currY,
|
currY,
|
||||||
boxSize,
|
boxSize,
|
||||||
boxSize,
|
boxSize,
|
||||||
filledAt(¤tPolycube.repr, x, y, z) ? currPolycubeColor : white);
|
0,
|
||||||
|
currentPolycube->color,
|
||||||
|
};
|
||||||
|
if (ui_checkboxRect(ui, &cellActive, rect)) {
|
||||||
|
soma->state.polycubeDirty = true;
|
||||||
|
spaceSet(¤tPolycube->repr, cellActive, x, y, z);
|
||||||
|
}
|
||||||
currX += paddingBetween + boxSize;
|
currX += paddingBetween + boxSize;
|
||||||
}
|
}
|
||||||
currY += paddingBetween + boxSize;
|
currY += paddingBetween + boxSize;
|
||||||
@@ -549,26 +538,38 @@ int main_cmd() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main_gfx() {
|
int mainGfx() {
|
||||||
Arena *arena = arenaAlloc(Megabytes(128));
|
Arena *arena = arenaAlloc(Megabytes(128));
|
||||||
|
|
||||||
WindowDims window_dims = { 800, 600 };
|
Scene mainScene = createScene();
|
||||||
GLFWwindow *window = init_window_and_gl(&window_dims);
|
|
||||||
if (!window) {
|
Soma soma = {};
|
||||||
|
soma.window.width = 800;
|
||||||
|
soma.window.height = 600;
|
||||||
|
soma.window.handle = initWindowAndGL(soma.window.width, soma.window.height);
|
||||||
|
soma.scene = &mainScene;
|
||||||
|
Renderer renderer = createRenderer(arena, &mainScene);
|
||||||
|
soma.renderer = &renderer;
|
||||||
|
|
||||||
|
if (!soma.window.handle) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame main_frame = createFrame(arena, window_dims.width, window_dims.height, 0, 0);
|
Frame mainFrame = createFrame(arena, soma.window.width, soma.window.height, 0, 0);
|
||||||
|
UI_Context ui = {};
|
||||||
|
|
||||||
app_state.current_polycube = 0;
|
GLFWcursor *pointerCursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||||
app_state.last_polycube_visible = 6;
|
GLFWcursor *arrowCursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||||
app_state.active_shader = 0;
|
|
||||||
app_state.polycubes = {};
|
|
||||||
app_state.light = new_entity();
|
|
||||||
app_state.camera = main_frame.cam;
|
|
||||||
|
|
||||||
SceneGraphNode *light_graph_node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node);
|
soma.state.currentPolycube = 0;
|
||||||
light_graph_node->translation = glm::vec3(4.0f, 6.0f, 24.0f);
|
soma.state.lastPolycubeVisible = 6;
|
||||||
|
soma.state.polycubeInput = PushListZero(arena, PolycubeInput, 64);
|
||||||
|
soma.state.polycubes = PushListZero(arena, Polycube, 64);
|
||||||
|
soma.state.light = createEntity(&mainScene);
|
||||||
|
soma.state.camera = mainFrame.cam;
|
||||||
|
|
||||||
|
SceneGraphNode *light = getSceneGraphNode(&mainScene, getEntity(&mainScene, soma.state.light)->graphNodeHandle);
|
||||||
|
light->translation = glm::vec3(4.0f, 6.0f, 24.0f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Shader solid_texture_shader = createShader(
|
Shader solid_texture_shader = createShader(
|
||||||
@@ -576,79 +577,91 @@ int main_gfx() {
|
|||||||
"./assets/shaders/2d-tex.fragment.glsl"_s);
|
"./assets/shaders/2d-tex.fragment.glsl"_s);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
solid_color_shader = createShader(
|
solidColorShader = createShader(
|
||||||
"./assets/shaders/2d-solid.vertex.glsl"_s,
|
"./assets/shaders/2d-solid.vertex.glsl"_s,
|
||||||
"./assets/shaders/2d-solid.fragment.glsl"_s);
|
"./assets/shaders/2d-solid.fragment.glsl"_s);
|
||||||
|
|
||||||
phong_shader = createShader(
|
phongShader = createShader(
|
||||||
"./assets/shaders/phong-solid.vertex.glsl"_s,
|
"./assets/shaders/phong-solid.vertex.glsl"_s,
|
||||||
"./assets/shaders/phong-solid.fragment.glsl"_s);
|
"./assets/shaders/phong-solid.fragment.glsl"_s);
|
||||||
|
|
||||||
app_state.active_shader = &phong_shader;
|
cubeMesh = createMesh("./assets/models/cube.obj");
|
||||||
|
wallTex = createTexture("./assets/textures/brick-wall.jpg");
|
||||||
cube_mesh = createMesh("./assets/models/cube.obj");
|
|
||||||
wall_tex = createTexture("./assets/textures/brick-wall.jpg");
|
|
||||||
|
|
||||||
Renderer renderer = createRenderer(arena);
|
|
||||||
|
|
||||||
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
|
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
|
||||||
Space voxel_space = { STD_SOMA[i], 3, 3, 3 };
|
Space voxelSpace = { STD_SOMA[i], 3, 3, 3 };
|
||||||
cullEmptySpace(&voxel_space);
|
Vector4<real32> color = colorFromIndex(i);
|
||||||
Polycube polycube = create_polycube_from_repr(&voxel_space);
|
appendList(&soma.state.polycubeInput, PolycubeInput{ voxelSpace, color });
|
||||||
polycube.color = color_from_index(i);
|
cullEmptySpace(&voxelSpace);
|
||||||
app_state.polycubes.push_back(polycube);
|
Polycube polycube = createPolycubeFromRepr(&soma, &voxelSpace, color);
|
||||||
get_scene_graph_node(renderer.scene_root)->children.push_back(app_state.polycubes.back().graph_node);
|
polycube.color = color;
|
||||||
|
appendList(&soma.state.polycubes, polycube);
|
||||||
|
sceneNodeAddEntity(renderer.scene, renderer.scene->sceneRoot, polycube.entityHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
app_state.camera->pos = glm::vec3(0.0f, 0.0f, 8.0f);
|
soma.state.camera->pos = glm::vec3(0.0f, 0.0f, 8.0f);
|
||||||
camera_look_at(app_state.camera, 0.0f, 0.0f, 0.0f);
|
cameraLookAt(soma.state.camera, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
SceneGraphNode *reference_polycube_gn = get_scene_graph_node(app_state.polycubes.back().graph_node);
|
SceneGraphNode *reference_polycube_gn = getSceneGraphNodeForEntity(soma.scene, soma.state.polycubes.data[0].entityHandle);
|
||||||
app_state.rotAxisY = glm::normalize(glm::vec4(0, 1, 0, 0) * glm::inverse(reference_polycube_gn->world));
|
soma.state.rotAxisY = glm::normalize(glm::vec4(0, 1, 0, 0) * glm::inverse(reference_polycube_gn->world));
|
||||||
glm::vec3 eyes = glm::normalize(app_state.camera->pos - reference_polycube_gn->translation);
|
glm::vec3 eyes = glm::normalize(soma.state.camera->pos - reference_polycube_gn->translation);
|
||||||
app_state.rotAxisX = glm::normalize(glm::cross(eyes, app_state.rotAxisY));
|
soma.state.rotAxisX = glm::normalize(glm::cross(eyes, soma.state.rotAxisY));
|
||||||
|
|
||||||
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
|
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
|
||||||
auto gn = get_scene_graph_node(app_state.polycubes.at(i).graph_node);
|
auto gn = getSceneGraphNodeForEntity(soma.scene, soma.state.polycubes.data[i].entityHandle);
|
||||||
gn->rotation *= glm::angleAxis(PI / 4, glm::vec3(1, 0, 0));
|
gn->rotation *= glm::angleAxis(PI / 4, glm::vec3(1, 0, 0));
|
||||||
gn->rotation *= glm::angleAxis(PI / 4, glm::vec3(0, 1, 0));
|
gn->rotation *= glm::angleAxis(PI / 4, glm::vec3(0, 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
glUseProgram(app_state.active_shader->prog_id);
|
real64 lastFrame = glfwGetTime();
|
||||||
setUniformMat4fv(app_state.active_shader, "projection", &main_frame.cam->proj);
|
real64 timeDelta = 1.0f/60.0f;
|
||||||
setUniformMat4fv(app_state.active_shader, "view", &main_frame.cam->view);
|
|
||||||
|
|
||||||
real64 last_frame = glfwGetTime();
|
while (!glfwWindowShouldClose(soma.window.handle)) {
|
||||||
real64 time_delta = 1.0f/60.0f;
|
real64 currTime = glfwGetTime();
|
||||||
|
timeDelta = currTime - lastFrame;
|
||||||
|
lastFrame = currTime;
|
||||||
|
//print("%.7f\n", timeDelta);
|
||||||
|
|
||||||
glm::vec3 lastLightPos = {};
|
|
||||||
Input prevInput = {};
|
|
||||||
while (!glfwWindowShouldClose(window)) {
|
|
||||||
time_delta = glfwGetTime() - last_frame;
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
Input input = get_current_input(window);
|
soma.currInput = getCurrentInput(soma.window.handle);
|
||||||
process_input(window, &input, &prevInput);
|
processInput(&soma);
|
||||||
|
|
||||||
glUseProgram(app_state.active_shader->prog_id);
|
if (soma.state.lastPolycubeVisible != soma.state.currentPolycube) {
|
||||||
SceneGraphNode *light_graph_node = get_scene_graph_node(get_entity(app_state.light)->scene_graph_node);
|
hideEntity(soma.scene, soma.state.polycubes.data[soma.state.lastPolycubeVisible].entityHandle);
|
||||||
setUniform3fv(&phong_shader, "light_pos", &light_graph_node->translation);
|
showEntity(soma.scene, soma.state.polycubes.data[soma.state.currentPolycube].entityHandle);
|
||||||
setUniform3fv(&phong_shader, "camera", &main_frame.cam->pos);
|
soma.state.lastPolycubeVisible = soma.state.currentPolycube;
|
||||||
|
}
|
||||||
if (app_state.last_polycube_visible != app_state.current_polycube) {
|
if (soma.state.polycubeDirty) {
|
||||||
hide_polycube(&app_state.polycubes[app_state.last_polycube_visible]);
|
PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube];
|
||||||
show_polycube(&app_state.polycubes[app_state.current_polycube]);
|
removeEntity(soma.scene, soma.state.polycubes.data[soma.state.currentPolycube].entityHandle);
|
||||||
app_state.last_polycube_visible = app_state.current_polycube;
|
Space culledRepr = pinput->repr;
|
||||||
|
cullEmptySpace(&culledRepr);
|
||||||
|
Polycube polycube = createPolycubeFromRepr(&soma, &culledRepr, pinput->color);
|
||||||
|
soma.state.polycubes.data[soma.state.currentPolycube] = polycube;
|
||||||
|
sceneNodeAddEntity(soma.scene, soma.scene->sceneRoot, polycube.entityHandle);
|
||||||
|
soma.state.polycubeDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_viewport_from_frame(&window_dims, &main_frame);
|
updateViewportFromFrame(soma.window.width, soma.window.height, &mainFrame);
|
||||||
recalculate_scene_graph(get_scene_graph_node(renderer.scene_root));
|
recalcScene(soma.scene);
|
||||||
|
|
||||||
renderBegin(&renderer);
|
renderBegin(&renderer);
|
||||||
drawUI(&renderer);
|
|
||||||
renderEnd(&renderer);
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
ui.cursorIsPointer = false;
|
||||||
prevInput = input;
|
ui.prevInput = &soma.prevInput;
|
||||||
|
ui.input = &soma.currInput;
|
||||||
|
ui.renderer = &renderer;
|
||||||
|
uiPass(&soma, &ui, &renderer);
|
||||||
|
if (ui.cursorIsPointer) {
|
||||||
|
glfwSetCursor(soma.window.handle, pointerCursor);
|
||||||
|
} else {
|
||||||
|
glfwSetCursor(soma.window.handle, arrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEnd(&soma, &renderer);
|
||||||
|
|
||||||
|
glfwSwapBuffers(soma.window.handle);
|
||||||
|
soma.prevInput = soma.currInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@@ -657,6 +670,6 @@ int main_gfx() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
initialiseCore();
|
initialiseCore();
|
||||||
return main_gfx();
|
return mainGfx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
91
src/world/scene.cpp
Normal file
91
src/world/scene.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include "scene.h"
|
||||||
|
|
||||||
|
Entity *getEntity(Scene *s, uint32 id) {
|
||||||
|
return &s->entities[id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) {
|
||||||
|
return &s->graphNodes[s->entities[entityHandle - 1].graphNodeHandle - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
|
||||||
|
return &s->graphNodes[sceneGraphNodeHandle - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 createEntity(Scene *s) {
|
||||||
|
s->entities.emplace_back();
|
||||||
|
s->graphNodes.emplace_back();
|
||||||
|
s->entities.back().graphNodeHandle = (uint32)s->graphNodes.size();
|
||||||
|
s->graphNodes.back().entityHandle = (uint32)s->entities.size();
|
||||||
|
uint32 handle = (uint32)s->entities.size();
|
||||||
|
uint32 graphNodeHandle = (uint32)s->graphNodes.size();
|
||||||
|
initGraphNode(getSceneGraphNode(s, graphNodeHandle));
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 createSceneGraphNode(Scene *s) {
|
||||||
|
s->graphNodes.emplace_back();
|
||||||
|
return (uint32)s->graphNodes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initGraphNode(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(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
n->local = glm::mat4(1.0f);
|
||||||
|
n->world = n->local;
|
||||||
|
}
|
||||||
|
|
||||||
|
void recalcGraphNode(SceneGraphNode *n) {
|
||||||
|
n->local = glm::scale(
|
||||||
|
glm::translate(
|
||||||
|
glm::mat4(1.0f),
|
||||||
|
n->translation
|
||||||
|
) * glm::toMat4(n->rotation),
|
||||||
|
n->scale
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene createScene() {
|
||||||
|
Scene result = {};
|
||||||
|
result.sceneRoot = createSceneGraphNode(&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void recalcSceneGraphNode(Scene *s, uint32 parentHandle) {
|
||||||
|
SceneGraphNode *node = getSceneGraphNode(s, parentHandle);
|
||||||
|
if (node->entityHandle) {
|
||||||
|
getEntity(s, node->entityHandle)->flags |= EntityFlags_Render;
|
||||||
|
}
|
||||||
|
for (uint32 &nodeId : node->children) {
|
||||||
|
SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
|
||||||
|
graphNode->parentHandle = parentHandle;
|
||||||
|
recalcGraphNode(graphNode);
|
||||||
|
graphNode->world = node->world * graphNode->local;
|
||||||
|
recalcSceneGraphNode(s, nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void recalcScene(Scene *s) {
|
||||||
|
recalcSceneGraphNode(s, s->sceneRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntity(Scene *s, uint32 entityHandle) {
|
||||||
|
Entity *entity = getEntity(s, entityHandle);
|
||||||
|
entity->flags |= EntityFlags_Dead;
|
||||||
|
SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle);
|
||||||
|
if (graphNode->parentHandle) {
|
||||||
|
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
|
||||||
|
for (int i = 0; i < parentNode->children.size(); i++) {
|
||||||
|
if (parentNode->children.at(i) == entityHandle) {
|
||||||
|
parentNode->children.erase(parentNode->children.begin() + i);
|
||||||
|
graphNode->parentHandle = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
|
||||||
|
getSceneGraphNode(s, graphNodeHandle)->children.push_back(getEntity(s, entityHandle)->graphNodeHandle);
|
||||||
|
}
|
||||||
47
src/world/scene.h
Normal file
47
src/world/scene.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <vector>
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
#include "../gfx/gfx.h"
|
||||||
|
|
||||||
|
enum EntityFlags {
|
||||||
|
EntityFlags_Visible=1<<0,
|
||||||
|
EntityFlags_Dead=1<<1,
|
||||||
|
EntityFlags_Render=1<<2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Entity {
|
||||||
|
Mesh *mesh;
|
||||||
|
Texture *tex;
|
||||||
|
uint32 graphNodeHandle;
|
||||||
|
uint64 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneGraphNode {
|
||||||
|
glm::mat4 local;
|
||||||
|
glm::mat4 world;
|
||||||
|
glm::vec3 translation;
|
||||||
|
glm::quat rotation;
|
||||||
|
glm::vec3 scale;
|
||||||
|
std::vector<uint32> children;
|
||||||
|
uint32 entityHandle;
|
||||||
|
uint32 parentHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scene {
|
||||||
|
uint32 sceneRoot;
|
||||||
|
std::vector<Entity> entities;
|
||||||
|
std::vector<SceneGraphNode> graphNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 createEntity(Scene *s);
|
||||||
|
Entity *getEntity(Scene *s);
|
||||||
|
SceneGraphNode *getSceneGraphNode(Scene *s, int id);
|
||||||
|
uint32 createSceneGraphNode(Scene *s);
|
||||||
|
Scene createScene(Scene *s);
|
||||||
|
void initGraphNode(SceneGraphNode *n);
|
||||||
|
void recalcGraphNode(SceneGraphNode *n);
|
||||||
|
void recalcSceneGraphNode(Scene *s, uint32 parentHandle);
|
||||||
|
void recalcScene(Scene *s);
|
||||||
|
void removeEntity(Scene *s, uint32 entityHandle);
|
||||||
|
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle);
|
||||||
|
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle);
|
||||||
1
src/world/world.cpp
Normal file
1
src/world/world.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "scene.cpp"
|
||||||
Reference in New Issue
Block a user