diff options
author | WormHeamer | 2025-07-18 20:41:42 -0400 |
---|---|---|
committer | WormHeamer | 2025-07-18 20:41:42 -0400 |
commit | cc0ca67cfe3397d73c810f7f04817b7cba4c9ed4 (patch) | |
tree | 9f2d5079d00808948c4fa738ae2c417009d90b07 /sdl_gpu_test.c | |
parent | c796b74bba315d4b2f14c6433ffa038dd87a4e04 (diff) |
pass in uniform camera matrix
Diffstat (limited to 'sdl_gpu_test.c')
-rw-r--r-- | sdl_gpu_test.c | 202 |
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); |