This commit is contained in:
zack 2025-05-23 21:13:53 -04:00
commit 444f800536
No known key found for this signature in database
GPG key ID: EE8A2B709E2401D1
122 changed files with 17137 additions and 0 deletions

View file

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.19)
project(Chapter03)
include(../../CMake/CommonMacros.txt)
SETUP_APP(Ch03_01_Assimp "Chapter 03")
target_include_directories(Ch03_01_Assimp PUBLIC ${CMAKE_SOURCE_DIR})
target_link_libraries(Ch03_01_Assimp SharedUtils)

View file

@ -0,0 +1,176 @@
#include "shared/HelpersGLFW.h"
#include <iostream>
#include <lvk/LVK.h>
#include <GLFW/glfw3.h>
#include <shared/Utils.h>
#include <glm/ext.hpp>
#include <glm/glm.hpp>
#include <assimp/cimport.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using glm::mat4;
using glm::vec3;
int main(int argc, char *argv[]) {
minilog::initialize(nullptr, {.threadNames = false});
int width = -65;
int height = -60;
GLFWwindow *window = lvk::initWindow("Ch03_01: Assimp", width, height);
std::unique_ptr<lvk::IContext> ctx =
lvk::createVulkanContextWithSwapchain(window, width, height, {});
const aiScene *scene =
aiImportFile("data/rubber_duck/scene.gltf", aiProcess_Triangulate);
if (!scene || !scene->HasMeshes()) {
printf("Unable to load data/rubber_duck/scene.gltf\n");
exit(255);
}
const aiMesh *mesh = scene->mMeshes[0];
std::vector<vec3> positions;
std::vector<uint32_t> indicies;
for (unsigned int i = 0; i != mesh->mNumVertices; i++) {
const aiVector3D v = mesh->mVertices[i];
positions.push_back(vec3(v.x, v.y, v.z));
}
for (unsigned int i = 0; i != mesh->mNumFaces; i++) {
for (int j = 0; j != 3; j++) {
indicies.push_back(mesh->mFaces[i].mIndices[j]);
}
}
aiReleaseImport(scene);
lvk::Holder<lvk::BufferHandle> vertexBuffer =
ctx->createBuffer({.usage = lvk::BufferUsageBits_Vertex,
.storage = lvk::StorageType_Device,
.size = sizeof(vec3) * positions.size(),
.data = positions.data(),
.debugName = "Buffer: vertex"});
lvk::Holder<lvk::BufferHandle> indexBuffer =
ctx->createBuffer({.usage = lvk::BufferUsageBits_Index,
.storage = lvk::StorageType_Device,
.size = sizeof(uint32_t) * indicies.size(),
.data = indicies.data(),
.debugName = "Buffer: index"});
lvk::Holder<lvk::TextureHandle> depthTexture =
ctx->createTexture({.type = lvk::TextureType_2D,
.format = lvk::Format_Z_F32,
.dimensions = {(uint32_t)width, (uint32_t)height},
.usage = lvk::TextureUsageBits_Attachment,
.debugName = "Depth buffer"});
const lvk::VertexInput vdesc = {
.attributes = {{.location = 0, .format = lvk::VertexFormat::Float3}},
.inputBindings = {{.stride = sizeof(vec3)}},
};
lvk::Holder<lvk::ShaderModuleHandle> vert =
loadShaderModule(ctx, "Chapter03/01_Assimp/src/main.vert");
lvk::Holder<lvk::ShaderModuleHandle> frag =
loadShaderModule(ctx, "Chapter03/01_Assimp/src/main.frag");
lvk::Holder<lvk::RenderPipelineHandle> pipelineSolid =
ctx->createRenderPipeline(
{.vertexInput = vdesc,
.smVert = vert,
.smFrag = frag,
.color = {{.format = ctx->getSwapchainFormat()}},
.depthFormat = ctx->getFormat(depthTexture),
.cullMode = lvk::CullMode_Back});
const uint32_t isWireframe = 1;
lvk::Holder<lvk::RenderPipelineHandle> pipelineWireframe =
ctx->createRenderPipeline(
{.vertexInput = vdesc,
.smVert = vert,
.smFrag = frag,
.specInfo = {.entries = {{.constantId = 0,
.size = sizeof(uint32_t)}},
.data = &isWireframe,
.dataSize = sizeof(isWireframe)},
.color = {{.format = ctx->getSwapchainFormat()}},
.depthFormat = ctx->getFormat(depthTexture),
.cullMode = lvk::CullMode_Back,
.polygonMode = lvk::PolygonMode_Line});
LVK_ASSERT(pipelineSolid.valid());
LVK_ASSERT(pipelineWireframe.valid());
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
if (!width || !height)
continue;
const float ratio = width / (float)height;
const mat4 m = glm::rotate(mat4(1.0f), glm::radians(-90.0f), vec3(1, 0, 0));
const mat4 v =
glm::rotate(glm::translate(mat4(1.0f), vec3(0.0f, -0.5f, -1.5f)),
(float)glfwGetTime(), vec3(0.0f, 1.0f, 0.0f));
const mat4 p = glm::perspective(45.0f, ratio, 0.1f, 1000.0f);
const lvk::RenderPass renderPass = {
.color = {{.loadOp = lvk::LoadOp_Clear,
.clearColor = {1.0f, 1.0f, 1.0f, 1.0f}}},
.depth = {.loadOp = lvk::LoadOp_Clear, .clearDepth = 1.0f}};
const lvk::Framebuffer framebuffer = {
.color = {{.texture = ctx->getCurrentSwapchainTexture()}},
.depthStencil = {.texture = depthTexture},
};
lvk::ICommandBuffer &buf = ctx->acquireCommandBuffer();
{
buf.cmdBeginRendering(renderPass, framebuffer);
{
buf.cmdPushDebugGroupLabel("Mesh", 0xff0000ff);
{
buf.cmdBindVertexBuffer(0, vertexBuffer);
buf.cmdBindIndexBuffer(indexBuffer, lvk::IndexFormat_UI32);
buf.cmdBindRenderPipeline(pipelineSolid);
buf.cmdBindDepthState(
{.compareOp = lvk::CompareOp_Less, .isDepthWriteEnabled = true});
buf.cmdPushConstants(p * v * m);
buf.cmdDrawIndexed(indicies.size());
buf.cmdBindRenderPipeline(pipelineWireframe);
buf.cmdSetDepthBiasEnable(true);
buf.cmdSetDepthBias(0.0f, -1.0f, 0.0f);
buf.cmdDrawIndexed(indicies.size());
}
buf.cmdPopDebugGroupLabel();
buf.cmdEndRendering();
}
}
ctx->submit(buf, ctx->getCurrentSwapchainTexture());
}
vert.reset();
frag.reset();
depthTexture.reset();
pipelineSolid.reset();
pipelineWireframe.reset();
vertexBuffer.reset();
indexBuffer.reset();
ctx.reset();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

View file

@ -0,0 +1,9 @@
//
#version 460 core
layout (location = 0) in vec3 color;
layout (location = 0) out vec4 out_FragColor;
void main() {
out_FragColor = vec4(color, 1.0);
}

View file

@ -0,0 +1,16 @@
//
#version 460 core
layout(push_constant) uniform PerFrameData {
mat4 MVP;
};
layout (constant_id = 0) const bool isWireframe = false;
layout (location=0) in vec3 pos;
layout (location=0) out vec3 color;
void main() {
gl_Position = MVP * vec4(pos, 1.0);
color = isWireframe ? vec3(0.0) : pos.xzy;
}