# HG changeset patch # User Sam # Date 1684149892 -25200 # Node ID d078b19bf53160e59b762f1d264a935dc410d2c7 # Parent 634c302869d5359714f0eb7123039c83efb9024c fix: a ton of bug after refactoring gpu_data, start to add ideas for materials diff -r 634c302869d5 -r d078b19bf531 src/semicongine/core/gpu_data.nim --- 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 diff -r 634c302869d5 -r d078b19bf531 src/semicongine/core/materials.nim --- /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] diff -r 634c302869d5 -r d078b19bf531 src/semicongine/materials.nim --- 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 diff -r 634c302869d5 -r d078b19bf531 src/semicongine/mesh.nim --- 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) diff -r 634c302869d5 -r d078b19bf531 src/semicongine/resources/mesh.nim --- 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