Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用vkQueueSubmit时,是什么导致VK_错误_设备_丢失的? 我正在使用C++在Vulkan中使用体素引擎。大多数样板代码在很大程度上基于。我有一个画框功能,看起来像这样 void drawFrame(float dt) { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); uint32_t imageIndex; VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); updateUniformBuffer(imageIndex, dt); if (result == VK_ERROR_OUT_OF_DATE_KHR) { recreateSwapChain(); return; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { throw std::runtime_error("failed to acquire swap chain image!"); } // Check if a previous frame is using this image (i.e.there is its fence to wait on) if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) { vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX); } // Mark the image as now being in use by this frame imagesInFlight[imageIndex] = inFlightFences[currentFrame]; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffers[imageIndex]; VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; vkResetFences(device, 1, &inFlightFences[currentFrame]); result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); if (result != VK_SUCCESS) { throw std::runtime_error("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR swapChains[] = { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = nullptr; // Optional result = vkQueuePresentKHR(presentQueue, &presentInfo); if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) { framebufferResized = false; recreateSwapChain(); } else if (result != VK_SUCCESS) { throw std::runtime_error("failed to present swap chain image!"); } // Increment the frame. By using the modulo(%) operator, we ensure that the frame index loops around after every MAX_FRAMES_IN_FLIGHT enqueued frames. currentFrame = (currentFrame + 1) % config->maxFramesInFlight; } void createVertexAndIndexBuffer() { for (size_t x = 0; x < 100; x++) { for (size_t y = 0; y < 4; y++) { for (size_t z = 0; z < 100; z++) { // for each block in the world vector auto blockId = world.getBlock(x, y, z); if (blockId == BlockId::Air) { continue; } Vec3 blockPosition = { x, y, z }; // get its data auto verts = blockdb.blockDataFor(blockId).getVertices(); auto inds = blockdb.blockDataFor(blockId).getIndices(); // account for the block position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos += blockPosition; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); } void createVertexAndIndexBuffer() { // set bounds of how far out to render based on what chunk the player is in Vec2XZ playerChunkCoords = { floor(player.position.x) / CHUNK_WIDTH, floor(player.position.z) / CHUNK_WIDTH }; Vec2XZ lowChunkXZ = { playerChunkCoords.x - renderDistance, playerChunkCoords.z - renderDistance }; Vec2XZ highChunkXZ = { playerChunkCoords.x + renderDistance, playerChunkCoords.z + renderDistance }; // for each chunk around the player within render distance for (int x = lowChunkXZ.x; x < highChunkXZ.x; x++) { for (int z = lowChunkXZ.z; z < highChunkXZ.z; z++) { // get the chunk Chunk* chunk = &world.getChunk(x, z); // load it if it isnt already if (!chunk->isLoaded) { chunk->load(); } // generate its geometry if it doesnt already exist if (chunk->vertices.size() == 0 || chunk->indices.size() == 0) { chunk->generateVerticesAndIndices(); } auto verts = chunk->vertices; auto inds = chunk->indices; // account for the chunk position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos.x += x * CHUNK_WIDTH; v.pos.z += z * CHUNK_WIDTH; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); }_C++_Vulkan_Voxel - Fatal编程技术网

调用vkQueueSubmit时,是什么导致VK_错误_设备_丢失的? 我正在使用C++在Vulkan中使用体素引擎。大多数样板代码在很大程度上基于。我有一个画框功能,看起来像这样 void drawFrame(float dt) { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); uint32_t imageIndex; VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); updateUniformBuffer(imageIndex, dt); if (result == VK_ERROR_OUT_OF_DATE_KHR) { recreateSwapChain(); return; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { throw std::runtime_error("failed to acquire swap chain image!"); } // Check if a previous frame is using this image (i.e.there is its fence to wait on) if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) { vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX); } // Mark the image as now being in use by this frame imagesInFlight[imageIndex] = inFlightFences[currentFrame]; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffers[imageIndex]; VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; vkResetFences(device, 1, &inFlightFences[currentFrame]); result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); if (result != VK_SUCCESS) { throw std::runtime_error("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR swapChains[] = { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = nullptr; // Optional result = vkQueuePresentKHR(presentQueue, &presentInfo); if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) { framebufferResized = false; recreateSwapChain(); } else if (result != VK_SUCCESS) { throw std::runtime_error("failed to present swap chain image!"); } // Increment the frame. By using the modulo(%) operator, we ensure that the frame index loops around after every MAX_FRAMES_IN_FLIGHT enqueued frames. currentFrame = (currentFrame + 1) % config->maxFramesInFlight; } void createVertexAndIndexBuffer() { for (size_t x = 0; x < 100; x++) { for (size_t y = 0; y < 4; y++) { for (size_t z = 0; z < 100; z++) { // for each block in the world vector auto blockId = world.getBlock(x, y, z); if (blockId == BlockId::Air) { continue; } Vec3 blockPosition = { x, y, z }; // get its data auto verts = blockdb.blockDataFor(blockId).getVertices(); auto inds = blockdb.blockDataFor(blockId).getIndices(); // account for the block position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos += blockPosition; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); } void createVertexAndIndexBuffer() { // set bounds of how far out to render based on what chunk the player is in Vec2XZ playerChunkCoords = { floor(player.position.x) / CHUNK_WIDTH, floor(player.position.z) / CHUNK_WIDTH }; Vec2XZ lowChunkXZ = { playerChunkCoords.x - renderDistance, playerChunkCoords.z - renderDistance }; Vec2XZ highChunkXZ = { playerChunkCoords.x + renderDistance, playerChunkCoords.z + renderDistance }; // for each chunk around the player within render distance for (int x = lowChunkXZ.x; x < highChunkXZ.x; x++) { for (int z = lowChunkXZ.z; z < highChunkXZ.z; z++) { // get the chunk Chunk* chunk = &world.getChunk(x, z); // load it if it isnt already if (!chunk->isLoaded) { chunk->load(); } // generate its geometry if it doesnt already exist if (chunk->vertices.size() == 0 || chunk->indices.size() == 0) { chunk->generateVerticesAndIndices(); } auto verts = chunk->vertices; auto inds = chunk->indices; // account for the chunk position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos.x += x * CHUNK_WIDTH; v.pos.z += z * CHUNK_WIDTH; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); }

调用vkQueueSubmit时,是什么导致VK_错误_设备_丢失的? 我正在使用C++在Vulkan中使用体素引擎。大多数样板代码在很大程度上基于。我有一个画框功能,看起来像这样 void drawFrame(float dt) { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); uint32_t imageIndex; VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); updateUniformBuffer(imageIndex, dt); if (result == VK_ERROR_OUT_OF_DATE_KHR) { recreateSwapChain(); return; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { throw std::runtime_error("failed to acquire swap chain image!"); } // Check if a previous frame is using this image (i.e.there is its fence to wait on) if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) { vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX); } // Mark the image as now being in use by this frame imagesInFlight[imageIndex] = inFlightFences[currentFrame]; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffers[imageIndex]; VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; vkResetFences(device, 1, &inFlightFences[currentFrame]); result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); if (result != VK_SUCCESS) { throw std::runtime_error("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR swapChains[] = { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = nullptr; // Optional result = vkQueuePresentKHR(presentQueue, &presentInfo); if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) { framebufferResized = false; recreateSwapChain(); } else if (result != VK_SUCCESS) { throw std::runtime_error("failed to present swap chain image!"); } // Increment the frame. By using the modulo(%) operator, we ensure that the frame index loops around after every MAX_FRAMES_IN_FLIGHT enqueued frames. currentFrame = (currentFrame + 1) % config->maxFramesInFlight; } void createVertexAndIndexBuffer() { for (size_t x = 0; x < 100; x++) { for (size_t y = 0; y < 4; y++) { for (size_t z = 0; z < 100; z++) { // for each block in the world vector auto blockId = world.getBlock(x, y, z); if (blockId == BlockId::Air) { continue; } Vec3 blockPosition = { x, y, z }; // get its data auto verts = blockdb.blockDataFor(blockId).getVertices(); auto inds = blockdb.blockDataFor(blockId).getIndices(); // account for the block position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos += blockPosition; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); } void createVertexAndIndexBuffer() { // set bounds of how far out to render based on what chunk the player is in Vec2XZ playerChunkCoords = { floor(player.position.x) / CHUNK_WIDTH, floor(player.position.z) / CHUNK_WIDTH }; Vec2XZ lowChunkXZ = { playerChunkCoords.x - renderDistance, playerChunkCoords.z - renderDistance }; Vec2XZ highChunkXZ = { playerChunkCoords.x + renderDistance, playerChunkCoords.z + renderDistance }; // for each chunk around the player within render distance for (int x = lowChunkXZ.x; x < highChunkXZ.x; x++) { for (int z = lowChunkXZ.z; z < highChunkXZ.z; z++) { // get the chunk Chunk* chunk = &world.getChunk(x, z); // load it if it isnt already if (!chunk->isLoaded) { chunk->load(); } // generate its geometry if it doesnt already exist if (chunk->vertices.size() == 0 || chunk->indices.size() == 0) { chunk->generateVerticesAndIndices(); } auto verts = chunk->vertices; auto inds = chunk->indices; // account for the chunk position and store the new verts for later for (int i = 0; i < verts.size(); i++) { Vertex v(verts[i]); v.pos.x += x * CHUNK_WIDTH; v.pos.z += z * CHUNK_WIDTH; vertices.push_back(v); } // store the indices for later accounting for the offset into the verts vector for (int i = 0; i < inds.size(); i++) { int ind(inds[i] + vertices.size()); indices.push_back(ind); } } } // time to start creating the actual buffer VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size(); VkBuffer vertexStagingBuffer; VkDeviceMemory vertexStagingBufferMemory; createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory); void* vertexData; vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData); memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); vkUnmapMemory(device, vertexStagingBufferMemory); createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory); // use copyBuffer() to move the vertex data to the device local buffer copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize); // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed. vkDestroyBuffer(device, vertexStagingBuffer, nullptr); vkFreeMemory(device, vertexStagingBufferMemory, nullptr); // and do the same for the index buffer VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size(); VkBuffer indexStagingBuffer; VkDeviceMemory indexStagingBufferMemory; createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory); void* indexData; vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData); memcpy(indexData, indices.data(), (size_t)indexBufferSize); vkUnmapMemory(device, indexStagingBufferMemory); createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize); vkDestroyBuffer(device, indexStagingBuffer, nullptr); vkFreeMemory(device, indexStagingBufferMemory, nullptr); },c++,vulkan,voxel,C++,Vulkan,Voxel,我像这样传递顶点 void drawFrame(float dt) { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); uint32_t imageIndex; VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[

我像这样传递顶点

void drawFrame(float dt) {
    vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);

    uint32_t imageIndex;
    VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);

    updateUniformBuffer(imageIndex, dt);

    if (result == VK_ERROR_OUT_OF_DATE_KHR) {
        recreateSwapChain();
        return;
    } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
        throw std::runtime_error("failed to acquire swap chain image!");
    }

    // Check if a previous frame is using this image (i.e.there is its fence to wait on)
    if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
        vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
    }
    // Mark the image as now being in use by this frame
    imagesInFlight[imageIndex] = inFlightFences[currentFrame];

    VkSubmitInfo submitInfo{};
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

    VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] };
    VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
    submitInfo.waitSemaphoreCount = 1;
    submitInfo.pWaitSemaphores = waitSemaphores;
    submitInfo.pWaitDstStageMask = waitStages;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &commandBuffers[imageIndex];

    VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] };
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = signalSemaphores;

    vkResetFences(device, 1, &inFlightFences[currentFrame]);

    result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]);
    if (result != VK_SUCCESS) {
        throw std::runtime_error("failed to submit draw command buffer!");
    }

    VkPresentInfoKHR presentInfo{};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.waitSemaphoreCount = 1;
    presentInfo.pWaitSemaphores = signalSemaphores;

    VkSwapchainKHR swapChains[] = { swapChain };
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = swapChains;
    presentInfo.pImageIndices = &imageIndex;
    presentInfo.pResults = nullptr; // Optional

    result = vkQueuePresentKHR(presentQueue, &presentInfo);

    if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
        framebufferResized = false;
        recreateSwapChain();
    } else if (result != VK_SUCCESS) {
        throw std::runtime_error("failed to present swap chain image!");
    }

    // Increment the frame. By using the modulo(%) operator, we ensure that the frame index loops around after every MAX_FRAMES_IN_FLIGHT enqueued frames.
    currentFrame = (currentFrame + 1) % config->maxFramesInFlight;
}
void createVertexAndIndexBuffer() {
    for (size_t x = 0; x < 100; x++) {
        for (size_t y = 0; y < 4; y++) {
            for (size_t z = 0; z < 100; z++) {
                // for each block in the world vector
                auto blockId = world.getBlock(x, y, z);
                if (blockId == BlockId::Air) {
                    continue;
                }
                Vec3 blockPosition = { x, y, z };

                // get its data
                auto verts = blockdb.blockDataFor(blockId).getVertices();
                auto inds = blockdb.blockDataFor(blockId).getIndices();

                // account for the block position and store the new verts for later
                for (int i = 0; i < verts.size(); i++) {
                    Vertex v(verts[i]);
                    v.pos += blockPosition;
                    vertices.push_back(v);
                }

                // store the indices for later accounting for the offset into the verts vector
                for (int i = 0; i < inds.size(); i++) {
                    int ind(inds[i] + vertices.size());
                    indices.push_back(ind);
                }
            }
        }
    }

    // time to start creating the actual buffer 
    VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size();

    VkBuffer vertexStagingBuffer;
    VkDeviceMemory vertexStagingBufferMemory;
    
    createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory);

    void* vertexData;
    vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData);
    memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); 
    vkUnmapMemory(device, vertexStagingBufferMemory);

    createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);

    // use copyBuffer() to move the vertex data to the device local buffer
    copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize);

    // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed.
    vkDestroyBuffer(device, vertexStagingBuffer, nullptr);
    vkFreeMemory(device, vertexStagingBufferMemory, nullptr);


    // and do the same for the index buffer
    VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size();

    VkBuffer indexStagingBuffer;
    VkDeviceMemory indexStagingBufferMemory;
    createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory);

    void* indexData;
    vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData);
    memcpy(indexData, indices.data(), (size_t)indexBufferSize);
    vkUnmapMemory(device, indexStagingBufferMemory);

    createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);

    copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize);

    vkDestroyBuffer(device, indexStagingBuffer, nullptr);
    vkFreeMemory(device, indexStagingBufferMemory, nullptr);
}
 void createVertexAndIndexBuffer() {
    // set bounds of how far out to render based on what chunk the player is in
    Vec2XZ playerChunkCoords = { floor(player.position.x) / CHUNK_WIDTH, floor(player.position.z) / CHUNK_WIDTH };

    Vec2XZ lowChunkXZ = { playerChunkCoords.x - renderDistance, playerChunkCoords.z - renderDistance };
    Vec2XZ highChunkXZ = { playerChunkCoords.x + renderDistance, playerChunkCoords.z + renderDistance };

    // for each chunk around the player within render distance
    for (int x = lowChunkXZ.x; x < highChunkXZ.x; x++) {
        for (int z = lowChunkXZ.z; z < highChunkXZ.z; z++) {
            // get the chunk
            Chunk* chunk = &world.getChunk(x, z);

            // load it if it isnt already
            if (!chunk->isLoaded) {
                chunk->load();
            }

            // generate its geometry if it doesnt already exist
            if (chunk->vertices.size() == 0 || chunk->indices.size() == 0) {
                chunk->generateVerticesAndIndices();
            }

            auto verts = chunk->vertices;
            auto inds = chunk->indices;

            // account for the chunk position and store the new verts for later
            for (int i = 0; i < verts.size(); i++) {
                Vertex v(verts[i]);
                v.pos.x += x * CHUNK_WIDTH;
                v.pos.z += z * CHUNK_WIDTH;
                vertices.push_back(v);
            }

            // store the indices for later accounting for the offset into the verts vector
            for (int i = 0; i < inds.size(); i++) {
                int ind(inds[i] + vertices.size());
                indices.push_back(ind);
            }
        }
    }

    // time to start creating the actual buffer 
    VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size();

    VkBuffer vertexStagingBuffer;
    VkDeviceMemory vertexStagingBufferMemory;
    
    createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer, vertexStagingBufferMemory);

    void* vertexData;
    vkMapMemory(device, vertexStagingBufferMemory, 0, vertexBufferSize, 0, &vertexData);
    memcpy(vertexData, vertices.data(), (size_t)vertexBufferSize); 
    vkUnmapMemory(device, vertexStagingBufferMemory);

    createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);

    // use copyBuffer() to move the vertex data to the device local buffer
    copyBuffer(vertexStagingBuffer, vertexBuffer, vertexBufferSize);

    // After copying the data from the staging buffer to the device buffer, we should clean up the staging buffer since it is no longer needed.
    vkDestroyBuffer(device, vertexStagingBuffer, nullptr);
    vkFreeMemory(device, vertexStagingBufferMemory, nullptr);


    // and do the same for the index buffer
    VkDeviceSize indexBufferSize = sizeof(indices[0]) * indices.size();

    VkBuffer indexStagingBuffer;
    VkDeviceMemory indexStagingBufferMemory;
    createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer, indexStagingBufferMemory);

    void* indexData;
    vkMapMemory(device, indexStagingBufferMemory, 0, indexBufferSize, 0, &indexData);
    memcpy(indexData, indices.data(), (size_t)indexBufferSize);
    vkUnmapMemory(device, indexStagingBufferMemory);

    createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);

    copyBuffer(indexStagingBuffer, indexBuffer, indexBufferSize);

    vkDestroyBuffer(device, indexStagingBuffer, nullptr);
    vkFreeMemory(device, indexStagingBufferMemory, nullptr);
}
void createVertexandexBuffer(){
对于(大小x=0;x<100;x++){
对于(大小y=0;y<4;y++){
对于(大小_t z=0;z<100;z++){
//对于世界向量中的每个块
auto blockId=world.getBlock(x,y,z);
if(blockId==blockId::Air){
继续;
}
Vec3 blockPosition={x,y,z};
//获取其数据
auto verts=blockdb.blockDataFor(blockId.getVertices();
auto inds=blockdb.blockDataFor(blockId.getindex();
//说明块位置并存储新顶点以备以后使用
对于(int i=0;i
一切都很好,但我需要能够按块而不是按块渲染,以实现块几何体优化。这是我的chunk.h和chunk.cpp

#pragma once
#include "Layer.h"

class Chunk {
public:
    Chunk() = default;
    Chunk(World* _world, Vec2XZ pos);
    ~Chunk() {}

    BlockId getBlock(int x, int y, int z);
    bool setBlock(BlockId id, int x, int y, int z);
    bool isBlockOutOfBounds(int x, int y, int z);
    void generateVerticesAndIndices();
    void load();

    std::array<Layer, CHUNK_HEIGHT> layers;
    const Vec2XZ position;
    const World* world;
    bool isLoaded = false;
    std::vector<Vertex> vertices;
    std::vector<uint32_t> indices;
private:
};
#pragma一次
#包括“Layer.h”
类块{
公众:
Chunk()=默认值;
区块(世界*_世界,Vec2XZ位置);
~Chunk(){}
BlockId getBlock(intx,inty,intz);
bool setBlock(BlockId id,int x,int y,int z);
bool是blockoutofbounds(intx,inty,intz);
无效生成条件();
空荷载();
std::阵列层;
常数向量2xz位置;
康斯特世界*世界;
bool isLoaded=false;
向量顶点;
std::向量指数;
私人:
};
#pragma一次
#包括“Chunk.h”
Chunk::Chunk(世界*_世界,Vec2XZ位置):
位置(pos),
世界{
}
BlockId Chunk::getBlock(intx,inty,intz){
if(isBlockOutOfBounds(x,y,z)){
返回BlockId::空气;
}
返回层[y].getBlock(x,z);
}
bool Chunk::setBlock(BlockId id,intx,inty,intz){
如果(!IsBlockOutof边界(x,y,z)){
if(层[y].setBlock(id,x,z)){
返回true;
}
}
返回false;
}
bool Chunk::isBlockOutOfBounds(intx,inty,intz){
如果(x>=块宽度)
返回true;
如果(z>=块宽度)
返回true;
if(x<0)
返回true;
if(y<0)
返回true;
if(z<0)
返回true;
如果(y>=块体高度){
返回true;
}
返回false;
}
void Chunk::generateverticesandices(){
顶点。清除();
索引。清除();
对于(int y=0;yblockdb->blockDataFor(blockId).getvertexts();
auto inds=world->blockdb->blockDataFor(blockId).getindex();
//说明块位置并存储n