Skip to content
Snippets Groups Projects
Commit cd353119 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Merge branch '63-laden-mehrer-meshes-mit-materials-und-textures' into 'develop'

Resolve "Laden mehrer Meshes mit Materials und Textures"

Closes #63

See merge request !51
parents 3a5e99cd 70fa675d
No related branches found
No related tags found
1 merge request!51Resolve "Laden mehrer Meshes mit Materials und Textures"
Pipeline #25766 passed
projects/first_scene/resources/Szene/boards2_vcyc_jpg.jpg

132 B

%VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv
%VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv
pause
\ No newline at end of file
File added
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 passNormal;
layout(location = 1) in vec2 passUV;
layout(location = 0) out vec3 outColor;
layout(set=0, binding=0) uniform texture2D meshTexture;
layout(set=0, binding=1) uniform sampler textureSampler;
void main() {
outColor = texture(sampler2D(meshTexture, textureSampler), passUV).rgb;
//outColor = passNormal * 0.5 + 0.5;
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 0) out vec3 passNormal;
layout(location = 1) out vec2 passUV;
layout( push_constant ) uniform constants{
mat4 mvp;
};
void main() {
gl_Position = mvp * vec4(inPosition, 1.0);
passNormal = inNormal;
passUV = inUV;
}
\ No newline at end of file
File added
#include <iostream>
#include <vkcv/Core.hpp>
#include <GLFW/glfw3.h>
#include <vkcv/camera/CameraManager.hpp>
#include <chrono>
#include <vkcv/asset/asset_loader.hpp>
#include <vkcv/Logger.hpp>
glm::mat4 arrayTo4x4Matrix(std::array<float,16> array){
glm::mat4 matrix;
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
matrix[i][j] = array[j * 4 + i];
}
}
return matrix;
}
int main(int argc, const char** argv) {
const char* applicationName = "First Scene";
uint32_t windowWidth = 800;
uint32_t windowHeight = 600;
vkcv::Window window = vkcv::Window::create(
applicationName,
windowWidth,
windowHeight,
true
);
vkcv::camera::CameraManager cameraManager(window);
uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3));
cameraManager.getCamera(camIndex0).setNearFar(0.1f, 30.0f);
cameraManager.getCamera(camIndex1).setNearFar(0.1f, 30.0f);
window.initEvents();
vkcv::Core core = vkcv::Core::create(
window,
applicationName,
VK_MAKE_VERSION(0, 0, 1),
{ vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer },
{},
{ "VK_KHR_swapchain" }
);
vkcv::asset::Scene scene;
const char* path = argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf";
int result = vkcv::asset::loadScene(path, scene);
if (result == 1) {
std::cout << "Mesh loading successful!" << std::endl;
}
else {
std::cout << "Mesh loading failed: " << result << std::endl;
return 1;
}
assert(!scene.vertexGroups.empty());
std::vector<std::vector<uint8_t>> vBuffers;
std::vector<std::vector<uint8_t>> iBuffers;
std::vector<vkcv::VertexBufferBinding> vBufferBindings;
std::vector<std::vector<vkcv::VertexBufferBinding>> vertexBufferBindings;
std::vector<vkcv::asset::VertexAttribute> vAttributes;
for (int i = 0; i < scene.vertexGroups.size(); i++) {
vBuffers.push_back(scene.vertexGroups[i].vertexBuffer.data);
iBuffers.push_back(scene.vertexGroups[i].indexBuffer.data);
auto& attributes = scene.vertexGroups[i].vertexBuffer.attributes;
std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) {
return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type);
});
}
std::vector<vkcv::Buffer<uint8_t>> vertexBuffers;
for (const vkcv::asset::VertexGroup& group : scene.vertexGroups) {
vertexBuffers.push_back(core.createBuffer<uint8_t>(
vkcv::BufferType::VERTEX,
group.vertexBuffer.data.size()));
vertexBuffers.back().fill(group.vertexBuffer.data);
}
std::vector<vkcv::Buffer<uint8_t>> indexBuffers;
for (const auto& dataBuffer : iBuffers) {
indexBuffers.push_back(core.createBuffer<uint8_t>(
vkcv::BufferType::INDEX,
dataBuffer.size()));
indexBuffers.back().fill(dataBuffer);
}
int vertexBufferIndex = 0;
for (const auto& vertexGroup : scene.vertexGroups) {
for (const auto& attribute : vertexGroup.vertexBuffer.attributes) {
vAttributes.push_back(attribute);
vBufferBindings.push_back(vkcv::VertexBufferBinding(attribute.offset, vertexBuffers[vertexBufferIndex].getVulkanHandle()));
}
vertexBufferBindings.push_back(vBufferBindings);
vBufferBindings.clear();
vertexBufferIndex++;
}
const vkcv::AttachmentDescription present_color_attachment(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR,
core.getSwapchainImageFormat()
);
const vkcv::AttachmentDescription depth_attachment(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR,
vk::Format::eD32Sfloat
);
vkcv::PassConfig scenePassDefinition({ present_color_attachment, depth_attachment });
vkcv::PassHandle scenePass = core.createPass(scenePassDefinition);
if (!scenePass) {
std::cout << "Error. Could not create renderpass. Exiting." << std::endl;
return EXIT_FAILURE;
}
vkcv::ShaderProgram sceneShaderProgram{};
sceneShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
sceneShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] }));
}
const vkcv::VertexLayout sceneLayout(bindings);
uint32_t setID = 0;
std::vector<vkcv::DescriptorBinding> descriptorBindings = { sceneShaderProgram.getReflectedDescriptors()[setID] };
vkcv::SamplerHandle sampler = core.createSampler(
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerMipmapMode::LINEAR,
vkcv::SamplerAddressMode::REPEAT
);
std::vector<vkcv::Image> sceneImages;
std::vector<vkcv::DescriptorSetHandle> descriptorSets;
for (const auto& vertexGroup : scene.vertexGroups) {
descriptorSets.push_back(core.createDescriptorSet(descriptorBindings));
const auto& material = scene.materials[vertexGroup.materialIndex];
int baseColorIndex = material.baseColor;
if (baseColorIndex < 0) {
vkcv_log(vkcv::LogLevel::WARNING, "Material lacks base color");
baseColorIndex = 0;
}
vkcv::asset::Texture& sceneTexture = scene.textures[baseColorIndex];
sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, sceneTexture.w, sceneTexture.h));
sceneImages.back().fill(sceneTexture.data.data());
vkcv::DescriptorWrites setWrites;
setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, sceneImages.back().getHandle()) };
setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) };
core.writeDescriptorSet(descriptorSets.back(), setWrites);
}
const vkcv::PipelineConfig scenePipelineDefsinition{
sceneShaderProgram,
UINT32_MAX,
UINT32_MAX,
scenePass,
{sceneLayout},
{ core.getDescriptorSet(descriptorSets[0]).layout },
true };
vkcv::PipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefsinition);
if (!scenePipeline) {
std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
return EXIT_FAILURE;
}
vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle();
const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
std::vector<vkcv::DrawcallInfo> drawcalls;
for(int i = 0; i < scene.vertexGroups.size(); i++){
vkcv::Mesh renderMesh(vertexBufferBindings[i], indexBuffers[i].getVulkanHandle(), scene.vertexGroups[i].numIndices);
vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSets[i]).vulkanHandle);
drawcalls.push_back(vkcv::DrawcallInfo(renderMesh, {descriptorUsage}));
}
std::vector<glm::mat4> modelMatrices;
modelMatrices.resize(scene.vertexGroups.size(), glm::mat4(1.f));
for (const auto &mesh : scene.meshes) {
const glm::mat4 m = arrayTo4x4Matrix(mesh.modelMatrix);
for (const auto &vertexGroupIndex : mesh.vertexGroups) {
modelMatrices[vertexGroupIndex] = m;
}
}
std::vector<glm::mat4> mvp;
auto start = std::chrono::system_clock::now();
while (window.isWindowOpen()) {
vkcv::Window::pollEvents();
if(window.getHeight() == 0 || window.getWidth() == 0)
continue;
uint32_t swapchainWidth, swapchainHeight;
if (!core.beginFrame(swapchainWidth, swapchainHeight)) {
continue;
}
if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) {
depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle();
windowWidth = swapchainWidth;
windowHeight = swapchainHeight;
}
auto end = std::chrono::system_clock::now();
auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
start = end;
cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
glm::mat4 vp = cameraManager.getActiveCamera().getMVP();
mvp.clear();
for (const auto& m : modelMatrices) {
mvp.push_back(vp * m);
}
vkcv::PushConstantData pushConstantData((void*)mvp.data(), sizeof(glm::mat4));
const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer };
auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
core.recordDrawcallsToCmdStream(
cmdStream,
scenePass,
scenePipeline,
pushConstantData,
drawcalls,
renderTargets);
core.prepareSwapchainImageForPresent(cmdStream);
core.submitCommandStream(cmdStream);
core.endFrame();
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment