Mercurial > games > semicongine
diff tests/test_gltf.nim @ 1255:2b5ca798f6d6
did: make example town loadable and renderable, yay!
author | sam <sam@basx.dev> |
---|---|
date | Sun, 28 Jul 2024 00:17:34 +0700 |
parents | b0f4c8ccd49a |
children | bfb75c934f4e |
line wrap: on
line diff
--- a/tests/test_gltf.nim Sat Jul 27 20:47:54 2024 +0700 +++ b/tests/test_gltf.nim Sun Jul 28 00:17:34 2024 +0700 @@ -13,53 +13,58 @@ type ObjectData = object transform: Mat4 + materialId: int32 Camera = object viewPerspective: Mat4 Material = object color: Vec4f = NewVec4f(1, 1, 1, 1) - colorTexture: int32 = -1 + # colorTexture: int32 = -1 metallic: float32 = 0 roughness: float32 = 0 - metallicRoughnessTexture: int32 = -1 - - normalTexture: int32 = -1 - occlusionTexture: int32 = -1 + # metallicRoughnessTexture: int32 = -1 + # normalTexture: int32 = -1 + # occlusionTexture: int32 = -1 emissive: Vec4f = NewVec4f(0, 0, 0, 0) - emissiveTexture: int32 = -1 + # emissiveTexture: int32 = -1 MainDescriptors = object - material: GPUValue[Material, UniformBuffer] + materials: array[32, GPUValue[Material, UniformBuffer]] camera: GPUValue[Camera, UniformBufferMapped] Shader = object objectData {.PushConstantAttribute.}: ObjectData position {.VertexAttribute.}: Vec3f color {.VertexAttribute.}: Vec4f - # uv {.VertexAttribute.}: Vec2f + normal {.VertexAttribute.}: Vec3f fragmentColor {.Pass.}: Vec4f - fragmentUv {.Pass.}: Vec2f + fragmentNormal {.Pass.}: Vec3f outColor {.ShaderOutput.}: Vec4f descriptors {.DescriptorSets.}: (MainDescriptors, ) # code vertexCode: string = """ void main() { - fragmentColor = color; - // fragmentUv = uv; - gl_Position = vec4(position, 1) * camera.viewPerspective; + fragmentColor = color * materials[objectData.materialId].color; + fragmentNormal = normal; + gl_Position = vec4(position, 1) * (objectData.transform * camera.viewPerspective); }""" - fragmentCode: string = """void main() { outColor = fragmentColor;}""" + fragmentCode: string = """ +const vec3 lightDir = normalize(vec3(1, -1, 1)); +void main() { + outColor = vec4(fragmentColor.rgb * (1 - abs(dot(fragmentNormal, lightDir))), fragmentColor.a); +}""" Mesh = object position: GPUArray[Vec3f, VertexBuffer] color: GPUArray[Vec4f, VertexBuffer] - uv: GPUArray[Vec2f, VertexBuffer] - DebugMesh = object - position: GPUArray[Vec3f, VertexBuffer] - color: GPUArray[Vec4f, VertexBuffer] + normal: GPUArray[Vec3f, VertexBuffer] + indices: GPUArray[uint32, IndexBuffer] + material: int32 var gltfData = LoadMeshes[Mesh, Material]( "town.glb", MeshAttributeNames( POSITION: "position", COLOR: @["color"], - TEXCOORD: @["uv"], + NORMAL: "normal", + indices: "indices", + material: "material", ), MaterialAttributeNames( baseColorFactor: "color", @@ -80,34 +85,20 @@ ), UniformBufferMapped) ) ) + for i in 0 ..< gltfData.materials.len: + descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) for mesh in mitems(gltfData.meshes): for primitive in mitems(mesh): primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, NewVec4f(1, 1, 1, 1)), VertexBuffer) renderdata.AssignBuffers(primitive[0]) renderdata.AssignBuffers(descriptors) - let O = default(Vec3f) - let Gray = NewVec4f(0.5, 0.5, 0.5, 1) - var gridPos = @[O, X, O, Y, O, Z] - var gridColor = @[R, R, G, G, B, B] - for i in 0 ..< 10: - gridPos.add [NewVec3f(-5, -0.001, i.float32 - 5), NewVec3f(5, -0.001, i.float32 - 5)] - gridPos.add [NewVec3f(i.float32 - 5, -0.001, -5), NewVec3f(i.float32 - 5, -0.001, 5)] - gridColor.add [Gray, Gray, Gray, Gray] - var grid = DebugMesh( - position: asGPUArray(gridPos, VertexBuffer), - color: asGPUArray(gridColor, VertexBuffer), - ) - renderdata.AssignBuffers(grid) - - var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode = []) - var debugpipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, lineWidth=10) + var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass) InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) renderdata.FlushAllMemory() - proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, - transform: Mat4 = Unit4) = + proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4) = let nodeTransform = gltfData.nodes[nodeId].transform * transform if gltfData.nodes[nodeId].mesh >= 0: for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]: @@ -115,7 +106,7 @@ commandbuffer = commandbuffer, pipeline = pipeline, mesh = primitive[0], - pushConstant = ObjectData(transform: nodeTransform) + pushConstant = ObjectData(transform: nodeTransform, materialId: primitive[0].material) ) for childNode in gltfData.nodes[nodeId].children: drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) @@ -142,16 +133,13 @@ if KeyIsDown(A): sideward -= 2 if KeyIsDown(D): sideward += 2 - let camDir = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * Z - echo camDir - let camDirSide = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * X - # echo camDir - # echo camDirSide + let camDir = (Rotate(camYaw, Y) * Rotate(camPitch, X)) * Z + let camDirSide = camDir.Cross(-Y).Normalized camPos += camDir * forward * dt camPos += camDirSide * sideward * dt descriptors.data.camera.data.viewPerspective = ( - Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.001, zFar = 100) * + Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.1, zFar = 1) * Rotate(-camPitch, X) * Rotate(-camYaw, Y) * Translate(-camPos) ) @@ -164,16 +152,18 @@ WithPipeline(commandbuffer, pipeline): WithBind(commandbuffer, (descriptors, ), pipeline): for nodeId in gltfData.scenes[0]: - drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId) - WithBind(commandbuffer, (descriptors, ), pipeline): - WithPipeline(commandbuffer, debugpipeline): - Render(commandbuffer = commandbuffer, pipeline = debugpipeline, mesh = grid) + drawNode( + commandbuffer = commandbuffer, + pipeline = pipeline, + nodeId = nodeId, + transform = Rotate(PI / 2, Z) + ) # cleanup checkVkResult vkDeviceWaitIdle(vulkan.device) DestroyPipeline(pipeline) - DestroyPipeline(debugpipeline) DestroyRenderData(renderdata) + when isMainModule: var time = 1000'f32 InitVulkan()