From 6c87a49eb8a23915f8fa69106bb3c232b61b6121 Mon Sep 17 00:00:00 2001 From: gBarbieri Date: Wed, 16 May 2018 09:20:37 +0200 Subject: [PATCH] up --- ...92fc2a92a4964420db5aec9f228d534feec2c2.xml | 11 + ...219ae7ba8048f7909266f77bb778c0e65ee5da.xml | 11 - ...bc98637e04a660fd89ce586abd19cfd11f9d1c.xml | 11 + ...a48060cb85ebaa456ce6c06891f47b76fff287.xml | 11 - ...4c486e71e7ad5ee301b6e65e6be9d697675d9d.xml | 11 - ...50e291a4e1a308cb4e583309d966ea8cbc1729.xml | 11 + Vulkan.iml | 18 +- build.gradle | 6 +- src/main/kotlin/vulkan/basics/02 Pipelines.kt | 2 +- .../vulkan/basics/03 Descriptor Sets.kt | 2 +- .../basics/04 Dynamic Uniform Buffers.kt | 4 +- .../kotlin/vulkan/basics/05 Push Constants.kt | 2 +- .../basics/06 Specialization Constants.kt | 2 +- src/main/kotlin/vulkan/basics/07 Texture.kt | 6 +- .../vulkan/basics/08 Texture Cubemap.kt | 4 +- .../kotlin/vulkan/basics/09 Texture Array.kt | 2 +- .../vulkan/basics/11 Model Rendering.kt | 2 +- .../vulkan/basics/14 Cpu Particle System.kt | 1518 ++++++++--------- .../computeShader/01 Image Processing.kt | 2 +- .../computeShader/02 Gpu Particle System.kt | 2 +- .../computeShader/03 N-Body Simulation.kt | 4 +- 21 files changed, 821 insertions(+), 821 deletions(-) create mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_assimp_3f92fc2a92a4964420db5aec9f228d534feec2c2.xml delete mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_assimp_4c219ae7ba8048f7909266f77bb778c0e65ee5da.xml create mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_a4bc98637e04a660fd89ce586abd19cfd11f9d1c.xml delete mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_dea48060cb85ebaa456ce6c06891f47b76fff287.xml delete mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_vkk_154c486e71e7ad5ee301b6e65e6be9d697675d9d.xml create mode 100644 .idea/libraries/Gradle__com_github_kotlin_graphics_vkk_eb50e291a4e1a308cb4e583309d966ea8cbc1729.xml diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_3f92fc2a92a4964420db5aec9f228d534feec2c2.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_3f92fc2a92a4964420db5aec9f228d534feec2c2.xml new file mode 100644 index 0000000..39741b0 --- /dev/null +++ b/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_3f92fc2a92a4964420db5aec9f228d534feec2c2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_4c219ae7ba8048f7909266f77bb778c0e65ee5da.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_4c219ae7ba8048f7909266f77bb778c0e65ee5da.xml deleted file mode 100644 index ed60c50..0000000 --- a/.idea/libraries/Gradle__com_github_kotlin_graphics_assimp_4c219ae7ba8048f7909266f77bb778c0e65ee5da.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_a4bc98637e04a660fd89ce586abd19cfd11f9d1c.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_a4bc98637e04a660fd89ce586abd19cfd11f9d1c.xml new file mode 100644 index 0000000..cc87f52 --- /dev/null +++ b/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_a4bc98637e04a660fd89ce586abd19cfd11f9d1c.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_dea48060cb85ebaa456ce6c06891f47b76fff287.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_dea48060cb85ebaa456ce6c06891f47b76fff287.xml deleted file mode 100644 index 77a5535..0000000 --- a/.idea/libraries/Gradle__com_github_kotlin_graphics_uno_sdk_dea48060cb85ebaa456ce6c06891f47b76fff287.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_154c486e71e7ad5ee301b6e65e6be9d697675d9d.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_154c486e71e7ad5ee301b6e65e6be9d697675d9d.xml deleted file mode 100644 index 1834000..0000000 --- a/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_154c486e71e7ad5ee301b6e65e6be9d697675d9d.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_eb50e291a4e1a308cb4e583309d966ea8cbc1729.xml b/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_eb50e291a4e1a308cb4e583309d966ea8cbc1729.xml new file mode 100644 index 0000000..ffc362f --- /dev/null +++ b/.idea/libraries/Gradle__com_github_kotlin_graphics_vkk_eb50e291a4e1a308cb4e583309d966ea8cbc1729.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Vulkan.iml b/Vulkan.iml index fbad720..2178fab 100644 --- a/Vulkan.iml +++ b/Vulkan.iml @@ -39,9 +39,9 @@ - - - + + + @@ -69,9 +69,9 @@ - - - + + + @@ -106,9 +106,9 @@ - - - + + + diff --git a/build.gradle b/build.gradle index 4cf7011..ada3a91 100644 --- a/build.gradle +++ b/build.gradle @@ -55,9 +55,9 @@ dependencies { ext.kx = 'com.github.kotlin-graphics' implementation "$kx:glm:738c60621c18939ad6093a13cddfe158344edbbe" - implementation "$kx:vkk:154c486e71e7ad5ee301b6e65e6be9d697675d9d" - implementation "$kx:uno-sdk:dea48060cb85ebaa456ce6c06891f47b76fff287" - implementation "$kx:assimp:4c219ae7ba8048f7909266f77bb778c0e65ee5da" + implementation "$kx:vkk:eb50e291a4e1a308cb4e583309d966ea8cbc1729" + implementation "$kx:uno-sdk:a4bc98637e04a660fd89ce586abd19cfd11f9d1c" + implementation "$kx:assimp:3f92fc2a92a4964420db5aec9f228d534feec2c2" // implementation "$kx:imgui:6aea5d675ec24b45ffda10e9106eb47656c049b2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" diff --git a/src/main/kotlin/vulkan/basics/02 Pipelines.kt b/src/main/kotlin/vulkan/basics/02 Pipelines.kt index 8e5b2fd..194b4e0 100644 --- a/src/main/kotlin/vulkan/basics/02 Pipelines.kt +++ b/src/main/kotlin/vulkan/basics/02 Pipelines.kt @@ -334,7 +334,7 @@ private class Pipelines : VulkanExampleBase() { .rotateAssign(rotation.y.rad, 0f, 1f, 0f) .rotateAssign(rotation.z.rad, 0f, 0f, 1f) - uboVS to uniformBuffer.mapped[0] + uboVS to uniformBuffer.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/03 Descriptor Sets.kt b/src/main/kotlin/vulkan/basics/03 Descriptor Sets.kt index 0389a1e..9866ed4 100644 --- a/src/main/kotlin/vulkan/basics/03 Descriptor Sets.kt +++ b/src/main/kotlin/vulkan/basics/03 Descriptor Sets.kt @@ -355,7 +355,7 @@ private class DescriptorSets : VulkanExampleBase() { .rotateAssign(cube.rotation.y.rad, 0f, 1f, 0f) .rotateAssign(cube.rotation.z.rad, 0f, 0f, 1f) } - cube.matrices to cube.uniformBuffer.mapped[0] + cube.matrices to cube.uniformBuffer.mapped } } diff --git a/src/main/kotlin/vulkan/basics/04 Dynamic Uniform Buffers.kt b/src/main/kotlin/vulkan/basics/04 Dynamic Uniform Buffers.kt index 614db63..57c954b 100644 --- a/src/main/kotlin/vulkan/basics/04 Dynamic Uniform Buffers.kt +++ b/src/main/kotlin/vulkan/basics/04 Dynamic Uniform Buffers.kt @@ -380,7 +380,7 @@ private class DynamicUniformBuffers : VulkanExampleBase() { uboVS.projection put camera.matrices.perspective uboVS.view put camera.matrices.view - uboVS to uniformBuffers.view.mapped[0] + uboVS to uniformBuffers.view.mapped } fun updateDynamicUniformBuffer(force: Boolean = false) { @@ -415,7 +415,7 @@ private class DynamicUniformBuffers : VulkanExampleBase() { animationTimer = 0f - memCopy(uboDataDynamic.address, uniformBuffers.dynamic.mapped[0], uniformBuffers.dynamic.size) + memCopy(uboDataDynamic.address, uniformBuffers.dynamic.mapped, uniformBuffers.dynamic.size) // Flush to make changes visible to the host val memoryRange = vk.MappedMemoryRange { memory = uniformBuffers.dynamic.memory diff --git a/src/main/kotlin/vulkan/basics/05 Push Constants.kt b/src/main/kotlin/vulkan/basics/05 Push Constants.kt index e476b1a..90299ca 100644 --- a/src/main/kotlin/vulkan/basics/05 Push Constants.kt +++ b/src/main/kotlin/vulkan/basics/05 Push Constants.kt @@ -317,7 +317,7 @@ private class PushConstants : VulkanExampleBase() { .rotateAssign(rotation.y.rad, 0f, 1f, 0f) .rotateAssign(rotation.z.rad, 0f, 0f, 1f) - uboVS to uniformBuffer.mapped[0] + uboVS to uniformBuffer.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/06 Specialization Constants.kt b/src/main/kotlin/vulkan/basics/06 Specialization Constants.kt index 2225c82..9efb7fc 100644 --- a/src/main/kotlin/vulkan/basics/06 Specialization Constants.kt +++ b/src/main/kotlin/vulkan/basics/06 Specialization Constants.kt @@ -341,7 +341,7 @@ class SpecializationConstants : VulkanExampleBase() { uboVS.projection = camera.matrices.perspective uboVS.modelView = camera.matrices.view - uboVS to uniformBuffer.mapped[0] + uboVS to uniformBuffer.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/07 Texture.kt b/src/main/kotlin/vulkan/basics/07 Texture.kt index a19df6d..e594fb0 100644 --- a/src/main/kotlin/vulkan/basics/07 Texture.kt +++ b/src/main/kotlin/vulkan/basics/07 Texture.kt @@ -10,6 +10,7 @@ package vulkan.basics import gli_.gli import glm_.L +import glm_.buffer.adr import glm_.f import glm_.func.rad import glm_.glm @@ -242,9 +243,8 @@ private class Texture : VulkanExampleBase() { device.bindBufferMemory(stagingBuffer, stagingMemory) // Copy texture data into staging buffer - val data = appBuffer.pointer - device.mapMemory(stagingMemory, 0, memReqs.size, 0, data) - memCopy(memAddress(tex2D.data()), memGetAddress(data), tex2D.size.L) + val data = device.mapMemory(stagingMemory, 0, memReqs.size) + memCopy(tex2D.data().adr, data, tex2D.size.L) device unmapMemory stagingMemory // Setup buffer copy regions for each mip level diff --git a/src/main/kotlin/vulkan/basics/08 Texture Cubemap.kt b/src/main/kotlin/vulkan/basics/08 Texture Cubemap.kt index a8f67db..680509f 100644 --- a/src/main/kotlin/vulkan/basics/08 Texture Cubemap.kt +++ b/src/main/kotlin/vulkan/basics/08 Texture Cubemap.kt @@ -523,7 +523,7 @@ private class TextureCubemap : VulkanExampleBase() { .rotateAssign(rotation.y.rad, 0f, 1f, 0f) .rotateAssign(rotation.z.rad, 0f, 0f, 1f) - uboVS to uniformBuffers.`object`.mapped[0] + uboVS to uniformBuffers.`object`.mapped // Skybox viewMatrix put 1f @@ -535,7 +535,7 @@ private class TextureCubemap : VulkanExampleBase() { .rotateAssign(rotation.y.rad, 0f, 1f, 0f) .rotateAssign(rotation.z.rad, 0f, 0f, 1f) - uboVS to uniformBuffers.skybox.mapped[0] + uboVS to uniformBuffers.skybox.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/09 Texture Array.kt b/src/main/kotlin/vulkan/basics/09 Texture Array.kt index e732a37..df006d5 100644 --- a/src/main/kotlin/vulkan/basics/09 Texture Array.kt +++ b/src/main/kotlin/vulkan/basics/09 Texture Array.kt @@ -539,7 +539,7 @@ class TextureArray : VulkanExampleBase() { .rotateAssign(rotation.z.rad, 0f, 0f, 1f) // Only update the matrices part of the uniform buffer - uboVS.matrices to uniformBufferVS.mapped[0] + uboVS.matrices to uniformBufferVS.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/11 Model Rendering.kt b/src/main/kotlin/vulkan/basics/11 Model Rendering.kt index 428fd71..0dd744f 100644 --- a/src/main/kotlin/vulkan/basics/11 Model Rendering.kt +++ b/src/main/kotlin/vulkan/basics/11 Model Rendering.kt @@ -482,7 +482,7 @@ private class ModelRendering : VulkanExampleBase() { .rotateAssign(rotation.y.rad, 0f, 1f, 0f) .rotateAssign(rotation.z.rad, 0f, 0f, 1f) - uboVS to uniformBuffers.scene.mapped[0] + uboVS to uniformBuffers.scene.mapped } fun draw() { diff --git a/src/main/kotlin/vulkan/basics/14 Cpu Particle System.kt b/src/main/kotlin/vulkan/basics/14 Cpu Particle System.kt index 18a135d..569f6f8 100644 --- a/src/main/kotlin/vulkan/basics/14 Cpu Particle System.kt +++ b/src/main/kotlin/vulkan/basics/14 Cpu Particle System.kt @@ -1,759 +1,759 @@ -/* -* Vulkan Example - CPU based fire particle system -* -* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -package vulkan.basics - -import glm_.BYTES -import glm_.L -import glm_.buffer.adr -import glm_.buffer.bufferBig -import glm_.glm -import glm_.mat4x4.Mat4 -import glm_.size -import glm_.vec2.Vec2 -import glm_.vec3.Vec3 -import glm_.vec4.Vec4 -import org.lwjgl.system.MemoryUtil.NULL -import vkk.* -import vulkan.VERTEX_BUFFER_BIND_ID -import vulkan.base.* -import java.nio.ByteBuffer -import kotlin.math.abs -import kotlin.math.cos -import kotlin.math.sin - - -private const val FLAME_RADIUS = 8f - -private object particle { - const val COUNT = 512 - const val SIZE = 10f - - enum class Type { Flame, Smoke } -} - - -fun main(args: Array) { - CpuParticleSystem().apply { - setupWindow() - initVulkan() - prepare() - renderLoop() - destroy() - } -} - -private class CpuParticleSystem : VulkanExampleBase() { - - object textures { - object particles { - val smoke = Texture2D() - val fire = Texture2D() - // Use a custom sampler to change sampler attributes required for rotating the uvs in the shader for alpha blended textures - var sampler: VkSampler = NULL - } - - object floor { - val colorMap = Texture2D() - val normalMap = Texture2D() - } - } - - // Vertex layout for the models - val vertexLayout = VertexLayout( - VertexComponent.POSITION, - VertexComponent.UV, - VertexComponent.NORMAL, - VertexComponent.TANGENT, - VertexComponent.BITANGENT) - - object models { - val environment = Model() - } - - val emitterPos = Vec3(0f, -FLAME_RADIUS + 2f, 0f) - val minVel = Vec3(-3f, 0.5f, -3f) - val maxVel = Vec3(3f, 7f, 3f) - - fun rnd(range: Float) = glm.linearRand(0f, range) - - private inner class Particle : Bufferizable() { - val pos = Vec4() - lateinit var color: Vec4 - var alpha = 0f - var size_ = 0f - var rotation = 0f - var type = particle.Type.Flame - // Attributes not used in shader - lateinit var vel: Vec4 - var rotationSpeed = 0f - - fun init(emitterPos: Vec3) { - - vel = Vec4(0f, minVel.y + rnd(maxVel.y - minVel.y), 0f, 0f) - alpha = rnd(0.75f) - size_ = 1f + rnd(0.5f) - color = Vec4(1f) - type = particle.Type.Flame - rotation = rnd(2f * glm.PIf) - rotationSpeed = rnd(2f) - rnd(2f) - - // Get random sphere point - val theta = rnd(2f * glm.PIf) - val phi = rnd(glm.PIf) - glm.HPIf - val r = rnd(FLAME_RADIUS) - - pos.x = r * cos(theta) * cos(phi) - pos.y = r * sin(phi) - pos.z = r * sin(theta) * cos(phi) - - pos plusAssign Vec4(emitterPos, 0f) - } - } - - val particleSize = Vec4.size * 3 + Float.BYTES * 4 + Int.BYTES - - object particlesData { - var buffer: VkBuffer = NULL - var memory: VkDeviceMemory = 0 - // Store the mapped address of the particle data for reuse - var mappedMemory = NULL - // Size of the particle buffer in bytes - var size = 0 - } - - object uniformBuffers { - val fire = Buffer() - val environment = Buffer() - } - - object uboVS { - lateinit var projection: Mat4 - lateinit var model: Mat4 - lateinit var viewportDim: Vec2 - val pointSize = particle.SIZE - } - - object uboEnv { - lateinit var projection: Mat4 - lateinit var model: Mat4 - lateinit var normal: Mat4 - val lightPos = Vec4(0f) - lateinit var cameraPos: Vec4 - } - - object pipelines { - var particles: VkPipeline = NULL - var environment: VkPipeline = NULL - } - - var pipelineLayout: VkPipelineLayout = NULL - var descriptorSetLayout: VkDescriptorSetLayout = NULL - - object descriptorSets { - var particles: VkDescriptorSet = NULL - var environment: VkDescriptorSet = NULL - } - - lateinit var particleBuffer: ByteBuffer - private val particles = ArrayList() - - init { - zoom = -75.0f - rotation(-15f, 45f, 0f) - title = "CPU based particle system" - settings.overlay = true - zoomSpeed *= 1.5f - timerSpeed *= 8f - } - - override fun destroy() { - - // Clean up used Vulkan resources - // Note : Inherited destructor cleans up resources stored in base class - - textures.particles.smoke.destroy() - textures.particles.fire.destroy() - textures.floor.colorMap.destroy() - textures.floor.normalMap.destroy() - - device.apply { - - destroyPipeline(pipelines.particles) - destroyPipeline(pipelines.environment) - - destroyPipelineLayout(pipelineLayout) - destroyDescriptorSetLayout(descriptorSetLayout) - - unmapMemory(particlesData.memory) - destroyBuffer(particlesData.buffer) - freeMemory(particlesData.memory) - - uniformBuffers.environment.destroy() - uniformBuffers.fire.destroy() - - models.environment.destroy() - - destroySampler(textures.particles.sampler) - } - super.destroy() - } - - override fun buildCommandBuffers() { - - val cmdBufInfo = vk.CommandBufferBeginInfo() - - val clearValues = vk.ClearValue(2).also { - it[0].color(defaultClearColor) - it[1].depthStencil(1f, 0) - } - val renderPassBeginInfo = vk.RenderPassBeginInfo { - renderPass = this@CpuParticleSystem.renderPass - renderArea.offset(0) - renderArea.extent(size) - this.clearValues = clearValues - } - for (i in drawCmdBuffers.indices) { - // Set target frame buffer - renderPassBeginInfo.framebuffer(frameBuffers[i]) - - drawCmdBuffers[i].apply { - - begin(cmdBufInfo) - - beginRenderPass(renderPassBeginInfo, VkSubpassContents.INLINE) - - setViewport(size) - setScissor(size) - - // Environment - bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSets.environment) - bindPipeline(VkPipelineBindPoint.GRAPHICS, pipelines.environment) - bindVertexBuffers(VERTEX_BUFFER_BIND_ID, models.environment.vertices.buffer) - bindIndexBuffer(models.environment.indices.buffer, 0, VkIndexType.UINT32) - drawIndexed(models.environment.indexCount, 1, 0, 0, 0) - - // Particle system (no index buffer) - bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSets.particles) - bindPipeline(VkPipelineBindPoint.GRAPHICS, pipelines.particles) - bindVertexBuffers(VERTEX_BUFFER_BIND_ID, particlesData.buffer) - draw(particle.COUNT, 1, 0, 0) - - endRenderPass() - - end() - } - } - } - - - private fun Particle.transition() = when (type) { - particle.Type.Flame -> { - // Flame particles have a chance of turning into smoke - if (rnd(1f) < 0.05f) { - alpha = 0f - color = Vec4(0.25f + rnd(0.25f)) - pos.x *= 0.5f - pos.z *= 0.5f - vel = Vec4(rnd(1f) - rnd(1f), (minVel.y * 2) + rnd(maxVel.y - minVel.y), rnd(1f) - rnd(1f), 0f) - size_ = 1f + rnd(0.5f) - rotationSpeed = rnd(1f) - rnd(1f) - type = particle.Type.Smoke - } else init(emitterPos) - } - // Respawn at end of life - particle.Type.Smoke -> init(emitterPos) - } - - fun prepareParticles() { - - particles += List(particle.COUNT) { - Particle().apply { - init(emitterPos) - alpha = 1f - abs(pos.y) / (FLAME_RADIUS * 2f) - } - } - - particleBuffer = bufferBig(particleSize * particles.size) - - for (i in particles.indices) - particles[i] to (particleBuffer.adr + particleSize * i) - - particlesData.size = particleBuffer.size - - vulkanDevice.createBuffer( - VkBufferUsage.VERTEX_BUFFER_BIT.i, - VkMemoryProperty.HOST_VISIBLE_BIT or VkMemoryProperty.HOST_COHERENT_BIT, - particlesData.size.L, - particlesData::buffer, - particlesData::memory, - particleBuffer.adr) - - // Map the memory and store the pointer for reuse - particlesData.mappedMemory = device.mapMemory(particlesData.memory, 0, particlesData.size.L) - } - - void updateParticles() - { - float particleTimer = frameTimer * 0.45f - for (auto& particle : particleBuffer) - { - switch(particle.type) - { - case PARTICLE_TYPE_FLAME : - particle.pos.y -= particle.vel.y * particleTimer * 3.5f - particle.alpha += particleTimer * 2.5f - particle.size -= particleTimer * 0.5f - break - case PARTICLE_TYPE_SMOKE : - particle.pos -= particle.vel * frameTimer * 1.0f - particle.alpha += particleTimer * 1.25f - particle.size += particleTimer * 0.125f - particle.color -= particleTimer * 0.05f - break - } - particle.rotation += particleTimer * particle.rotationSpeed - // Transition particle state - if (particle.alpha > 2.0f) { - transitionParticle(& particle) - } - } - size_t size = particleBuffer . size () * sizeof(Particle) - memcpy(particles.mappedMemory, particleBuffer.data(), size) - } - - void loadAssets() - { - // Textures - std::string texFormatSuffix - VkFormat texFormat - // Get supported compressed texture format - if (vulkanDevice->features.textureCompressionBC) { - texFormatSuffix = "_bc3_unorm" - texFormat = VK_FORMAT_BC3_UNORM_BLOCK - } - else if (vulkanDevice->features.textureCompressionASTC_LDR) { - texFormatSuffix = "_astc_8x8_unorm" - texFormat = VK_FORMAT_ASTC_8x8_UNORM_BLOCK - } - else if (vulkanDevice->features.textureCompressionETC2) { - texFormatSuffix = "_etc2_unorm" - texFormat = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK - } - else { - vks::tools::exitFatal("Device does not support any compressed texture format!", VK_ERROR_FEATURE_NOT_PRESENT) - } - - // Particles - textures.particles.smoke.loadFromFile(getAssetPath() + "textures/particle_smoke.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue) - textures.particles.fire.loadFromFile(getAssetPath() + "textures/particle_fire.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue) - - // Floor - textures.floor.colorMap.loadFromFile(getAssetPath() + "textures/fireplace_colormap" + texFormatSuffix + ".ktx", texFormat, vulkanDevice, queue) - textures.floor.normalMap.loadFromFile(getAssetPath() + "textures/fireplace_normalmap" + texFormatSuffix + ".ktx", texFormat, vulkanDevice, queue) - - // Create a custom sampler to be used with the particle textures - // Create sampler - VkSamplerCreateInfo samplerCreateInfo = vks ::initializers::samplerCreateInfo() - samplerCreateInfo.magFilter = VK_FILTER_LINEAR - samplerCreateInfo.minFilter = VK_FILTER_LINEAR - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR - // Different address mode - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU - samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU - samplerCreateInfo.mipLodBias = 0.0f - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER - samplerCreateInfo.minLod = 0.0f - // Both particle textures have the same number of mip maps - samplerCreateInfo.maxLod = float(textures.particles.fire.mipLevels) - // Enable anisotropic filtering - samplerCreateInfo.maxAnisotropy = 8.0f - samplerCreateInfo.anisotropyEnable = VK_TRUE - // Use a different border color (than the normal texture loader) for additive blending - samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK - VK_CHECK_RESULT(vkCreateSampler(device, & samplerCreateInfo, nullptr, & textures . particles . sampler)) - - models.environment.loadFromFile(getAssetPath() + "models/fireplace.obj", vertexLayout, 10.0f, vulkanDevice, queue) - } - - void setupDescriptorPool() - { - // Example uses one ubo and one image sampler - std::vector poolSizes = - { - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4) - } - - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo( - poolSizes.size(), - poolSizes.data(), - 2) - - VK_CHECK_RESULT(vkCreateDescriptorPool(device, & descriptorPoolInfo, nullptr, & descriptorPool)) - } - - void setupDescriptorSetLayout() - { - std::vector setLayoutBindings = - { - // Binding 0 : Vertex shader uniform buffer - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_SHADER_STAGE_VERTEX_BIT, - 0), - // Binding 1 : Fragment shader image sampler - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1), - // Binding 1 : Fragment shader image sampler - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 2) - } - - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo( - setLayoutBindings.data(), - setLayoutBindings.size()) - - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, & descriptorLayout, nullptr, & descriptorSetLayout)) - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo( - & descriptorSetLayout, - 1) - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, & pPipelineLayoutCreateInfo, nullptr, & pipelineLayout)) - } - - void setupDescriptorSets() - { - std::vector writeDescriptorSets - - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, - & descriptorSetLayout, - 1) - - VK_CHECK_RESULT(vkAllocateDescriptorSets(device, & allocInfo, & descriptorSets . particles)) - - // Image descriptor for the color map texture - VkDescriptorImageInfo texDescriptorSmoke = - vks::initializers::descriptorImageInfo( - textures.particles.sampler, - textures.particles.smoke.view, - VK_IMAGE_LAYOUT_GENERAL) - VkDescriptorImageInfo texDescriptorFire = - vks::initializers::descriptorImageInfo( - textures.particles.sampler, - textures.particles.fire.view, - VK_IMAGE_LAYOUT_GENERAL) - - writeDescriptorSets = { - // Binding 0: Vertex shader uniform buffer - vks::initializers::writeDescriptorSet( - descriptorSets.particles, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - & uniformBuffers . fire . descriptor), - // Binding 1: Smoke texture - vks::initializers::writeDescriptorSet( - descriptorSets.particles, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - & texDescriptorSmoke), - // Binding 1: Fire texture array - vks::initializers::writeDescriptorSet( - descriptorSets.particles, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 2, - & texDescriptorFire) - } - - vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL) - - // Environment - VK_CHECK_RESULT(vkAllocateDescriptorSets(device, & allocInfo, & descriptorSets . environment)) - - writeDescriptorSets = { - // Binding 0: Vertex shader uniform buffer - vks::initializers::writeDescriptorSet( - descriptorSets.environment, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - & uniformBuffers . environment . descriptor), - // Binding 1: Color map - vks::initializers::writeDescriptorSet( - descriptorSets.environment, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - & textures . floor . colorMap . descriptor), - // Binding 2: Normal map - vks::initializers::writeDescriptorSet( - descriptorSets.environment, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 2, - & textures . floor . normalMap . descriptor), - } - - vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL) - } - - void preparePipelines() - { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = - vks::initializers::pipelineInputAssemblyStateCreateInfo( - VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - 0, - VK_FALSE) - - VkPipelineRasterizationStateCreateInfo rasterizationState = - vks::initializers::pipelineRasterizationStateCreateInfo( - VK_POLYGON_MODE_FILL, - VK_CULL_MODE_BACK_BIT, - VK_FRONT_FACE_CLOCKWISE, - 0) - - VkPipelineColorBlendAttachmentState blendAttachmentState = - vks::initializers::pipelineColorBlendAttachmentState( - 0xf, - VK_FALSE) - - VkPipelineColorBlendStateCreateInfo colorBlendState = - vks::initializers::pipelineColorBlendStateCreateInfo( - 1, - & blendAttachmentState) - - VkPipelineDepthStencilStateCreateInfo depthStencilState = - vks::initializers::pipelineDepthStencilStateCreateInfo( - VK_TRUE, - VK_TRUE, - VK_COMPARE_OP_LESS_OR_EQUAL) - - VkPipelineViewportStateCreateInfo viewportState = - vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0) - - VkPipelineMultisampleStateCreateInfo multisampleState = - vks::initializers::pipelineMultisampleStateCreateInfo( - VK_SAMPLE_COUNT_1_BIT, - 0) - - std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - } - VkPipelineDynamicStateCreateInfo dynamicState = - vks::initializers::pipelineDynamicStateCreateInfo( - dynamicStateEnables.data(), - dynamicStateEnables.size(), - 0) - - // Load shaders - std::array < VkPipelineShaderStageCreateInfo, 2> shaderStages - - VkGraphicsPipelineCreateInfo pipelineCreateInfo = - vks::initializers::pipelineCreateInfo( - pipelineLayout, - renderPass, - 0) - - pipelineCreateInfo.pInputAssemblyState = & inputAssemblyState - pipelineCreateInfo.pRasterizationState = & rasterizationState - pipelineCreateInfo.pColorBlendState = & colorBlendState - pipelineCreateInfo.pMultisampleState = & multisampleState - pipelineCreateInfo.pViewportState = & viewportState - pipelineCreateInfo.pDepthStencilState = & depthStencilState - pipelineCreateInfo.pDynamicState = & dynamicState - pipelineCreateInfo.stageCount = shaderStages.size() - pipelineCreateInfo.pStages = shaderStages.data(); - - // Particle rendering pipeline - { - // Shaders - shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT) - shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) - - // Vertex input state - VkVertexInputBindingDescription vertexInputBinding = - vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, sizeof(Particle), VK_VERTEX_INPUT_RATE_VERTEX) - - std::vector vertexInputAttributes = { - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Particle, pos)), // Location 0: Position - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Particle, color)), // Location 1: Color - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32_SFLOAT, offsetof(Particle, alpha)), // Location 2: Alpha - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32_SFLOAT, offsetof(Particle, size)), // Location 3: Size - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 4, VK_FORMAT_R32_SFLOAT, offsetof(Particle, rotation)), // Location 4: Rotation - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 5, VK_FORMAT_R32_SINT, offsetof(Particle, type)), // Location 5: Particle type - } - - VkPipelineVertexInputStateCreateInfo vertexInputState = vks ::initializers::pipelineVertexInputStateCreateInfo() - vertexInputState.vertexBindingDescriptionCount = 1 - vertexInputState.pVertexBindingDescriptions = & vertexInputBinding - vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()) - vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data() - - pipelineCreateInfo.pVertexInputState = & vertexInputState - - // Dont' write to depth buffer - depthStencilState.depthWriteEnable = VK_FALSE - - // Premulitplied alpha - blendAttachmentState.blendEnable = VK_TRUE - blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE - blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA - blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD - blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE - blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO - blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD - blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT - - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, & pipelineCreateInfo, nullptr, & pipelines . particles)) - } - - // Environment rendering pipeline (normal mapped) - { - // Shaders - shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.vert.spv", VK_SHADER_STAGE_VERTEX_BIT) - shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) - - // Vertex input state - VkVertexInputBindingDescription vertexInputBinding = - vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX) - - std::vector vertexInputAttributes = { - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // Location 1: UV - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 5), // Location 2: Normal - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Location 3: Tangent - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 4, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 11), // Location 4: Bitangen - } - - VkPipelineVertexInputStateCreateInfo vertexInputState = vks ::initializers::pipelineVertexInputStateCreateInfo() - vertexInputState.vertexBindingDescriptionCount = 1 - vertexInputState.pVertexBindingDescriptions = & vertexInputBinding - vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()) - vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data() - - pipelineCreateInfo.pVertexInputState = & vertexInputState - - blendAttachmentState.blendEnable = VK_FALSE - depthStencilState.depthWriteEnable = VK_TRUE - inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST - - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, & pipelineCreateInfo, nullptr, & pipelines . environment)) - } - } - - // Prepare and initialize uniform buffer containing shader uniforms - void prepareUniformBuffers() - { - // Vertex shader uniform buffer block - VK_CHECK_RESULT(vulkanDevice->createBuffer( - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformBuffers.fire, - sizeof(uboVS))) - - // Vertex shader uniform buffer block - VK_CHECK_RESULT(vulkanDevice->createBuffer( - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformBuffers.environment, - sizeof(uboEnv))) - - // Map persistent - VK_CHECK_RESULT(uniformBuffers.fire.map()) - VK_CHECK_RESULT(uniformBuffers.environment.map()) - - updateUniformBuffers() - } - - void updateUniformBufferLight() - { - // Environment - uboEnv.lightPos.x = sin(timer * 2.0f * float(M_PI)) * 1.5f - uboEnv.lightPos.y = 0.0f - uboEnv.lightPos.z = cos(timer * 2.0f * float(M_PI)) * 1.5f - memcpy(uniformBuffers.environment.mapped, & uboEnv, sizeof(uboEnv)) - } - - void updateUniformBuffers() - { - // Vertex shader - glm::mat4 viewMatrix = glm ::mat4(1.0f) - uboVS.projection = glm::perspective(glm::radians(60.0f), (float) width /(float) height, 0.001f, 256.0f) - viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom)) - - uboVS.model = glm::mat4(1.0f) - uboVS.model = viewMatrix * glm::translate(uboVS.model, glm::vec3(0.0f, 15.0f, 0.0f)) - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)) - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)) - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)) - - uboVS.viewportDim = glm::vec2((float) width, (float) height) - memcpy(uniformBuffers.fire.mapped, & uboVS, sizeof(uboVS)) - - // Environment - uboEnv.projection = uboVS.projection - uboEnv.model = uboVS.model - uboEnv.normal = glm::inverseTranspose(uboEnv.model) - uboEnv.cameraPos = glm::vec4(0.0, 0.0, zoom, 0.0) - memcpy(uniformBuffers.environment.mapped, & uboEnv, sizeof(uboEnv)) - } - - void draw() - { - VulkanExampleBase::prepareFrame() - - // Command buffer to be sumitted to the queue - submitInfo.commandBufferCount = 1 - submitInfo.pCommandBuffers = & drawCmdBuffers [currentBuffer] - - // Submit to queue - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, & submitInfo, VK_NULL_HANDLE)) - - VulkanExampleBase::submitFrame() - } - - void prepare() - { - VulkanExampleBase::prepare() - loadAssets() - prepareParticles() - prepareUniformBuffers() - setupDescriptorSetLayout() - preparePipelines() - setupDescriptorPool() - setupDescriptorSets() - buildCommandBuffers() - prepared = true - } - - virtual void render() - { - if (!prepared) - return - draw() - if (!paused) { - updateUniformBufferLight() - updateParticles() - } - } - - virtual void viewChanged() - { - updateUniformBuffers() - } -} - -VULKAN_EXAMPLE_MAIN() \ No newline at end of file +///* +//* Vulkan Example - CPU based fire particle system +//* +//* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de +//* +//* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +//*/ +// +//package vulkan.basics +// +//import glm_.BYTES +//import glm_.L +//import glm_.buffer.adr +//import glm_.buffer.bufferBig +//import glm_.glm +//import glm_.mat4x4.Mat4 +//import glm_.size +//import glm_.vec2.Vec2 +//import glm_.vec3.Vec3 +//import glm_.vec4.Vec4 +//import org.lwjgl.system.MemoryUtil.NULL +//import vkk.* +//import vulkan.VERTEX_BUFFER_BIND_ID +//import vulkan.base.* +//import java.nio.ByteBuffer +//import kotlin.math.abs +//import kotlin.math.cos +//import kotlin.math.sin +// +// +//private const val FLAME_RADIUS = 8f +// +//private object particle { +// const val COUNT = 512 +// const val SIZE = 10f +// +// enum class Type { Flame, Smoke } +//} +// +// +//fun main(args: Array) { +// CpuParticleSystem().apply { +// setupWindow() +// initVulkan() +// prepare() +// renderLoop() +// destroy() +// } +//} +// +//private class CpuParticleSystem : VulkanExampleBase() { +// +// object textures { +// object particles { +// val smoke = Texture2D() +// val fire = Texture2D() +// // Use a custom sampler to change sampler attributes required for rotating the uvs in the shader for alpha blended textures +// var sampler: VkSampler = NULL +// } +// +// object floor { +// val colorMap = Texture2D() +// val normalMap = Texture2D() +// } +// } +// +// // Vertex layout for the models +// val vertexLayout = VertexLayout( +// VertexComponent.POSITION, +// VertexComponent.UV, +// VertexComponent.NORMAL, +// VertexComponent.TANGENT, +// VertexComponent.BITANGENT) +// +// object models { +// val environment = Model() +// } +// +// val emitterPos = Vec3(0f, -FLAME_RADIUS + 2f, 0f) +// val minVel = Vec3(-3f, 0.5f, -3f) +// val maxVel = Vec3(3f, 7f, 3f) +// +// fun rnd(range: Float) = glm.linearRand(0f, range) +// +// private inner class Particle : Bufferizable() { +// val pos = Vec4() +// lateinit var color: Vec4 +// var alpha = 0f +// var size_ = 0f +// var rotation = 0f +// var type = particle.Type.Flame +// // Attributes not used in shader +// lateinit var vel: Vec4 +// var rotationSpeed = 0f +// +// fun init(emitterPos: Vec3) { +// +// vel = Vec4(0f, minVel.y + rnd(maxVel.y - minVel.y), 0f, 0f) +// alpha = rnd(0.75f) +// size_ = 1f + rnd(0.5f) +// color = Vec4(1f) +// type = particle.Type.Flame +// rotation = rnd(2f * glm.PIf) +// rotationSpeed = rnd(2f) - rnd(2f) +// +// // Get random sphere point +// val theta = rnd(2f * glm.PIf) +// val phi = rnd(glm.PIf) - glm.HPIf +// val r = rnd(FLAME_RADIUS) +// +// pos.x = r * cos(theta) * cos(phi) +// pos.y = r * sin(phi) +// pos.z = r * sin(theta) * cos(phi) +// +// pos plusAssign Vec4(emitterPos, 0f) +// } +// } +// +// val particleSize = Vec4.size * 3 + Float.BYTES * 4 + Int.BYTES +// +// object particlesData { +// var buffer: VkBuffer = NULL +// var memory: VkDeviceMemory = 0 +// // Store the mapped address of the particle data for reuse +// var mappedMemory = NULL +// // Size of the particle buffer in bytes +// var size = 0 +// } +// +// object uniformBuffers { +// val fire = Buffer() +// val environment = Buffer() +// } +// +// object uboVS { +// lateinit var projection: Mat4 +// lateinit var model: Mat4 +// lateinit var viewportDim: Vec2 +// val pointSize = particle.SIZE +// } +// +// object uboEnv { +// lateinit var projection: Mat4 +// lateinit var model: Mat4 +// lateinit var normal: Mat4 +// val lightPos = Vec4(0f) +// lateinit var cameraPos: Vec4 +// } +// +// object pipelines { +// var particles: VkPipeline = NULL +// var environment: VkPipeline = NULL +// } +// +// var pipelineLayout: VkPipelineLayout = NULL +// var descriptorSetLayout: VkDescriptorSetLayout = NULL +// +// object descriptorSets { +// var particles: VkDescriptorSet = NULL +// var environment: VkDescriptorSet = NULL +// } +// +// lateinit var particleBuffer: ByteBuffer +// private val particles = ArrayList() +// +// init { +// zoom = -75.0f +// rotation(-15f, 45f, 0f) +// title = "CPU based particle system" +// settings.overlay = true +// zoomSpeed *= 1.5f +// timerSpeed *= 8f +// } +// +// override fun destroy() { +// +// // Clean up used Vulkan resources +// // Note : Inherited destructor cleans up resources stored in base class +// +// textures.particles.smoke.destroy() +// textures.particles.fire.destroy() +// textures.floor.colorMap.destroy() +// textures.floor.normalMap.destroy() +// +// device.apply { +// +// destroyPipeline(pipelines.particles) +// destroyPipeline(pipelines.environment) +// +// destroyPipelineLayout(pipelineLayout) +// destroyDescriptorSetLayout(descriptorSetLayout) +// +// unmapMemory(particlesData.memory) +// destroyBuffer(particlesData.buffer) +// freeMemory(particlesData.memory) +// +// uniformBuffers.environment.destroy() +// uniformBuffers.fire.destroy() +// +// models.environment.destroy() +// +// destroySampler(textures.particles.sampler) +// } +// super.destroy() +// } +// +// override fun buildCommandBuffers() { +// +// val cmdBufInfo = vk.CommandBufferBeginInfo() +// +// val clearValues = vk.ClearValue(2).also { +// it[0].color(defaultClearColor) +// it[1].depthStencil(1f, 0) +// } +// val renderPassBeginInfo = vk.RenderPassBeginInfo { +// renderPass = this@CpuParticleSystem.renderPass +// renderArea.offset(0) +// renderArea.extent(size) +// this.clearValues = clearValues +// } +// for (i in drawCmdBuffers.indices) { +// // Set target frame buffer +// renderPassBeginInfo.framebuffer(frameBuffers[i]) +// +// drawCmdBuffers[i].apply { +// +// begin(cmdBufInfo) +// +// beginRenderPass(renderPassBeginInfo, VkSubpassContents.INLINE) +// +// setViewport(size) +// setScissor(size) +// +// // Environment +// bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSets.environment) +// bindPipeline(VkPipelineBindPoint.GRAPHICS, pipelines.environment) +// bindVertexBuffers(VERTEX_BUFFER_BIND_ID, models.environment.vertices.buffer) +// bindIndexBuffer(models.environment.indices.buffer, 0, VkIndexType.UINT32) +// drawIndexed(models.environment.indexCount, 1, 0, 0, 0) +// +// // Particle system (no index buffer) +// bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSets.particles) +// bindPipeline(VkPipelineBindPoint.GRAPHICS, pipelines.particles) +// bindVertexBuffers(VERTEX_BUFFER_BIND_ID, particlesData.buffer) +// draw(particle.COUNT, 1, 0, 0) +// +// endRenderPass() +// +// end() +// } +// } +// } +// +// +// private fun Particle.transition() = when (type) { +// particle.Type.Flame -> { +// // Flame particles have a chance of turning into smoke +// if (rnd(1f) < 0.05f) { +// alpha = 0f +// color = Vec4(0.25f + rnd(0.25f)) +// pos.x *= 0.5f +// pos.z *= 0.5f +// vel = Vec4(rnd(1f) - rnd(1f), (minVel.y * 2) + rnd(maxVel.y - minVel.y), rnd(1f) - rnd(1f), 0f) +// size_ = 1f + rnd(0.5f) +// rotationSpeed = rnd(1f) - rnd(1f) +// type = particle.Type.Smoke +// } else init(emitterPos) +// } +// // Respawn at end of life +// particle.Type.Smoke -> init(emitterPos) +// } +// +// fun prepareParticles() { +// +// particles += List(particle.COUNT) { +// Particle().apply { +// init(emitterPos) +// alpha = 1f - abs(pos.y) / (FLAME_RADIUS * 2f) +// } +// } +// +// particleBuffer = bufferBig(particleSize * particles.size) +// +// for (i in particles.indices) +// particles[i] to (particleBuffer.adr + particleSize * i) +// +// particlesData.size = particleBuffer.size +// +// vulkanDevice.createBuffer( +// VkBufferUsage.VERTEX_BUFFER_BIT.i, +// VkMemoryProperty.HOST_VISIBLE_BIT or VkMemoryProperty.HOST_COHERENT_BIT, +// particlesData.size.L, +// particlesData::buffer, +// particlesData::memory, +// particleBuffer.adr) +// +// // Map the memory and store the pointer for reuse +// particlesData.mappedMemory = device.mapMemory(particlesData.memory, 0, particlesData.size.L) +// } +// +// void updateParticles() +// { +// float particleTimer = frameTimer * 0.45f +// for (auto& particle : particleBuffer) +// { +// switch(particle.type) +// { +// case PARTICLE_TYPE_FLAME : +// particle.pos.y -= particle.vel.y * particleTimer * 3.5f +// particle.alpha += particleTimer * 2.5f +// particle.size -= particleTimer * 0.5f +// break +// case PARTICLE_TYPE_SMOKE : +// particle.pos -= particle.vel * frameTimer * 1.0f +// particle.alpha += particleTimer * 1.25f +// particle.size += particleTimer * 0.125f +// particle.color -= particleTimer * 0.05f +// break +// } +// particle.rotation += particleTimer * particle.rotationSpeed +// // Transition particle state +// if (particle.alpha > 2.0f) { +// transitionParticle(& particle) +// } +// } +// size_t size = particleBuffer . size () * sizeof(Particle) +// memcpy(particles.mappedMemory, particleBuffer.data(), size) +// } +// +// void loadAssets() +// { +// // Textures +// std::string texFormatSuffix +// VkFormat texFormat +// // Get supported compressed texture format +// if (vulkanDevice->features.textureCompressionBC) { +// texFormatSuffix = "_bc3_unorm" +// texFormat = VK_FORMAT_BC3_UNORM_BLOCK +// } +// else if (vulkanDevice->features.textureCompressionASTC_LDR) { +// texFormatSuffix = "_astc_8x8_unorm" +// texFormat = VK_FORMAT_ASTC_8x8_UNORM_BLOCK +// } +// else if (vulkanDevice->features.textureCompressionETC2) { +// texFormatSuffix = "_etc2_unorm" +// texFormat = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK +// } +// else { +// vks::tools::exitFatal("Device does not support any compressed texture format!", VK_ERROR_FEATURE_NOT_PRESENT) +// } +// +// // Particles +// textures.particles.smoke.loadFromFile(getAssetPath() + "textures/particle_smoke.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue) +// textures.particles.fire.loadFromFile(getAssetPath() + "textures/particle_fire.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue) +// +// // Floor +// textures.floor.colorMap.loadFromFile(getAssetPath() + "textures/fireplace_colormap" + texFormatSuffix + ".ktx", texFormat, vulkanDevice, queue) +// textures.floor.normalMap.loadFromFile(getAssetPath() + "textures/fireplace_normalmap" + texFormatSuffix + ".ktx", texFormat, vulkanDevice, queue) +// +// // Create a custom sampler to be used with the particle textures +// // Create sampler +// VkSamplerCreateInfo samplerCreateInfo = vks ::initializers::samplerCreateInfo() +// samplerCreateInfo.magFilter = VK_FILTER_LINEAR +// samplerCreateInfo.minFilter = VK_FILTER_LINEAR +// samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR +// // Different address mode +// samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER +// samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU +// samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU +// samplerCreateInfo.mipLodBias = 0.0f +// samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER +// samplerCreateInfo.minLod = 0.0f +// // Both particle textures have the same number of mip maps +// samplerCreateInfo.maxLod = float(textures.particles.fire.mipLevels) +// // Enable anisotropic filtering +// samplerCreateInfo.maxAnisotropy = 8.0f +// samplerCreateInfo.anisotropyEnable = VK_TRUE +// // Use a different border color (than the normal texture loader) for additive blending +// samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK +// VK_CHECK_RESULT(vkCreateSampler(device, & samplerCreateInfo, nullptr, & textures . particles . sampler)) +// +// models.environment.loadFromFile(getAssetPath() + "models/fireplace.obj", vertexLayout, 10.0f, vulkanDevice, queue) +// } +// +// void setupDescriptorPool() +// { +// // Example uses one ubo and one image sampler +// std::vector poolSizes = +// { +// vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), +// vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4) +// } +// +// VkDescriptorPoolCreateInfo descriptorPoolInfo = +// vks::initializers::descriptorPoolCreateInfo( +// poolSizes.size(), +// poolSizes.data(), +// 2) +// +// VK_CHECK_RESULT(vkCreateDescriptorPool(device, & descriptorPoolInfo, nullptr, & descriptorPool)) +// } +// +// void setupDescriptorSetLayout() +// { +// std::vector setLayoutBindings = +// { +// // Binding 0 : Vertex shader uniform buffer +// vks::initializers::descriptorSetLayoutBinding( +// VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, +// VK_SHADER_STAGE_VERTEX_BIT, +// 0), +// // Binding 1 : Fragment shader image sampler +// vks::initializers::descriptorSetLayoutBinding( +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// VK_SHADER_STAGE_FRAGMENT_BIT, +// 1), +// // Binding 1 : Fragment shader image sampler +// vks::initializers::descriptorSetLayoutBinding( +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// VK_SHADER_STAGE_FRAGMENT_BIT, +// 2) +// } +// +// VkDescriptorSetLayoutCreateInfo descriptorLayout = +// vks::initializers::descriptorSetLayoutCreateInfo( +// setLayoutBindings.data(), +// setLayoutBindings.size()) +// +// VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, & descriptorLayout, nullptr, & descriptorSetLayout)) +// +// VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = +// vks::initializers::pipelineLayoutCreateInfo( +// & descriptorSetLayout, +// 1) +// +// VK_CHECK_RESULT(vkCreatePipelineLayout(device, & pPipelineLayoutCreateInfo, nullptr, & pipelineLayout)) +// } +// +// void setupDescriptorSets() +// { +// std::vector writeDescriptorSets +// +// VkDescriptorSetAllocateInfo allocInfo = +// vks::initializers::descriptorSetAllocateInfo( +// descriptorPool, +// & descriptorSetLayout, +// 1) +// +// VK_CHECK_RESULT(vkAllocateDescriptorSets(device, & allocInfo, & descriptorSets . particles)) +// +// // Image descriptor for the color map texture +// VkDescriptorImageInfo texDescriptorSmoke = +// vks::initializers::descriptorImageInfo( +// textures.particles.sampler, +// textures.particles.smoke.view, +// VK_IMAGE_LAYOUT_GENERAL) +// VkDescriptorImageInfo texDescriptorFire = +// vks::initializers::descriptorImageInfo( +// textures.particles.sampler, +// textures.particles.fire.view, +// VK_IMAGE_LAYOUT_GENERAL) +// +// writeDescriptorSets = { +// // Binding 0: Vertex shader uniform buffer +// vks::initializers::writeDescriptorSet( +// descriptorSets.particles, +// VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, +// 0, +// & uniformBuffers . fire . descriptor), +// // Binding 1: Smoke texture +// vks::initializers::writeDescriptorSet( +// descriptorSets.particles, +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// 1, +// & texDescriptorSmoke), +// // Binding 1: Fire texture array +// vks::initializers::writeDescriptorSet( +// descriptorSets.particles, +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// 2, +// & texDescriptorFire) +// } +// +// vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL) +// +// // Environment +// VK_CHECK_RESULT(vkAllocateDescriptorSets(device, & allocInfo, & descriptorSets . environment)) +// +// writeDescriptorSets = { +// // Binding 0: Vertex shader uniform buffer +// vks::initializers::writeDescriptorSet( +// descriptorSets.environment, +// VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, +// 0, +// & uniformBuffers . environment . descriptor), +// // Binding 1: Color map +// vks::initializers::writeDescriptorSet( +// descriptorSets.environment, +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// 1, +// & textures . floor . colorMap . descriptor), +// // Binding 2: Normal map +// vks::initializers::writeDescriptorSet( +// descriptorSets.environment, +// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +// 2, +// & textures . floor . normalMap . descriptor), +// } +// +// vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL) +// } +// +// void preparePipelines() +// { +// VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = +// vks::initializers::pipelineInputAssemblyStateCreateInfo( +// VK_PRIMITIVE_TOPOLOGY_POINT_LIST, +// 0, +// VK_FALSE) +// +// VkPipelineRasterizationStateCreateInfo rasterizationState = +// vks::initializers::pipelineRasterizationStateCreateInfo( +// VK_POLYGON_MODE_FILL, +// VK_CULL_MODE_BACK_BIT, +// VK_FRONT_FACE_CLOCKWISE, +// 0) +// +// VkPipelineColorBlendAttachmentState blendAttachmentState = +// vks::initializers::pipelineColorBlendAttachmentState( +// 0xf, +// VK_FALSE) +// +// VkPipelineColorBlendStateCreateInfo colorBlendState = +// vks::initializers::pipelineColorBlendStateCreateInfo( +// 1, +// & blendAttachmentState) +// +// VkPipelineDepthStencilStateCreateInfo depthStencilState = +// vks::initializers::pipelineDepthStencilStateCreateInfo( +// VK_TRUE, +// VK_TRUE, +// VK_COMPARE_OP_LESS_OR_EQUAL) +// +// VkPipelineViewportStateCreateInfo viewportState = +// vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0) +// +// VkPipelineMultisampleStateCreateInfo multisampleState = +// vks::initializers::pipelineMultisampleStateCreateInfo( +// VK_SAMPLE_COUNT_1_BIT, +// 0) +// +// std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, +// VK_DYNAMIC_STATE_SCISSOR +// } +// VkPipelineDynamicStateCreateInfo dynamicState = +// vks::initializers::pipelineDynamicStateCreateInfo( +// dynamicStateEnables.data(), +// dynamicStateEnables.size(), +// 0) +// +// // Load shaders +// std::array < VkPipelineShaderStageCreateInfo, 2> shaderStages +// +// VkGraphicsPipelineCreateInfo pipelineCreateInfo = +// vks::initializers::pipelineCreateInfo( +// pipelineLayout, +// renderPass, +// 0) +// +// pipelineCreateInfo.pInputAssemblyState = & inputAssemblyState +// pipelineCreateInfo.pRasterizationState = & rasterizationState +// pipelineCreateInfo.pColorBlendState = & colorBlendState +// pipelineCreateInfo.pMultisampleState = & multisampleState +// pipelineCreateInfo.pViewportState = & viewportState +// pipelineCreateInfo.pDepthStencilState = & depthStencilState +// pipelineCreateInfo.pDynamicState = & dynamicState +// pipelineCreateInfo.stageCount = shaderStages.size() +// pipelineCreateInfo.pStages = shaderStages.data(); +// +// // Particle rendering pipeline +// { +// // Shaders +// shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/particle.vert.spv", VK_SHADER_STAGE_VERTEX_BIT) +// shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/particle.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) +// +// // Vertex input state +// VkVertexInputBindingDescription vertexInputBinding = +// vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, sizeof(Particle), VK_VERTEX_INPUT_RATE_VERTEX) +// +// std::vector vertexInputAttributes = { +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Particle, pos)), // Location 0: Position +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Particle, color)), // Location 1: Color +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32_SFLOAT, offsetof(Particle, alpha)), // Location 2: Alpha +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32_SFLOAT, offsetof(Particle, size)), // Location 3: Size +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 4, VK_FORMAT_R32_SFLOAT, offsetof(Particle, rotation)), // Location 4: Rotation +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 5, VK_FORMAT_R32_SINT, offsetof(Particle, type)), // Location 5: Particle type +// } +// +// VkPipelineVertexInputStateCreateInfo vertexInputState = vks ::initializers::pipelineVertexInputStateCreateInfo() +// vertexInputState.vertexBindingDescriptionCount = 1 +// vertexInputState.pVertexBindingDescriptions = & vertexInputBinding +// vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()) +// vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data() +// +// pipelineCreateInfo.pVertexInputState = & vertexInputState +// +// // Dont' write to depth buffer +// depthStencilState.depthWriteEnable = VK_FALSE +// +// // Premulitplied alpha +// blendAttachmentState.blendEnable = VK_TRUE +// blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE +// blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA +// blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD +// blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE +// blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO +// blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD +// blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT +// +// VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, & pipelineCreateInfo, nullptr, & pipelines . particles)) +// } +// +// // Environment rendering pipeline (normal mapped) +// { +// // Shaders +// shaderStages[0] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.vert.spv", VK_SHADER_STAGE_VERTEX_BIT) +// shaderStages[1] = loadShader(getAssetPath() + "shaders/particlefire/normalmap.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT) +// +// // Vertex input state +// VkVertexInputBindingDescription vertexInputBinding = +// vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX) +// +// std::vector vertexInputAttributes = { +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // Location 1: UV +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 5), // Location 2: Normal +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Location 3: Tangent +// vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 4, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 11), // Location 4: Bitangen +// } +// +// VkPipelineVertexInputStateCreateInfo vertexInputState = vks ::initializers::pipelineVertexInputStateCreateInfo() +// vertexInputState.vertexBindingDescriptionCount = 1 +// vertexInputState.pVertexBindingDescriptions = & vertexInputBinding +// vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()) +// vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data() +// +// pipelineCreateInfo.pVertexInputState = & vertexInputState +// +// blendAttachmentState.blendEnable = VK_FALSE +// depthStencilState.depthWriteEnable = VK_TRUE +// inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST +// +// VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, & pipelineCreateInfo, nullptr, & pipelines . environment)) +// } +// } +// +// // Prepare and initialize uniform buffer containing shader uniforms +// void prepareUniformBuffers() +// { +// // Vertex shader uniform buffer block +// VK_CHECK_RESULT(vulkanDevice->createBuffer( +// VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, +// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, +// &uniformBuffers.fire, +// sizeof(uboVS))) +// +// // Vertex shader uniform buffer block +// VK_CHECK_RESULT(vulkanDevice->createBuffer( +// VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, +// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, +// &uniformBuffers.environment, +// sizeof(uboEnv))) +// +// // Map persistent +// VK_CHECK_RESULT(uniformBuffers.fire.map()) +// VK_CHECK_RESULT(uniformBuffers.environment.map()) +// +// updateUniformBuffers() +// } +// +// void updateUniformBufferLight() +// { +// // Environment +// uboEnv.lightPos.x = sin(timer * 2.0f * float(M_PI)) * 1.5f +// uboEnv.lightPos.y = 0.0f +// uboEnv.lightPos.z = cos(timer * 2.0f * float(M_PI)) * 1.5f +// memcpy(uniformBuffers.environment.mapped, & uboEnv, sizeof(uboEnv)) +// } +// +// void updateUniformBuffers() +// { +// // Vertex shader +// glm::mat4 viewMatrix = glm ::mat4(1.0f) +// uboVS.projection = glm::perspective(glm::radians(60.0f), (float) width /(float) height, 0.001f, 256.0f) +// viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom)) +// +// uboVS.model = glm::mat4(1.0f) +// uboVS.model = viewMatrix * glm::translate(uboVS.model, glm::vec3(0.0f, 15.0f, 0.0f)) +// uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)) +// uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)) +// uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)) +// +// uboVS.viewportDim = glm::vec2((float) width, (float) height) +// memcpy(uniformBuffers.fire.mapped, & uboVS, sizeof(uboVS)) +// +// // Environment +// uboEnv.projection = uboVS.projection +// uboEnv.model = uboVS.model +// uboEnv.normal = glm::inverseTranspose(uboEnv.model) +// uboEnv.cameraPos = glm::vec4(0.0, 0.0, zoom, 0.0) +// memcpy(uniformBuffers.environment.mapped, & uboEnv, sizeof(uboEnv)) +// } +// +// void draw() +// { +// VulkanExampleBase::prepareFrame() +// +// // Command buffer to be sumitted to the queue +// submitInfo.commandBufferCount = 1 +// submitInfo.pCommandBuffers = & drawCmdBuffers [currentBuffer] +// +// // Submit to queue +// VK_CHECK_RESULT(vkQueueSubmit(queue, 1, & submitInfo, VK_NULL_HANDLE)) +// +// VulkanExampleBase::submitFrame() +// } +// +// void prepare() +// { +// VulkanExampleBase::prepare() +// loadAssets() +// prepareParticles() +// prepareUniformBuffers() +// setupDescriptorSetLayout() +// preparePipelines() +// setupDescriptorPool() +// setupDescriptorSets() +// buildCommandBuffers() +// prepared = true +// } +// +// virtual void render() +// { +// if (!prepared) +// return +// draw() +// if (!paused) { +// updateUniformBufferLight() +// updateParticles() +// } +// } +// +// virtual void viewChanged() +// { +// updateUniformBuffers() +// } +//} +// +//VULKAN_EXAMPLE_MAIN() \ No newline at end of file diff --git a/src/main/kotlin/vulkan/computeShader/01 Image Processing.kt b/src/main/kotlin/vulkan/computeShader/01 Image Processing.kt index fa58578..6418b4b 100644 --- a/src/main/kotlin/vulkan/computeShader/01 Image Processing.kt +++ b/src/main/kotlin/vulkan/computeShader/01 Image Processing.kt @@ -573,7 +573,7 @@ private class ImageProcessing : VulkanExampleBase() { .rotateAssign(rotation.z.rad, 0f, 0f, 1f) uboVS.pack() - memCopy(uboVS.address, uniformBufferVS.mapped[0], uboVS.size.L) + memCopy(uboVS.address, uniformBufferVS.mapped, uboVS.size.L) } fun draw() { diff --git a/src/main/kotlin/vulkan/computeShader/02 Gpu Particle System.kt b/src/main/kotlin/vulkan/computeShader/02 Gpu Particle System.kt index a00ed1b..7ba64d3 100644 --- a/src/main/kotlin/vulkan/computeShader/02 Gpu Particle System.kt +++ b/src/main/kotlin/vulkan/computeShader/02 Gpu Particle System.kt @@ -499,7 +499,7 @@ class GpuParticleSystem : VulkanExampleBase() { } compute.ubo.pack() - memCopy(compute.ubo.address, compute.uniformBuffer.mapped[0], compute.ubo.size.L) + memCopy(compute.ubo.address, compute.uniformBuffer.mapped, compute.ubo.size.L) } fun draw() { diff --git a/src/main/kotlin/vulkan/computeShader/03 N-Body Simulation.kt b/src/main/kotlin/vulkan/computeShader/03 N-Body Simulation.kt index 5ce0439..2002a82 100644 --- a/src/main/kotlin/vulkan/computeShader/03 N-Body Simulation.kt +++ b/src/main/kotlin/vulkan/computeShader/03 N-Body Simulation.kt @@ -627,7 +627,7 @@ private class NBodySimulation : VulkanExampleBase() { compute.ubo.deltaT = if (paused) 0f else frameTimer * 0.05f compute.ubo.dest(sin((timer * 360f).rad) * 0.75f, 0f) compute.ubo.pack() - memCopy(compute.ubo.address, compute.uniformBuffer.mapped[0], compute.ubo.size.L) + memCopy(compute.ubo.address, compute.uniformBuffer.mapped, compute.ubo.size.L) } fun updateGraphicsUniformBuffers() { @@ -635,7 +635,7 @@ private class NBodySimulation : VulkanExampleBase() { graphics.ubo.view put camera.matrices.view graphics.ubo.screenDim(size) compute.ubo.pack() - memCopy(graphics.ubo.address, graphics.uniformBuffer.mapped[0], graphics.ubo.size.L) + memCopy(graphics.ubo.address, graphics.uniformBuffer.mapped, graphics.ubo.size.L) } fun draw() {