comparison src/engine.nim @ 17:b40466fa446a

add: vertex basics, some refactoring
author Sam <sam@basx.dev>
date Sun, 01 Jan 2023 01:00:50 +0700
parents 3415afff1d1a
children 90e117952f74
comparison
equal deleted inserted replaced
16:617c6dcddbe2 17:b40466fa446a
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)