Added demo handling and easyloggingpp
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
[submodule "lib/glm"]
|
||||
path = lib/glm
|
||||
url = git@github.com:g-truc/glm.git
|
||||
[submodule "lib/easyloggingpp"]
|
||||
path = lib/easyloggingpp
|
||||
url = git@github.com:amrayn/easyloggingpp.git
|
||||
|
||||
+3
-1
@@ -9,10 +9,12 @@ find_package(OpenGL REQUIRED)
|
||||
|
||||
include_directories("src/")
|
||||
include_directories("gl/include")
|
||||
include_directories("lib/easyloggingpp/src")
|
||||
add_subdirectory(lib/glm EXCLUDE_FROM_ALL)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(src/animation)
|
||||
add_subdirectory(src/demo)
|
||||
|
||||
add_executable(demo main.cpp gl/src/glad.c ${SOURCE})
|
||||
add_executable(demo main.cpp gl/src/glad.c ${SOURCE} lib/easyloggingpp/src/easylogging++.cc)
|
||||
target_link_libraries(demo glfw OpenGL::GL)
|
||||
Submodule
+1
Submodule lib/easyloggingpp added at 8489989bb2
@@ -1,4 +1,11 @@
|
||||
#include "peripherals_glfw.h"
|
||||
#include "demo/demo_engine.h"
|
||||
#include "timer.h"
|
||||
|
||||
using namespace acidrain;
|
||||
using namespace std;
|
||||
|
||||
INITIALIZE_EASYLOGGINGPP
|
||||
|
||||
int main() {
|
||||
acidrain::peripherals_glfw peripherals;
|
||||
@@ -6,15 +13,231 @@ int main() {
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
double alpha = 0.0;
|
||||
while (!peripherals.should_close()) {
|
||||
alpha += 0.01;
|
||||
if (alpha > 1.0) alpha = 0.0;
|
||||
const float DEMO_LENGTH_IN_SECONDS = 100;
|
||||
|
||||
glClearColor(0.0 * alpha, 0.1 * alpha, 1.0 * alpha, 1 * alpha);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Load resources
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
acidrain::texture_generator tg(256, 256);
|
||||
tg.brick(0, 50, 20, 4, glm::vec4(1), glm::vec4(0));
|
||||
|
||||
shared_ptr<mesh> affectedSphere = mesh_generator::sphere(50, 50);
|
||||
map_transform(affectedSphere, tg, 0, 0, 0.2f);
|
||||
calculate_normals(*affectedSphere.get());
|
||||
|
||||
affectedSphere = mesh_generator::cog(0.2, 0.5, 50, 4, 0.1, 0.2, 0.2, 0.1);
|
||||
|
||||
demo_data::meshes.push_back(affectedSphere);
|
||||
demo_data::meshes.push_back(mesh_generator::sphere(50, 50));
|
||||
demo_data::meshes.push_back(mesh_generator::grid(30, 30));
|
||||
demo_data::meshes.push_back(mesh_generator::cube());
|
||||
|
||||
auto mat = shared_ptr<material>(new material());
|
||||
mat->ambient = glm::vec4(0, 0, 0.15, 1);
|
||||
mat->diffuse = glm::vec4(1, 1, 1, 1);
|
||||
// material->diffuse = glm::vec4(1, 0, 0, 1);
|
||||
mat->specular = glm::vec4(0.3, 0.3, 0.3, 1);
|
||||
mat->shininess = 200;
|
||||
mat->cast_shadows = true;
|
||||
|
||||
auto *textureGenerator1 = new texture_generator(256, 256);
|
||||
mat->textures[texture_role::diffuse] = textureGenerator1->checker_board(0, 20,
|
||||
colour(1, 1, 1, 1),
|
||||
colour(0, 0.5, 0.2, 1)).get_texture(0);
|
||||
// mat->textures[texture_role::diffuse] = textureGenerator1->brick(0, 50, 20, 4, colour(0.3, 0.1, 0, 1),
|
||||
// colour(1, 0.3, 0, 1)).get_texture(0);
|
||||
|
||||
demo_data::materials.push_back(mat);
|
||||
|
||||
auto material2 = make_shared<material>();
|
||||
material2->ambient = glm::vec4(0, 0, 0.15, 1);
|
||||
material2->textures[texture_role::diffuse] = textureGenerator1->get_texture(0);
|
||||
// material2->diffuse = glm::vec4(0.2, 1.0, 0.7, 1);
|
||||
material2->diffuse = glm::vec4(1, 1, 1, 1);
|
||||
material2->specular = glm::vec4(0.3, 0.3, 0.3, 1);
|
||||
material2->shininess = 200;
|
||||
material2->cast_shadows = false;
|
||||
demo_data::materials.push_back(material2);
|
||||
|
||||
auto material3 = make_shared<material>();
|
||||
material3->ambient = glm::vec4(0, 0, 0.15, 1);
|
||||
// material3->diffuse = glm::vec4(1.0, 0.7, 0.2, 1);
|
||||
material3->diffuse = glm::vec4(1, 1, 1, 1);
|
||||
material3->specular = glm::vec4(0.3, 0.3, 0.3, 1);
|
||||
material3->shininess = 200;
|
||||
material3->cast_shadows = true;
|
||||
demo_data::materials.push_back(material3);
|
||||
|
||||
auto material4 = make_shared<material>();
|
||||
material4->ambient = glm::vec4(0, 0, 0.15, 1);
|
||||
// material4->diffuse = glm::vec4(1.0, 0.7, 0.2, 1);
|
||||
material4->diffuse = glm::vec4(1, 1, 1, 1);
|
||||
material4->specular = glm::vec4(0.3, 0.3, 0.3, 1);
|
||||
material4->shininess = 200;
|
||||
material4->cast_shadows = false;
|
||||
demo_data::materials.push_back(material4);
|
||||
|
||||
auto material5 = make_shared<material>();
|
||||
material5->ambient = glm::vec4(0.1, 0.1, 0.15, 1);
|
||||
// material4->diffuse = glm::vec4(1.0, 0.7, 0.2, 1);
|
||||
material5->diffuse = glm::vec4(1, 1, 1, 1);
|
||||
material5->specular = glm::vec4(1, 1, 1, 1);
|
||||
material5->shininess = 10;
|
||||
material5->cast_shadows = false;
|
||||
demo_data::materials.push_back(material5);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Set up demo parts
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
DemoPartClear demoPartClear;
|
||||
demoPartClear.startTime = 0;
|
||||
demoPartClear.endTime = DEMO_LENGTH_IN_SECONDS;
|
||||
demoPartClear.color = glm::vec4(0.1f, 0.1f, 0.3f, 1.0f);
|
||||
|
||||
DemoPartScene demoPartScene;
|
||||
demoPartScene.startTime = 0;
|
||||
demoPartScene.endTime = DEMO_LENGTH_IN_SECONDS;
|
||||
demoPartScene.cameraName = "cam1";
|
||||
demoPartScene.lightName = "light1";
|
||||
|
||||
scene *scene1 = new scene();
|
||||
demoPartScene.scene_ = shared_ptr<scene>(scene1);
|
||||
|
||||
auto smallSphere = shared_ptr<mesh_node>(new mesh_node());
|
||||
smallSphere->mesh_ = demo_data::meshes[1];
|
||||
smallSphere->material_ = demo_data::materials[0];
|
||||
smallSphere->position = glm::vec3(0, 0, 0);
|
||||
smallSphere->scale = glm::vec3(0.5);
|
||||
// meshNode->rotation = glm::angleAxis(2.25f , glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
auto ground_plane = std::make_shared<mesh_node>();
|
||||
ground_plane->mesh_ = demo_data::meshes[2];
|
||||
ground_plane->material_ = demo_data::materials[1];
|
||||
ground_plane->position = glm::vec3(0, 0, 0);
|
||||
ground_plane->scale = glm::vec3(10);
|
||||
ground_plane->rotation = glm::angleAxis(3.141529f / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
auto black_plane = std::make_shared<mesh_node>();
|
||||
black_plane->mesh_ = demo_data::meshes[2];
|
||||
black_plane->material_ = demo_data::materials[1];
|
||||
black_plane->position = glm::vec3(0, 5, -5);
|
||||
black_plane->scale = glm::vec3(10);
|
||||
black_plane->rotation = angleAxis(3.141529f, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
auto left_plane = std::make_shared<mesh_node>();
|
||||
left_plane->mesh_ = demo_data::meshes[2];
|
||||
left_plane->material_ = demo_data::materials[1];
|
||||
left_plane->position = glm::vec3(-5, 5, 0);
|
||||
left_plane->scale = glm::vec3(10);
|
||||
left_plane->rotation = angleAxis(-3.141529f / 2.0f, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
auto right_plane = std::make_shared<mesh_node>();
|
||||
right_plane->mesh_ = demo_data::meshes[2];
|
||||
right_plane->material_ = demo_data::materials[1];
|
||||
right_plane->position = glm::vec3(5, 5, 0);
|
||||
right_plane->scale = glm::vec3(10);
|
||||
right_plane->rotation = angleAxis(3.141529f / 2.0f, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
auto bigSphere = make_shared<mesh_node>();
|
||||
bigSphere->mesh_ = demo_data::meshes[0];
|
||||
bigSphere->material_ = demo_data::materials[4];
|
||||
bigSphere->position = glm::vec3(-2, 2, 0);
|
||||
bigSphere->scale = glm::vec3(0.8);
|
||||
bigSphere->rotation = glm::angleAxis(3.141529f / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
|
||||
auto lightMeshNode = std::make_shared<mesh_node>();
|
||||
lightMeshNode->mesh_ = demo_data::meshes[0];
|
||||
lightMeshNode->material_ = demo_data::materials[3];
|
||||
lightMeshNode->position = glm::vec3(1, 2, 1);
|
||||
lightMeshNode->scale = glm::vec3(0.1);
|
||||
|
||||
auto camNode = std::make_shared<camera_node>();
|
||||
camNode->name = "cam1";
|
||||
camNode->position = glm::vec3(0, 2, 5);
|
||||
camNode->target = glm::vec3(0, 0, 0);
|
||||
camNode->fov = 45;
|
||||
|
||||
auto lightNode = make_shared<light_node>(light_type::spot);
|
||||
lightNode->name = "light1";
|
||||
lightNode->position = glm::vec3(-5, 5, 0);
|
||||
lightNode->spot_target = glm::vec3(0, 0, 0);
|
||||
lightNode->spot_cutoff = 50.0f;
|
||||
lightNode->spot_exponent = 16.0f;
|
||||
lightNode->ambient = glm::vec4(0.1, 0.1, 0.1, 1.0);
|
||||
lightNode->diffuse = glm::vec4(0.5, 1.0, 1.0, 1.0);
|
||||
lightNode->specular = glm::vec4(0.0, 0.8, 0.1, 1.0);
|
||||
|
||||
auto lightNode2 = make_shared<light_node>(light_type::spot);
|
||||
lightNode2->name = "light2";
|
||||
lightNode2->position = glm::vec3(5, 5, 0);
|
||||
lightNode2->spot_target = glm::vec3(0, 0, 0);
|
||||
lightNode2->spot_cutoff = 50.0f;
|
||||
lightNode2->spot_exponent = 16.0f;
|
||||
lightNode2->ambient = glm::vec4(0.1, 0.1, 0.1, 1.0);
|
||||
lightNode2->diffuse = glm::vec4(1.0, 0.5, 1.0, 1.0);
|
||||
lightNode2->specular = glm::vec4(0.0, 0.8, 0.1, 1.0);
|
||||
|
||||
scene1->tree->add(ground_plane);
|
||||
scene1->tree->add(black_plane);
|
||||
scene1->tree->add(left_plane);
|
||||
scene1->tree->add(right_plane);
|
||||
|
||||
scene1->tree->add(smallSphere);
|
||||
scene1->tree->add(bigSphere);
|
||||
scene1->tree->add(lightMeshNode);
|
||||
|
||||
scene1->tree->add(camNode);
|
||||
|
||||
scene1->tree->add(lightNode);
|
||||
scene1->tree->add(lightNode2);
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Run demo
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
timer timer1;
|
||||
while (!peripherals.should_close() && timer1.seconds_since_start() < DEMO_LENGTH_IN_SECONDS) {
|
||||
double elapsedSeconds = timer1.seconds_since_start();
|
||||
|
||||
// bigSphere->mesh_ = mesh_generator::extrude(mesh_generator::sphere(50, 50), {200, 201, 100, 101, 400, 401}, 0.05,
|
||||
// (int) ((sin(elapsedSeconds) + 0.5) * 40));
|
||||
//
|
||||
// smallSphere->position = glm::vec3(0, sin(2 * M_PI * 0.13 * elapsedSeconds) * 2.0 + 0.5, 0);
|
||||
//// meshNode->position = glm::vec3(0, 0.001, 0);
|
||||
// // camNode->target = glm::vec3(0, 0.0001, 0);
|
||||
// // camNode->position = glm::vec3(0, 5, -10);
|
||||
// lightNode2->position = glm::vec3(5 * sin(2 * M_PI * 0.15 * elapsedSeconds), 2,
|
||||
// 5 * cos(2 * M_PI * 0.15 * elapsedSeconds));
|
||||
// lightNode->position = glm::vec3(5 * cos(2 * M_PI * 0.75 * elapsedSeconds), 2,
|
||||
// 5 * sin(2 * M_PI * 0.75 * elapsedSeconds));
|
||||
//
|
||||
// lightMeshNode->position = lightNode2->position;
|
||||
//
|
||||
// bigSphere->rotation *= angleAxis((float) (M_PI / 4.0 * timer1.lap()), normalize(glm::vec3(0.2, 0.5, 0.3)));
|
||||
|
||||
demoPartClear.process(demoPartClear.normalizeTime(elapsedSeconds));
|
||||
demoPartScene.process(demoPartScene.normalizeTime(elapsedSeconds));
|
||||
|
||||
peripherals.swap_buffers();
|
||||
peripherals.poll_events();
|
||||
}
|
||||
|
||||
// double alpha = 0.0;
|
||||
// while (!peripherals.should_close()) {
|
||||
// alpha += 0.01;
|
||||
// if (alpha > 1.0) alpha = 0.0;
|
||||
//
|
||||
// glClearColor(0.0 * alpha, 0.1 * alpha, 1.0 * alpha, 1 * alpha);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
//
|
||||
// peripherals.swap_buffers();
|
||||
// peripherals.poll_events();
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ set(HEADERS
|
||||
${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_renderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scene_tree.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shader_constants.h
|
||||
@@ -38,6 +39,7 @@ set(SOURCE
|
||||
${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_renderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scene_tree.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shader_constants.cpp
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
||||
#include <easylogging++.h>
|
||||
|
||||
#define BEGIN_NAMESPACE namespace acidrain {
|
||||
#define END_NAMESPACE };
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
set(HEADERS
|
||||
${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_engine.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_clear.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_marching_cubes.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_render_to_texture.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_scene.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_scene.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/marching_cubes_table.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
set(SOURCE
|
||||
${SOURCE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_clear.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_marching_cubes.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_render_to_texture.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_part_scene.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/demo_scene.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
#add_subdirectory(animation)
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "demo_data.h"
|
||||
#include "demo_part_scene.h"
|
||||
#include "demo_part_clear.h"
|
||||
#include "demo_part_marching_cubes.h"
|
||||
#include "demo_part_render_to_texture.h"
|
||||
#include "texture_generator.h"
|
||||
#include "mesh_generator.h"
|
||||
#include "mesh_node.h"
|
||||
#include "camera_node.h"
|
||||
#include "light_node.h"
|
||||
#include "animation/vec3_track.h"
|
||||
#include "animation/float_track.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "demo_part.h"
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
struct DemoPart {
|
||||
float startTime; // absolute time, since demo starts
|
||||
float endTime; // absolute time, since demo starts
|
||||
|
||||
float normalizeTime(float absoluteTimeInSeconds) {
|
||||
return (absoluteTimeInSeconds - startTime) / static_cast<float>(endTime - startTime);
|
||||
}
|
||||
|
||||
virtual void process(float normalizedTime) = 0;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "demo_part_clear.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
void DemoPartClear::process(float normalizedTime) {
|
||||
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
|
||||
GLbitfield mask = 0;
|
||||
if (clearDepth)
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
if (clearColor)
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
|
||||
if (clearStencil)
|
||||
mask |= GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
glClear(mask);
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "demo_part.h"
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
struct DemoPartClear : DemoPart {
|
||||
|
||||
glm::vec4 color = glm::vec4(0, 0, 0, 0);
|
||||
|
||||
bool clearDepth = true;
|
||||
bool clearColor = true;
|
||||
bool clearStencil = true;
|
||||
|
||||
void process(float normalizedTime) override;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,224 @@
|
||||
#include "demo_part_marching_cubes.h"
|
||||
#include "marching_cubes_table.h"
|
||||
#include "mesh_generator.h"
|
||||
// #include <iostream>
|
||||
// #include <iomanip>
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
DemoPartMarchingCubes::DemoPartMarchingCubes(std::shared_ptr<mesh> affectedMesh) {
|
||||
mesh_ = affectedMesh;
|
||||
|
||||
field.emitters.push_back(glm::vec4(0, 0.7, 0, 1));
|
||||
field.emitters.push_back(glm::vec4(0, -0.7, 0, 1));
|
||||
field.emitters.push_back(glm::vec4(0.3, -0.7, 0.3, 1));
|
||||
// field.emitters.push_back(glm::vec4(-0.5, 0.7, -0.3, 1));
|
||||
}
|
||||
|
||||
void DemoPartMarchingCubes::process(float normalizedTime) {
|
||||
|
||||
field.emitters[0].x = sin(normalizedTime * 2 * M_PI * 4);
|
||||
field.emitters[0].z = cos(normalizedTime * 2 * M_PI * 4);
|
||||
field.emitters[0].y = 0.7 * cos(normalizedTime * 2 * M_PI * 2);
|
||||
|
||||
field.emitters[1].x = sin(normalizedTime * 2 * M_PI * 7);
|
||||
field.emitters[1].z = cos(normalizedTime * 2 * M_PI * 3.5);
|
||||
|
||||
field.emitters[2].y = 0.5 * sin(normalizedTime * 2 * M_PI * 4);
|
||||
field.emitters[2].z = 0.8 * cos(normalizedTime * 2 * M_PI * 2);
|
||||
|
||||
// field.emitters[3].y = 0.8 * cos(normalizedTime * 2 * M_PI * 3);
|
||||
// field.emitters[3].z = 0.2 * sin(normalizedTime * 2 * M_PI * 8);
|
||||
|
||||
grid.evaluateForces(field);
|
||||
grid.triangulate(*mesh_.get(), minFieldValue);
|
||||
|
||||
for (auto &v: mesh_->vertices)
|
||||
v.normal = field.getFieldNormalAt(v.position);
|
||||
|
||||
// calculateNormals(*mesh.get());
|
||||
}
|
||||
|
||||
void MarchingCubesGrid::evaluateForces(ForceField &field) {
|
||||
|
||||
// Make sure we have enough space preallocated.
|
||||
// We use resize because we want it also logically allocated with defaults
|
||||
// so we can simply access an item at certain index with no issues
|
||||
gridVertices.resize((xCells + 1) * (yCells + 1) * (zCells + 1));
|
||||
|
||||
glm::vec3 stepSize(
|
||||
(xMax - xMin) / static_cast<float>(xCells),
|
||||
(yMax - yMin) / static_cast<float>(yCells),
|
||||
(zMax - zMin) / static_cast<float>(zCells)
|
||||
);
|
||||
|
||||
int cellIndex = 0;
|
||||
glm::vec4 gridVertex;
|
||||
|
||||
// starts from top-left-farthest and ends to bottom-right-closest
|
||||
for (int z = 0; z <= zCells; z++) {
|
||||
gridVertex.z = zMin + z * stepSize.z;
|
||||
|
||||
for (int y = 0; y <= yCells; y++) {
|
||||
gridVertex.y = yMax - y * stepSize.y;
|
||||
|
||||
for (int x = 0; x <= xCells; x++) {
|
||||
gridVertex.x = xMin + x * stepSize.x;
|
||||
gridVertex.w = field.getFieldValueAt(glm::vec3(gridVertex));
|
||||
|
||||
// std::cout << std::setprecision(5) << std::fixed << "(x: " << gridVertex.x << ", y: " << gridVertex.y << ", z: " << gridVertex.z << ", val: " << gridVertex.w << ")" << std::endl;
|
||||
|
||||
gridVertices[cellIndex] = gridVertex;
|
||||
|
||||
cellIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MarchingCubesGrid::triangulate(mesh &m, float minFieldValue) {
|
||||
|
||||
m.vertices.clear();
|
||||
m.facets.clear();
|
||||
m.edges.clear();
|
||||
|
||||
for (int z = 0; z < zCells; z++) {
|
||||
for (int y = 0; y < yCells; y++) {
|
||||
for (int x = 0; x < xCells; x++) {
|
||||
|
||||
calculateCellVertices(x, y, z);
|
||||
|
||||
int cellType = classifyCell(minFieldValue);
|
||||
if (!edgeTable[cellType]) continue;
|
||||
|
||||
calculateIntersectionVertices(cellType, minFieldValue);
|
||||
addResultingFacets(m, cellType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MarchingCubesGrid::calculateCellVertices(int x, int y, int z) {
|
||||
// TODO: optimize these out. they are constant for a given grid size.
|
||||
int xVerts = xCells + 1;
|
||||
int yVerts = yCells + 1;
|
||||
int vertsInXYPlane = xVerts * yVerts;
|
||||
|
||||
int leftTopFarthestIndex = z * vertsInXYPlane + x + y * xCells;
|
||||
|
||||
// see http://paulbourke.net/geometry/polygonise/polygonise1.gif
|
||||
cubeVertexIndices[0] = leftTopFarthestIndex + xVerts;
|
||||
cubeVertexIndices[1] = leftTopFarthestIndex + xVerts + 1;
|
||||
cubeVertexIndices[2] = leftTopFarthestIndex + xVerts + 1 + vertsInXYPlane;
|
||||
cubeVertexIndices[3] = leftTopFarthestIndex + xVerts + vertsInXYPlane;
|
||||
|
||||
cubeVertexIndices[4] = leftTopFarthestIndex;
|
||||
cubeVertexIndices[5] = leftTopFarthestIndex + 1;
|
||||
cubeVertexIndices[6] = leftTopFarthestIndex + 1 + vertsInXYPlane;
|
||||
cubeVertexIndices[7] = leftTopFarthestIndex + vertsInXYPlane;
|
||||
}
|
||||
|
||||
|
||||
int MarchingCubesGrid::classifyCell(float minFieldValue) {
|
||||
int result = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (gridVertices[cubeVertexIndices[i]].w <= minFieldValue)
|
||||
result |= 1 << i;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void MarchingCubesGrid::calculateIntersectionVertices(int cellType, float minFieldValue) {
|
||||
|
||||
if (edgeTable[cellType] & 1)
|
||||
intersectionVertices[0] = intersection(cubeVertexIndices[0], cubeVertexIndices[1], minFieldValue);
|
||||
if (edgeTable[cellType] & 2)
|
||||
intersectionVertices[1] = intersection(cubeVertexIndices[1], cubeVertexIndices[2], minFieldValue);
|
||||
if (edgeTable[cellType] & 4)
|
||||
intersectionVertices[2] = intersection(cubeVertexIndices[2], cubeVertexIndices[3], minFieldValue);
|
||||
if (edgeTable[cellType] & 8)
|
||||
intersectionVertices[3] = intersection(cubeVertexIndices[3], cubeVertexIndices[0], minFieldValue);
|
||||
if (edgeTable[cellType] & 16)
|
||||
intersectionVertices[4] = intersection(cubeVertexIndices[4], cubeVertexIndices[5], minFieldValue);
|
||||
if (edgeTable[cellType] & 32)
|
||||
intersectionVertices[5] = intersection(cubeVertexIndices[5], cubeVertexIndices[6], minFieldValue);
|
||||
if (edgeTable[cellType] & 64)
|
||||
intersectionVertices[6] = intersection(cubeVertexIndices[6], cubeVertexIndices[7], minFieldValue);
|
||||
if (edgeTable[cellType] & 128)
|
||||
intersectionVertices[7] = intersection(cubeVertexIndices[7], cubeVertexIndices[4], minFieldValue);
|
||||
if (edgeTable[cellType] & 256)
|
||||
intersectionVertices[8] = intersection(cubeVertexIndices[0], cubeVertexIndices[4], minFieldValue);
|
||||
if (edgeTable[cellType] & 512)
|
||||
intersectionVertices[9] = intersection(cubeVertexIndices[1], cubeVertexIndices[5], minFieldValue);
|
||||
if (edgeTable[cellType] & 1024)
|
||||
intersectionVertices[10] = intersection(cubeVertexIndices[2], cubeVertexIndices[6], minFieldValue);
|
||||
if (edgeTable[cellType] & 2048)
|
||||
intersectionVertices[11] = intersection(cubeVertexIndices[3], cubeVertexIndices[7], minFieldValue);
|
||||
|
||||
}
|
||||
|
||||
glm::vec3 MarchingCubesGrid::intersection(int v1Index, int v2Index, float minFieldValue) {
|
||||
glm::vec4 &a = gridVertices[v1Index];
|
||||
glm::vec4 &b = gridVertices[v2Index];
|
||||
|
||||
if (a.w != b.w) {
|
||||
float alpha = (minFieldValue - a.w) / (b.w - a.w);
|
||||
return glm::mix(glm::vec3(a), glm::vec3(b), alpha);
|
||||
} else {
|
||||
return glm::vec3(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MarchingCubesGrid::addResultingFacets(mesh &m, int cellType) {
|
||||
facet f{};
|
||||
vertex v{};
|
||||
int vertexOffset = m.vertices.size();
|
||||
|
||||
for (int n = 0; triTable[cellType][n] != -1; n += 3) {
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
v.position = intersectionVertices[triTable[cellType][n + 2 - i]];
|
||||
m.vertices.push_back(v);
|
||||
}
|
||||
|
||||
f.a = vertexOffset++;
|
||||
f.b = vertexOffset++;
|
||||
f.c = vertexOffset++;
|
||||
m.facets.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float ForceField::getFieldValueAt(const glm::vec3 &position) const {
|
||||
float result = 0;
|
||||
|
||||
for (auto &e: emitters) {
|
||||
float dist = glm::length(glm::vec3(e) - position);
|
||||
result += 1.0f / (dist * dist);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 ForceField::getFieldNormalAt(const glm::vec3 &position) const {
|
||||
// Hello blackpawn! http://www.blackpawn.com/texts/metanormals/default.html
|
||||
glm::vec3 normal = glm::vec3(0);
|
||||
|
||||
for (auto &e: emitters) {
|
||||
float distance = glm::length(glm::vec3(e) - position);
|
||||
float coefficient = 1.0f / (distance * distance * distance * distance);
|
||||
|
||||
glm::vec3 temp = (glm::vec3(e) - position) * 2.0f;
|
||||
normal += temp * coefficient;
|
||||
}
|
||||
|
||||
return glm::normalize(normal);
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "demo_part.h"
|
||||
#include "mesh.h"
|
||||
#include <memory>
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
struct ForceField {
|
||||
float getFieldValueAt(const glm::vec3 &position) const;
|
||||
glm::vec3 getFieldNormalAt(const glm::vec3 &position) const;
|
||||
|
||||
std::vector<glm::vec4> emitters; // vec4 = position + strength
|
||||
};
|
||||
|
||||
struct MarchingCubesGrid {
|
||||
int xCells = 60;
|
||||
int yCells = 60;
|
||||
int zCells = 60;
|
||||
|
||||
float xMin = -2;
|
||||
float xMax = 2;
|
||||
|
||||
float yMin = -2;
|
||||
float yMax = 2;
|
||||
|
||||
float zMin = -2;
|
||||
float zMax = 2;
|
||||
|
||||
// .w will hold field value for code size optimisation purposes
|
||||
std::vector<glm::vec4> gridVertices;
|
||||
|
||||
void evaluateForces(ForceField &field);
|
||||
void triangulate(mesh &m, float minFieldValue);
|
||||
|
||||
private:
|
||||
void calculateCellVertices(int x, int y, int z);
|
||||
int classifyCell(float minFieldValue);
|
||||
void calculateIntersectionVertices(int cellType, float minFieldValue);
|
||||
void addResultingFacets(mesh &m, int cellType);
|
||||
glm::vec3 intersection(int v1Index, int v2Index, float minFieldValue);
|
||||
|
||||
int cubeVertexIndices[8];
|
||||
glm::vec3 intersectionVertices[12];
|
||||
|
||||
};
|
||||
|
||||
struct DemoPartMarchingCubes : DemoPart {
|
||||
DemoPartMarchingCubes(std::shared_ptr<mesh> affectedMesh);
|
||||
|
||||
void process(float normalizedTime) override;
|
||||
|
||||
MarchingCubesGrid grid;
|
||||
ForceField field;
|
||||
float minFieldValue = 2.6;
|
||||
std::shared_ptr<mesh> mesh_;
|
||||
};
|
||||
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "demo_part_render_to_texture.h"
|
||||
#include "demo_data.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
DemoPartRenderToTexture::DemoPartRenderToTexture(int s, RenderToTextureAction a)
|
||||
: slot(s), action(a) {
|
||||
}
|
||||
|
||||
void DemoPartRenderToTexture::process(float normalizedTime) {
|
||||
if (action == RenderToTextureAction::Start)
|
||||
demo_data::fbos[slot]->use();
|
||||
else
|
||||
demo_data::fbos[slot]->unuse();
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "demo_part.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
enum class RenderToTextureAction {
|
||||
Start,
|
||||
Stop
|
||||
};
|
||||
|
||||
struct DemoPartRenderToTexture : DemoPart {
|
||||
|
||||
DemoPartRenderToTexture(int slot, RenderToTextureAction action);
|
||||
|
||||
void process(float normalizedTime) override;
|
||||
|
||||
int slot;
|
||||
RenderToTextureAction action;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "demo_part_scene.h"
|
||||
#include "mesh_node.h"
|
||||
#include "camera_node.h"
|
||||
#include "light_node.h"
|
||||
#include "shader_constants.h"
|
||||
#include "demo_data.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
DemoPartScene::DemoPartScene() {
|
||||
renderer = std::make_shared<scene_renderer>();
|
||||
}
|
||||
|
||||
DemoPartScene::~DemoPartScene() {
|
||||
}
|
||||
|
||||
void DemoPartScene::process(float normalizedTime) {
|
||||
if (scene_->animation)
|
||||
scene_->animation->set_at_time(normalizedTime);
|
||||
|
||||
if (scene_->tree) {
|
||||
scene_->tree->transform();
|
||||
renderer->render(*scene_->tree, cameraName);
|
||||
}
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "demo_part.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "scene.h"
|
||||
#include "material.h"
|
||||
#include "scene_renderer.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
struct DemoPartScene : DemoPart {
|
||||
|
||||
DemoPartScene();
|
||||
virtual ~DemoPartScene();
|
||||
|
||||
std::shared_ptr<scene_renderer> renderer;
|
||||
std::shared_ptr<scene> scene_;
|
||||
std::string cameraName;
|
||||
std::string lightName;
|
||||
float animationStartTime; // normalized time, [0-1]
|
||||
float animationEndTime; // normalized time, [0-1]
|
||||
|
||||
GLuint fboID;
|
||||
GLuint shadowMapTexID;
|
||||
std::shared_ptr<shader> firstPassShadowShader;
|
||||
std::shared_ptr<material> firstPassShadowMaterial;
|
||||
|
||||
std::shared_ptr<shader> secondPassShadowShader;
|
||||
std::shared_ptr<material> secondPassShadowMaterial;
|
||||
|
||||
void process(float normalizedTime) override;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1 @@
|
||||
#include "demo_scene.h"
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
#include "glm/vec3.hpp"
|
||||
#include "glm/mat4x4.hpp"
|
||||
#include "glm/gtx/quaternion.hpp"
|
||||
#include "glm/gtx/transform.hpp"
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
|
||||
#include "shader.h"
|
||||
#include "texture.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
#pragma once
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
// Thanks, Paul Bourke!
|
||||
// This came from: http://paulbourke.net/geometry/polygonise/
|
||||
// In order to reduce size perhaps we could use the alternative (shorter) table from http://paulbourke.net/geometry/polygonise/table2.txt
|
||||
|
||||
static int edgeTable[256] = {
|
||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
||||
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
|
||||
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
|
||||
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
|
||||
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
|
||||
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
||||
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
||||
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
||||
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
||||
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
||||
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
||||
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
|
||||
};
|
||||
|
||||
static int triTable[256][16] = {
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
|
||||
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
|
||||
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
|
||||
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
|
||||
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
|
||||
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
|
||||
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
|
||||
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
|
||||
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
|
||||
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
|
||||
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
|
||||
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
|
||||
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
|
||||
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
|
||||
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
|
||||
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
|
||||
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
|
||||
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
|
||||
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
|
||||
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
|
||||
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
|
||||
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
|
||||
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
|
||||
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
|
||||
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
|
||||
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
|
||||
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
|
||||
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
|
||||
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
|
||||
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
|
||||
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
|
||||
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
|
||||
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
|
||||
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
|
||||
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
|
||||
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
|
||||
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
|
||||
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
|
||||
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
|
||||
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
|
||||
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
|
||||
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
|
||||
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
|
||||
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
|
||||
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
|
||||
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
|
||||
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
|
||||
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
|
||||
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
|
||||
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
|
||||
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
|
||||
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
|
||||
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
|
||||
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
|
||||
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
|
||||
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
|
||||
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
|
||||
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
|
||||
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
|
||||
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
|
||||
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
|
||||
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
|
||||
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
|
||||
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
|
||||
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
|
||||
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
|
||||
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
|
||||
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
|
||||
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
|
||||
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
|
||||
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
|
||||
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
|
||||
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
|
||||
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
|
||||
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
|
||||
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
|
||||
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
|
||||
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
|
||||
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
|
||||
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
|
||||
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
|
||||
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
|
||||
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
|
||||
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
|
||||
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
|
||||
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
|
||||
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
|
||||
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
|
||||
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
|
||||
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
|
||||
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
|
||||
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
+1
-1
@@ -76,7 +76,7 @@ void set_material(std::shared_ptr<material> &mat) {
|
||||
}
|
||||
}
|
||||
|
||||
void unset_material(shared_ptr<material> &mat) {
|
||||
void unset_material(std::shared_ptr<material> &mat) {
|
||||
// int textureUnit = 0;
|
||||
// for (auto& kv : material->textures) {
|
||||
// glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
|
||||
@@ -28,7 +28,7 @@ bool peripherals_glfw::init() {
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
window = glfwCreateWindow(800, 600, "Demo", nullptr, nullptr);
|
||||
window = glfwCreateWindow(1024, 768, "Demo", nullptr, nullptr);
|
||||
if (window == nullptr) {
|
||||
std::cerr << "Unable to create window!" << std::endl;
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
#include "scene_renderer.h"
|
||||
#include "light_node.h"
|
||||
#include "shader.h"
|
||||
#include "material.h"
|
||||
#include "mesh_node.h"
|
||||
#include "demo_data.h"
|
||||
#include "camera_node.h"
|
||||
#include "glm/gtc/matrix_inverse.hpp"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
static const char *vs = R"(
|
||||
#version 150 core
|
||||
|
||||
uniform mat4 mmtx;
|
||||
uniform mat4 wlmtx;
|
||||
uniform mat4 lpmtx;
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
in vec2 texCoords;
|
||||
|
||||
void main() {
|
||||
gl_Position = lpmtx * wlmtx * mmtx * vec4(position, 1);
|
||||
}
|
||||
)";
|
||||
|
||||
static const char *ps = R"(
|
||||
#version 150 core
|
||||
|
||||
out vec4 colorOut;
|
||||
|
||||
void main (void) {
|
||||
colorOut = vec4(1);
|
||||
}
|
||||
)";
|
||||
|
||||
static const char *vs2 = R"(
|
||||
#version 150 core
|
||||
|
||||
uniform mat4 mmtx;
|
||||
uniform mat4 vmtx;
|
||||
uniform mat3 nmtx;
|
||||
uniform mat4 pmtx;
|
||||
|
||||
uniform mat4 wlmtx[4];
|
||||
uniform mat4 lpmtx[4];
|
||||
uniform mat4 sbmtx;
|
||||
|
||||
out vec3 vEyeSpaceNormal;
|
||||
out vec3 vEyeSpacePosition;
|
||||
out vec4 vShadowCoords[4];
|
||||
out vec2 vTexCoords;
|
||||
uniform int numLights;
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
in vec2 texCoords;
|
||||
|
||||
void main() {
|
||||
gl_Position = pmtx * vmtx * mmtx * vec4(position, 1);
|
||||
|
||||
vEyeSpacePosition = (vmtx * mmtx * vec4(position, 1)).xyz;
|
||||
vEyeSpaceNormal = normalize(nmtx * normal);
|
||||
vTexCoords = texCoords;
|
||||
|
||||
for (int i = 0; i < numLights; i++) {
|
||||
vShadowCoords[i] = sbmtx * lpmtx[i] * wlmtx[i] * mmtx * vec4(position, 1);
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
static const char *ps2 = R"(
|
||||
#version 150 core
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap4;
|
||||
|
||||
|
||||
uniform vec3 lPosEye[4];
|
||||
uniform vec4 matAmbientCol;
|
||||
uniform vec4 matDiffuseCol;
|
||||
uniform vec4 matSpecularCol;
|
||||
uniform float matShininess;
|
||||
uniform int numLights;
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
struct Light {
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
float spotCutoff;
|
||||
float spotExponent;
|
||||
vec3 attenuation;
|
||||
vec4 ambient;
|
||||
vec4 diffuse;
|
||||
vec4 specular;
|
||||
};
|
||||
|
||||
uniform Light light[4];
|
||||
|
||||
const vec2 texmapscale = vec2(1.0f/1024.0f, 1.0f/1024.0f);
|
||||
|
||||
in vec3 vEyeSpaceNormal;
|
||||
in vec3 vEyeSpacePosition;
|
||||
in vec4 vShadowCoords[4];
|
||||
in vec2 vTexCoords;
|
||||
|
||||
const float shadowBias = -0.01;
|
||||
|
||||
float lookup(int lightIndex, vec2 offset) {
|
||||
if (lightIndex == 0)
|
||||
return textureProj(
|
||||
shadowMap1,
|
||||
vShadowCoords[lightIndex] + vec4(
|
||||
offset.x * texmapscale.x * vShadowCoords[lightIndex].w,
|
||||
offset.y * texmapscale.y * vShadowCoords[lightIndex].w,
|
||||
shadowBias,
|
||||
0.0
|
||||
)
|
||||
);
|
||||
else if (lightIndex == 1)
|
||||
return textureProj(
|
||||
shadowMap2,
|
||||
vShadowCoords[lightIndex] + vec4(
|
||||
offset.x * texmapscale.x * vShadowCoords[lightIndex].w,
|
||||
offset.y * texmapscale.y * vShadowCoords[lightIndex].w,
|
||||
shadowBias,
|
||||
0.0
|
||||
)
|
||||
);
|
||||
else if (lightIndex == 2)
|
||||
return textureProj(
|
||||
shadowMap3,
|
||||
vShadowCoords[lightIndex] + vec4(
|
||||
offset.x * texmapscale.x * vShadowCoords[lightIndex].w,
|
||||
offset.y * texmapscale.y * vShadowCoords[lightIndex].w,
|
||||
shadowBias,
|
||||
0.0
|
||||
)
|
||||
);
|
||||
else
|
||||
return textureProj(
|
||||
shadowMap3,
|
||||
vShadowCoords[lightIndex] + vec4(
|
||||
offset.x * texmapscale.x * vShadowCoords[lightIndex].w,
|
||||
offset.y * texmapscale.y * vShadowCoords[lightIndex].w,
|
||||
shadowBias,
|
||||
0.0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 finalColor = vec4(0);
|
||||
vec3 normal = normalize(vEyeSpaceNormal);
|
||||
|
||||
vec4 diffuseColor = matDiffuseCol * texture(diffuseMap, vTexCoords);
|
||||
|
||||
for (int i = 0; i < numLights; i++) {
|
||||
vec3 L = (light[i].position - vEyeSpacePosition);
|
||||
float d = length(L);
|
||||
L = normalize(L);
|
||||
float diffuse = max(0.0, dot(normal, L));
|
||||
|
||||
vec3 E = normalize(-vEyeSpacePosition);
|
||||
vec3 R = normalize(-reflect(L, vEyeSpaceNormal));
|
||||
float specular = pow(max(dot(R, E), 0.0), 0.3*matShininess);
|
||||
|
||||
float shadow = 1.0f;
|
||||
if (vShadowCoords[i].w > 1.0) {
|
||||
float x,y;
|
||||
shadow = 0.0f;
|
||||
for (y = -1.5 ; y <=1.5 ; y+=1.0)
|
||||
for (x = -1.5 ; x <=1.5 ; x+=1.0)
|
||||
shadow += lookup(i, vec2(x,y));
|
||||
|
||||
shadow /= 16.0;
|
||||
}
|
||||
|
||||
finalColor += matAmbientCol * matDiffuseCol;
|
||||
finalColor += diffuseColor * diffuse * light[i].diffuse * shadow;
|
||||
finalColor += matSpecularCol * specular * shadow;
|
||||
}
|
||||
|
||||
outColor = finalColor;
|
||||
}
|
||||
)";
|
||||
|
||||
scene_renderer::scene_renderer()
|
||||
: fbo_id{0} {
|
||||
|
||||
glGenFramebuffers(1, &fbo_id);
|
||||
|
||||
first_pass_shadow_shader = std::make_shared<shader>(vs, ps);
|
||||
|
||||
first_pass_shadow_material = std::make_shared<material>();
|
||||
first_pass_shadow_material->shader = first_pass_shadow_shader;
|
||||
first_pass_shadow_material->zbuffer_write = true;
|
||||
first_pass_shadow_material->zbuffer_test = true;
|
||||
first_pass_shadow_material->transparent = false;
|
||||
first_pass_shadow_material->cull_faces = true;
|
||||
first_pass_shadow_material->cull_front_faces = false;
|
||||
|
||||
second_pass_shadow_shader = std::make_shared<shader>(vs2, ps2);
|
||||
|
||||
second_pass_shadow_material = std::make_shared<material>();
|
||||
second_pass_shadow_material->shader = second_pass_shadow_shader;
|
||||
second_pass_shadow_material->diffuse = glm::vec4(1, 0, 0, 1);
|
||||
second_pass_shadow_material->zbuffer_write = true;
|
||||
second_pass_shadow_material->zbuffer_test = true;
|
||||
second_pass_shadow_material->transparent = false;
|
||||
second_pass_shadow_material->cull_faces = false;
|
||||
second_pass_shadow_material->flat_shaded = false;
|
||||
}
|
||||
|
||||
void scene_renderer::attach_depth_texture(texture &text) const {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, text.get_id(), 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void scene_renderer::render(const scene_tree &scene, const std::string &cameraName) {
|
||||
for (auto &node: scene.lights) {
|
||||
light_node &light = node->as_light_node();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
render_shadow_map(scene, light);
|
||||
}
|
||||
|
||||
std::shared_ptr<scene_node> camNode = scene.nodeByNameAndType(cameraName, scene_node_type::camera);
|
||||
camera_node &camera = camNode->as_camera_node();
|
||||
|
||||
shader_consts.set(uniforms::ViewMatrix, camera.view_matrix);
|
||||
shader_consts.set(uniforms::ProjectionMatrix, camera.projection_matrix);
|
||||
shader_consts.set(uniforms::NumberOfLights, (int) scene.lights.size());
|
||||
// TODO: inject this from outside
|
||||
// shaderConstants.set(Uniforms::DemoPartNormalizedTime, normalizedTime);
|
||||
|
||||
set_material(second_pass_shadow_material);
|
||||
|
||||
int lightIndex = 0;
|
||||
for (auto &node: scene.lights) {
|
||||
light_node &light = node->as_light_node();
|
||||
|
||||
shader_consts.set(uniforms::WorldToLightMatrix, light.world_to_light_matrix[0], lightIndex);
|
||||
shader_consts.set(uniforms::LightProjectionMatrix, light.light_projection_matrix[0], lightIndex);
|
||||
shader_consts.set(uniforms::ShadowMatrix, light.final_shadow_map_matrix[0], lightIndex);
|
||||
shader_consts.set(uniforms::ShadowBiasMatrix, light.shadow_map_bias_matrix);
|
||||
|
||||
glm::vec3 lightPositionInEyeSpace = light.position - camera.position;
|
||||
shader_consts.set(uniforms::LightPosition, lightPositionInEyeSpace, lightIndex);
|
||||
|
||||
glm::vec3 lightTargetInEyeSpace = light.spot_target - camera.position;
|
||||
shader_consts.set(uniforms::LightTarget, lightTargetInEyeSpace, lightIndex);
|
||||
|
||||
shader_consts.set(uniforms::LightAmbient, light.ambient, lightIndex);
|
||||
shader_consts.set(uniforms::LightDiffuse, light.diffuse, lightIndex);
|
||||
shader_consts.set(uniforms::LightSpecular, light.specular, lightIndex);
|
||||
|
||||
shader_consts.set(uniforms::LightSpotCutoff, light.spot_cutoff, lightIndex);
|
||||
shader_consts.set(uniforms::LightSpotExponent, light.spot_exponent, lightIndex);
|
||||
shader_consts.set(uniforms::LightAttenuation, light.attenuation, lightIndex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + 4 + lightIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, light.shadow_map[0]->get_id());
|
||||
|
||||
if (lightIndex == 0) {
|
||||
shader_consts.set(uniforms::ShadowMap1, lightIndex + 4);
|
||||
} else if (lightIndex == 1) {
|
||||
shader_consts.set(uniforms::ShadowMap2, lightIndex + 4);
|
||||
} else if (lightIndex == 2) {
|
||||
shader_consts.set(uniforms::ShadowMap3, lightIndex + 4);
|
||||
} else if (lightIndex == 3) {
|
||||
shader_consts.set(uniforms::ShadowMap4, lightIndex + 4);
|
||||
}
|
||||
|
||||
lightIndex++;
|
||||
}
|
||||
|
||||
// draw opaque nodes
|
||||
for (auto &node: scene.nodes) {
|
||||
if (node->type == scene_node_type::mesh) {
|
||||
mesh_node &meshNode = node->as_mesh_node();
|
||||
|
||||
glm::mat3 normalMatrix = glm::inverseTranspose(
|
||||
glm::mat3(camera.view_matrix * meshNode.model_to_world_space_matrix));
|
||||
|
||||
shader_consts.set(uniforms::ModelToWorldMatrix, meshNode.model_to_world_space_matrix);
|
||||
shader_consts.set(uniforms::NormalMatrix, normalMatrix);
|
||||
shader_consts.set(uniforms::MaterialAmbientColor, meshNode.material_->ambient);
|
||||
shader_consts.set(uniforms::MaterialDiffuseColor, meshNode.material_->diffuse);
|
||||
shader_consts.set(uniforms::MaterialSpecularColor, meshNode.material_->specular);
|
||||
shader_consts.set(uniforms::MaterialShininess, meshNode.material_->shininess);
|
||||
|
||||
shader_consts.apply_to(*second_pass_shadow_material->shader);
|
||||
|
||||
if (meshNode.material_->textures[texture_role::diffuse]) {
|
||||
int textureUnit = 0;
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
meshNode.material_->textures[texture_role::diffuse]->use();
|
||||
|
||||
second_pass_shadow_material->shader->setIntUniform(textureUnit, "diffuseMap");
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
meshNode.mesh_->render(second_pass_shadow_material->flat_shaded);
|
||||
}
|
||||
}
|
||||
|
||||
unset_material(second_pass_shadow_material);
|
||||
}
|
||||
|
||||
void scene_renderer::render_shadow_map(const scene_tree &scene, light_node &light) {
|
||||
light.calculate_local_transform();
|
||||
|
||||
attach_depth_texture(*light.shadow_map[0]);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
|
||||
glViewport(0, 0, light.shadow_map_width, light.shadow_map_width);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
shader_consts.set(uniforms::WorldToLightMatrix, light.world_to_light_matrix[0]);
|
||||
shader_consts.set(uniforms::LightProjectionMatrix, light.light_projection_matrix[0]);
|
||||
shader_consts.set(uniforms::ShadowMatrix, light.final_shadow_map_matrix[0]);
|
||||
shader_consts.set(uniforms::ShadowBiasMatrix, light.shadow_map_bias_matrix);
|
||||
|
||||
set_material(first_pass_shadow_material);
|
||||
|
||||
// first pass - draw all objects that may cast shadows as seen from light
|
||||
for (auto &node: scene.nodes) {
|
||||
if (node->type == scene_node_type::mesh) {
|
||||
mesh_node &meshNode = node->as_mesh_node();
|
||||
if (!meshNode.material_->transparent && meshNode.material_->cast_shadows) {
|
||||
|
||||
shader_consts.set(uniforms::ModelToWorldMatrix, meshNode.model_to_world_space_matrix);
|
||||
shader_consts.apply_to(*first_pass_shadow_material->shader);
|
||||
|
||||
meshNode.mesh_->render(first_pass_shadow_material->flat_shaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset_material(first_pass_shadow_material);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDrawBuffer(GL_BACK_LEFT);
|
||||
glViewport(0, 0, demo_data::screen_width, demo_data::screen_height);
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "scene_tree.h"
|
||||
#include <string>
|
||||
#include "shader_constants.h"
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
class shader;
|
||||
|
||||
class material;
|
||||
|
||||
class texture;
|
||||
|
||||
class scene_renderer {
|
||||
public:
|
||||
|
||||
scene_renderer();
|
||||
|
||||
void render(const scene_tree &scene, const std::string &cameraName);
|
||||
|
||||
private:
|
||||
void attach_depth_texture(texture &text) const;
|
||||
void render_shadow_map(const scene_tree &scene, light_node &light);
|
||||
|
||||
std::shared_ptr<shader> first_pass_shadow_shader;
|
||||
std::shared_ptr<material> first_pass_shadow_material;
|
||||
|
||||
std::shared_ptr<shader> second_pass_shadow_shader;
|
||||
std::shared_ptr<material> second_pass_shadow_material;
|
||||
|
||||
shader_constants shader_consts;
|
||||
GLuint fbo_id;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
+26
-1
@@ -14,11 +14,34 @@ void check_compile_error(GLuint shaderId) {
|
||||
char errorLog[maxLength];
|
||||
glGetShaderInfoLog(shaderId, maxLength, &maxLength, &errorLog[0]);
|
||||
|
||||
std::cout << "Shader error: " << errorLog << std::endl;
|
||||
LOG(ERROR) << "Shader compile error: (" << isCompiled << ") - " << std::string(errorLog);
|
||||
|
||||
//Provide the infolog in whatever manor you deem best.
|
||||
//Exit with failure.
|
||||
glDeleteShader(shaderId); //Don't leak the shader.
|
||||
} else {
|
||||
LOG(INFO) << "Shader successfully compiled";
|
||||
}
|
||||
}
|
||||
|
||||
void check_link_error(GLuint program_id) {
|
||||
GLint is_linked = 0;
|
||||
glGetShaderiv(program_id, GL_LINK_STATUS, &is_linked);
|
||||
if (is_linked == GL_FALSE) {
|
||||
GLint maxLength = 0;
|
||||
glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
|
||||
//The maxLength includes the NULL character
|
||||
char errorLog[maxLength];
|
||||
glGetShaderInfoLog(program_id, maxLength, &maxLength, &errorLog[0]);
|
||||
|
||||
LOG(ERROR) << "Shader program link error: " << "(" << is_linked << ") - " << std::string(errorLog);
|
||||
|
||||
//Provide the info log in whatever manner you deem best.
|
||||
//Exit with failure.
|
||||
glDeleteShader(program_id); //Don't leak the program shader.
|
||||
} else {
|
||||
LOG(INFO) << "Shader program successfully linked";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +67,8 @@ shader::shader(const char *vs_content, const char *ps_content) {
|
||||
glBindAttribLocation(program_id, 2, "texCoords");
|
||||
|
||||
glLinkProgram(program_id);
|
||||
check_link_error(program_id);
|
||||
|
||||
glUseProgram(program_id);
|
||||
}
|
||||
|
||||
|
||||
+29
-29
@@ -3,35 +3,35 @@
|
||||
|
||||
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");
|
||||
uniform_descriptor uniforms::ViewMatrix("vmtx");
|
||||
uniform_descriptor uniforms::ProjectionMatrix("pmtx");
|
||||
uniform_descriptor uniforms::ModelToWorldMatrix("mmtx");
|
||||
uniform_descriptor uniforms::NormalMatrix("nmtx");
|
||||
uniform_descriptor uniforms::WorldToLightMatrix("wlmtx");
|
||||
uniform_descriptor uniforms::LightProjectionMatrix("lpmtx");
|
||||
uniform_descriptor uniforms::ShadowBiasMatrix("sbmtx");
|
||||
uniform_descriptor uniforms::ShadowMatrix("smtx");
|
||||
uniform_descriptor uniforms::DemoPartNormalizedTime("dptimen");
|
||||
uniform_descriptor uniforms::LightPositionInEyeSpace("lPosEye");
|
||||
uniform_descriptor uniforms::MaterialAmbientColor("matAmbientCol");
|
||||
uniform_descriptor uniforms::MaterialDiffuseColor("matDiffuseCol");
|
||||
uniform_descriptor uniforms::MaterialSpecularColor("matSpecularCol");
|
||||
uniform_descriptor uniforms::MaterialShininess("matShininess");
|
||||
uniform_descriptor uniforms::DiffuseMap("diffuseMap");
|
||||
uniform_descriptor uniforms::ShadowMap("shadowMap");
|
||||
uniform_descriptor uniforms::ShadowMap1("shadowMap1");
|
||||
uniform_descriptor uniforms::ShadowMap2("shadowMap2");
|
||||
uniform_descriptor uniforms::ShadowMap3("shadowMap3");
|
||||
uniform_descriptor uniforms::ShadowMap4("shadowMap4");
|
||||
uniform_descriptor uniforms::NumberOfLights("numLights");
|
||||
uniform_descriptor uniforms::LightPosition("light", "position");
|
||||
uniform_descriptor uniforms::LightTarget("light", "target");
|
||||
uniform_descriptor uniforms::LightAmbient("light", "ambient");
|
||||
uniform_descriptor uniforms::LightDiffuse("light", "diffuse");
|
||||
uniform_descriptor uniforms::LightSpecular("light", "specular");
|
||||
uniform_descriptor uniforms::LightSpotCutoff("light", "spotCutoff");
|
||||
uniform_descriptor uniforms::LightSpotExponent("light", "spotExponent");
|
||||
uniform_descriptor uniforms::LightAttenuation("light", "attenuation");
|
||||
|
||||
/*
|
||||
const char* ShaderConstantNameResolver::nameFor(const ShaderConstantType& type) {
|
||||
|
||||
+117
-121
@@ -11,100 +11,96 @@
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct UniformDescriptor {
|
||||
string structureName;
|
||||
string memberName;
|
||||
struct uniform_descriptor {
|
||||
std::string structure_name;
|
||||
std::string member_name;
|
||||
|
||||
// TODO: implement memoization of uniform name calculation
|
||||
|
||||
UniformDescriptor(const char *member) {
|
||||
structureName = "";
|
||||
memberName = member;
|
||||
uniform_descriptor(const char *member) {
|
||||
structure_name = "";
|
||||
member_name = member;
|
||||
}
|
||||
|
||||
UniformDescriptor(const char *structure, const char *member) {
|
||||
structureName = structure;
|
||||
memberName = member;
|
||||
uniform_descriptor(const char *structure, const char *member) {
|
||||
structure_name = structure;
|
||||
member_name = member;
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
if (structureName.empty())
|
||||
return memberName;
|
||||
std::string get_name() {
|
||||
if (structure_name.empty())
|
||||
return member_name;
|
||||
|
||||
std::stringstream ss(structureName);
|
||||
ss << "." << memberName;
|
||||
std::stringstream ss(structure_name);
|
||||
ss << "." << member_name;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string getName(int index) {
|
||||
std::string get_name(int index) {
|
||||
std::stringstream ss;
|
||||
if (structureName.empty()) {
|
||||
ss << memberName << "[" << index << "]";
|
||||
if (structure_name.empty()) {
|
||||
ss << member_name << "[" << index << "]";
|
||||
} else {
|
||||
ss << structureName << "[" << index << "]." << memberName;
|
||||
ss << structure_name << "[" << index << "]." << member_name;
|
||||
}
|
||||
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;
|
||||
struct uniforms {
|
||||
static uniform_descriptor ViewMatrix;
|
||||
static uniform_descriptor ProjectionMatrix;
|
||||
static uniform_descriptor ModelToWorldMatrix;
|
||||
static uniform_descriptor NormalMatrix;
|
||||
static uniform_descriptor WorldToLightMatrix;
|
||||
static uniform_descriptor LightProjectionMatrix;
|
||||
static uniform_descriptor ShadowBiasMatrix;
|
||||
static uniform_descriptor ShadowMatrix;
|
||||
static uniform_descriptor DemoPartNormalizedTime;
|
||||
static uniform_descriptor LightPositionInEyeSpace;
|
||||
static uniform_descriptor MaterialAmbientColor;
|
||||
static uniform_descriptor MaterialDiffuseColor;
|
||||
static uniform_descriptor MaterialSpecularColor;
|
||||
static uniform_descriptor MaterialShininess;
|
||||
static uniform_descriptor DiffuseMap;
|
||||
static uniform_descriptor ShadowMap;
|
||||
static uniform_descriptor ShadowMap1;
|
||||
static uniform_descriptor ShadowMap2;
|
||||
static uniform_descriptor ShadowMap3;
|
||||
static uniform_descriptor ShadowMap4;
|
||||
static uniform_descriptor NumberOfLights;
|
||||
static uniform_descriptor LightPosition;
|
||||
static uniform_descriptor LightTarget;
|
||||
static uniform_descriptor LightAmbient;
|
||||
static uniform_descriptor LightDiffuse;
|
||||
static uniform_descriptor LightSpecular;
|
||||
static uniform_descriptor LightSpotCutoff;
|
||||
static uniform_descriptor LightSpotExponent;
|
||||
static uniform_descriptor LightAttenuation;
|
||||
};
|
||||
|
||||
enum class ShaderConstantType {
|
||||
Vec3,
|
||||
Vec4,
|
||||
Integer,
|
||||
Float,
|
||||
Mat3,
|
||||
Mat4
|
||||
enum class shader_constant_type {
|
||||
vec3,
|
||||
vec4,
|
||||
integer,
|
||||
decimal,
|
||||
mat3,
|
||||
mat4
|
||||
};
|
||||
|
||||
class ShaderConstantValue {
|
||||
class shader_constant_value {
|
||||
public:
|
||||
|
||||
ShaderConstantType type;
|
||||
shader_constant_type type;
|
||||
|
||||
glm::vec3 vec3Val;
|
||||
glm::vec4 vec4Val;
|
||||
glm::mat3 mat3Val;
|
||||
glm::mat4 mat4Val;
|
||||
int intVal;
|
||||
float floatVal;
|
||||
glm::vec3 vec3Val{};
|
||||
glm::vec4 vec4Val{};
|
||||
glm::mat3 mat3Val{};
|
||||
glm::mat4 mat4Val{};
|
||||
int intVal{};
|
||||
float floatVal{};
|
||||
|
||||
ShaderConstantValue(const ShaderConstantValue &rhs) {
|
||||
shader_constant_value(const shader_constant_value &rhs) {
|
||||
type = rhs.type;
|
||||
vec3Val = rhs.vec3Val;
|
||||
vec4Val = rhs.vec4Val;
|
||||
@@ -114,119 +110,119 @@ public:
|
||||
floatVal = rhs.floatVal;
|
||||
}
|
||||
|
||||
ShaderConstantValue(glm::vec3 &value) {
|
||||
shader_constant_value(glm::vec3 &value) {
|
||||
vec3Val = value;
|
||||
type = ShaderConstantType::Vec3;
|
||||
type = shader_constant_type::vec3;
|
||||
}
|
||||
|
||||
ShaderConstantValue(glm::vec4 &value) {
|
||||
shader_constant_value(glm::vec4 &value) {
|
||||
vec4Val = value;
|
||||
type = ShaderConstantType::Vec4;
|
||||
type = shader_constant_type::vec4;
|
||||
}
|
||||
|
||||
ShaderConstantValue(glm::mat3 &value) {
|
||||
shader_constant_value(glm::mat3 &value) {
|
||||
mat3Val = value;
|
||||
type = ShaderConstantType::Mat3;
|
||||
type = shader_constant_type::mat3;
|
||||
}
|
||||
|
||||
ShaderConstantValue(glm::mat4 &value) {
|
||||
shader_constant_value(glm::mat4 &value) {
|
||||
mat4Val = value;
|
||||
type = ShaderConstantType::Mat4;
|
||||
type = shader_constant_type::mat4;
|
||||
}
|
||||
|
||||
ShaderConstantValue(int value) {
|
||||
shader_constant_value(int value) {
|
||||
intVal = value;
|
||||
type = ShaderConstantType::Integer;
|
||||
type = shader_constant_type::integer;
|
||||
}
|
||||
|
||||
ShaderConstantValue(float value) {
|
||||
shader_constant_value(float value) {
|
||||
floatVal = value;
|
||||
type = ShaderConstantType::Float;
|
||||
type = shader_constant_type::decimal;
|
||||
}
|
||||
|
||||
void applyTo(shader &shader, const char *uniformName) {
|
||||
void apply_to(shader &shader, const char *uniform_name) {
|
||||
switch (type) {
|
||||
case ShaderConstantType::Vec3:
|
||||
shader.setVec3Uniform(glm::value_ptr(vec3Val), uniformName);
|
||||
case shader_constant_type::vec3:
|
||||
shader.setVec3Uniform(glm::value_ptr(vec3Val), uniform_name);
|
||||
break;
|
||||
case ShaderConstantType::Vec4:
|
||||
shader.setVec4Uniform(glm::value_ptr(vec4Val), uniformName);
|
||||
case shader_constant_type::vec4:
|
||||
shader.setVec4Uniform(glm::value_ptr(vec4Val), uniform_name);
|
||||
break;
|
||||
case ShaderConstantType::Mat3:
|
||||
shader.setMatrix3Uniform(glm::value_ptr(mat3Val), uniformName);
|
||||
case shader_constant_type::mat3:
|
||||
shader.setMatrix3Uniform(glm::value_ptr(mat3Val), uniform_name);
|
||||
break;
|
||||
case ShaderConstantType::Mat4:
|
||||
shader.setMatrix4Uniform(glm::value_ptr(mat4Val), uniformName);
|
||||
case shader_constant_type::mat4:
|
||||
shader.setMatrix4Uniform(glm::value_ptr(mat4Val), uniform_name);
|
||||
break;
|
||||
case ShaderConstantType::Integer:
|
||||
shader.setIntUniform(intVal, uniformName);
|
||||
case shader_constant_type::integer:
|
||||
shader.setIntUniform(intVal, uniform_name);
|
||||
break;
|
||||
case ShaderConstantType::Float:
|
||||
shader.setFloatUniform(floatVal, uniformName);
|
||||
case shader_constant_type::decimal:
|
||||
shader.setFloatUniform(floatVal, uniform_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ShaderConstants {
|
||||
class shader_constants {
|
||||
public:
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::mat3 value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::mat3 value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::mat3 value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::mat3 value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::mat4 value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::mat4 value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::mat4 value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::mat4 value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::vec3 value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::vec3 value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::vec3 value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::vec3 value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::vec4 value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::vec4 value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, glm::vec4 value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, glm::vec4 value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, int value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, int value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, int value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, int value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, float value) {
|
||||
constants[descriptor.getName()] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, float value) {
|
||||
constants[descriptor.get_name()] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void set(UniformDescriptor descriptor, float value, int index) {
|
||||
constants[descriptor.getName(index)] = make_shared<ShaderConstantValue>(value);
|
||||
void set(uniform_descriptor descriptor, float value, int index) {
|
||||
constants[descriptor.get_name(index)] = std::make_shared<shader_constant_value>(value);
|
||||
}
|
||||
|
||||
void applyTo(shader &shd) {
|
||||
void apply_to(shader &shd) {
|
||||
for (auto &kv: constants)
|
||||
kv.second->applyTo(shd, kv.first.c_str());
|
||||
kv.second->apply_to(shd, kv.first.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<string, std::shared_ptr<ShaderConstantValue>> constants;
|
||||
std::map<std::string, std::shared_ptr<shader_constant_value>> constants;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
void timeline::setAt(float time) {
|
||||
void timeline::set_at_time(float time) {
|
||||
for (auto &track: tracks)
|
||||
track->set_at(time);
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
struct timeline {
|
||||
void setAt(float time);
|
||||
void set_at_time(float time);
|
||||
std::vector<std::shared_ptr<animation_track>> tracks;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user