changeset 594:512d33d314c4

add: correct swapchain destruction, update 1st example to be working
author Sam <sam@basx.dev>
date Thu, 20 Apr 2023 21:59:52 +0700
parents dfd554f8487a
children 7f7e797335ed
files examples/E01_hello_triangle.nim src/semicongine/engine.nim src/semicongine/renderer.nim src/semicongine/vulkan/pipeline.nim src/semicongine/vulkan/renderpass.nim src/semicongine/vulkan/swapchain.nim
diffstat 6 files changed, 61 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/examples/E01_hello_triangle.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/examples/E01_hello_triangle.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -1,55 +1,45 @@
-import std/times
 import std/strutils
 import std/enumerate
 
 import semicongine
 
-type
-  # define type of vertex
-  VertexDataA = object
-    position: PositionAttribute[Vec2]
-    color: ColorAttribute[Vec3]
-
-var pipeline: RenderPipeline[VertexDataA, void]
-
-proc globalUpdate(engine: var Engine, t, dt: float32) =
-  discard
-
-# vertex data (types must match the above VertexAttributes)
-const
-  triangle_pos = @[
-    Vec2([0.0'f32, -0.5'f32]),
-    Vec2([0.5'f32, 0.5'f32]),
-    Vec2([-0.5'f32, 0.5'f32]),
-  ]
-  triangle_color = @[
-    Vec3([1.0'f32, 0.0'f32, 0.0'f32]),
-    Vec3([0.0'f32, 1.0'f32, 0.0'f32]),
-    Vec3([0.0'f32, 0.0'f32, 1.0'f32]),
-  ]
 
-when isMainModule:
-  var myengine = igniteEngine("Hello triangle")
-
-  # build a mesh
-  var trianglemesh = new Mesh[VertexDataA, uint16]
-  trianglemesh.vertexData = VertexDataA(
-    position: PositionAttribute[Vec2](data: triangle_pos),
-    color: ColorAttribute[Vec3](data: triangle_color),
+const
+  vertexInput = @[
+    attr[Vec3f]("position", memoryLocation=VRAM),
+    attr[Vec3f]("color", memoryLocation=VRAM),
+  ]
+  vertexOutput = @[attr[Vec3f]("outcolor")]
+  fragOutput = @[attr[Vec4f]("color")]
+  vertexCode = compileGlslShader(
+    stage=VK_SHADER_STAGE_VERTEX_BIT,
+    inputs=vertexInput,
+    outputs=vertexOutput,
+    main="""gl_Position = vec4(position, 1.0); outcolor = color;"""
   )
-  # build a single-object scene graph
-  var triangle = newThing("triangle", trianglemesh)
+  fragmentCode = compileGlslShader(
+    stage=VK_SHADER_STAGE_FRAGMENT_BIT,
+    inputs=vertexOutput,
+    outputs=fragOutput,
+    main="color = vec4(outcolor, 1);"
+  )
 
-  # upload data, prepare shaders, etc
-  const vertexShader = generateVertexShaderCode[VertexDataA, void]()
-  const fragmentShader = generateFragmentShaderCode[VertexDataA]()
-  pipeline = setupPipeline[VertexDataA, void, uint16](
-    myengine,
-    triangle,
-    vertexShader,
-    fragmentShader
+var
+  triangle = newEntity(
+    "triangle",
+    newMesh(
+      [newVec3f(-0.5, 0.5), newVec3f(0, -0.5), newVec3f(0.5, 0.5)],
+      [X, Y, Z],
+    )
   )
-  # show something
-  myengine.run(pipeline, globalUpdate)
-  pipeline.trash()
-  myengine.trash()
+  myengine = initEngine("Hello triangle")
+  renderPass = myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)
+
+myengine.setRenderer(renderPass)
+myengine.addScene(triangle, vertexInput)
+
+while myengine.running and not myengine.keyWasPressed(Escape):
+  myengine.updateInputs()
+  myengine.renderScene(triangle)
+
+myengine.destroy()
--- a/src/semicongine/engine.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/src/semicongine/engine.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -43,6 +43,7 @@
   engine.debugger.destroy()
   engine.instance.destroy()
   engine.window.destroy()
+  engine.running = false
 
 
 proc initEngine*(
@@ -88,11 +89,13 @@
   engine.renderer.setupDrawableBuffers(entity, vertexInput)
 
 proc renderScene*(engine: var Engine, entity: Entity) =
-  assert engine.running
-  engine.renderer.render(entity)
+  if engine.running:
+    engine.renderer.render(entity)
 
 proc updateInputs*(engine: var Engine) =
-  assert engine.running
+  if not engine.running:
+    return
+
   engine.input.keyWasPressed = {}
   engine.input.keyWasReleased = {}
   engine.input.mouseWasPressed = {}
--- a/src/semicongine/renderer.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/src/semicongine/renderer.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -177,7 +177,7 @@
       raise newException(Exception, "Unable to recreate swapchain")
 
   if oldSwapchain.vk.valid:
-    oldSwapchain.queueFinishedFence[oldSwapchain.currentInFlight].wait()
+    checkVkResult renderer.device.vk.vkDeviceWaitIdle()
     oldSwapchain.destroy()
 
 
--- a/src/semicongine/vulkan/pipeline.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/src/semicongine/vulkan/pipeline.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -43,6 +43,8 @@
   var uniformBufferSize = 0'u64
   for uniform in pipeline.uniforms:
     uniformBufferSize += uniform.thetype.size
+  if uniformBufferSize == 0:
+    return
 
   for i in 0 ..< inFlightFrames:
     var buffer = pipeline.device.createBuffer(
@@ -187,6 +189,8 @@
   result.setupUniforms(inFlightFrames=inFlightFrames)
 
 proc updateUniforms*(pipeline: Pipeline, rootEntity: Entity, currentInFlight: int) =
+  if pipeline.uniformBuffers.len == 0:
+    return
   assert pipeline.vk.valid
   assert pipeline.uniformBuffers[currentInFlight].vk.valid
 
--- a/src/semicongine/vulkan/renderpass.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/src/semicongine/vulkan/renderpass.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -4,6 +4,7 @@
 import ./api
 import ./utils
 import ./device
+import ./physicaldevice
 import ./pipeline
 import ./shader
 import ./framebuffer
@@ -65,11 +66,21 @@
   result.subpasses = pSubpasses
   checkVkResult device.vk.vkCreateRenderPass(addr(createInfo), nil, addr(result.vk))
 
-proc simpleForwardRenderPass*(device: Device, format: VkFormat, vertexCode: ShaderCode, fragmentCode: ShaderCode, inFlightFrames: int, clearColor=Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32])): RenderPass =
+proc simpleForwardRenderPass*(
+  device: Device,
+  vertexCode: ShaderCode,
+  fragmentCode: ShaderCode,
+  inFlightFrames: int = 2,
+  format = VkFormat(0),
+  clearColor=Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32])
+): RenderPass =
   assert device.vk.valid
+  var theformat = format
+  if theformat == VkFormat(0):
+    theformat = device.physicalDevice.getSurfaceFormats().filterSurfaceFormat().format
   var
     attachments = @[VkAttachmentDescription(
-        format: format,
+        format: theformat,
         samples: VK_SAMPLE_COUNT_1_BIT,
         loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
         storeOp: VK_ATTACHMENT_STORE_OP_STORE,
--- a/src/semicongine/vulkan/swapchain.nim	Thu Apr 20 01:00:48 2023 +0700
+++ b/src/semicongine/vulkan/swapchain.nim	Thu Apr 20 21:59:52 2023 +0700
@@ -35,7 +35,7 @@
     queueFamily: QueueFamily
     imageCount: uint32
     presentMode: VkPresentModeKHR
-    inFlightFrames: int
+    inFlightFrames*: int
 
 
 proc createSwapchain*(