Mercurial > games > semicongine
annotate 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 |
rev | line source |
---|---|
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
1 import std/os |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
2 import std/sequtils |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
3 import std/monotimes |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
4 import std/times |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
5 import std/options |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
6 import std/random |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
7 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
8 import ../semiconginev2 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
9 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
10 proc test_gltf(time: float32) = |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
11 var renderdata = InitRenderData() |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
12 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
13 type |
1253 | 14 ObjectData = object |
15 transform: Mat4 | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
16 materialId: int32 |
1253 | 17 Camera = object |
1254 | 18 viewPerspective: Mat4 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
19 Material = object |
1248 | 20 color: Vec4f = NewVec4f(1, 1, 1, 1) |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
21 # colorTexture: int32 = -1 |
1248 | 22 metallic: float32 = 0 |
23 roughness: float32 = 0 | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
24 # metallicRoughnessTexture: int32 = -1 |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
25 # normalTexture: int32 = -1 |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
26 # occlusionTexture: int32 = -1 |
1248 | 27 emissive: Vec4f = NewVec4f(0, 0, 0, 0) |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
28 # emissiveTexture: int32 = -1 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
29 MainDescriptors = object |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
30 materials: array[32, GPUValue[Material, UniformBuffer]] |
1253 | 31 camera: GPUValue[Camera, UniformBufferMapped] |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
32 Shader = object |
1253 | 33 objectData {.PushConstantAttribute.}: ObjectData |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
34 position {.VertexAttribute.}: Vec3f |
1254 | 35 color {.VertexAttribute.}: Vec4f |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
36 normal {.VertexAttribute.}: Vec3f |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
37 fragmentColor {.Pass.}: Vec4f |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
38 fragmentNormal {.Pass.}: Vec3f |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
39 outColor {.ShaderOutput.}: Vec4f |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
40 descriptors {.DescriptorSets.}: (MainDescriptors, ) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
41 # code |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
42 vertexCode: string = """ |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
43 void main() { |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
44 fragmentColor = color * materials[objectData.materialId].color; |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
45 fragmentNormal = normal; |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
46 gl_Position = vec4(position, 1) * (objectData.transform * camera.viewPerspective); |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
47 }""" |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
48 fragmentCode: string = """ |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
49 const vec3 lightDir = normalize(vec3(1, -1, 1)); |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
50 void main() { |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
51 outColor = vec4(fragmentColor.rgb * (1 - abs(dot(fragmentNormal, lightDir))), fragmentColor.a); |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
52 }""" |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
53 Mesh = object |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
54 position: GPUArray[Vec3f, VertexBuffer] |
1254 | 55 color: GPUArray[Vec4f, VertexBuffer] |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
56 normal: GPUArray[Vec3f, VertexBuffer] |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
57 indices: GPUArray[uint32, IndexBuffer] |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
58 material: int32 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
59 |
1251 | 60 var gltfData = LoadMeshes[Mesh, Material]( |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
61 "town.glb", |
1248 | 62 MeshAttributeNames( |
63 POSITION: "position", | |
1254 | 64 COLOR: @["color"], |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
65 NORMAL: "normal", |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
66 indices: "indices", |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
67 material: "material", |
1254 | 68 ), |
1248 | 69 MaterialAttributeNames( |
70 baseColorFactor: "color", | |
71 baseColorTexture: "colorTexture", | |
72 metallicFactor: "metallic", | |
73 roughnessFactor: "roughness", | |
74 metallicRoughnessTexture: "metallicRoughnessTexture", | |
75 normalTexture: "normalTexture", | |
76 occlusionTexture: "occlusionTexture", | |
77 emissiveTexture: "emissiveTexture", | |
78 emissiveFactor: "emissive", | |
79 ) | |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
80 ) |
1253 | 81 var descriptors = asDescriptorSet( |
82 MainDescriptors( | |
83 camera: asGPUValue(Camera( | |
1254 | 84 viewPerspective: Unit4, |
85 ), UniformBufferMapped) | |
86 ) | |
1253 | 87 ) |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
88 for i in 0 ..< gltfData.materials.len: |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
89 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) |
1251 | 90 for mesh in mitems(gltfData.meshes): |
1249
d83726af7abb
did: first triangles getting loaded from gltf
sam <sam@basx.dev>
parents:
1248
diff
changeset
|
91 for primitive in mitems(mesh): |
1254 | 92 primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, NewVec4f(1, 1, 1, 1)), VertexBuffer) |
1249
d83726af7abb
did: first triangles getting loaded from gltf
sam <sam@basx.dev>
parents:
1248
diff
changeset
|
93 renderdata.AssignBuffers(primitive[0]) |
1253 | 94 renderdata.AssignBuffers(descriptors) |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
95 |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
96 var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass) |
1253 | 97 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) |
1254 | 98 |
1253 | 99 renderdata.FlushAllMemory() |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
100 |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
101 proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4) = |
1251 | 102 let nodeTransform = gltfData.nodes[nodeId].transform * transform |
103 if gltfData.nodes[nodeId].mesh >= 0: | |
104 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]: | |
1254 | 105 RenderWithPushConstant( |
106 commandbuffer = commandbuffer, | |
107 pipeline = pipeline, | |
108 mesh = primitive[0], | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
109 pushConstant = ObjectData(transform: nodeTransform, materialId: primitive[0].material) |
1254 | 110 ) |
1251 | 111 for childNode in gltfData.nodes[nodeId].children: |
112 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) | |
113 | |
1254 | 114 var camPos: Vec3f |
115 var camYaw: float32 | |
116 var camPitch: float32 | |
117 | |
118 discard UpdateInputs() # clear inputs, otherwise MouseMove will have stuff | |
1251 | 119 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
120 var start = getMonoTime() |
1254 | 121 var lastT = getMonoTime() |
122 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and UpdateInputs(): | |
123 let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32 | |
124 lastT = getMonoTime() | |
125 | |
126 camYaw -= MouseMove().x / 1000 | |
127 camPitch -= MouseMove().y / 1000 | |
128 var | |
129 forward = 0'f32 | |
130 sideward = 0'f32 | |
131 if KeyIsDown(W): forward += 2 | |
132 if KeyIsDown(S): forward -= 2 | |
133 if KeyIsDown(A): sideward -= 2 | |
134 if KeyIsDown(D): sideward += 2 | |
135 | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
136 let camDir = (Rotate(camYaw, Y) * Rotate(camPitch, X)) * Z |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
137 let camDirSide = camDir.Cross(-Y).Normalized |
1254 | 138 camPos += camDir * forward * dt |
139 camPos += camDirSide * sideward * dt | |
140 | |
141 descriptors.data.camera.data.viewPerspective = ( | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
142 Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.1, zFar = 1) * |
1254 | 143 Rotate(-camPitch, X) * Rotate(-camYaw, Y) * Translate(-camPos) |
144 ) | |
145 | |
146 UpdateGPUBuffer(descriptors.data.camera) | |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
147 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
148 WithNextFrame(framebuffer, commandbuffer): |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
149 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
150 WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
151 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
152 WithPipeline(commandbuffer, pipeline): |
1253 | 153 WithBind(commandbuffer, (descriptors, ), pipeline): |
154 for nodeId in gltfData.scenes[0]: | |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
155 drawNode( |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
156 commandbuffer = commandbuffer, |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
157 pipeline = pipeline, |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
158 nodeId = nodeId, |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
159 transform = Rotate(PI / 2, Z) |
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
160 ) |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
161 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
162 # cleanup |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
163 checkVkResult vkDeviceWaitIdle(vulkan.device) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
164 DestroyPipeline(pipeline) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
165 DestroyRenderData(renderdata) |
1255
2b5ca798f6d6
did: make example town loadable and renderable, yay!
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
166 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
167 when isMainModule: |
1254 | 168 var time = 1000'f32 |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
169 InitVulkan() |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
170 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
171 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
172 SetupSwapchain(renderpass = renderpass) |
1254 | 173 LockMouse(true) |
1247
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
174 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
175 # tests a simple triangle with minimalistic shader and vertex format |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
176 test_gltf(time) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
177 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
178 checkVkResult vkDeviceWaitIdle(vulkan.device) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
179 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil) |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
180 ClearSwapchain() |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
181 |
c15770761865
add: gltf loading test, gltf loading for materials
sam <sam@basx.dev>
parents:
diff
changeset
|
182 DestroyVulkan() |