Mercurial > games > semicongine
changeset 1240:42eeb59f3a43
add: more tests, line and point rendering
author | sam <sam@basx.dev> |
---|---|
date | Mon, 22 Jul 2024 12:42:35 +0700 |
parents | 69489a678141 |
children | a0ed1a918fda |
files | semiconginev2/rendering.nim semiconginev2/rendering/renderer.nim semiconginev2/rendering/shaders.nim semiconginev2/text/textbox.nim tests/test_rendering.nim tests/test_text.nim |
diffstat | 6 files changed, 113 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/semiconginev2/rendering.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/semiconginev2/rendering.nim Mon Jul 22 12:42:35 2024 +0700 @@ -302,6 +302,11 @@ ) deviceExtensionsC = allocCStringArray(deviceExtensions) defer: deallocCStringArray(deviceExtensionsC) + let enabledFeatures = VkPhysicalDeviceFeatures( + fillModeNonSolid: true, + wideLines: true, + largePoints: true, + ) var createDeviceInfo = VkDeviceCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, queueCreateInfoCount: 1, @@ -310,7 +315,7 @@ ppEnabledLayerNames: nil, enabledExtensionCount: uint32(deviceExtensions.len), ppEnabledExtensionNames: deviceExtensionsC, - pEnabledFeatures: nil, + pEnabledFeatures: addr(enabledFeatures), ) checkVkResult vkCreateDevice( physicalDevice = vulkan.physicalDevice,
--- a/semiconginev2/rendering/renderer.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/semiconginev2/rendering/renderer.nim Mon Jul 22 12:42:35 2024 +0700 @@ -304,7 +304,6 @@ renderdata: var RenderData, bufferType: BufferType, size: uint64, - needsFrameInFlight = -1 ): (Buffer, uint64) = # find buffer that has space @@ -312,9 +311,8 @@ for i in 0 ..< renderData.buffers[bufferType].len: let buffer = renderData.buffers[bufferType][i] - if needsFrameInFlight == -1 or buffer.useForFrameInFlight == needsFrameInFlight: - if buffer.size - alignedTo(buffer.offsetNextFree, BUFFER_ALIGNMENT) >= size: - selectedBufferI = i + if buffer.size - alignedTo(buffer.offsetNextFree, BUFFER_ALIGNMENT) >= size: + selectedBufferI = i # otherwise create new buffer if selectedBufferI < 0: @@ -323,8 +321,6 @@ size = max(size, BUFFER_ALLOCATION_SIZE), bufferType = bufferType, ) - if needsFrameInFlight >= 0: - renderdata.buffers[bufferType][selectedBufferI].useForFrameInFlight = needsFrameInFlight # assigne value let selectedBuffer = renderdata.buffers[bufferType][selectedBufferI]
--- a/semiconginev2/rendering/shaders.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/semiconginev2/rendering/shaders.nim Mon Jul 22 12:42:35 2024 +0700 @@ -349,7 +349,7 @@ polygonMode: VkPolygonMode = VK_POLYGON_MODE_FILL, cullMode: openArray[VkCullModeFlagBits] = [VK_CULL_MODE_BACK_BIT], frontFace: VkFrontFace = VK_FRONT_FACE_CLOCKWISE, - descriptorPoolLimit = 1024, + lineWidth = 1'f32, ): Pipeline[TShader] = # create pipeline @@ -427,7 +427,7 @@ depthClampEnable: VK_FALSE, rasterizerDiscardEnable: VK_FALSE, polygonMode: polygonMode, - lineWidth: 1.0, + lineWidth: lineWidth, cullMode: toBits cullMode, frontFace: frontFace, depthBiasEnable: VK_FALSE, @@ -457,7 +457,7 @@ ) colorBlendAttachment = VkPipelineColorBlendAttachmentState( colorWriteMask: toBits [VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, VK_COLOR_COMPONENT_A_BIT], - blendEnable: VK_TRUE, + blendEnable: true, srcColorBlendFactor: VK_BLEND_FACTOR_SRC_ALPHA, dstColorBlendFactor: VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, colorBlendOp: VK_BLEND_OP_ADD, @@ -468,8 +468,10 @@ colorBlending = VkPipelineColorBlendStateCreateInfo( sType: VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, logicOpEnable: false, + logicOp: VK_LOGIC_OP_COPY, attachmentCount: 1, pAttachments: addr(colorBlendAttachment), + blendConstants: [0'f32, 0'f32, 0'f32, 0'f32] ) dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] dynamicState = VkPipelineDynamicStateCreateInfo(
--- a/semiconginev2/text/textbox.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/semiconginev2/text/textbox.nim Mon Jul 22 12:42:35 2024 +0700 @@ -47,7 +47,7 @@ of Top: 0'f32 of Center: -height / 2 of Bottom: -height - ) - textbox.font.capHeight + ) + textbox.font.capHeight var offsetX = 0'f32
--- a/tests/test_rendering.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/tests/test_rendering.nim Mon Jul 22 12:42:35 2024 +0700 @@ -433,7 +433,6 @@ let looptime = tEndLoop - tStartLoop let waitTime = 16_666 - looptime.inMicroseconds if waitTime > 0: - echo "sleep ", waitTime / 1000 sleep((waitTime / 1000).int) # cleanup @@ -441,7 +440,64 @@ DestroyPipeline(pipeline) DestroyRenderData(renderdata) -proc test_06_triangle_2pass(time: float32, depthBuffer: bool, samples: VkSampleCountFlagBits) = +proc test_06_different_draw_modes(time: float32) = + var renderdata = InitRenderData() + + type + Shader = object + position {.VertexAttribute.}: Vec3f + color {.VertexAttribute.}: Vec3f + fragmentColor {.Pass.}: Vec3f + outColor {.ShaderOutput.}: Vec4f + # code + vertexCode: string = """void main() { + gl_PointSize = 100; + fragmentColor = color; + gl_Position = vec4(position, 1);}""" + fragmentCode: string = """void main() { + outColor = vec4(fragmentColor, 1);}""" + TriangleMesh = object + position: GPUArray[Vec3f, VertexBuffer] + color: GPUArray[Vec3f, VertexBuffer] + var triangle = TriangleMesh( + position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), + color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer), + ) + var lines = TriangleMesh( + position: asGPUArray([NewVec3f(-0.9, 0), NewVec3f(-0.05, -0.9), NewVec3f(0.05, -0.9), NewVec3f(0.9, 0)], VertexBuffer), + color: asGPUArray([NewVec3f(1, 1, 0), NewVec3f(1, 1, 0), NewVec3f(0, 1, 0), NewVec3f(0, 1, 0)], VertexBuffer), + ) + AssignBuffers(renderdata, triangle) + AssignBuffers(renderdata, lines) + renderdata.FlushAllMemory() + + var pipeline1 = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, polygonMode = VK_POLYGON_MODE_LINE, lineWidth = 20'f32) + var pipeline2 = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, polygonMode = VK_POLYGON_MODE_POINT) + var pipeline3 = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, lineWidth = 5) + var pipeline4 = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST) + + var start = getMonoTime() + while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: + WithNextFrame(framebuffer, commandbuffer): + WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): + WithPipeline(commandbuffer, pipeline1): + Render(commandbuffer = commandbuffer, pipeline = pipeline1, mesh = triangle) + WithPipeline(commandbuffer, pipeline2): + Render(commandbuffer = commandbuffer, pipeline = pipeline2, mesh = triangle) + WithPipeline(commandbuffer, pipeline3): + Render(commandbuffer = commandbuffer, pipeline = pipeline3, mesh = lines) + WithPipeline(commandbuffer, pipeline4): + Render(commandbuffer = commandbuffer, pipeline = pipeline4, mesh = lines) + + # cleanup + checkVkResult vkDeviceWaitIdle(vulkan.device) + DestroyPipeline(pipeline1) + DestroyPipeline(pipeline2) + DestroyPipeline(pipeline3) + DestroyPipeline(pipeline4) + DestroyRenderData(renderdata) + +proc test_07_triangle_2pass(time: float32, depthBuffer: bool, samples: VkSampleCountFlagBits) = var (offscreenRP, presentRP) = CreateIndirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples) SetupSwapchain(renderpass = presentRP) @@ -580,7 +636,6 @@ attachments = @[msaaImageView, depthImageView, uniforms1.data.frameTexture.imageview] else: attachments = @[msaaImageView, uniforms1.data.frameTexture.imageview] - echo attachments var offscreenFB = svkCreateFramebuffer( offscreenRP.vk, vulkan.swapchain.width, @@ -633,6 +688,7 @@ (depthBuffer: true, samples: VK_SAMPLE_COUNT_4_BIT), ] + # test normal for i, (depthBuffer, samples) in renderPasses: var renderpass = CreateDirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples) @@ -653,12 +709,15 @@ # rotating cube test_05_cube(time) + # different draw modes (lines, points, and topologies) + test_06_different_draw_modes(time) + checkVkResult vkDeviceWaitIdle(vulkan.device) vkDestroyRenderPass(vulkan.device, renderpass.vk, nil) ClearSwapchain() # test multiple render passes for i, (depthBuffer, samples) in renderPasses: - test_06_triangle_2pass(time, depthBuffer, samples) + test_07_triangle_2pass(time, depthBuffer, samples) DestroyVulkan()
--- a/tests/test_text.nim Mon Jul 22 00:46:10 2024 +0700 +++ b/tests/test_text.nim Mon Jul 22 12:42:35 2024 +0700 @@ -1,4 +1,5 @@ import std/os +import std/algorithm import std/strutils import std/sequtils import std/monotimes @@ -160,10 +161,41 @@ DestroyRenderData(renderdata) proc test_04_lots_of_texts(time: float32) = - discard # TODO + var renderdata = InitRenderData() + + var pipeline = CreatePipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) + + var font = LoadFont("DejaVuSans.ttf", lineHeightPixels = 160) + var labels: seq[Textbox] + for i in 0 ..< 100: + labels.add InitTextbox( + renderdata, + pipeline.descriptorSetLayouts[0], + font, + $i, + color = NewVec4f(rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0)), + scale = rand(0.0002 .. 0.002), + position = NewVec3f(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1)) + ) + labels = labels.sortedByIt(-it.Position.z) + + var start = getMonoTime() + while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: + for l in labels.mitems: + l.Refresh() + WithNextFrame(framebuffer, commandbuffer): + WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): + WithPipeline(commandbuffer, pipeline): + for l in labels: + Render(l, commandbuffer, pipeline) + + # cleanup + checkVkResult vkDeviceWaitIdle(vulkan.device) + DestroyPipeline(pipeline) + DestroyRenderData(renderdata) when isMainModule: - var time = 10'f32 + var time = 1000'f32 InitVulkan() var renderpass = CreateDirectPresentationRenderPass(depthBuffer = true) @@ -172,7 +204,8 @@ # tests a simple triangle with minimalistic shader and vertex format # test_01_static_label(time, swapchain) # test_02_multiple_animated(time) - test_03_layouting(time) + # test_03_layouting(time) + test_04_lots_of_texts(time) checkVkResult vkDeviceWaitIdle(vulkan.device)