Some unidentified vertex or index generation error
This commit is contained in:
parent
a778a406d0
commit
8e2559cf26
@ -28,6 +28,8 @@ file(GLOB SHADER_SOURCE_FILES
|
||||
assets/shaders/*.frag
|
||||
assets/shaders/*.vert
|
||||
assets/shaders/*.geom
|
||||
assets/shaders/*.tese
|
||||
assets/shaders/*.tesc
|
||||
)
|
||||
|
||||
foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES})
|
||||
|
||||
@ -20,7 +20,7 @@ struct Buffer {
|
||||
}
|
||||
template<typename T>
|
||||
inline void upload(const std::vector<T>& data) {
|
||||
upload(reinterpret_cast<uint8_t*>(data.data()), data.size()*sizeof(T));
|
||||
upload(reinterpret_cast<const uint8_t*>(data.data()), data.size()*sizeof(T));
|
||||
}
|
||||
|
||||
operator vk::Buffer& () {
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#include <util/log.hpp>
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders, const vk::Extent2D& extent, const RenderPass& render_pass, vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings, const VertexBuffer& vertex_buffer, enum Type type = Type::GLTF) : dev(dev) {
|
||||
GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders, const vk::Extent2D& extent, const RenderPass& render_pass, vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings, const VertexBuffer& vertex_buffer, enum Type type) : dev(dev) {
|
||||
/* create layout
|
||||
* Eventually add a graphicspipline constructor that allows specification of layouts etc
|
||||
* kinda like how Image::Image has all those versions
|
||||
@ -80,10 +80,21 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& sh
|
||||
.primitiveRestartEnable = vk::False,
|
||||
};
|
||||
|
||||
const vk::PipelineTessellationStateCreateInfo* ptesselation_info = nullptr;
|
||||
|
||||
const auto tess_info = vk::PipelineTessellationStateCreateInfo {
|
||||
/* quads*/
|
||||
.patchControlPoints = 4,
|
||||
};
|
||||
|
||||
if(type == Type::eTERRAIN) {
|
||||
ptesselation_info = &tess_info;
|
||||
}
|
||||
|
||||
const auto raster_info = vk::PipelineRasterizationStateCreateInfo {
|
||||
.depthClampEnable = vk::False,
|
||||
.polygonMode = type == Type::eGLTF? vk::PolygonMode::eFill : vk::PolygonMode::eLine,
|
||||
.cullMode = vk::CullModeFlagBits::eBack,
|
||||
.cullMode = vk::CullModeFlagBits::eNone,
|
||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
||||
.depthBiasEnable = vk::False,
|
||||
.lineWidth = 1.0,
|
||||
@ -154,7 +165,7 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& sh
|
||||
.pStages = shader_info.data(),
|
||||
.pVertexInputState = &vertex_input_info,
|
||||
.pInputAssemblyState = &input_asm_info,
|
||||
.pTessellationState = nullptr,
|
||||
.pTessellationState = ptesselation_info,
|
||||
.pViewportState = &viewport_info,
|
||||
.pRasterizationState = &raster_info,
|
||||
.pMultisampleState = &multisample_info,
|
||||
|
||||
@ -143,6 +143,8 @@ Renderer::Renderer(Window& win) : win(win) {
|
||||
|
||||
const auto features = vk::PhysicalDeviceFeatures{
|
||||
.geometryShader = vk::True,
|
||||
.tessellationShader = vk::True,
|
||||
.fillModeNonSolid = vk::True,
|
||||
};
|
||||
|
||||
auto dev_info = vk::DeviceCreateInfo{
|
||||
@ -182,6 +184,7 @@ Renderer::Renderer(Window& win) : win(win) {
|
||||
|
||||
textures = createResources({
|
||||
"assets/textures/oil.jpg",
|
||||
"assets/textures/heightmap.png",
|
||||
});
|
||||
|
||||
std::vector<Shader> shaders = {
|
||||
@ -209,7 +212,7 @@ Renderer::Renderer(Window& win) : win(win) {
|
||||
|
||||
|
||||
/* create Terrain */
|
||||
terrain = std::make_unique<Terrain>(phys_dev, dev, textures[0]);
|
||||
terrain = std::make_unique<Terrain>(phys_dev, dev, textures[1]);
|
||||
|
||||
std::vector<Shader> terrain_shaders = {
|
||||
{ dev, "assets/shaders/terrain.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
||||
@ -218,7 +221,7 @@ Renderer::Renderer(Window& win) : win(win) {
|
||||
{ dev, "assets/shaders/terrain.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
||||
};
|
||||
|
||||
terrain_pipeline = std::make_unique<GraphicsPipeline>(dev, terrain_shaders, swapchain->extent, *render_pass, bindings, terrain->vertex_buffer, GraphicsPipeline::eTERRAIN);
|
||||
terrain_pipeline = std::make_unique<GraphicsPipeline>(dev, terrain_shaders, swapchain->extent, *render_pass, bindings, *terrain->vertex_buffer, GraphicsPipeline::eTERRAIN);
|
||||
|
||||
for (auto& shader : shaders)
|
||||
shader.cleanup();
|
||||
@ -236,7 +239,7 @@ std::vector<Texture> Renderer::createResources(const std::vector<std::string>& n
|
||||
texture_cmd.begin();
|
||||
|
||||
for (const auto& name : names) {
|
||||
ret.push_back({phys_dev, dev, texture_cmd, name});
|
||||
ret.push_back({phys_dev, dev, texture_cmd, name, false});
|
||||
}
|
||||
|
||||
texture_cmd.end();
|
||||
@ -338,11 +341,13 @@ void Renderer::draw() {
|
||||
uniform_buffer->upload(UniformData {
|
||||
.mvp = p * cam.view(),
|
||||
.time = time,
|
||||
// .aspect_ratio= static_cast<float>(sz.width) / static_cast<float>(sz.height),
|
||||
.cam_pos = cam.pos,
|
||||
.viewport = glm::vec2(viewport.width, viewport.y),
|
||||
.tess_factor = tess_factor,
|
||||
.tess_edge_size = tess_edge_size,
|
||||
});
|
||||
|
||||
command_buffer->command_buffer.drawIndexed(models[0]->indices.size(), 10, 0, 0, 0);
|
||||
//command_buffer->command_buffer.drawIndexed(models[0]->indices.size(), 10, 0, 0, 0);
|
||||
|
||||
command_buffer->bind(*terrain_pipeline);
|
||||
command_buffer->command_buffer.setViewport(0, viewport);
|
||||
@ -411,10 +416,14 @@ Renderer::~Renderer() {
|
||||
for(auto& model : models)
|
||||
model.reset();
|
||||
|
||||
terrain.reset();
|
||||
|
||||
uniform_buffer.reset();
|
||||
vertex_buffer.reset();
|
||||
terrain_pipeline.reset();
|
||||
pipeline.reset();
|
||||
|
||||
|
||||
for (auto& tex : textures) {
|
||||
tex.cleanup();
|
||||
}
|
||||
|
||||
@ -72,4 +72,7 @@ struct Renderer {
|
||||
float time = 0.0;
|
||||
float speed = 1.0;
|
||||
bool running = true;
|
||||
|
||||
float tess_factor;
|
||||
float tess_edge_size = 20.0f;
|
||||
};
|
||||
|
||||
@ -13,6 +13,9 @@ struct UniformData {
|
||||
glm::mat4 mvp;
|
||||
float time;
|
||||
glm::vec3 cam_pos;
|
||||
glm::vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
struct UniformBuffer {
|
||||
|
||||
@ -18,6 +18,7 @@ Texture::Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer& com
|
||||
|
||||
|
||||
image_data = stbi_load(fname.c_str(), reinterpret_cast<int*>(&extent.width), reinterpret_cast<int*>(&extent.height), &n_channels, STBI_rgb_alpha);
|
||||
Log::info("Texture is %dx%d loaded at %p\n", extent.width, extent.height, image_data);
|
||||
extent.depth = 1;
|
||||
|
||||
image = std::make_unique<Image>(phys_dev, dev, extent, vk::Format::eR8G8B8A8Unorm,
|
||||
@ -31,8 +32,10 @@ Texture::Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer& com
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
|
||||
staging->upload(image_data);
|
||||
if(free_memory)
|
||||
if(free_memory) {
|
||||
stbi_image_free(image_data);
|
||||
image_data = nullptr;
|
||||
}
|
||||
|
||||
/* pipeline memory barrier ensures this doesn't get reordered wrong */
|
||||
|
||||
|
||||
@ -5,17 +5,16 @@
|
||||
|
||||
|
||||
float Terrain::getHeight(int32_t x, int32_t y) {
|
||||
Log::debug("Height queried at %d, %d\n", x, y);
|
||||
if (x < 0)
|
||||
x += heightmap_tex->extent.width;
|
||||
x += 64;
|
||||
if (y < 0)
|
||||
y += heightmap_tex->extent.height;
|
||||
y += 64;
|
||||
|
||||
if (x <= heightmap_tex->extent.width)
|
||||
x -= heightmap_tex->extent.width;
|
||||
if (y <= heightmap_tex->extent.height)
|
||||
y -= heightmap_tex->extent.height;
|
||||
x %= 64;
|
||||
y %= 64;
|
||||
|
||||
return heightmap_tex->image_data[y * heightmap_tex->extent.width + x * 4];
|
||||
return heightmap_tex->image_data[(y * heightmap_tex->extent.height * heightmap_tex->extent.width / 64 + x * heightmap_tex->extent.width / 64) * 4];
|
||||
}
|
||||
|
||||
Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : phys_dev(phys_dev), dev(dev) {
|
||||
@ -26,12 +25,15 @@ Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : ph
|
||||
const auto uv_scale = 1.0f;
|
||||
const auto vertex_count = patch_size * patch_size;
|
||||
|
||||
vertices.reserve(vertex_count);
|
||||
vertices.resize(vertex_count);
|
||||
|
||||
for (size_t x = 0; x < patch_size; x++)
|
||||
for (size_t y = 0; y < patch_size; y++)
|
||||
vertices.push_back(Vertex {
|
||||
.pos = glm::vec3(2.0f*x+1.0f - patch_size, 0.0f, 2.0f * y + 1.0f - patch_size),
|
||||
vertices[x + y*patch_size] = (Vertex {
|
||||
.pos = glm::vec3(
|
||||
2.0f * x + 1.0f - patch_size,
|
||||
0.0f,
|
||||
2.0f * y * 1.0f - patch_size),
|
||||
.uv = glm::vec2(static_cast<float>(x)/patch_size, static_cast<float>(y) / patch_size) * uv_scale,
|
||||
});
|
||||
|
||||
@ -54,8 +56,8 @@ Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : ph
|
||||
* +----+----+----+
|
||||
*/
|
||||
|
||||
for(auto x = 0_u32; x < patch_size; x++)
|
||||
for (auto y = 0_u32; y < patch_size; y++) {
|
||||
for(auto x = 0_i32; x < patch_size; x++)
|
||||
for (auto y = 0_i32; y < patch_size; y++) {
|
||||
float moores_heights[3][3] = {
|
||||
{ getHeight(x - 1, y - 1), getHeight(x - 1, y), getHeight(x - 1, y + 1) },
|
||||
{ getHeight(x + 0, y - 1), getHeight(x + 0, y), getHeight(x + 0, y + 1) },
|
||||
@ -84,8 +86,8 @@ Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : ph
|
||||
const auto w = patch_size - 1;
|
||||
indices.resize(w * w * 4);
|
||||
|
||||
for (auto x = 0_u32; x < patch_size; x++)
|
||||
for (auto y = 0_u32; y < patch_size; y++) {
|
||||
for (auto x = 0_u32; x < w; x++)
|
||||
for (auto y = 0_u32; y < w; y++) {
|
||||
auto idx = x + y * w * 4;
|
||||
indices[idx] = x+y*patch_size;
|
||||
indices[idx+1] = indices[idx] + patch_size;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
#include <Scene/Camera.hpp>
|
||||
|
||||
UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .time = ren->time, .cam = ren->cam, }, dev(ren->dev) {
|
||||
UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .time = ren->time, .cam = ren->cam, .tess_factor = ren->tess_factor, .tess_edge_size = ren->tess_edge_size }, dev(ren->dev) {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
@ -92,11 +92,8 @@ void UI::newFrame() {
|
||||
ImGui::Text("FPS: %f", info.fps);
|
||||
ImGui::Text("Time: %f", info.time);
|
||||
ImGui::Checkbox("Fly Camera", &info.flycam);
|
||||
ImGui::SliderAngle("Theta", &info.cam.theta, 0.01, 179.9);
|
||||
ImGui::SliderAngle("Phi", &info.cam.phi, 0.0, 360.0, "%.0f def");
|
||||
ImGui::SliderFloat("cam.x", &info.cam.pos.x, -1e2, 1e2);
|
||||
ImGui::SliderFloat("cam.y", &info.cam.pos.y, -1e2, 1e2);
|
||||
ImGui::SliderFloat("cam.z", &info.cam.pos.z, -1e2, 1e2);
|
||||
ImGui::SliderFloat("Tessellation Factor: %f", &info.tess_factor, 0.0, 20.0);
|
||||
ImGui::SliderFloat("Edge Size: %f", &info.tess_edge_size, 0.0, 40.0);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@ struct UI {
|
||||
float& time;
|
||||
/* camera stuff */
|
||||
Camera& cam;
|
||||
float& tess_factor;
|
||||
float& tess_edge_size;
|
||||
} info;
|
||||
|
||||
vk::Device dev;
|
||||
|
||||
18
assets/shaders/terrain.frag
Normal file
18
assets/shaders/terrain.frag
Normal file
@ -0,0 +1,18 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 2) in vec3 pos;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 mvp;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(1.0);
|
||||
}
|
||||
BIN
assets/shaders/terrain.frag.spv
Normal file
BIN
assets/shaders/terrain.frag.spv
Normal file
Binary file not shown.
60
assets/shaders/terrain.tesc
Normal file
60
assets/shaders/terrain.tesc
Normal file
@ -0,0 +1,60 @@
|
||||
#version 450 core
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 mvp;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler2D heightmap;
|
||||
|
||||
layout (vertices = 4) out;
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
layout (location = 2) in vec3 pos[];
|
||||
|
||||
layout (location = 0) out vec3 _norm[4];
|
||||
layout (location = 1) out vec2 _texCoord[4];
|
||||
layout (location = 2) out vec3 _pos[4];
|
||||
|
||||
|
||||
float screen_space_tess(vec4 p0, vec4 p1) {
|
||||
/* calc midpoint + distance btw the two points */
|
||||
vec4 mid = (p0+p1) / 2.0;
|
||||
float r = distance(p0, p1) / 2.0;
|
||||
|
||||
vec4 v0 = mvp * mid;
|
||||
|
||||
/* projevt into clip spaace */
|
||||
vec4 clip0 = mvp * (v0 - vec4(r, 0.0, 0.0, 0.0));
|
||||
vec4 clip1 = mvp * (v0 + vec4(r, 0.0, 0.0, 0.0));
|
||||
|
||||
clip0 /= clip0.w;
|
||||
clip1 /= clip1.w;
|
||||
|
||||
/* convert to viewport coords */
|
||||
clip0.xy * viewport;
|
||||
clip1.xy * viewport;
|
||||
|
||||
return clamp(distance(clip0, clip0) / tess_edge_size * tess_factor, 1.0, 64.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
if(gl_InvocationID == 0) {
|
||||
gl_TessLevelOuter[0] = screen_space_tess(gl_in[3].gl_Position, gl_in[0].gl_Position);
|
||||
gl_TessLevelOuter[1] = screen_space_tess(gl_in[0].gl_Position, gl_in[1].gl_Position);
|
||||
gl_TessLevelOuter[2] = screen_space_tess(gl_in[1].gl_Position, gl_in[2].gl_Position);
|
||||
gl_TessLevelOuter[3] = screen_space_tess(gl_in[2].gl_Position, gl_in[3].gl_Position);
|
||||
gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
|
||||
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
|
||||
}
|
||||
|
||||
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
||||
_norm[gl_InvocationID] = norm[gl_InvocationID];
|
||||
_texCoord[gl_InvocationID] = texCoord[gl_InvocationID];
|
||||
_pos[gl_InvocationID] = pos[gl_InvocationID];
|
||||
}
|
||||
BIN
assets/shaders/terrain.tesc.spv
Normal file
BIN
assets/shaders/terrain.tesc.spv
Normal file
Binary file not shown.
42
assets/shaders/terrain.tese
Normal file
42
assets/shaders/terrain.tese
Normal file
@ -0,0 +1,42 @@
|
||||
#version 450 core
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 mvp;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler2D heightmap;
|
||||
|
||||
layout(quads, equal_spacing, ccw) in;
|
||||
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
layout (location = 2) in vec3 pos[];
|
||||
|
||||
layout (location = 0) out vec3 _norm;
|
||||
layout (location = 1) out vec2 _texCoord;
|
||||
layout (location = 2) out vec3 _pos;
|
||||
|
||||
void main() {
|
||||
/* interpolation of UV coordinates */
|
||||
vec2 uv1 = mix(texCoord[0], texCoord[1], gl_TessCoord.x);
|
||||
vec2 uv2 = mix(texCoord[3], texCoord[2], gl_TessCoord.x);
|
||||
_texCoord = mix(uv1, uv2, gl_TessCoord.y);
|
||||
|
||||
|
||||
vec3 norm1 = mix(norm[0], norm[1], gl_TessCoord.x);
|
||||
vec3 norm2 = mix(norm[3], norm[2], gl_TessCoord.x);
|
||||
_norm = mix(norm1, norm2, gl_TessCoord.y);
|
||||
|
||||
/* not displacing yet */
|
||||
vec4 pos1 = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
|
||||
vec4 pos2 = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
|
||||
_pos = mix(pos1, pos2, gl_TessCoord.y).xyz;
|
||||
|
||||
gl_Position = mvp * mix(pos1, pos2, gl_TessCoord.y);
|
||||
}
|
||||
BIN
assets/shaders/terrain.tese.spv
Normal file
BIN
assets/shaders/terrain.tese.spv
Normal file
Binary file not shown.
20
assets/shaders/terrain.vert
Normal file
20
assets/shaders/terrain.vert
Normal file
@ -0,0 +1,20 @@
|
||||
#version 460 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNorm;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
layout (location = 0) out vec3 norm;
|
||||
layout (location = 1) out vec2 texCoord;
|
||||
layout (location = 2) out vec3 pos;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 mvp;
|
||||
float time;
|
||||
};
|
||||
|
||||
void main() {
|
||||
pos = aPos;
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
texCoord = aTexCoord;
|
||||
norm = aNorm;
|
||||
}
|
||||
BIN
assets/shaders/terrain.vert.spv
Normal file
BIN
assets/shaders/terrain.vert.spv
Normal file
Binary file not shown.
BIN
assets/textures/heightmap.png
Normal file
BIN
assets/textures/heightmap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
@ -28,7 +28,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
while (in->queue.size()) {
|
||||
/* take event from front of queue, then process it */
|
||||
const auto& event = in->queue.front();
|
||||
const auto event = in->queue.front();
|
||||
in->queue.pop();
|
||||
switch (event.tag) {
|
||||
case InputEvent::Tag::eRESIZE:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user