changeset 800:668eed376029

add: nice mesh API, fix: copying of whole scenedata all the time
author Sam <sam@basx.dev>
date Thu, 07 Sep 2023 23:28:36 +0700
parents 7ce4e28c71dd
children 73de86a9ec0a
files examples/E04_input.nim src/semicongine/mesh.nim src/semicongine/renderer.nim src/semicongine/text.nim
diffstat 4 files changed, 46 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/examples/E04_input.nim	Wed Sep 06 00:03:51 2023 +0700
+++ b/examples/E04_input.nim	Thu Sep 07 23:28:36 2023 +0700
@@ -188,16 +188,16 @@
     for (index, key) in enumerate(keyIndices):
       if myengine.keyWasPressed(key):
         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)
+        keyboardmesh["color", baseIndex + 0] = activeColor
+        keyboardmesh["color", baseIndex + 1] = activeColor
+        keyboardmesh["color", baseIndex + 2] = activeColor
+        keyboardmesh["color", baseIndex + 3] = activeColor
       if myengine.keyWasReleased(key):
         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)
+        keyboardmesh["color", baseIndex + 0] = baseColor
+        keyboardmesh["color", baseIndex + 1] = baseColor
+        keyboardmesh["color", baseIndex + 2] = baseColor
+        keyboardmesh["color", baseIndex + 3] = baseColor
 
     myengine.renderScene(scene)
 
--- a/src/semicongine/mesh.nim	Wed Sep 06 00:03:51 2023 +0700
+++ b/src/semicongine/mesh.nim	Thu Sep 07 23:28:36 2023 +0700
@@ -227,7 +227,7 @@
   else:
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
-proc getAttribute*[T: GPUType|int|uint|float](mesh: MeshObject, attribute: string): seq[T] =
+proc getAttribute[T: GPUType|int|uint|float](mesh: MeshObject, attribute: string): seq[T] =
   if mesh.vertexData.contains(attribute):
     getValues[T](mesh.vertexData[attribute])
   elif mesh.instanceData.contains(attribute):
@@ -235,7 +235,12 @@
   else:
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
-proc updateAttributeData*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, data: seq[T]) =
+template `[]`*(mesh: MeshObject, attribute: string, t: typedesc): seq[t] =
+  getAttribute[t](mesh, attribute)
+template `[]`*(mesh: Mesh, attribute: string, t: typedesc): seq[t] =
+  getAttribute[t](mesh[], attribute)
+
+proc updateAttributeData[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, data: seq[T]) =
   if mesh.vertexData.contains(attribute):
     assert data.len == mesh.vertexCount
     setValues(mesh.vertexData[attribute], data)
@@ -247,7 +252,7 @@
   if not mesh.dirtyAttributes.contains(attribute):
     mesh.dirtyAttributes.add attribute
 
-proc updateAttributeData*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, i: int, value: T) =
+proc updateAttributeData[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, i: int, value: T) =
   if mesh.vertexData.contains(attribute):
     assert i < mesh.vertexData[attribute].len
     setValue(mesh.vertexData[attribute], i, value)
@@ -259,6 +264,21 @@
   if not mesh.dirtyAttributes.contains(attribute):
     mesh.dirtyAttributes.add attribute
 
+proc `[]=`*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, data: seq[T]) =
+  updateAttributeData[T](mesh, attribute, data)
+proc `[]=`*[T: GPUType|int|uint|float](mesh: Mesh, attribute: string, data: seq[T]) =
+  updateAttributeData[t](mesh[], attribute, data)
+
+proc `[]=`*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, value: T) =
+  updateAttributeData[T](mesh, attribute, newSeqWith(mesh.vertexCount, value))
+proc `[]=`*[T: GPUType|int|uint|float](mesh: Mesh, attribute: string, value: T) =
+  updateAttributeData[T](mesh[], attribute, newSeqWith(mesh.vertexCount, value))
+
+proc `[]=`*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, i: int, value: T) =
+  updateAttributeData[T](mesh, attribute, i, value)
+proc `[]=`*[T: GPUType|int|uint|float](mesh: Mesh, attribute: string, i: int, value: T) =
+  updateAttributeData[T](mesh[], attribute, i, value)
+
 proc appendAttributeData*[T: GPUType|int|uint|float](mesh: var MeshObject, attribute: string, data: seq[T]) =
   if mesh.vertexData.contains(attribute):
     appendValues(mesh.vertexData[attribute], data)
@@ -292,7 +312,7 @@
 proc updateInstanceTransforms*(mesh: var MeshObject, attribute: string) =
   let currentTransforms = mesh.instanceTransforms.mapIt(mesh.transform * it)
   if currentTransforms != mesh.transformCache:
-    mesh.updateAttributeData(attribute, currentTransforms)
+    mesh[attribute] = currentTransforms
     mesh.transformCache = currentTransforms
 
 func dirtyAttributes*(mesh: MeshObject): seq[string] =
@@ -312,7 +332,7 @@
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
 func getCollisionPoints*(mesh: MeshObject, positionAttribute="position"): seq[Vec3f] =
-  for p in getAttribute[Vec3f](mesh, positionAttribute):
+  for p in mesh[positionAttribute, Vec3f]:
     result.add mesh.transform * p
 
 # GENERATORS ============================================================================
--- a/src/semicongine/renderer.nim	Wed Sep 06 00:03:51 2023 +0700
+++ b/src/semicongine/renderer.nim	Thu Sep 07 23:28:36 2023 +0700
@@ -23,7 +23,7 @@
 const VERTEX_ATTRIB_ALIGNMENT = 4 # used for buffer alignment
 
 type
-  SceneData = object
+  SceneData = ref object
     drawables*: seq[tuple[drawable: Drawable, mesh: Mesh]]
     vertexBuffers*: Table[MemoryPerformanceHint, Buffer]
     indexBuffer*: Buffer
--- a/src/semicongine/text.nim	Wed Sep 06 00:03:51 2023 +0700
+++ b/src/semicongine/text.nim	Thu Sep 07 23:28:36 2023 +0700
@@ -56,24 +56,24 @@
         top = glyph.topOffset
         bottom = glyph.topOffset + glyph.dimension.y
 
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 0, newVec3f(left - centerX, bottom + centerY))
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 1, newVec3f(left - centerX, top + centerY))
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 2, newVec3f(right - centerX, top + centerY))
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 3, newVec3f(right - centerX, bottom + centerY))
+      textbox.mesh["position", vertexOffset + 0] = newVec3f(left - centerX, bottom + centerY)
+      textbox.mesh["position", vertexOffset + 1] = newVec3f(left - centerX, top + centerY)
+      textbox.mesh["position", vertexOffset + 2] = newVec3f(right - centerX, top + centerY)
+      textbox.mesh["position", vertexOffset + 3] = newVec3f(right - centerX, bottom + centerY)
 
-      textbox.mesh[].updateAttributeData("uv", vertexOffset + 0, glyph.uvs[0])
-      textbox.mesh[].updateAttributeData("uv", vertexOffset + 1, glyph.uvs[1])
-      textbox.mesh[].updateAttributeData("uv", vertexOffset + 2, glyph.uvs[2])
-      textbox.mesh[].updateAttributeData("uv", vertexOffset + 3, glyph.uvs[3])
+      textbox.mesh["uv", vertexOffset + 0] = glyph.uvs[0]
+      textbox.mesh["uv", vertexOffset + 1] = glyph.uvs[1]
+      textbox.mesh["uv", vertexOffset + 2] = glyph.uvs[2]
+      textbox.mesh["uv", vertexOffset + 3] = glyph.uvs[3]
 
       offsetX += glyph.advance
       if i < textbox.text.len - 1:
         offsetX += textbox.font.kerning[(textbox.text[i], textbox.text[i + 1])]
     else:
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 0, newVec3f())
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 1, newVec3f())
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 2, newVec3f())
-      textbox.mesh[].updateAttributeData("position", vertexOffset + 3, newVec3f())
+      textbox.mesh["position", vertexOffset + 0] = newVec3f()
+      textbox.mesh["position", vertexOffset + 1] = newVec3f()
+      textbox.mesh["position", vertexOffset + 2] = newVec3f()
+      textbox.mesh["position", vertexOffset + 3] = newVec3f()
 
 
 func text*(textbox: Textbox): seq[Rune] =