90 const std::string &modelPath,
91 const std::string &textureManifestPath,
92 const std::string &textureBasePath,
105 const std::string &textureManifestPath,
106 const std::string &textureBasePath,
107 [[maybe_unused]]
float scale = 1.0f);
115 void setShaders(
VK_Window *window,
const std::string &vertSpv,
const std::string &fragSpv);
141 [[nodiscard]]
bool updatePrimaryTexture(
const void *pixels,
int width,
int height,
int pitch = 0);
150 [[nodiscard]]
bool updatePrimaryTextureCuda(
const cv::cuda::GpuMat &rgba, cv::cuda::Stream &stream);
159 void render(VkCommandBuffer cmd, uint32_t imageIndex,
bool wireframe =
false)
const;
173 bool wireframe =
false);
178 VkImageView textureView,
180 bool wireframe =
false);
203 [[nodiscard]]
bool isLoaded()
const {
return obj.indexCount() > 0 && vertexBufferReady(); }
218 struct TextureEntry {
219 VkImage image = VK_NULL_HANDLE;
220 VkDeviceMemory memory = VK_NULL_HANDLE;
221 VkImageView view = VK_NULL_HANDLE;
225 VkDeviceSize cudaExportMemorySize = 0;
226 cudaExternalMemory_t cudaExternalMemory =
nullptr;
227 cudaMipmappedArray_t cudaMipmappedArray =
nullptr;
228 cudaArray_t cudaArray =
nullptr;
229 bool cudaInteropEnabled =
false;
230 bool cudaInteropUnavailableLogged =
false;
231 bool cudaUploadLogged =
false;
232 bool cudaWriteTransitionLogged =
false;
233 bool cudaShaderTransitionLogged =
false;
234 VkImageLayout cudaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
239 std::vector<TextureEntry> textures{};
241 VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
242 VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
243 uint32_t descriptorPoolSetCapacity = 0;
244 std::vector<VkDescriptorSet> descriptorSets{};
246 VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
247 VkPipeline pipelineFill = VK_NULL_HANDLE;
248 VkPipeline pipelineWireframe = VK_NULL_HANDLE;
249 VkSampler textureSampler = VK_NULL_HANDLE;
251 std::vector<VkBuffer> uniformBuffers{};
252 std::vector<VkDeviceMemory> uniformBufferMemory{};
253 std::vector<void *> uniformBuffersMapped{};
254 std::vector<VkBuffer> fragmentUniformBuffers{};
255 std::vector<VkDeviceMemory> fragmentUniformBufferMemory{};
256 std::vector<void *> fragmentUniformBuffersMapped{};
258 glm::vec3 modelCenterOffsetValue{0.0f, 0.0f, 0.0f};
259 float modelRenderScaleValue = 1.0f;
260 glm::vec3 modelAxisExtentValue{1.0f, 1.0f, 1.0f};
262 std::string vertexShaderPath{};
263 std::string fragmentShaderPath{};
264 bool backfaceCullingEnabled =
false;
265 bool alphaBlendingEnabled =
false;
266 ModelFragmentPushConstants fragmentPushConstants{};
267 bool extendedFragmentUniformsEnabled =
false;
269 VK_Window *windowPtr =
nullptr;
271 [[nodiscard]]
bool vertexBufferReady()
const {
return obj.vertexBuffer() != VK_NULL_HANDLE && obj.indexBuffer() != VK_NULL_HANDLE; }
273 void computeBoundsAndScale();
274 void loadTextures(
const std::string &textureManifestPath,
const std::string &textureBasePath);
275 void loadTexturesFromMTL(
const std::string &textureBasePath);
276 void createFallbackTexture();
278 void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
279 VkMemoryPropertyFlags properties, VkBuffer &buffer,
280 VkDeviceMemory &bufferMemory)
const;
281 [[nodiscard]] uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
const;
282 [[nodiscard]] VkCommandBuffer beginSingleTimeCommands()
const;
283 void endSingleTimeCommands(VkCommandBuffer commandBuffer)
const;
284 void createImage(uint32_t width, uint32_t height, VkFormat format,
285 VkImageTiling tiling, VkImageUsageFlags usage,
286 VkMemoryPropertyFlags properties, VkImage &image,
287 VkDeviceMemory &memory)
const;
288 void createTextureImage(uint32_t width, uint32_t height, TextureEntry &texture)
const;
290 void createCudaExportableImage(uint32_t width, uint32_t height, TextureEntry &texture)
const;
291 void destroyTextureCudaInterop(TextureEntry &texture)
const;
292 [[nodiscard]]
bool ensureTextureCudaInterop(TextureEntry &texture)
const;
293 [[nodiscard]]
bool transitionTextureForCudaWrite(TextureEntry &texture)
const;
294 [[nodiscard]]
bool transitionTextureForShaderRead(TextureEntry &texture)
const;
295 [[nodiscard]]
bool updatePrimaryTextureCudaHost(TextureEntry &texture,
const void *pixels,
296 uint32_t width, uint32_t height, uint32_t pitch)
const;
297 void recreatePrimaryTextureForCuda(TextureEntry &texture, uint32_t width, uint32_t height);
299 [[nodiscard]] VkImageView createImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
const;
300 void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
const;
301 void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height)
const;
303 void createTextureSampler();
304 void createDescriptorSetLayout();
305 void createUniformBuffers();
306 void destroyUniformBuffers();
307 void createDescriptorPool();
308 void createDescriptorSets();
309 void updateTextureDescriptor(VkDescriptorSet descriptorSet,
310 VkImageView imageView)
const;
311 void createPipelines();
313 void destroyPipelines();
314 void destroyDescriptors();
315 void destroyTextures();