Browse Source

Planet WIP.

master
Draklaw 4 years ago
parent
commit
33531a6eec
  1. 1
      CMakeLists.txt
  2. 150
      src/Planet.cpp
  3. 78
      src/Planet.h
  4. 60
      src/VulkanTutorial.cpp
  5. 9
      src/VulkanTutorial.h

1
CMakeLists.txt

@ -35,6 +35,7 @@ add_executable(vk_expe
src/main.cpp
src/utils.cpp
src/Logger.cpp
src/Planet.cpp
src/VkExpe.cpp
src/VulkanTutorial.cpp
)

150
src/Planet.cpp

@ -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

@ -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];
};

60
src/VulkanTutorial.cpp

@ -2,6 +2,7 @@
#include <utils.h>
#include <Logger.h>
#include <Planet.h>
#include <SDL2/SDL_vulkan.h>
@ -15,7 +16,7 @@
#include <cstring>
VkVertexInputBindingDescription Vertex::binding_description() {
VkVertexInputBindingDescription vertex_binding_description() {
return {
.binding = 0,
.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 {
VkVertexInputAttributeDescription {
.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}, {0.0f, 1.0f, 0.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}},
};
const std::vector<uint16_t> indices = {
std::vector<uint32_t> indices = {
0, 1, 2,
2, 1, 3,
@ -84,6 +85,50 @@ VulkanTutorial::VulkanTutorial() {
std::bind(&VulkanTutorial::create_swapchain_objects, this, std::placeholders::_1));
m_swapchain.register_destruction_callback(
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() {
@ -375,9 +420,9 @@ void VulkanTutorial::create_graphic_pipeline() {
};
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 {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
@ -420,6 +465,7 @@ void VulkanTutorial::create_graphic_pipeline() {
.depthClampEnable = VK_FALSE,
.rasterizerDiscardEnable = VK_FALSE,
.polygonMode = VK_POLYGON_MODE_FILL,
// .cullMode = VK_CULL_MODE_NONE,
.cullMode = VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_CLOCKWISE,
.depthBiasEnable = VK_FALSE,
@ -778,7 +824,7 @@ void VulkanTutorial::create_command_buffers() {
command_buffer,
m_index_buffer,
0,
VK_INDEX_TYPE_UINT16
VK_INDEX_TYPE_UINT32
);
vkCmdDrawIndexed(

9
src/VulkanTutorial.h

@ -10,13 +10,8 @@
#include <chrono>
struct Vertex {
Eigen::Vector3f position;
Eigen::Vector3f color;
static VkVertexInputBindingDescription binding_description();
static std::array<VkVertexInputAttributeDescription, 2> attributes_description();
};
VkVertexInputBindingDescription vertex_binding_description();
std::array<VkVertexInputAttributeDescription, 2> vertex_attributes_description();
class VulkanTutorial {

Loading…
Cancel
Save