SBgl 0.1.0
A graphics framework in C99
Loading...
Searching...
No Matches
voxel3D_main.c
Go to the documentation of this file.
1
6#include "sbgl.h"
7#include "sbgl_camera.h"
8#include "sbgl_math.h"
9#include "sbgl_voxel.h"
10#include <stdio.h>
11#include "voxel3D_vert.h"
12#include "voxel3D_frag.h"
13
23
24int main(void) {
25 /*
26 * Initialize the SBgl framework with a standard window configuration.
27 */
28 sbgl_InitResult res = sbgl_Init(1280, 720, "SBgl Zero-Sync Infinite Voxels");
29 if (res.error != SBGL_SUCCESS) {
30 return 1;
31 }
32 sbgl_Context* ctx = res.ctx;
33
34 /*
35 * Create the voxel system. This encapsulates all GPU resource management,
36 * compute pipelines, and chunk management logic.
37 */
38 sbgl_VoxelConfig vConfig = { .max_slots = 256, .chunk_radius = 3, .enable_telemetry = true };
39 sbgl_VoxelSystem* voxelSys = sbgl_Voxel_Create(ctx, &vConfig);
40
41 if (!voxelSys) {
42 fprintf(stderr, "Failed to initialize VoxelSystem\n");
43 sbgl_Shutdown(ctx);
44 return 1;
45 }
46
47 /*
48 * Load the shaders for the final rendering pass.
49 * Note: The compute shaders are managed internally by the voxel system.
50 */
51 sbgl_Shader vertShader =
52 sbgl_LoadShader(ctx, SBGL_SHADER_STAGE_VERTEX, (const uint32_t*)voxel3D_vert_spv, voxel3D_vert_spv_len);
53 sbgl_Shader fragShader =
54 sbgl_LoadShader(ctx, SBGL_SHADER_STAGE_FRAGMENT, (const uint32_t*)voxel3D_frag_spv, voxel3D_frag_spv_len);
55
56 if (vertShader == SBGL_INVALID_HANDLE || fragShader == SBGL_INVALID_HANDLE) {
57 fprintf(stderr, "Failed to load graphics shaders\n");
58 sbgl_Voxel_Destroy(voxelSys);
59 sbgl_Shutdown(ctx);
60 return 1;
61 }
62
63 /*
64 * Configure the graphics pipeline for voxel rendering.
65 */
67 ctx,
68 &(sbgl_PipelineConfig){ .vertexShader = vertShader, .fragmentShader = fragShader }
69 );
70
71 if (renderPipe == SBGL_INVALID_HANDLE) {
72 fprintf(stderr, "Failed to create graphics pipeline\n");
73 sbgl_Voxel_Destroy(voxelSys);
74 sbgl_Shutdown(ctx);
75 return 1;
76 }
77
78 /*
79 * Create a simple index buffer for the unit cube.
80 * This is used as the geometry template for all voxel instances.
81 */
82 uint32_t idxs[36];
83 for (uint32_t i = 0; i < 36; i++)
84 idxs[i] = i;
85 sbgl_Buffer iBuf = sbgl_CreateBuffer(ctx, SBGL_BUFFER_USAGE_INDEX, sizeof(idxs), idxs);
86
87 /*
88 * Setup the interactive camera system.
89 */
90 sbgl_Camera camera = sbgl_CameraPerspective(0.8f, 1280.0f / 720.0f, 0.1f, 10000.0f);
91 camera.position = sbgl_Vec3Set(0.0f, 400.0f, -800.0f);
92 camera.target = sbgl_Vec3Set(0.0f, 128.0f, 0.0f);
93
94 float pitch = -0.4f, yaw = SBGL_PI / 2.0f;
95 bool mouseLocked = false;
96 float moveSpeed = 400.0f, sensitivity = 0.005f;
97 double lastTime = sbgl_GetTime(ctx);
98
99 printf("--- Voxel Controls ---\n");
100 printf("W/A/S/D: Move\n");
101 printf("Q/E: Vertical Move\n");
102 printf("TAB: Lock/Unlock Mouse\n");
103 printf("ESC: Exit\n");
104 printf("----------------------\n");
105
106 while (!sbgl_WindowShouldClose(ctx)) {
107 double currentTime = sbgl_GetTime(ctx);
108 float dt = (float)(currentTime - lastTime);
109 lastTime = currentTime;
110
111 /* Ensure event polling and GPU command buffer start happen before input query */
113
114 const sbgl_InputState* input = sbgl_GetInputState(ctx);
115 if (input->keysDown[SBGL_KEY_ESCAPE])
116 break;
117
118 /* Handle Mouse Locking */
119 if (input->keysPressed[SBGL_KEY_TAB]) {
120 mouseLocked = !mouseLocked;
122 }
123
124 /* Update Camera Orientation */
125 if (mouseLocked) {
126 yaw += (float)input->mouseDeltaX * sensitivity;
127 pitch -= (float)input->mouseDeltaY * sensitivity;
128 if (pitch > 1.5f)
129 pitch = 1.5f;
130 if (pitch < -1.5f)
131 pitch = -1.5f;
132 }
133
135 sbgl_Vec3Set(cosf(yaw) * cosf(pitch), sinf(pitch), sinf(yaw) * cosf(pitch))
136 );
138 float velocity = moveSpeed * dt;
139
140 /* Handle Movement */
141 if (input->keysDown[SBGL_KEY_W])
142 camera.position = sbgl_Vec3Add(camera.position, sbgl_Vec3Mul(front, velocity));
143 if (input->keysDown[SBGL_KEY_S])
144 camera.position = sbgl_Vec3Sub(camera.position, sbgl_Vec3Mul(front, velocity));
145 if (input->keysDown[SBGL_KEY_A])
146 camera.position = sbgl_Vec3Sub(camera.position, sbgl_Vec3Mul(right, velocity));
147 if (input->keysDown[SBGL_KEY_D])
148 camera.position = sbgl_Vec3Add(camera.position, sbgl_Vec3Mul(right, velocity));
149 if (input->keysDown[SBGL_KEY_Q])
150 camera.position.y -= velocity;
151 if (input->keysDown[SBGL_KEY_E])
152 camera.position.y += velocity;
153
154 camera.target = sbgl_Vec3Add(camera.position, front);
155 camera.up = sbgl_Vec3Normalize(sbgl_Vec3Cross(right, front));
156
157 int width, height;
158 sbgl_GetWindowSize(ctx, &width, &height);
159 camera.aspect = (float)width / (float)height;
160
161 sbgl_Mat4 viewProj =
163
164 /*
165 * Perform the voxel system update.
166 * This dispatches compute shaders only if the camera crosses a chunk boundary.
167 */
168 sbgl_Voxel_Update(voxelSys, camera.position);
169
170 /*
171 * Perform GPU-driven culling before starting the graphics pass.
172 */
173 sbgl_Voxel_Cull(voxelSys, viewProj);
174
175 /*
176 * Clear the framebuffer and begin the graphics pass.
177 */
178 sbgl_Clear(ctx, 0.5f, 0.7f, 1.0f, 1.0f);
180
181 /* Bind the rendering pipeline and geometry */
182 sbgl_BindPipeline(ctx, renderPipe);
184
185 /* Setup graphics push constants using addresses retrieved from the voxel system */
186 RenderPushConstants rpc = { .viewProj = viewProj,
187 .aabbAddress = sbgl_Voxel_GetAABBAddress(voxelSys),
188 .voxelDataAddress = sbgl_Voxel_GetInstanceAddress(voxelSys),
189 .paletteAddress = sbgl_Voxel_GetPaletteAddress(voxelSys) };
190 sbgl_PushConstants(ctx, sizeof(rpc), &rpc);
191
192 /* Dispatch the voxel rendering commands (Graphics pass only) */
193 sbgl_Voxel_Render(voxelSys);
194
195 sbgl_EndDrawing(ctx);
196 }
197
198 /*
199 * Gracefully release all resources before shutting down.
200 */
202 sbgl_Voxel_Destroy(voxelSys);
203 sbgl_DestroyPipeline(ctx, renderPipe);
204 sbgl_DestroyShader(ctx, vertShader);
205 sbgl_DestroyShader(ctx, fragShader);
206 sbgl_DestroyBuffer(ctx, iBuf);
207 sbgl_Shutdown(ctx);
208
209 return 0;
210}
@ SBGL_MOUSE_MODE_NORMAL
Definition sbgl_input.h:154
@ SBGL_MOUSE_MODE_CAPTURED
Definition sbgl_input.h:156
API for the SiputBiru Graphics Library (SBgl).
#define SBGL_KEY_A
Definition sbgl.h:42
sbgl_InitResult sbgl_Init(int w, int h, const char *title)
Initializes the engine and opens a window.
Definition sbgl_core.c:193
#define SBGL_KEY_E
Definition sbgl.h:46
void sbgl_GetWindowSize(sbgl_Context *ctx, int *w, int *h)
Retrieves the current window dimensions.
Definition sbgl_core.c:252
bool sbgl_WindowShouldClose(sbgl_Context *ctx)
Checks if the user or OS has requested to close the window.
Definition sbgl_core.c:238
const sbgl_InputState * sbgl_GetInputState(sbgl_Context *ctx)
Retrieves the input state for the current frame.
Definition sbgl_core.c:413
sbgl_Pipeline sbgl_CreatePipeline(sbgl_Context *ctx, const sbgl_PipelineConfig *config)
Creates a graphics pipeline.
Definition sbgl_core.c:587
#define SBGL_KEY_S
Definition sbgl.h:60
void sbgl_DestroyShader(sbgl_Context *ctx, sbgl_Shader shader)
Destroys a shader module.
Definition sbgl_core.c:565
sbgl_Shader sbgl_LoadShader(sbgl_Context *ctx, sbgl_ShaderStage stage, const uint32_t *bytecode, size_t size)
Loads a shader from SPIR-V bytecode.
Definition sbgl_core.c:523
void sbgl_SetMouseMode(sbgl_Context *ctx, sbgl_MouseMode mode)
Sets the cursor behavior and visibility.
Definition sbgl_core.c:422
void sbgl_PushConstants(sbgl_Context *ctx, size_t size, const void *data)
Updates push constants for the currently bound pipeline.
Definition sbgl_core.c:733
void sbgl_EndDrawing(sbgl_Context *ctx)
Finalizes the current frame and presents it to the screen.
Definition sbgl_core.c:315
#define SBGL_KEY_ESCAPE
Definition sbgl.h:84
#define SBGL_KEY_D
Definition sbgl.h:45
void sbgl_BindPipeline(sbgl_Context *ctx, sbgl_Pipeline pipeline)
Binds a graphics pipeline for subsequent draw calls.
Definition sbgl_core.c:673
#define SBGL_KEY_Q
Definition sbgl.h:58
#define sbgl_Clear
Backward compatibility alias for sbgl_SetClearColor.
Definition sbgl.h:229
void sbgl_DestroyBuffer(sbgl_Context *ctx, sbgl_Buffer buffer)
Destroys a GPU buffer.
Definition sbgl_core.c:457
void sbgl_BeginCompute(sbgl_Context *ctx)
Prepares the engine for compute operations before the main drawing pass.
Definition sbgl_core.c:344
#define SBGL_KEY_TAB
Definition sbgl.h:86
void sbgl_DeviceWaitIdle(sbgl_Context *ctx)
Synchronizes the CPU with the GPU, waiting for all commands to complete.
Definition sbgl_core.c:391
double sbgl_GetTime(sbgl_Context *ctx)
Retrieves the current monotonic system time in seconds.
Definition sbgl_core.c:245
void sbgl_Shutdown(sbgl_Context *ctx)
Gracefully shuts down the engine and releases all resources.
Definition sbgl_core.c:204
void sbgl_BeginDrawing(sbgl_Context *ctx)
Prepares the engine for a new frame of drawing.
Definition sbgl_core.c:262
void sbgl_BindBuffer(sbgl_Context *ctx, sbgl_Buffer buffer, sbgl_BufferUsage usage)
Binds a buffer to the pipeline.
Definition sbgl_core.c:681
#define SBGL_KEY_W
Definition sbgl.h:64
void sbgl_DestroyPipeline(sbgl_Context *ctx, sbgl_Pipeline pipeline)
Destroys a graphics pipeline.
Definition sbgl_core.c:597
sbgl_Buffer sbgl_CreateBuffer(sbgl_Context *ctx, sbgl_BufferUsage usage, size_t size, const void *data)
Creates a GPU buffer.
Definition sbgl_core.c:445
Camera system and batch collision math for SBgl.
static sbgl_Camera sbgl_CameraPerspective(float fov_y_rad, float aspect, float near_p, float far_p)
Initializes a camera with perspective projection.
Definition sbgl_camera.h:86
static sbgl_Mat4 sbgl_CameraGetProjection(const sbgl_Camera *cam)
Computes the projection matrix for the given camera.
static sbgl_Mat4 sbgl_CameraGetView(const sbgl_Camera *cam)
Computes the view matrix for the given camera.
Single-header math library for SBgl.
static sbgl_Vec3 sbgl_Vec3Set(float x, float y, float z)
Creates a Vec3, correctly padded.
Definition sbgl_math.h:93
static sbgl_Vec3 sbgl_Vec3Add(sbgl_Vec3 a, sbgl_Vec3 b)
Adds two Vec3 vectors.
Definition sbgl_math.h:132
static sbgl_Vec3 sbgl_Vec3Mul(sbgl_Vec3 a, float s)
Multiplies a Vec3 by a scalar.
Definition sbgl_math.h:142
#define SBGL_PI
Definition sbgl_math.h:22
static sbgl_Mat4 sbgl_Mat4Mul(sbgl_Mat4 a, sbgl_Mat4 b)
Multiplies two matrices.
Definition sbgl_math.h:240
static sbgl_Vec3 sbgl_Vec3Cross(sbgl_Vec3 a, sbgl_Vec3 b)
Computes the cross product of two Vec3 vectors.
Definition sbgl_math.h:152
static sbgl_Vec3 sbgl_Vec3Normalize(sbgl_Vec3 v)
Normalizes a Vec3.
Definition sbgl_math.h:162
static sbgl_Vec3 sbgl_Vec3Sub(sbgl_Vec3 a, sbgl_Vec3 b)
Subtracts b from a.
Definition sbgl_math.h:137
@ SBGL_BUFFER_USAGE_INDEX
Definition sbgl_types.h:124
@ SBGL_SUCCESS
Definition sbgl_types.h:215
uint32_t sbgl_Buffer
Handle for a GPU-side buffer.
Definition sbgl_types.h:37
uint32_t sbgl_Shader
Handle for a shader module.
Definition sbgl_types.h:42
@ SBGL_SHADER_STAGE_FRAGMENT
Definition sbgl_types.h:135
@ SBGL_SHADER_STAGE_VERTEX
Definition sbgl_types.h:134
uint32_t sbgl_Pipeline
Handle for a graphics pipeline.
Definition sbgl_types.h:47
#define SBGL_INVALID_HANDLE
Definition sbgl_types.h:8
Public API for the SBgl voxel rendering system.
uint64_t sbgl_Voxel_GetInstanceAddress(sbgl_VoxelSystem *sys)
Returns the device address of the instance buffer.
Definition sbgl_voxel.c:563
void sbgl_Voxel_Cull(sbgl_VoxelSystem *sys, sbgl_Mat4 view_proj)
Performs GPU-driven frustum culling on voxel chunks. MUST be called BEFORE sbgl_BeginDrawing.
Definition sbgl_voxel.c:436
uint64_t sbgl_Voxel_GetPaletteAddress(sbgl_VoxelSystem *sys)
Returns the device address of the material palette buffer.
Definition sbgl_voxel.c:568
uint64_t sbgl_Voxel_GetAABBAddress(sbgl_VoxelSystem *sys)
Returns the device address of the AABB buffer.
Definition sbgl_voxel.c:558
void sbgl_Voxel_Update(sbgl_VoxelSystem *sys, sbgl_Vec3 camera_pos)
Updates the voxel system state based on the current camera position. This function handles chunk gene...
Definition sbgl_voxel.c:286
void sbgl_Voxel_Render(sbgl_VoxelSystem *sys)
Issues the indirect draw calls for visible voxel chunks. MUST be called BETWEEN sbgl_BeginDrawing and...
Definition sbgl_voxel.c:487
void sbgl_Voxel_Destroy(sbgl_VoxelSystem *sys)
Destroys the voxel system and releases all associated resources.
Definition sbgl_voxel.c:525
sbgl_VoxelSystem * sbgl_Voxel_Create(sbgl_Context *ctx, const sbgl_VoxelConfig *config)
Creates and initializes a new voxel system. This operation allocates GPU resources and internal track...
Definition sbgl_voxel.c:143
Push constants for the graphics pipeline.
uint64_t voxelDataAddress
Stateful camera representation.
Definition sbgl_camera.h:27
sbgl_Vec3 target
Definition sbgl_camera.h:31
sbgl_Vec3 up
Definition sbgl_camera.h:32
sbgl_Vec3 position
Definition sbgl_camera.h:30
Engine context.
Definition sbgl_types.h:268
Result structure for initialization.
Definition sbgl_types.h:339
sbgl_Context * ctx
Definition sbgl_types.h:340
sbgl_Result error
Definition sbgl_types.h:341
Represents the real-time state of physical inputs.
Definition sbgl_input.h:165
bool keysPressed[SBGL_SCANCODE_MAX]
Definition sbgl_input.h:167
bool keysDown[SBGL_SCANCODE_MAX]
Definition sbgl_input.h:166
4x4 Matrix, 16-byte aligned, column-major.
Definition sbgl_math.h:83
Configuration for creating a graphics pipeline.
Definition sbgl_types.h:204
Configuration parameters for initializing the voxel system.
Definition sbgl_voxel.h:21
Internal state for the voxel system. This structure adheres to Data-Oriented Design principles by mai...
Definition sbgl_voxel.c:70
3D Vector, 16-byte aligned and padded for SIMD safety.
Definition sbgl_math.h:49
float y
Definition sbgl_math.h:52
int main(void)