diff --git a/base/vulkanMeshLoader.hpp b/base/vulkanMeshLoader.hpp index 7266a6f9..baca16be 100644 --- a/base/vulkanMeshLoader.hpp +++ b/base/vulkanMeshLoader.hpp @@ -31,6 +31,7 @@ #include #include +#include #include "vulkandevice.hpp" @@ -58,15 +59,25 @@ namespace vkMeshLoader size_t size = 0; }; + /** @brief Stores a mesh's vertex and index descriptions */ + struct MeshDescriptor + { + uint32_t vertexCount; + uint32_t indexBase; + uint32_t indexCount; + }; + + /** @brief Mesh representation storing all data required to generate buffers */ struct MeshBuffer { + std::vector meshDescriptors; MeshBufferInfo vertices; MeshBufferInfo indices; uint32_t indexCount; glm::vec3 dim; }; - // Used to set parameters upon mesh creation + /** @brief Holds parameters for mesh creation */ struct MeshCreateInfo { glm::vec3 center; @@ -74,7 +85,13 @@ namespace vkMeshLoader glm::vec2 uvscale; }; - // Get vertex size from vertex layout + /** + * Get the size of a vertex layout + * + * @param layout VertexLayout to get the size for + * + * @return Size of the vertex layout in bytes + */ static uint32_t vertexSize(std::vector layout) { uint32_t vSize = 0; @@ -93,8 +110,16 @@ namespace vkMeshLoader return vSize; } - // Generate vertex attribute descriptions for a layout at the given binding point // Note: Always assumes float formats + /** + * Generate vertex attribute descriptions for a layout at the given binding point + * + * @param layout VertexLayout from which to generate the descriptions + * @param attributeDescriptions Refernce to a vector of the descriptions to generate + * @param binding Index of the attribute description binding point + * + * @note Always assumes float formats + */ static void getVertexInputAttributeDescriptions(std::vector layout, std::vector &attributeDescriptions, uint32_t binding) { uint32_t offset = 0; @@ -208,6 +233,8 @@ class VulkanMeshLoader private: vk::VulkanDevice *vulkanDevice; + static const int defaultFlags = aiProcess_FlipWindingOrder | aiProcess_Triangulate | aiProcess_PreTransformVertices | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals; + struct Vertex { glm::vec3 m_pos; @@ -254,48 +281,39 @@ public: uint32_t numVertices = 0; - // Optional - struct - { - VkBuffer buf; - VkDeviceMemory mem; - } vertexBuffer; - - struct { - VkBuffer buf; - VkDeviceMemory mem; - uint32_t count; - } indexBuffer; - - VkPipelineVertexInputStateCreateInfo vi; - std::vector bindingDescriptions; - std::vector attributeDescriptions; - VkPipeline pipeline; - Assimp::Importer Importer; const aiScene* pScene; + /** + * Default constructor + * + * @param vulkanDevice Pointer to a valid VulkanDevice + */ VulkanMeshLoader(vk::VulkanDevice *vulkanDevice) { assert(vulkanDevice != nullptr); this->vulkanDevice = vulkanDevice; } + /** + * Default destructor + * + * @note Does not free any Vulkan resources + */ ~VulkanMeshLoader() { m_Entries.clear(); } - // Loads the mesh with some default flags - bool LoadMesh(const std::string& filename) - { - int flags = aiProcess_FlipWindingOrder | aiProcess_Triangulate | aiProcess_PreTransformVertices | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals; - - return LoadMesh(filename, flags); - } - - // Load the mesh with custom flags - bool LoadMesh(const std::string& filename, int flags) + /** + * Load a scene from a supported 3D file format + * + * @param filename Name of the file (or asset) to load + * @param flags (Optional) Set of ASSIMP processing flags + * + * @return Returns true if the scene has been loaded + */ + bool LoadMesh(const std::string& filename, int flags = defaultFlags) { #if defined(__ANDROID__) // Meshes are stored inside the apk on Android (compressed) @@ -320,7 +338,17 @@ public: if (pScene) { - return InitFromScene(pScene, filename); + m_Entries.clear(); + m_Entries.resize(pScene->mNumMeshes); + // Read in all meshes in the scene + for (auto i = 0; i < m_Entries.size(); i++) + { + m_Entries[i].vertexBase = numVertices; + numVertices += pScene->mMeshes[i]->mNumVertices; + const aiMesh* paiMesh = pScene->mMeshes[i]; + InitMesh(&m_Entries[i], paiMesh, pScene); + } + return true; } else { @@ -332,58 +360,39 @@ public: } } - bool InitFromScene(const aiScene* pScene, const std::string& Filename) + /** + * Read mesh data from ASSIMP mesh to an internal mesh representation that can be used to generate Vulkan buffers + * + * @param meshEntry Pointer to the target MeshEntry strucutre for the mesh data + * @param paiMesh ASSIMP mesh to get the data from + * @param pScene Scene file of the ASSIMP mesh + */ + void InitMesh(MeshEntry *meshEntry, const aiMesh* paiMesh, const aiScene* pScene) { - m_Entries.resize(pScene->mNumMeshes); - - // Counters - for (unsigned int i = 0; i < m_Entries.size(); i++) - { - m_Entries[i].vertexBase = numVertices; - numVertices += pScene->mMeshes[i]->mNumVertices; - } - - // Initialize the meshes in the scene one by one - for (unsigned int i = 0; i < m_Entries.size(); i++) - { - const aiMesh* paiMesh = pScene->mMeshes[i]; - InitMesh(i, paiMesh, pScene); - } - - return true; - } - - void InitMesh(unsigned int index, const aiMesh* paiMesh, const aiScene* pScene) - { - m_Entries[index].MaterialIndex = paiMesh->mMaterialIndex; + meshEntry->MaterialIndex = paiMesh->mMaterialIndex; aiColor3D pColor(0.f, 0.f, 0.f); pScene->mMaterials[paiMesh->mMaterialIndex]->Get(AI_MATKEY_COLOR_DIFFUSE, pColor); aiVector3D Zero3D(0.0f, 0.0f, 0.0f); - for (unsigned int i = 0; i < paiMesh->mNumVertices; i++) { + for (unsigned int i = 0; i < paiMesh->mNumVertices; i++) + { aiVector3D* pPos = &(paiMesh->mVertices[i]); aiVector3D* pNormal = &(paiMesh->mNormals[i]); - aiVector3D *pTexCoord; - if (paiMesh->HasTextureCoords(0)) - { - pTexCoord = &(paiMesh->mTextureCoords[0][i]); - } - else { - pTexCoord = &Zero3D; - } + aiVector3D* pTexCoord = (paiMesh->HasTextureCoords(0)) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D; aiVector3D* pTangent = (paiMesh->HasTangentsAndBitangents()) ? &(paiMesh->mTangents[i]) : &Zero3D; aiVector3D* pBiTangent = (paiMesh->HasTangentsAndBitangents()) ? &(paiMesh->mBitangents[i]) : &Zero3D; - Vertex v(glm::vec3(pPos->x, -pPos->y, pPos->z), + Vertex v( + glm::vec3(pPos->x, -pPos->y, pPos->z), glm::vec2(pTexCoord->x , pTexCoord->y), glm::vec3(pNormal->x, pNormal->y, pNormal->z), glm::vec3(pTangent->x, pTangent->y, pTangent->z), glm::vec3(pBiTangent->x, pBiTangent->y, pBiTangent->z), glm::vec3(pColor.r, pColor.g, pColor.b) ); - + dim.max.x = fmax(pPos->x, dim.max.x); dim.max.y = fmax(pPos->y, dim.max.y); dim.max.z = fmax(pPos->z, dim.max.z); @@ -392,39 +401,28 @@ public: dim.min.y = fmin(pPos->y, dim.min.y); dim.min.z = fmin(pPos->z, dim.min.z); - m_Entries[index].Vertices.push_back(v); + meshEntry->Vertices.push_back(v); } dim.size = dim.max - dim.min; - for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) + uint32_t indexBase = static_cast(meshEntry->Indices.size()); + for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) { const aiFace& Face = paiMesh->mFaces[i]; if (Face.mNumIndices != 3) continue; - m_Entries[index].Indices.push_back(Face.mIndices[0]); - m_Entries[index].Indices.push_back(Face.mIndices[1]); - m_Entries[index].Indices.push_back(Face.mIndices[2]); + meshEntry->Indices.push_back(indexBase + Face.mIndices[0]); + meshEntry->Indices.push_back(indexBase + Face.mIndices[1]); + meshEntry->Indices.push_back(indexBase + Face.mIndices[2]); } } - /** - * Free up all Vulkan resources used by a mesh - */ - static void freeVulkanResources(VkDevice device, VulkanMeshLoader *mesh) - { - vkDestroyBuffer(device, mesh->vertexBuffer.buf, nullptr); - vkFreeMemory(device, mesh->vertexBuffer.mem, nullptr); - vkDestroyBuffer(device, mesh->indexBuffer.buf, nullptr); - vkFreeMemory(device, mesh->indexBuffer.mem, nullptr); - } - - // Create vertex and index buffer with given layout - // Note : Only does staging if a valid command buffer and transfer queue are passed - /** * Create Vulkan buffers for the index and vertex buffer using a vertex layout * + * @note Only does staging if a valid command buffer and transfer queue are passed + * * @param meshBuffer Pointer to the mesh buffer containing buffer handles and memory * @param layout Vertex layout for the vertex buffer * @param createInfo Structure containing information for mesh creation time (center, scaling, etc.) @@ -529,15 +527,19 @@ public: std::vector indexBuffer; for (uint32_t m = 0; m < m_Entries.size(); m++) { - uint32_t indexBase = (uint32_t)indexBuffer.size(); + uint32_t indexBase = static_cast(indexBuffer.size()); for (uint32_t i = 0; i < m_Entries[m].Indices.size(); i++) { indexBuffer.push_back(m_Entries[m].Indices[i] + indexBase); } + vkMeshLoader::MeshDescriptor descriptor{}; + descriptor.indexBase = indexBase; + descriptor.indexCount = static_cast(m_Entries[m].Indices.size()); + descriptor.vertexCount = static_cast(m_Entries[m].Vertices.size()); + meshBuffer->meshDescriptors.push_back(descriptor); } meshBuffer->indices.size = indexBuffer.size() * sizeof(uint32_t); - - meshBuffer->indexCount = (uint32_t)indexBuffer.size(); + meshBuffer->indexCount = static_cast(indexBuffer.size()); // Use staging buffer to move vertex and index buffer to device local memory if (useStaging && copyQueue != VK_NULL_HANDLE && copyCmd != VK_NULL_HANDLE) diff --git a/vulkanscene/vulkanscene.cpp b/vulkanscene/vulkanscene.cpp index 0eb9cd63..1622ad39 100644 --- a/vulkanscene/vulkanscene.cpp +++ b/vulkanscene/vulkanscene.cpp @@ -32,22 +32,38 @@ class VulkanExample : public VulkanExampleBase { public: + struct DemoMesh + { + vk::Buffer vertexBuffer; + vk::Buffer indexBuffer; + uint32_t indexCount; + VkPipeline *pipeline; + + void draw(VkCommandBuffer cmdBuffer) + { + VkDeviceSize offsets[1] = { 0 }; + vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + vkCmdBindVertexBuffers(cmdBuffer, VERTEX_BUFFER_BIND_ID, 1, &vertexBuffer.buffer, offsets); + vkCmdBindIndexBuffer(cmdBuffer, indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(cmdBuffer, indexCount, 1, 0, 0, 0); + } + }; + struct DemoMeshes { std::vector names{ "logos", "background", "models", "skybox" }; VkPipelineVertexInputStateCreateInfo inputState; std::vector bindingDescriptions; std::vector attributeDescriptions; - VkPipeline pipeline; - VulkanMeshLoader* logos; - VulkanMeshLoader* background; - VulkanMeshLoader* models; - VulkanMeshLoader* skybox; + DemoMesh logos; + DemoMesh background; + DemoMesh models; + DemoMesh skybox; } demoMeshes; - std::vector meshes; + std::vector meshes; struct { - vkTools::UniformData meshVS; + vk::Buffer meshVS; } uniformData; struct { @@ -97,23 +113,15 @@ public: vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - vkTools::destroyUniformData(device, &uniformData.meshVS); + uniformData.meshVS.destroy(); - for (auto& mesh : meshes) + for (auto mesh : meshes) { - vkDestroyBuffer(device, mesh->vertexBuffer.buf, nullptr); - vkFreeMemory(device, mesh->vertexBuffer.mem, nullptr); - - vkDestroyBuffer(device, mesh->indexBuffer.buf, nullptr); - vkFreeMemory(device, mesh->indexBuffer.mem, nullptr); + mesh.vertexBuffer.destroy(); + mesh.indexBuffer.destroy(); } textureLoader->destroyTexture(textures.skybox); - - delete(demoMeshes.logos); - delete(demoMeshes.background); - delete(demoMeshes.models); - delete(demoMeshes.skybox); } void loadTextures() @@ -158,12 +166,9 @@ public: vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); VkDeviceSize offsets[1] = { 0 }; - for (auto& mesh : meshes) + for (auto mesh : meshes) { - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, mesh->pipeline); - vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &mesh->vertexBuffer.buf, offsets); - vkCmdBindIndexBuffer(drawCmdBuffers[i], mesh->indexBuffer.buf, 0, VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed(drawCmdBuffers[i], mesh->indexBuffer.count, 1, 0, 0, 0); + mesh.draw(drawCmdBuffers[i]); } vkCmdEndRenderPass(drawCmdBuffers[i]); @@ -174,154 +179,111 @@ public: void prepareVertices() { - struct Vertex { + struct Vertex + { float pos[3]; float normal[3]; float uv[2]; float color[3]; }; - // Load meshes for demos scene - demoMeshes.logos = new VulkanMeshLoader(vulkanDevice); - demoMeshes.background = new VulkanMeshLoader(vulkanDevice); - demoMeshes.models = new VulkanMeshLoader(vulkanDevice); - demoMeshes.skybox = new VulkanMeshLoader(vulkanDevice); - -#if defined(__ANDROID__) - demoMeshes.logos->assetManager = androidApp->activity->assetManager; - demoMeshes.background->assetManager = androidApp->activity->assetManager; - demoMeshes.models->assetManager = androidApp->activity->assetManager; - demoMeshes.skybox->assetManager = androidApp->activity->assetManager; -#endif - - demoMeshes.logos->LoadMesh(getAssetPath() + "models/vulkanscenelogos.dae"); - demoMeshes.background->LoadMesh(getAssetPath() + "models/vulkanscenebackground.dae"); - demoMeshes.models->LoadMesh(getAssetPath() + "models/vulkanscenemodels.dae"); - demoMeshes.skybox->LoadMesh(getAssetPath() + "models/cube.obj"); - - std::vector meshList; - meshList.push_back(demoMeshes.skybox); // skybox first because of depth writes - meshList.push_back(demoMeshes.logos); - meshList.push_back(demoMeshes.background); - meshList.push_back(demoMeshes.models); - - VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); - VkMemoryRequirements memReqs; + std::vector meshFiles = { "vulkanscenelogos.dae", "vulkanscenebackground.dae", "vulkanscenemodels.dae", "cube.obj" }; + std::vector meshPipelines = { &pipelines.logos, &pipelines.models, &pipelines.models, &pipelines.skybox}; // todo : Use mesh function for loading float scale = 1.0f; - for (auto& mesh : meshList) + for (auto i = 0; i < meshFiles.size(); i++) { + VulkanMeshLoader scene(vulkanDevice); + +#if defined(__ANDROID__) + scene.assetManager = androidApp->activity->assetManager; +#endif + scene.LoadMesh(getAssetPath() + "models/" + meshFiles[i]); + // Generate vertex buffer (pos, normal, uv, color) std::vector vertexBuffer; - for (size_t m = 0; m < mesh->m_Entries.size(); m++) + glm::vec3 offset(0.0f); + // Offset on Y (except skypbox) + if (meshFiles[i] != "cube.obj") { - for (size_t i = 0; i < mesh->m_Entries[m].Vertices.size(); i++) { - glm::vec3 pos = mesh->m_Entries[m].Vertices[i].m_pos * scale; - glm::vec3 normal = mesh->m_Entries[m].Vertices[i].m_normal; - glm::vec2 uv = mesh->m_Entries[m].Vertices[i].m_tex; - glm::vec3 col = mesh->m_Entries[m].Vertices[i].m_color; - Vertex vert = { + offset.y += 1.15f; + } + for (size_t m = 0; m < scene.m_Entries.size(); m++) + { + for (size_t v = 0; v < scene.m_Entries[m].Vertices.size(); v++) + { + glm::vec3 pos = (scene.m_Entries[m].Vertices[v].m_pos + offset) * scale; + glm::vec3 normal = scene.m_Entries[m].Vertices[v].m_normal; + glm::vec2 uv = scene.m_Entries[m].Vertices[v].m_tex; + glm::vec3 col = scene.m_Entries[m].Vertices[v].m_color; + Vertex vert = + { { pos.x, pos.y, pos.z }, { normal.x, -normal.y, normal.z }, { uv.s, uv.t }, { col.r, col.g, col.b } }; - // Offset skybox mesh - // todo : center before export - if (mesh != demoMeshes.skybox) - { - vert.pos[1] += 1.15f; - } - vertexBuffer.push_back(vert); } } std::vector indexBuffer; - for (size_t m = 0; m < mesh->m_Entries.size(); m++) + for (size_t m = 0; m < scene.m_Entries.size(); m++) { int indexBase = indexBuffer.size(); - for (size_t i = 0; i < mesh->m_Entries[m].Indices.size(); i++) { - indexBuffer.push_back(mesh->m_Entries[m].Indices[i] + indexBase); + for (size_t i = 0; i < scene.m_Entries[m].Indices.size(); i++) { + indexBuffer.push_back(scene.m_Entries[m].Indices[i] + indexBase); } } - mesh->indexBuffer.count = static_cast(indexBuffer.size()); + + DemoMesh mesh; + + mesh.indexCount = static_cast(indexBuffer.size()); + mesh.pipeline = meshPipelines[i]; uint32_t vertexBufferSize = static_cast(vertexBuffer.size()) * sizeof(Vertex); uint32_t indexBufferSize = static_cast(indexBuffer.size()) * sizeof(uint32_t); - struct { - VkBuffer buffer; - VkDeviceMemory memory; - } vertexStaging, indexStaging; + vk::Buffer vertexStaging, indexStaging; // Create staging buffers // Vertex data - createBuffer( + vulkanDevice->createBuffer( VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &vertexStaging, vertexBufferSize, - vertexBuffer.data(), - &vertexStaging.buffer, - &vertexStaging.memory); + vertexBuffer.data()); // Index data - createBuffer( + vulkanDevice->createBuffer( VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &indexStaging, indexBufferSize, - indexBuffer.data(), - &indexStaging.buffer, - &indexStaging.memory); + indexBuffer.data()); // Create device local buffers // Vertex buffer - createBuffer( + vulkanDevice->createBuffer( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - vertexBufferSize, - nullptr, - &mesh->vertexBuffer.buf, - &mesh->vertexBuffer.mem); + &mesh.vertexBuffer, + vertexBufferSize); // Index buffer - createBuffer( + vulkanDevice->createBuffer( VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - indexBufferSize, - nullptr, - &mesh->indexBuffer.buf, - &mesh->indexBuffer.mem); + &mesh.indexBuffer, + indexBufferSize); // Copy from staging buffers - VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + vulkanDevice->copyBuffer(&vertexStaging, &mesh.vertexBuffer, queue); + vulkanDevice->copyBuffer(&indexStaging, &mesh.indexBuffer, queue); - VkBufferCopy copyRegion = {}; - - copyRegion.size = vertexBufferSize; - vkCmdCopyBuffer( - copyCmd, - vertexStaging.buffer, - mesh->vertexBuffer.buf, - 1, - ©Region); - - copyRegion.size = indexBufferSize; - vkCmdCopyBuffer( - copyCmd, - indexStaging.buffer, - mesh->indexBuffer.buf, - 1, - ©Region); - - VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); - - vkDestroyBuffer(device, vertexStaging.buffer, nullptr); - vkFreeMemory(device, vertexStaging.memory, nullptr); - vkDestroyBuffer(device, indexStaging.buffer, nullptr); - vkFreeMemory(device, indexStaging.memory, nullptr); - - // todo : staging + vertexStaging.destroy(); + indexStaging.destroy(); meshes.push_back(mesh); } @@ -342,28 +304,28 @@ public: VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, - 0); + offsetof(Vertex, pos)); // Location 1 : Normal demoMeshes.attributeDescriptions[1] = vkTools::initializers::vertexInputAttributeDescription( VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, - sizeof(float) * 3); + offsetof(Vertex, normal)); // Location 2 : Texture coordinates demoMeshes.attributeDescriptions[2] = vkTools::initializers::vertexInputAttributeDescription( VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32G32_SFLOAT, - sizeof(float) * 6); + offsetof(Vertex, uv)); // Location 3 : Color demoMeshes.attributeDescriptions[3] = vkTools::initializers::vertexInputAttributeDescription( VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32G32B32_SFLOAT, - sizeof(float) * 8); + offsetof(Vertex, color)); demoMeshes.inputState = vkTools::initializers::pipelineVertexInputStateCreateInfo(); demoMeshes.inputState.vertexBindingDescriptionCount = demoMeshes.bindingDescriptions.size(); @@ -542,26 +504,16 @@ public: shaderStages[0] = loadShader(getAssetPath() + "shaders/vulkanscene/skybox.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/vulkanscene/skybox.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.skybox)); - - // Assign pipelines - demoMeshes.logos->pipeline = pipelines.logos; - demoMeshes.models->pipeline = pipelines.models; - demoMeshes.background->pipeline = pipelines.models; - demoMeshes.skybox->pipeline = pipelines.skybox; } // Prepare and initialize uniform buffer containing shader uniforms void prepareUniformBuffers() { - // Vertex shader uniform buffer block - createBuffer( + vulkanDevice->createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - sizeof(uboVS), - &uboVS, - &uniformData.meshVS.buffer, - &uniformData.meshVS.memory, - &uniformData.meshVS.descriptor); + &uniformData.meshVS, + sizeof(uboVS)); updateUniformBuffers(); } @@ -585,10 +537,9 @@ public: uboVS.lightPos = lightPos; - uint8_t *pData; - VK_CHECK_RESULT(vkMapMemory(device, uniformData.meshVS.memory, 0, sizeof(uboVS), 0, (void **)&pData)); - memcpy(pData, &uboVS, sizeof(uboVS)); - vkUnmapMemory(device, uniformData.meshVS.memory); + VK_CHECK_RESULT(uniformData.meshVS.map()); + memcpy(uniformData.meshVS.mapped, &uboVS, sizeof(uboVS)); + uniformData.meshVS.unmap(); } void draw() @@ -630,63 +581,4 @@ public: }; -VulkanExample *vulkanExample; - -#if defined(_WIN32) -LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (vulkanExample != NULL) - { - vulkanExample->handleMessages(hWnd, uMsg, wParam, lParam); - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} -#elif defined(__linux__) && !defined(__ANDROID__) -static void handleEvent(const xcb_generic_event_t *event) -{ - if (vulkanExample != NULL) - { - vulkanExample->handleEvent(event); -} - } -#endif - -// Main entry point -#if defined(_WIN32) -// Windows entry point -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) -#elif defined(__ANDROID__) -// Android entry point -void android_main(android_app* state) -#elif defined(__linux__) -// Linux entry point -int main(const int argc, const char *argv[]) -#endif -{ -#if defined(__ANDROID__) - // Removing this may cause the compiler to omit the main entry point - // which would make the application crash at start - app_dummy(); -#endif - vulkanExample = new VulkanExample(); -#if defined(_WIN32) - vulkanExample->setupWindow(hInstance, WndProc); -#elif defined(__ANDROID__) - // Attach vulkan example to global android application state - state->userData = vulkanExample; - state->onAppCmd = VulkanExample::handleAppCommand; - state->onInputEvent = VulkanExample::handleAppInput; - vulkanExample->androidApp = state; -#elif defined(__linux__) - vulkanExample->setupWindow(); -#endif -#if !defined(__ANDROID__) - vulkanExample->initSwapchain(); - vulkanExample->prepare(); -#endif - vulkanExample->renderLoop(); - delete(vulkanExample); -#if !defined(__ANDROID__) - return 0; -#endif -} \ No newline at end of file +VULKAN_EXAMPLE_MAIN() \ No newline at end of file