Mercurial > games > semicongine
annotate README.md @ 1357:b95d19124e90
add: allow manual swapchain recreation, will likely also need another function to pass in a new renderpass
| author | sam <sam@basx.dev> |
|---|---|
| date | Sat, 02 Nov 2024 16:49:09 +0700 |
| parents | 4f1c3994009d |
| children | 0f3f2017b054 |
| rev | line source |
|---|---|
| 922 | 1 Note: If you are reading this on Github, please not that this is only a mirror |
| 1266 | 2 repository and the newest code is hosted on my mercurial repository at |
| 3 https://hg.basx.dev/games/semicongine/. | |
| 922 | 4 |
| 289 | 5 # Semicongine |
| 41 | 6 |
|
926
f8974736e446
did: smile, just for the sake of testing mercurial hooks :)
sam <sam@basx.dev>
parents:
925
diff
changeset
|
7 Hi there |
| 8 | 8 |
|
213
b5d9410a8184
add: resource packaging and loading for different resource types, simplify build commands, update readme
Sam <sam@basx.dev>
parents:
202
diff
changeset
|
9 This is a little game engine, mainly trying to wrap around vulkan and the |
|
b5d9410a8184
add: resource packaging and loading for different resource types, simplify build commands, update readme
Sam <sam@basx.dev>
parents:
202
diff
changeset
|
10 operating system's windowing, input and audio system. I am using the last |
|
b5d9410a8184
add: resource packaging and loading for different resource types, simplify build commands, update readme
Sam <sam@basx.dev>
parents:
202
diff
changeset
|
11 programming language you will ever need, [Nim](https://nim-lang.org/) |
| 41 | 12 |
| 1301 | 13 The (incomplete, autogenerated) API documentation is hosted at <https://semicongine.diademgames.com/>. |
| 14 | |
| 1266 | 15 ## Features |
| 16 | |
| 17 The engine currently features the following: | |
| 18 | |
| 19 - No dependencies outside of this repo (except zip/unzip on Linux). All | |
| 1275 | 20 dependencies are included (`libs` for library dependencies, `tools` for |
| 21 binaries/scripts, `semicongine/thirdparty` for code dependencies) | |
| 1266 | 22 - Low-level, Vulkan-base rendering system |
| 1275 | 23 - All vertex/uniform/descriptors/shader-formats can and must be defined |
| 24 "freely". The only restriction that we currently have, is that vertex data is | |
| 25 non-interleaved. | |
| 1266 | 26 - A ton of compiletime checks to ensure the defined mesh-data and shaders are |
| 27 compatible for rendering | |
| 28 - Simple audio mixer, should suffice for most things | |
| 29 - Simple input-system, no controller support at this time | |
| 1275 | 30 - Resource packaging of images, audio and 3D files as either folders, zip files or embedded in the executable |
| 1267 | 31 - Simple font and text rendering |
| 1266 | 32 - A few additional utils like a simple storage API, a few algorithms for |
| 33 collision detection, noise generation and texture packing, and a simple | |
| 34 settings API with hot-reloading | |
| 35 | |
| 36 ## Hello world example | |
| 37 | |
| 38 Attention, this project is not optimized for "hello world"-scenarios, so you | |
| 1302 | 39 have to write quite a few lines to get something to display: |
| 1266 | 40 |
| 1269 | 41 ```nim |
| 1266 | 42 |
| 43 import semicongine | |
| 44 | |
| 45 # required | |
| 46 InitVulkan() | |
| 47 | |
| 48 # set up a simple render pass to render the displayed frame | |
| 49 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = false, samples = VK_SAMPLE_COUNT_1_BIT) | |
| 50 | |
| 51 # the swapchain, needs to be attached to the main renderpass | |
| 52 SetupSwapchain(renderpass = renderpass) | |
| 53 | |
| 54 # render data is used for memory management on the GPU | |
| 55 var renderdata = InitRenderData() | |
| 56 | |
| 57 type | |
| 58 # define a push constant, to have something moving | |
| 59 PushConstant = object | |
| 60 scale: float32 | |
| 61 # This is how we define shaders: the interface needs to be "typed" | |
| 62 # but the shader code itself can freely be written in glsl | |
| 63 Shader = object | |
| 64 position {.VertexAttribute.}: Vec3f | |
| 65 color {.VertexAttribute.}: Vec3f | |
| 66 pushConstant {.PushConstantAttribute.}: PushConstant | |
| 67 fragmentColor {.Pass.}: Vec3f | |
| 68 outColor {.ShaderOutput.}: Vec4f | |
| 69 # code | |
| 70 vertexCode: string = """void main() { | |
| 71 fragmentColor = color; | |
| 72 gl_Position = vec4(position * pushConstant.scale, 1);}""" | |
| 73 fragmentCode: string = """void main() { | |
| 74 outColor = vec4(fragmentColor, 1);}""" | |
| 75 # And we also need to define our Mesh, which does describe the vertex layout | |
| 76 TriangleMesh = object | |
| 77 position: GPUArray[Vec3f, VertexBuffer] | |
| 78 color: GPUArray[Vec3f, VertexBuffer] | |
| 79 | |
| 80 # instantiate the mesh and fill with data | |
| 81 var mesh = TriangleMesh( | |
| 82 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), | |
| 83 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer), | |
| 84 ) | |
| 85 | |
| 86 # this allocates GPU data, uploads the data to the GPU and flushes any thing that is host-cached | |
| 87 # this is a shortcut version, more fine-grained control is possible | |
| 88 AssignBuffers(renderdata, mesh) | |
| 89 renderdata.FlushAllMemory() | |
| 90 | |
| 91 # Now we need to instantiate the shader as a pipeline object that is attached to a renderpass | |
| 92 var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass) | |
| 93 | |
| 94 # the main render-loop will exit if we get a kill-signal from the OS | |
| 95 while UpdateInputs(): | |
| 96 | |
| 97 # starts the drawing for the next frame and provides us necesseary framebuffer and commandbuffer objects in this scope | |
| 98 WithNextFrame(framebuffer, commandbuffer): | |
| 99 | |
| 100 # start the main (and only) renderpass we have, needs to know the target framebuffer and a commandbuffer | |
| 101 WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)): | |
| 102 | |
| 103 # now activate our shader-pipeline | |
| 104 WithPipeline(commandbuffer, pipeline): | |
| 105 | |
| 106 # and finally, draw the mesh and set a single parameter | |
| 107 # more complicated setups with descriptors/uniforms are of course possible | |
| 108 RenderWithPushConstant(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh, pushConstant = PushConstant(scale: 0.3)) | |
| 109 | |
| 110 # cleanup | |
| 111 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 112 DestroyPipeline(pipeline) | |
| 113 DestroyRenderData(renderdata) | |
| 114 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil) | |
| 115 DestroyVulkan() | |
| 116 | |
| 117 ``` | |
| 118 | |
| 1275 | 119 ## Future development |
| 41 | 120 |
| 1266 | 121 For now all features that I need are implemented. I will gradually add more |
| 122 stuff that I need, based on the games that I am developing. Here are a few | |
| 123 things that I consider integrating at a later point, once I have gather some | |
| 124 more experience what can/should be used across different projects: | |
|
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
187
diff
changeset
|
125 |
| 1269 | 126 - [ ] More support for glTF format (JPEG textures, animations, morphing) |
| 1275 | 127 - [ ] Some often used utils like camera-controllers, offscreen-rendering, shadow-map rendering, etc. |
| 128 - [ ] Some UI-stuff | |
| 1269 | 129 - [ ] Controller support |
