Mercurial > games > semicongine
comparison tests/test_gltf.nim @ 1332:df3c075e5dea
did: formatting
author | sam <sam@basx.dev> |
---|---|
date | Thu, 22 Aug 2024 18:31:59 +0700 |
parents | 3ba2c180e52c |
children |
comparison
equal
deleted
inserted
replaced
1331:1abdd42f5cfe | 1332:df3c075e5dea |
---|---|
11 | 11 |
12 type | 12 type |
13 ObjectData = object | 13 ObjectData = object |
14 transform: Mat4 | 14 transform: Mat4 |
15 materialId: int32 | 15 materialId: int32 |
16 | |
16 Camera = object | 17 Camera = object |
17 view: Mat4 | 18 view: Mat4 |
18 normal: Mat4 | 19 normal: Mat4 |
19 projection: Mat4 | 20 projection: Mat4 |
21 | |
20 Material = object | 22 Material = object |
21 color: Vec4f = vec4(1, 1, 1, 1) | 23 color: Vec4f = vec4(1, 1, 1, 1) |
22 # colorTexture: int32 = -1 | 24 # colorTexture: int32 = -1 |
23 metallic: float32 = 0 | 25 metallic: float32 = 0 |
24 roughness: float32 = 0 | 26 roughness: float32 = 0 |
25 # metallicRoughnessTexture: int32 = -1 | 27 # metallicRoughnessTexture: int32 = -1 |
26 # normalTexture: int32 = -1 | 28 # normalTexture: int32 = -1 |
27 # occlusionTexture: int32 = -1 | 29 # occlusionTexture: int32 = -1 |
28 emissive: Vec4f = vec4(0, 0, 0, 0) | 30 emissive: Vec4f = vec4(0, 0, 0, 0) # emissiveTexture: int32 = -1 |
29 # emissiveTexture: int32 = -1 | 31 |
30 MainDescriptors = object | 32 MainDescriptors = object |
31 materials: array[50, GPUValue[Material, UniformBuffer]] | 33 materials: array[50, GPUValue[Material, UniformBuffer]] |
32 camera: GPUValue[Camera, UniformBufferMapped] | 34 camera: GPUValue[Camera, UniformBufferMapped] |
35 | |
33 Shader = object | 36 Shader = object |
34 objectData {.PushConstant.}: ObjectData | 37 objectData {.PushConstant.}: ObjectData |
35 position {.VertexAttribute.}: Vec3f | 38 position {.VertexAttribute.}: Vec3f |
36 color {.VertexAttribute.}: Vec4f | 39 color {.VertexAttribute.}: Vec4f |
37 normal {.VertexAttribute.}: Vec3f | 40 normal {.VertexAttribute.}: Vec3f |
39 fragmentColor {.Pass.}: Vec4f | 42 fragmentColor {.Pass.}: Vec4f |
40 fragmentNormal {.Pass.}: Vec3f | 43 fragmentNormal {.Pass.}: Vec3f |
41 outColor {.ShaderOutput.}: Vec4f | 44 outColor {.ShaderOutput.}: Vec4f |
42 descriptors {.DescriptorSet: 0.}: MainDescriptors | 45 descriptors {.DescriptorSet: 0.}: MainDescriptors |
43 # code | 46 # code |
44 vertexCode: string = """ | 47 vertexCode: string = |
48 """ | |
45 void main() { | 49 void main() { |
46 mat4 modelView = objectData.transform * camera.view; | 50 mat4 modelView = objectData.transform * camera.view; |
47 mat3 normalMat = mat3(transpose(inverse(objectData.transform))); | 51 mat3 normalMat = mat3(transpose(inverse(objectData.transform))); |
48 vec4 posTransformed = vec4(position, 1) * modelView; | 52 vec4 posTransformed = vec4(position, 1) * modelView; |
49 fragmentPosition = posTransformed.xyz / posTransformed.w; | 53 fragmentPosition = posTransformed.xyz / posTransformed.w; |
50 fragmentColor = color * materials[objectData.materialId].color; | 54 fragmentColor = color * materials[objectData.materialId].color; |
51 fragmentNormal = normal * normalMat; | 55 fragmentNormal = normal * normalMat; |
52 gl_Position = vec4(position, 1) * (modelView * camera.projection); | 56 gl_Position = vec4(position, 1) * (modelView * camera.projection); |
53 }""" | 57 }""" |
54 fragmentCode: string = """ | 58 fragmentCode: string = |
59 """ | |
55 const vec3 lightPosition = vec3(7, 9, -12); | 60 const vec3 lightPosition = vec3(7, 9, -12); |
56 const float shininess = 40; | 61 const float shininess = 40; |
57 const vec3 ambientColor = vec3(0, 0, 0); | 62 const vec3 ambientColor = vec3(0, 0, 0); |
58 const vec3 lightColor = vec3(1, 1, 1); | 63 const vec3 lightColor = vec3(1, 1, 1); |
59 // const vec3 specColor = vec3(1, 1, 1); | 64 // const vec3 specColor = vec3(1, 1, 1); |
80 vec3 specColor = diffuseColor; | 85 vec3 specColor = diffuseColor; |
81 vec3 color = ambientColor + diffuseColor * lambertian * lightColor * lightPower / dist + specColor * specular * lightColor * lightPower / dist; | 86 vec3 color = ambientColor + diffuseColor * lambertian * lightColor * lightPower / dist + specColor * specular * lightColor * lightPower / dist; |
82 | 87 |
83 outColor = vec4(color, fragmentColor.a); | 88 outColor = vec4(color, fragmentColor.a); |
84 }""" | 89 }""" |
90 | |
85 Mesh = object | 91 Mesh = object |
86 position: GPUArray[Vec3f, VertexBuffer] | 92 position: GPUArray[Vec3f, VertexBuffer] |
87 color: GPUArray[Vec4f, VertexBuffer] | 93 color: GPUArray[Vec4f, VertexBuffer] |
88 normal: GPUArray[Vec3f, VertexBuffer] | 94 normal: GPUArray[Vec3f, VertexBuffer] |
89 indices: GPUArray[uint32, IndexBuffer] | 95 indices: GPUArray[uint32, IndexBuffer] |
107 metallicRoughnessTexture: "metallicRoughnessTexture", | 113 metallicRoughnessTexture: "metallicRoughnessTexture", |
108 normalTexture: "normalTexture", | 114 normalTexture: "normalTexture", |
109 occlusionTexture: "occlusionTexture", | 115 occlusionTexture: "occlusionTexture", |
110 emissiveTexture: "emissiveTexture", | 116 emissiveTexture: "emissiveTexture", |
111 emissiveFactor: "emissive", | 117 emissiveFactor: "emissive", |
112 ) | 118 ), |
113 ) | 119 ) |
114 var descriptors = asDescriptorSetData( | 120 var descriptors = asDescriptorSetData( |
115 MainDescriptors( | 121 MainDescriptors( |
116 camera: asGPUValue(Camera( | 122 camera: asGPUValue( |
117 view: Unit4, | 123 Camera(view: Unit4, normal: Unit4, projection: Unit4), UniformBufferMapped |
118 normal: Unit4, | 124 ) |
119 projection: Unit4, | |
120 ), UniformBufferMapped) | |
121 ) | 125 ) |
122 ) | 126 ) |
123 for i in 0 ..< gltfData.materials.len: | 127 for i in 0 ..< gltfData.materials.len: |
124 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) | 128 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) |
125 for mesh in mitems(gltfData.meshes): | 129 for mesh in mitems(gltfData.meshes): |
126 for primitive in mitems(mesh): | 130 for primitive in mitems(mesh): |
127 primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, vec4(1, 1, 1, 1)), VertexBuffer) | 131 primitive[0].color = asGPUArray( |
132 newSeqWith(primitive[0].position.data.len, vec4(1, 1, 1, 1)), VertexBuffer | |
133 ) | |
128 renderdata.assignBuffers(primitive[0]) | 134 renderdata.assignBuffers(primitive[0]) |
129 renderdata.assignBuffers(descriptors) | 135 renderdata.assignBuffers(descriptors) |
130 | 136 |
131 var pipeline = createPipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode=[]) | 137 var pipeline = |
138 createPipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode = []) | |
132 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) | 139 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) |
133 | 140 |
134 renderdata.flushAllMemory() | 141 renderdata.flushAllMemory() |
135 | 142 |
136 proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4) = | 143 proc drawNode( |
144 commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4 | |
145 ) = | |
137 let nodeTransform = gltfData.nodes[nodeId].transform * transform | 146 let nodeTransform = gltfData.nodes[nodeId].transform * transform |
138 if gltfData.nodes[nodeId].mesh >= 0: | 147 if gltfData.nodes[nodeId].mesh >= 0: |
139 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh].mitems: | 148 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh].mitems: |
140 renderWithPushConstant( | 149 renderWithPushConstant( |
141 commandbuffer = commandbuffer, | 150 commandbuffer = commandbuffer, |
142 pipeline = pipeline, | 151 pipeline = pipeline, |
143 mesh = primitive[0], | 152 mesh = primitive[0], |
144 pushConstant = ObjectData(transform: nodeTransform, materialId: primitive[0].material) | 153 pushConstant = |
154 ObjectData(transform: nodeTransform, materialId: primitive[0].material), | |
145 ) | 155 ) |
146 for childNode in gltfData.nodes[nodeId].children: | 156 for childNode in gltfData.nodes[nodeId].children: |
147 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) | 157 drawNode( |
158 commandbuffer = commandbuffer, | |
159 pipeline = pipeline, | |
160 nodeId = childNode, | |
161 transform = nodeTransform, | |
162 ) | |
148 | 163 |
149 var camPos: Vec3f | 164 var camPos: Vec3f |
150 var camYaw: float32 | 165 var camYaw: float32 |
151 var camPitch: float32 | 166 var camPitch: float32 |
152 | 167 |
156 var lastT = getMonoTime() | 171 var lastT = getMonoTime() |
157 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and updateInputs(): | 172 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and updateInputs(): |
158 let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32 | 173 let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32 |
159 lastT = getMonoTime() | 174 lastT = getMonoTime() |
160 | 175 |
161 camYaw += mouseMove().x.float32 / 1000'f32 | 176 camYaw += mouseMove().x.float32 / 1000'f32 |
162 camPitch += mouseMove().y.float32 / 1000'f32 | 177 camPitch += mouseMove().y.float32 / 1000'f32 |
163 var | 178 var |
164 forward = 0'f32 | 179 forward = 0'f32 |
165 sideward = 0'f32 | 180 sideward = 0'f32 |
166 if keyIsDown(W): forward += 2 | 181 if keyIsDown(W): |
167 if keyIsDown(S): forward -= 2 | 182 forward += 2 |
168 if keyIsDown(A): sideward -= 2 | 183 if keyIsDown(S): |
169 if keyIsDown(D): sideward += 2 | 184 forward -= 2 |
185 if keyIsDown(A): | |
186 sideward -= 2 | |
187 if keyIsDown(D): | |
188 sideward += 2 | |
170 | 189 |
171 let camDir = (rotate(camYaw, Y) * rotate(camPitch, X)) * Z | 190 let camDir = (rotate(camYaw, Y) * rotate(camPitch, X)) * Z |
172 let camDirSide = camDir.cross(-Y).normalized | 191 let camDirSide = camDir.cross(-Y).normalized |
173 camPos += camDir * forward * dt | 192 camPos += camDir * forward * dt |
174 camPos += camDirSide * sideward * dt | 193 camPos += camDirSide * sideward * dt |
175 | 194 |
176 let view = rotate(-camPitch, X) * rotate(-camYaw, Y) * translate(-camPos) | 195 let view = rotate(-camPitch, X) * rotate(-camYaw, Y) * translate(-camPos) |
177 descriptors.data.camera.data.view = view | 196 descriptors.data.camera.data.view = view |
178 descriptors.data.camera.data.normal = view | 197 descriptors.data.camera.data.normal = view |
179 descriptors.data.camera.data.projection = projection(PI / 2, aspect = getAspectRatio(), zNear = 0.01, zFar = 20) | 198 descriptors.data.camera.data.projection = |
199 projection(PI / 2, aspect = getAspectRatio(), zNear = 0.01, zFar = 20) | |
180 | 200 |
181 updateGPUBuffer(descriptors.data.camera) | 201 updateGPUBuffer(descriptors.data.camera) |
182 | 202 |
183 withNextFrame(framebuffer, commandbuffer): | 203 withNextFrame(framebuffer, commandbuffer): |
184 | 204 withRenderPass( |
185 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): | 205 vulkan.swapchain.renderPass, |
186 | 206 framebuffer, |
207 commandbuffer, | |
208 vulkan.swapchain.width, | |
209 vulkan.swapchain.height, | |
210 vec4(0, 0, 0, 0), | |
211 ): | |
187 withPipeline(commandbuffer, pipeline): | 212 withPipeline(commandbuffer, pipeline): |
188 bindDescriptorSet(commandbuffer, descriptors, 0, pipeline) | 213 bindDescriptorSet(commandbuffer, descriptors, 0, pipeline) |
189 for nodeId in gltfData.scenes[0]: | 214 for nodeId in gltfData.scenes[0]: |
190 drawNode( | 215 drawNode( |
191 commandbuffer = commandbuffer, | 216 commandbuffer = commandbuffer, |
192 pipeline = pipeline, | 217 pipeline = pipeline, |
193 nodeId = nodeId, | 218 nodeId = nodeId, |
194 transform = rotate(PI / 2, Z) | 219 transform = rotate(PI / 2, Z), |
195 ) | 220 ) |
196 | 221 |
197 # cleanup | 222 # cleanup |
198 checkVkResult vkDeviceWaitIdle(vulkan.device) | 223 checkVkResult vkDeviceWaitIdle(vulkan.device) |
199 destroyPipeline(pipeline) | 224 destroyPipeline(pipeline) |
201 | 226 |
202 when isMainModule: | 227 when isMainModule: |
203 var time = 1000'f32 | 228 var time = 1000'f32 |
204 initVulkan() | 229 initVulkan() |
205 | 230 |
206 var renderpass = createDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT) | 231 var renderpass = createDirectPresentationRenderPass( |
232 depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT | |
233 ) | |
207 setupSwapchain(renderpass = renderpass) | 234 setupSwapchain(renderpass = renderpass) |
208 lockMouse(true) | 235 lockMouse(true) |
209 # showSystemCursor(false) | 236 # showSystemCursor(false) |
210 | 237 |
211 # tests a simple triangle with minimalistic shader and vertex format | 238 # tests a simple triangle with minimalistic shader and vertex format |