Commit 2f449113 authored by Johannes Braun's avatar Johannes Braun
Browse files

Cleaned up a little bit of mess in LS c++ files

parent 62514c17
......@@ -14,7 +14,6 @@ namespace glare
void GraphNode::gui()
{
ImGui::Begin("Scene");
auto cached_indent = ImGui::GetStyle().IndentSpacing;
ImGui::GetStyle().IndentSpacing = 10;
ImGui::PushID(("Node::" + m_name).c_str());
......@@ -85,8 +84,6 @@ namespace glare
}
ImGui::PopID();
ImGui::GetStyle().IndentSpacing = cached_indent;
ImGui::End();
}
void GraphNode::update(const glm::mat4 &parent_transform)
......
......@@ -126,7 +126,9 @@ namespace glare
animation_manager->update();
if (graph_root)
{
ImGui::Begin("Scene");
graph_root->gui();
ImGui::End();
graph_root->update();
}
}
......
......@@ -14,15 +14,12 @@ namespace glare
{
namespace raytrace
{
std::unique_ptr<core::Program> AngularLinespace::m_construction_shader;
AngularLinespace::AngularLinespace()
{
}
AngularLinespace::AngularLinespace(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Platform generator)
AngularLinespace::AngularLinespace(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, const Platform generator)
: AngularLinespace()
{
generate(collector, box_subdivisions, radial_subdivisions, generator);
......@@ -38,8 +35,7 @@ namespace glare
const int max_subdivisions = linespace_tag.find_child_by_attribute("item", "name", "subdivisions").attribute("value").as_int(16);
const int radial_subdivisions = linespace_tag.find_child_by_attribute("item", "name", "radial-subdivision").attribute("value").as_int(16);
const std::string gen = linespace_tag.find_child_by_attribute("item", "name", "generator").attribute("value").as_string("cpu");
Platform generator = gen == "gpu" ? Platform::eGPU : Platform::eCPU;
const Platform generator = gen == "gpu" ? Platform::eGPU : Platform::eCPU;
generate(collector, max_subdivisions, radial_subdivisions, generator);
}
......@@ -49,7 +45,7 @@ namespace glare
int i = 0;
};
void AngularLinespace::generate(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Platform generator)
void AngularLinespace::generate(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, const Platform generator)
{
core::ClockMS clock;
......@@ -57,14 +53,8 @@ namespace glare
m_subdivision = m_bounds.subdivide(box_subdivisions);
m_radial_subdivisions = radial_subdivisions;
m_lines_per_patch = linesPerPatch();
m_generator = generator;
m_num_lines = unsigned(calculateLineCount());
const size_t memory = sizeof(AngleLine) * m_num_lines;
m_lines.resize(m_num_lines, AngleLine{ -1 });
switch (m_generator)
switch (generator)
{
default:
case Platform::eCPU:
......@@ -75,8 +65,11 @@ namespace glare
break;
}
const size_t num_lines = unsigned(lineCount());
const size_t memory = sizeof(AngleLine) * num_lines;
Log_Info << "[Linespace Data] Generation Time: " << clock.time() << "ms";
Log_Info << "[Linespace Data] Lines: " << m_num_lines;
Log_Info << "[Linespace Data] Lines: " << num_lines;
Log_Info << "[Linespace Data] Memory: " << memory << " Bytes";
Log_Info << "[Linespace Data] Patch Subdivisions: " << m_subdivision.resolution.x << ", " << m_subdivision.resolution.y << ", " << m_subdivision.resolution.z;
Log_Info << "[Linespace Data] Patch Size: " << m_subdivision.size;
......@@ -86,10 +79,12 @@ namespace glare
void AngularLinespace::generateCPU(const LocalCollector &collector)
{
std::vector<AngleLine> lines(lineCount(), AngleLine{ -1 });
const LocalBVH &line_bvh = collector.bvh();
for (Face face = Face::ePosX; unsigned(face) <= unsigned(Face::eNegZ); face = Face(unsigned(face) + 1))
{
const unsigned patches = m_subdivision.resolution[face_width_axises[unsigned(face) % 3]] * m_subdivision.resolution[face_height_axises[unsigned(face) % 3]];
const size_t patches = patchCount(face);
const size_t count_and_radial = patches * m_lines_per_patch;
Log_Info << "Computing for face " << unsigned(face) << ": " << patches << " patches, " << m_lines_per_patch << " lines per patch and " << count_and_radial << " lines in total.";
......@@ -107,7 +102,7 @@ namespace glare
patch.index_horizontal = id % width;
patch.index_vertical = id / width;
glm::vec3 direction = hemisphere::direction_from_id(radial_id, m_radial_subdivisions, axis, face_width_axises[axis], face_height_axises[axis], unsigned(face) <= 2);
const glm::vec3 direction = hemisphere::direction_from_id(radial_id, m_radial_subdivisions, axis, face_width_axises[axis], face_height_axises[axis], unsigned(face) <= 2);
Ray test_ray;
test_ray.origin = patchCenter(patch);
......@@ -115,64 +110,56 @@ namespace glare
test_ray.origin -= 1e2 * direction;
Hit nearest;
nearest.triangle = -1;
line_bvh.nearestIntersection(test_ray, nearest);
uint32_t index = offset(patch) + radial_id;
m_lines[index].triangle = (nearest.barycentric.x != -1) ? int(nearest.triangle) : -1;
lines[offsetOf(patch) + radial_id].triangle = nearest ? int(nearest.triangle) : -1;
}
}
m_line_buffer.upload(m_lines, gl::BufferUsage::eStaticDraw);
m_line_buffer.upload(lines, gl::BufferUsage::eStaticDraw);
m_line_buffer.makeResident(gl::Access::eReadOnly);
}
void AngularLinespace::generateGPU(const LocalCollector &collector)
{
if (!m_construction_shader)
{
Log_Info << "Compiling construction shader...";
Log_Warn << "Caution: This will influence the construction time by a lot, so don't rely on the next time measurement for performance purposes.";
core::ClockMS compile_timer;
m_construction_shader = std::make_unique<core::Program>(files::shader("/raytracer/linespace_build/angular_linespace_generate.comp"));
Log_Warn << "Compilation took " << compile_timer.time() << "ms";
}
m_line_buffer.reserve<Line>(calculateLineCount(), gl::BufferUsage::eDynamicDraw);
const static std::unique_ptr<core::Program> construction_shader = std::make_unique<core::Program>(files::shader("/raytracer/linespace_build/angular_linespace_generate.comp"));
m_line_buffer.reserve<Line>(lineCount(), gl::BufferUsage::eDynamicDraw);
m_line_buffer.makeResident(gl::Access::eReadWrite);
//An offset length with which the generator ray will be offset backwards to assure intersecting all possible faces.
const float ray_bias = 1e-2f;
construction_shader->uniform("ray_bias", ray_bias);
construction_shader->uniform("u_bounds.min", m_bounds.min);
construction_shader->uniform("u_bounds.max", m_bounds.max);
construction_shader->uniform("u_subdivisions", m_subdivision.resolution);
construction_shader->uniform("u_subdivisions_size", m_subdivision.size);
construction_shader->uniform("u_lines_per_patch", unsigned(m_lines_per_patch));
construction_shader->uniform("u_radial_subdivision", unsigned(m_radial_subdivisions));
construction_shader->storageBuffer("line_buffer", m_line_buffer);
for (Face face = Face::ePosX; unsigned(face) <= unsigned(Face::eNegZ); face = Face(unsigned(face) + 1))
{
const unsigned patches = m_subdivision.resolution[face_width_axises[unsigned(face) % 3]] * m_subdivision.resolution[face_height_axises[unsigned(face) % 3]];
const size_t patches = patchCount(face);
const size_t count_and_radial = patches * m_lines_per_patch;
Log_Info << "Computing for face " << unsigned(face) << ": " << patches << " patches, " << m_lines_per_patch << " lines per patch and " << count_and_radial << " lines in total.";
//An offset length with which the generator ray will be offset backwards to assure intersecting all possible faces.
const float ray_bias = 1e-2f;
m_construction_shader->use();
m_construction_shader->uniform("u_face", unsigned(face));
m_construction_shader->uniform("u_lines_per_patch", unsigned(m_lines_per_patch));
m_construction_shader->uniform("u_radial_subdivision", unsigned(m_radial_subdivisions));
m_construction_shader->uniform("ray_bias", ray_bias);
m_construction_shader->uniform("u_bounds.min", m_bounds.min);
m_construction_shader->uniform("u_bounds.max", m_bounds.max);
m_construction_shader->uniform("u_subdivisions", m_subdivision.resolution);
m_construction_shader->uniform("u_subdivisions_size", m_subdivision.size);
m_construction_shader->storageBuffer("line_buffer", m_line_buffer);
construction_shader->use();
construction_shader->uniform("u_face", unsigned(face));
auto mesh = collector.makeMesh(0);
m_construction_shader->uniform("u_mesh.triangles", mesh.triangle_buffer_ptr);
m_construction_shader->uniform("u_mesh.id", mesh.id);
m_construction_shader->uniform("u_mesh.vertices", mesh.vertex_buffer_ptr);
m_construction_shader->uniform("u_mesh.nodes", mesh.datastructure_buffer_ptr);
construction_shader->uniform("u_mesh.triangles", mesh.triangle_buffer_ptr);
construction_shader->uniform("u_mesh.id", mesh.id);
construction_shader->uniform("u_mesh.vertices", mesh.vertex_buffer_ptr);
construction_shader->uniform("u_mesh.nodes", mesh.datastructure_buffer_ptr);
m_construction_shader->dispatch1d(unsigned(count_and_radial), 1024);
construction_shader->dispatch1d(unsigned(count_and_radial), 1024);
}
}
uint32_t AngularLinespace::offset(const SurfacePatch &patch)
uint32_t AngularLinespace::offsetOf(const SurfacePatch &patch)
{
//const unsigned n = unsigned(glm::max(0, int(patch.face)-1));
// patch offset at face 0 is 0
......@@ -180,12 +167,11 @@ namespace glare
// patch offset at face 2 is (x+z)*y
// patch offsets larger than that have x*y + y*z + x*z added
unsigned patch_offset;
const unsigned count_x = m_subdivision.resolution[face_width_axises[0]] * m_subdivision.resolution[face_height_axises[0]];
const unsigned count_y = m_subdivision.resolution[face_width_axises[1]] * m_subdivision.resolution[face_height_axises[1]];
const unsigned count_z = m_subdivision.resolution[face_width_axises[2]] * m_subdivision.resolution[face_height_axises[2]];
const unsigned count_x = unsigned(patchCount(Face::ePosX));
const unsigned count_y = unsigned(patchCount(Face::ePosY));
const unsigned count_z = unsigned(patchCount(Face::ePosZ));
unsigned patch_offset;
//A switch is actually very performant for this purpose, did't find a faster solution.
switch (patch.face)
{
......@@ -202,6 +188,11 @@ namespace glare
return uint32_t(patch_offset * m_lines_per_patch + patch_sub_offset * m_lines_per_patch);
}
size_t AngularLinespace::patchCount(Face face) const
{
return m_subdivision.resolution[face_width_axises[unsigned(face) % 3]] * m_subdivision.resolution[face_height_axises[unsigned(face) % 3]];
}
size_t AngularLinespace::linesPerPatch() const
{
return 4 * m_radial_subdivisions * (m_radial_subdivisions - 1) + 1;
......@@ -209,15 +200,14 @@ namespace glare
glm::vec3 AngularLinespace::patchCenter(const SurfacePatch &patch)
{
unsigned face_index = unsigned(patch.face);
unsigned max_factor = 1 - (face_index / 3); // 1 for pos plane, 0 for neg plane
const unsigned face_index = unsigned(patch.face);
glm::vec3 position;
position[face_index % 3] = m_bounds.min[face_index % 3] + max_factor*m_bounds.size()[face_index % 3];
// (1 - (face_index / 3)) is 1 for positive planes, 0 for negative
position[face_index % 3] = m_bounds.min[face_index % 3] + (1 - (face_index / 3))*m_bounds.size()[face_index % 3];
unsigned axis_width = face_width_axises[face_index % 3];
unsigned axis_height = face_height_axises[face_index % 3];
const unsigned axis_width = face_width_axises[face_index % 3];
const unsigned axis_height = face_height_axises[face_index % 3];
if (patch.face < Face::eNegX) {
position[axis_width] = m_bounds.min[axis_width] + patch.index_horizontal * m_subdivision.size + m_subdivision.size / 2;
......@@ -231,12 +221,10 @@ namespace glare
return position;
}
size_t AngularLinespace::calculateLineCount() const
size_t AngularLinespace::lineCount() const
{
// Number of start faces times the number of sample rays
return 2 * (m_subdivision.resolution.x * m_subdivision.resolution.y +
m_subdivision.resolution.x * m_subdivision.resolution.z +
m_subdivision.resolution.y * m_subdivision.resolution.z) * linesPerPatch();
return 2 * (patchCount(Face::ePosX) + patchCount(Face::ePosY) + patchCount(Face::ePosZ)) * linesPerPatch();
}
const core::Buffer<gl::BufferType::eShaderStorage> &AngularLinespace::lineBuffer() const
......@@ -256,10 +244,8 @@ namespace glare
data.patch_size = m_subdivision.size;
data.resolution = glm::uvec3(m_subdivision.resolution);
data.lines = m_line_buffer.residentAddress();
data.arb_prop = unsigned(m_radial_subdivisions);
data.line_count = glm::uint(m_num_lines);
data.line_count = glm::uint(lineCount());
return data;
}
......@@ -267,10 +253,5 @@ namespace glare
{
return m_subdivision;
}
unsigned AngularLinespace::lines() const
{
return m_num_lines;
}
}
}
......@@ -24,41 +24,40 @@ namespace glare
class AngularLinespace
{
public:
const glm::uvec3 face_width_axises = { 2, 2, 0 };
const glm::uvec3 face_height_axises = { 1, 0, 1 };
AngularLinespace();
AngularLinespace(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Platform generator = Platform::eCPU);
AngularLinespace(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, const Platform generator = Platform::eCPU);
AngularLinespace(AngularLinespace& other) = default;
AngularLinespace(AngularLinespace&& other) = default;
AngularLinespace& operator=(AngularLinespace& other) = default;
AngularLinespace& operator=(AngularLinespace&& other) = default;
void generate(const LocalCollector &collector, const fs::path &settings_file);
void generate(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Platform generator = Platform::eCPU);
glm::vec3 patchCenter(const SurfacePatch &patch);
size_t calculateLineCount() const;
size_t linesPerPatch() const;
uint32_t offset(const SurfacePatch &patch);
void generate(const LocalCollector &collector, int box_subdivisions, int radial_subdivisions, const Platform generator = Platform::eCPU);
const math::Bounds& bounds() const;
const math::Subdivision& subdivision() const;
unsigned lines() const;
LinespaceData data() const;
const core::Buffer<gl::BufferType::eShaderStorage> &lineBuffer() const;
private:
void generateCPU(const LocalCollector &collector);
void generateGPU(const LocalCollector &collector);
core::Buffer<gl::BufferType::eShaderStorage> m_line_buffer;
static std::unique_ptr<core::Program> m_construction_shader;
size_t lineCount() const;
size_t linesPerPatch() const;
uint32_t offsetOf(const SurfacePatch &patch);
glm::vec3 patchCenter(const SurfacePatch &patch);
size_t patchCount(Face face) const;
core::Buffer<gl::BufferType::eShaderStorage> m_line_buffer;
std::vector<AngleLine> m_lines;
math::Bounds m_bounds;
math::Subdivision m_subdivision;
unsigned m_num_lines;
size_t m_lines_per_patch;
math::Bounds m_bounds;
int m_radial_subdivisions;
Platform m_generator;
};
}
}
......
......@@ -10,19 +10,12 @@ namespace glare
{
namespace raytrace
{
std::unique_ptr<core::Program> Linespace::m_construction_shader;
size_t Linespace::faceRangeIndex(Face in, Face out)
{
return size_t((((-0.5 * unsigned(in)) + 4.5)*unsigned(in)) - 1 + unsigned(out));
}
Linespace::Linespace()
{
}
Linespace::Linespace(const LocalCollector &collector, int max_subdivisions, Platform generator)
Linespace::Linespace(const LocalCollector &collector, int max_subdivisions, const Platform generator)
: Linespace()
{
generate(collector, max_subdivisions, generator);
......@@ -39,44 +32,27 @@ namespace glare
const int max_subdivisions = linespace_tag.find_child_by_attribute("item", "name", "subdivisions").attribute("value").as_int(16);
const std::string gen = linespace_tag.find_child_by_attribute("item", "name", "generator").attribute("value").as_string("cpu");
Platform generator = gen == "gpu" ? Platform::eGPU : Platform::eCPU;
const Platform generator = gen == "gpu" ? Platform::eGPU : Platform::eCPU;
generate(collector, max_subdivisions, generator);
}
void Linespace::generate(const LocalCollector &collector, int max_subdivisions, Platform generator)
void Linespace::generate(const LocalCollector &collector, int max_subdivisions, const Platform generator)
{
m_generator = generator;
if (max_subdivisions <= 0) {
pugi::xml_document doc;
Log_Warn << doc.load_file(files::asset("/preferences/default.xml").c_str()).description();
max_subdivisions = doc.child("settings").find_child_by_attribute("group", "name", "linespace").find_child_by_attribute("item", "name", "subdivisions").attribute("value").as_uint(32);
}
m_bounds = collector.bounds();
m_subdivision = m_bounds.subdivide(max_subdivisions);
m_face_widths = { m_subdivision.resolution.z, m_subdivision.resolution.z, m_subdivision.resolution.x };
m_face_heights = { m_subdivision.resolution.y, m_subdivision.resolution.x, m_subdivision.resolution.y };
Log_Info << "Building Line Space for collector id " << collector.id() << "...";
core::ClockGL::instance().start();
switch (m_generator)
m_bounds = collector.bounds();
m_subdivision = m_bounds.subdivide(max_subdivisions);
switch (generator)
{
default:
case Platform::eCPU:
generateCPU(collector);
break;
case Platform::eGPU:
generateGPU(collector);
break;
case Platform::eCPU: generateCPU(collector); break;
case Platform::eGPU: generateGPU(collector); break;
}
size_t line_count = calculateLineCount();
const size_t line_count = lineCount();
m_line_buffer.makeResident(gl::Access::eReadOnly);
Log_Info << "[Linespace Data] Generation Time: " << core::ClockGL::instance().end()/1000000.f << "ms";
Log_Info << "[Linespace Data] Lines: " << line_count;
Log_Info << "[Linespace Data] Memory: " << (line_count * sizeof(Line)) << " Bytes";
......@@ -87,22 +63,18 @@ namespace glare
void Linespace::generateCPU(const LocalCollector &collector)
{
Line base;
base.nearest = -1;
base.farthest = -1;
m_mesh_id = collector.id();
m_lines.resize(calculateLineCount(), base);
std::vector<Line> lines(lineCount(), Line{ -1, -1 });
const LocalBVH &line_bvh = collector.bvh();
for (int config = 0; config < 15; ++config) {
const Face begin_face = start_end_patches[config].first;
const Face end_face = start_end_patches[config].second;
for (const auto& configuration : configurations) {
const Face begin_face = configuration.first;
const Face end_face = configuration.second;
Log_Info << "Working on lines between Faces " << unsigned(begin_face) << " and " << unsigned(end_face) << "...";
//For readability, I'll add those variables here.
const unsigned begin_count = m_face_widths[unsigned(begin_face) % 3] * m_face_heights[unsigned(begin_face) % 3];
const unsigned end_count = m_face_widths[unsigned(end_face) % 3] * m_face_heights[unsigned(end_face) % 3];
const unsigned begin_count = m_subdivision.resolution[face_width_axises[unsigned(begin_face) % 3]] * m_subdivision.resolution[face_height_axises[unsigned(begin_face) % 3]];
const unsigned end_count = m_subdivision.resolution[face_width_axises[unsigned(end_face) % 3]] * m_subdivision.resolution[face_height_axises[unsigned(end_face) % 3]];
//An offset length with which the generator ray will be offset backwards to assure intersecting all possible faces.
const float ray_bias = 1e-2f;
......@@ -117,11 +89,11 @@ namespace glare
const unsigned begin_id = unsigned(id) / end_count;
const unsigned end_id = unsigned(id) % end_count;
const unsigned begin_width = m_face_widths[unsigned(begin.face) % 3];
const unsigned begin_width = m_subdivision.resolution[face_width_axises[unsigned(begin.face) % 3]];
begin.index_horizontal = begin_id % begin_width;
begin.index_vertical = begin_id / begin_width;
const unsigned end_width = m_face_widths[unsigned(end.face) % 3];
const unsigned end_width = m_subdivision.resolution[face_width_axises[unsigned(end.face) % 3]];
end.index_horizontal = end_id % end_width;
end.index_vertical = end_id / end_width;
......@@ -132,124 +104,103 @@ namespace glare
Ray ray;
ray.direction = glm::normalize(center_end - center_begin).xyz;
ray.origin = center_begin.xyz - ray_bias * ray.direction;
Line &line = m_lines[lineIndex(begin, end)];
line.nearest = -1;
line.farthest = -1;
//Invalidate intersections
Hit nearest;
Hit farthest;
nearest.barycentric = glm::vec2(-1);
farthest.barycentric = glm::vec2(-1);
Hit nearest, farthest;
line_bvh.nearestAndFarthestIntersection(ray, nearest, farthest);
if (nearest.barycentric.x != -1)
{
line.nearest = nearest.triangle;
}
if (farthest.barycentric.x != -1)
{
line.farthest = farthest.triangle;
}
const size_t line_index = lineIndex(begin, end);
if (nearest) lines[line_index].nearest = nearest.triangle;
if (farthest) lines[line_index].farthest = farthest.triangle;
}
}
m_line_buffer.upload(m_lines, gl::BufferUsage::eDynamicRead);
m_line_buffer.upload(lines, gl::BufferUsage::eDynamicRead);
}
void Linespace::generateGPU(const LocalCollector &collector)
{
if (!m_construction_shader)
{
Log_Info << "Compiling construction shader...";
Log_Warn << "Caution: This will influence the construction time by a lot, so don't rely on the next time measurement for performance purposes.";
core::ClockMS compile_timer;
m_construction_shader = std::make_unique<core::Program>(files::shader("/raytracer/linespace_build/linespace_generate.comp"));
Log_Warn << "Compilation took " << compile_timer.time() << "ms";
}
m_construction_shader->use();
// construct once, use it for all further generators.
const static std::unique_ptr<core::Program> construction_shader
= std::make_unique<core::Program>(files::shader("/raytracer/linespace_build/linespace_generate.comp"));
construction_shader->use();
// Reserve the needed buffer memory
m_line_buffer.reserve<Line>(lineCount(), gl::BufferUsage::eDynamicDraw);
m_line_buffer.reserve<Line>(calculateLineCount(), gl::BufferUsage::eDynamicDraw);
//An offset length with which the generator ray will be offset backwards to assure intersecting all possible faces.
const float ray_bias = 1e-2f;
m_construction_shader->uniform("ray_bias", ray_bias);
m_construction_shader->uniform("u_bounds.min", m_bounds.min);
m_construction_shader->uniform("u_bounds.max", m_bounds.max);
m_construction_shader->storageBuffer("line_buffer", m_line_buffer);
m_construction_shader->uniform("u_subdivisions", m_subdivision.resolution);
m_construction_shader->uniform("u_subdivisions_size", m_subdivision.size);
for (int i = 0; i < 15; ++i) {
m_construction_shader->uniform("u_offsets[" + std::to_string(i) + "]", unsigned(m_offsets[i]));
}
construction_shader->uniform("ray_bias", ray_bias);
construction_shader->uniform("u_bounds.min", m_bounds.min);
construction_shader->uniform("u_bounds.max", m_bounds.max);
construction_shader->uniform("u_subdivisions", m_subdivision.resolution);
construction_shader->uniform("u_subdivisions_size", m_subdivision.size);
auto mesh = collector.makeMesh(0);
m_construction_shader->uniform("u_mesh.triangles", mesh.triangle_buffer_ptr);
m_construction_shader->uniform("u_mesh.id", mesh.id);
m_construction_shader->uniform("u_mesh.vertices", mesh.vertex_buffer_ptr);
m_construction_shader->uniform("u_mesh.nodes", mesh.datastructure_buffer_ptr);
const auto mesh = collector.makeMesh(0);
construction_shader->uniform("u_mesh.triangles", mesh.triangle_buffer_ptr);
construction_shader->uniform("u_mesh.id", mesh.id);
construction_shader->uniform("u_mesh.vertices", mesh.vertex_buffer_ptr);
construction_shader->uniform("u_mesh.nodes", mesh.datastructure_buffer_ptr);
for (int config = 0; config < 15; ++config) {
construction_shader->storageBuffer("line_buffer", m_line_buffer);
const Face begin_face = start_end_patches[config].first;
const Face end_face = start_end_patches[config].second;
for (const auto& configuration : configurations) {
const Face begin_face = configuration.first;
const Face end_face = configuration.second;
Log_Debug << "Working on lines between Faces " << unsigned(begin_face) << " and " << unsigned(end_face) << "...";
//For readability, I'll add those variables here.
const unsigned begin_count = m_face_widths[unsigned(begin_face) % 3] * m_face_heights[unsigned(begin_face) % 3];
const unsigned end_count = m_face_widths[unsigned(end_face) % 3] * m_face_heights[unsigned(end_face) % 3];
const unsigned begin_count = unsigned(patchCount(begin_face));
const unsigned end_count = unsigned(patchCount(end_face));
m_construction_shader->uniform("u_begin_face", unsigned(begin_face));
m_construction_shader->uniform("u_end_face", unsigned(end_face));
m_construction_shader->uniform("u_begin_count", unsigned(begin_count));
m_construction_shader->uniform("u_end_count", unsigned(end_count));
construction_shader->uniform("u_begin_face", unsigned(begin_face));
construction_shader->uniform("u_end_face", unsigned(end_face));
construction_shader->uniform("u_begin_count", unsigned(begin_count));
construction_shader->uniform("u_end_count", unsigned(end_count));
m_construction_shader->dispatch1d(begin_count * end_count, 1024);
construction_shader->dispatch1d(begin_count * end_count, 1024);
}
}