summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-07-18 20:41:42 -0400
committerWormHeamer2025-07-18 20:41:42 -0400
commitcc0ca67cfe3397d73c810f7f04817b7cba4c9ed4 (patch)
tree9f2d5079d00808948c4fa738ae2c417009d90b07
parentc796b74bba315d4b2f14c6433ffa038dd87a4e04 (diff)
pass in uniform camera matrix
-rw-r--r--sdl_gpu_test.c202
1 files changed, 119 insertions, 83 deletions
diff --git a/sdl_gpu_test.c b/sdl_gpu_test.c
index d77e137..8bc6b73 100644
--- a/sdl_gpu_test.c
+++ b/sdl_gpu_test.c
@@ -1,8 +1,9 @@
-/* sdl_gpu_test.c -- -lSDL3 */
+/* sdl_gpu_test.c -- -lSDL3 -lm */
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_gpu.h>
+#include <math.h>
#include <stdio.h>
#include <err.h>
@@ -12,25 +13,36 @@ SDL_GPUGraphicsPipeline *pipeline_fill;
SDL_GPUBuffer *buf_vert;
SDL_GPUTransferBuffer *buf_vert_xfer;
-float vertices[][2] = {
- { 0.5, -0.5 },
- { 0.5, 0.5 },
- { -0.5, -0.5 },
+typedef struct {
+ float x, y;
+ float u, v;
+} Vertex;
+
+Vertex vertices[] = {
+ { -1, -1, 0, 0, },
+ { 0, -1, 1, 0, },
+ { 0, 0, 1, 1, },
+
+ { -1, -1, 0, 0, },
+ { -1, 0, 0, 1, },
+ { 0, 0, 1, 1, },
+
+ { 0, 0, 0, 0, },
+ { 1, 0, 1, 0, },
+ { 1, 1, 1, 1, },
+
+ { 0, 0, 0, 0, },
+ { 0, 1, 0, 1, },
+ { 1, 1, 1, 1, },
- { -0.5, -0.5 },
- { -0.5, 0.5 },
- { 0.5, 0.5 },
};
-SDL_GPUShader* load_shader(
- SDL_GPUDevice* dev,
- const char *path,
- SDL_GPUShaderStage stage,
- Uint32 samplers,
- Uint32 uniformbufs,
- Uint32 storagebufs,
- Uint32 storagetextures)
-{
+typedef struct {
+ SDL_GPUShaderStage stage;
+ Uint32 n_sampler, n_uniformbuf, n_storagebuf, n_storagetex;
+} ShaderDesc;
+
+SDL_GPUShader* load_shader(SDL_GPUDevice* dev, const char *path, ShaderDesc *desc) {
size_t code_size;
void *code = SDL_LoadFile(path, &code_size);
if (!code) {
@@ -38,24 +50,19 @@ SDL_GPUShader* load_shader(
return NULL;
}
- SDL_GPUShaderCreateInfo info = {
+ SDL_GPUShader *sh = SDL_CreateGPUShader(dev, &(SDL_GPUShaderCreateInfo) {
.code = code,
.code_size = code_size,
.entrypoint = "main",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
- .stage = stage,
- .num_samplers = samplers,
- .num_uniform_buffers = uniformbufs,
- .num_storage_buffers = storagebufs,
- .num_storage_textures = storagetextures
- };
-
- SDL_GPUShader *sh = SDL_CreateGPUShader(dev, &info);
- if (!sh) {
- fprintf(stderr, "failed to create shader: %s\n", SDL_GetError());
- return NULL;
- }
-
+ .stage = desc->stage,
+ .num_samplers = desc->n_sampler,
+ .num_uniform_buffers = desc->n_uniformbuf,
+ .num_storage_buffers = desc->n_storagebuf,
+ .num_storage_textures = desc->n_storagetex
+ });
+
+ if (!sh) return NULL;
SDL_free(code);
return sh;
}
@@ -73,25 +80,30 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
CHECK(gpudev, "failed to create gpu device");
CHECK(SDL_ClaimWindowForGPUDevice(gpudev, win), "failed to claim window");
- SDL_GPUShader *shader_vert = load_shader(gpudev, "shader/tri.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0, 0, 0);
+ SDL_GPUShader *shader_vert = load_shader(gpudev, "shader/tri.vert.spv", &(ShaderDesc) {
+ .stage = SDL_GPU_SHADERSTAGE_VERTEX,
+ .n_uniformbuf = 1
+ });
CHECK(shader_vert, "load vertex shader");
- SDL_GPUShader *shader_frag = load_shader(gpudev, "shader/tri.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 0, 0, 0, 0);
+ SDL_GPUShader *shader_frag = load_shader(gpudev, "shader/tri.frag.spv", &(ShaderDesc) { SDL_GPU_SHADERSTAGE_FRAGMENT });
CHECK(shader_frag, "load fragment shader");
- SDL_GPUBufferCreateInfo buf_desc = {
+ buf_vert = SDL_CreateGPUBuffer(gpudev, &(SDL_GPUBufferCreateInfo) {
.usage = SDL_GPU_BUFFERUSAGE_VERTEX,
.size = sizeof(vertices),
.props = 0
- };
- buf_vert = SDL_CreateGPUBuffer(gpudev, &buf_desc);
+ });
CHECK(buf_vert, "vertex buffer");
- SDL_GPUTransferBufferCreateInfo buf_xfer_desc = {
- .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
- .size = sizeof(buf_vert),
- .props = 0
- };
- buf_vert_xfer = SDL_CreateGPUTransferBuffer(gpudev, &buf_xfer_desc);
+ buf_vert_xfer = SDL_CreateGPUTransferBuffer(
+ gpudev,
+ &(SDL_GPUTransferBufferCreateInfo) {
+ .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
+ .size = sizeof(vertices),
+ .props = 0
+ }
+ );
+
CHECK(buf_vert_xfer, "vertex transfer buffer");
void *map = SDL_MapGPUTransferBuffer(gpudev, buf_vert_xfer, false);
@@ -103,27 +115,38 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
SDL_GPUCopyPass *copypass = SDL_BeginGPUCopyPass(cmdbuf);
CHECK(copypass, "gpu copy pass");
- SDL_GPUTransferBufferLocation src = {
- .transfer_buffer = buf_vert_xfer,
- .offset = 0
- };
-
- SDL_GPUBufferRegion dest = {
- .buffer = buf_vert,
- .offset = 0,
- .size = sizeof(vertices)
- };
+ SDL_UploadToGPUBuffer(
+ copypass,
+ &(SDL_GPUTransferBufferLocation) {
+ .transfer_buffer = buf_vert_xfer,
+ .offset = 0
+ },
+ &(SDL_GPUBufferRegion) {
+ .buffer = buf_vert,
+ .offset = 0,
+ .size = sizeof(vertices)
+ },
+ false
+ );
- SDL_UploadToGPUBuffer(copypass, &src, &dest, false);
SDL_EndGPUCopyPass(copypass);
SDL_SubmitGPUCommandBuffer(cmdbuf);
SDL_ReleaseGPUTransferBuffer(gpudev, buf_vert_xfer);
- SDL_GPUGraphicsPipelineCreateInfo pipeline_info = {
+ pipeline_fill = SDL_CreateGPUGraphicsPipeline(gpudev, &(SDL_GPUGraphicsPipelineCreateInfo) {
.target_info = {
.num_color_targets = 1,
.color_target_descriptions = (SDL_GPUColorTargetDescription[]) {{
- .format = SDL_GetGPUSwapchainTextureFormat(gpudev, win)
+ .format = SDL_GetGPUSwapchainTextureFormat(gpudev, win),
+ .blend_state = {
+ .enable_blend = true,
+ .color_blend_op = SDL_GPU_BLENDOP_ADD,
+ .alpha_blend_op = SDL_GPU_BLENDOP_ADD,
+ .src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
+ .dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
+ .src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
+ .dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
+ }
}},
},
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
@@ -133,25 +156,32 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
.num_vertex_buffers = 1,
.vertex_buffer_descriptions = &(SDL_GPUVertexBufferDescription) {
.slot = 0,
- .pitch = sizeof(float) * 2,
+ .pitch = sizeof(Vertex),
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0,
},
- .num_vertex_attributes = 1,
+ .num_vertex_attributes = 2,
.vertex_attributes = (SDL_GPUVertexAttribute[]) {
{
.location = 0,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 0
+ },
+ {
+ .location = 1,
+ .buffer_slot = 0,
+ .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
+ .offset = sizeof(float) * 2
}
}
},
+ .rasterizer_state = {
+ .fill_mode = SDL_GPU_FILLMODE_FILL
+ },
.props = 0
- };
+ });
- pipeline_info.rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL;
- pipeline_fill = SDL_CreateGPUGraphicsPipeline(gpudev, &pipeline_info);
CHECK(pipeline_fill, "graphics pipeline");
SDL_ReleaseGPUShader(gpudev, shader_frag);
@@ -176,33 +206,39 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
(void)appstate;
SDL_GPUCommandBuffer *cmdbuf = SDL_AcquireGPUCommandBuffer(gpudev);
- if (!cmdbuf) {
- fprintf(stderr, "failed to acquire GPU command buffer: %s\n", SDL_GetError());
- return SDL_APP_FAILURE;
- }
+ CHECK(cmdbuf, "gpu cmd buffer acquisition");
SDL_GPUTexture *swapchain;
- if (!SDL_WaitAndAcquireGPUSwapchainTexture(cmdbuf, win, &swapchain, NULL, NULL)) {
- fprintf(stderr, "failed to acquire swapchain texture: %s\n", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- if (!swapchain) {
- fprintf(stderr, "null swapchain texture: %s\n", SDL_GetError());
- SDL_SubmitGPUCommandBuffer(cmdbuf);
- return SDL_APP_FAILURE;
- }
-
- SDL_GPUColorTargetInfo color_target_info = { 0 };
- color_target_info.texture = swapchain;
- color_target_info.clear_color = (SDL_FColor) { 0, 0, 0, 1 };
- color_target_info.load_op = SDL_GPU_LOADOP_CLEAR;
- color_target_info.store_op = SDL_GPU_STOREOP_STORE;
-
- SDL_GPURenderPass *render_pass = SDL_BeginGPURenderPass(cmdbuf, &color_target_info, 1, NULL);
+ Uint32 swc_width, swc_height;
+ CHECK(SDL_WaitAndAcquireGPUSwapchainTexture(cmdbuf, win, &swapchain, &swc_width, &swc_height), "swapchain texture acquisition");
+ CHECK(swapchain, "nil swapchain texture");
+
+ float how = (float)swc_height / (float)swc_width;
+ float woh = (float)swc_width / (float)swc_height;
+ float scale = (32 * 2) / fminf(swc_width, swc_height);
+ float scale_x = (swc_height < swc_width ? how : 1) * scale;
+ float scale_y = (swc_height < swc_width ? 1 : woh) * scale;
+ float cam_mat[4][4] = {
+ { scale_x, 0, 0, 0, },
+ { 0, scale_y, 0, 0, },
+ { 0, 0, 1, 0, },
+ { 0, 0, 0, 1, },
+ };
+ SDL_PushGPUVertexUniformData(cmdbuf, 0, &cam_mat, sizeof(cam_mat));
+ SDL_GPURenderPass *render_pass = SDL_BeginGPURenderPass(
+ cmdbuf,
+ &(SDL_GPUColorTargetInfo) {
+ .texture = swapchain,
+ .clear_color = { 0, 0, 0, 1 },
+ .load_op = SDL_GPU_LOADOP_CLEAR,
+ .store_op = SDL_GPU_STOREOP_STORE,
+ },
+ 1,
+ NULL
+ );
SDL_BindGPUGraphicsPipeline(render_pass, pipeline_fill);
SDL_BindGPUVertexBuffers(render_pass, 0, &(SDL_GPUBufferBinding) { .buffer = buf_vert, .offset = 0 }, 1);
- SDL_DrawGPUPrimitives(render_pass, sizeof(vertices) / (sizeof(float)*2), 1, 0, 0);
+ SDL_DrawGPUPrimitives(render_pass, sizeof(vertices) / sizeof(Vertex), 1, 0, 0);
SDL_EndGPURenderPass(render_pass);
SDL_SubmitGPUCommandBuffer(cmdbuf);