changeset 533:e4a0450c30e3

did: some minor fixes, add optinal FPS limit
author Sam <sam@basx.dev>
date Sun, 05 Feb 2023 21:57:07 +0700
parents 5d457f7bb624
children e1b60a09d7dc
files src/semicongine/engine.nim src/semicongine/mesh.nim src/semicongine/shader.nim src/semicongine/thing.nim
diffstat 4 files changed, 48 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/engine.nim	Sun Feb 05 11:39:11 2023 +0700
+++ b/src/semicongine/engine.nim	Sun Feb 05 21:57:07 2023 +0700
@@ -1,4 +1,5 @@
 import std/options
+import std/os
 import std/times
 import std/typetraits
 import std/strformat
@@ -55,6 +56,7 @@
     uniformBuffers*: array[MAX_FRAMES_IN_FLIGHT, Buffer]
     descriptorPool*: VkDescriptorPool
     descriptors: array[MAX_FRAMES_IN_FLIGHT, VkDescriptorSet]
+    clearColor*: Vec4
   QueueFamily = object
     properties*: VkQueueFamilyProperties
     hasSurfaceSupport*: bool
@@ -93,12 +95,13 @@
     window*: NativeWindow
     currentscenedata*: Thing
     input*: Input
+    fps*: uint
 
 
-method update*(thing: Thing, engine: Engine, dt: float32) {.base.} = discard
-method update*(part: Part, engine: Engine, dt: float32) {.base.} = discard
+method update*(thing: Thing, engine: Engine, t, dt: float32) {.base.} = discard
+method update*(part: Part, engine: Engine, t, dt: float32) {.base.} = discard
 
-method update*[T, U](mesh: Mesh[T, U], engine: Engine, dt: float32) =
+method update*[T, U](mesh: Mesh[T, U], engine: Engine, t, dt: float32) =
   let transform = @[mesh.thing.getModelTransform().transposed()]
   for name, value in mesh.vertexData.fieldPairs:
     when value is ModelTransformAttribute:
@@ -710,8 +713,8 @@
       sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
       pInheritanceInfo: nil,
     )
-    clearColor = VkClearValue(color: VkClearColorValue(float32: [0.2'f, 0.2'f,
-        0.2'f, 1.0'f]))
+    clearColor = VkClearValue(color: VkClearColorValue(
+        float32: pipeline.clearColor))
     renderPassInfo = VkRenderPassBeginInfo(
       sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
       renderPass: renderPass,
@@ -806,12 +809,17 @@
     (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain()
 
 
+func frametime(engine: Engine): auto =
+  if engine.fps == 0: 0'f
+  else: 1'f / float32(engine.fps)
+
 proc run*(engine: var Engine, pipeline: var RenderPipeline, globalUpdate: proc(
-    engine: var Engine, dt: float32)) =
+    engine: var Engine, t, dt: float32)) =
   var
     currentFrame = 0
     resized = false
-    lastUpdate = getTime()
+    lastUpdate = cpuTime()
+    lastframe = 0'f
 
   while true:
     # process input
@@ -845,19 +853,22 @@
 
     # game logic update
     let
-      now = getTime()
-      dt = float32(float64((now - lastUpdate).inNanoseconds) / 1_000_000_000'f64)
+      now = cpuTime()
+      dt = now - lastUpdate
     lastUpdate = now
-    engine.globalUpdate(dt)
+    engine.globalUpdate(now, dt)
     for thing in allThings(engine.currentscenedata):
       for part in thing.parts:
-        update(part, engine, dt)
-      update(thing, engine, dt)
+        update(part, engine, now, dt)
+      update(thing, engine, now, dt)
 
     # submit frame for drawing
-    engine.window.drawFrame(engine.vulkan, currentFrame, resized, pipeline)
+    if engine.fps == 0 or (now - lastframe >= engine.frametime): # framerate limit
+      engine.window.drawFrame(engine.vulkan, currentFrame, resized, pipeline)
+      lastframe = now
     resized = false
     currentFrame = (currentFrame + 1) mod MAX_FRAMES_IN_FLIGHT
+
   checkVkResult vkDeviceWaitIdle(engine.vulkan.device.device)
 
 proc trash*(pipeline: var RenderPipeline) =
--- a/src/semicongine/mesh.nim	Sun Feb 05 11:39:11 2023 +0700
+++ b/src/semicongine/mesh.nim	Sun Feb 05 21:57:07 2023 +0700
@@ -109,10 +109,17 @@
   else:
     result[3] = uint32(mesh.vertexData.VertexCount)
 
-func squareData*[T: SomeFloat](): auto = PositionAttribute[TVec2[T]](
-  data: @[TVec2[T]([T(0), T(0)]), TVec2[T]([T(0), T(1)]), TVec2[T]([T(1), T(
-      1)]), TVec2[T]([T(1), T(0)])]
-)
-func squareIndices*[T: uint16|uint32](): auto = seq[array[3, T]](
-  @[[T(0), T(1), T(3)], [T(2), T(1), T(3)]]
-)
+func quad*[VertexType, VecType, T](): Mesh[VertexType, uint16] =
+  result = new Mesh[VertexType, uint16]
+  result.indexed = true
+  result.indices = @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]]
+  result.vertexData = VertexType()
+  for attrname, value in result.vertexData.fieldPairs:
+    when typeof(value) is PositionAttribute:
+      value.data = @[
+        VecType([T(-0.5), T(-0.5), T(0)]),
+        VecType([T(+0.5), T(-0.5), T(0)]),
+        VecType([T(+0.5), T(+0.5), T(0)]),
+        VecType([T(-0.5), T(+0.5), T(0)]),
+      ]
+      value.useOnDeviceMemory = true
--- a/src/semicongine/shader.nim	Sun Feb 05 11:39:11 2023 +0700
+++ b/src/semicongine/shader.nim	Sun Feb 05 21:57:07 2023 +0700
@@ -141,10 +141,11 @@
       elif getAttributeType(value) is TVec4:
         lines.add &"    vec4 out_color = in_color;";
       hasColor += 1
-  let uniformBlockName = name(Uniforms).toLower()
-  for attrname, value in Uniforms().fieldPairs:
-    when typeof(value) is ViewProjectionTransform:
-      lines.add "out_position = " & uniformBlockName & "." & attrname & " * out_position;"
+  when not (Uniforms is void):
+    let uniformBlockName = name(Uniforms).toLower()
+    for attrname, value in Uniforms().fieldPairs:
+      when typeof(value) is ViewProjectionTransform:
+        lines.add "out_position = " & uniformBlockName & "." & attrname & " * out_position;"
 
   lines.add shaderBody
   lines.add "    gl_Position = out_position;"
--- a/src/semicongine/thing.nim	Sun Feb 05 11:39:11 2023 +0700
+++ b/src/semicongine/thing.nim	Sun Feb 05 21:57:07 2023 +0700
@@ -16,7 +16,11 @@
 
 
 func `$`*(thing: Thing): string = thing.name
-method `$`*(part: Part): string {.base.} = &"{part.thing} -> Part"
+method `$`*(part: Part): string {.base.} =
+  if part.thing != nil:
+    &"{part.thing} -> Part"
+  else:
+    &"Standalone Part"
 
 proc add*(thing: Thing, child: Thing) =
   child.parent = thing