Mercurial > games > semicongine
comparison 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 |
comparison
equal
deleted
inserted
replaced
1254:b0f4c8ccd49a | 1255:2b5ca798f6d6 |
---|---|
11 var renderdata = InitRenderData() | 11 var renderdata = InitRenderData() |
12 | 12 |
13 type | 13 type |
14 ObjectData = object | 14 ObjectData = object |
15 transform: Mat4 | 15 transform: Mat4 |
16 materialId: int32 | |
16 Camera = object | 17 Camera = object |
17 viewPerspective: Mat4 | 18 viewPerspective: Mat4 |
18 Material = object | 19 Material = object |
19 color: Vec4f = NewVec4f(1, 1, 1, 1) | 20 color: Vec4f = NewVec4f(1, 1, 1, 1) |
20 colorTexture: int32 = -1 | 21 # colorTexture: int32 = -1 |
21 metallic: float32 = 0 | 22 metallic: float32 = 0 |
22 roughness: float32 = 0 | 23 roughness: float32 = 0 |
23 metallicRoughnessTexture: int32 = -1 | 24 # metallicRoughnessTexture: int32 = -1 |
24 | 25 # normalTexture: int32 = -1 |
25 normalTexture: int32 = -1 | 26 # occlusionTexture: int32 = -1 |
26 occlusionTexture: int32 = -1 | |
27 emissive: Vec4f = NewVec4f(0, 0, 0, 0) | 27 emissive: Vec4f = NewVec4f(0, 0, 0, 0) |
28 emissiveTexture: int32 = -1 | 28 # emissiveTexture: int32 = -1 |
29 MainDescriptors = object | 29 MainDescriptors = object |
30 material: GPUValue[Material, UniformBuffer] | 30 materials: array[32, GPUValue[Material, UniformBuffer]] |
31 camera: GPUValue[Camera, UniformBufferMapped] | 31 camera: GPUValue[Camera, UniformBufferMapped] |
32 Shader = object | 32 Shader = object |
33 objectData {.PushConstantAttribute.}: ObjectData | 33 objectData {.PushConstantAttribute.}: ObjectData |
34 position {.VertexAttribute.}: Vec3f | 34 position {.VertexAttribute.}: Vec3f |
35 color {.VertexAttribute.}: Vec4f | 35 color {.VertexAttribute.}: Vec4f |
36 # uv {.VertexAttribute.}: Vec2f | 36 normal {.VertexAttribute.}: Vec3f |
37 fragmentColor {.Pass.}: Vec4f | 37 fragmentColor {.Pass.}: Vec4f |
38 fragmentUv {.Pass.}: Vec2f | 38 fragmentNormal {.Pass.}: Vec3f |
39 outColor {.ShaderOutput.}: Vec4f | 39 outColor {.ShaderOutput.}: Vec4f |
40 descriptors {.DescriptorSets.}: (MainDescriptors, ) | 40 descriptors {.DescriptorSets.}: (MainDescriptors, ) |
41 # code | 41 # code |
42 vertexCode: string = """ | 42 vertexCode: string = """ |
43 void main() { | 43 void main() { |
44 fragmentColor = color; | 44 fragmentColor = color * materials[objectData.materialId].color; |
45 // fragmentUv = uv; | 45 fragmentNormal = normal; |
46 gl_Position = vec4(position, 1) * camera.viewPerspective; | 46 gl_Position = vec4(position, 1) * (objectData.transform * camera.viewPerspective); |
47 }""" | 47 }""" |
48 fragmentCode: string = """void main() { outColor = fragmentColor;}""" | 48 fragmentCode: string = """ |
49 const vec3 lightDir = normalize(vec3(1, -1, 1)); | |
50 void main() { | |
51 outColor = vec4(fragmentColor.rgb * (1 - abs(dot(fragmentNormal, lightDir))), fragmentColor.a); | |
52 }""" | |
49 Mesh = object | 53 Mesh = object |
50 position: GPUArray[Vec3f, VertexBuffer] | 54 position: GPUArray[Vec3f, VertexBuffer] |
51 color: GPUArray[Vec4f, VertexBuffer] | 55 color: GPUArray[Vec4f, VertexBuffer] |
52 uv: GPUArray[Vec2f, VertexBuffer] | 56 normal: GPUArray[Vec3f, VertexBuffer] |
53 DebugMesh = object | 57 indices: GPUArray[uint32, IndexBuffer] |
54 position: GPUArray[Vec3f, VertexBuffer] | 58 material: int32 |
55 color: GPUArray[Vec4f, VertexBuffer] | |
56 | 59 |
57 var gltfData = LoadMeshes[Mesh, Material]( | 60 var gltfData = LoadMeshes[Mesh, Material]( |
58 "town.glb", | 61 "town.glb", |
59 MeshAttributeNames( | 62 MeshAttributeNames( |
60 POSITION: "position", | 63 POSITION: "position", |
61 COLOR: @["color"], | 64 COLOR: @["color"], |
62 TEXCOORD: @["uv"], | 65 NORMAL: "normal", |
66 indices: "indices", | |
67 material: "material", | |
63 ), | 68 ), |
64 MaterialAttributeNames( | 69 MaterialAttributeNames( |
65 baseColorFactor: "color", | 70 baseColorFactor: "color", |
66 baseColorTexture: "colorTexture", | 71 baseColorTexture: "colorTexture", |
67 metallicFactor: "metallic", | 72 metallicFactor: "metallic", |
78 camera: asGPUValue(Camera( | 83 camera: asGPUValue(Camera( |
79 viewPerspective: Unit4, | 84 viewPerspective: Unit4, |
80 ), UniformBufferMapped) | 85 ), UniformBufferMapped) |
81 ) | 86 ) |
82 ) | 87 ) |
88 for i in 0 ..< gltfData.materials.len: | |
89 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) | |
83 for mesh in mitems(gltfData.meshes): | 90 for mesh in mitems(gltfData.meshes): |
84 for primitive in mitems(mesh): | 91 for primitive in mitems(mesh): |
85 primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, NewVec4f(1, 1, 1, 1)), VertexBuffer) | 92 primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, NewVec4f(1, 1, 1, 1)), VertexBuffer) |
86 renderdata.AssignBuffers(primitive[0]) | 93 renderdata.AssignBuffers(primitive[0]) |
87 renderdata.AssignBuffers(descriptors) | 94 renderdata.AssignBuffers(descriptors) |
88 | 95 |
89 let O = default(Vec3f) | 96 var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass) |
90 let Gray = NewVec4f(0.5, 0.5, 0.5, 1) | |
91 var gridPos = @[O, X, O, Y, O, Z] | |
92 var gridColor = @[R, R, G, G, B, B] | |
93 for i in 0 ..< 10: | |
94 gridPos.add [NewVec3f(-5, -0.001, i.float32 - 5), NewVec3f(5, -0.001, i.float32 - 5)] | |
95 gridPos.add [NewVec3f(i.float32 - 5, -0.001, -5), NewVec3f(i.float32 - 5, -0.001, 5)] | |
96 gridColor.add [Gray, Gray, Gray, Gray] | |
97 var grid = DebugMesh( | |
98 position: asGPUArray(gridPos, VertexBuffer), | |
99 color: asGPUArray(gridColor, VertexBuffer), | |
100 ) | |
101 renderdata.AssignBuffers(grid) | |
102 | |
103 var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode = []) | |
104 var debugpipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, lineWidth=10) | |
105 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) | 97 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) |
106 | 98 |
107 renderdata.FlushAllMemory() | 99 renderdata.FlushAllMemory() |
108 | 100 |
109 proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, | 101 proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4) = |
110 transform: Mat4 = Unit4) = | |
111 let nodeTransform = gltfData.nodes[nodeId].transform * transform | 102 let nodeTransform = gltfData.nodes[nodeId].transform * transform |
112 if gltfData.nodes[nodeId].mesh >= 0: | 103 if gltfData.nodes[nodeId].mesh >= 0: |
113 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]: | 104 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]: |
114 RenderWithPushConstant( | 105 RenderWithPushConstant( |
115 commandbuffer = commandbuffer, | 106 commandbuffer = commandbuffer, |
116 pipeline = pipeline, | 107 pipeline = pipeline, |
117 mesh = primitive[0], | 108 mesh = primitive[0], |
118 pushConstant = ObjectData(transform: nodeTransform) | 109 pushConstant = ObjectData(transform: nodeTransform, materialId: primitive[0].material) |
119 ) | 110 ) |
120 for childNode in gltfData.nodes[nodeId].children: | 111 for childNode in gltfData.nodes[nodeId].children: |
121 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) | 112 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) |
122 | 113 |
123 var camPos: Vec3f | 114 var camPos: Vec3f |
140 if KeyIsDown(W): forward += 2 | 131 if KeyIsDown(W): forward += 2 |
141 if KeyIsDown(S): forward -= 2 | 132 if KeyIsDown(S): forward -= 2 |
142 if KeyIsDown(A): sideward -= 2 | 133 if KeyIsDown(A): sideward -= 2 |
143 if KeyIsDown(D): sideward += 2 | 134 if KeyIsDown(D): sideward += 2 |
144 | 135 |
145 let camDir = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * Z | 136 let camDir = (Rotate(camYaw, Y) * Rotate(camPitch, X)) * Z |
146 echo camDir | 137 let camDirSide = camDir.Cross(-Y).Normalized |
147 let camDirSide = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * X | |
148 # echo camDir | |
149 # echo camDirSide | |
150 camPos += camDir * forward * dt | 138 camPos += camDir * forward * dt |
151 camPos += camDirSide * sideward * dt | 139 camPos += camDirSide * sideward * dt |
152 | 140 |
153 descriptors.data.camera.data.viewPerspective = ( | 141 descriptors.data.camera.data.viewPerspective = ( |
154 Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.001, zFar = 100) * | 142 Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.1, zFar = 1) * |
155 Rotate(-camPitch, X) * Rotate(-camYaw, Y) * Translate(-camPos) | 143 Rotate(-camPitch, X) * Rotate(-camYaw, Y) * Translate(-camPos) |
156 ) | 144 ) |
157 | 145 |
158 UpdateGPUBuffer(descriptors.data.camera) | 146 UpdateGPUBuffer(descriptors.data.camera) |
159 | 147 |
162 WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): | 150 WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): |
163 | 151 |
164 WithPipeline(commandbuffer, pipeline): | 152 WithPipeline(commandbuffer, pipeline): |
165 WithBind(commandbuffer, (descriptors, ), pipeline): | 153 WithBind(commandbuffer, (descriptors, ), pipeline): |
166 for nodeId in gltfData.scenes[0]: | 154 for nodeId in gltfData.scenes[0]: |
167 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId) | 155 drawNode( |
168 WithBind(commandbuffer, (descriptors, ), pipeline): | 156 commandbuffer = commandbuffer, |
169 WithPipeline(commandbuffer, debugpipeline): | 157 pipeline = pipeline, |
170 Render(commandbuffer = commandbuffer, pipeline = debugpipeline, mesh = grid) | 158 nodeId = nodeId, |
159 transform = Rotate(PI / 2, Z) | |
160 ) | |
171 | 161 |
172 # cleanup | 162 # cleanup |
173 checkVkResult vkDeviceWaitIdle(vulkan.device) | 163 checkVkResult vkDeviceWaitIdle(vulkan.device) |
174 DestroyPipeline(pipeline) | 164 DestroyPipeline(pipeline) |
175 DestroyPipeline(debugpipeline) | |
176 DestroyRenderData(renderdata) | 165 DestroyRenderData(renderdata) |
166 | |
177 when isMainModule: | 167 when isMainModule: |
178 var time = 1000'f32 | 168 var time = 1000'f32 |
179 InitVulkan() | 169 InitVulkan() |
180 | 170 |
181 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT) | 171 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT) |