可编译,无法运行,待debug

reconstruct-gltfLoader
InkSoul 2026-03-15 21:43:08 +08:00
parent 907b94dcdd
commit 64c71e8eed
21 changed files with 544 additions and 322 deletions

2
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"name": "Launch",
"type": "lldb",
"request": "launch",
"program": "${workspaceRoot}/<your program>",
"program": "${workspaceRoot}/build/bin/PlumageRender.exe",
"args": [],
"cwd": "${workspaceRoot}"
}

Binary file not shown.

View File

@ -773,7 +773,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
#ifdef __STDC_LIB_EXT1__
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#else
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
len = snprintf(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#endif
s->func(s->context, buffer, len);

View File

@ -2,25 +2,36 @@
`TinyGLTF` is a header only C++11 glTF 2.0 https://github.com/KhronosGroup/glTF library.
`TinyGLTF` uses Niels Lohmann's json library(https://github.com/nlohmann/json), so now it requires C++11 compiler.
If you are looking for old, C++03 version, please use `devel-picojson` branch.
`TinyGLTF` uses Niels Lohmann's json library (https://github.com/nlohmann/json), so now it requires C++11 compiler.
(Also, you can use RadpidJSON as an JSON backend)
If you are looking for old, C++03 version, please use `devel-picojson` branch (but not maintained anymore).
## Status
Currently TinyGLTF is stable and maintenance mode. No drastic changes and feature additions planned.
- v2.9.0 Various fixes and improvements. Filesystem callback API change.
- v2.8.0 Add URICallbacks for custom URI handling in Buffer and Image. PR#397
- v2.7.0 Change WriteImageDataFunction user callback function signature. PR#393
- v2.6.0 Support serializing sparse accessor(Thanks to @fynv).
- v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
- v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance)
- v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class)
- v2.2.0 release(Support loading 16bit PNG. Sparse accessor support)
- v2.1.0 release(Draco support)
- v2.1.0 release(Draco decoding support)
- v2.0.0 release(22 Aug, 2018)!
### Branches
* `sajson` : Use sajson to parse JSON. Parsing only but faster compile time(2x reduction compared to json.hpp and RapidJson), but not well maintained.
## Builds
[![Build Status](https://travis-ci.org/syoyo/tinygltf.svg?branch=devel)](https://travis-ci.org/syoyo/tinygltf)
[![Build status](https://ci.appveyor.com/api/projects/status/warngenu9wjjhlm8?svg=true)](https://ci.appveyor.com/project/syoyo/tinygltf)
![C/C++ CI](https://github.com/syoyo/tinygltf/workflows/C/C++%20CI/badge.svg)
## Features
Probably mostly feature-complete. Last missing feature is Draco encoding: https://github.com/syoyo/tinygltf/issues/207
* Written in portable C++. C++-11 with STL dependency only.
* [x] macOS + clang(LLVM)
* [x] iOS + clang
@ -71,6 +82,13 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [glview](examples/glview) : Simple glTF geometry viewer.
* [validator](examples/validator) : Simple glTF validator with JSON schema.
* [basic](examples/basic) : Basic glTF viewer with texturing support.
* [build-gltf](examples/build-gltf) : Build simple glTF scene from a scratch.
### WASI/WASM build
Users who want to run TinyGLTF securely and safely(e.g. need to handle malcious glTF file to serve online glTF conver),
I recommend to build TinyGLTF for WASM target.
WASI build example is located in [wasm](wasm) .
## Projects using TinyGLTF
@ -83,11 +101,16 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [QuickLook GLTF](https://github.com/toshiks/glTF-quicklook) - quicklook plugin for macos. Also SceneKit wrapper for tinygltf.
* [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux
* [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications.
* [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11
* [SanityEngine](https://github.com/DethRaid/SanityEngine) - A C++/D3D12 renderer focused on the personal and professional development of its developer
* [Open3D](http://www.open3d.org/) - A Modern Library for 3D Data Processing
* [Supernova Engine](https://github.com/supernovaengine/supernova) - Game engine for 2D and 3D projects with Lua or C++ in data oriented design.
* [Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine) - 3D engine with modern graphics
* Your projects here! (Please send PR)
## TODOs
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing.
* [ ] Robust URI decoding/encoding. https://github.com/syoyo/tinygltf/issues/369
* [ ] Mesh Compression/decompression(Open3DGC, etc)
* [x] Load Draco compressed mesh
* [ ] Save Draco compressed mesh
@ -98,6 +121,10 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [ ] 16bit PNG support in Serialization
* [ ] Write example and tests for `animation` and `skin`
### Optional
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing?
## Licenses
TinyGLTF is licensed under MIT license.
@ -130,9 +157,10 @@ Model model;
TinyGLTF loader;
std::string err;
std::string warn;
std::string filename = "input.gltf";
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, argv[1]);
//bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, argv[1]); // for binary glTF(.glb)
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
//bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, filename); // for binary glTF(.glb)
if (!warn.empty()) {
printf("Warn: %s\n", warn.c_str());
@ -143,11 +171,14 @@ if (!err.empty()) {
}
if (!ret) {
printf("Failed to parse glTF\n");
return -1;
printf("Failed to parse glTF: %s\n", filename.c_str());
}
```
#### Loader options
* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader).
## Compile options
* `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF.
@ -157,12 +188,32 @@ if (!ret) {
* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand.
* `TINYGLTF_ENABLE_DRACO`: Enable Draco compression. User must provide include path and link correspnding libraries in your project file.
* `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_RAPIDJSON `: Disable including RapidJson's header files from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this featrure.
* `TINYGLTF_USE_CPP14` : Use C++14 feature(requires C++14 compiler). This may give better performance than C++11.
* `TINYGLTF_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this feature.
## CMake options
You can add tinygltf using `add_subdirectory` feature.
If you add tinygltf to your project using `add_subdirectory`, it would be better to set `TINYGLTF_HEADER_ONLY` on(just add an include path to tinygltf) and `TINYGLTF_INSTALL` off(Which does not install tinygltf files).
```
// Your project's CMakeLists.txt
...
set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE)
set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE)
add_subdirectory(/path/to/tinygltf)
```
NOTE: Using tinygltf as a submodule doesn't automatically add the headers to your include path (as standard for many libraries). To get this functionality, add the following to the CMakeLists.txt file from above:
```
target_include_directories(${PROJECT_NAME} PRIVATE "/path/to/tinygltf")
```
### Saving gltTF 2.0 model
* Buffers.
@ -182,7 +233,7 @@ if (!ret) {
#### Setup
Python 2.6 or 2.7 required.
Python required.
Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir.
#### Run parsing test

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -64,9 +64,6 @@ if(WIN32)
${GLTF_MODEL_LOADER}
${VULKAN_BASE}
${PBR}
"render/renderFoundation.h"
"render/renderFoundation.cpp"
)
target_link_libraries(${RenderName} base ${Vulkan_LIBRARY} ${WINLIBS})
endif()

View File

@ -43,6 +43,80 @@ VulkanDevice::~VulkanDevice()
}
}
/// @brief 据分配的物理设备创建逻辑设备,同时获取默认队列族索引
/// @param enabledFeatures 在创建设备时启用某些功能
/// @param enabledExtensions 在创建设备时启用某些扩展
/// @param requestedQueueTypes 指定要从设备请求的队列类型
/// @return 逻辑设备是否成功创建
VkResult VulkanDevice::createLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, std::vector<const char *> enabledExtensions, VkQueueFlags requestedQueueTypes)
{
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
const float defaultQueuePriority(0.0f);
// Graphics queue
if (requestedQueueTypes & VK_QUEUE_GRAPHICS_BIT)
{
m_queueFamilyIndices.graphics = getQueueFamilyIndex(VK_QUEUE_GRAPHICS_BIT);
VkDeviceQueueCreateInfo queueInfo{};
queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueInfo.queueFamilyIndex = m_queueFamilyIndices.graphics;
queueInfo.queueCount = 1;
queueInfo.pQueuePriorities = &defaultQueuePriority;
queueCreateInfos.push_back(queueInfo);
}
else
{
m_queueFamilyIndices.graphics = 0;
}
// Dedicated compute queue
if (requestedQueueTypes & VK_QUEUE_COMPUTE_BIT)
{
m_queueFamilyIndices.compute = getQueueFamilyIndex(VK_QUEUE_COMPUTE_BIT);
if (m_queueFamilyIndices.compute != m_queueFamilyIndices.graphics)
{
// If compute family index differs, we need an additional queue create info for the compute queue
VkDeviceQueueCreateInfo queueInfo{};
queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueInfo.queueFamilyIndex = m_queueFamilyIndices.compute;
queueInfo.queueCount = 1;
queueInfo.pQueuePriorities = &defaultQueuePriority;
queueCreateInfos.push_back(queueInfo);
}
}
else
{
m_queueFamilyIndices.compute = m_queueFamilyIndices.graphics;
}
// Create the logical device representation
std::vector<const char *> deviceExtensions(enabledExtensions);
deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
;
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.pEnabledFeatures = &enabledFeatures;
if (deviceExtensions.size() > 0)
{
deviceCreateInfo.enabledExtensionCount = (uint32_t)deviceExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
}
VkResult result = vkCreateDevice(m_physicalDevice, &deviceCreateInfo, nullptr, &m_logicalDevice);
if (result == VK_SUCCESS)
{
m_commandPool = createCommandPool(m_queueFamilyIndices.graphics);
}
m_enabledFeatures = enabledFeatures;
return result;
}
VkDevice VulkanDevice::getLogicalDevice()
{
return m_logicalDevice;

View File

@ -4,7 +4,6 @@
#include "VulkanInitializers.hpp"
#include "vulkan/vulkan.h"
#include <algorithm>
#include <assert.h>
#include <cstring>

View File

@ -1,6 +1,18 @@
#include "glTFMainModel.h"
#include "glTFMaterial.h"
#include "glTFNode.h"
#include <VulkanTools.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"
#define TINYGLTF_IMPLEMENTATION
#define TINYGLTF_NO_INCLUDE_STB_IMAGE
#include <tiny_gltf.h>
#include <iostream>
#include <vector>
GLTFLOADER_NAMESPACE_BEGIN
@ -1071,4 +1083,34 @@ glTFNode *glTFMainModel::nodeFromIndex(uint32_t index)
return nodeFound;
}
std::vector<glTFNode *> glTFMainModel::getNodes()
{
return m_nodes;
}
std::vector<glTFMaterial> glTFMainModel::getMaterials()
{
return m_materials;
}
std::vector<glTFAnimation> glTFMainModel::getAnimations()
{
return m_animations;
}
std::vector<std::string> glTFMainModel::getExtensions()
{
return m_extensions;
}
std::vector<glTFNode *> glTFMainModel::getLinearNodes()
{
return m_linearNodes;
}
glm::mat4 glTFMainModel::getAABB()
{
return m_aabb;
}
GLTFLOADER_NAMESPACE_END

View File

@ -1,9 +1,8 @@
#ifndef GLTFMAINMODEL_H
#define GLTFMAINMODEL_H
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_STB_IMAGE_WRITE
#endif
#include "glTFMaterial.h"
#include "glm/detail/type_mat.hpp"
#include "glTFModel_Marco.h"
#include "glTFModel_common.h"
@ -15,8 +14,6 @@
#include "glTFSkin.h"
#include "glTFTexture.h"
#include <tiny_gltf.h>
#include <glm/glm.hpp>
#include <string>
#include <vector>
@ -67,6 +64,13 @@ public:
glTFNode *findNode(glTFNode *parent, uint32_t index);
glTFNode *nodeFromIndex(uint32_t index);
std::vector<glTFNode *> getNodes();
std::vector<glTFNode *> getLinearNodes();
std::vector<glTFMaterial> getMaterials();
std::vector<glTFAnimation> getAnimations();
std::vector<std::string> getExtensions();
glm::mat4 getAABB();
private:
VulkanBase::VulkanDevice *m_device;

View File

@ -20,12 +20,6 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_STB_IMAGE_WRITE
#endif //
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
#endif

View File

@ -18,6 +18,11 @@ void glTFTexture::updateDescriptor()
m_descriptor.imageLayout = m_imageLayout;
}
VkDescriptorImageInfo glTFTexture::getDescriptor()
{
return m_descriptor;
}
void glTFTexture::destroy()
{
VkDevice logicalDevice = m_device->getLogicalDevice();
@ -25,24 +30,26 @@ void glTFTexture::destroy()
vkDestroyImage(logicalDevice, m_image, nullptr);
vkFreeMemory(logicalDevice, m_deviceMemory, nullptr);
vkDestroySampler(logicalDevice, m_sampler, nullptr);
}
void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTextureSampler textureSampler, VulkanBase::VulkanDevice* device, VkQueue copyQueue)
void glTFTexture::fromglTfImage(tinygltf::Image &gltfimage, VulkanBase::VulkanTextureSampler textureSampler, VulkanBase::VulkanDevice *device, VkQueue copyQueue)
{
VkDevice logicalDevice = device->getLogicalDevice();
unsigned char* buffer = nullptr;
unsigned char *buffer = nullptr;
VkDeviceSize bufferSize = 0;
bool deleteBuffer = false;
if (gltfimage.component == 3) {
if (gltfimage.component == 3)
{
/// 即使创建为24bit的rgb硬件上依旧是rgba因此填充alpha值但带宽压力上升25%
/// 可选todo采用计算着色器将rgb写入uniform buffer
bufferSize = gltfimage.width * gltfimage.height * 4;
buffer = new unsigned char[bufferSize];
unsigned char* rgba = buffer;
unsigned char* rgb = &gltfimage.image[0];
for (int32_t i = 0; i < gltfimage.width * gltfimage.height; ++i) {
for (int32_t j = 0; j < 3; ++j) {
unsigned char *rgba = buffer;
unsigned char *rgb = &gltfimage.image[0];
for (int32_t i = 0; i < gltfimage.width * gltfimage.height; ++i)
{
for (int32_t j = 0; j < 3; ++j)
{
rgba[j] = rgb[j];
}
rgba += 4;
@ -50,7 +57,8 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
}
deleteBuffer = true;
}
else {
else
{
buffer = &gltfimage.image[0];
bufferSize = gltfimage.image.size();
}
@ -86,8 +94,8 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
VK_CHECK_RESULT(vkAllocateMemory(logicalDevice, &memAllocInfo, nullptr, &stagingMemory));
VK_CHECK_RESULT(vkBindBufferMemory(logicalDevice, stagingBuffer, stagingMemory, 0));
// 向设备内存中写入缓冲区
uint8_t* data;
VK_CHECK_RESULT(vkMapMemory(logicalDevice, stagingMemory, 0, memReqs.size, 0, (void**)&data));
uint8_t *data;
VK_CHECK_RESULT(vkMapMemory(logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data));
memcpy(data, buffer, bufferSize);
vkUnmapMemory(logicalDevice, stagingMemory);
/// 创建图片类型设备内存
@ -102,7 +110,7 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.extent = { m_width, m_height, 1 };
imageCreateInfo.extent = {m_width, m_height, 1};
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
VK_CHECK_RESULT(vkCreateImage(logicalDevice, &imageCreateInfo, nullptr, &m_image));
vkGetImageMemoryRequirements(logicalDevice, m_image, &memReqs);
@ -163,7 +171,8 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
// 生成mip-map链 (glTF 使用 jpg 和 png 格式, 需要当场生成mip-map)
VkCommandBuffer blitCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
for (uint32_t i = 1; i < m_mipLevels; i++) {
for (uint32_t i = 1; i < m_mipLevels; i++)
{
VkImageBlit imageBlit{};
imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -254,7 +263,7 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
viewInfo.image = m_image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format;
viewInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
viewInfo.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.layerCount = 1;
viewInfo.subresourceRange.levelCount = m_mipLevels;
@ -264,7 +273,6 @@ void glTFTexture::fromglTfImage(tinygltf::Image& gltfimage, VulkanBase::VulkanTe
if (deleteBuffer)
delete[] buffer;
}
GLTFLOADER_NAMESPACE_END

View File

@ -5,6 +5,7 @@
#include "VulkanDevice.h"
#include "VulkanTextureSampler.h"
#include "vulkan/vulkan_core.h"
#include <tiny_gltf.h>
@ -23,6 +24,8 @@ public:
void fromglTfImage(tinygltf::Image &gltfimage, VulkanBase::VulkanTextureSampler textureSampler, VulkanBase::VulkanDevice *device, VkQueue copyQueue);
VkDescriptorImageInfo getDescriptor();
private:
VulkanBase::VulkanDevice *m_device;
VkImage m_image;

View File

@ -1,5 +1,5 @@
#pragma once
#include "RenderStagingBuffer.h"
#include "renderStagingBuffer.h"
class IndexStagingBuffer : public RenderStagingBuffer
{
public:

View File

@ -1,5 +1,12 @@
#include "RenderPushBlock.h"
RenderPushBlock::RenderPushBlock()
{
}
RenderPushBlock::~RenderPushBlock()
{
}
// Getter method definitions
const glm::mat4 &RenderPushBlock::getMvp() const
{

View File

@ -1,5 +1,5 @@
#pragma once
#include "renderStagingBuffer.h"
#include "RenderStagingBuffer.h"
class VertexStagingBuffer : public RenderStagingBuffer
{
public:

View File

@ -1,34 +1,30 @@
#pragma once

#include "render.h"
#include "PbrBaseTexture.h"
#include "PbrTextureCoordSet.h"
#include "glTFAnimation.h"
#include "glTFMainModel.h"
#include "glTFMesh.h"
#include "glTFModel_common.h"
#include "PushConstBlockMaterial.h"
#include "ShaderLoader.h"
#include "VulkanTexture.h"
#include "glTFMaterial.h"
#include "glTFNode.h"
#include "glTFPrimitive.h"
#include "glTFSkin.h"
#include "glTFTexture.h"
#include "glm/gtc/matrix_transform.hpp"
#include "renderUniformBufferSet.h"
#include "vulkan/vulkan_core.h"
#include <cmath>
#include <cstddef>
#include <vector>
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#endif
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_STB_IMAGE_WRITE
#endif
// #include "VulkanUtils.hpp"
// #include "assetLoader.h"
@ -270,22 +266,23 @@ void PlumageRender::buildCommandBuffers()
}
boundPipeline = VK_NULL_HANDLE;
std::vector<glTFLoader::glTFNode *> modelNodes = model.getNodes();
// Opaque primitives first
for (auto node : model.nodes)
for (auto node : modelNodes)
{
renderNode(node, i, glTFModel::Material::ALPHAMODE_OPAQUE);
renderNode(node, i, glTFLoader::ALPHAMODE_OPAQUE);
}
// Alpha masked primitives
for (auto node : model.nodes)
for (auto node : modelNodes)
{
renderNode(node, i, glTFModel::Material::ALPHAMODE_MASK);
renderNode(node, i, glTFLoader::ALPHAMODE_MASK);
}
// Transparent primitives
// TODO: Correct depth sorting
for (auto node : model.nodes)
for (auto node : modelNodes)
{
renderNode(node, i, glTFModel::Material::ALPHAMODE_BLEND);
renderNode(node, i, glTFLoader::ALPHAMODE_BLEND);
}
// User interface
@ -381,12 +378,14 @@ void PlumageRender::loadAssets()
loadEnvironment(envMapFile.c_str());
}
void PlumageRender::setupNodeDescriptorSet(glTFModel::Node *node)
void PlumageRender::setupNodeDescriptorSet(glTFLoader::glTFNode *node)
{
/*
This sample uses separate descriptor sets (and layouts) for the matrices and materials (textures)
*/
if (node->mesh)
glTFLoader::glTFMesh *mesh = node->getMesh();
if (mesh)
{
VkDescriptorSetAllocateInfo descriptorSetAllocInfo{};
descriptorSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
@ -394,19 +393,21 @@ void PlumageRender::setupNodeDescriptorSet(glTFModel::Node *node)
VkDescriptorSetLayout nodeDescriptorSetLayout = m_descriptorSetLayoutList.getNode();
descriptorSetAllocInfo.pSetLayouts = &nodeDescriptorSetLayout;
descriptorSetAllocInfo.descriptorSetCount = 1;
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &node->mesh->uniformBuffer.descriptorSet));
VkDescriptorSet descriptorSet = mesh->getUniformBuffer().descriptorSet;
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSet));
VkWriteDescriptorSet writeDescriptorSet{};
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writeDescriptorSet.descriptorCount = 1;
writeDescriptorSet.dstSet = node->mesh->uniformBuffer.descriptorSet;
writeDescriptorSet.dstSet = mesh->getUniformBuffer().descriptorSet;
writeDescriptorSet.dstBinding = 0;
writeDescriptorSet.pBufferInfo = &node->mesh->uniformBuffer.descriptor;
VkDescriptorBufferInfo descriptor = mesh->getUniformBuffer().descriptor;
writeDescriptorSet.pBufferInfo = &descriptor;
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
}
for (auto &child : node->children)
for (auto &child : node->getChildren())
{
setupNodeDescriptorSet(child);
}
@ -424,17 +425,21 @@ void PlumageRender::setupDescriptors()
// Environment samplers (radiance, irradiance, brdflut)
imageSamplerCount += 3;
std::vector<glTFModel::Model *> modellist = {&m_sceneModel.getSkyBox(), &m_sceneModel.getScene()};
std::vector<glTFLoader::glTFMainModel *> modellist = {&m_sceneModel.getSkyBox(), &m_sceneModel.getScene()};
for (auto &model : modellist)
{
for (auto &material : model->materials)
std::vector<glTFLoader::glTFMaterial> materials = model->getMaterials();
for (auto &material : materials)
{
imageSamplerCount += 5;
materialCount++;
}
for (auto node : model->linearNodes)
std::vector<glTFLoader::glTFNode *> linearNodes = model->getLinearNodes();
for (auto node : linearNodes)
{
if (node->mesh)
if (node->getMesh())
{
meshCount++;
}
@ -542,7 +547,7 @@ void PlumageRender::setupDescriptors()
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &materialDescriptorSetLayout));
// Per-Material descriptor sets
for (auto &material : m_sceneModel.getScene().materials)
for (auto &material : m_sceneModel.getScene().getMaterials())
{
VkDescriptorSetAllocateInfo descriptorSetAllocInfo{};
descriptorSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
@ -550,36 +555,70 @@ void PlumageRender::setupDescriptors()
VkDescriptorSetLayout materialDescriptorSetLayout = m_descriptorSetLayoutList.getMaterial();
descriptorSetAllocInfo.pSetLayouts = &materialDescriptorSetLayout;
descriptorSetAllocInfo.descriptorSetCount = 1;
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &material.descriptorSet));
VkDescriptorSet materialDescriptorSet = material.getDescriptorSet();
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &materialDescriptorSet));
VkDescriptorImageInfo emptyTexDescriptor = m_sceneTextures.getEmpty().descriptor;
std::vector<VkDescriptorImageInfo> imageDescriptors = {
emptyTexDescriptor,
emptyTexDescriptor,
material.normalTexture ? material.normalTexture->descriptor : emptyTexDescriptor,
material.occlusionTexture ? material.occlusionTexture->descriptor : emptyTexDescriptor,
material.emissiveTexture ? material.emissiveTexture->descriptor : emptyTexDescriptor};
std::vector<VkDescriptorImageInfo> imageDescriptors(5);
imageDescriptors[0] = emptyTexDescriptor;
imageDescriptors[1] = emptyTexDescriptor;
if (material.pbrWorkflows.metallicRoughness)
// 法线贴图
glTFLoader::glTFTexture *normalTexture = material.getPbrBaseTexture()->getNormalTexture();
if (normalTexture)
{
if (material.baseColorTexture)
{
imageDescriptors[0] = material.baseColorTexture->descriptor;
imageDescriptors[2] = normalTexture->getDescriptor();
}
if (material.metallicRoughnessTexture)
else
{
imageDescriptors[1] = material.metallicRoughnessTexture->descriptor;
}
imageDescriptors[2] = emptyTexDescriptor;
}
if (material.pbrWorkflows.specularGlossiness)
glTFLoader::glTFTexture *occlusionTexture = material.getPbrBaseTexture()->getOcclusionTexture();
// 遮蔽贴图
if (occlusionTexture)
{
if (material.extension.diffuseTexture)
{
imageDescriptors[0] = material.extension.diffuseTexture->descriptor;
imageDescriptors[3] = occlusionTexture->getDescriptor();
}
if (material.extension.specularGlossinessTexture)
else
{
imageDescriptors[1] = material.extension.specularGlossinessTexture->descriptor;
imageDescriptors[3] = emptyTexDescriptor;
}
glTFLoader::glTFTexture *emissiveTexture = material.getPbrBaseTexture()->getEmissiveTexture();
// 自发光贴图
if (emissiveTexture)
{
imageDescriptors[4] = emissiveTexture->getDescriptor();
}
else
{
imageDescriptors[4] = emptyTexDescriptor;
}
bool metallicRoughness = material.getPbrWorkFlow()->getMetallicRoughness();
if (metallicRoughness)
{
glTFLoader::glTFTexture *baseColorTexture = material.getPbrBaseTexture()->getBaseColorTexture();
if (baseColorTexture)
{
imageDescriptors[0] = baseColorTexture->getDescriptor();
}
glTFLoader::glTFTexture *metallicRoughnessTexture = material.getPbrBaseTexture()->getMetalicRoughnessTexture();
if (metallicRoughnessTexture)
{
imageDescriptors[1] = metallicRoughnessTexture->getDescriptor();
}
}
bool specularGlossiness = material.getPbrWorkFlow()->getSpecularGlossiness();
if (specularGlossiness)
{
glTFLoader::glTFTexture *diffuseTexture = material.getTextureExtension()->getDiffuseTexture();
if (diffuseTexture)
{
imageDescriptors[0] = diffuseTexture->getDescriptor();
}
glTFLoader::glTFTexture *specularGlossinessTexture = material.getTextureExtension()->getSpecularGlossinessTexture();
if (specularGlossinessTexture)
{
imageDescriptors[1] = specularGlossinessTexture->getDescriptor();
}
}
@ -589,7 +628,7 @@ void PlumageRender::setupDescriptors()
writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeDescriptorSets[i].descriptorCount = 1;
writeDescriptorSets[i].dstSet = material.descriptorSet;
writeDescriptorSets[i].dstSet = material.getDescriptorSet();
writeDescriptorSets[i].dstBinding = static_cast<uint32_t>(i);
writeDescriptorSets[i].pImageInfo = &imageDescriptors[i];
}
@ -610,7 +649,7 @@ void PlumageRender::setupDescriptors()
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &nodeDescriptorSetLayout));
// Per-Node descriptor set
for (auto &node : m_sceneModel.getScene().nodes)
for (auto &node : m_sceneModel.getScene().getNodes())
{
setupNodeDescriptorSet(node);
}
@ -723,7 +762,7 @@ void PlumageRender::preparePipelines()
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
// Vertex bindings an attributes
VkVertexInputBindingDescription vertexInputBinding = {0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputBindingDescription vertexInputBinding = {0, sizeof(glTFLoader::Vertex), VK_VERTEX_INPUT_RATE_VERTEX};
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
{0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0},
{1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3},
@ -1116,7 +1155,7 @@ void PlumageRender::generateCubemaps()
dynamicStateCI.dynamicStateCount = static_cast<uint32_t>(dynamicStateEnables.size());
// Vertex input state
VkVertexInputBindingDescription vertexInputBinding = {0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputBindingDescription vertexInputBinding = {0, sizeof(glTFLoader::Vertex), VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputAttributeDescription vertexInputAttribute = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0};
VkPipelineVertexInputStateCreateInfo vertexInputStateCI{};
@ -1644,13 +1683,13 @@ void PlumageRender::updateUniformBuffers()
// Scene
m_shaderDataScene.setProjection(camera.matrices.perspective);
m_shaderDataScene.setView(camera.matrices.view);
glTFModel::Model &models = m_sceneModel.getScene();
float modelSize = std::max(models.aabb[0][0], std::max(models.aabb[1][1], models.aabb[2][2]));
glTFLoader::glTFMainModel &models = m_sceneModel.getScene();
glm::mat4 aabb = models.getAABB();
float modelSize = std::max(aabb[0][0], std::max(aabb[1][1], aabb[2][2]));
// Center and scale model
float scale = (1.0f / modelSize) * 0.5f;
glm::vec3 translate = -glm::vec3(models.aabb[3][0], models.aabb[3][1], models.aabb[3][2]);
translate += -0.5f * glm::vec3(models.aabb[0][0], models.aabb[1][1], models.aabb[2][2]);
glm::vec3 translate = -glm::vec3(aabb[3][0], aabb[3][1], aabb[3][2]);
translate += -0.5f * glm::vec3(aabb[0][0], aabb[1][1], aabb[2][2]);
// camera.setPosition(glm::vec3(0, 0, -modelSize - 2));
@ -2196,12 +2235,14 @@ void PlumageRender::render()
modelrot -= 360.0f;
}
}
if ((animate) && (m_sceneModel.getScene().animations.size() > 0))
std::vector<glTFLoader::glTFAnimation> animations = m_sceneModel.getScene().getAnimations();
if ((animate) && (animations.size()))
{
animationTimer += frameTimer;
if (animationTimer > m_sceneModel.getScene().animations[animationIndex].end)
glTFLoader::glTFAnimation currentAnimation = animations.at(animationIndex);
if (animationTimer > currentAnimation.getEnd())
{
animationTimer -= m_sceneModel.getScene().animations[animationIndex].end;
animationTimer -= currentAnimation.getEnd();
}
m_sceneModel.getScene().updateAnimation(animationIndex, animationTimer);
}
@ -2357,7 +2398,8 @@ void PlumageRender::updateUIOverlay()
}
if (gui->beginMenu(m_localizationStrings.getMenuAnimation()))
{
if (m_sceneModel.getScene().animations.size() > 0)
std::vector<glTFLoader::glTFAnimation> animations = m_sceneModel.getScene().getAnimations();
if (animations.size())
{
if (gui->beginMenu(m_localizationStrings.getMenuAnimationActivation()))
{
@ -2367,9 +2409,9 @@ void PlumageRender::updateUIOverlay()
if (gui->beginMenu(m_localizationStrings.getMenuAnimationAnimationSequence()))
{
std::vector<std::string> animationNames;
for (auto animation : m_sceneModel.getScene().animations)
for (auto animation : animations)
{
animationNames.push_back(animation.name);
animationNames.push_back(animation.getName());
}
gui->combo(m_localizationStrings.getAnimationSeq(), &animationIndex, animationNames);
gui->endMenu();

View File

@ -6,6 +6,7 @@
#include "RenderPipelineList.h"
#include "RenderSceneTextures.h"
#include "glTFMaterial.h"
#include "glTFNode.h"
#include "glTFSkin.h"
#include "renderShaderData.h"
#if defined(_WIN32)
@ -36,7 +37,7 @@
#include <sys/stat.h>
#include "VulkanExampleBase.h"
#include "glTFModel.h"
#include "ui.hpp"
#include <VulkanTexture.h>
#include <vulkan/vulkan.h>
@ -56,7 +57,7 @@
#include "RenderPipelineList.h"
#include "RenderSceneTextures.h"
#include "SceneUBOMatrices.h"
#include "ShaderLoader.h"
#include "SkyboxUBOMatrices.h"
#include "VertexStagingBuffer.h"
#include "renderEffectState.h"
@ -191,7 +192,7 @@ public:
void loadEnvironment(std::string filename);
void buildCommandBuffers();
void loadAssets();
void setupNodeDescriptorSet(glTFModel::Node *node);
void setupNodeDescriptorSet(glTFLoader::glTFNode *node);
void setupDescriptors();
void preparePipelines();
// void tonemappingPipelin();

View File

@ -1,4 +1,4 @@
#include "renderStagingBuffer.h"
#include "RenderStagingBuffer.h"
// Getter method definitions
VkBuffer RenderStagingBuffer::getBuffer() const