procedural-3d-engine/examples/vertexattributes/vertexattributes.h

145 lines
3.4 KiB
C
Raw Normal View History

/*
* Vulkan Example - Passing vertex attributes using interleaved and separate buffers
*
* Copyright (C) 2022 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_STB_IMAGE
#define TINYGLTF_NO_EXTERNAL_IMAGE
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
#endif
#include "tiny_gltf.h"
#include "vulkanexamplebase.h"
#define ENABLE_VALIDATION false
struct PushConstBlock {
glm::mat4 nodeMatrix;
uint32_t alphaMask;
float alphaMaskCutoff;
};
struct Material {
glm::vec4 baseColorFactor = glm::vec4(1.0f);
uint32_t baseColorTextureIndex;
uint32_t normalTextureIndex;
std::string alphaMode = "OPAQUE";
float alphaCutOff;
VkDescriptorSet descriptorSet;
};
struct Image {
vks::Texture2D texture;
};
struct Texture {
int32_t imageIndex;
};
// Layout for the interleaved vertex attributes
struct Vertex {
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv;
glm::vec4 tangent;
};
struct Primitive {
uint32_t firstIndex;
uint32_t indexCount;
int32_t materialIndex;
};
struct Mesh {
std::vector<Primitive> primitives;
};
struct Node;
struct Node {
Node* parent;
std::vector<Node> children;
Mesh mesh;
glm::mat4 matrix;
};
std::vector<Node> nodes;
class VulkanExample : public VulkanExampleBase
{
public:
enum VertexAttributeSettings { interleaved, separate };
VertexAttributeSettings vertexAttributeSettings = separate;
2022-01-21 21:07:16 +01:00
// Used to store indices and vertices from glTF to be uploaded to the GPU
std::vector<uint32_t> indexBuffer;
std::vector<Vertex> vertexBuffer;
2022-01-21 21:07:16 +01:00
struct VertexAttributes {
std::vector<glm::vec2> uv;
std::vector<glm::vec3> pos, normal;
std::vector<glm::vec4> tangent;
} vertexAttributeBuffers;
// Buffers for the separate vertex attributes
// @todo: rename
2022-01-21 09:59:30 +01:00
struct SeparateVertexBuffers {
vks::Buffer pos, normal, uv, tangent;
2022-01-21 09:59:30 +01:00
} separateVertexBuffers;
// Single vertex buffer for all primitives
vks::Buffer interleavedVertexBuffer;
// Index buffer for all primitives of the scene
vks::Buffer indices;
struct ShaderData {
vks::Buffer buffer;
struct Values {
glm::mat4 projection;
glm::mat4 view;
glm::vec4 lightPos = glm::vec4(0.0f, 2.5f, 0.0f, 1.0f);
glm::vec4 viewPos;
} values;
} shaderData;
struct Pipelines {
VkPipeline vertexAttributesInterleaved;
VkPipeline vertexAttributesSeparate;
} pipelines;
VkPipelineLayout pipelineLayout;
struct DescriptorSetLayouts {
VkDescriptorSetLayout matrices;
VkDescriptorSetLayout textures;
} descriptorSetLayouts;
VkDescriptorSet descriptorSet;
struct Scene {
std::vector<Image> images;
std::vector<Texture> textures;
std::vector<Material> materials;
} scene;
VulkanExample();
~VulkanExample();
virtual void getEnabledFeatures();
void buildCommandBuffers();
void uploadVertexData();
void loadglTFFile(std::string filename);
void loadAssets();
void setupDescriptors();
void preparePipelines();
void prepareUniformBuffers();
void updateUniformBuffers();
void prepare();
2022-01-21 21:07:16 +01:00
void loadSceneNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, Node* parent);
void drawSceneNode(VkCommandBuffer commandBuffer, Node node);
virtual void render();
virtual void viewChanged();
virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay);
};