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 | 5e5a3311ca44 |
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 |
