# HG changeset patch # User Sam # Date 1704120100 -25200 # Node ID 7d926cc81620aab40314298d59a82a9ea137f0c8 # Parent c81c6e7047e3cfe55cd07eb7b9a935c370f42915 some fixes + some intermedite state diff -r c81c6e7047e3 -r 7d926cc81620 semicongine/material.nim --- a/semicongine/material.nim Mon Jan 01 17:40:29 2024 +0700 +++ b/semicongine/material.nim Mon Jan 01 21:41:40 2024 +0700 @@ -15,7 +15,13 @@ MaterialData* = object theType*: MaterialType name*: string - attributes*: Table[string, DataList] + attributes: Table[string, DataList] + +func hasMatchingAttribute*(materialType: MaterialType, attr: ShaderAttribute): bool = + return materialType.attributes.contains(attr.name) and materialType.attributes[attr.name] == attr.theType + +func hasMatchingAttribute*(material: MaterialData, attr: ShaderAttribute): bool = + return material.attributes.contains(attr.name) and material.attributes[attr.name].theType == attr.theType proc hash*(materialType: MaterialType): Hash = return hash(materialType.name) @@ -29,6 +35,9 @@ proc `==`*(a, b: MaterialData): bool = return a.name == b.name +proc get*(material: MaterialData, attributeName: string): DataList = + material.attributes[attributeName] + let EMPTY_MATERIAL* = MaterialType( name: "empty material", vertexAttributes: {"position": Vec3F32}.toTable, diff -r c81c6e7047e3 -r 7d926cc81620 semicongine/renderer.nim --- a/semicongine/renderer.nim Mon Jan 01 17:40:29 2024 +0700 +++ b/semicongine/renderer.nim Mon Jan 01 21:41:40 2024 +0700 @@ -80,24 +80,14 @@ 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, theType in materialType.attributes.pairs: - if name == uniform.name and theType == uniform.theType: - foundMatch = true - break - if not foundMatch: + if not materialType.hasMatchingAttribute(uniform): return (true, &"shader uniform '{uniform.name}' was not found in scene globals or scene materials") for texture in shaderPipeline.samplers: if scene.shaderGlobals.contains(texture.name): if scene.shaderGlobals[texture.name].theType != texture.theType: return (true, &"shader texture '{texture.name}' needs type {texture.theType} but scene global is of type {scene.shaderGlobals[texture.name].theType}") else: - var foundMatch = true - for name in materialType.attributes.keys: - if name == texture.name: - foundMatch = true - break - if not foundMatch: + if not materialType.hasMatchingAttribute(texture): return (true, &"Required texture for shader texture '{texture.name}' was not found in scene materials") return (false, "") @@ -279,17 +269,15 @@ else: var foundTexture = false for material in scene.getMaterials(materialType): - for materialAttribName, value in material.attributes.pairs: - if materialAttribName == texture.name: - if not foundTexture: - foundTexture = true - assert value.theType == TextureType, &"Mesh material has attribute '{materialAttribName}' which is expected to be of type 'Texture' but is of type {value.theType}" - assert value.len == 1, &"Mesh material attribute '{materialAttribName}' has texture-array, but only single textures are allowed" - let textureValue = getValues[Texture](value)[][0] - if not uploadedTextures.contains(textureValue): - uploadedTextures[textureValue] = renderer.device.uploadTexture(textureValue) - scenedata.textures[shaderPipeline.vk][texture.name].add uploadedTextures[textureValue] - break + if material.hasMatchingAttribute(texture): + foundTexture = true + assert value.len == 1, &"Mesh material attribute '{materialAttribName}' has texture-array, but only single textures are allowed" + let textureValue = getValues[Texture](value)[][0] + if not uploadedTextures.contains(textureValue): + uploadedTextures[textureValue] = renderer.device.uploadTexture(textureValue) + scenedata.textures[shaderPipeline.vk][texture.name].add uploadedTextures[textureValue] + + break assert foundTexture, &"No texture found in shaderGlobals or materials for '{texture.name}'" let nTextures = scenedata.textures[shaderPipeline.vk][texture.name].len assert (texture.arrayCount == 0 and nTextures == 1) or texture.arrayCount == nTextures, &"Shader assigned to render '{materialType}' expected {texture.arrayCount} textures for '{texture.name}' but got {nTextures}" @@ -360,6 +348,7 @@ let dirty = scene.dirtyShaderGlobals if not forceAll and dirty.len == 0: + echo "Nothing dirty" return if forceAll: @@ -383,6 +372,7 @@ var offset = 0 # loop over all uniforms of the shader-shaderPipeline for uniform in shaderPipeline.uniforms: + echo "UNIFORM: ", uniform if dirty.contains(uniform.name) or forceAll: # only update if necessary var value: DataList if scene.shaderGlobals.hasKey(uniform.name):