7P4O3MAXN2LHNTNUNJXGMAG3RWHFDQQAE3VPWKIB4ERINQNSD4BAC , vk/[ vulkan, vkTypes, vulkan_record, pipeline_record], scenes/[ scene_object, scene_utils, scene_record, main_scenes]import drawable/text as mtextimport scenes/intro as sIntroimport scenes/title as sTitle#TODO: Figure out a way to auto-sync or get rid of current_scene and the_main_scene# so we only need to worry about one to know and go to the proper sceneproc load*( sr: var Scene_Record, rec: var Vulkan_Record, pipeline_record: Pipeline_Record) = discard#sTitle.load rec, title#sIntro.load rec, intro#case sr.the_main_scene#of Main_Scene_Enum.Intro: sr.current_scene = sr.get_scene "intro"#of Main_Scene_Enum.Title: sr.current_scene = sr.get_scene "title"proc update*( sr: var Scene_Record, rec: var Vulkan_Record, fps: string, tick_rate: float32) = discard#[ case sr.the_main_sceneof Main_Scene_Enum.Title:sr.current_scene = sr.get_scene "title"sTitle.update rec, sr.current_scene[]of Main_Scene_Enum.Intro:sr.current_scene = sr.get_scene "intro"sIntro.update rec, sr.current_scene[], sr, fps ]#proc input*( sr: var Scene_Record, rec: var Vulkan_Record) = discard#[ case sr.the_main_sceneof Main_Scene_Enum.Title: sTitle.input rec, srof Main_Scene_Enum.Intro: sIntro.input rec, sr ]##of Main_Scene_Enum.alive: discard #alive.input(w, hero)proc show*( sr: Scene_Record, rec: var Vulkan_Record, pipeline_record: Pipeline_Record) = discard#[ case sr.the_main_sceneof Main_Scene_Enum.Title:sTitle.show rec, sr.current_scene[]of Main_Scene_Enum.Intro: sIntro.show( rec, sr.current_scene[], pipeline_record) ]## of Main_Scene_Enum.alive: discard #alive.input(w, hero)proc prepFrame*(rec: var Vulkan_Record, sr: var Scene_Record, pipeline_record: Pipeline_Record) =discard vkAcquireNextImageKHR( rec.vk_device, rec.swapChain.handle, uint64.high, rec.presentCompleteSemaphore, VkFence 0, addr rec.currentFrameBuffer)discard vkWaitForFences(rec.vk_device, 1, addr rec.fences[rec.currentFrameBuffer], VKBool32 true, uint64.high)discard vkResetFences(rec.vk_device, 1, addr rec.fences[rec.currentFrameBuffer])sr.show rec, pipeline_recordproc submitFrame*( current_frame_buffer: uint32, render_complete_semaphore: VkSemaphore, queue: VkQueue#, scene: var Scene, present_info: var VkPresentInfoKHR) =#for shape in scene.shapes.mitems:#if shape.changed: rec.vk_device.updateCamera shape#[ for text in scene.texts.mitems:if text.changed:text.updateCamera ]## THE M A G I C (presenting) queuePresent#[ var presentInfo: VkPresentInfoKHRpresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHRpresentInfo.pNext = nilpresentInfo.swapchainCount = 1presentInfo.pSwapchains = addr rec.swapChain.swapChainKHR ]#present_info.pImageIndices = addr current_frame_buffer #rec.currentFrameBuffer# Check if a wait semaphore has been specified to wait for# before presenting the imageif (render_complete_semaphore.int != 0):presentInfo.pWaitSemaphores = addr render_complete_semaphorepresentInfo.waitSemaphoreCount = 1#TODO: WHY DOES THIS MEMORY LEAK EVERY FRAMEvar preres = vkQueuePresentKHR( queue, addr presentInfo)#if preres == VK_SUBOPTIMAL_KHR: quit "bad vkQueuePresentKHR"# rec.windowResize scene# scene.rebuild rec# discard vkDeviceWaitIdle rec.vk_device# rec.readyFrame = trueproc sendFrame*(rec: var Vulkan_Record, sr: var Scene_Record, pipeline_record: Pipeline_Record, present_info: var VkPresentInfoKHR) =if rec.readyFrame:rec.prepFrame sr, pipeline_recordvarwaitStageMask = VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BITsubmitInfo = VkSubmitInfo(sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, pWaitDstStageMask: addr waitStageMask, pWaitSemaphores: addr rec.presentCompleteSemaphore, waitSemaphoreCount: 1, pSignalSemaphores: addr rec.renderCompleteSemaphore, commandBufferCount: 1, pCommandBuffers: addr rec.draw_command_buffers[rec.currentFrameBuffer], signalSemaphoreCount: 1)discard vkQueueSubmit( rec.queue, 1, submitInfo.addr, rec.fences[rec.currentFrameBuffer])submitFrame( rec.currentFrameBuffer, rec.renderCompleteSemaphore, rec.queue, present_info)#rec.readyFrame = falseimport wain/window
{.experimental: "parallel".}import scene_object, scene_utils, scene_record, ../vk/[ vulkan, vkTypes, vulkan_record, graphics_pipeline, pipeline_record, buffer, gpu, vulkan_utils], ../drawable/[ shape_object, shape_types, plane, colors, grid], ../drawable/text as mText, ../deshn_entity/[ being, actions], glm, strUtils, ../camera, std/tables, ../state_machine, optionsproc load*( vulkan_record: var Vulkan_Record, pipeline_record: Pipeline_Record, intro: var Scene, scene_record: var Scene_Record) =varprotag_shape = a_shape( vulkan_record, pipeline_record, intro.render_pass, intro.current_entity_id, 3, "protag_tri", theSize = vec2f( 4.5, 4.5), being_color = silver_blue, deshn_color = yellow, camera_type = Camera_Kind.Perspective, hollow = false)#[ intro.add Plane( shape: a_shape( vulkan_record, pipeline_record, intro.render_pass, intro.current_entity_id, 4, "plane0_quad", theSize = vec2f( 80, 40), being_color = dark_purple, deshn_color = yellow, camera_type = Camera_Kind.Perspective, hollow = false), name: "plane0", grid: a_dynamic_grid( 10, 10, vulkan_record, intro.render_pass, pipeline_record, intro.current_entity_id, parent_buffer)) ]#intro.add( a_deshn_being( shape = protag_shape, name = "protag"))#[ intro.the_deshn_being("protag").move_to( (vulkan_record.swapchain.current_extent.width.int / 2).float32, (vulkan_record.swapchain.current_extent.height.int / 2).float32)intro.the_plane("plane0").move_to( (vulkan_record.swapchain.current_extent.width.int / 2).float32, (vulkan_record.swapchain.current_extent.height.int / 2).float32) ]#intro.the_deshn_being("protag").shape.camera.position_is vec3f(0.0,0.0,-50.0)# intro.the_shape("plane0_quad").camera.position_is vec3f(0.0,0.0,-50.0)scene_record.add_scene( addr intro, "intro")intro.the_deshn_being("protag").main_state_machine.current_state = some Main_Deshn_Being_States.Idleintro.indirect_commands.setLen intro.current_entity_idfor i in 0..intro.current_entity_id - 1:intro.indirect_commands[i].instanceCount = 1intro.indirect_commands[i].firstInstance = 1intro.indirect_commands[i].firstIndex = 0intro.indirect_commands[i].indexCount = 1#echo intro.the_deshn_being("protag").main_state_machine.transitionsprepare_vertices( intro, vulkan_record.vk_device, vulkan_record.gpu.memory_properties, vulkan_record.command_pool, vulkan_record.queue, vulkan_record.master_vertex_buffer, vulkan_record.master_index_buffer)proc input*( vulkan_record: var Vulkan_Record, sr: var Scene_Record) = discardproc update*( vulkan_record: var Vulkan_Record, intro: var Scene, sr: var Scene_Record, fps: string) =varprotag = intro.the_deshn_being("protag")# plane = intro.the_plane("plane0")protag.shape.camera.position_is vec3f( protag.shape.camera.position.xy, protag.shape.camera.position.z + 0.1)protag.shape.camera.position_is vec3f( protag.shape.camera.position.xy, protag.shape.camera.position.z - 0.1)plane.shape.camera.position_is vec3f( plane.shape.camera.position.xy, plane.shape.camera.position.z + 0.1)plane.shape.camera.position_is vec3f( plane.shape.camera.position.xy, plane.shape.camera.position.z - 0.1) ]#protag.move_up 1protag.move_down 1protag.move_left 1protag.move_right 1not protag.recovering:protag.current_state_is Not_Movingif not protag.deshn_pool_is_full andnot protag.recovering:# echo "NOT moving, adding."protag.add_amount_to_deshn_pool 0.03else:#echo "can't add because: " , protag.deshn_pool_is_full, " <> ", protag.recoveringdiscardif protag.recovering:#echo "RECOVERING: ", protag.current_deshn_pool_recovery_poolprotag.add_amount_to_recovery_pool 0.01proc build_command_buffers*( draw_command_buffer: var VkCommandBuffer, scene: var Scene, graphics_pipeline: Graphics_Pipeline, descriptor_set: VkDescriptorSet, gpu: GPU, vulkan_record: var Vulkan_Record, indirect_command_buffer: var Buffer) =varcommand_buffer_info = VkCommandBufferBeginInfo(sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)scissor: VkRect2DclearValues: array[2,VkClearValue]render_pass_info: VkRenderPassBeginInfooffsets = VkDeviceSize 0viewport = VkViewport( width: float32 vulkan_record.swapchain.current_extent.width, height: float32 vulkan_record.swapchain.current_extent.height, minDepth: 0.0f, maxDepth: 1.0f)scissor.extent.width = uint32 vulkan_record.swapchain.current_extent.widthscissor.extent.height = uint32 vulkan_record.swapchain.current_extent.heightscissor.offset.x = 0scissor.offset.y = 0clearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrender_pass_info.pNext = nilrender_pass_info.renderArea.offset.x = 0render_pass_info.renderArea.offset.y = 0render_pass_info.renderArea.extent.width = uint32 vulkan_record.swapchain.current_extent.widthrender_pass_info.renderArea.extent.height = uint32 vulkan_record.swapchain.current_extent.heightrender_pass_info.clearValueCount = 2render_pass_info.pClearValues = addr clearValues[0]render_pass_info.render_pass = scene.render_passfor i in 0 .. vulkan_record.draw_command_buffers.len:render_pass_info.framebuffer = vulkan_record.frame_buffers[i]discard vkBeginCommandBuffer( vulkan_record.draw_command_buffers[i], addr command_buffer_info)vkCmdBeginRenderPass( vulkan_record.draw_command_buffers[i], addr render_pass_info, VK_SUBPASS_CONTENTS_INLINE)vkCmdSetViewport( vulkan_record.draw_command_buffers[i], 0, 1, addr vulkan_record.current_viewport)vkCmdSetScissor( vulkan_record.draw_command_buffers[i], 0, 1, addr scissor)vkCmdBindDescriptorSets( vulkan_record.draw_command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline.pipeline_layout, 0, 1, addr descriptor_set, 0, nil)vkCmdBindPipeline( vulkan_record.draw_command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline.pipeline)vkCmdSetLineWidth(vulkan_record.draw_command_buffers[i], 1)vkCmdBindVertexBuffers( vulkan_record.draw_command_buffers[i], 0, 1, addr scene.vertex_buffer.vk_buffer, addr offsets)vkCmdBindIndexBuffer( vulkan_record.draw_command_buffers[i], scene.index_buffer.vk_buffer, VkDeviceSize 0, VK_INDEX_TYPE_UINT32)#[ vkCmdPushConstants( draw_command_buffer, graphics_pipeline.pipeline_layout, VKShaderStageFlags VK_SHADER_STAGE_VERTEX_BIT.ord or VK_SHADER_STAGE_FRAGMENT_BIT.ord, uint32 0, uint32 sizeof Shape_Pushes, cast[pointer] ( addr push_constants )) ]#if gpu.features.multiDrawIndirect.bool:vkCmdDrawIndexedIndirect( vulkan_record.draw_command_buffers[i], indirect_command_buffer.vk_buffer, VkDeviceSize 0, uint32 scene.indirect_commands.len, uint32 sizeof(VkDrawIndexedIndirectCommand))vkCmdEndRenderPass( vulkan_record.draw_command_buffers[i])discard vkEndCommandBuffer( vulkan_record.draw_command_buffers[i])#shape.camera.updateAR(60, vulkan_record.swapchain.current_extent.width.float / float vulkan_record.swapchain.current_extent.height )#vulkan_record.readyFrame = trueproc show*( vulkan_record: var Vulkan_Record, scene: var Scene, pipeline_record: Pipeline_Record) =vulkan_record.readyFrame = trueif WAIN_Key.Comma.is_up andWAIN_Key.O.is_up andWAIN_Key.A.is_up andWAIN_Key.E.is_up andif WAIN_Key.E.is_down_or_held:if WAIN_Key.A.is_down_or_held:if WAIN_Key.O.is_down_or_held:if WAIN_Key.Comma.is_down_or_held:if WAIN_Key.K4.is_down_or_held:#[ if WAIN_Key.K3.is_down_or_held:if WAIN_Key.K2.is_down_or_held:if WAIN_Key.K1.is_down_or_held:, ../wain/keyboard
import tables, ../drawable/[ shape_object, textTypes, plane], ../deshn_entity/[ being], ../vk/[ vulkan, vkTypes, depth_stencil, buffer]typeSceneObj = object of RootObjdevice*: ptr VkDeviceentities*: TableRef[string, int]shapes*: seq[Shape]#texts*: seq[SDFText]deshn_beings*: seq[Deshn_Being]planes*: seq[Plane]current_entity_id*: intrender_pass*: VkRenderPassdepth_stencil*: Depth_Stencilrender_pass_begin_info*: VkRenderPassBeginInfoscissor*: VkRect2Dvertex_buffer*: Bufferindex_buffer*: Bufferstaging_vertex_buffer*: Bufferstaging_index_buffer*: Buffer# TODO: a better way , instead of having to redundantly copy vertices and indicesthe_vertices*: seq[float32]the_indices*: seq[uint32]indirect_commands*: seq[VkDrawIndexedIndirectCommand]Scene* = ref object of SceneObj
import scene_object, main_scenesimport std/tablestypeScene_Record_Object = object of RootObjcurrent_scene*: ptr Scenemain_scene_table*: Table[string, ptr Scene]Scene_Record* = ref object of Scene_Record_Objectproc a_scene_record*( the_main_scene: Main_Scene_Enum, current_scene: ptr Scene = nil): Scene_Record =result = Scene_Record( current_scene: current_scene, main_scene_table: initTable[string, ptr Scene]())proc add_scene*( scene_record: var Scene_Record, scene: ptr Scene, scene_name: string) =scene_record.main_scene_table[scene_name] = sceneproc get_scene*( scene_record: var Scene_Record, scene_name: string): ptr Scene =scene_record.main_scene_table[scene_name]
{.experimental: "codeReordering".}{.deadCodeElim: on.}#TODO: REBUILD render_Pass_begin_info on window size changeimport ../vk/[ vulkan_record, vulkan_utils, vulkan, depth_stencil, swapchain, buffer], scene_object, scene_record, ../deshn_entity/[ being], ../drawable/[ shape_object, textTypes, plane]], std/[ tables, bitops], glmproc 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.idproc theNames*(scene: Scene): seq[string] =for t in scene.shapes: result.add t.nameproc the_shape*( scene: var Scene, id: int, name: string): var Shape =for t in scene.shapes.mitems:if t.id == id: return tquit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)proc the_shape*( scene: var Scene, name: string): var Shape =scene.the_shape scene.entities[name], nameproc 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 tquit("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 tquit("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 tquit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)proc the_plane*( scene: var Scene, name: string): var Plane =scene.the_plane scene.entities[name], nameproc add*( scene: var Scene, shape: Shape) =#echo "adding: ", sh.name, " ", sh.idscene.shapes.add shapescene.entities[shape.name] = shape.idscene.current_entity_id += 1scene.the_vertices.add shape.verticesscene.the_indices.add shape.indices#[ proc add*( scene: var Scene, text: SDFText) =scene.texts.add textscene.entities[text.name] = scene.current_entity_idscene.current_entity_id += 1for text_vert in text.vertices:scene.the_vertices.add text_vert.pos.xscene.the_vertices.add text_vert.pos.yscene.the_vertices.add text_vert.pos.zscene.the_vertices.add text_vert.uv.xscene.the_vertices.add text_vert.uv.yscene.the_indices.add text.indices]#proc add*( scene: var Scene, deshn_being: Deshn_Being) =#echo "adding: ", sh.name, " ", sh.idscene.deshn_beings.add deshn_beingscene.entities[deshn_being.name] = deshn_being.idscene.current_entity_id += 1scene.add deshn_being.shapeproc add*( scene: var Scene, plane: Plane) =#echo "adding: ", sh.name, " ", sh.idscene.planes.add planescene.entities[plane.name] = plane.idscene.current_entity_id += 1scene.add plane.shapeproc 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) =varcopyCmd: VkCommandBuffer = vk_device.getCommandBuffers(command_pool, true)copyRegion: VkBufferCopydata: 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.sizeofvkCmdCopyBuffer(copyCmd, scene.staging_vertex_buffer.vkbuffer, scene.vertex_buffer.vkbuffer, 1.uint32, addr copyRegion)copyRegion.size = VkDeviceSize scene.the_indices.sizeofvkCmdCopyBuffer(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 returningvk_device.flushCommandBuffer queue, command_pool, copyCmd# Destroy staging buffers# Note: Staging buffer must not be deleted before the copies have been submitted and executedvkDestroyBuffer( 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 cleanup*( 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), ready_frame: var bool, scene : var Scene) =readyFrame = false#vk_record.draw_command_buffers.setLen 0# frame_buffers.setLen 0proc rebuild_render_pass_info*( vk_record: var Vulkan_Record, scene: var Scene) =varscissor = 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 = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 vk_record.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 vk_record.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]renderPassBeginInfo.render_pass = scene.render_passrenderPassBeginInfo.framebuffer = vk_record.frame_buffers[vk_record.currentFrameBuffer]scene[].render_pass_begin_info = renderPassBeginInfoscene[].scissor = scissorproc windowResize*( the_waindow: var Waindow, ../wain/[ window_object
import scene_object, scene_utils, scene_record, main_scenes, ../vk/[ vulkan, vkTypes, vulkan_record], ../drawable/[ shape_object, text], glmimport ../drawable/text as mTextimport ../drawable/shape_objecttypeMenuState = enum Begin, Exitvarms = MenuState.Begin#TODO proper dynamic resolution scaling of UI elementsproc load*( rec: var Vulkan_Record, title: var Scene, scene_record: var Scene_Record) =#[ title.add rec.anSDFText(title, "title", str = "Shapes", size = 18)title.add rec.anSDFText(title, "begin", str = "begin", size = 14)title.add rec.anSDFText(title, "exit", str = "exit", size = 14)title.add rec.a_shape( title.render_pass, title.current_entity_id, 4, "settingsFrame", hollow = true, theSize = 100)title.the_text("title").move_to( 150, 40)title.the_text("begin").move_to( 900, 70)title.the_text("exit").move_to( 1600, 70)title.the_text("title").updateFS( outlined = 0.0)echo rec.swapchain.current_extent.widthtitle.the_shape("settingsFrame").move_to( rec.swapchain.current_extent.width.float32 / 2, ((rec.swapchain.current_extent.height.int / 2) + 100 ).float32)title.the_shape("settingsFrame").scale( 8, 4) ]##$title.the_shape("settingsFrame").ubo.model.scale(50)scene_record.add_scene( addr title, "title")#TODO: switching states is kinda buggyproc input*( rec: var Vulkan_Record, sr: var Scene_Record) =case msof MenuState.Begin: inc msof MenuState.Exit: ms = MenuState.Begincase msof MenuState.Begin: ms = MenuState.Exitof MenuState.Exit: dec mscase ms#of MenuState.Begin: sr.the_main_scene = Main_Scene_Enum.Introof MenuState.Exit: quit()else: discardproc update*( rec: var Vulkan_Record, menu: var Scene) = discard#[ case msof MenuState.Begin:menu.the_text("begin").updateFS( outlined = 0.1)menu.the_text("exit").updateFS( outlined = 0.0)of MenuState.Exit:menu.the_text("begin").updateFS( outlined = 0.0)menu.the_text("exit").updateFS( outlined = 0.1) ]#proc show*( rec: var Vulkan_Record, scene: var Scene) =varcmdBufInfo: VkCommandBufferBeginInfoscissor: VkRect2DclearValues: array[2,VkClearValue]renderPassBeginInfo: VkRenderPassBeginInfoscissor.extent.width = uint32 rec.swapchain.current_extent.widthscissor.extent.height = uint32 rec.swapchain.current_extent.heightscissor.offset.x = 0scissor.offset.y = 0cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFOcmdBufInfo.pNext = nilclearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrenderPassBeginInfo.pNext = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 rec.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 rec.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]renderPassBeginInfo.render_pass = scene.render_passrenderPassBeginInfo.framebuffer = rec.frame_buffers[rec.currentFrameBuffer]discard vkBeginCommandBuffer(rec.draw_command_buffers[rec.currentFrameBuffer], addr cmdBufInfo)vkCmdBeginRenderPass(rec.draw_command_buffers[rec.currentFrameBuffer], addr renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE)vkCmdSetViewport(rec.draw_command_buffers[rec.currentFrameBuffer], 0, 1, addr rec.current_viewport)vkCmdSetScissor(rec.draw_command_buffers[rec.currentFrameBuffer], 0, 1, addr scissor)#[ for shape in scene.shapes.mitems:rec.buildCommandBuffers shape, scene.render_pass, int rec.currentFrameBufferfor text in scene.texts.mitems:mtext.buildCommandBuffers rec, text, scene.render_pass, int rec.currentFrameBuffer ]#vkCmdEndRenderPass(rec.draw_command_buffers[rec.currentFrameBuffer])discard vkEndCommandBuffer(rec.draw_command_buffers[rec.currentFrameBuffer])rec.readyFrame = trueif WAIN_Key.Enter.is_down:if WAIN_Key.Down.is_down orWAIN_Key.Left.is_down:if WAIN_Key.Up.is_down orWAIN_Key.Right.is_down:, ../wain/keyboard
import vulkan, vulkan_record, pipeline_record, graphics_pipelineproc show*( vulkan_record: var Vulkan_Record, pipeline_record: Pipeline_Record) =varcmdBufInfo = VkCommandBufferBeginInfo(sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)scissor: VkRect2DclearValues: array[2,VkClearValue]renderPassBeginInfo: VkRenderPassBeginInfoimageRange = VkImageSubresourceRange( aspectMask: VkImageAspectFlags VK_IMAGE_ASPECT_COLOR_BIT, levelCount: 1, layerCount: 1)discard vkResetFences( vulkan_record.vk_device, 1, addr vulkan_record.fences[vulkan_record.current_frame])if vulkan_record.current_frame_buffer > 1:vulkan_record.current_frame_buffer = 1discard vkResetCommandBuffer( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], VkCommandBufferResetFlags 0)scissor.extent.width = uint32 vulkan_record.swapchain.current_extent.widthscissor.extent.height = uint32 vulkan_record.swapchain.current_extent.height#scissor.offset.x = 0#scissor.offset.y = 0clearValues[0].color = VkClearColorValue(float32: [1f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrenderPassBeginInfo.pNext = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 vulkan_record.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 vulkan_record.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]renderPassBeginInfo.renderPass = vulkan_record.current_render_pass.vk_handlerenderPassBeginInfo.framebuffer = vulkan_record.frame_buffers[vulkan_record.current_image_index]discard vkBeginCommandBuffer( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], addr cmdBufInfo)vkCmdSetViewport( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], 0, 1, addr vulkan_record.current_viewport)vkCmdSetScissor( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], 0, 1, addr scissor)vkCmdClearColorImage( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], vulkan_record.swapchain.images[vulkan_record.current_frame_buffer], VK_IMAGE_LAYOUT_GENERAL, addr clearValues[0].color, 1, addr imageRange)vkCmdBeginRenderPass( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], addr renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE)varoffsets = VkDeviceSize 0#[ vkCmdBindDescriptorSets( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_record.pipelines["test"].pipeline_layout, 0, 1, addr descriptor_set, 0, nil)]#vkCmdEndRenderPass vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer]discard vkEndCommandBuffer vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer]vulkan_record.ready_frame = trueproc submit_frame*( image_index: var uint32, render_complete_semaphore: VkSemaphore, queue: VkQueue, current_swapchain_handle: VkSwapchainKHR) =varpresentInfo: VkPresentInfoKHRpresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHRpresentInfo.pNext = nilpresentInfo.waitSemaphoreCount = 1presentInfo.pWaitSemaphores = addr render_complete_semaphorepresentInfo.swapchainCount = 1presentInfo.pSwapchains = addr current_swapchain_handlepresent_info.pImageIndices = addr image_index# Check if a wait semaphore has been specified to wait for# before presenting the imageif (render_complete_semaphore.int != 0):presentInfo.pWaitSemaphores = addr render_complete_semaphorepresentInfo.waitSemaphoreCount = 1#TODO: WHY DOES THIS MEMORY LEAK EVERY FRAMEvar preres = vkQueuePresentKHR( queue, addr presentInfo)#if preres == VK_SUBOPTIMAL_KHR: quit "bad vkQueuePresentKHR"# vulkan_record.windowResize scene# scene.rebuild vulkan_record# discard vkDeviceWaitIdle vulkan_record.vk_device# vulkan_record.ready_frame = trueproc send_frame*( vulkan_record: var Vulkan_Record) =#prep framediscard vkWaitForFences( vulkan_record.vk_device, 1, addr vulkan_record.fences[vulkan_record.current_frame], VKBool32 true, uint64.high)varres = vkAcquireNextImageKHR( vulkan_record.vk_device, vulkan_record.swap_chain.handle, uint64.high, vulkan_record.present_semaphores[vulkan_record.current_frame], VkFence 0, addr vulkan_record.current_image_index)if res == VK_ERROR_OUT_OF_DATE_KHR: discard#resize_screen()# show l#discard vkResetFences( vulkan_record.vk_device, 1, addr vulkan_record.fences[vulkan_record.current_frame])discard vkResetCommandBuffer( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], VkCommandBufferResetFlags 0)varcmdBufInfo = VkCommandBufferBeginInfo(sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)scissor: VkRect2DclearValues: array[2,VkClearValue]renderPassBeginInfo: VkRenderPassBeginInfoimageRange = VkImageSubresourceRange( aspectMask: VkImageAspectFlags VK_IMAGE_ASPECT_COLOR_BIT, levelCount: 1, layerCount: 1)scissor.extent.width = uint32 vulkan_record.swapchain.current_extent.widthscissor.extent.height = uint32 vulkan_record.swapchain.current_extent.height#scissor.offset.x = 0#scissor.offset.y = 0clearValues[0].color = VkClearColorValue(float32: [1f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrenderPassBeginInfo.pNext = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 vulkan_record.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 vulkan_record.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]renderPassBeginInfo.renderPass = vulkan_record.current_render_pass.vk_handlerenderPassBeginInfo.framebuffer = vulkan_record.frame_buffers[vulkan_record.current_image_index]discard vkBeginCommandBuffer( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], addr cmdBufInfo)vkCmdBeginRenderPass( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], addr renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE)vkCmdSetViewport( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], 0, 1, addr vulkan_record.current_viewport)vkCmdSetScissor( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], 0, 1, addr scissor)vkCmdBindDescriptorSets( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_record.current_graphics_pipeline.pipelineLayout, 0, 1, addr vulkan_record.uniform_buffers[vulkan_record.current_frame_buffer].descriptor_set, 0, nil)# Bind the rendering pipeline# The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation timevkCmdBindPipeline( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_record.current_graphics_pipeline.pipeline)# Bind triangle vertex buffer (contains position and colors)var offsets: array[1, VkDeviceSize] = [VkDeviceSize 0]#[ vkCmdBindVertexBuffers(vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], 0, 1, &vertices.buffer, offsets)# Bind triangle index buffervkCmdBindIndexBuffer( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], indices.buffer, 0, VK_INDEX_TYPE_UINT32)# Draw indexed trianglevkCmdDrawIndexed( vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], indices.count, 1, 0, 0, 1) ]#vkCmdEndRenderPass vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer]discard vkEndCommandBuffer vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer]# show l#varwaitStageMask = VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BITsubmitInfo = VkSubmitInfo( sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, pWaitDstStageMask: addr waitStageMask, pWaitSemaphores: addr vulkan_record.present_semaphores[vulkan_record.current_frame], waitSemaphoreCount: 1, pSignalSemaphores: addr vulkan_record.render_semaphores[vulkan_record.current_frame], commandBufferCount: 1, pCommandBuffers: addr vulkan_record.draw_command_buffers[vulkan_record.current_frame_buffer], signalSemaphoreCount: 1)discard vkQueueSubmit( vulkan_record.queue, 1, submitInfo.addr, vulkan_record.fences[vulkan_record.current_frame])if vulkan_record.current_frame == 2:vulkan_record.current_frame = 1submit_frame( vulkan_record.current_image_index, vulkan_record.render_semaphores[vulkan_record.current_frame], vulkan_record.queue, vulkan_record.swapchain.handle)
#[static i32 find_memory_index(vulkan_context *context, u32 type_filter, u32 property_flags){for (u32 i = 0; i < memory_properties.memoryTypeCount; ++i) {// Check each memory type to see if its bit is set to 1.if ( type_filter & (1 << i) && (memory_properties.memoryTypes[i].propertyFlags & property_flags) ==property_flags) {return i;}}
letmemory_type_bits = 1 shl memory_indexis_required_memory_type = (the_type_bits and memory_type_bits.uint32)property_flags: VkMemoryPropertyFlags = memory_properties.memoryTypes[memory_index].propertyFlagsmemory_has_required_properties = ( property_flags.int andrequired_memory_properties.int)
varis_required_memory_property = bitand( the_type_bits_filter.int, (1 shl memory_index)) >= 1the_memory_indexs_property_flag = memory_properties.memoryTypes[memory_index].propertyFlags.int
# is == 1 correct?if is_required_memory_type == 1 andmemory_has_required_properties == 1:return memory_indexquit("no matching memory type could be found:")
#echo "RMP: ", is_required_memory_property, " <> (", bitand( the_type_bits_filter.int, (1 shl memory_index)), ") ", the_memory_indexs_property_flagif is_required_memory_property andbitand( the_memory_indexs_property_flag, required_memory_properties.int) == required_memory_properties.int:return memory_indexquit("find_memory_with_property: no matching memory type could be found:")
import vulkan, vulkan_record, pipeline_record, ../scene/[ scene_record, scene_controller]proc prepare_frame*(rec: var Vulkan_Record, scene_record: var Scene_Record, pipeline_record: Pipeline_Record) =discard vkAcquireNextImageKHR( rec.vk_device, rec.swapChain.handle, uint64.high, rec.presentCompleteSemaphore, VkFence 0, addr rec.currentFrameBuffer)discard vkWaitForFences(rec.vk_device, 1, addr rec.fences[rec.currentFrameBuffer], VKBool32 true, uint64.high)discard vkResetFences(rec.vk_device, 1, addr rec.fences[rec.currentFrameBuffer])#proc submit_frame*( current_frame_buffer: uint32, render_complete_semaphore: VkSemaphore, queue: VkQueue#, scene: var Scene, present_info: var VkPresentInfoKHR) =#for shape in scene.shapes.mitems:#if shape.changed: rec.vk_device.updateCamera shape#[ for text in scene.texts.mitems:if text.changed:text.updateCamera ]## THE M A G I C (presenting) queuePresent#[ var presentInfo: VkPresentInfoKHRpresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHRpresentInfo.pNext = nilpresentInfo.swapchainCount = 1presentInfo.pSwapchains = addr rec.swapChain.swapChainKHR ]#present_info.pImageIndices = addr current_frame_buffer #rec.currentFrameBuffer# Check if a wait semaphore has been specified to wait for# before presenting the imageif (render_complete_semaphore.int != 0):presentInfo.pWaitSemaphores = addr render_complete_semaphorepresentInfo.waitSemaphoreCount = 1#TODO: WHY DOES THIS MEMORY LEAK EVERY FRAMEvar preres = vkQueuePresentKHR( queue, addr presentInfo)#if preres == VK_SUBOPTIMAL_KHR: quit "bad vkQueuePresentKHR"# rec.windowResize scene# scene.rebuild rec# discard vkDeviceWaitIdle rec.vk_device# rec.readyFrame = trueproc draw*(rec: var Vulkan_Record, scene_record: var Scene_Record, pipeline_record: Pipeline_Record) =if rec.readyFrame:rec.prepare_frame scene_record, pipeline_recordscene_record.draw_current_scene rec, pipeline_recordvarwaitStageMask = VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BITsubmitInfo = VkSubmitInfo( sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, pWaitDstStageMask: addr waitStageMask, pWaitSemaphores: addr rec.presentCompleteSemaphore, waitSemaphoreCount: 1, pSignalSemaphores: addr rec.renderCompleteSemaphore, commandBufferCount: 1, pCommandBuffers: addr rec.draw_command_buffers[rec.currentFrameBuffer], signalSemaphoreCount: 1)discard vkQueueSubmit( rec.queue, 1, submitInfo.addr, rec.fences[rec.currentFrameBuffer])submit_frame( rec.currentFrameBuffer, rec.renderCompleteSemaphore, rec.queue, scene_record.current_scene[].present_info)#rec.readyFrame = false
vkCreateBuffer = cast[ proc( device: VkDevice, pCreateInfo: ptr VkBufferCreateInfo, pAllocator: ptr VkAllocationCallbacks, pBuffer: ptr VkBuffer): VkResult {.stdcall.}] (vkGetDeviceProcAddr( device, "vkCreateBuffer") )vkGetBufferMemoryRequirements =cast[ proc(device: VkDevice, buffer: VkBuffer, pMemoryRequirements: ptr VkMemoryRequirements): void {.stdcall.}]((vkGetDeviceProcAddr( device, "vkGetBufferMemoryRequirements") ))vkBindBufferMemory = cast[proc(device: VkDevice, buffer: VkBuffer, memory: VkDeviceMemory, memoryOffset: VkDeviceSize): VkResult {.stdcall.}](vkGetDeviceProcAddr( device, "vkBindBufferMemory"))
result.master_vertex_buffer = a_vulkan_buffer( result.vk_device, result.gpu.memory_properties, VkBufferUsageFlags bitor( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT.ord, VK_BUFFER_USAGE_TRANSFER_DST_BIT.ord), VkMemoryPropertyFlags VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, MiB_vkds(256))result.master_index_buffer = a_vulkan_buffer( result.vk_device, result.gpu.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, MiB_vkds(128))result.master_uniform_buffer = a_vulkan_buffer( result.vk_device, result.gpu.memory_properties, VkBufferUsageFlags VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkMemoryPropertyFlags ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.ord orVK_MEMORY_PROPERTY_HOST_COHERENT_BIT.ord), MiB_vkds(256))
#[ result.master_vertex_buffer = a_vulkan_buffer( result.vk_device, result.gpu.memory_properties, VkBufferUsageFlags bitor( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT.ord, VK_BUFFER_USAGE_TRANSFER_DST_BIT.ord), VkMemoryPropertyFlags VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, MiB_vkds(256)) ]##[ master_index_buffer = a_vulkan_buffer()master_uniform_buffer = a_vulkan_buffer()]#
, addr vulkan_record.master_vertex_buffer.data[vulkan_record.master_vertex_buffer.current_data_offset], Natural vertex_data.sizeof)
, addr vulkan_record.master_vertex_buffer.data[vulkan_record.master_vertex_buffer.current_data_offset], Natural vertex_data.sizeof)
, addr vulkan_record.master_index_buffer.data[vulkan_record.master_index_buffer.current_data_offset], Natural index_data.sizeof)
, addr vulkan_record.master_index_buffer.data[vulkan_record.master_index_buffer.current_data_offset], Natural index_data.sizeof)
, gpu_memory_properties: VkPhysicalDeviceMemoryProperties, allocation_size: VkDeviceSize, buffer_usage_flags: VkBufferUsageFlags, memory_flags: VkMemoryPropertyFlags): Buffer =
, gpu_memory_properties: VkPhysicalDeviceMemoryProperties, buffer_usage_flags: VkBufferUsageFlags, memory_flags: VkMemoryPropertyFlags, allocation_size: VkDeviceSize): Buffer =
allocation_info.memoryTypeIndex = gpu_memory_properties.find_memory_with_property( mem_reqs.memoryTypeBits, memory_flags)
allocation_info.memoryTypeIndex =gpu_memory_properties.find_memory_with_property( mem_reqs.memoryTypeBits, memory_flags)
, result.device_memory, VkDeviceSize 0, allocation_size, VkMemoryMapFlags 0, cast[ptr pointer] (result.data)) == VK_SUCCESS
, result.device_memory, VkDeviceSize 0, allocation_size, VkMemoryMapFlags 0, cast[ptr pointer] (result.data)) == VK_SUCCESS
import ../scene/[scene_object, scene_utils, scene_record, main_scenes], ../vk/[ vulkan, vkTypes, vulkan_record], ../drawable/[ shape_object, text], ../wain/keyboard, glmimport ../drawable/text as mTextimport ../drawable/shape_objecttypeMenuState = enum Begin, Exitvarms = MenuState.Begin#TODO proper dynamic resolution scaling of UI elementsproc load*( rec: var Vulkan_Record, title: var Scene, scene_record: var Scene_Record) =#[ title.add rec.anSDFText(title, "title", str = "Shapes", size = 18)title.add rec.anSDFText(title, "begin", str = "begin", size = 14)title.add rec.anSDFText(title, "exit", str = "exit", size = 14)title.add rec.a_shape( title.render_pass, title.current_entity_id, 4, "settingsFrame", hollow = true, theSize = 100)title.the_text("title").move_to( 150, 40)title.the_text("begin").move_to( 900, 70)title.the_text("exit").move_to( 1600, 70)title.the_text("title").updateFS( outlined = 0.0)echo rec.swapchain.current_extent.widthtitle.the_shape("settingsFrame").move_to( rec.swapchain.current_extent.width.float32 / 2, ((rec.swapchain.current_extent.height.int / 2) + 100 ).float32)title.the_shape("settingsFrame").scale( 8, 4) ]##$title.the_shape("settingsFrame").ubo.model.scale(50)scene_record.add_scene( addr title, "title")#TODO: switching states is kinda buggyproc input*( rec: var Vulkan_Record, sr: var Scene_Record) =if WAIN_Key.Up.is_down orWAIN_Key.Right.is_down:case msof MenuState.Begin: inc msof MenuState.Exit: ms = MenuState.Beginif WAIN_Key.Down.is_down orWAIN_Key.Left.is_down:case msof MenuState.Begin: ms = MenuState.Exitof MenuState.Exit: dec msif WAIN_Key.Enter.is_down:case ms#of MenuState.Begin: sr.the_main_scene = Main_Scene_Enum.Introof MenuState.Exit: quit()else: discardproc update*( rec: var Vulkan_Record, menu: var Scene) = discard#[ case msof MenuState.Begin:menu.the_text("begin").updateFS( outlined = 0.1)menu.the_text("exit").updateFS( outlined = 0.0)of MenuState.Exit:menu.the_text("begin").updateFS( outlined = 0.0)menu.the_text("exit").updateFS( outlined = 0.1) ]#proc build_scene*( rec: var Vulkan_Record, scene: var Scene) =varcmdBufInfo: VkCommandBufferBeginInfoscissor: VkRect2DclearValues: array[2,VkClearValue]renderPassBeginInfo: VkRenderPassBeginInfoscissor.extent.width = uint32 rec.swapchain.current_extent.widthscissor.extent.height = uint32 rec.swapchain.current_extent.heightscissor.offset.x = 0scissor.offset.y = 0cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFOcmdBufInfo.pNext = nilclearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrenderPassBeginInfo.pNext = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 rec.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 rec.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]#renderPassBeginInfo.render_pass = scene.render_passrenderPassBeginInfo.framebuffer = rec.frame_buffers[rec.currentFrameBuffer]discard vkBeginCommandBuffer(rec.draw_command_buffers[rec.currentFrameBuffer], addr cmdBufInfo)vkCmdBeginRenderPass(rec.draw_command_buffers[rec.currentFrameBuffer], addr renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE)vkCmdSetViewport(rec.draw_command_buffers[rec.currentFrameBuffer], 0, 1, addr rec.current_viewport)vkCmdSetScissor(rec.draw_command_buffers[rec.currentFrameBuffer], 0, 1, addr scissor)#[ for shape in scene.shapes.mitems:rec.buildCommandBuffers shape, scene.render_pass, int rec.currentFrameBufferfor text in scene.texts.mitems:mtext.buildCommandBuffers rec, text, scene.render_pass, int rec.currentFrameBuffer ]#vkCmdEndRenderPass(rec.draw_command_buffers[rec.currentFrameBuffer])discard vkEndCommandBuffer(rec.draw_command_buffers[rec.currentFrameBuffer])rec.readyFrame = true
import ../scene/[ scene_object, scene_record, scene_utils], ../vk/[ vulkan_record, pipeline_record], ../drawable/[ colors, actions, grid, plane, shape_object, shape_primitives, shape_types, text, text_types], vmathproc load*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record) =vartest_area = a_scene(vulkan_record)test_area.add( a_shape( vulkan_record, test_area.current_entity_id, 3, "tri", vec2(100.0,100.0)) )proc input*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record) = discardproc update*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record, fps: string) = discardproc build_scene*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record, pipeline_record: Pipeline_Record) = discard
{.experimental: "parallel".}import ../scene/[ scene_object, scene_utils, scene_record], ../vk/[ vulkan, vkTypes, vulkan_record, graphics_pipeline, pipeline_record, buffer, gpu, vulkan_utils], ../drawable/[ shape_object, shape_types, plane, colors, grid], ../drawable/text as mText, ../deshn_entity/[ being, actions], glm, strUtils, ../wain/keyboard, ../camera, std/tables, ../state_machine, optionsproc load*( vulkan_record: var Vulkan_Record, pipeline_record: Pipeline_Record, intro: var Scene, scene_record: var Scene_Record) = discard#intro.the_deshn_being("protag").main_state_machine.current_state = some Main_Deshn_Being_States.Idleproc input*( vulkan_record: var Vulkan_Record, sr: var Scene_Record) = discardproc update*( vulkan_record: var Vulkan_Record, intro: var Scene, sr: var Scene_Record, fps: string) =varprotag = intro.the_deshn_being("protag")# plane = intro.the_plane("plane0")#[ if WAIN_Key.K3.is_down_or_held:plane.shape.camera.position_is vec3f( plane.shape.camera.position.xy, plane.shape.camera.position.z + 0.1)if WAIN_Key.K4.is_down_or_held:plane.shape.camera.position_is vec3f( plane.shape.camera.position.xy, plane.shape.camera.position.z - 0.1) ]#if WAIN_Key.Comma.is_up andWAIN_Key.O.is_up andWAIN_Key.A.is_up andWAIN_Key.E.is_up andnot protag.recovering:protag.current_state_is Not_Movingif not protag.deshn_pool_is_full andnot protag.recovering:# echo "NOT moving, adding."protag.add_amount_to_deshn_pool 0.03else:#echo "can't add because: " , protag.deshn_pool_is_full, " <> ", protag.recoveringdiscardif protag.recovering:#echo "RECOVERING: ", protag.current_deshn_pool_recovery_poolprotag.add_amount_to_recovery_pool 0.01proc build_command_buffers*( draw_command_buffer: var VkCommandBuffer, scene: var Scene, graphics_pipeline: Graphics_Pipeline, descriptor_set: VkDescriptorSet, gpu: GPU, vulkan_record: var Vulkan_Record, indirect_command_buffer: var Buffer) =varcommand_buffer_info = VkCommandBufferBeginInfo(sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)scissor: VkRect2DclearValues: array[2,VkClearValue]render_pass_info: VkRenderPassBeginInfooffsets = VkDeviceSize 0viewport = VkViewport( width: float32 vulkan_record.swapchain.current_extent.width, height: float32 vulkan_record.swapchain.current_extent.height, minDepth: 0.0f, maxDepth: 1.0f)scissor.extent.width = uint32 vulkan_record.swapchain.current_extent.widthscissor.extent.height = uint32 vulkan_record.swapchain.current_extent.heightscissor.offset.x = 0scissor.offset.y = 0clearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f])clearValues[1].depth_stencil = VkClearDepthStencilValue(depth: 1.0f, stencil: 0 )render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFOrender_pass_info.pNext = nilrender_pass_info.renderArea.offset.x = 0render_pass_info.renderArea.offset.y = 0render_pass_info.renderArea.extent.width = uint32 vulkan_record.swapchain.current_extent.widthrender_pass_info.renderArea.extent.height = uint32 vulkan_record.swapchain.current_extent.heightrender_pass_info.clearValueCount = 2render_pass_info.pClearValues = addr clearValues[0]#render_pass_info.render_pass = scene.render_passfor i in 0 .. vulkan_record.draw_command_buffers.len:render_pass_info.framebuffer = vulkan_record.frame_buffers[i]discard vkBeginCommandBuffer( vulkan_record.draw_command_buffers[i], addr command_buffer_info)vkCmdBeginRenderPass( vulkan_record.draw_command_buffers[i], addr render_pass_info, VK_SUBPASS_CONTENTS_INLINE)vkCmdSetViewport( vulkan_record.draw_command_buffers[i], 0, 1, addr vulkan_record.current_viewport)vkCmdSetScissor( vulkan_record.draw_command_buffers[i], 0, 1, addr scissor)vkCmdBindDescriptorSets( vulkan_record.draw_command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline.pipeline_layout, 0, 1, addr descriptor_set, 0, nil)vkCmdBindPipeline( vulkan_record.draw_command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline.pipeline)vkCmdSetLineWidth(vulkan_record.draw_command_buffers[i], 1)vkCmdBindVertexBuffers( vulkan_record.draw_command_buffers[i], 0, 1, addr scene.vertex_buffer.vk_buffer, addr offsets)vkCmdBindIndexBuffer( vulkan_record.draw_command_buffers[i], scene.index_buffer.vk_buffer, VkDeviceSize 0, VK_INDEX_TYPE_UINT32)#[ vkCmdPushConstants( draw_command_buffer, graphics_pipeline.pipeline_layout, VKShaderStageFlags VK_SHADER_STAGE_VERTEX_BIT.ord or VK_SHADER_STAGE_FRAGMENT_BIT.ord, uint32 0, uint32 sizeof Shape_Pushes, cast[pointer] ( addr push_constants )) ]#if gpu.features.multiDrawIndirect.bool:vkCmdDrawIndexedIndirect( vulkan_record.draw_command_buffers[i], indirect_command_buffer.vk_buffer, VkDeviceSize 0, uint32 scene.indirect_commands.len, uint32 sizeof(VkDrawIndexedIndirectCommand))vkCmdEndRenderPass( vulkan_record.draw_command_buffers[i])discard vkEndCommandBuffer( vulkan_record.draw_command_buffers[i])#shape.camera.updateAR(60, vulkan_record.swapchain.current_extent.width.float / float vulkan_record.swapchain.current_extent.height )#vulkan_record.readyFrame = trueproc build_scene*( vulkan_record: var Vulkan_Record, scene: var Scene, pipeline_record: Pipeline_Record) =vulkan_record.readyFrame = true
{.experimental: "codeReordering".}{.deadCodeElim: on.}#TODO: REBUILD render_Pass_begin_info on window size changeimport ../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], glmproc 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.idproc theNames*(scene: Scene): seq[string] =for t in scene.shapes: result.add t.nameproc the_shape*( scene: var Scene, id: int, name: string): var Shape =for t in scene.shapes.mitems:if t.id == id: return tquit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)proc the_shape*( scene: var Scene, name: string): var Shape =scene.the_shape scene.entities[name], nameproc 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 tquit("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 tquit("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 tquit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id)proc the_plane*( scene: var Scene, name: string): var Plane =scene.the_plane scene.entities[name], nameproc add*( scene: var Scene, shape: Shape) =#echo "adding: ", sh.name, " ", sh.idscene.shapes.add shapescene.entities[shape.name] = shape.idscene.current_entity_id += 1scene.the_vertices.add shape.verticesscene.the_indices.add shape.indices#[ proc add*( scene: var Scene, text: SDFText) =scene.texts.add textscene.entities[text.name] = scene.current_entity_idscene.current_entity_id += 1for text_vert in text.vertices:scene.the_vertices.add text_vert.pos.xscene.the_vertices.add text_vert.pos.yscene.the_vertices.add text_vert.pos.zscene.the_vertices.add text_vert.uv.xscene.the_vertices.add text_vert.uv.yscene.the_indices.add text.indices]#proc add*( scene: var Scene, deshn_being: Deshn_Being) =#echo "adding: ", sh.name, " ", sh.idscene.deshn_beings.add deshn_beingscene.entities[deshn_being.name] = deshn_being.idscene.current_entity_id += 1scene.add deshn_being.shapeproc add*( scene: var Scene, plane: Plane) =#echo "adding: ", sh.name, " ", sh.idscene.planes.add planescene.entities[plane.name] = plane.idscene.current_entity_id += 1scene.add plane.shapeproc 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) =varcopyCmd: VkCommandBuffer = vk_device.getCommandBuffers(command_pool, true)copyRegion: VkBufferCopydata: 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.sizeofvkCmdCopyBuffer(copyCmd, scene.staging_vertex_buffer.vkbuffer, scene.vertex_buffer.vkbuffer, 1.uint32, addr copyRegion)copyRegion.size = VkDeviceSize scene.the_indices.sizeofvkCmdCopyBuffer(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 returningvk_device.flushCommandBuffer queue, command_pool, copyCmd# Destroy staging buffers# Note: Staging buffer must not be deleted before the copies have been submitted and executedvkDestroyBuffer( 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) =varscissor = 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 = nilrenderPassBeginInfo.renderArea.offset.x = 0renderPassBeginInfo.renderArea.offset.y = 0renderPassBeginInfo.renderArea.extent.width = uint32 vk_record.swapchain.current_extent.widthrenderPassBeginInfo.renderArea.extent.height = uint32 vk_record.swapchain.current_extent.heightrenderPassBeginInfo.clearValueCount = 2renderPassBeginInfo.pClearValues = addr clearValues[0]renderPassBeginInfo.render_pass = scene.render_passrenderPassBeginInfo.framebuffer = vk_record.frame_buffers[vk_record.currentFrameBuffer]scene[].render_pass_begin_info = renderPassBeginInfoscene[].scissor = scissor ]#
import scene_object, main_scenes, ../vk/vulkan_recordimport std/tablestypeScene_Record_Object = object of RootObjcurrent_scene*: ptr Scenemain_scene_table*: Table[string, ptr Scene]current_scene_name*: Main_ScenesScene_Record* = ref object of Scene_Record_Objectproc a_scene_record*( the_main_scene: Main_Scenes, current_scene: ptr Scene = nil): Scene_Record =result = Scene_Record( current_scene: current_scene, main_scene_table: initTable[string, ptr Scene]())proc add_scene*( scene_record: var Scene_Record, scene: ptr Scene, scene_name: string) =scene_record.main_scene_table[scene_name] = sceneproc get_scene*( scene_record: var Scene_Record, scene_name: string): ptr Scene =scene_record.main_scene_table[scene_name]
import tables, ../drawable/[ shape_object, text_types, plane], ../deshn_entity/[ being], ../vk/[ vulkan, vkTypes, depth_stencil, buffer]typeScene_Object = object of RootObjdevice*: ptr VkDeviceentities*: TableRef[string, int]shapes*: seq[Shape]#texts*: seq[SDFText]planes*: seq[Plane]deshn_beings*: seq[Deshn_Being]current_entity_id*: intvertex_buffer*: Bufferindex_buffer*: Bufferstaging_vertex_buffer*: Bufferstaging_index_buffer*: Buffer#render_pass_begin_info*: VkRenderPassBeginInfo#scissor*: VkRect2D#render_pass*: VkRenderPass#depth_stencil*: Depth_Stencilpresent_info*: VkPresentInfoKHR# TODO: a better way , instead of having to redundantly copy vertices and indicesthe_vertices*: seq[float32]the_indices*: seq[uint32]indirect_commands*: seq[VkDrawIndexedIndirectCommand]Scene* = ref object of Scene_Object
import ../the_scenes/[ intro, title, test_area], main_scenes, scene_object, scene_recordimport ../vk/[ vulkan_record, pipeline_record]proc load*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record) =case scene_record.current_scene_nameof Title: discardof Intro: discardof Test_Area: test_area.load( scene_record, vulkan_record)proc input*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record) =case scene_record.current_scene_nameof Title: discardof Intro: discardof Test_Area: test_area.input( scene_record, vulkan_record)proc update*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record, fps: string) =case scene_record.current_scene_nameof Title: discardof Intro: discardof Test_Area: test_area.update( scene_record, vulkan_record, fps)proc draw_current_scene*( scene_record: var Scene_Record, vulkan_record: var Vulkan_Record, pipeline_record: Pipeline_Record) =case scene_record.current_scene_nameof Title: discardof Intro: discardof Test_Area: test_area.build_scene( scene_record, vulkan_record, pipeline_record)
typeMain_Scenes* = enumTitle = 0 ,Intro = 1 ,Test_Area = 99
#[ {.experimental: "codeReordering".}{.deadCodeElim: on.}import glm, ../camera, tables, freetype/[ freetype, fttypes], ../vk/[ vulkan, buffer, vulkan_utils, vkTypes, vulkan_record, graphics_pipeline], bitops, ../drawable/texture, ../utils/letstype# Area = ref object# x: int# y: int# width: int# height: intBmchar* = objectx*: uint32y*: uint32width*: uint32height*: uint32xoffset*: int32yoffset*: int32xadvance*: int32page*: uint32#chl ??TextVert* = objectpos*: Vec3[float32]uv*: Vec2[float32]#color*: Vec4[float]#texCoord*: Vec2[float]#blendMode*: int32#data*: array[4, int32]TextUboFS* = ref objectoutlineColor*: Vec4[float32]outlineWidth*: floatoutline*: boolTextPipelines* = ref objectsdf*: VkPipelinebitmap*: VkPipelineGlyph* = objecttop*: intleft*: intwidth*: intheight*: intadv*: inttexture*: Texture2dface*: FT_Faceind*: FT_UintPBMFont* = objectchars*: array[255,Bmchar]face*: FT_Faceglyphs*: Table[uint16, Glyph]VertDescr* = ref object of VertDescrObjVertDescrObj* = object of RootObjinputState*: VkPipelineVertexInputStateCreateInfobindingDescriptions*: seq[VkVertexInputBindingDescription]attributeDescriptions*: seq[VkVertexInputAttributeDescription]UBOVS* = objectproj*: Mat4[float32]model*: Mat4[float32]view*: Mat4[float32] # ?UBOFS* = objectoutlineColor*: Vec4[float32]outlineWidth*: float32outlined*: float32UBOS* = ref object of UBOSObjUBOSObj* = object of RootObjvs*: UBOVSfs*: UBOFSSDFTextObj = object of RootObjcamera*: CameradescrSet*: VkDescriptorSetdescrSetLayout*: VkDescriptorSetLayoutid*: intindices*: seq[uint32]indexCount*: uint32indexedAmount*: uint32indexBuffer*: BuffervertexBuffer*: BufferuniBufferV*: BufferuniBufferF*: Bufferfont*: PBMFontname*: stringpipelineCache*: VkPipelineCachegraphicsPipeline*: Graphics_PipelinestVertexBuffer*: BufferstIndexBuffer*: Buffertexture*: Texture2Dubos*: UBOsdescrPool*: VkDescriptorPoolchanged*: boolstrChanged*: boolstr*: stringcamera_type*: Camera_Kinddevice*: ptr VkDevicesize*: float32vertices*: seq[TextVert]theVkRec*: ptr Vulkan_RecordSDFText* = ref object of SDFTextObjTextureWindow* = objectx0*: floaty0*: floatx1*: floaty1*: floatTextureAtlas* = ref object of TextureAtlasObjTextureAtlasObj = object of RootObjwidth*: uint32height*: uint32sampler*: VkSamplerdescPool*: VkDescriptorPooldescrSet*: VkDescriptorSetdescrSetLayout*: VkDescriptorSetLayoutimageView*: VkImageViewboundImage*: BoundImageglyphs*: Table[uint16, Glyph]proc aGlyph*(font: PBMFont, glyphs: var Table[uint16, Glyph], key: uint16): Glyph =if glyphs.hasKey(key): return glyphs[key]else:vargind = FT_Get_Char_Index(font.face, key)#auto glyph = std::make_shared<Glyph>(m_face, glyphIndex, m_textureAtlas);g = Glyph(face: font.face, ind: gind)glyphs[key] = greturn gproc transitionImageLayout( rec: var Vulkan_Record, image: VkImage, oldLayout: VkImageLayout, newLayout: VkImageLayout) =varsourceStage: VkPipelineStageFlags = VkPipelineStageFlags VK_PIPELINE_STAGE_TOP_OF_PIPE_BITdestinationStage: VkPipelineStageFlags = VkPipelineStageFlags VK_PIPELINE_STAGE_TOP_OF_PIPE_BITcmdBuffer: VkCommandBuffer = beginSingleTimeCommands( rec.vk_device, rec.command_pool)barrier = VkImageMemoryBarrier( sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, oldLayout: oldLayout, newLayout: newLayout, srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED, dstQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED, image: image, subresourceRange: VkImageSubresourceRange( aspectMask: VkImageAspectFlags VK_IMAGE_ASPECT_COLOR_BIT, baseMipLevel: 0, levelCount: 1, baseArrayLayer: 0, layerCount: 1))case oldLayout:of VK_IMAGE_LAYOUT_UNDEFINED: barrier.srcAccessMask = VkAccessFlags 0of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:barrier.srcAccessMask = VkAccessFlags VK_ACCESS_TRANSFER_WRITE_BITsourceStage = VkPipelineStageFlags VK_PIPELINE_STAGE_TRANSFER_BITof VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:barrier.srcAccessMask = VkAccessFlags VK_ACCESS_SHADER_READ_BITsourceStage = VkPipelineStageFlags VK_PIPELINE_STAGE_FRAGMENT_SHADER_BITelse: quit("unsupported image transition12")case newLayout:of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:barrier.dstAccessMask = VkAccessFlags VK_ACCESS_TRANSFER_WRITE_BITdestinationStage = VkPipelineStageFlags VK_PIPELINE_STAGE_TRANSFER_BITof VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:barrier.srcAccessMask = VkAccessFlags VK_ACCESS_TRANSFER_WRITE_BITbarrier.dstAccessMask = VkAccessFlags VK_ACCESS_SHADER_READ_BITdestinationStage = VkPipelineStageFlags VK_PIPELINE_STAGE_FRAGMENT_SHADER_BITelse: quit("unsupported image transition13")vkCmdPipelineBarrier(cmdBuffer, sourceStage, destinationStage, VkDependencyFlags 0, uint32 0, nil, uint32 0, nil, uint32 1, addr barrier )endSingleTimeCommands( rec.vk_device, cmdBuffer, rec.graphics_queue, rec.command_pool)proc createTextureDescrSet*( rec: Vulkan_Record, ta: var TextureAtlas): VkDescriptorSet =vardescriptorSet: VkDescriptorSetallocInfo = VkDescriptorSetAllocateInfo( sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, descriptorPool: ta.descPool, descriptorSetCount: 1, pSetLayouts: addr ta.descrSetLayout)discard vkAllocateDescriptorSets( rec.vk_device, addr allocInfo, addr descriptorSet)varimageInfo = VkDescriptorImageInfo( imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageView: ta.imageView, sampler: ta.sampler)descriptorWrites = VkWriteDescriptorSet( sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, dstSet: descriptorSet, dstBinding: 0, dstArrayElement: 0, descriptorType: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorCount: 1, pImageInfo: addr imageInfo)vkUpdateDescriptorSets( rec.vk_device, u321, addr descriptorWrites, u320, nil)resultproc aTextureAtlas*( rec: var Vulkan_Record, width, height: uint32, format = VK_FORMAT_R8G8B8A8_UNORM): TextureAtlas =result.width = widthresult.height = heightresult.boundImage = createImage( rec.vk_device, rec.gpu.memory_properties, result.width, result.height, format, VK_IMAGE_TILING_OPTIMAL, VkImageUsageFlags bitor( VK_IMAGE_USAGE_TRANSFER_DST_BIT.ord, VK_IMAGE_USAGE_SAMPLED_BIT.ord), VkMemoryPropertyFlags VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT.ord)rec.transitionImageLayout( result.boundImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)rec.transitionImageLayout( result.boundImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)result.imageView = rec.vk_device.createImageView(result.boundImage.image, format)result.sampler = rec.vk_device.createSamplerresult.descrSet = rec.createTextureDescrSet result]#
projection*: Mat4fmodel*: Mat4fview*: Mat4fmodel_view_projection*: Mat4[float32]being_color*: Vec4[float32]deshn_color*: Vec4[float32]pos*: Vec4[float32]
projection*: Mat4model*: Mat4view*: Mat4model_view_projection*: Mat4being_color*: Vec4deshn_color*: Vec4pos*: Vec4
, pipeline_record: Pipeline_Record, render_pass: VkRenderPass, current_enitity_id: int#, s: var Scene # TODO: DO NOT DELET, sides: Natural, name: string, the_size: Vec2[float32], being_color: Vec4[float32] = vec4f(1.0, 0.0, 0.0, 1.0), deshn_color: Vec4[float32] = vec4f(1.0, 0.0, 0.0, 1.0), camera_type: Camera_Kind = Ortho, hollow: bool = false# TODO: custom vertices and indices# , vertices: seq[seq[seq[float32]# , indices seq[float32]): Shape =
, current_enitity_id: int#, s: var Scene # TODO: DO NOT DELET, sides: Natural, name: string, the_size: Vec2, being_color: Vec4 = vec4(1.0, 0.0, 0.0, 1.0), deshn_color: Vec4 = vec4(1.0, 0.0, 0.0, 1.0), camera_type: Camera_Kind = Ortho, hollow: bool = false# TODO: custom vertices and indices# , vertices: seq[seq[seq[float32]# , indices seq[float32]): Shape =
, camera: a_camera ( (float vulkan_record.swapchain.current_extent.width) /(float vulkan_record.swapchain.current_extent.height))
#[ , camera: a_camera ( (float vulkan_record.swapchain.current_extent.width) /(float vulkan_record.swapchain.current_extent.height)) ]#
case result.camera_kind:of Perspective:result.ubo.projection = vkm.perspectiveLH( 90.0'f32, vulkan_record.swapchain.current_extent.width.float32 /vulkan_record.swapchain.current_extent.height.float32, 1.0.float32, 1000.0.float32)result.ubo.model = mat4f(1.float32).scale( result.the_size.x, result.the_size.y, 0.0).translate(0.float32,0,0)result.ubo.view = lookAt( vec3f( 0.0, 0.0, 0.0), vec3f( 0.0, 0.0, 0.0), vec3f( 0.0, 0.0, 0.0)
of Ortho:result.ubo.projection = vkm.ortho( 0.float32, vulkan_record.swapchain.current_extent.width.float32, 0.float32, vulkan_record.swapchain.current_extent.height.float32, 0.0.float32, -1000.0.float32)result.ubo.model = mat4f(1.float32).scale( result.the_size.x, result.the_size.y, 0.0)#.translate(0.float32,0,0).rotate( radians 180'f32, 1, 0, 0)result.ubo.view = mat4f(1)# lookAtRH( vec3( 1280.float32 / 2, 1280.float32, 1.0)#, vec3(0f, 0.0, 0)#, vec3(0f, 0, 1)#)
)#vulkan_record.prepare_uniform_buffers result#vulkan_record.vk_device.updateCamera shape# actionsproc update_model_view_projection*( shape: var Shape) =shape.ubo.model_view_projection = shape.camera.matrices.perspective *shape.camera.matrices.view *shape.ubo.modelproc scale*( t: var Shape, x: float32, y: float32) =varposX = t.ubo.model[3][0]posY = t.ubo.model[3][1]t.ubo.model = mat4f(1)#.scale(x,y,1).translate(posX, posY, 0)t.ubo.model = t.ubo.model.scale( t.the_size.x * x, t.the_size.y * y, 0.0)t.update_model_view_projection()# vulkan is y negproc move_up*( t: var Shape, y: float32#, x: float32) =t.camera.translate(normalize vec3f(0.0,-y,0.0))t.update_model_view_projection()# vulkan is y negproc move_down*( t: var Shape, y: float32#, x: float32) =t.camera.translate(normalize vec3f( 0.0, y,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()# vulkan is y negproc move_left*( t: var Shape, x: float32#, y: float32) =t.camera.translate(normalize vec3f(-x,0.0,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()# vulkan is y negproc move_right*( t: var Shape, x: float32#, y: float32) =t.camera.translate(normalize vec3f(x,0.0,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()proc move_up2*( t: var Shape, y: float32#, x: float32) =t.ubo.model = t.ubo.model.translate(normalize vec3f(0.0,y,0.0))t.update_model_view_projection()# vulkan is y negproc move_down2*( t: var Shape, y: float32#, x: float32) =t.ubo.model = t.ubo.model.translate(normalize vec3f( 0.0, -y,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()# vulkan is y negproc move_left2*( t: var Shape, x: float32#, y: float32) =t.ubo.model = t.ubo.model.translate(normalize vec3f(-x,0.0,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()# vulkan is y negproc move_right2*( t: var Shape, x: float32#, y: float32) =t.ubo.model = t.ubo.model.translate(normalize vec3f(x,0.0,0.0))# .rotate(radians 180.0, 1, 0, 0 )#.scale(t.the_size)t.update_model_view_projection()# vulkan is y negproc move_to*( t: var Shape, x: float32, y: float32) =t.ubo.model = mat4f(1).translate(0,0,0).translate(x,-y,0)# .rotate(radians 180.0, 1, 0, 0 ).scale( t.the_size.x, t.the_size.y, 0.0)t.update_model_view_projection()#[ proc updateCamera*( shape: var Shape) =# if text.camera_type == Ortho:#text.ubos.vs.view = text.camera.matrices.view#text.camera.updateViewMatrix()# if text.camera_type == Perspective:# text.ubos.vs.projection = text.camera.matrices.persp# text.ubos.vs.view = text.camera.matrices.view# text.ubos.vs.model = mat4(1.0.float32).scale 0.16# text.camera.updateViewMatrix()shape.vk_device[].map_memory( shape.uniform_buffer.memory, shape.uniform_buffer.data)shape.vk_device[].map_memory( shape.uniform_buffer.memory, shape.uniform_buffer.data)copymem(shape.uniform_buffer.data, addr shape.ubo, shape.ubo.sizeof)copymem(shape.uniform_buffer.data, addr shape.ubo, shape.ubo.sizeof)vkUnmapMemory(shape.vk_device[], shape.uniform_buffer.memory)vkUnmapMemory(shape.vk_device[], shape.uniform_buffer.memory)#shape.changed = false ]#
)
proc move_to*( being: var Deshn_Being, x, y: float32) = being.shape.move_to( x, y)proc move_up*( being: var Deshn_Being, amount: float32, deshn_cost = 0.1) =if being.can_move:being.shape.move_up amountbeing.process_event Main_Deshn_Being_Events.Movedbeing.remove_amount_from_deshn_pool 0.03else: discardproc move_down*( being: var Deshn_Being, amount: float32, deshn_cost = 0.1) =if being.can_move:being.shape.move_down amountbeing.process_event Main_Deshn_Being_Events.Movedbeing.remove_amount_from_deshn_pool 0.03else: discardproc move_left*( being: var Deshn_Being, amount: float32, deshn_cost = 0.1) =if being.can_move:being.shape.move_left amountbeing.process_event Main_Deshn_Being_Events.Movedbeing.remove_amount_from_deshn_pool 0.03else: discard
flip_Y*: boolproc update_view_matrix*( camera: var Camera) =varrotation_matrix = mat4 1.0ftranslation_matrix: Mat4[float32]camera_flip_mod = if camera.flipY: -1.0f else: 1.0ftranslation = camera.positionrotation_matrix = rotate( rotation_matrix, radians(camera.rotation.x *camera_flip_mod), vec3( 1.0f, 0.0f, 0.0f))rotation_matrix = rotate( rotation_matrix, radians(camera.rotation.y), vec3( 0.0f, 1.0f, 0.0f));rotation_matrix = rotate( rotation_matrix, radians(camera.rotation.z), vec3( 0.0f, 0.0f, 1.0f));if camera.flipY: translation.y *= -1.0ftranslation_matrix = translate( mat4(1.0f), translation)# if (type == CameraType::firstperson)# {# matrices.view = rotation_matrix * translation_matrix;# }# else# {camera.matrices.view = translation_matrix * rotation_matrix;# }camera.view_position = vec4( camera.position, 0.0f) *vec4( -1.0f, 1.0f, -1.0f, 1.0f)camera.updated = trueproc `set_perspective_with`*( c: var Camera, fov, aspect, z_near, z_far: float32) =c.fov = fovc.z_near = z_nearc.z_far = z_farc.matrices.perspective = perspective( radians fov, aspect, z_near, z_far)if (c.flipY): c.matrices.perspective[1][1] *= -1fproc `position_is`*( c: var Camera, position: Vec3[float32]) =c.position = positionc.update_view_matrixproc `position+=`*( c: var Camera, position: Vec3[float32]) =c.position += positionc.update_view_matrixproc `rotation=`*( c: var Camera, rot: Vec3[float32]) =c.rotation = rotproc translate*( c: var Camera, vector: Vec3[float32]) =c.position += vectorc.update_view_matrix()proc update*( camera: var Camera, dt: float) =camera.updated = falseproc `set_aspect_ratio_with`*( c: var Camera, fov, ar: float32) =c.set_perspective_with radians(fov), ar, 1, 256.0#c.update_view_matrix()proc a_camera*( ar: float32, camera_type: Camera_Kind = Perspective): Camera =case camera_typeof Ortho: discardof Perspective: discardresult.position = vec3f( 0.0.float32, 0.0, 0.0)result.rotation = vec3f(0.float32)result.set_perspective_with( 90.0.float32, ar, 1.0, 256.0)result.update_view_matrix()result
flip_Y*: bool
typeAlternative_Seq*[T] = objectlength*: int, capacity*: intdata*: ptr UncheckedArray[T]proc `=destroy`*[T](x: Alternative_Seq[T]) =if x.data != nil:for i in 0..<x.len: `=destroy`(x.data[i])dealloc(x.data)proc `=trace`[T](x: var Alternative_Seq[T]; env: pointer) =# `=trace` allows the cycle collector `--mm:orc`# to understand how to trace the object graph.if x.data != nil:for i in 0..<x.len: `=trace`(x.data[i], env)proc `=copy`*[T](a: var Alternative_Seq[T]; b: Alternative_Seq[T]) =# do nothing for self-assignments:if a.data == b.data: return`=destroy`(a)wasMoved(a)a.len = b.lena.cap = b.capif b.data != nil:a.data = cast[typeof(a.data)](alloc(a.cap * sizeof(T)))for i in 0..<a.len:a.data[i] = b.data[i]proc `=dup`*[T](a: Alternative_Seq[T]): Alternative_Seq[T] {.nodestroy.} =# an optimized version of `=wasMoved(tmp); `=copy(tmp, src)`# usually present if a custom `=copy` hook is overriddenresult.len = a.lenresult.cap = a.capif a.data != nil:result.data = cast[typeof(result.data)](alloc(result.cap * sizeof(T)))for i in 0..<result.len:result.data[i] = `=dup`(a.data[i])proc `=sink`*[T](a: var Alternative_Seq[T]; b: Alternative_Seq[T]) =# move assignment, optional.# Compiler is using `=destroy` and `copyMem` when not provided`=destroy`(a)wasMoved(a)a.len = b.lena.cap = b.capa.data = b.dataproc add*[T](x: var Alternative_Seq[T]; y: sink T) =if x.len >= x.cap:x.cap = max(x.len + 1, x.cap * 2)x.data = cast[typeof(x.data)](realloc(x.data, x.cap * sizeof(T)))x.data[x.len] = yinc x.lenproc `[]`*[T](x: Alternative_Seq[T]; i: Natural): lent T =assert i < x.lenx.data[i]proc `[]=`*[T](x: var Alternative_Seq[T]; i: Natural; y: sink T) =assert i < x.lenx.data[i] = yproc an_alternative_seq*[T](elems: varargs[T]): Alternative_Seq[T] =result.cap = elems.lenresult.len = elems.lenresult.data = cast[typeof(result.data)](alloc(result.cap * sizeof(T)))for i in 0..<result.len: result.data[i] = elems[i]proc len*[T](x: Alternative_Seq[T]): int {.inline.} = x.len