comparison README.md @ 1266:9e4dc93d4fa9

did: completely rewrite readme
author sam <sam@basx.dev>
date Sun, 28 Jul 2024 22:50:22 +0700
parents f8974736e446
children 4cf9872f7bb6
comparison
equal deleted inserted replaced
1265:51348a4abefc 1266:9e4dc93d4fa9
1 Note: If you are reading this on Github, please not that this is only a mirror 1 Note: If you are reading this on Github, please not that this is only a mirror
2 repository and the default branch is ```hg```. 2 repository and the newest code is hosted on my mercurial repository at
3 3 https://hg.basx.dev/games/semicongine/.
4 Also, some of the README is a bit out of date, as I am now focusing mostly on
5 writing my first game. However, developement ist onging and the documentation
6 will be overhauled once I start working on my next game.
7 4
8 # Semicongine 5 # Semicongine
9 6
10 Hi there 7 Hi there
11 8
12 This is a little game engine, mainly trying to wrap around vulkan and the 9 This is a little game engine, mainly trying to wrap around vulkan and the
13 operating system's windowing, input and audio system. I am using the last 10 operating system's windowing, input and audio system. I am using the last
14 programming language you will ever need, [Nim](https://nim-lang.org/) 11 programming language you will ever need, [Nim](https://nim-lang.org/)
15 12
13 ## Features
14
15 The engine currently features the following:
16
17 - No dependencies outside of this repo (except zip/unzip on Linux). All
18 dependencies are included.
19 - Low-level, Vulkan-base rendering system
20 - All vertex/uniform/descriptors/shader-formats, shaders can and must be
21 defined "freely". The only restriction that we currently have, is that vertex
22 data is non-interleaved.
23 - A ton of compiletime checks to ensure the defined mesh-data and shaders are
24 compatible for rendering
25 - Simple audio mixer, should suffice for most things
26 - Simple input-system, no controller support at this time
27 - Resource packaging of images, audio and 3D files.
28 - A few additional utils like a simple storage API, a few algorithms for
29 collision detection, noise generation and texture packing, and a simple
30 settings API with hot-reloading
31
32 ## Hello world example
33
34 Attention, this project is not optimized for "hello world"-scenarios, so you
35 have quite a few lines to get something to display:
36
37 ```
38
39 import semicongine
40
41 # required
42 InitVulkan()
43
44 # set up a simple render pass to render the displayed frame
45 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = false, samples = VK_SAMPLE_COUNT_1_BIT)
46
47 # the swapchain, needs to be attached to the main renderpass
48 SetupSwapchain(renderpass = renderpass)
49
50 # render data is used for memory management on the GPU
51 var renderdata = InitRenderData()
52
53 type
54 # define a push constant, to have something moving
55 PushConstant = object
56 scale: float32
57 # This is how we define shaders: the interface needs to be "typed"
58 # but the shader code itself can freely be written in glsl
59 Shader = object
60 position {.VertexAttribute.}: Vec3f
61 color {.VertexAttribute.}: Vec3f
62 pushConstant {.PushConstantAttribute.}: PushConstant
63 fragmentColor {.Pass.}: Vec3f
64 outColor {.ShaderOutput.}: Vec4f
65 # code
66 vertexCode: string = """void main() {
67 fragmentColor = color;
68 gl_Position = vec4(position * pushConstant.scale, 1);}"""
69 fragmentCode: string = """void main() {
70 outColor = vec4(fragmentColor, 1);}"""
71 # And we also need to define our Mesh, which does describe the vertex layout
72 TriangleMesh = object
73 position: GPUArray[Vec3f, VertexBuffer]
74 color: GPUArray[Vec3f, VertexBuffer]
75
76 # instantiate the mesh and fill with data
77 var mesh = TriangleMesh(
78 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer),
79 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer),
80 )
81
82 # this allocates GPU data, uploads the data to the GPU and flushes any thing that is host-cached
83 # this is a shortcut version, more fine-grained control is possible
84 AssignBuffers(renderdata, mesh)
85 renderdata.FlushAllMemory()
86
87 # Now we need to instantiate the shader as a pipeline object that is attached to a renderpass
88 var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass)
89
90 # the main render-loop will exit if we get a kill-signal from the OS
91 while UpdateInputs():
92
93 # starts the drawing for the next frame and provides us necesseary framebuffer and commandbuffer objects in this scope
94 WithNextFrame(framebuffer, commandbuffer):
95
96 # start the main (and only) renderpass we have, needs to know the target framebuffer and a commandbuffer
97 WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
98
99 # now activate our shader-pipeline
100 WithPipeline(commandbuffer, pipeline):
101
102 # and finally, draw the mesh and set a single parameter
103 # more complicated setups with descriptors/uniforms are of course possible
104 RenderWithPushConstant(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh, pushConstant = PushConstant(scale: 0.3))
105
106 # cleanup
107 checkVkResult vkDeviceWaitIdle(vulkan.device)
108 DestroyPipeline(pipeline)
109 DestroyRenderData(renderdata)
110 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil)
111 DestroyVulkan()
112
113 ```
114
16 ## Roadmap 115 ## Roadmap
17 116
18 Here a bit to see what has been planed and what is done already. Is being 117 For now all features that I need are implemented. I will gradually add more
19 updated frequently (marking those checkboxes just feels to good to stop working). 118 stuff that I need, based on the games that I am developing. Here are a few
119 things that I consider integrating at a later point, once I have gather some
120 more experience what can/should be used across different projects:
20 121
21 Rendering: 122 [ ] More support for glTF format (JPEG textures, animations, morphing)
22 123 [ ] Maybe some often used utils like camera-controllers, offscreen-rendering, shadow-map rendering, etc.
23 - [x] Vertex attributes, vertex data 124 [ ] Maybe some UI-stuff
24 - [x] Shaders (allow for predefined and custom shaders) 125 [ ] Controller support
25 - [x] Uniforms
26 - [x] Per-instance vertex attributes (required to be able to draw scene graph)
27 - [x] Fixed framerate
28 - [x] Instanced drawing (currently can use instance attributes, but we only support a single instance per draw call)
29 - [x] Textures
30 - [x] Materials (vertices with material indices)
31 - [x] Allow different shaders (ie pipelines) for different meshes
32
33 Required for 3D rendering:
34
35 - [ ] Depth buffering
36 - [ ] Mipmaps
37
38 Asset handling:
39
40 - [x] Resource loading - [x] Mod/resource-pack concept - [x] Load from directory - [x] Load from zip - [x] Load from exe-embeded
41 - [x] Mesh/material files (glTF, but incomplete, not all features supported)
42 - [x] Image files (BMP RGBA)
43 - [x] Audio files (AU)
44 - [x] API to transform/recalculate mesh data
45
46 Other (required for alpha release):
47
48 - [x] Config files ala \*.ini files (use std/parsecfg)
49 - [x] Mouse/Keyboard input handling
50 - [x] X11
51 - [x] Win32
52 - [x] Enable/disable hardware cursor
53 - [x] Fullscreen mode + switch between modes - [x] Linux - [x] Window
54 - [x] Audio playing - [x] Linux - [x] Windows Waveform API
55 - [ ] Generic configuration concept (engine defaults, per-user, etc)
56 - [ ] Input-mapping configuration
57 - [ ] Telemetry
58 - [x] Add simple event logging service
59 - [ ] Add exception reporting
60
61 Other important features:
62
63 - [ ] Multisampling
64 - [x] Text rendering
65 - [x] Animation system
66 - [ ] Sprite system
67 - [ ] Particle system
68 - [ ] Sound-animation
69 - [ ] Paletton-export-loader
70 - [ ] Arrange buffer memory types based on per-mesh-attribute type instead of per-shader-attribute type (possible?)
71
72 Other less important features:
73
74 - [ ] Viewport scaling (e.g. framebuffer resolution != window resolution)
75 - [ ] Query and display rendering information from Vulkan?
76 - [ ] Game controller input handling
77 - [ ] Allow multipel Uniform blocks
78 - [ ] Documentation
79
80 Quality improvments:
81
82 - [x] Better scenegraph API
83 - [x] Better rendering pipeline API
84
85 Build-system:
86
87 - [x] move all of Makefile to config.nims
88
89 # Documentation
90
91 Okay, here is first quick-n-dirty documentation, the only purpose to organize my thoughts a bit.
92
93 ## Engine parts
94
95 Currently we have at least the following:
96
97 - Rendering: rendering.nim vulkan/\*
98 - Scene graph: entity.nim
99 - Audio: audio.nim audiotypes.nim
100 - Input: events.nim
101 - Settings: settings.nim
102 - Meshes: mesh.nim
103 - Math: math/\*
104 - Telemetry: telemetry.nim (wip)
105 - Resources (loading, mods): resources.nim
106
107 Got you: Everything is wip, but (wip) here means work has not started yet.
108
109 ## Handling of assets
110
111 A short description how I want to handle assets.
112
113 Support for file formats (super limited, no external dependencies, uses quite a bit of space, hoping for zip):
114
115 - Images: BMP
116 - Audio: AU
117 - Mesh: glTF (\*.gld)
118
119 In-memory layout of assets (everything needs to be converted to those while loading):
120
121 - Images: 4 channel with each uint8 = 32 bit RGBA, little endian (R is low bits, A is high bits)
122 - Audio: 2 Channel 16 bit signed little endian, 44100Hz
123 - Meshes: non-interleaved, lists of values for each vertex, one list per attribute
124
125 ## Configuration
126
127 Or: How to organize s\*\*t that is not code
128
129 Not sure why, but this feels super important to get done right. The engine is
130 being designed with a library-mindset, not a framework mindset. And with that,
131 ensuring the configuration of the build, runtime and settings in general
132 becomes a bit less straight-forward.
133
134 So here is the idea: There are three to four different kinds of configurations
135 that the engine should be able to handle:
136
137 1. Build configuration: Engine version, project name, log level, etc.
138 2. Runtime engine/project settings: Video/audio settings, telemetry, log-output, etc.
139 3. Mods: Different sets of assets and configuration to allow easy testing of different scenarios
140 4. Save data: Saving world state of the game
141
142 Okay, let's look at each of those and how I plan to implement them:
143
144 **1. Build configuration**
145
146 **2. Runtime settings**
147
148 This is mostly implemented already. I am using the Nim module std/parsecfg.
149 There is also the option to watch the filesystem and update values at runtime,
150 mostly usefull for development.
151
152 The engine scans all files in the settings-root directory and builds a
153 settings tree that can be access via a setting-hierarchy like this:
154
155 setting("a.b.c.d.e")
156
157 `a.b` refers to the settings directory `./a/b/` (from the settings-root)
158 `c` refers to the file `c.ini` inside `./a/b/`
159 `d` refers to the ini-section inside the file `./a/b/c.ini`
160 `e` refers to the key inside section `d` inside the file `./a/b/c.ini`
161
162 `a.b` are optional, they just allow larger configuration trees.
163 `d` is optional, if it is not give, `e` refers to the top-level section
164 of the ini-file.
165
166 **3. Mods**
167
168 A mod is just a collection of resources for a game. Can maybe switched from
169 inside a game. Current mod can be defined via "2. Runtime settings"
170
171 I want to support mods from:
172
173 a) a directory on the filesystem
174 b) a zip-file on the filesystem
175 c) a zip-file that is embeded in the executable
176
177 The reasoning is simple: a) is helpfull for development, testing of
178 new/replaced assets, b) is the default deployment with mod-support and c) is
179 deployment without mod-support, demo-versions and similar.
180
181 Should not be that difficult but give us everything we ever need in terms of
182 resource packaging.
183
184 **4. Save data**
185
186 Not too much thought here yet. Maybe we can use Nim's std/marshal module. It
187 produces JSON from nim objects. Pretty dope, but maybe pretty slow. However, we
188 are indie-JSON here, not 10M of GTA Online JSON:
189 https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/