// Tell SDL that we will use the callback-based main system (SDL_AppInit, SDL_AppIterate, etc.)
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>
// Global handles for the window and GPU device.
// In a real engine you would wrap these in a class.
SDL_Window* window;
SDL_GPUDevice* device;
/*
SDL_AppInit
-----------
Called once at startup. This replaces your traditional main() when using SDL_MAIN_USE_CALLBACKS.
*/
SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
{
// Create a resizable window.
// SDL3 removed the old width/height positional parameters; now it's (title, w, h, flags).
window = SDL_CreateWindow(
"clear a window to some color with SDL_GPU",
960, 540,
SDL_WINDOW_RESIZABLE
);
// Create a GPU device.
// SDL_GPU_SHADERFORMAT_SPIRV means we want Vulkan-style SPIR‑V shaders.
// The second parameter (false) means "do not use debug mode".
// The last parameter is a SDL_GPUDeviceProperties struct (NULL = default).
device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, false, NULL);
// Bind the window to the GPU device so it can present frames.
SDL_ClaimWindowForGPUDevice(device, window);
return SDL_APP_CONTINUE;
}
/*
SDL_AppIterate
--------------
Called every frame. This is the main loop.
*/
SDL_AppResult SDL_AppIterate(void* appstate)
{
// Acquire a command buffer for this frame.
// All GPU work must be recorded into a command buffer.
SDL_GPUCommandBuffer* commandBuffer = SDL_AcquireGPUCommandBuffer(device);
// Acquire the swapchain texture (the backbuffer we will render into).
SDL_GPUTexture* swapchainTexture;
Uint32 width, height;
// This waits for the swapchain to be ready and gives us the texture.
SDL_WaitAndAcquireGPUSwapchainTexture(
commandBuffer,
window,
&swapchainTexture,
&width,
&height
);
// If no swapchain texture is available, we must still submit the command buffer.
if (swapchainTexture == NULL)
{
SDL_SubmitGPUCommandBuffer(commandBuffer);
return SDL_APP_CONTINUE;
}
// Describe the color target (Green) for the render pass.
SDL_GPUColorTargetInfo colorTargetInfo{};
colorTargetInfo.clear_color = {
89.0f / 255.0f, // R
179.0f / 255.0f, // G
0.0f, // B
1.0f // A
};
colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; // Clear the texture at start
colorTargetInfo.store_op = SDL_GPU_STOREOP_STORE; // Store the result so it can be presented
colorTargetInfo.texture = swapchainTexture; // The swapchain backbuffer
// Begin a render pass.
// A render pass is where you issue draw calls.
SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(
commandBuffer,
&colorTargetInfo,
1, // number of color targets
NULL // no depth/stencil target
);
// --- DRAW CALLS WOULD GO HERE ---
// For example: SDL_IssueGPUDraw(...)
// End the render pass.
SDL_EndGPURenderPass(renderPass);
// Submit the command buffer so the GPU executes it.
SDL_SubmitGPUCommandBuffer(commandBuffer);
return SDL_APP_CONTINUE;
}
/*
SDL_AppEvent
------------
Called for every SDL event.
*/
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
{
// If the user tries to close the window, exit the app.
if (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED)
{
return SDL_APP_SUCCESS;
}
return SDL_APP_CONTINUE;
}
/*
SDL_AppQuit
-----------
Called once when the app is shutting down.
*/
void SDL_AppQuit(void* appstate, SDL_AppResult result)
{
// Destroy the GPU device first.
SDL_DestroyGPUDevice(device);
// Then destroy the window.
SDL_DestroyWindow(window);
}
/*
run:
*/