{.experimental: "codeReordering".}
{.deadCodeElim: on.}
#TODO: REBUILD render_Pass_begin_info on window size change
import ../vk/[ vulkan_record
, vulkan_utils
, vulkan
, depth_stencil
, swapchain
, buffer
]
, scene_object
, scene_record
, ../deshn_entity/[ being
]
, ../drawable/[ shape_object
, text_types
, plane
]
, ../wain/[ waindow_object
]
, std/[ tables
, bitops
]
, glm
proc a_scene*( vk_record: var Vulkan_Record
): Scene =
result = Scene()
result.entities = newTable[string, int]()
proc theIds*(scene: Scene): seq[int] =
for t in scene.shapes: result.add t.id
proc theNames*(scene: Scene): seq[string] =
for t in scene.shapes: result.add t.name
proc the_shape*( scene: var Scene
, id: int
, name: string
): var Shape =
for t in scene.shapes.mitems:
if t.id == id: return t
quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)
proc the_shape*( scene: var Scene
, name: string
): var Shape =
scene.the_shape scene.entities[name], name
proc the_deshn_being*( scene: var Scene
, id: int
, name: string
): var Deshn_Being =
for t in scene.deshn_beings.mitems:
if t.id == id: return t
quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)
proc the_deshn_being*( scene: var Scene
, name: string
): var Deshn_Being =
scene.the_deshn_being scene.entities[name], name
#[ proc the_text*( scene: Scene
, id: int
, name: string
): var SDFText =
#WARNING]: Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit]
for t in scene.texts.mitems:
if t.id == id: return t
quit("ERROR: Entity[SDFTEXT] not found: " & name & " / id:" & $id)
proc the_text*( scene: Scene
, name: string
): var SDFText = scene.the_text scene.entities[name], name ]#
# # TODO: need drawable-independent command buffers
# proc build*( vk_record: Vulkan_Record
# , scene: var Scene
# ) =
proc the_plane*( scene: var Scene
, id: int
, name: string
): var Plane =
for t in scene.planes.mitems:
if t.id == id: return t
quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)
proc the_plane*( scene: var Scene
, name: string
): var Plane =
scene.the_plane scene.entities[name], name
proc add*( scene: var Scene
, shape: Shape
) =
#echo "adding: ", sh.name, " ", sh.id
scene.shapes.add shape
scene.entities[shape.name] = shape.id
scene.current_entity_id += 1
scene.the_vertices.add shape.vertices
scene.the_indices.add shape.indices
#[ proc add*( scene: var Scene
, text: SDFText
) =
scene.texts.add text
scene.entities[text.name] = scene.current_entity_id
scene.current_entity_id += 1
for text_vert in text.vertices:
scene.the_vertices.add text_vert.pos.x
scene.the_vertices.add text_vert.pos.y
scene.the_vertices.add text_vert.pos.z
scene.the_vertices.add text_vert.uv.x
scene.the_vertices.add text_vert.uv.y
scene.the_indices.add text.indices
]#
proc add*( scene: var Scene
, deshn_being: Deshn_Being
) =
#echo "adding: ", sh.name, " ", sh.id
scene.deshn_beings.add deshn_being
scene.entities[deshn_being.name] = deshn_being.id
scene.current_entity_id += 1
scene.add deshn_being.shape
proc add*( scene: var Scene
, plane: Plane
) =
#echo "adding: ", sh.name, " ", sh.id
scene.planes.add plane
scene.entities[plane.name] = plane.id
scene.current_entity_id += 1
scene.add plane.shape
proc prepare_vertices*( scene: var Scene
, vk_device: VkDevice
, memory_properties: VkPhysicalDeviceMemoryProperties
, command_pool: VkCommandPool
, queue: VkQueue
, master_vertex_buffer: var Buffer
, master_index_buffer: var Buffer
) =
var
copyCmd: VkCommandBuffer = vk_device.getCommandBuffers(command_pool, true)
copyRegion: VkBufferCopy
data: pointer
#[ copyMem( data, addr scene.the_vertices[0]
, Natural scene.the_vertices.sizeof
)
vkUnmapMemory( vk_device
, scene.staging_vertex_buffer.device_memory
)
discard vkBindBufferMemory( vk_device
, scene.staging_vertex_buffer.vkbuffer
, scene.staging_vertex_buffer.device_memory
, VkDeviceSize 0
)
discard vkBindBufferMemory( vk_device
, scene.vertex_buffer.vkbuffer
, scene.vertex_buffer.device_memory
, VkDeviceSize 0
)
scene.staging_index_buffer = a_vulkan_buffer( vk_device
, memory_properties
, VkBufferUsageFlags VK_BUFFER_USAGE_TRANSFER_SRC_BIT
, VkMemoryPropertyFlags bitor( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.ord
, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT.ord
)
, VkDeviceSize scene.the_indices.sizeof
)
scene.index_buffer = a_vulkan_buffer( vk_device
, memory_properties
, VkBufferUsageFlags bitor(VK_BUFFER_USAGE_INDEX_BUFFER_BIT.ord, VK_BUFFER_USAGE_TRANSFER_DST_BIT.ord)
, VkMemoryPropertyFlags VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
, VkDeviceSize scene.the_indices.sizeof
)
vk_device.map_memory( scene.staging_index_buffer.device_memory
, data
)
copyMem(data, addr scene.the_indices[0], Natural scene.the_indices.sizeof)
vkUnmapMemory(vk_device, scene.staging_index_buffer.device_memory)
discard vkBindBufferMemory(vk_device, scene.staging_index_buffer.vkbuffer, scene.staging_index_buffer.device_memory, VkDeviceSize 0)
discard vkBindBufferMemory(vk_device, scene.index_buffer.vkbuffer, scene.index_buffer.device_memory, VkDeviceSize 0)
copyRegion.size = VkDeviceSize scene.the_vertices.sizeof
vkCmdCopyBuffer(copyCmd, scene.staging_vertex_buffer.vkbuffer, scene.vertex_buffer.vkbuffer, 1.uint32, addr copyRegion)
copyRegion.size = VkDeviceSize scene.the_indices.sizeof
vkCmdCopyBuffer(copyCmd, scene.staging_index_buffer.vkbuffer, scene.index_buffer.vkbuffer, 1.uint32, addr copyRegion)
# # Flushing the command buffer will also submit it to the queue and
# # uses a fence to ensure that all commands have been executed before returning
vk_device.flushCommandBuffer queue, command_pool, copyCmd
# Destroy staging buffers
# Note: Staging buffer must not be deleted before the copies have been submitted and executed
vkDestroyBuffer( vk_device
, scene.staging_vertex_buffer.vkbuffer
, nil
)
vkFreeMemory( vk_device
, scene.staging_vertex_buffer.device_memory
, nil
)
vkDestroyBuffer( vk_device
, scene.staging_index_buffer.vkbuffer
, nil
)
vkFreeMemory( vk_device
, scene.staging_index_buffer.device_memory
, nil
) ]#
proc clean_up*( vk_record: var Vulkan_Record
, scene: var Scene
) =
discard vkDeviceWaitIdle vk_record.vk_device
# recycle the Pools!
# vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL)
# vkDestroyCommandPool(demo->device, demo->command_pool, NULL);
#should we have an initial "setup command buffer"?
#[ for shape in scene.shapes:
vk_record.vk_device.vkDestroyPipeline(shape.graphicsPipeline.pipeline, nil)
vk_record.vk_device.vkDestroyPipelineLayout(shape.graphicsPipeline.pipelineLayout, nil)
vk_record.vk_device.vkDestroyDescriptorSetLayout(shape.descrSetLayout, nil)
for text in scene.texts:
vk_record.vk_device.vkDestroyPipeline(text.graphicsPipeline.pipeline, nil)
vk_record.vk_device.vkDestroyPipelineLayout(text.graphicsPipeline.pipelineLayout, nil)
vk_record.vk_device.vkDestroyDescriptorSetLayout(text.descrSetLayout, nil) ]#
#[ for i,fb in vk_record.draw_command_buffers:
vkFreeCommandBuffers( vk_record.vk_device
, vk_record.command_pool
, 1
, addr vk_record.draw_command_buffers[i]
)
vk_record.vk_device.vkDestroyRenderPass(scene.render_pass, nil) ]#
#[
proc rebuild_render_pass_info*( vk_record: var Vulkan_Record
, scene: var Scene
) =
var
scissor = VkRect2D( extent: VkExtent2D( width: uint32 vk_record.swapchain.current_extent.width
, height: uint32 vk_record.swapchain.current_extent.height
)
, offset: VkOffset2D( x: 0
, y: 0
)
)
renderPassBeginInfo = VkRenderPassBeginInfo(sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO)
clearValues: array[2,VkClearValue]
clearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f])
clearValues[1].depth_stencil = VkClearDepthStencilValue( depth: 1.0f
, stencil: 0
)
renderPassBeginInfo.pNext = nil
renderPassBeginInfo.renderArea.offset.x = 0
renderPassBeginInfo.renderArea.offset.y = 0
renderPassBeginInfo.renderArea.extent.width = uint32 vk_record.swapchain.current_extent.width
renderPassBeginInfo.renderArea.extent.height = uint32 vk_record.swapchain.current_extent.height
renderPassBeginInfo.clearValueCount = 2
renderPassBeginInfo.pClearValues = addr clearValues[0]
renderPassBeginInfo.render_pass = scene.render_pass
renderPassBeginInfo.framebuffer = vk_record.frame_buffers[vk_record.currentFrameBuffer]
scene[].render_pass_begin_info = renderPassBeginInfo
scene[].scissor = scissor ]#