changeset 225:d078b19bf531

fix: a ton of bug after refactoring gpu_data, start to add ideas for materials
author Sam <sam@basx.dev>
date Mon, 15 May 2023 18:24:52 +0700
parents 634c302869d5
children 3cbbf50e9e4c
files src/semicongine/core/gpu_data.nim src/semicongine/core/materials.nim src/semicongine/materials.nim src/semicongine/mesh.nim src/semicongine/resources/mesh.nim
diffstat 5 files changed, 94 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/core/gpu_data.nim	Mon May 15 14:25:04 2023 +0700
+++ b/src/semicongine/core/gpu_data.nim	Mon May 15 18:24:52 2023 +0700
@@ -349,6 +349,58 @@
   elif T is TMat4[float64]: value.mat4f64
   else: {.error: "Virtual datatype has no value" .}
 
+func setValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) =
+  value.len = uint32(data.len)
+  when T is float32: value.float32[] = data
+  elif T is float64: value.float64[] = data
+  elif T is int8: value.int8[] = data
+  elif T is int16: value.int16[] = data
+  elif T is int32: value.int32[] = data
+  elif T is int64: value.int64[] = data
+  elif T is uint8: value.uint8[] = data
+  elif T is uint16: value.uint16[] = data
+  elif T is uint32: value.uint32[] = data
+  elif T is uint64: value.uint64[] = data
+  elif T is int and sizeof(int) == sizeof(int32): value.int32[] = data
+  elif T is int and sizeof(int) == sizeof(int64): value.int64[] = data
+  elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[] = data
+  elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[] = data
+  elif T is float and sizeof(float) == sizeof(float32): value.float32[] = data
+  elif T is float and sizeof(float) == sizeof(float64): value.float64[] = data
+  elif T is TVec2[int32]: value.vec2i32[] = data
+  elif T is TVec2[int64]: value.vec2i64[] = data
+  elif T is TVec3[int32]: value.vec3i32[] = data
+  elif T is TVec3[int64]: value.vec3i64[] = data
+  elif T is TVec4[int32]: value.vec4i32[] = data
+  elif T is TVec4[int64]: value.vec4i64[] = data
+  elif T is TVec2[uint32]: value.vec2u32[] = data
+  elif T is TVec2[uint64]: value.vec2u64[] = data
+  elif T is TVec3[uint32]: value.vec3u32[] = data
+  elif T is TVec3[uint64]: value.vec3u64[] = data
+  elif T is TVec4[uint32]: value.vec4u32[] = data
+  elif T is TVec4[uint64]: value.vec4u64[] = data
+  elif T is TVec2[float32]: value.vec2f32[] = data
+  elif T is TVec2[float64]: value.vec2f64[] = data
+  elif T is TVec3[float32]: value.vec3f32[] = data
+  elif T is TVec3[float64]: value.vec3f64[] = data
+  elif T is TVec4[float32]: value.vec4f32[] = data
+  elif T is TVec4[float64]: value.vec4f64[] = data
+  elif T is TMat2[float32]: value.mat2f32[] = data
+  elif T is TMat2[float64]: value.mat2f64[] = data
+  elif T is TMat23[float32]: value.mat23f32[] = data
+  elif T is TMat23[float64]: value.mat23f64[] = data
+  elif T is TMat32[float32]: value.mat32f32[] = data
+  elif T is TMat32[float64]: value.mat32f64[] = data
+  elif T is TMat3[float32]: value.mat3f32[] = data
+  elif T is TMat3[float64]: value.mat3f64[] = data
+  elif T is TMat34[float32]: value.mat34f32[] = data
+  elif T is TMat34[float64]: value.mat34f64[] = data
+  elif T is TMat43[float32]: value.mat43f32[] = data
+  elif T is TMat43[float64]: value.mat43f64[] = data
+  elif T is TMat4[float32]: value.mat4f32[] = data
+  elif T is TMat4[float64]: value.mat4f64[] = data
+  else: {. error: "Virtual datatype has no values" .}
+
 func newDataList*(thetype: DataType): DataList =
   result = DataList(thetype: thetype)
   case result.thetype
@@ -403,8 +455,7 @@
 
 func newDataList*[T: GPUType](data: seq[T]): DataList =
   result = newDataList(getDataType[T]())
-  result.setValues[T](data)
-
+  setValues[T](result, data)
 
 func getValues*[T: GPUType|int|uint|float](value: DataList): ref seq[T] =
   when T is float32: value.float32
@@ -651,58 +702,6 @@
   elif T is TMat4[float64]: value.mat4f64 = data
   else: {.error: "Virtual datatype has no value" .}
 
-func setValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) =
-  value.len = uint32(data.len)
-  when T is float32: value.float32[] = data
-  elif T is float64: value.float64[] = data
-  elif T is int8: value.int8[] = data
-  elif T is int16: value.int16[] = data
-  elif T is int32: value.int32[] = data
-  elif T is int64: value.int64[] = data
-  elif T is uint8: value.uint8[] = data
-  elif T is uint16: value.uint16[] = data
-  elif T is uint32: value.uint32[] = data
-  elif T is uint64: value.uint64[] = data
-  elif T is int and sizeof(int) == sizeof(int32): value.int32[] = data
-  elif T is int and sizeof(int) == sizeof(int64): value.int64[] = data
-  elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[] = data
-  elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[] = data
-  elif T is float and sizeof(float) == sizeof(float32): value.float32[] = data
-  elif T is float and sizeof(float) == sizeof(float64): value.float64[] = data
-  elif T is TVec2[int32]: value.vec2i32[] = data
-  elif T is TVec2[int64]: value.vec2i64[] = data
-  elif T is TVec3[int32]: value.vec3i32[] = data
-  elif T is TVec3[int64]: value.vec3i64[] = data
-  elif T is TVec4[int32]: value.vec4i32[] = data
-  elif T is TVec4[int64]: value.vec4i64[] = data
-  elif T is TVec2[uint32]: value.vec2u32[] = data
-  elif T is TVec2[uint64]: value.vec2u64[] = data
-  elif T is TVec3[uint32]: value.vec3u32[] = data
-  elif T is TVec3[uint64]: value.vec3u64[] = data
-  elif T is TVec4[uint32]: value.vec4u32[] = data
-  elif T is TVec4[uint64]: value.vec4u64[] = data
-  elif T is TVec2[float32]: value.vec2f32[] = data
-  elif T is TVec2[float64]: value.vec2f64[] = data
-  elif T is TVec3[float32]: value.vec3f32[] = data
-  elif T is TVec3[float64]: value.vec3f64[] = data
-  elif T is TVec4[float32]: value.vec4f32[] = data
-  elif T is TVec4[float64]: value.vec4f64[] = data
-  elif T is TMat2[float32]: value.mat2f32[] = data
-  elif T is TMat2[float64]: value.mat2f64[] = data
-  elif T is TMat23[float32]: value.mat23f32[] = data
-  elif T is TMat23[float64]: value.mat23f64[] = data
-  elif T is TMat32[float32]: value.mat32f32[] = data
-  elif T is TMat32[float64]: value.mat32f64[] = data
-  elif T is TMat3[float32]: value.mat3f32[] = data
-  elif T is TMat3[float64]: value.mat3f64[] = data
-  elif T is TMat34[float32]: value.mat34f32[] = data
-  elif T is TMat34[float64]: value.mat34f64[] = data
-  elif T is TMat43[float32]: value.mat43f32[] = data
-  elif T is TMat43[float64]: value.mat43f64[] = data
-  elif T is TMat4[float32]: value.mat4f32[] = data
-  elif T is TMat4[float64]: value.mat4f64[] = data
-  else: {. error: "Virtual datatype has no values" .}
-
 func appendValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) =
   value.len += data.len
   when T is float32: value.float32[].add data
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/semicongine/core/materials.nim	Mon May 15 18:24:52 2023 +0700
@@ -0,0 +1,9 @@
+import std/tables
+
+import ./imagetypes
+import ./gpu_data
+
+type
+  Material* = object
+    textures: Table[string, Image]
+    constants: Table[string, DataValue]
--- a/src/semicongine/materials.nim	Mon May 15 14:25:04 2023 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-import ./core
-
-type
-  # based on the default material
-  # from glTF
-  PBRMetalicRoughness* = object
-    name: string
-
-    baseColor: Vec4f
-    baseColorTexture: Image
-
-    metalic: float32
-    roughness: float32
-    metalicRoughnessTexture: Image
-
-    normalScale: float32
-    normalTexture: Image
-
-    occlusionStrength: float32
-    occlusionTexture: Image
-
-    emissiveFactor: float32
-    emissiveTexture: Image
--- a/src/semicongine/mesh.nim	Mon May 15 14:25:04 2023 +0700
+++ b/src/semicongine/mesh.nim	Mon May 15 18:24:52 2023 +0700
@@ -38,11 +38,13 @@
     uint32(mesh.data[mesh.data.keys().toSeq[0]].len)
 
 func indicesCount*(mesh: Mesh): uint32 =
-  case mesh.indexType
-  of None: 0'u32
-  of Tiny: uint32(mesh.tinyIndices.len)
-  of Small: uint32(mesh.smallIndices.len)
-  of Big: uint32(mesh.bigIndices.len)
+  (
+    case mesh.indexType
+    of None: 0'u32
+    of Tiny: uint32(mesh.tinyIndices.len)
+    of Small: uint32(mesh.smallIndices.len)
+    of Big: uint32(mesh.bigIndices.len)
+  ) * 3
 
 method `$`*(mesh: Mesh): string =
   &"Mesh, vertexCount: {mesh.vertexCount}, vertexData: {mesh.data.keys().toSeq()}, indexType: {mesh.indexType}"
@@ -56,6 +58,14 @@
     of Small: &"indices: {mesh.smallIndices}"
     of Big: &"indices: {mesh.bigIndices}")
 
+proc setMeshData*[T: GPUType|int|uint|float](mesh: var Mesh, attribute: string, data: seq[T]) =
+  assert not (attribute in mesh.data)
+  mesh.data[attribute] = newDataList(data)
+
+proc setMeshData*(mesh: var Mesh, attribute: string, data: DataList) =
+  assert not (attribute in mesh.data)
+  mesh.data[attribute] = data
+
 func newMesh*(
   positions: openArray[Vec3f],
   indices: openArray[array[3, uint32|int32|uint16|int16|int]],
@@ -67,16 +77,10 @@
   assert colors.len == 0 or colors.len == positions.len
   assert uvs.len == 0 or uvs.len == positions.len
 
-  result = new Mesh
-  result.instanceCount = instanceCount
-  result.data["position"] = DataList(thetype: Vec3F32)
-  setValues(result.data["position"], positions.toSeq)
-  if colors.len > 0:
-    result.data["color"] = DataList(thetype: Vec4F32)
-    setValues(result.data["color"], colors.toSeq)
-  if uvs.len > 0:
-    result.data["uv"] = DataList(thetype: Vec2F32)
-    setValues(result.data["uv"], uvs.toSeq)
+  result = Mesh(instanceCount: instanceCount)
+  setMeshData(result, "position", positions.toSeq)
+  if colors.len > 0: setMeshData(result, "color", colors.toSeq)
+  if uvs.len > 0: setMeshData(result, "uv", uvs.toSeq)
 
   for i in indices:
     assert uint32(i[0]) < result.vertexCount
@@ -151,14 +155,6 @@
   else:
     mesh.data[attribute.name].initData(mesh.vertexCount)
 
-proc setMeshData*[T: GPUType|int|uint|float](mesh: var Mesh, attribute: string, data: seq[T]) =
-  assert not (attribute in mesh.data)
-  mesh.data[attribute] = newDataList[T](data)
-
-proc setMeshData*(mesh: var Mesh, attribute: string, data: DataList) =
-  assert not (attribute in mesh.data)
-  mesh.data[attribute] = data
-
 proc updateMeshData*[T: GPUType|int|uint|float](mesh: var Mesh, attribute: string, data: seq[T]) =
   assert attribute in mesh.data
   mesh.changedAttributes.add attribute
@@ -184,8 +180,7 @@
 proc setInstanceData*[T: GPUType|int|uint|float](mesh: var Mesh, attribute: string, data: seq[T]) =
   assert uint32(data.len) == mesh.instanceCount
   assert not (attribute in mesh.data)
-  mesh.data[attribute] = DataList(thetype: getDataType[T]())
-  setValues(mesh.data[attribute], data)
+  mesh.data[attribute] = newDataList(data)
 
 proc updateInstanceData*[T: GPUType|int|uint|float](mesh: var Mesh, attribute: string, data: seq[T]) =
   assert uint32(data.len) == mesh.instanceCount
@@ -214,56 +209,38 @@
 
 proc transform*[T: GPUType](mesh: var Mesh, attribute: string, transform: Mat4) =
   assert attribute in mesh.data
-  echo "=========", getMeshData[Vec3f](mesh, attribute)[][0 .. 3]
   for v in getValues[T](mesh.data[attribute])[].mitems:
     when T is Vec3f:
       v = (transform * newVec4f(v.x, v.y, v.z)).xyz
     else:
       v = transform * v
-  echo "=========", getMeshData[Vec3f](mesh, attribute)[][0 .. 3]
 
 func rect*(width=1'f32, height=1'f32, color="ffffffff"): Mesh =
-  result = new Mesh
-  result.instanceCount = 1
-  result.data["position"] = DataList(thetype: Vec3F32)
-  result.data["color"] = DataList(thetype: Vec4F32)
-  result.data["uv"] = DataList(thetype: Vec2F32)
-  result.indexType = Small
-  result.smallIndices = @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]]
+  result = Mesh(instanceCount: 1, indexType: Small, smallIndices: @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]])
 
   let
     half_w = width / 2
     half_h = height / 2
+    pos = @[newVec3f(-half_w, -half_h), newVec3f( half_w, -half_h), newVec3f( half_w,  half_h), newVec3f(-half_w,  half_h)]
     c = hexToColorAlpha(color)
-    v = [newVec3f(-half_w, -half_h), newVec3f( half_w, -half_h), newVec3f( half_w,  half_h), newVec3f(-half_w,  half_h)]
 
-  setValues(result.data["position"], v.toSeq)
-  setValues(result.data["color"], @[c, c, c, c])
-  setValues(result.data["uv"], @[newVec2f(0, 0), newVec2f(1, 0), newVec2f(1, 1), newVec2f(0, 1)])
+  setMeshData(result, "position", pos)
+  setMeshData(result, "color", @[c, c, c, c])
+  setMeshData(result, "uv", @[newVec2f(0, 0), newVec2f(1, 0), newVec2f(1, 1), newVec2f(0, 1)])
 
 func tri*(width=1'f32, height=1'f32, color="ffffffff"): Mesh =
-  result = new Mesh
-  # result.vertexCount = 3
-  result.instanceCount = 1
-  result.data["position"] = DataList(thetype: Vec3F32)
-  result.data["color"] = DataList(thetype: Vec4F32)
+  result = Mesh(instanceCount: 1)
   let
     half_w = width / 2
     half_h = height / 2
     colorVec = hexToColorAlpha(color)
-  setValues(result.data["position"], @[
-    newVec3f(0, -half_h), newVec3f( half_w, half_h), newVec3f(-half_w,  half_h),
-  ])
-  setValues(result.data["color"], @[colorVec, colorVec, colorVec])
+  setMeshData(result, "position", @[newVec3f(0, -half_h), newVec3f( half_w, half_h), newVec3f(-half_w,  half_h)])
+  setMeshData(result, "color", @[colorVec, colorVec, colorVec])
 
 func circle*(width=1'f32, height=1'f32, nSegments=12'u16, color="ffffffff"): Mesh =
   assert nSegments >= 3
-  result = new Mesh
-  # result.vertexCount = nSegments + 2
-  result.instanceCount = 1
-  result.indexType = Small
-  result.data["position"] = DataList(thetype: Vec3F32)
-  result.data["color"] = DataList(thetype: Vec4F32)
+  result = Mesh(instanceCount: 1, indexType: Small)
+
   let
     half_w = width / 2
     half_h = height / 2
@@ -277,5 +254,5 @@
     col.add c
     result.smallIndices.add [0'u16, i + 1, i + 2]
 
-  setValues(result.data["position"], pos)
-  setValues(result.data["color"], col)
+  setMeshData(result, "position", pos)
+  setMeshData(result, "color", col)
--- a/src/semicongine/resources/mesh.nim	Mon May 15 14:25:04 2023 +0700
+++ b/src/semicongine/resources/mesh.nim	Mon May 15 18:24:52 2023 +0700
@@ -5,7 +5,6 @@
 import std/strformat
 import std/streams
 
-# from ../entity import Entity, Scene, Component
 import ../entity
 import ../mesh
 import ../core