Planet WIP.
This commit is contained in:
@@ -35,6 +35,7 @@ add_executable(vk_expe
|
|||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/utils.cpp
|
src/utils.cpp
|
||||||
src/Logger.cpp
|
src/Logger.cpp
|
||||||
|
src/Planet.cpp
|
||||||
src/VkExpe.cpp
|
src/VkExpe.cpp
|
||||||
src/VulkanTutorial.cpp
|
src/VulkanTutorial.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
150
src/Planet.cpp
Normal file
150
src/Planet.cpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
|
||||||
|
#include <Planet.h>
|
||||||
|
#include <Logger.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 lerp(Real factor, const Vector3& v0, const Vector3& v1) {
|
||||||
|
return (Real(1) - factor) * v0 + factor * v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Cell::Cell(
|
||||||
|
const Vector3& corner00,
|
||||||
|
const Vector3& corner01,
|
||||||
|
const Vector3& corner10,
|
||||||
|
const Vector3& corner11
|
||||||
|
)
|
||||||
|
: m_corners{ corner00, corner01, corner10, corner11 }
|
||||||
|
, m_heightFactor(heightFactor(m_corners))
|
||||||
|
, m_cells{ nullptr, nullptr, nullptr, nullptr }
|
||||||
|
{}
|
||||||
|
|
||||||
|
Cell& Cell::cell(uint32_t cellIndex) {
|
||||||
|
assert(cellIndex < CellCount);
|
||||||
|
auto& cell = m_cells[cellIndex];
|
||||||
|
if(!cell)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
return *cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cell::writeMesh(
|
||||||
|
Vertex*& vertices, const Vertex* verticesEnd,
|
||||||
|
uint32_t*& indices, const uint32_t* indicesEnd,
|
||||||
|
uint32_t subdivCount
|
||||||
|
) const {
|
||||||
|
auto const sideEdgeCount = (1u << subdivCount);
|
||||||
|
auto const sideVertCount = sideEdgeCount + 1;
|
||||||
|
|
||||||
|
auto const quadCount = sideEdgeCount * sideEdgeCount;
|
||||||
|
auto const triCount = 2 * quadCount;
|
||||||
|
auto const vertCount = sideVertCount * sideVertCount;
|
||||||
|
|
||||||
|
assert(vertices + vertCount <= verticesEnd);
|
||||||
|
assert(indices + (3 * triCount) <= indicesEnd);
|
||||||
|
|
||||||
|
auto const index = [sideVertCount](uint32_t x, uint32_t y) -> uint32_t {
|
||||||
|
return x + y * sideVertCount;
|
||||||
|
};
|
||||||
|
auto const vertex = [vertices, &index](uint32_t x, uint32_t y) -> Vertex& {
|
||||||
|
return vertices[index(x, y)];
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 c00(0.0f, 0.0f, 1.0f);
|
||||||
|
Vector3 c01(1.0f, 0.0f, 1.0f);
|
||||||
|
Vector3 c10(0.0f, 1.0f, 1.0f);
|
||||||
|
Vector3 c11(1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
auto const color = [&c00, &c01, &c10, &c11, sideEdgeCount](uint32_t x, uint32_t y) -> Vector3 {
|
||||||
|
const auto c0 = lerp(Real(x) / Real(sideEdgeCount), c00, c01);
|
||||||
|
const auto c1 = lerp(Real(x) / Real(sideEdgeCount), c10, c11);
|
||||||
|
return lerp(Real(y) / Real(sideEdgeCount), c0, c1);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto const setVertex = [&vertex, &color](uint32_t x, uint32_t y, const Vector3& pos) {
|
||||||
|
vertex(x, y) = Vertex {
|
||||||
|
pos,
|
||||||
|
color(x, y)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
setVertex( 0, 0, m_corners[0]);
|
||||||
|
setVertex(sideEdgeCount, 0, m_corners[1]);
|
||||||
|
setVertex( 0, sideEdgeCount, m_corners[2]);
|
||||||
|
setVertex(sideEdgeCount, sideEdgeCount, m_corners[3]);
|
||||||
|
|
||||||
|
struct QuadCell {
|
||||||
|
uint32_t x0, x1, y0, y1;
|
||||||
|
};
|
||||||
|
std::vector<QuadCell> stack;
|
||||||
|
stack.reserve(quadCount / 4);
|
||||||
|
if(subdivCount > 0) {
|
||||||
|
stack.emplace_back(QuadCell {
|
||||||
|
0, sideEdgeCount,
|
||||||
|
0, sideEdgeCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!stack.empty()) {
|
||||||
|
const auto quadCell = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
|
||||||
|
auto const mx = (quadCell.x0 + quadCell.x1) / 2;
|
||||||
|
auto const my = (quadCell.y0 + quadCell.y1) / 2;
|
||||||
|
|
||||||
|
auto const& v00 = vertex(quadCell.x0, quadCell.y0).position;
|
||||||
|
auto const& v01 = vertex(quadCell.x1, quadCell.y0).position;
|
||||||
|
auto const& v10 = vertex(quadCell.x0, quadCell.y1).position;
|
||||||
|
auto const& v11 = vertex(quadCell.x1, quadCell.y1).position;
|
||||||
|
|
||||||
|
setVertex( mx, quadCell.y0,
|
||||||
|
(v00 + v01).normalized()
|
||||||
|
);
|
||||||
|
setVertex(quadCell.x0, my,
|
||||||
|
(v00 + v10).normalized()
|
||||||
|
);
|
||||||
|
setVertex(mx, my,
|
||||||
|
(v00 + v01 + v10 + v11).normalized()
|
||||||
|
);
|
||||||
|
setVertex(quadCell.x1, my,
|
||||||
|
(v01 + v11).normalized()
|
||||||
|
);
|
||||||
|
setVertex( mx, quadCell.y1,
|
||||||
|
(v10 + v11).normalized()
|
||||||
|
);
|
||||||
|
|
||||||
|
if(quadCell.x0 + 1 < mx) {
|
||||||
|
stack.emplace_back(QuadCell { mx, quadCell.x1, my, quadCell.y1 });
|
||||||
|
stack.emplace_back(QuadCell { quadCell.x0, mx, my, quadCell.y1 });
|
||||||
|
stack.emplace_back(QuadCell { mx, quadCell.x1, quadCell.y0, my });
|
||||||
|
stack.emplace_back(QuadCell { quadCell.x0, mx, quadCell.y0, my });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vertices += vertCount;
|
||||||
|
|
||||||
|
for(uint32_t y = 0; y < sideEdgeCount; y += 1) {
|
||||||
|
for(uint32_t x = 0; x < sideEdgeCount; x += 1) {
|
||||||
|
const auto i00 = index(x, y);
|
||||||
|
const auto i01 = i00 + 1;
|
||||||
|
const auto i10 = i00 + sideVertCount;
|
||||||
|
const auto i11 = i10 + 1;
|
||||||
|
|
||||||
|
*(indices++) = i00;
|
||||||
|
*(indices++) = i01;
|
||||||
|
*(indices++) = i10;
|
||||||
|
|
||||||
|
*(indices++) = i10;
|
||||||
|
*(indices++) = i01;
|
||||||
|
*(indices++) = i11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Real Cell::heightFactor(Vector3 corners[CornerCount]) {
|
||||||
|
Vector3 c = (corners[0] + corners[1] + corners[2] + corners[3]).normalized();
|
||||||
|
return Real(1) / corners[0].dot(c);
|
||||||
|
}
|
||||||
78
src/Planet.h
Normal file
78
src/Planet.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Dense>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
using Real = float;
|
||||||
|
using Vector3 = Eigen::Matrix<Real, 3, 1>;
|
||||||
|
|
||||||
|
class Cell;
|
||||||
|
using CellUP = std::unique_ptr<Cell>;
|
||||||
|
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 lerp(Real factor, const Vector3& v0, const Vector3& v1);
|
||||||
|
|
||||||
|
|
||||||
|
class Cell {
|
||||||
|
public:
|
||||||
|
static constexpr uint32_t CornerCount = 4;
|
||||||
|
static constexpr uint32_t CellCount = 4;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Cell(
|
||||||
|
const Vector3& corner00,
|
||||||
|
const Vector3& corner01,
|
||||||
|
const Vector3& corner10,
|
||||||
|
const Vector3& corner11
|
||||||
|
);
|
||||||
|
Cell(const Cell&) = delete;
|
||||||
|
Cell(Cell&&) = default;
|
||||||
|
~Cell() = default;
|
||||||
|
|
||||||
|
Cell& operator=(const Cell&) = delete;
|
||||||
|
Cell& operator=(Cell&&) = default;
|
||||||
|
|
||||||
|
Cell& cell(uint32_t cellIndex);
|
||||||
|
|
||||||
|
void writeMesh(
|
||||||
|
Vertex*& vertices, const Vertex* verticesEnd,
|
||||||
|
uint32_t*& indices, const uint32_t* indicesEnd,
|
||||||
|
uint32_t subdivCount = 4
|
||||||
|
) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Real heightFactor(Vector3 corners[CornerCount]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector3 m_corners[CornerCount];
|
||||||
|
Real m_heightFactor;
|
||||||
|
CellUP m_cells[CellCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Planet {
|
||||||
|
public:
|
||||||
|
static constexpr uint32_t CellCount = 6;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Planet();
|
||||||
|
Planet(const Planet&) = delete;
|
||||||
|
Planet(Planet&&) = default;
|
||||||
|
~Planet() = default;
|
||||||
|
|
||||||
|
Planet& operator=(const Planet&) = delete;
|
||||||
|
Planet& operator=(Planet&&) = default;
|
||||||
|
|
||||||
|
Cell& cell(uint32_t cellIndex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CellUP m_cells[CellCount];
|
||||||
|
};
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
#include <Logger.h>
|
#include <Logger.h>
|
||||||
|
#include <Planet.h>
|
||||||
|
|
||||||
#include <SDL2/SDL_vulkan.h>
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
VkVertexInputBindingDescription Vertex::binding_description() {
|
VkVertexInputBindingDescription vertex_binding_description() {
|
||||||
return {
|
return {
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.stride = sizeof(Vertex),
|
.stride = sizeof(Vertex),
|
||||||
@@ -23,7 +24,7 @@ VkVertexInputBindingDescription Vertex::binding_description() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<VkVertexInputAttributeDescription, 2> Vertex::attributes_description() {
|
std::array<VkVertexInputAttributeDescription, 2> vertex_attributes_description() {
|
||||||
return {
|
return {
|
||||||
VkVertexInputAttributeDescription {
|
VkVertexInputAttributeDescription {
|
||||||
.location = 0,
|
.location = 0,
|
||||||
@@ -41,7 +42,7 @@ std::array<VkVertexInputAttributeDescription, 2> Vertex::attributes_description(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector<Vertex> vertices = {
|
std::vector<Vertex> vertices = {
|
||||||
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
|
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
|
||||||
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
|
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
|
||||||
{{-0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}},
|
{{-0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}},
|
||||||
@@ -53,7 +54,7 @@ const std::vector<Vertex> vertices = {
|
|||||||
{{0.5f, 0.5f, 0.5f}, {0.2f, 0.2f, 0.2f}},
|
{{0.5f, 0.5f, 0.5f}, {0.2f, 0.2f, 0.2f}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<uint16_t> indices = {
|
std::vector<uint32_t> indices = {
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
2, 1, 3,
|
2, 1, 3,
|
||||||
|
|
||||||
@@ -84,6 +85,50 @@ VulkanTutorial::VulkanTutorial() {
|
|||||||
std::bind(&VulkanTutorial::create_swapchain_objects, this, std::placeholders::_1));
|
std::bind(&VulkanTutorial::create_swapchain_objects, this, std::placeholders::_1));
|
||||||
m_swapchain.register_destruction_callback(
|
m_swapchain.register_destruction_callback(
|
||||||
std::bind(&VulkanTutorial::destroy_swapchain_objects, this));
|
std::bind(&VulkanTutorial::destroy_swapchain_objects, this));
|
||||||
|
|
||||||
|
auto const subdivCount = 2;
|
||||||
|
auto const sideEdgeCount = (1u << subdivCount);
|
||||||
|
auto const sideVertCount = sideEdgeCount + 1;
|
||||||
|
auto const quadCount = sideEdgeCount * sideEdgeCount;
|
||||||
|
auto const indexCount = 6 * quadCount;
|
||||||
|
auto const vertCount = sideVertCount * sideVertCount;
|
||||||
|
|
||||||
|
vertices.assign(vertCount, Vertex{
|
||||||
|
Vector3::Constant(std::numeric_limits<Real>::quiet_NaN()),
|
||||||
|
Vector3::Zero()
|
||||||
|
});
|
||||||
|
indices.assign(indexCount, UINT32_MAX);
|
||||||
|
|
||||||
|
Cell cell(
|
||||||
|
Vector3(-1.0f, -1.0f, 1.0f).normalized(),
|
||||||
|
Vector3( 1.0f, -1.0f, 1.0f).normalized(),
|
||||||
|
Vector3(-1.0f, -1.0f, -1.0f).normalized(),
|
||||||
|
Vector3( 1.0f, -1.0f, -1.0f).normalized()
|
||||||
|
);
|
||||||
|
|
||||||
|
auto vertex = &*vertices.begin();
|
||||||
|
const auto verticesEnd = &*vertices.end();
|
||||||
|
auto index = &*indices.begin();
|
||||||
|
const auto indicesEnd = &*indices.end();
|
||||||
|
cell.writeMesh(
|
||||||
|
vertex, verticesEnd,
|
||||||
|
index, indicesEnd,
|
||||||
|
subdivCount
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info() << "Vertices:";
|
||||||
|
for(auto v = &*vertices.begin(); v < vertex; v += 1)
|
||||||
|
logger.debug() << (v - &*vertices.begin()) << ": "
|
||||||
|
<< v->position.transpose() << " - "
|
||||||
|
<< v->color.transpose();
|
||||||
|
|
||||||
|
logger.info() << "Indices:";
|
||||||
|
for(auto i = &*indices.begin(); i < index; i += 6)
|
||||||
|
logger.debug() << (i - &*indices.begin()) << ": "
|
||||||
|
<< i[0] << ", " << i[1] << ", " << i[2] << " - "
|
||||||
|
<< i[3] << ", " << i[4] << ", " << i[5];
|
||||||
|
|
||||||
|
// abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanTutorial::~VulkanTutorial() {
|
VulkanTutorial::~VulkanTutorial() {
|
||||||
@@ -375,9 +420,9 @@ void VulkanTutorial::create_graphic_pipeline() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const VkVertexInputBindingDescription vertex_bindings[] = {
|
const VkVertexInputBindingDescription vertex_bindings[] = {
|
||||||
Vertex::binding_description(),
|
vertex_binding_description(),
|
||||||
};
|
};
|
||||||
const auto vertex_attributes = Vertex::attributes_description();
|
const auto vertex_attributes = vertex_attributes_description();
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertex_info {
|
VkPipelineVertexInputStateCreateInfo vertex_info {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
@@ -420,6 +465,7 @@ void VulkanTutorial::create_graphic_pipeline() {
|
|||||||
.depthClampEnable = VK_FALSE,
|
.depthClampEnable = VK_FALSE,
|
||||||
.rasterizerDiscardEnable = VK_FALSE,
|
.rasterizerDiscardEnable = VK_FALSE,
|
||||||
.polygonMode = VK_POLYGON_MODE_FILL,
|
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||||
|
// .cullMode = VK_CULL_MODE_NONE,
|
||||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||||
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
||||||
.depthBiasEnable = VK_FALSE,
|
.depthBiasEnable = VK_FALSE,
|
||||||
@@ -778,7 +824,7 @@ void VulkanTutorial::create_command_buffers() {
|
|||||||
command_buffer,
|
command_buffer,
|
||||||
m_index_buffer,
|
m_index_buffer,
|
||||||
0,
|
0,
|
||||||
VK_INDEX_TYPE_UINT16
|
VK_INDEX_TYPE_UINT32
|
||||||
);
|
);
|
||||||
|
|
||||||
vkCmdDrawIndexed(
|
vkCmdDrawIndexed(
|
||||||
|
|||||||
@@ -10,13 +10,8 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
struct Vertex {
|
VkVertexInputBindingDescription vertex_binding_description();
|
||||||
Eigen::Vector3f position;
|
std::array<VkVertexInputAttributeDescription, 2> vertex_attributes_description();
|
||||||
Eigen::Vector3f color;
|
|
||||||
|
|
||||||
static VkVertexInputBindingDescription binding_description();
|
|
||||||
static std::array<VkVertexInputAttributeDescription, 2> attributes_description();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class VulkanTutorial {
|
class VulkanTutorial {
|
||||||
|
|||||||
Reference in New Issue
Block a user