Mercurial > games > semicongine
changeset 366:857cd931d24b
add: function-based animations, preparing-refactring for better material system, hashable dynamic arrays
author | Sam <sam@basx.dev> |
---|---|
date | Thu, 12 Oct 2023 14:55:28 +0700 |
parents | a6bcee717532 |
children | 7ef01f1841b3 |
files | config.nims src/semicongine.nim src/semicongine/animation.nim src/semicongine/core/buildconfig.nim src/semicongine/core/dynamic_arrays.nim src/semicongine/core/gpu_types.nim src/semicongine/core/imagetypes.nim src/semicongine/engine.nim src/semicongine/mesh.nim src/semicongine/renderer.nim src/semicongine/resources/mesh.nim src/semicongine/text.nim src/semicongine/vulkan/renderpass.nim |
diffstat | 13 files changed, 142 insertions(+), 91 deletions(-) [+] |
line wrap: on
line diff
--- a/config.nims Wed Oct 04 22:02:23 2023 +0700 +++ b/config.nims Thu Oct 12 14:55:28 2023 +0700 @@ -14,6 +14,7 @@ task build, "build": switch("d", "BUNDLETYPE=" & BUNDLETYPE) switch("d", "RESOURCEROOT=" & RESOURCEROOT) + switch("d", "nimPreviewHashRef") switch("mm", "orc") switch("experimental", "strictEffects") switch("threads", "on")
--- a/src/semicongine.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine.nim Thu Oct 12 14:55:28 2023 +0700 @@ -10,7 +10,9 @@ import semicongine/collision import semicongine/scene import semicongine/events +import semicongine/material import semicongine/mesh +import semicongine/noise import semicongine/renderer import semicongine/resources import semicongine/settings @@ -24,7 +26,9 @@ export collision export scene export events +export material export mesh +export noise export renderer export resources export settings
--- a/src/semicongine/animation.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/animation.nim Thu Oct 12 14:55:28 2023 +0700 @@ -1,7 +1,7 @@ +import std/sugar import std/tables import std/math import std/sequtils -import std/strformat import std/algorithm import ./core/matrix @@ -17,7 +17,7 @@ Expo Sine Circ - AnimationTime = 0'f32 .. 1'f32 + AnimationTime* = 0'f32 .. 1'f32 Direction* = enum Forward Backward @@ -28,7 +28,7 @@ easeIn: Ease easeOut: Ease Animation*[T] = object - keyframes*: seq[Keyframe[T]] + animationFunction: (t: AnimationTime) -> T duration: float32 direction: Direction iterations: int @@ -50,9 +50,6 @@ func easeSine(x: float32): float32 = 1'f32 - cos((x * PI) / 2'f32) func easeCirc(x: float32): float32 = 1'f32 - sqrt(1'f32 - pow(x, 2'f32)) -func `$`*(animation: Animation): string = - &"{animation.keyframes.len} keyframes, {animation.duration}s" - const EASEFUNC_MAP = { None: easeConst, Linear: easeLinear, @@ -96,44 +93,58 @@ assert kf.timestamp > last, "Succeding keyframes must have increasing timestamps" last = kf.timestamp + let theKeyframes = keyframes.toSeq + + proc animationFunc(t: AnimationTime): T = + var i = 0 + while i < theKeyframes.len - 1: + if theKeyframes[i].timestamp > t: + break + inc i + + let + keyFrameDist = theKeyframes[i].timestamp - theKeyframes[i - 1].timestamp + timestampDist = t - theKeyframes[i - 1].timestamp + x = timestampDist / keyFrameDist + + let value = theKeyframes[i - 1].interpol(x) + return theKeyframes[i].value * value + theKeyframes[i - 1].value * (1 - value) + Animation[T]( - keyframes: keyframes.toSeq, + animationFunction: animationFunc, duration: duration, direction: direction, iterations: iterations ) -func valueAt[T](animation: Animation[T], timestamp: AnimationTime): T = - var i = 0 - while i < animation.keyframes.len - 1: - if animation.keyframes[i].timestamp > timestamp: - break - inc i - - let - keyFrameDist = animation.keyframes[i].timestamp - animation.keyframes[i - 1].timestamp - timestampDist = timestamp - animation.keyframes[i - 1].timestamp - x = timestampDist / keyFrameDist - - let newX = animation.keyframes[i - 1].interpol(x) - return animation.keyframes[i].value * newX + animation.keyframes[i - 1].value * (1 - newX) +func newAnimation*[T](fun: (t: AnimationTime) -> T, duration: float32, direction=Forward, iterations=1): Animation[T] = + Animation[T]( + animationFunction: fun, + duration: duration, + direction: direction, + iterations: iterations + ) func resetPlayer*(player: var AnimationPlayer) = player.currentTime = 0 player.currentDirection = if player.animation.direction == Backward: -1 else : 1 player.currentIteration = player.animation.iterations + func newAnimationPlayer*[T](animation: Animation[T]): AnimationPlayer[T] = - result = AnimationPlayer[T]( animation: animation, playing: false,) + result = AnimationPlayer[T](animation: animation, playing: false) result.resetPlayer() +func newAnimationPlayer*[T](value: T = default(T)): AnimationPlayer[T] = + newAnimationPlayer[T](newAnimation[T]((t: AnimationTime) => value, 0)) + func start*(player: var AnimationPlayer) = player.playing = true func stop*(player: var AnimationPlayer) = player.playing = false -func advance*[T](player: var AnimationPlayer[T], dt: float32): T = +proc advance*[T](player: var AnimationPlayer[T], dt: float32): T = # TODO: check this function, not 100% correct I think if player.playing: player.currentTime += float32(player.currentDirection) * dt @@ -152,5 +163,5 @@ player.currentDirection = -player.currentDirection player.currentTime += float32(player.currentDirection) * dt * 2'f32 - player.currentValue = valueAt(player.animation, (abs(player.currentTime) / player.animation.duration) mod high(AnimationTime)) + player.currentValue = player.animation.animationFunction((abs(player.currentTime) / player.animation.duration) mod high(AnimationTime)) return player.currentValue
--- a/src/semicongine/core/buildconfig.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/core/buildconfig.nim Thu Oct 12 14:55:28 2023 +0700 @@ -15,10 +15,12 @@ # checks required build options: static: assert compileOption("threads"), ENGINENAME & " requires --threads=on" + assert defined(nimPreviewHashRef), ENGINENAME & " requires -d:nimPreviewHashRef" if defined(release): assert compileOption("app", "gui"), ENGINENAME & " requires --app=gui for release builds" + if defined(linux): assert defined(VK_USE_PLATFORM_XLIB_KHR), ENGINENAME & " requires --d:VK_USE_PLATFORM_XLIB_KHR for linux builds" elif defined(windows):
--- a/src/semicongine/core/dynamic_arrays.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/core/dynamic_arrays.nim Thu Oct 12 14:55:28 2023 +0700 @@ -1,3 +1,5 @@ +import std/hashes + import ./gpu_types import ./vector import ./matrix @@ -50,11 +52,57 @@ of Mat43F64: mat43f64: ref seq[TMat43[float64]] of Mat4F32: mat4f32: ref seq[TMat4[float32]] of Mat4F64: mat4f64: ref seq[TMat4[float64]] - of Sampler2D: texture: ref seq[Texture] + of TextureType: texture: ref seq[Texture] func size*(value: DataList): int = value.theType.size * value.len +func hash*(value: DataList): Hash = + case value.theType + of Float32: hash(value.float32) + of Float64: hash(value.float64) + of Int8: hash(value.int8) + of Int16: hash(value.int16) + of Int32: hash(value.int32) + of Int64: hash(value.int64) + of UInt8: hash(value.uint8) + of UInt16: hash(value.uint16) + of UInt32: hash(value.uint32) + of UInt64: hash(value.uint64) + of Vec2I32: hash(value.vec2i32) + of Vec2I64: hash(value.vec2i64) + of Vec3I32: hash(value.vec3i32) + of Vec3I64: hash(value.vec3i64) + of Vec4I32: hash(value.vec4i32) + of Vec4I64: hash(value.vec4i64) + of Vec2U32: hash(value.vec2u32) + of Vec2U64: hash(value.vec2u64) + of Vec3U32: hash(value.vec3u32) + of Vec3U64: hash(value.vec3u64) + of Vec4U32: hash(value.vec4u32) + of Vec4U64: hash(value.vec4u64) + of Vec2F32: hash(value.vec2f32) + of Vec2F64: hash(value.vec2f64) + of Vec3F32: hash(value.vec3f32) + of Vec3F64: hash(value.vec3f64) + of Vec4F32: hash(value.vec4f32) + of Vec4F64: hash(value.vec4f64) + of Mat2F32: hash(value.mat2f32) + of Mat2F64: hash(value.mat2f64) + of Mat23F32: hash(value.mat23f32) + of Mat23F64: hash(value.mat23f64) + of Mat32F32: hash(value.mat32f32) + of Mat32F64: hash(value.mat32f64) + of Mat3F32: hash(value.mat3f32) + of Mat3F64: hash(value.mat3f64) + of Mat34F32: hash(value.mat34f32) + of Mat34F64: hash(value.mat34f64) + of Mat43F32: hash(value.mat43f32) + of Mat43F64: hash(value.mat43f64) + of Mat4F32: hash(value.mat4f32) + of Mat4F64: hash(value.mat4f64) + of TextureType: hash(value.texture) + func `==`*(a, b: DataList): bool = if a.theType != b.theType: return false @@ -101,7 +149,7 @@ of Mat43F64: return a.mat43f64 == b.mat43f64 of Mat4F32: return a.mat4f32 == b.mat4f32 of Mat4F64: return a.mat4f64 == b.mat4f64 - of Sampler2D: a.texture == b.texture + of TextureType: a.texture == b.texture proc setValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) = value.setLen(data.len) @@ -201,7 +249,7 @@ of Mat43F64: result.mat43f64 = new seq[TMat43[float64]] of Mat4F32: result.mat4f32 = new seq[TMat4[float32]] of Mat4F64: result.mat4f64 = new seq[TMat4[float64]] - of Sampler2D: result.texture = new seq[Texture] + of TextureType: result.texture = new seq[Texture] proc newDataList*[T: GPUType](len=0): DataList = result = newDataList(getDataType[T]()) @@ -367,7 +415,7 @@ of Mat43F64: result[0] = value.mat43f64[].toCPointer of Mat4F32: result[0] = value.mat4f32[].toCPointer of Mat4F64: result[0] = value.mat4f64[].toCPointer - of Sampler2D: result[0] = nil + of TextureType: result[0] = nil proc setLen*(value: var DataList, len: int) = value.len = len @@ -414,7 +462,7 @@ of Mat43F64: value.mat43f64[].setLen(len) of Mat4F32: value.mat4f32[].setLen(len) of Mat4F64: value.mat4f64[].setLen(len) - of Sampler2D: discard + of TextureType: discard proc appendValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) = value.len += data.len @@ -515,7 +563,7 @@ of Mat43F64: value.mat43f64[].add data.mat43f64[] of Mat4F32: value.mat4f32[].add data.mat4f32[] of Mat4F64: value.mat4f64[].add data.mat4f64[] - of Sampler2D: value.texture[].add data.texture[] + of TextureType: value.texture[].add data.texture[] proc setValue*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) = when T is float32: value.float32[] = data @@ -667,7 +715,7 @@ of Mat43F64: a.mat43f64[i] = b.mat43f64[j] of Mat4F32: a.mat4f32[i] = b.mat4f32[j] of Mat4F64: a.mat4f64[i] = b.mat4f64[j] - of Sampler2D: a.texture[i] = b.texture[j] + of TextureType: a.texture[i] = b.texture[j] proc copy*(datalist: DataList): DataList = result = newDataList(datalist.theType) @@ -717,4 +765,4 @@ of Mat43F64: $list.mat43f64[] of Mat4F32: $list.mat4f32[] of Mat4F64: $list.mat4f64[] - of Sampler2D: $list.texture[] + of TextureType: $list.texture[]
--- a/src/semicongine/core/gpu_types.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/core/gpu_types.nim Thu Oct 12 14:55:28 2023 +0700 @@ -51,7 +51,7 @@ Mat43F64 Mat4F32 Mat4F64 - Sampler2D + TextureType MemoryPerformanceHint* = enum PreferFastRead, PreferFastWrite ShaderAttribute* = object @@ -123,7 +123,7 @@ of Mat43F64: 92 of Mat4F32: 64 of Mat4F64: 128 - of Sampler2D: 0 + of TextureType: 0 func size*(attribute: ShaderAttribute, perDescriptor=false): int = if perDescriptor: @@ -187,7 +187,7 @@ elif T is TMat43[float64]: Mat43F64 elif T is TMat4[float32]: Mat4F32 elif T is TMat4[float64]: Mat4F64 - elif T is Texture: Sampler2D + elif T is Texture: TextureType else: static: raise newException(Exception, &"Unsupported data type for GPU data: {name(T)}" ) @@ -309,7 +309,7 @@ of Mat43F64: 2 of Mat4F32: 1 of Mat4F64: 2 - of Sampler2D: 1 + of TextureType: 1 func glslType*(theType: DataType): string = # todo: likely not correct as we would need to enable some @@ -353,7 +353,7 @@ of Mat43F64: "dmat43" of Mat4F32: "mat4" of Mat4F64: "dmat4" - of Sampler2D: "sampler2D" + of TextureType: "sampler2D" func glslInput*(group: openArray[ShaderAttribute]): seq[string] = if group.len == 0:
--- a/src/semicongine/core/imagetypes.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/core/imagetypes.nim Thu Oct 12 14:55:28 2023 +0700 @@ -1,4 +1,5 @@ import ./vulkanapi +import ./vector type Pixel* = array[4, uint8] @@ -18,6 +19,9 @@ image*: Image sampler*: Sampler +converter toRGBA*(p: Pixel): Vec4f = + newVec4f(float32(p[0]) / 255'f32, float32(p[1]) / 255'f32, float32(p[2]) / 255'f32, float32(p[3]) / 255'f32) + proc `[]`*(image: Image, x, y: int): Pixel = assert x < image.width assert y < image.height
--- a/src/semicongine/engine.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/engine.nim Thu Oct 12 14:55:28 2023 +0700 @@ -1,4 +1,3 @@ -import std/tables import std/options import std/logging import std/os
--- a/src/semicongine/mesh.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/mesh.nim Thu Oct 12 14:55:28 2023 +0700 @@ -9,8 +9,9 @@ import ./core import ./collision +import ./material -var instanceCounter = 0 +var instanceCounter* = 0 type MeshIndexType* = enum @@ -26,7 +27,7 @@ of Tiny: tinyIndices*: seq[array[3, uint8]] of Small: smallIndices*: seq[array[3, uint16]] of Big: bigIndices*: seq[array[3, uint32]] - materials*: seq[Material] + materials*: seq[MaterialData] transform*: Mat4 = Unit4 instanceTransforms*: seq[Mat4] applyMeshTransformToInstances*: bool = true # if true, the transform attribute for the shader will apply the instance transform AND the mesh transform, to each instance @@ -36,15 +37,6 @@ instanceData: Table[string, DataList] dirtyAttributes: seq[string] Mesh* = ref MeshObject - Material* = object - name*: string - constants*: Table[string, DataList] - textures*: Table[string, Texture] - index*: uint16 # optional, may be used to index into uniform arrays in shader - -let DEFAULT_MATERIAL* = Material( - name: "default material" -) func instanceCount*(mesh: MeshObject): int = mesh.instanceTransforms.len @@ -66,15 +58,6 @@ func `$`*(mesh: Mesh): string = $mesh[] -proc `$`*(material: Material): string = - var constants: seq[string] - for key, value in material.constants.pairs: - constants.add &"{key}: {value}" - var textures: seq[string] - for key in material.textures.keys: - textures.add &"{key}" - return &"""{material.name} | Values: {constants.join(", ")} | Textures: {textures.join(", ")}""" - func vertexAttributes*(mesh: MeshObject): seq[string] = mesh.vertexData.keys.toSeq @@ -84,9 +67,6 @@ func attributes*(mesh: MeshObject): seq[string] = mesh.vertexAttributes & mesh.instanceAttributes -func hash*(material: Material): Hash = - hash(material.name) - func hash*(mesh: Mesh): Hash = hash(cast[ptr MeshObject](mesh)) @@ -133,7 +113,7 @@ uvs: openArray[Vec2f]=[], transform: Mat4=Unit4F32, instanceTransforms: openArray[Mat4]=[Unit4F32], - material: Material=DEFAULT_MATERIAL, + material: MaterialData=DEFAULT_MATERIAL, autoResize=true, name: string="" ): Mesh = @@ -189,7 +169,7 @@ uvs: openArray[Vec2f]=[], transform: Mat4=Unit4F32, instanceTransforms: openArray[Mat4]=[Unit4F32], - material: Material=DEFAULT_MATERIAL, + material: MaterialData=DEFAULT_MATERIAL, name: string="", ): Mesh = newMesh(
--- a/src/semicongine/renderer.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/renderer.nim Thu Oct 12 14:55:28 2023 +0700 @@ -19,6 +19,7 @@ import ./scene import ./mesh +import ./material const TRANSFORMATTRIBUTE = "transform" const VERTEX_ATTRIB_ALIGNMENT = 4 # used for buffer alignment @@ -34,7 +35,7 @@ vertexBufferOffsets*: Table[(Mesh, string), int] descriptorPools*: Table[VkPipeline, DescriptorPool] descriptorSets*: Table[VkPipeline, seq[DescriptorSet]] - materials: seq[Material] + materials: seq[MaterialData] Renderer* = object device: Device surfaceFormat: VkSurfaceFormatKHR @@ -78,14 +79,14 @@ if scene.usesMaterial(materialName): result.add pipeline.samplers -func materialCompatibleWithPipeline(scene: Scene, material: Material, pipeline: Pipeline): (bool, string) = +func materialCompatibleWithPipeline(scene: Scene, material: MaterialData, pipeline: Pipeline): (bool, string) = for uniform in pipeline.uniforms: if scene.shaderGlobals.contains(uniform.name): if scene.shaderGlobals[uniform.name].theType != uniform.theType: return (true, &"shader uniform needs type {uniform.theType} but scene global is of type {scene.shaderGlobals[uniform.name].theType}") else: var foundMatch = true - for name, constant in material.constants.pairs: + for name, constant in material.values.pairs: if name == uniform.name and constant.theType == uniform.theType: foundMatch = true break @@ -162,7 +163,7 @@ if not scenedata.materials.contains(material): scenedata.materials.add material for textureName, texture in material.textures.pairs: - if scene.shaderGlobals.contains(textureName) and scene.shaderGlobals[textureName].theType == Sampler2D: + if scene.shaderGlobals.contains(textureName) and scene.shaderGlobals[textureName].theType == TextureType: warn &"Ignoring material texture '{textureName}' as scene-global textures with the same name have been defined" else: if not scenedata.textures.hasKey(textureName): @@ -170,7 +171,7 @@ scenedata.textures[textureName].add renderer.device.uploadTexture(texture) for name, value in scene.shaderGlobals.pairs: - if value.theType == Sampler2D: + if value.theType == TextureType: assert not scenedata.textures.contains(name) # should be handled by the above code scenedata.textures[name] = @[] for texture in getValues[Texture](value)[]: @@ -382,7 +383,7 @@ foundValue = true else: for mat in renderer.scenedata[scene].materials: - for name, materialConstant in mat.constants.pairs: + for name, materialConstant in mat.values.pairs: if uniform.name == name: value = materialConstant foundValue = true
--- a/src/semicongine/resources/mesh.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/resources/mesh.nim Thu Oct 12 14:55:28 2023 +0700 @@ -7,6 +7,7 @@ import std/streams import ../mesh +import ../material import ../core import ./image @@ -149,62 +150,62 @@ result.sampler.wrapModeT = SAMPLER_WRAP_MODE_MAP[sampler["wrapS"].getInt()] -proc loadMaterial(root: JsonNode, materialNode: JsonNode, mainBuffer: seq[uint8], materialIndex: uint16): Material = - result = Material(name: materialNode["name"].getStr(), index: materialIndex) +proc loadMaterial(root: JsonNode, materialNode: JsonNode, mainBuffer: seq[uint8], materialIndex: uint16): MaterialData = + result = MaterialData(name: materialNode["name"].getStr(), index: materialIndex) let pbr = materialNode["pbrMetallicRoughness"] # color - result.constants["baseColorFactor"] = newDataList(thetype=Vec4F32) + result.values["baseColorFactor"] = newDataList(thetype=Vec4F32) if pbr.hasKey("baseColorFactor"): - setValue(result.constants["baseColorFactor"], @[newVec4f( + setValue(result.values["baseColorFactor"], @[newVec4f( pbr["baseColorFactor"][0].getFloat(), pbr["baseColorFactor"][1].getFloat(), pbr["baseColorFactor"][2].getFloat(), pbr["baseColorFactor"][3].getFloat(), )]) else: - setValue(result.constants["baseColorFactor"], @[newVec4f(1, 1, 1, 1)]) + setValue(result.values["baseColorFactor"], @[newVec4f(1, 1, 1, 1)]) - # pbr material constants + # pbr material values for factor in ["metallicFactor", "roughnessFactor"]: - result.constants[factor] = newDataList(thetype=Float32) + result.values[factor] = newDataList(thetype=Float32) if pbr.hasKey(factor): - setValue(result.constants[factor], @[float32(pbr[factor].getFloat())]) + setValue(result.values[factor], @[float32(pbr[factor].getFloat())]) else: - setValue(result.constants[factor], @[0.5'f32]) + setValue(result.values[factor], @[0.5'f32]) # pbr material textures for texture in ["baseColorTexture", "metallicRoughnessTexture"]: if pbr.hasKey(texture): result.textures[texture] = loadTexture(root, pbr[texture]["index"].getInt(), mainBuffer) - result.constants[texture & "Index"] = newDataList(thetype=UInt8) - setValue(result.constants[texture & "Index"], @[pbr[texture].getOrDefault("texCoord").getInt(0).uint8]) + result.values[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.values[texture & "Index"], @[pbr[texture].getOrDefault("texCoord").getInt(0).uint8]) else: result.textures[texture] = EMPTY_TEXTURE - result.constants[texture & "Index"] = newDataList(thetype=UInt8) - setValue(result.constants[texture & "Index"], @[0'u8]) + result.values[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.values[texture & "Index"], @[0'u8]) # generic material textures for texture in ["normalTexture", "occlusionTexture", "emissiveTexture"]: if materialNode.hasKey(texture): result.textures[texture] = loadTexture(root, materialNode[texture]["index"].getInt(), mainBuffer) - result.constants[texture & "Index"] = newDataList(thetype=UInt8) - setValue(result.constants[texture & "Index"], @[materialNode[texture].getOrDefault("texCoord").getInt(0).uint8]) + result.values[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.values[texture & "Index"], @[materialNode[texture].getOrDefault("texCoord").getInt(0).uint8]) else: result.textures[texture] = EMPTY_TEXTURE - result.constants[texture & "Index"] = newDataList(thetype=UInt8) - setValue(result.constants[texture & "Index"], @[0'u8]) + result.values[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.values[texture & "Index"], @[0'u8]) # emissiv color - result.constants["emissiveFactor"] = newDataList(thetype=Vec3F32) + result.values["emissiveFactor"] = newDataList(thetype=Vec3F32) if materialNode.hasKey("emissiveFactor"): - setValue(result.constants["emissiveFactor"], @[newVec3f( + setValue(result.values["emissiveFactor"], @[newVec3f( materialNode["emissiveFactor"][0].getFloat(), materialNode["emissiveFactor"][1].getFloat(), materialNode["emissiveFactor"][2].getFloat(), )]) else: - setValue(result.constants["emissiveFactor"], @[newVec3f(1'f32, 1'f32, 1'f32)]) + setValue(result.values["emissiveFactor"], @[newVec3f(1'f32, 1'f32, 1'f32)]) proc addPrimitive(mesh: Mesh, root: JsonNode, primitiveNode: JsonNode, mainBuffer: seq[uint8]) = if primitiveNode.hasKey("mode") and primitiveNode["mode"].getInt() != 4:
--- a/src/semicongine/text.nim Wed Oct 04 22:02:23 2023 +0700 +++ b/src/semicongine/text.nim Thu Oct 12 14:55:28 2023 +0700 @@ -4,6 +4,7 @@ import ./core import ./mesh +import ./material import ./vulkan/shader const SHADER_ATTRIB_PREFIX = "semicon_text_" @@ -109,7 +110,7 @@ inc instanceCounter result.mesh[].renameAttribute("position", POSITION_ATTRIB) result.mesh[].renameAttribute("uv", UV_ATTRIB) - result.mesh.materials = @[Material( + result.mesh.materials = @[MaterialData( name: TEXT_MATERIAL, textures: {"fontAtlas": font.fontAtlas}.toTable, )]