changeset 336:887ddc8d45fd

did: update examples to work with improved scenegraph/material api, notice removed complexity!
author Sam <sam@basx.dev>
date Tue, 05 Sep 2023 00:28:35 +0700
parents f05b4bef44d1
children 677f3b5a2943
files examples/E01_hello_triangle.nim examples/E02_squares.nim examples/E03_hello_cube.nim examples/E04_input.nim examples/E10_pong.nim
diffstat 5 files changed, 93 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/examples/E01_hello_triangle.nim	Mon Sep 04 00:55:35 2023 +0700
+++ b/examples/E01_hello_triangle.nim	Tue Sep 05 00:28:35 2023 +0700
@@ -21,12 +21,12 @@
     meshes: @[newMesh(
       [newVec3f(-0.5, 0.5), newVec3f(0, -0.5), newVec3f(0.5, 0.5)],
       [newVec4f(1, 0, 0, 1), newVec4f(0, 1, 0, 1), newVec4f(0, 0, 1, 1)],
-      material=Material(name: "")
+      material=Material(name: "default")
     )]
   )
   myengine = initEngine("Hello triangle")
 
-myengine.initRenderer({"": shaderConfiguration}.toTable)
+myengine.initRenderer({"default": shaderConfiguration}.toTable)
 myengine.addScene(triangle)
 
 while myengine.updateInputs() == Running and not myengine.keyWasPressed(Escape):
--- a/examples/E02_squares.nim	Mon Sep 04 00:55:35 2023 +0700
+++ b/examples/E02_squares.nim	Tue Sep 05 00:28:35 2023 +0700
@@ -1,4 +1,5 @@
 import std/sequtils
+import std/tables
 import std/random
 
 import ../src/semicongine
@@ -42,19 +43,15 @@
 
 
   const
-    inputs = @[
-      attr[Vec3f]("position"),
-      attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
-      attr[uint32]("index"),
-    ]
-    intermediate = @[attr[Vec4f]("outcolor")]
-    uniforms = @[attr[float32]("time")]
-    outputs = @[attr[Vec4f]("color")]
-    (vertexCode, fragmentCode) = compileVertexFragmentShaderSet(
-      inputs=inputs,
-      intermediate=intermediate,
-      outputs=outputs,
-      uniforms=uniforms,
+    shaderConfiguration = createShaderConfiguration(
+      inputs=[
+        attr[Vec3f]("position"),
+        attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
+        attr[uint32]("index"),
+      ],
+      intermediates=[attr[Vec4f]("outcolor")],
+      uniforms=[attr[float32]("time")],
+      outputs=[attr[Vec4f]("color")],
       vertexCode="""
 float pos_weight = index / 100.0; // add some gamma correction?
 float t = sin(Uniforms.time * 0.5) * 0.5 + 0.5;
@@ -69,17 +66,18 @@
     positions=vertices,
     indices=indices,
     colors=colors,
+    material=Material(name: "default")
   )
-  setMeshData[uint32](squaremesh, "index", iValues.toSeq)
+  squaremesh[].initVertexAttribute("index", iValues.toSeq)
 
   var myengine = initEngine("Squares")
-  myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode))
+  myengine.initRenderer({"default": shaderConfiguration}.toTable)
 
-  var scene = newScene("scene", newEntity("scene", [], newEntity("squares", {"mesh": Component(squaremesh)})))
-  myengine.addScene(scene, inputs, @[], transformAttribute="")
+  var scene = Scene(name: "scene", meshes: @[squaremesh])
   scene.addShaderGlobal("time", 0.0'f32)
+  myengine.addScene(scene)
   while myengine.updateInputs() == Running and not myengine.keyWasPressed(Escape):
-    setShaderGlobal(scene, "time", getShaderGlobal[float32](scene, "time") + 0.0005'f)
+    scene.setShaderGlobal("time", getShaderGlobal[float32](scene, "time") + 0.0005'f)
     myengine.renderScene(scene)
 
   myengine.destroy()
--- a/examples/E03_hello_cube.nim	Mon Sep 04 00:55:35 2023 +0700
+++ b/examples/E03_hello_cube.nim	Tue Sep 05 00:28:35 2023 +0700
@@ -8,6 +8,7 @@
 #
 
 
+import std/tables
 import std/times
 
 import ../src/semicongine
@@ -52,35 +53,31 @@
   var myengine = initEngine("Hello cube")
 
   const
-    inputs = @[
-      attr[Vec3f]("position"),
-      attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
-    ]
-    intermediate = @[attr[Vec4f]("outcolor")]
-    uniforms = @[
-      attr[Mat4]("projection"),
-      attr[Mat4]("view"),
-      attr[Mat4]("model"),
-    ]
-    fragOutput = @[attr[Vec4f]("color")]
-    (vertexCode, fragmentCode) = compileVertexFragmentShaderSet(
-      inputs=inputs,
-      intermediate=intermediate,
-      outputs=fragOutput,
-      uniforms=uniforms,
+    shaderConfiguration = createShaderConfiguration(
+      inputs=[
+        attr[Vec3f]("position"),
+        attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
+      ],
+      intermediates=[attr[Vec4f]("outcolor")],
+      uniforms=[
+        attr[Mat4]("projection"),
+        attr[Mat4]("view"),
+        attr[Mat4]("model"),
+      ],
+      outputs=[attr[Vec4f]("color")],
       vertexCode="""outcolor = color; gl_Position = (Uniforms.projection * Uniforms.view * Uniforms.model) * vec4(position, 1);""",
       fragmentCode="color = outcolor;",
     )
-  myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode))
-  var cube = newScene("scene", newEntity("cube", {"mesh": Component(newMesh(positions=cube_pos, indices=tris, colors=cube_color))}))
+  myengine.initRenderer({"default": shaderConfiguration}.toTable)
+  var cube = Scene(name: "scene", meshes: @[newMesh(positions=cube_pos, indices=tris, colors=cube_color, material=Material(name: "default"))])
   cube.addShaderGlobal("projection", Unit4f32)
   cube.addShaderGlobal("view", Unit4f32)
   cube.addShaderGlobal("model", Unit4f32)
-  myengine.addScene(cube, inputs, @[], transformAttribute="")
+  myengine.addScene(cube)
 
   var t: float32 = cpuTime()
   while myengine.updateInputs() == Running and not myengine.keyWasPressed(Escape):
-    setShaderGlobal(cube, "model", translate3d(0'f32, 0'f32, 10'f32) * rotate3d(t, Yf32))
+    setShaderGlobal(cube, "model", translate(0'f32, 0'f32, 10'f32) * rotate(t, Yf32))
     setShaderGlobal(cube, "projection",
       perspective(
         float32(PI / 4),
@@ -90,7 +87,6 @@
       )
     )
     t = cpuTime()
-
     myengine.renderScene(cube)
 
   myengine.destroy()
--- a/examples/E04_input.nim	Mon Sep 04 00:55:35 2023 +0700
+++ b/examples/E04_input.nim	Tue Sep 05 00:28:35 2023 +0700
@@ -1,4 +1,5 @@
 import std/enumerate
+import std/tables
 import std/typetraits
 import std/math
 
@@ -107,15 +108,17 @@
 
   # define mesh objects
   var
+    material = Material(name: "default")
     cursormesh = newMesh(
       positions=positions,
       colors=arrow_colors,
-      instanceCount=1,
+      material=material,
     )
     keyboardmesh = newMesh(
       positions=keyvertexpos,
       colors=keyvertexcolor,
-      indices=keymeshindices
+      indices=keymeshindices,
+      material=material,
     )
     backgroundmesh = newMesh(
       positions= @[
@@ -131,48 +134,42 @@
         backgroundColor,
       ],
       indices= @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]],
+      material=material,
     )
 
   # define mesh objects
-  scene = newScene("scene", newEntity("scene"))
-  scene.root.add newEntity("background", {"mesh": Component(backgroundmesh)})
-  let keyboard = newEntity("keyboard", {"mesh": Component(keyboardmesh)})
-  keyboard.transform = translate3d(
+  var keyboard_center = translate(
     -float32(rowWidth) / 2'f32,
     -float32(tupleLen(keyRows) * (keyDimension + keyGap) - keyGap) / 2'f32,
     0'f32
   )
-  scene.root.add newEntity("keyboard-center", [], keyboard)
-  scene.root.add newEntity("cursor", {"mesh": Component(cursormesh)})
+  scene = Scene(name: "scene", meshes: @[backgroundmesh, keyboardmesh, cursormesh])
 
   # shaders
   const
-    inputs = @[
-      attr[Vec3f]("position"),
-      attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
-      attr[Mat4]("transform", memoryPerformanceHint=PreferFastWrite, perInstance=true),
-    ]
-    intermediate = @[attr[Vec4f]("outcolor")]
-    uniforms = @[attr[Mat4]("projection")]
-    outputs = @[attr[Vec4f]("color")]
-    (vertexCode, fragmentCode) = compileVertexFragmentShaderSet(
-      inputs=inputs,
-      intermediate=intermediate,
-      outputs=outputs,
-      uniforms=uniforms,
+    shaderConfiguration = createShaderConfiguration(
+      inputs=[
+        attr[Vec3f]("position"),
+        attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
+        attr[Mat4]("transform", memoryPerformanceHint=PreferFastWrite, perInstance=true),
+      ],
+      intermediates=[attr[Vec4f]("outcolor")],
+      uniforms=[attr[Mat4]("projection")],
+      outputs=[attr[Vec4f]("color")],
       vertexCode="""outcolor = color; gl_Position = vec4(position, 1) * (transform * Uniforms.projection);""",
       fragmentCode="color = outcolor;",
     )
 
   # set up rendering
-  myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode, clearColor=newVec4f(0, 0, 0.5)))
-  myengine.addScene(scene, inputs, @[], transformAttribute="transform")
+  myengine.initRenderer({"default": shaderConfiguration}.toTable)
   scene.addShaderGlobal("projection", Unit4f32)
+  myengine.addScene(scene)
+  myengine.hideSystemCursor()
 
   # mainloop
   while myengine.updateInputs() == Running:
     if myengine.windowWasResized():
-      setShaderGlobal(scene, "projection",
+      scene.setShaderGlobal("projection",
         ortho(
           0, float32(myengine.getWindow().size[0]),
           0, float32(myengine.getWindow().size[1]),
@@ -181,27 +178,26 @@
       )
       let
         winsize = myengine.getWindow().size
-        center = translate3d(float32(winsize[0]) / 2'f32, float32(winsize[1]) / 2'f32, 0.1'f32)
-      scene.root.firstWithName("keyboard-center").transform = center
-      scene.root.firstWithName("background").transform = scale3d(float32(winsize[0]), float32(winsize[1]), 1'f32)
+        center = translate(float32(winsize[0]) / 2'f32, float32(winsize[1]) / 2'f32, 0.1'f32)
+      keyboardmesh.transform = keyboard_center * center
+      backgroundmesh.transform = scale(float32(winsize[0]), float32(winsize[1]), 1'f32)
 
-    let mousePos = translate3d(myengine.mousePosition().x + 20, myengine.mousePosition().y + 20, 0'f32)
-    scene.root.firstWithName("cursor").transform = mousePos
+    let mousePos = translate(myengine.mousePosition().x + 20, myengine.mousePosition().y + 20, 0'f32)
+    cursormesh.transform = mousePos
 
-    var mesh = Mesh(scene.root.firstWithName("keyboard")["mesh"])
     for (index, key) in enumerate(keyIndices):
       if myengine.keyWasPressed(key):
-        let baseIndex = uint32(index * 4)
-        mesh.updateMeshData("color", baseIndex + 0, activeColor)
-        mesh.updateMeshData("color", baseIndex + 1, activeColor)
-        mesh.updateMeshData("color", baseIndex + 2, activeColor)
-        mesh.updateMeshData("color", baseIndex + 3, activeColor)
+        let baseIndex = index * 4
+        keyboardmesh[].updateAttributeData("color", baseIndex + 0, activeColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 1, activeColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 2, activeColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 3, activeColor)
       if myengine.keyWasReleased(key):
-        let baseIndex = uint32(index * 4)
-        mesh.updateMeshData("color", baseIndex + 0, baseColor)
-        mesh.updateMeshData("color", baseIndex + 1, baseColor)
-        mesh.updateMeshData("color", baseIndex + 2, baseColor)
-        mesh.updateMeshData("color", baseIndex + 3, baseColor)
+        let baseIndex = index * 4
+        keyboardmesh[].updateAttributeData("color", baseIndex + 0, baseColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 1, baseColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 2, baseColor)
+        keyboardmesh[].updateAttributeData("color", baseIndex + 3, baseColor)
 
     myengine.renderScene(scene)
 
--- a/examples/E10_pong.nim	Mon Sep 04 00:55:35 2023 +0700
+++ b/examples/E10_pong.nim	Tue Sep 05 00:28:35 2023 +0700
@@ -1,4 +1,5 @@
 import std/times
+import std/tables
 
 import ../src/semicongine
 
@@ -8,8 +9,8 @@
   barWidth = 0.01'f
   ballcolor = hexToColorAlpha("B17F08").gamma(2.2).colorToHex()
   ballSize = 0.01'f
-  backgroundColor = hexToColorAlpha("FAC034FF").gamma(2.2)
   ballSpeed = 60'f
+  material = Material(name: "default")
 
 var
   level: Scene
@@ -17,41 +18,31 @@
 
 when isMainModule:
   var myengine = initEngine("Pong")
-  level = newScene("scene", newEntity("Level"))
-  var playerbarmesh = rect(color=barcolor)
-  var playerbar = newEntity("playerbar", {"mesh": Component(playerbarmesh)})
-  playerbar.transform = scale3d(barWidth, barSize, 1'f) * translate3d(0.5'f, 0'f, 0'f)
-  var player = newEntity("player", [], playerbar)
-  player.transform = translate3d(0'f, 0.3'f, 0'f)
-  level.root.add player
 
-  var ballmesh = circle(color=ballcolor)
-  var ball = newEntity("ball", {"mesh": Component(ballmesh)})
-  ball.transform = scale3d(ballSize, ballSize, 1'f) * translate3d(10'f, 10'f, 0'f)
-  level.root.add ball
+  var player = rect(color=barcolor, width=barWidth, height=barSize)
+  player.material = material
+  var ball = circle(color=ballcolor)
+  ball.material = material
+  level = Scene(name: "scene", meshes: @[ball, player])
 
   const
-    inputs = @[
-      attr[Vec3f]("position"),
-      attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
-      attr[Mat4]("transform", memoryPerformanceHint=PreferFastWrite, perInstance=true),
-    ]
-    intermediate = @[attr[Vec4f]("outcolor")]
-    uniforms = @[attr[Mat4]("projection")]
-    outputs = @[attr[Vec4f]("color")]
-    (vertexCode, fragmentCode) = compileVertexFragmentShaderSet(
-      inputs=inputs,
-      intermediate=intermediate,
-      outputs=outputs,
-      uniforms=uniforms,
+    shaderConfiguration = createShaderConfiguration(
+      inputs=[
+        attr[Vec3f]("position"),
+        attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite),
+        attr[Mat4]("transform", memoryPerformanceHint=PreferFastWrite, perInstance=true),
+      ],
+      intermediates=[attr[Vec4f]("outcolor")],
+      uniforms=[attr[Mat4]("projection")],
+      outputs=[attr[Vec4f]("color")],
       vertexCode="""outcolor = color; gl_Position = vec4(position, 1) * (transform * Uniforms.projection);""",
       fragmentCode="color = outcolor;",
     )
 
   # set up rendering
-  myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode, clearColor=backgroundColor))
-  myengine.addScene(level, inputs, @[], transformAttribute="transform")
+  myengine.initRenderer({"default": shaderConfiguration}.toTable)
   level.addShaderGlobal("projection", Unit4f32)
+  myengine.addScene(level)
 
   var
     winsize = myengine.getWindow().size
@@ -78,22 +69,21 @@
       height = float32(winsize[1]) / float32(winsize[0])
       width = 1'f
       setShaderGlobal(level, "projection", ortho(0, width, 0, height, 0, 1))
-    var player = level.root.firstWithName("player")
     if myengine.keyIsDown(Down) and (player.transform.col(3).y + barSize/2) < height:
-      player.transform = player.transform * translate3d(0'f, 1'f * dt, 0'f)
+      player.transform = player.transform * translate(0'f, 1'f * dt, 0'f)
     if myengine.keyIsDown(Up) and (player.transform.col(3).y - barSize/2) > 0:
-      player.transform = player.transform * translate3d(0'f, -1'f * dt, 0'f)
+      player.transform = player.transform * translate(0'f, -1'f * dt, 0'f)
 
     # bounce level
     if ball.transform.col(3).x + ballSize/2 > width: ballVelocity[0] = -ballVelocity[0]
     if ball.transform.col(3).y - ballSize/2 <= 0: ballVelocity[1] = -ballVelocity[1]
     if ball.transform.col(3).y + ballSize/2 > height: ballVelocity[1] = -ballVelocity[1]
 
-    ball.transform = ball.transform * translate3d(ballVelocity[0] * dt, ballVelocity[1] * dt, 0'f32)
+    ball.transform = ball.transform * translate(ballVelocity[0] * dt, ballVelocity[1] * dt, 0'f32)
 
     # loose
     if ball.transform.col(3).x - ballSize/2 <= 0:
-      ball.transform = scale3d(ballSize, ballSize, 1'f) * translate3d(30'f, 30'f, 0'f)
+      ball.transform = scale(ballSize, ballSize, 1'f) * translate(30'f, 30'f, 0'f)
       ballVelocity = newVec2f(1, 1).normalized * ballSpeed
 
     # bar