Added support for custom shaders with the GPU renderer

Added an example of MSDF font rendering with the SDL 2D renderer
This commit is contained in:
Sam Lantinga 2025-03-13 16:41:58 -07:00
parent eb56c8af85
commit 2aee105b43
19 changed files with 1460 additions and 34 deletions

View file

@ -59,6 +59,7 @@
#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
@ -2709,6 +2710,117 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetDefaultTextureScaleMode(SDL_Renderer *re
*/
extern SDL_DECLSPEC bool SDLCALL SDL_GetDefaultTextureScaleMode(SDL_Renderer *renderer, SDL_ScaleMode *scale_mode);
/**
* GPU render state description.
*
* This structure should be initialized using SDL_INIT_INTERFACE().
*
* \since This struct is available since SDL 3.4.0.
*
* \sa SDL_CreateGPURenderState
*/
typedef struct SDL_GPURenderStateDesc
{
Uint32 version; /**< the version of this interface */
SDL_GPUShader *fragment_shader; /**< The fragment shader to use when this render state is active */
Sint32 num_sampler_bindings; /**< The number of additional fragment samplers to bind when this render state is active */
const SDL_GPUTextureSamplerBinding *sampler_bindings; /** Additional fragment samplers to bind when this render state is active */
Sint32 num_storage_textures; /**< The number of storage textures to bind when this render state is active */
SDL_GPUTexture *const *storage_textures; /** Storage textures to bind when this render state is active */
Sint32 num_storage_buffers; /**< The number of storage buffers to bind when this render state is active */
SDL_GPUBuffer *const *storage_buffers; /** Storage buffers to bind when this render state is active */
} SDL_GPURenderStateDesc;
/* Check the size of SDL_GPURenderStateDesc
*
* If this assert fails, either the compiler is padding to an unexpected size,
* or the interface has been updated and this should be updated to match and
* the code using this interface should be updated to handle the old version.
*/
SDL_COMPILE_TIME_ASSERT(SDL_GPURenderStateDesc_SIZE,
(sizeof(void *) == 4 && sizeof(SDL_GPURenderStateDesc) == 32) ||
(sizeof(void *) == 8 && sizeof(SDL_GPURenderStateDesc) == 64));
/**
* A custom GPU render state.
*
* \since This struct is available since SDL 3.4.0.
*
* \sa SDL_CreateGPURenderState
* \sa SDL_SetGPURenderStateFragmentUniformData
* \sa SDL_SetRenderGPUState
* \sa SDL_DestroyGPURenderState
*/
typedef struct SDL_GPURenderState SDL_GPURenderState;
/**
* Create custom GPU render state.
*
* \param renderer the renderer to use.
* \param desc GPU render state description, initialized using SDL_INIT_INTERFACE().
* \returns a custom GPU render state or NULL on failure; call SDL_GetError() for more information.
*
* \threadsafety This function should be called on the thread that created the renderer.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_SetGPURenderStateFragmentUniformData
* \sa SDL_SetRenderGPUState
* \sa SDL_DestroyGPURenderState
*/
extern SDL_DECLSPEC SDL_GPURenderState * SDLCALL SDL_CreateGPURenderState(SDL_Renderer *renderer, SDL_GPURenderStateDesc *desc);
/**
* Set fragment shader uniform variables in a custom GPU render state.
*
* The data is copied and will be pushed using SDL_PushGPUFragmentUniformData() during draw call execution.
*
* \param state the state to modify.
* \param slot_index the fragment uniform slot to push data to.
* \param data client data to write.
* \param length the length of the data to write.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function should be called on the thread that created the renderer.
*
* \since This function is available since SDL 3.4.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetGPURenderStateFragmentUniformData(SDL_GPURenderState *state, Uint32 slot_index, const void *data, Uint32 length);
/**
* Set custom GPU render state.
*
* This function sets custom GPU render state for subsequent draw calls. This allows using custom shaders with the GPU renderer.
*
* \param renderer the renderer to use.
* \param state the state to to use, or NULL to clear custom GPU render state.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function should be called on the thread that created the renderer.
*
* \since This function is available since SDL 3.4.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderGPUState(SDL_Renderer *renderer, SDL_GPURenderState *state);
/**
* Destroy custom GPU render state.
*
* \param state the state to destroy.
*
* \threadsafety This function should be called on the thread that created the renderer.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateGPURenderState
*/
extern SDL_DECLSPEC void SDLCALL SDL_DestroyGPURenderState(SDL_GPURenderState *state);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}