Mercurial > games > semicongine
comparison src/engine.nim @ 478:871ee602bf95
add: vertex basics, some refactoring
author | Sam <sam@basx.dev> |
---|---|
date | Sun, 01 Jan 2023 01:00:50 +0700 |
parents | af43f2acf2b9 |
children | 90e117952f74 |
comparison
equal
deleted
inserted
replaced
477:f226c99b5043 | 478:871ee602bf95 |
---|---|
6 | 6 |
7 import ./vulkan | 7 import ./vulkan |
8 import ./vulkan_helpers | 8 import ./vulkan_helpers |
9 import ./window | 9 import ./window |
10 import ./events | 10 import ./events |
11 import ./math/vector | |
12 import ./shader | |
13 import ./vertex | |
11 | 14 |
12 import ./glslang/glslang | 15 import ./glslang/glslang |
13 | 16 |
14 const MAX_FRAMES_IN_FLIGHT = 2 | 17 const MAX_FRAMES_IN_FLIGHT = 2 |
15 const DEBUG_LOG = not defined(release) | 18 const DEBUG_LOG = not defined(release) |
16 | 19 |
17 var logger = newConsoleLogger() | 20 var logger = newConsoleLogger() |
18 addHandler(logger) | 21 addHandler(logger) |
19 | 22 |
20 | 23 |
21 var vertexShaderCode: string = """#version 450 | 24 type |
25 MyVertex = object | |
26 position: VertexAttribute[Vec2[float32]] | |
27 color: VertexAttribute[Vec3[float32]] | |
28 | |
29 const vertices = [ | |
30 (Vec2([ 0.0'f32, -0.5'f32]), Vec3([1.0'f32, 0.0'f32, 0.0'f32])), | |
31 (Vec2([ 0.5'f32, 0.5'f32]), Vec3([0.0'f32, 1.0'f32, 0.0'f32])), | |
32 (Vec2([-0.5'f32, 0.5'f32]), Vec3([0.0'f32, 0.0'f32, 1.0'f32])) | |
33 ] | |
34 | |
35 | |
36 proc getBindingDescription(binding: int): auto = | |
37 VkVertexInputBindingDescription( | |
38 binding: uint32(binding), | |
39 stride: uint32(sizeof(vertices[0])), | |
40 inputRate: VK_VERTEX_INPUT_RATE_VERTEX, # VK_VERTEX_INPUT_RATE_INSTANCE for instances | |
41 ) | |
42 | |
43 proc getAttributeDescriptions(binding: int): auto = | |
44 [ | |
45 VkVertexInputAttributeDescription( | |
46 binding: 0'u32, | |
47 location: 0, | |
48 format: VK_FORMAT_R32G32_SFLOAT, | |
49 offset: 0, | |
50 ), | |
51 VkVertexInputAttributeDescription( | |
52 binding: 0'u32, | |
53 location: 1, | |
54 format: VK_FORMAT_R32G32B32_SFLOAT, | |
55 offset: uint32(sizeof(Vec2)), # use offsetOf? | |
56 ), | |
57 ] | |
58 | |
59 var vertexShaderCode = """ | |
60 #version 450 | |
61 | |
62 layout(location = 0) in vec2 inPosition; | |
63 layout(location = 1) in vec3 inColor; | |
64 | |
22 layout(location = 0) out vec3 fragColor; | 65 layout(location = 0) out vec3 fragColor; |
23 vec3 colors[3] = vec3[]( | 66 |
24 vec3(1.0, 0.0, 0.0), | |
25 vec3(0.0, 1.0, 0.0), | |
26 vec3(0.0, 0.0, 1.0) | |
27 ); | |
28 vec2 positions[3] = vec2[]( | |
29 vec2(0.0, -0.5), | |
30 vec2(0.5, 0.5), | |
31 vec2(-0.5, 0.5) | |
32 ); | |
33 void main() { | 67 void main() { |
34 gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); | 68 gl_Position = vec4(inPosition, 0.0, 1.0); |
35 fragColor = colors[gl_VertexIndex]; | 69 fragColor = inColor; |
36 }""" | 70 } |
37 | 71 """ |
38 var fragmentShaderCode: string = """#version 450 | 72 |
73 var fragmentShaderCode = """#version 450 | |
39 layout(location = 0) out vec4 outColor; | 74 layout(location = 0) out vec4 outColor; |
40 layout(location = 0) in vec3 fragColor; | 75 layout(location = 0) in vec3 fragColor; |
41 void main() { | 76 void main() { |
42 outColor = vec4(fragColor, 1.0); | 77 outColor = vec4(fragColor, 1.0); |
43 }""" | 78 }""" |
55 Swapchain = object | 90 Swapchain = object |
56 swapchain: VkSwapchainKHR | 91 swapchain: VkSwapchainKHR |
57 images: seq[VkImage] | 92 images: seq[VkImage] |
58 imageviews: seq[VkImageView] | 93 imageviews: seq[VkImageView] |
59 RenderPipeline = object | 94 RenderPipeline = object |
60 shaderStages*: seq[VkPipelineShaderStageCreateInfo] | 95 shaders*: seq[ShaderProgram] |
61 layout*: VkPipelineLayout | 96 layout*: VkPipelineLayout |
62 pipeline*: VkPipeline | 97 pipeline*: VkPipeline |
63 QueueFamily = object | 98 QueueFamily = object |
64 properties*: VkQueueFamilyProperties | 99 properties*: VkQueueFamilyProperties |
65 hasSurfaceSupport*: bool | 100 hasSurfaceSupport*: bool |
263 pDependencies: addr(dependency), | 298 pDependencies: addr(dependency), |
264 ) | 299 ) |
265 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result)) | 300 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result)) |
266 | 301 |
267 proc setupRenderPipeline(device: VkDevice, frameDimension: VkExtent2D, renderPass: VkRenderPass): RenderPipeline = | 302 proc setupRenderPipeline(device: VkDevice, frameDimension: VkExtent2D, renderPass: VkRenderPass): RenderPipeline = |
268 # (seq[VkPipelineShaderStageCreateInfo], VkViewport, VkRect2D, VkPipelineLayout, VkPipeline) = | |
269 | |
270 # load shaders | 303 # load shaders |
271 result.shaderStages.add(device.createShaderStage(VK_SHADER_STAGE_VERTEX_BIT, vertexShaderCode)) | 304 result.shaders.add(device.initShaderProgram(VK_SHADER_STAGE_VERTEX_BIT, vertexShaderCode)) |
272 result.shaderStages.add(device.createShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShaderCode)) | 305 result.shaders.add(device.initShaderProgram(VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShaderCode)) |
273 | 306 |
274 var | 307 var |
275 # define which parts can be dynamic (pipeline is fixed after setup) | 308 # define which parts can be dynamic (pipeline is fixed after setup) |
276 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] | 309 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] |
277 dynamicState = VkPipelineDynamicStateCreateInfo( | 310 dynamicState = VkPipelineDynamicStateCreateInfo( |
278 sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 311 sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, |
279 dynamicStateCount: uint32(dynamicStates.len), | 312 dynamicStateCount: uint32(dynamicStates.len), |
280 pDynamicStates: addr(dynamicStates[0]), | 313 pDynamicStates: addr(dynamicStates[0]), |
281 ) | 314 ) |
315 vertexbindings = generateInputVertexBinding[MyVertex]() | |
316 attributebindings = generateInputAttributeBinding[MyVertex]() | |
317 | |
282 # define input data format | 318 # define input data format |
283 vertexInputInfo = VkPipelineVertexInputStateCreateInfo( | 319 vertexInputInfo = VkPipelineVertexInputStateCreateInfo( |
284 sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | 320 sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, |
285 vertexBindingDescriptionCount: 0, | 321 vertexBindingDescriptionCount: uint32(vertexbindings.len), |
286 pVertexBindingDescriptions: nil, | 322 pVertexBindingDescriptions: addr(vertexbindings[0]), |
287 vertexAttributeDescriptionCount: 0, | 323 vertexAttributeDescriptionCount: uint32(attributebindings.len), |
288 pVertexAttributeDescriptions: nil, | 324 pVertexAttributeDescriptions: addr(attributebindings[0]), |
289 ) | 325 ) |
290 inputAssembly = VkPipelineInputAssemblyStateCreateInfo( | 326 inputAssembly = VkPipelineInputAssemblyStateCreateInfo( |
291 sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | 327 sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, |
292 topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, | 328 topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, |
293 primitiveRestartEnable: VK_FALSE, | 329 primitiveRestartEnable: VK_FALSE, |
356 pushConstantRangeCount: 0, | 392 pushConstantRangeCount: 0, |
357 pPushConstantRanges: nil, | 393 pPushConstantRanges: nil, |
358 ) | 394 ) |
359 checkVkResult device.vkCreatePipelineLayout(addr(pipelineLayoutInfo), nil, addr(result.layout)) | 395 checkVkResult device.vkCreatePipelineLayout(addr(pipelineLayoutInfo), nil, addr(result.layout)) |
360 | 396 |
397 var stages: seq[VkPipelineShaderStageCreateInfo] | |
398 for shader in result.shaders: | |
399 stages.add(shader.shader) | |
361 var pipelineInfo = VkGraphicsPipelineCreateInfo( | 400 var pipelineInfo = VkGraphicsPipelineCreateInfo( |
362 sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | 401 sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, |
363 stageCount: 2, | 402 stageCount: uint32(stages.len), |
364 pStages: addr(result.shaderStages[0]), | 403 pStages: addr(stages[0]), |
365 pVertexInputState: addr(vertexInputInfo), | 404 pVertexInputState: addr(vertexInputInfo), |
366 pInputAssemblyState: addr(inputAssembly), | 405 pInputAssemblyState: addr(inputAssembly), |
367 pViewportState: addr(viewportState), | 406 pViewportState: addr(viewportState), |
368 pRasterizationState: addr(rasterizer), | 407 pRasterizationState: addr(rasterizer), |
369 pMultisampleState: addr(multisampling), | 408 pMultisampleState: addr(multisampling), |
631 engine.vulkan.device.device.vkDestroyCommandPool(engine.vulkan.commandPool, nil) | 670 engine.vulkan.device.device.vkDestroyCommandPool(engine.vulkan.commandPool, nil) |
632 engine.vulkan.device.device.vkDestroyPipeline(engine.vulkan.pipeline.pipeline, nil) | 671 engine.vulkan.device.device.vkDestroyPipeline(engine.vulkan.pipeline.pipeline, nil) |
633 engine.vulkan.device.device.vkDestroyPipelineLayout(engine.vulkan.pipeline.layout, nil) | 672 engine.vulkan.device.device.vkDestroyPipelineLayout(engine.vulkan.pipeline.layout, nil) |
634 engine.vulkan.device.device.vkDestroyRenderPass(engine.vulkan.renderPass, nil) | 673 engine.vulkan.device.device.vkDestroyRenderPass(engine.vulkan.renderPass, nil) |
635 | 674 |
636 for shaderStage in engine.vulkan.pipeline.shaderStages: | 675 for shader in engine.vulkan.pipeline.shaders: |
637 engine.vulkan.device.device.vkDestroyShaderModule(shaderStage.module, nil) | 676 engine.vulkan.device.device.vkDestroyShaderModule(shader.shader.module, nil) |
638 | 677 |
639 engine.vulkan.instance.vkDestroySurfaceKHR(engine.vulkan.surface, nil) | 678 engine.vulkan.instance.vkDestroySurfaceKHR(engine.vulkan.surface, nil) |
640 engine.vulkan.device.device.vkDestroyDevice(nil) | 679 engine.vulkan.device.device.vkDestroyDevice(nil) |
641 when DEBUG_LOG: | 680 when DEBUG_LOG: |
642 engine.vulkan.instance.vkDestroyDebugUtilsMessengerEXT(engine.vulkan.debugMessenger, nil) | 681 engine.vulkan.instance.vkDestroyDebugUtilsMessengerEXT(engine.vulkan.debugMessenger, nil) |