Commit 3c473089 authored by 's avatar
Browse files

Added visualization for lines

parent ffe4df92
#version 430
in vec4 color;
layout(location=0) out vec4 out_color;
void main()
{
out_color = color;
}
\ No newline at end of file
#version 430
#extension GL_ARB_shading_language_include : require
#include <raytracer/std.glh>
#include <raytracer/basic_structs.glh>
#include <raytracer/buffers.glh>
#include <raytracer/utilities.glh>
struct Patch
{
uint face;
uvec2 index;
uint padding;
};
struct Line
{
vec4 center_begin;
vec4 center_end;
Patch begin;
Patch end;
Hit nearest;
Hit farthest;
};
STD_BUFFER line_buffer
{
Line b_lines[];
};
layout(points) in;
layout(line_strip, max_vertices = 2) out;
uniform mat4 u_view_projection;
uniform uint u_mesh;
uniform uint u_triangle_count;
out vec4 color;
void main()
{
int tbi_id = int(gl_in[0].gl_Position.x);
Line line = b_lines[tbi_id];
vec4 last_position;
gl_Position = u_view_projection * line.center_begin;
color = vec4(0, 1, 0, 1);
if (line.end.face == 6) {
EmitVertex();
}
gl_Position = u_view_projection * line.center_end;
color = vec4(1, 0, 0, 1);
if (line.end.face == 6) {
EmitVertex();
}
EndPrimitive();
return;
if (line.nearest.triangle < u_triangle_count && line.farthest.triangle < u_triangle_count) {
Mesh mesh = b_meshes[u_mesh];
Triangle triangle = mesh.triangles[line.nearest.triangle];
Vertex v1 = mesh.vertices[triangle.indices[1]];
Vertex v2 = mesh.vertices[triangle.indices[2]];
Vertex v3 = mesh.vertices[triangle.indices[0]];
vec4 position = hit__getFromBarycentric(line.nearest.barycentric, triangle, position);
gl_Position = u_view_projection * position;
color = vec4(0, 1, 0, 1);
last_position = position;
color.b = (line.begin.face) / 6.f;
EmitVertex();
}
if (line.farthest.triangle < u_triangle_count) {
Mesh mesh = b_meshes[u_mesh];
Triangle triangle = mesh.triangles[line.farthest.triangle];
Vertex v1 = mesh.vertices[triangle.indices[1]];
Vertex v2 = mesh.vertices[triangle.indices[2]];
Vertex v3 = mesh.vertices[triangle.indices[0]];
vec4 position = hit__getFromBarycentric(line.farthest.barycentric, triangle, position);
if (position == last_position)
{
position += vec4(vec3(1e-2), 0);
}
gl_Position = u_view_projection * position;
color = vec4(1, 0, 0, 1);
color.b = (line.end.face) / 6.f;
EmitVertex();
}
EndPrimitive();
}
\ No newline at end of file
#version 430
void main()
{
gl_Position = vec4(gl_VertexID, 0, 0, 1);
}
\ No newline at end of file
......@@ -3,6 +3,7 @@
#include <advanced/IntersectionTests.h>
#include <advanced/linespace/LineSpaceMaskGenerator.h>
#include <advanced/linespace/LineSpaceMath.h>
#include <advanced/tracer/RayGenerator.h>
......
......@@ -47,7 +47,7 @@ namespace glare
//Create a skybox from cube map.
m_skybox = std::make_shared<core::Skybox>(core::Skybox::collectFilesFrom(core::asset("/textures/ryfjallet/")));
initializeScene(core::asset("/meshes/scenery/Spheres.dae"), 1.f);
initializeScene(core::asset("/meshes/scenery/simple_flat_box.dae"), 1.f);
initializeRenderRequirements();
initializeAdvanced();
initializeGUI();
......@@ -55,24 +55,34 @@ namespace glare
gl::setEnabled(gl::EnableParameter::eMultisample, true);
////////////////////////////////////////////////////////////////////////////////
/////
///// LS STUFF
/////
{
#define DEBUG__GENERATE_LS
#ifdef DEBUG__GENERATE_LS
m_collector->collect();
const auto &mesh_collector = m_collector->meshCollectors().begin()->second;
/*math::UniformBoundsSubdivision subdivision(mesh_collector.bounds(), 20);
size_t lines = advanced::lsmath::calculateLineCount(subdivision);
Log_Info << subdivision.subdivisions.x << "; " << subdivision.subdivisions.y << "; " << subdivision.subdivisions.z;*/
//Exemplary Line generation
unsigned line_mesh_id = 0;
const auto &mesh_collector = m_collector->meshCollectors().at(line_mesh_id);
std::vector<advanced::lsmath::Line> lines = advanced::lsmath::generateLines(*mesh_collector, 10);
advanced::lsmath::generateLines(mesh_collector, 20);
std::vector<std::shared_ptr<core::Shader>> shaders = {
std::make_shared<core::Shader>(gl::ShaderType::eVertex, "/linespace/visualize/lines.vert"),
std::make_shared<core::Shader>(gl::ShaderType::eGeometry, "/linespace/visualize/lines.geom"),
std::make_shared<core::Shader>(gl::ShaderType::eFragment, "/linespace/visualize/lines.frag")
};
std::unique_ptr<core::ShaderProgram> lines_program = std::make_unique<core::ShaderProgram>(shaders);
quitPromptDefault(0);
}
core::Buffer<gl::BufferType::eShaderStorage> line_buffer;
line_buffer.setData(lines, gl::BufferUsage::eDynamicRead);
core::VertexArray lines_vao;
#endif
/////
////////////////////////////////////////////////////////////////////////////////
......@@ -110,6 +120,25 @@ namespace glare
case AppRenderState::eVoxels:
{
//TODO: Render voxels? Which ones? local ones!
m_collector->collect();
lines_program->use();
lines_program->updateStorageBuffer("mesh_buffer", m_collector->meshBuffer());
lines_program->updateStorageBuffer("line_buffer", line_buffer);
/* auto vec = line_buffer.read<advanced::lsmath::Line>(lines.size());
for (auto && bla : vec) {
if (*reinterpret_cast<unsigned*>(&bla.end.face) == 6) {
Log_Error << "BELAJE";
}
}*/
lines_program->updateUniformUInt("u_mesh", line_mesh_id);
lines_program->updateUniformUInt("u_triangle_count", unsigned(mesh_collector->triangles().size()));
lines_program->updateUniformMatrix("u_view_projection", core::EngineState::main_camera->getViewProjection());
lines_vao.draw(gl::PrimitiveType::ePoints, lines.size());
}
break;
case AppRenderState::eRaytrace:
......@@ -240,7 +269,7 @@ namespace glare
ImGui::Title("Render Mode");
ImGui::RadioButton("Lines", &render_state, 0);
ImGui::RadioButton("Default GBuffer", &render_state, 1);
// ImGui::RadioButton("Voxels", &render_state, 2);
ImGui::RadioButton("Voxels", &render_state, 2);
ImGui::RadioButton("Raytracer", &render_state, 3);
if (m_render_state != AppRenderState(render_state)) {
......
......@@ -90,7 +90,7 @@ namespace glare
e2 = v3 - v1;
//Begin calculating determinant - also used to calculate u parameter
P = glm::cross(glm::vec3(ray.direction), e2);
P = glm::cross(glm::vec3(ray.direction.xyz), e2);
//if determinant is near zero, ray lies in plane of triangle
det = glm::dot(e1, P);
......@@ -109,14 +109,14 @@ namespace glare
if (u < 0.f || u > 1.f) return false;
//Prepare to test v parameter
Q = glm::cross(T, e1);
Q = cross(T, e1);
//Calculate V parameter and test bound
v = glm::dot(glm::vec3(ray.direction), Q) * inv_det;
v = glm::dot(glm::vec3(ray.direction.xyz), Q) * inv_det;
//The intersection lies outside of the triangle
if (v < 0.f || u + v > 1.f) return false;
t = dot(e2, Q) * inv_det;
t = glm::dot(e2, Q) * inv_det;
if (t > EPSILON) { //ray intersection
return true;
......
......@@ -12,74 +12,108 @@ namespace glare
return unsigned(face) % 3;
}
void lsmath::generateLines(const LocalCollector &collector, unsigned max_subdivisions)
const glm::uvec3 face_width_axises = { 2, 2, 0 };
const glm::uvec3 face_height_axises = { 1, 0, 1 };
std::vector<lsmath::Line> lsmath::generateLines(const LocalCollector &collector, unsigned max_subdivisions)
{
const math::UniformBoundsSubdivision subdivision(collector.bounds(), max_subdivisions);
const glm::uvec3 face_widths = { subdivision.subdivisions.z, subdivision.subdivisions.x, subdivision.subdivisions.x };
const glm::uvec3 face_heights = { subdivision.subdivisions.y, subdivision.subdivisions.z, subdivision.subdivisions.y };
const glm::uvec3 face_widths = { subdivision.subdivisions.z, subdivision.subdivisions.z, subdivision.subdivisions.x };
const glm::uvec3 face_heights = { subdivision.subdivisions.y, subdivision.subdivisions.x, subdivision.subdivisions.y };
const LocalBVH &line_bvh = static_cast<const LocalBVH&>(collector.datastructure());
std::vector<Line> lines(calculateLineCount(subdivision));
core::ClockMS clock;
Line line;
for (line.begin = Patch(Face::ePosX); line.begin.face < Face::eNegZ; line.begin.face = Face(unsigned(line.begin.face)+1))
{
for (line.end = Patch(Face(unsigned(line.begin.face) + 1)); line.end.face <= Face::eNegZ; line.end.face = Face(unsigned(line.end.face) + 1))
size_t current_index = 0;
Log_Info << "Linespace is being generated now...";
//Loop through all possible and useful startface-endface-configurations
for (line.begin = Patch(Face::ePosX); line.begin.face < Face::eNegZ; line.begin.face = Face(unsigned(line.begin.face) + 1))
for (line.end = Patch(Face(unsigned(line.begin.face) + 1)); line.end.face <= Face::eNegZ; line.end.face = Face(unsigned(line.end.face) + 1)) {
Log_Info << "Working on lines between Faces " << unsigned(line.begin.face) << " and " << unsigned(line.end.face) << "...";
//For all start patches...
for (line.begin.index_horizontal = 0; line.begin.index_horizontal < face_widths[unsigned(line.begin.face) % 3]; ++line.begin.index_horizontal)
for (line.begin.index_vertical = 0; line.begin.index_vertical < face_heights[unsigned(line.begin.face) % 3]; ++line.begin.index_vertical)
{
for (line.begin.index_horizontal = 0; line.begin.index_horizontal < face_widths[unsigned(line.begin.face) % 3]; ++line.begin.index_horizontal)
//... and all end patches...
for (line.end.index_horizontal = 0; line.end.index_horizontal < face_widths[unsigned(line.end.face) % 3]; ++line.end.index_horizontal)
for (line.end.index_vertical = 0; line.end.index_vertical < face_heights[unsigned(line.end.face) % 3]; ++line.end.index_vertical)
{
for (line.begin.index_vertical = 0; line.begin.index_vertical < face_heights[unsigned(line.begin.face) % 3]; ++line.begin.index_vertical)
{
for (line.end.index_horizontal = 0; line.end.index_horizontal < face_widths[unsigned(line.end.face) % 3]; ++line.end.index_horizontal)
{
for (line.end.index_vertical = 0; line.end.index_vertical < face_heights[unsigned(line.end.face) % 3]; ++line.end.index_vertical)
{
glm::vec3 center_begin = getPatchCenter(collector.bounds(), subdivision, line.begin);
glm::vec3 center_end = getPatchCenter(collector.bounds(), subdivision, line.end);
math::Ray ray{ glm::vec4(center_begin, 1), glm::vec4(glm::normalize(center_end - center_begin), 0)};
math::Hit nearest_hit, farthest_hit;
line_bvh.nearestAndFarthestIntersection(ray, nearest_hit, farthest_hit);
}
}
//... do a center line check.
line.center_begin = glm::vec4(getPatchCenter(collector.bounds(), subdivision, line.begin), 1);
line.center_end = glm::vec4(getPatchCenter(collector.bounds(), subdivision, line.end), 1);
math::Ray ray;
ray.direction = glm::normalize(line.center_end - line.center_begin);
ray.origin = line.center_begin;
glm::vec3 normal(0);
normal[unsigned(line.begin.face) % 3] = 1 - 2 * (line.begin.face >= Face::eNegX);
if (unsigned(line.end.face) == 6) {
Log_Error << "Wat?";
line.center_begin = glm::vec4(getPatchCenter(collector.bounds(), subdivision, line.begin), 1);
}
line.nearest.barycentric = glm::vec3(-1);
line.farthest.barycentric = glm::vec3(-1);
line_bvh.nearestAndFarthestIntersection(ray, line.nearest, line.farthest);
lines[current_index++] = line;
}
}
}
Log_Info << "Took: " << clock.time();
Log_Info << "Linespace generation took " << clock.time() << "ms";
Log_Info << "[Linespace Data] Lines: " << lines.size();
Log_Info << "[Linespace Data] Memory: " << (lines.size() * sizeof(Line)) << " Bytes";
Log_Info << "[Linespace Data] Patch Subdivisions: " << subdivision.subdivisions.x << ", " << subdivision.subdivisions.y << ", " << subdivision.subdivisions.z;
Log_Info << "[Linespace Data] Patch Size: " << subdivision.size;
Log_Info << "[Linespace Data] Object Bounds: " << collector.bounds();
return lines;
}
glm::vec3 lsmath::getPatchCenter(const math::Bounds &bounds, const math::UniformBoundsSubdivision &subdivision, const Patch &patch)
{
const glm::uvec3 face_widths = { subdivision.subdivisions.z, subdivision.subdivisions.x, subdivision.subdivisions.x };
const glm::uvec3 face_heights = { subdivision.subdivisions.y, subdivision.subdivisions.z, subdivision.subdivisions.y };
unsigned face_index = unsigned(patch.face);
unsigned max_factor = 1-(face_index / 3); // 1 for pos plane, 0 for neg plane
unsigned max_factor = 1 - (face_index / 3); // 1 for pos plane, 0 for neg plane
glm::vec3 position;
position[face_index % 3] = bounds.min[face_index % 3] + max_factor*bounds.size()[face_index%3];
position[(face_index + 1) % 3] = bounds.min[(face_index + 1) % 3] + patch.index_horizontal * subdivision.size + subdivision.size/2;
position[(face_index + 2) % 3] = bounds.min[(face_index + 2) % 3] + patch.index_vertical * subdivision.size + subdivision.size / 2;
position[face_index % 3] = bounds.min[face_index % 3] + max_factor*bounds.size()[face_index % 3];
unsigned axis_width = face_width_axises[face_index % 3];
unsigned axis_height = face_height_axises[face_index % 3];
if (patch.face < Face::eNegX) {
position[axis_width] = bounds.min[axis_width] + patch.index_horizontal * subdivision.size + subdivision.size / 2;
position[axis_height] = bounds.min[axis_height] + patch.index_vertical * subdivision.size + subdivision.size / 2;
}
else {
position[axis_width] = bounds.min[axis_width] + bounds.size()[axis_width] - (patch.index_horizontal * subdivision.size + subdivision.size / 2);
position[axis_height] = bounds.min[axis_height] + bounds.size()[axis_height] - (patch.index_vertical * subdivision.size + subdivision.size / 2);
}
return position;
}
size_t lsmath::lineIndex(const math::UniformBoundsSubdivision &subdivision, const Line &line)
{
return 0;
throw std::runtime_error("lsmath::lineIndex is not implemented!");
}
size_t lsmath::patchIndex(const math::UniformBoundsSubdivision &subdivision, const Patch &patch)
{
float offset_x = subdivision.subdivisions.y * subdivision.subdivisions.z;
float offset_y = subdivision.subdivisions.x * subdivision.subdivisions.z;
float offset_z = subdivision.subdivisions.x * subdivision.subdivisions.y;
throw std::runtime_error("lsmath::patchIndex is not implemented!");
float offset_x = float(subdivision.subdivisions.y * subdivision.subdivisions.z);
float offset_y = float(subdivision.subdivisions.x * subdivision.subdivisions.z);
float offset_z = float(subdivision.subdivisions.x * subdivision.subdivisions.y);
glm::uvec3 face_widths = { subdivision.subdivisions.z, subdivision.subdivisions.x, subdivision.subdivisions.x };
int face_width = face_widths[faceAxis(patch.face)];
......
......@@ -14,8 +14,8 @@ namespace glare
{
ePosX = 0,
ePosY = 1,
eNegX = 2,
ePosZ = 3,
ePosZ = 2,
eNegX = 3,
eNegY = 4,
eNegZ = 5
};
......@@ -43,13 +43,19 @@ namespace glare
struct Line
{
glm::vec4 center_begin;
glm::vec4 center_end;
Patch begin;
Patch end;
math::Hit nearest;
math::Hit farthest;
};
unsigned faceAxis(Face face);
void generateLines(const LocalCollector &collector, unsigned max_subdivisions);
std::vector<Line> generateLines(const LocalCollector &collector, unsigned max_subdivisions);
glm::vec3 getPatchCenter(const math::Bounds &bounds, const math::UniformBoundsSubdivision &subdivision, const Patch &patch);
......
......@@ -396,7 +396,7 @@ namespace glare
bool LocalBVH::nearestAndFarthestIntersection(const math::Ray &ray, math::Hit &nearest_hit, math::Hit &farthest_hit) const
{
float min_t = std::numeric_limits<float>::max();
float max_t = std::numeric_limits<float>::min();
float max_t = -min_t;
return traverse(ray, nearest_hit, false, std::numeric_limits<float>::max(), min_t, true, farthest_hit, max_t);
}
......
......@@ -39,7 +39,7 @@ namespace glare
m_triangles[i / 3] = triangle;
}
datastructure->apply(m_vertices, m_triangles);
m_datastructure->apply(m_vertices, m_triangles);
if (!m_triangle_buffer)
m_triangle_buffer = std::make_shared<core::Buffer<gl::BufferType::eShaderStorage>>();
......
......@@ -164,13 +164,12 @@ namespace glare
void SceneCollector::collectMeshRenderer(std::shared_ptr<core::MeshRenderer> mesh_renderer)
{
advanced::LocalCollector mc(*mesh_renderer, std::make_shared<advanced::LocalBVH>());
m_mesh_collectors.emplace(mesh_renderer->id(), mc);
m_mesh_collectors.emplace(mesh_renderer->id(), std::make_unique<advanced::LocalCollector>(*mesh_renderer, std::make_shared<advanced::LocalBVH>()));
}
void SceneCollector::updateMeshTransform(std::shared_ptr<core::MeshRenderer> mesh_renderer)
{
m_mesh_collectors[mesh_renderer->id()].updateTransform(*mesh_renderer);
m_mesh_collectors[mesh_renderer->id()]->updateTransform(*mesh_renderer);
}
void SceneCollector::collectMaterial(std::shared_ptr<core::Material> material)
......@@ -188,7 +187,7 @@ namespace glare
{
for (auto &&collector : m_mesh_collectors)
{
m_meshes.push_back(collector.second.makeMesh(glm::uint(m_material_filter[collector.second.materialID()])));
m_meshes.push_back(collector.second->makeMesh(glm::uint(m_material_filter[collector.second->materialID()])));
}
}
......
......@@ -67,7 +67,7 @@ namespace glare
return unsigned(m_meshes.size());
}
const std::map<size_t, LocalCollector> &meshCollectors() const
const std::map<size_t, std::unique_ptr<LocalCollector>> &meshCollectors() const
{
return m_mesh_collectors;
}
......@@ -88,7 +88,7 @@ namespace glare
std::shared_ptr<core::Buffer<gl::BufferType::eShaderStorage>> m_light_buffer;
std::shared_ptr<core::GraphNode> m_scene_root;
std::map<size_t, LocalCollector> m_mesh_collectors; //!< mesh renderer id to mesh collector
std::map<size_t, std::unique_ptr<LocalCollector>> m_mesh_collectors; //!< mesh renderer id to mesh collector
std::map<size_t, size_t> m_material_filter;
unsigned m_active_camera = 0;
......
......@@ -77,8 +77,8 @@ namespace glare
unsigned mesh = 0;
for (auto &&pair : raytracer.collector()->meshCollectors()) {
m_generator_shader_gbuffer->updateUniformUInt("u_mesh_id", mesh++);
m_generator_shader_gbuffer->updateUniformMatrix("u_mvp", core::EngineState::main_camera->getViewProjection() * pair.second.m_transform);
m_vertex_array->draw(gl::PrimitiveType::ePoints, pair.second.triangles().size());
m_generator_shader_gbuffer->updateUniformMatrix("u_mvp", core::EngineState::main_camera->getViewProjection() * pair.second->m_transform);
m_vertex_array->draw(gl::PrimitiveType::ePoints, pair.second->triangles().size());
}
gl::memoryBarrier(gl::MemoryBarrierBit::eAll);
......
......@@ -238,6 +238,11 @@ namespace glare
return 0;
}
void Bounds::print(std::ostream &stream) const
{
stream << "{ min: { " << min.x << ", " << min.y << ", " << min.z << " }, max: { " << max.x << ", " << max.y << ", " << max.z << " } }";
}
UniformBoundsSubdivision::UniformBoundsSubdivision(Bounds bounds, int max_subdivisions)
{
int largest_axis = bounds.largest();
......
......@@ -37,6 +37,13 @@ inline typename std::enable_if<std::is_enum<Enum>::value, Enum>::type operator ~
return Enum(~static_cast<std::underlying_type_t<Enum>>(lhs));
}
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}
namespace glare
{
namespace math
......@@ -238,6 +245,8 @@ namespace glare
float surface() const;
int largest() const;
void print(std::ostream &stream) const;
};
struct UniformBoundsSubdivision
......
......@@ -307,7 +307,20 @@ namespace glare
auto &&mesh_mat_vec = data->mesh_material_symbols[url.substr(1, url.size() - 1)];
auto bind_mat_node_tc = sub->getFirstChildOfTagTitle("bind_material")->getFirstChildOfTagTitle("technique_common");
auto bind_mat = sub->getFirstChildOfTagTitle("bind_material");
if (!bind_mat) {
for (auto &&mesh_mat : mesh_mat_vec)
{
auto mesh_spt = mesh_mat.mesh;
std::shared_ptr<core::GraphNode> mesh_node = std::make_shared<core::GraphNode>(sub->tag->values["url"]);
mesh_node->addComponent(std::make_shared<core::MeshRenderer>(mesh_spt, data->materials["qeng_coll_default_material"]));
root->attach(mesh_node);
}
continue;
}
auto bind_mat_node_tc = bind_mat->getFirstChildOfTagTitle("technique_common");
for (auto &&mesh_mat : mesh_mat_vec)
{
......@@ -630,7 +643,14 @@ namespace glare
void ColladaLoader::decodeMaterialsNode(std::shared_ptr<TagTreeNode> mat_node) const
{
//Add a default material.
data->materials.emplace("qeng_coll_default_material", std::make_shared<core::Material>("qeng_coll_default_material"));
auto default_material = std::make_shared<core::Material>("qeng_coll_default_material");
default_material->color_diffuse = Colors::White.rgb;
default_material->ior = 1.0;
default_material->specular_exponent = 1;
data->materials.emplace("qeng_coll_default_material", default_material);
if (!mat_node)
return;
for (auto &&mat_sub : mat_node->children)
{
......@@ -667,6 +687,8 @@ namespace glare
void ColladaLoader::decodeMaterialEffectsNode(std::shared_ptr<TagTreeNode> mat_effects_node) const