changeset 71:53ccd6090116

did: cleanup + auto-generate mvp-transformartion in shader code
author Sam <sam@basx.dev>
date Sun, 05 Feb 2023 11:39:11 +0700
parents 02bc1232905c
children a61172f2d94e
files examples/E04_input.nim src/semicongine/descriptor.nim src/semicongine/platform/linux/xlib.nim src/semicongine/shader.nim
diffstat 4 files changed, 42 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/examples/E04_input.nim	Sun Feb 05 00:48:03 2023 +0700
+++ b/examples/E04_input.nim	Sun Feb 05 11:39:11 2023 +0700
@@ -1,4 +1,3 @@
-import std/tables
 import std/enumerate
 import std/strutils
 import std/typetraits
@@ -14,7 +13,7 @@
     color: ColorAttribute[Vec4]
     transform: ModelTransformAttribute
   Uniforms = object
-    projection: Descriptor[Mat44]
+    projection: ViewProjectionTransform
 
 const
   arrow = @[
@@ -213,9 +212,7 @@
   scene.add newThing("cursor", cursormesh)
 
   # upload data, prepare shaders, etc
-  const vertexShader = generateVertexShaderCode[VertexDataA, Uniforms]("""
-    out_position = uniforms.projection * transform * vec4(position, 1);
-  """)
+  const vertexShader = generateVertexShaderCode[VertexDataA, Uniforms]()
   const fragmentShader = generateFragmentShaderCode[VertexDataA]()
   pipeline = setupPipeline[VertexDataA, Uniforms, uint16](
     myengine,
--- a/src/semicongine/descriptor.nim	Sun Feb 05 00:48:03 2023 +0700
+++ b/src/semicongine/descriptor.nim	Sun Feb 05 11:39:11 2023 +0700
@@ -14,10 +14,12 @@
 #
 type
   DescriptorType = SomeNumber|TVec|TMat
-  Descriptor*[T:DescriptorType] = object
+  Descriptor*[T: DescriptorType] = object
     value*: T
+  ViewProjectionTransform* = Descriptor[Mat44]
 
-proc createUniformDescriptorLayout*(device: VkDevice, shaderStage: VkShaderStageFlags, binding: uint32): VkDescriptorSetLayout =
+proc createUniformDescriptorLayout*(device: VkDevice,
+    shaderStage: VkShaderStageFlags, binding: uint32): VkDescriptorSetLayout =
   var
     layoutbinding = VkDescriptorSetLayoutBinding(
       binding: binding,
@@ -33,7 +35,8 @@
     )
   checkVkResult device.vkCreateDescriptorSetLayout(addr(layoutInfo), nil, addr(result))
 
-proc createUniformBuffers*[nBuffers: static int, Uniforms](device: VkDevice, physicalDevice: VkPhysicalDevice): array[nBuffers, Buffer] =
+proc createUniformBuffers*[nBuffers: static int, Uniforms](device: VkDevice,
+    physicalDevice: VkPhysicalDevice): array[nBuffers, Buffer] =
   let size = sizeof(Uniforms)
   for i in 0 ..< nBuffers:
     var buffer = InitBuffer(
@@ -47,7 +50,8 @@
 
 template getDescriptorType*(v: Descriptor): auto = get(genericParams(typeof(v)), 0)
 
-func generateGLSLUniformDeclarations*[Uniforms](binding: int = 0): string {.compileTime.} =
+func generateGLSLUniformDeclarations*[Uniforms](
+  binding: int = 0): string {.compileTime.} =
   var stmtList: seq[string]
 
   when not (Uniforms is void):
--- a/src/semicongine/platform/linux/xlib.nim	Sun Feb 05 00:48:03 2023 +0700
+++ b/src/semicongine/platform/linux/xlib.nim	Sun Feb 05 11:39:11 2023 +0700
@@ -3,9 +3,7 @@
 import
   x11/xlib,
   x11/xutil,
-  x11/keysym,
-  x11/xinput,
-  x11/xinput2
+  x11/keysym
 import x11/x
 
 import ../../events
@@ -141,7 +139,7 @@
       addr(root),
       addr(win),
       addr(rootX),
-      addr(rootX),
+      addr(rootY),
       addr(winX),
       addr(winY),
       addr(mask),
--- a/src/semicongine/shader.nim	Sun Feb 05 00:48:03 2023 +0700
+++ b/src/semicongine/shader.nim	Sun Feb 05 11:39:11 2023 +0700
@@ -1,4 +1,5 @@
 import std/os
+import std/typetraits
 import std/hashes
 import std/strformat
 import std/strutils
@@ -21,6 +22,15 @@
     shader*: VkPipelineShaderStageCreateInfo
     uniforms*: Uniforms
 
+proc staticExecChecked(command: string, input = ""): string {.compileTime.} =
+  let (output, exitcode) = gorgeEx(
+      command = command,
+      input = input)
+  if exitcode != 0:
+    raise newException(Exception, output)
+  return output
+
+
 func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} =
   case stage
   of VK_SHADER_STAGE_VERTEX_BIT: "vert"
@@ -44,17 +54,21 @@
     shaderfile = getTempDir() / fmt"shader_{shaderHash}.{stagename}"
     projectPath = querySetting(projectPath)
 
-  let (output, exitCode_glsl) = gorgeEx(
+  discard staticExecChecked(
       command = fmt"{projectPath}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {shaderfile}",
-      input = shaderSource)
-  if exitCode_glsl != 0:
-    raise newException(Exception, output)
+      input = shaderSource
+  )
 
   when defined(mingw): # required for crosscompilation, path separators get messed up
     let shaderbinary = staticRead shaderfile.replace("\\", "/")
   else:
     let shaderbinary = staticRead shaderfile
-  # removeFile(shaderfile) TODO: remove file at compile time? how to do in cross-platform consistent way?
+  when defined(linux) or defined(mingw):
+    discard staticExecChecked(command = fmt"rm {shaderfile}")
+  elif defined(windows):
+    discard staticExecChecked(command = fmt"del {shaderfile}")
+  else:
+    raise newException(Exception, "Unsupported operating system")
 
   var i = 0
   while i < shaderbinary.len:
@@ -102,12 +116,14 @@
   lines.add "layout(location = 0) out vec4 fragColor;"
   lines.add "void " & entryPoint & "() {"
 
+  var viewprojection = ""
+
   var hasPosition = 0
   var hasColor = 0
-  for name, value in VertexType().fieldPairs:
+  for attrname, value in VertexType().fieldPairs:
     when typeof(value) is PositionAttribute:
       let glsltype = getGLSLType[getAttributeType(value)]()
-      lines.add &"    {glsltype} in_position = " & name & ";"
+      lines.add &"    {glsltype} in_position = " & attrname & ";"
       if getAttributeType(value) is TVec2:
         lines.add "    vec4 out_position = vec4(in_position, 0.0, 1.0);"
       elif getAttributeType(value) is TVec3:
@@ -115,14 +131,20 @@
       elif getAttributeType(value) is TVec4:
         lines.add "    vec4 out_position = in_position;"
       hasPosition += 1
+    when typeof(value) is ModelTransformAttribute:
+      lines.add &"    out_position = " & attrname & " * out_position;"
     when typeof(value) is ColorAttribute:
       let glsltype = getGLSLType[getAttributeType(value)]()
-      lines.add &"    {glsltype} in_color = " & name & ";"
+      lines.add &"    {glsltype} in_color = " & attrname & ";"
       if getAttributeType(value) is TVec3:
         lines.add &"    vec4 out_color = vec4(in_color, 1);";
       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;"
 
   lines.add shaderBody
   lines.add "    gl_Position = out_position;"