Added scene related things

This commit is contained in:
2022-04-23 22:46:06 +03:00
parent 3c721273c0
commit 50d032418e
27 changed files with 1177 additions and 16 deletions
+22
View File
@@ -1,27 +1,49 @@
set(HEADERS set(HEADERS
${HEADERS} ${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/animation_track.h
${CMAKE_CURRENT_SOURCE_DIR}/camera_node.h
${CMAKE_CURRENT_SOURCE_DIR}/colour.h ${CMAKE_CURRENT_SOURCE_DIR}/colour.h
${CMAKE_CURRENT_SOURCE_DIR}/demo_data.h
${CMAKE_CURRENT_SOURCE_DIR}/fbo.h ${CMAKE_CURRENT_SOURCE_DIR}/fbo.h
${CMAKE_CURRENT_SOURCE_DIR}/light_node.h
${CMAKE_CURRENT_SOURCE_DIR}/material.h
${CMAKE_CURRENT_SOURCE_DIR}/mesh.h ${CMAKE_CURRENT_SOURCE_DIR}/mesh.h
${CMAKE_CURRENT_SOURCE_DIR}/mesh_generator.h ${CMAKE_CURRENT_SOURCE_DIR}/mesh_generator.h
${CMAKE_CURRENT_SOURCE_DIR}/mesh_node.h
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h ${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h ${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
${CMAKE_CURRENT_SOURCE_DIR}/scene.h
${CMAKE_CURRENT_SOURCE_DIR}/scene_node.h
${CMAKE_CURRENT_SOURCE_DIR}/scene_tree.h
${CMAKE_CURRENT_SOURCE_DIR}/shader.h ${CMAKE_CURRENT_SOURCE_DIR}/shader.h
${CMAKE_CURRENT_SOURCE_DIR}/shader_constants.h
${CMAKE_CURRENT_SOURCE_DIR}/texture.h ${CMAKE_CURRENT_SOURCE_DIR}/texture.h
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.h ${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.h
${CMAKE_CURRENT_SOURCE_DIR}/timeline.h
${CMAKE_CURRENT_SOURCE_DIR}/timer.h ${CMAKE_CURRENT_SOURCE_DIR}/timer.h
PARENT_SCOPE PARENT_SCOPE
) )
set(SOURCE set(SOURCE
${SOURCE} ${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/animation_track.cpp
${CMAKE_CURRENT_SOURCE_DIR}/camera_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/demo_data.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/light_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/material.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mesh_generator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mesh_generator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mesh_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp ${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/scene.cpp
${CMAKE_CURRENT_SOURCE_DIR}/scene_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/scene_tree.cpp
${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/shader_constants.cpp
${CMAKE_CURRENT_SOURCE_DIR}/texture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/texture.cpp
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timeline.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/timer.cpp
PARENT_SCOPE PARENT_SCOPE
) )
+35
View File
@@ -0,0 +1,35 @@
#include "animation_track.h"
BEGIN_NAMESPACE
void animation_track::add_key(animation_key *key) {
keys.push_back(std::shared_ptr<animation_key>(key));
}
void animation_track::add_controlled_object(void *controlled_object) {
controlled_objects.push_back(controlled_object);
}
void animation_track::set_at(float time) {
std::shared_ptr<animation_key> first, second;
auto i = std::begin(keys);
while (i != std::end(keys)) {
if ((*i)->time >= time) {
second = *i;
break;
} else {
first = *i;
}
++i;
}
float alpha = (time - first->time) / static_cast<float>(second->time - first->time);
animated_value interpolated_value = get_value(first->value, second->value, alpha);
for (auto o: controlled_objects)
control_object(o, interpolated_value);
}
END_NAMESPACE
+64
View File
@@ -0,0 +1,64 @@
#pragma once
#include <vector>
#include <memory>
#include "defines.h"
#include "glm/glm.hpp"
#include "glm/gtc/quaternion.hpp"
BEGIN_NAMESPACE
enum class animated_value_type {
integer,
decimal,
vec3,
vec4,
quaternion
};
// sadly we cannot use union here since we have non-POD types
struct animated_value {
int intVal;
float floatVal;
glm::vec3 vec3Val;
glm::vec4 vec4Val;
glm::quat quatVal;
};
struct animation_key {
float time;
animated_value value;
static animation_key *vec3Key(float t, glm::vec3 val) {
auto *result = new animation_key();
result->time = t;
result->value.vec3Val = val;
return result;
}
static animation_key *floatKey(float t, float val) {
auto *result = new animation_key();
result->time = t;
result->value.floatVal = val;
return result;
}
};
class animation_track {
public:
void add_key(animation_key *key);
void add_controlled_object(void *controlled_object);
void set_at(float time);
virtual animated_value get_value(const animated_value &first,
const animated_value &second,
float alpha) = 0;
virtual void control_object(void *controlled_object, const animated_value &value) = 0;
std::vector<std::shared_ptr<animation_key>> keys;
std::vector<void *> controlled_objects;
};
END_NAMESPACE
+30
View File
@@ -0,0 +1,30 @@
#include "camera_node.h"
#include "demo_data.h"
#include "glm/gtx/quaternion.hpp"
#include "glm/gtx/transform.hpp"
#include "glm/gtc/matrix_transform.hpp"
BEGIN_NAMESPACE
camera_node::camera_node() {
type = scene_node_type::camera;
}
void camera_node::calculate_local_transform() {
scene_node::calculate_local_transform();
view_matrix = glm::translate(glm::mat4(1.0f),
glm::vec3(-position.x, -position.y, -position.z));
view_matrix *= glm::lookAt(glm::vec3(position.x, position.y, position.z),
glm::vec3(target.x, target.y, target.z),
glm::vec3(0, 1, 0)
);
projection_matrix = glm::perspective(fov,
demo_data::screen_width / static_cast<float>(demo_data::screen_height),
0.001f,
100000.0f
);
}
END_NAMESPACE
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "scene_node.h"
BEGIN_NAMESPACE
struct camera_node : scene_node {
camera_node();
void calculate_local_transform() override;
glm::vec3 target;
float roll_angle;
float fov;
glm::mat4 view_matrix;
glm::mat4 projection_matrix;
};
END_NAMESPACE
+11 -6
View File
@@ -3,12 +3,17 @@
#include <cstdint> #include <cstdint>
#include "glm/vec4.hpp" #include "glm/vec4.hpp"
typedef glm::vec4 colour; BEGIN_NAMESPACE
using colour = glm::vec4;
inline uint32_t as_int(const glm::vec4 &col) { inline uint32_t as_int(const glm::vec4 &col) {
unsigned char rr = static_cast<unsigned char>(col.r * 255); auto r = static_cast<uint8_t>(col.r * 255);
unsigned char gg = static_cast<unsigned char>(col.g * 255); auto g = static_cast<uint8_t>(col.g * 255);
unsigned char bb = static_cast<unsigned char>(col.b * 255); auto b = static_cast<uint8_t>(col.b * 255);
unsigned char aa = static_cast<unsigned char>(col.a * 255); auto a = static_cast<uint8_t>(col.a * 255);
return rr + (gg << 8) + (bb << 16) + (aa << 24);
return r | g << 8 | b << 16 | a << 24;
} }
END_NAMESPACE
+2 -2
View File
@@ -4,5 +4,5 @@
#define BEGIN_NAMESPACE namespace acidrain { #define BEGIN_NAMESPACE namespace acidrain {
#define END_NAMESPACE }; #define END_NAMESPACE };
static int SCREEN_WIDTH = 800; //static int SCREEN_WIDTH = 800;
static int SCREEN_HEIGHT = 600; //static int SCREEN_HEIGHT = 600;
+14
View File
@@ -0,0 +1,14 @@
#include "demo_data.h"
BEGIN_NAMESPACE
std::vector<std::shared_ptr<texture>> demo_data::textures;
std::vector<std::shared_ptr<shader>> demo_data::shaders;
std::vector<std::shared_ptr<material>> demo_data::materials;
std::vector<std::shared_ptr<mesh>> demo_data::meshes;
std::vector<std::shared_ptr<fbo>> demo_data::fbos;
int demo_data::screen_width = 1024;
int demo_data::screen_height = 768;
END_NAMESPACE
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <vector>
#include "material.h"
#include "mesh.h"
#include "fbo.h"
BEGIN_NAMESPACE
struct demo_data {
static std::vector<std::shared_ptr<texture>> textures;
static std::vector<std::shared_ptr<shader>> shaders;
static std::vector<std::shared_ptr<material>> materials;
static std::vector<std::shared_ptr<mesh>> meshes;
static std::vector<std::shared_ptr<fbo>> fbos;
// holds the current viewport size at any point in time
static int screen_width;
static int screen_height;
};
END_NAMESPACE
+8 -7
View File
@@ -1,5 +1,6 @@
#include "fbo.h" #include "fbo.h"
#include "demo_data.h"
#include <memory> #include <memory>
BEGIN_NAMESPACE BEGIN_NAMESPACE
@@ -48,22 +49,22 @@ GLuint fbo::get_depth_buffer_id() const {
} }
void fbo::use() { void fbo::use() {
old_width = SCREEN_WIDTH; old_width = demo_data::screen_width;
old_height = SCREEN_HEIGHT; old_height = demo_data::screen_height;
SCREEN_WIDTH = width; demo_data::screen_height = width;
SCREEN_HEIGHT = height; demo_data::screen_height = height;
glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_id); glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_id);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
} }
void fbo::unuse() { void fbo::unuse() const {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, old_width, old_height); glViewport(0, 0, old_width, old_height);
SCREEN_WIDTH = old_width; demo_data::screen_width = old_width;
SCREEN_HEIGHT = old_height; demo_data::screen_height = old_height;
} }
std::shared_ptr<texture> fbo::get_texture() { std::shared_ptr<texture> fbo::get_texture() {
+1 -1
View File
@@ -11,7 +11,7 @@ public:
~fbo() = default; ~fbo() = default;
void use(); void use();
void unuse(); void unuse() const;
int get_width() const; int get_width() const;
int get_height() const; int get_height() const;
+53
View File
@@ -0,0 +1,53 @@
#include "light_node.h"
//#define GL_COMPARE_REF_TO_TEXTURE 0x884E
BEGIN_NAMESPACE
light_node::light_node(light_type type_) {
type = scene_node_type::light;
light_type_ = type_;
shadow_map_bias_matrix = glm::scale(glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f)),
glm::vec3(0.5f, 0.5f, 0.5f));
int textures_to_generate = light_type_ == light_type::point ? 6 : 1;
for (int i = 0; i < textures_to_generate; i++) {
GLuint shadow_map_texture_id;
// setup the shadowmap texture
glGenTextures(1, &shadow_map_texture_id);
glBindTexture(GL_TEXTURE_2D, shadow_map_texture_id);
// set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
// TODO: see if we need
// glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
shadow_map_width, shadow_map_width,
0,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE,
nullptr);
shadow_map[i] = std::make_shared<texture>(shadow_map_texture_id, shadow_map_width, shadow_map_width);
}
}
void light_node::calculate_local_transform() {
if (light_type_ == light_type::spot) {
world_to_light_matrix[0] = glm::lookAt(position, spot_target, glm::vec3(0, 1, 0));
light_projection_matrix[0] = glm::perspective(90.0f, 1.0f, 0.1f, 100.0f);
glm::mat4 lightProjectionAndBiasMatrix = shadow_map_bias_matrix * light_projection_matrix[0];
final_shadow_map_matrix[0] = lightProjectionAndBiasMatrix * world_to_light_matrix[0];
}
}
END_NAMESPACE
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include "scene_node.h"
#include "texture.h"
BEGIN_NAMESPACE
// http://en.wikipedia.org/wiki/Shading#Lighting
enum class light_type {
directional,
point,
spot
};
struct light_node : scene_node {
light_node(light_type type);
void calculate_local_transform() override;
light_type light_type_;
glm::vec4 ambient = glm::vec4(0.2, 0.2, 0.2, 1);
glm::vec4 diffuse = glm::vec4(0.5, 0.5, 0.5, 1);
glm::vec4 specular = glm::vec4(1);
glm::vec3 attenuation;
glm::vec3 spot_target;
float spot_cutoff;
float spot_exponent;
bool active = true;
int shadow_map_width = 1024;
glm::mat4 light_projection_matrix[6];
glm::mat4 world_to_light_matrix[6];
glm::mat4 shadow_map_bias_matrix;
glm::mat4 final_shadow_map_matrix[6];
std::shared_ptr<texture> shadow_map[6];
};
END_NAMESPACE
+104
View File
@@ -0,0 +1,104 @@
#include "material.h"
#include "shader_constants.h"
BEGIN_NAMESPACE
GLenum to_gl(const blending_constant &c) {
switch (c) {
case blending_constant::src_color:
return GL_SRC_COLOR;
case blending_constant::dst_color:
return GL_DST_COLOR;
case blending_constant::one:
return GL_ONE;
case blending_constant::zero:
return GL_ZERO;
case blending_constant::src_alpha:
return GL_SRC_ALPHA;
case blending_constant::dst_alpha:
return GL_DST_ALPHA;
case blending_constant::one_minus_src_alpha:
return GL_ONE_MINUS_SRC_ALPHA;
case blending_constant::one_minus_dst_alpha:
return GL_ONE_MINUS_DST_ALPHA;
default:
return GL_ZERO;
}
}
void set_material(std::shared_ptr<material> &mat) {
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
mat->shader->use();
// if (material->textures[TextureRole::Diffuse]) {
// std::cout << "CAN has diffuse texture!!!!!!!!!11" << std::endl;
// int textureUnit = 0;
// glActiveTexture(GL_TEXTURE0 + textureUnit);
// material->shader->setIntUniform(textureUnit, "diffuseMap");
// material->textures[TextureRole::Diffuse]->use();
// } else {
// std::cout << "Cannot has diffuse texture!!!!!!!!!11" << std::endl;
// }
// int textureUnit = 0;
// for (auto& kv : material->textures) {
// glActiveTexture(GL_TEXTURE0 + textureUnit);
// const char* uniformName = ShaderConstantNameResolver::nameFor(kv.first);
// material->shader->setIntUniform(textureUnit, uniformName);
// kv.second->use();
// textureUnit++;
// }
if (mat->transparent) {
glEnable(GL_BLEND);
glBlendFunc(to_gl(mat->blend_src_fact), to_gl(mat->blend_dst_fact));
} else {
glDisable(GL_BLEND);
}
if (mat->zbuffer_test)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
if (mat->zbuffer_write)
glDepthMask(GL_TRUE);
else
glDepthMask(GL_FALSE);
if (mat->cull_faces) {
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(mat->cull_front_faces ? GL_FRONT : GL_BACK);
} else {
glDisable(GL_CULL_FACE);
}
}
void unset_material(shared_ptr<material> &mat) {
// int textureUnit = 0;
// for (auto& kv : material->textures) {
// glActiveTexture(GL_TEXTURE0 + textureUnit);
// const char* uniformName = ShaderConstantNameResolver::nameFor(kv.first);
// material->shader->setIntUniform(textureUnit, uniformName);
// kv.second->unuse();
// textureUnit++;
// }
mat->shader->unuse();
if (mat->transparent)
glDisable(GL_BLEND);
if (!mat->zbuffer_test)
glEnable(GL_DEPTH_TEST);
if (!mat->zbuffer_write)
glDepthMask(GL_TRUE);
if (mat->cull_faces)
glDisable(GL_CULL_FACE);
}
END_NAMESPACE
+62
View File
@@ -0,0 +1,62 @@
#pragma once
#include <memory>
#include <map>
#include "texture.h"
#include "shader.h"
#include "glm/glm.hpp"
BEGIN_NAMESPACE
enum class fill_mode_type {
wireframe,
solid
};
enum class blending_constant {
src_color,
dst_color,
one,
zero,
src_alpha,
dst_alpha,
one_minus_src_alpha,
one_minus_dst_alpha,
};
enum class texture_role {
diffuse,
specular,
normal,
emissive,
environment
};
using texture_map = std::map<texture_role, std::shared_ptr<texture>>;
struct material {
glm::vec4 ambient;
glm::vec4 diffuse;
glm::vec4 specular;
float shininess = 1.f;
bool flat_shaded = true;
bool zbuffer_write = true;
bool zbuffer_test = true;
bool cull_faces = false;
bool cull_front_faces = false;
bool transparent = false;
bool cast_shadows = true;
blending_constant blend_src_fact = blending_constant::src_alpha;
blending_constant blend_dst_fact = blending_constant::one_minus_src_alpha;
fill_mode_type fill_mode = fill_mode_type::solid;
std::shared_ptr<shader> shader;
texture_map textures;
};
void set_material(std::shared_ptr<material> &material);
void unset_material(std::shared_ptr<material> &material);
END_NAMESPACE
+9
View File
@@ -0,0 +1,9 @@
#include "mesh_node.h"
BEGIN_NAMESPACE
mesh_node::mesh_node() {
type = scene_node_type::mesh;
}
END_NAMESPACE
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "material.h"
#include "mesh.h"
#include "scene_node.h"
BEGIN_NAMESPACE
struct mesh_node : scene_node {
mesh_node();
std::shared_ptr<mesh> mesh_;
std::shared_ptr<material> material_;
};
END_NAMESPACE
+12
View File
@@ -0,0 +1,12 @@
#include "scene.h"
#include <memory>
BEGIN_NAMESPACE
scene::scene() {
tree = std::make_shared<scene_tree>();
animation = std::make_shared<timeline>();
}
END_NAMESPACE
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <memory>
#include "scene_tree.h"
#include "timeline.h"
BEGIN_NAMESPACE
struct scene {
scene();
std::shared_ptr<scene_tree> tree;
std::shared_ptr<timeline> animation;
};
END_NAMESPACE
+38
View File
@@ -0,0 +1,38 @@
#include "scene_node.h"
#include "mesh_node.h"
#include "camera_node.h"
#include "light_node.h"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtx/quaternion.hpp"
BEGIN_NAMESPACE
void scene_node::calculate_local_transform() {
local_to_parent_space_matrix = glm::translate(glm::mat4(1.0f), position)
* glm::translate(glm::mat4(1.0f), pivot)
* glm::toMat4(rotation)
* glm::translate(glm::mat4(1.0f), -pivot)
* glm::scale(glm::mat4(1.0f), scale);
}
void scene_node::apply_parent_transform(const glm::mat4 &parent_transform) {
model_to_world_space_matrix = parent_transform * local_to_parent_space_matrix;
for (auto &child: children)
child->apply_parent_transform(model_to_world_space_matrix);
}
mesh_node &scene_node::as_mesh_node() {
return *static_cast<mesh_node *>(this);
}
light_node &scene_node::as_light_node() {
return *static_cast<light_node *>(this);
}
camera_node &scene_node::as_camera_node() {
return *static_cast<camera_node *>(this);
}
END_NAMESPACE
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include "defines.h"
#include <vector>
#include <string>
#include <memory>
#include "glm/glm.hpp"
#include "glm/gtc/quaternion.hpp"
BEGIN_NAMESPACE
enum class scene_node_type {
mesh,
camera,
light
};
struct mesh_node;
struct light_node;
struct camera_node;
struct scene_node {
virtual void calculate_local_transform();
void apply_parent_transform(const glm::mat4 &parent_transform);
mesh_node &as_mesh_node();
light_node &as_light_node();
camera_node &as_camera_node();
int id;
std::string name;
scene_node_type type; // We rely on type comparison instead of dynamic casting because comparing types is much faster
// Helpers to navigate the hierarchy
std::shared_ptr<scene_node> parent;
std::vector<std::shared_ptr<scene_node>> children;
// Transform
glm::vec3 scale = glm::vec3(1);
glm::vec3 position = glm::vec3(0);
glm::vec3 pivot = glm::vec3(0);
glm::quat rotation;
glm::mat4 local_to_parent_space_matrix = glm::mat4(1);
glm::mat4 model_to_world_space_matrix = glm::mat4(1);
};
END_NAMESPACE
+47
View File
@@ -0,0 +1,47 @@
#include "scene_tree.h"
BEGIN_NAMESPACE
std::shared_ptr<scene_node> scene_tree::nodeById(int id) const {
for (auto& node : nodes)
if (node->id == id)
return node;
return std::shared_ptr<scene_node>(nullptr);
}
std::shared_ptr<scene_node> scene_tree::nodeByNameAndType(std::string name, scene_node_type type) const {
for (auto& node : nodes)
if (node->name == name && node->type == type)
return node;
return std::shared_ptr<scene_node>(nullptr);
}
void scene_tree::add(std::shared_ptr<scene_node> node) {
add(node, std::shared_ptr<scene_node>(nullptr));
}
void scene_tree::add(std::shared_ptr<scene_node> node, std::shared_ptr<scene_node> parent) {
nodes.push_back(node);
node->parent = parent;
if (parent)
parent->children.push_back(node);
else
rootNodes.push_back(node);
if (node->type == scene_node_type::light)
lights.push_back(node);
}
void scene_tree::transform() {
for (auto& node : nodes)
node->calculate_local_transform();
for (auto& node : rootNodes)
node->apply_parent_transform(glm::mat4(1));
}
END_NAMESPACE
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "scene_node.h"
#include <string>
BEGIN_NAMESPACE
class scene_tree {
public:
std::shared_ptr<scene_node> nodeById(int id) const;
std::shared_ptr<scene_node> nodeByNameAndType(std::string name, scene_node_type type) const;
void add(std::shared_ptr<scene_node> node);
void add(std::shared_ptr<scene_node> node, std::shared_ptr<scene_node> parent);
void transform();
std::vector<std::shared_ptr<scene_node>> nodes;
std::vector<std::shared_ptr<scene_node>> rootNodes;
std::vector<std::shared_ptr<scene_node>> lights;
};
END_NAMESPACE
+160
View File
@@ -0,0 +1,160 @@
#include "shader_constants.h"
#include "glm/gtc/type_ptr.hpp"
BEGIN_NAMESPACE
UniformDescriptor Uniforms::ViewMatrix("vmtx");
UniformDescriptor Uniforms::ProjectionMatrix("pmtx");
UniformDescriptor Uniforms::ModelToWorldMatrix("mmtx");
UniformDescriptor Uniforms::NormalMatrix("nmtx");
UniformDescriptor Uniforms::WorldToLightMatrix("wlmtx");
UniformDescriptor Uniforms::LightProjectionMatrix("lpmtx");
UniformDescriptor Uniforms::ShadowBiasMatrix("sbmtx");
UniformDescriptor Uniforms::ShadowMatrix("smtx");
UniformDescriptor Uniforms::DemoPartNormalizedTime("dptimen");
UniformDescriptor Uniforms::LightPositionInEyeSpace("lPosEye");
UniformDescriptor Uniforms::MaterialAmbientColor("matAmbientCol");
UniformDescriptor Uniforms::MaterialDiffuseColor("matDiffuseCol");
UniformDescriptor Uniforms::MaterialSpecularColor("matSpecularCol");
UniformDescriptor Uniforms::MaterialShininess("matShininess");
UniformDescriptor Uniforms::DiffuseMap("diffuseMap");
UniformDescriptor Uniforms::ShadowMap("shadowMap");
UniformDescriptor Uniforms::ShadowMap1("shadowMap1");
UniformDescriptor Uniforms::ShadowMap2("shadowMap2");
UniformDescriptor Uniforms::ShadowMap3("shadowMap3");
UniformDescriptor Uniforms::ShadowMap4("shadowMap4");
UniformDescriptor Uniforms::NumberOfLights("numLights");
UniformDescriptor Uniforms::LightPosition("light", "position");
UniformDescriptor Uniforms::LightTarget("light", "target");
UniformDescriptor Uniforms::LightAmbient("light", "ambient");
UniformDescriptor Uniforms::LightDiffuse("light", "diffuse");
UniformDescriptor Uniforms::LightSpecular("light", "specular");
UniformDescriptor Uniforms::LightSpotCutoff("light", "spotCutoff");
UniformDescriptor Uniforms::LightSpotExponent("light", "spotExponent");
UniformDescriptor Uniforms::LightAttenuation("light", "attenuation");
/*
const char* ShaderConstantNameResolver::nameFor(const ShaderConstantType& type) {
switch (type) {
case ShaderConstantType::ViewMatrix: return "vmtx";
case ShaderConstantType::ProjectionMatrix: return "pmtx";
case ShaderConstantType::ModelToWorldMatrix: return "mmtx";
case ShaderConstantType::NormalMatrix: return "nmtx";
case ShaderConstantType::DemoPartNormalizedTime: return "dptimen";
case ShaderConstantType::WorldToLightMatrix: return "wlmtx";
case ShaderConstantType::LightProjectionMatrix: return "lpmtx";
case ShaderConstantType::ShadowBiasMatrix: return "sbmtx";
case ShaderConstantType::ShadowMatrix: return "smtx";
case ShaderConstantType::LightPositionInEyeSpace: return "lPosEye";
case ShaderConstantType::MaterialAmbientColor: return "matAmbientCol";
case ShaderConstantType::MaterialDiffuseColor: return "matDiffuseCol";
case ShaderConstantType::MaterialSpecularColor: return "matSpecularCol";
case ShaderConstantType::MaterialShininess: return "matShininess";
case ShaderConstantType::ShadowMap: return "shadowMap";
case ShaderConstantType::NumberOfLights: return "numLights";
default: return "";
}
}
const char* ShaderConstantNameResolver::nameFor(const TextureRole& type) {
switch (type) {
case TextureRole::Diffuse: return "mapDiffuse";
case TextureRole::Specular: return "mapSpecular";
case TextureRole::Normal: return "mapNormal";
// TODO: remove Bump since we have normal map
case TextureRole::Bump: return "mapBump";
default: return "";
}
}
void ShaderConstants::add(ShaderConstantType type, float value) {
ShaderConstantValue val;
val.floatVal = value;
constants[type] = val;
}
void ShaderConstants::add(ShaderConstantType type, int value) {
ShaderConstantValue val;
val.intVal = value;
constants[type] = val;
}
void ShaderConstants::add(ShaderConstantType type, const glm::vec3& value) {
ShaderConstantValue val;
val.vec3Val = value;
constants[type] = val;
}
void ShaderConstants::add(ShaderConstantType type, const glm::vec4& value) {
ShaderConstantValue val;
val.vec4Val = value;
constants[type] = val;
}
void ShaderConstants::add(ShaderConstantType type, const glm::mat3& value) {
ShaderConstantValue val;
val.mat3Val = value;
constants[type] = val;
}
void ShaderConstants::add(ShaderConstantType type, const glm::mat4& value) {
ShaderConstantValue val;
val.mat4Val = value;
constants[type] = val;
}
void ShaderConstants::set(Shader& shader) {
for (auto& kv : constants) {
const char* uniformName = ShaderConstantNameResolver::nameFor(kv.first);
switch (kv.first) {
case ShaderConstantType::NormalMatrix: {
shader.setMatrix3Uniform(glm::value_ptr(kv.second.mat3Val), uniformName);
break;
}
case ShaderConstantType::ViewMatrix:
case ShaderConstantType::ProjectionMatrix:
case ShaderConstantType::ModelToWorldMatrix:
case ShaderConstantType::WorldToLightMatrix:
case ShaderConstantType::LightProjectionMatrix:
case ShaderConstantType::ShadowBiasMatrix:
case ShaderConstantType::ShadowMatrix: {
shader.setMatrix4Uniform(glm::value_ptr(kv.second.mat4Val), uniformName);
break;
}
case ShaderConstantType::DemoPartNormalizedTime: {
shader.setFloatUniform(kv.second.floatVal, uniformName);
break;
}
case ShaderConstantType::MaterialShininess:
case ShaderConstantType::ShadowMap:
case ShaderConstantType::NumberOfLights: {
shader.setIntUniform(kv.second.intVal, uniformName);
break;
}
case ShaderConstantType::LightPositionInEyeSpace: {
shader.setVec3Uniform(glm::value_ptr(kv.second.vec3Val), uniformName);
break;
}
case ShaderConstantType::MaterialAmbientColor:
case ShaderConstantType::MaterialDiffuseColor:
case ShaderConstantType::MaterialSpecularColor: {
shader.setVec4Uniform(glm::value_ptr(kv.second.vec4Val), uniformName);
break;
}
default:
break;
}
}
}
*/
END_NAMESPACE
+295
View File
@@ -0,0 +1,295 @@
#pragma once
#include "defines.h"
#include "shader.h"
#include "texture.h"
#include <map>
#include "material.h"
#include "glm/glm.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <sstream>
BEGIN_NAMESPACE
using namespace std;
struct UniformDescriptor {
string structureName;
string memberName;
// TODO: implement memoization of uniform name calculation
UniformDescriptor(const char *member) {
structureName = "";
memberName = member;
}
UniformDescriptor(const char *structure, const char *member) {
structureName = structure;
memberName = member;
}
std::string getName() {
if (structureName.empty())
return memberName;
std::stringstream ss(structureName);
ss << "." << memberName;
return ss.str();
}
std::string getName(int index) {
std::stringstream ss;
if (structureName.empty()) {
ss << memberName << "[" << index << "]";
} else {
ss << structureName << "[" << index << "]." << memberName;
}
return ss.str();
}
};
class Uniforms {
public:
static UniformDescriptor ViewMatrix;
static UniformDescriptor ProjectionMatrix;
static UniformDescriptor ModelToWorldMatrix;
static UniformDescriptor NormalMatrix;
static UniformDescriptor WorldToLightMatrix;
static UniformDescriptor LightProjectionMatrix;
static UniformDescriptor ShadowBiasMatrix;
static UniformDescriptor ShadowMatrix;
static UniformDescriptor DemoPartNormalizedTime;
static UniformDescriptor LightPositionInEyeSpace;
static UniformDescriptor MaterialAmbientColor;
static UniformDescriptor MaterialDiffuseColor;
static UniformDescriptor MaterialSpecularColor;
static UniformDescriptor MaterialShininess;
static UniformDescriptor DiffuseMap;
static UniformDescriptor ShadowMap;
static UniformDescriptor ShadowMap1;
static UniformDescriptor ShadowMap2;
static UniformDescriptor ShadowMap3;
static UniformDescriptor ShadowMap4;
static UniformDescriptor NumberOfLights;
static UniformDescriptor LightPosition;
static UniformDescriptor LightTarget;
static UniformDescriptor LightAmbient;
static UniformDescriptor LightDiffuse;
static UniformDescriptor LightSpecular;
static UniformDescriptor LightSpotCutoff;
static UniformDescriptor LightSpotExponent;
static UniformDescriptor LightAttenuation;
};
enum class ShaderConstantType {
Vec3,
Vec4,
Integer,
Float,
Mat3,
Mat4
};
class ShaderConstantValue {
public:
ShaderConstantType type;
glm::vec3 vec3Val;
glm::vec4 vec4Val;
glm::mat3 mat3Val;
glm::mat4 mat4Val;
int intVal;
float floatVal;
ShaderConstantValue(const ShaderConstantValue &rhs) {
type = rhs.type;
vec3Val = rhs.vec3Val;
vec4Val = rhs.vec4Val;
mat3Val = rhs.mat3Val;
mat4Val = rhs.mat4Val;
intVal = rhs.intVal;
floatVal = rhs.floatVal;
}
ShaderConstantValue(glm::vec3 &value) {
vec3Val = value;
type = ShaderConstantType::Vec3;
}
ShaderConstantValue(glm::vec4 &value) {
vec4Val = value;
type = ShaderConstantType::Vec4;
}
ShaderConstantValue(glm::mat3 &value) {
mat3Val = value;
type = ShaderConstantType::Mat3;
}
ShaderConstantValue(glm::mat4 &value) {
mat4Val = value;
type = ShaderConstantType::Mat4;
}
ShaderConstantValue(int value) {
intVal = value;
type = ShaderConstantType::Integer;
}
ShaderConstantValue(float value) {
floatVal = value;
type = ShaderConstantType::Float;
}
void applyTo(shader &shader, const char *uniformName) {
switch (type) {
case ShaderConstantType::Vec3:
shader.setVec3Uniform(glm::value_ptr(vec3Val), uniformName);
break;
case ShaderConstantType::Vec4:
shader.setVec4Uniform(glm::value_ptr(vec4Val), uniformName);
break;
case ShaderConstantType::Mat3:
shader.setMatrix3Uniform(glm::value_ptr(mat3Val), uniformName);
break;
case ShaderConstantType::Mat4:
shader.setMatrix4Uniform(glm::value_ptr(mat4Val), uniformName);
break;
case ShaderConstantType::Integer:
shader.setIntUniform(intVal, uniformName);
break;
case ShaderConstantType::Float:
shader.setFloatUniform(floatVal, uniformName);
break;
}
}
};
class ShaderConstants {
public:
void set(UniformDescriptor descriptor, glm::mat3 value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::mat3 value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::mat4 value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::mat4 value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::vec3 value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::vec3 value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::vec4 value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, glm::vec4 value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, int value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, int value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, float value) {
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
}
void set(UniformDescriptor descriptor, float value, int index) {
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
}
void applyTo(shader &shd) {
for (auto &kv: constants)
kv.second->applyTo(shd, kv.first.c_str());
}
private:
std::map<string, std::shared_ptr<ShaderConstantValue>> constants;
};
/*
enum class ShaderConstantType {
ViewMatrix,
ProjectionMatrix,
ModelToWorldMatrix,
NormalMatrix,
WorldToLightMatrix,
LightProjectionMatrix,
ShadowBiasMatrix,
ShadowMatrix,
DemoPartNormalizedTime,
LightPositionInEyeSpace,
MaterialAmbientColor,
MaterialDiffuseColor,
MaterialSpecularColor,
MaterialShininess,
ShadowMap,
NumberOfLights
};
class ShaderConstantNameResolver {
public:
static const char* nameFor(const ShaderConstantType& type);
static const char* nameFor(const TextureRole& type);
};
union ShaderConstantValue {
glm::vec2 vec2Val;
glm::vec3 vec3Val;
glm::vec4 vec4Val;
glm::mat3 mat3Val;
glm::mat4 mat4Val;
bool boolVal;
int intVal;
float floatVal;
ShaderConstantValue() {
this->floatVal = 0;
};
ShaderConstantValue(const ShaderConstantValue& lhs) {
this->mat4Val = lhs.mat4Val;
}
ShaderConstantValue& operator=(const ShaderConstantValue& lhs) {
this->mat4Val = lhs.mat4Val;
return *this;
};
};
struct ShaderConstants {
std::map<ShaderConstantType, ShaderConstantValue> constants;
void add(ShaderConstantType type, float value);
void add(ShaderConstantType type, int value);
void add(ShaderConstantType type, const glm::vec3& value);
void add(ShaderConstantType type, const glm::vec4& value);
void add(ShaderConstantType type, const glm::mat4& value);
void add(ShaderConstantType type, const glm::mat3& value);
void set(Shader& shader);
};
*/
END_NAMESPACE
+10
View File
@@ -0,0 +1,10 @@
#include "timeline.h"
BEGIN_NAMESPACE
void timeline::setAt(float time) {
for (auto &track: tracks)
track->set_at(time);
}
END_NAMESPACE
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "animation_track.h"
BEGIN_NAMESPACE
struct timeline {
void setAt(float time);
std::vector<std::shared_ptr<animation_track>> tracks;
};
END_NAMESPACE