diff --git a/shaders/common_2d.slang b/shaders/common_2d.slang new file mode 100644 index 0000000..b0bd686 --- /dev/null +++ b/shaders/common_2d.slang @@ -0,0 +1,327 @@ +// ============================================================================= +// SDL 2D Shader Common Definitions +// 全局变量和通用功能定义 +// ============================================================================= + +#ifndef SDL_2D_COMMON_H +#define SDL_2D_COMMON_H + +// ============================================================================= +// 平台检测和资源绑定宏 +// ============================================================================= + +#ifdef METAL_TARGET + // Metal使用统一索引空间 + #define BIND_VERTEX_TEXTURE(slot) register(t##slot) + #define BIND_VERTEX_SAMPLER(slot) register(s##slot) + #define BIND_VERTEX_BUFFER(slot) register(b##slot) + #define BIND_VERTEX_STORAGE(slot) register(u##slot) + + #define BIND_PIXEL_TEXTURE(slot) register(t##slot) + #define BIND_PIXEL_SAMPLER(slot) register(s##slot) + #define BIND_PIXEL_BUFFER(slot) register(b##slot) + #define BIND_PIXEL_STORAGE(slot) register(u##slot) +#else + // Vulkan/DirectX 使用分离空间 + #define BIND_VERTEX_TEXTURE(slot) register(t##slot, space0) + #define BIND_VERTEX_SAMPLER(slot) register(s##slot, space0) + #define BIND_VERTEX_BUFFER(slot) register(b##slot, space1) + #define BIND_VERTEX_STORAGE(slot) register(u##slot, space0) + + #define BIND_PIXEL_TEXTURE(slot) register(t##slot, space2) + #define BIND_PIXEL_SAMPLER(slot) register(s##slot, space2) + #define BIND_PIXEL_BUFFER(slot) register(b##slot, space3) + #define BIND_PIXEL_STORAGE(slot) register(u##slot, space2) +#endif + +// ============================================================================= +// 数学常量 +// ============================================================================= + +static const float PI = 3.14159265359; +static const float TWO_PI = 6.28318530718; +static const float HALF_PI = 1.57079632679; +static const float INV_PI = 0.31830988618; +static const float EPSILON = 1e-6; +static const float GAMMA = 2.2; +static const float INV_GAMMA = 0.454545; + +// ============================================================================= +// 标准2D顶点格式 +// ============================================================================= + +struct Vertex2D { + float2 position; // 位置 + float2 texCoord; // 纹理坐标 + float4 color; // 顶点颜色 +}; + +struct VertexShaderOutput { + float4 clipPos : SV_Position; + float2 texCoord : TEXCOORD0; + float4 color : TEXCOORD1; + float2 worldPos : TEXCOORD2; // 世界空间位置(用于特效) +}; + +// ============================================================================= +// 全局Uniform缓冲区结构 +// ============================================================================= + +// 场景级别的全局数据 +struct SceneGlobals { + float4x4 viewProjection; // 视图投影矩阵 + float4x4 invViewProjection; // 逆视图投影矩阵 + float2 screenSize; // 屏幕尺寸 + float2 invScreenSize; // 1.0 / 屏幕尺寸 + float time; // 当前时间(秒) + float deltaTime; // 帧时间 + float2 _padding0; +}; + +// 每个绘制调用的数据 +struct DrawCallData { + float4x4 modelMatrix; // 模型矩阵 + float4 tintColor; // 色调 + float4 uvTransform; // UV变换 (offset.xy, scale.xy) + float2 pivot; // 旋转中心点 + float rotation; // 旋转角度(弧度) + float _padding1; +}; + +// 材质参数 +struct MaterialParams { + float4 baseColor; // 基础颜色 + float opacity; // 不透明度 + float brightness; // 亮度 + float contrast; // 对比度 + float saturation; // 饱和度 + float hue; // 色相偏移 + float bloomIntensity; // 泛光强度 + float2 distortionAmount; // 扭曲程度 +}; + +// 特效参数 +struct EffectParams { + float4 glowColor; // 发光颜色 + float glowSize; // 发光大小 + float shadowSoftness; // 阴影柔和度 + float shadowDistance; // 阴影距离 + float shadowAngle; // 阴影角度 + float4 gradientColors[4]; // 渐变颜色(最多4个) + float gradientStops[4]; // 渐变停止点 + float noiseScale; // 噪声缩放 + float noiseIntensity; // 噪声强度 + float2 _padding2; +}; + +// ============================================================================= +// 全局资源声明宏 +// ============================================================================= + +// 顶点着色器全局资源 +#define DECLARE_VERTEX_GLOBALS \ + ConstantBuffer g_scene : BIND_VERTEX_BUFFER(0); \ + ConstantBuffer g_draw : BIND_VERTEX_BUFFER(1); + +// 像素着色器全局资源 +#define DECLARE_PIXEL_GLOBALS \ + ConstantBuffer g_scene : BIND_PIXEL_BUFFER(0); \ + ConstantBuffer g_material : BIND_PIXEL_BUFFER(1); \ + ConstantBuffer g_effect : BIND_PIXEL_BUFFER(2); + +// 标准纹理资源 +#define DECLARE_STANDARD_TEXTURES \ + Texture2D g_mainTexture : BIND_PIXEL_TEXTURE(0); \ + Texture2D g_normalTexture : BIND_PIXEL_TEXTURE(1); \ + Texture2D g_maskTexture : BIND_PIXEL_TEXTURE(2); \ + Texture2D g_noiseTexture : BIND_PIXEL_TEXTURE(3); \ + SamplerState g_linearSampler : BIND_PIXEL_SAMPLER(0); \ + SamplerState g_pointSampler : BIND_PIXEL_SAMPLER(1); \ + SamplerState g_linearClampSampler : BIND_PIXEL_SAMPLER(2); \ + SamplerState g_pointClampSampler : BIND_PIXEL_SAMPLER(3); + +// ============================================================================= +// 实用函数库 +// ============================================================================= + +// 2D变换函数 +float2 rotate2D(float2 v, float angle) { + float c = cos(angle); + float s = sin(angle); + return float2( + v.x * c - v.y * s, + v.x * s + v.y * c + ); +} + +float2 scale2D(float2 v, float2 scale) { + return v * scale; +} + +float2 translate2D(float2 v, float2 offset) { + return v + offset; +} + +// UV坐标变换 +float2 transformUV(float2 uv, float4 uvTransform) { + return uv * uvTransform.zw + uvTransform.xy; +} + +// 颜色空间转换 +float3 sRGBToLinear(float3 color) { + return pow(color, float3(GAMMA)); +} + +float3 linearToSRGB(float3 color) { + return pow(color, float3(INV_GAMMA)); +} + +float4 sRGBToLinear(float4 color) { + return float4(sRGBToLinear(color.rgb), color.a); +} + +float4 linearToSRGB(float4 color) { + return float4(linearToSRGB(color.rgb), color.a); +} + +// HSV颜色空间 +float3 rgbToHSV(float3 rgb) { + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + float4 p = lerp(float4(rgb.bg, K.wz), float4(rgb.gb, K.xy), step(rgb.b, rgb.g)); + float4 q = lerp(float4(p.xyw, rgb.r), float4(rgb.r, p.yzx), step(p.x, rgb.r)); + + float d = q.x - min(q.w, q.y); + float e = EPSILON; + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +float3 hsvToRGB(float3 hsv) { + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(hsv.xxx + K.xyz) * 6.0 - K.www); + return hsv.z * lerp(K.xxx, saturate(p - K.xxx), hsv.y); +} + +// 颜色调整函数 +float3 adjustBrightness(float3 color, float brightness) { + return color * brightness; +} + +float3 adjustContrast(float3 color, float contrast) { + return (color - 0.5) * contrast + 0.5; +} + +float3 adjustSaturation(float3 color, float saturation) { + float gray = dot(color, float3(0.299, 0.587, 0.114)); + return lerp(float3(gray), color, saturation); +} + +float3 adjustHue(float3 color, float hueShift) { + float3 hsv = rgbToHSV(color); + hsv.x = frac(hsv.x + hueShift); + return hsvToRGB(hsv); +} + +// 混合模式 +float3 blendNormal(float3 base, float3 blend, float opacity) { + return lerp(base, blend, opacity); +} + +float3 blendMultiply(float3 base, float3 blend, float opacity) { + return lerp(base, base * blend, opacity); +} + +float3 blendScreen(float3 base, float3 blend, float opacity) { + return lerp(base, 1.0 - (1.0 - base) * (1.0 - blend), opacity); +} + +float3 blendOverlay(float3 base, float3 blend, float opacity) { + float3 result = lerp( + 2.0 * base * blend, + 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), + step(0.5, base) + ); + return lerp(base, result, opacity); +} + +// 抗锯齿函数 +float smootherstep(float edge0, float edge1, float x) { + x = saturate((x - edge0) / (edge1 - edge0)); + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); +} + +// SDF相关函数 +float sdCircle(float2 p, float r) { + return length(p) - r; +} + +float sdBox(float2 p, float2 b) { + float2 d = abs(p) - b; + return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); +} + +float sdRoundedBox(float2 p, float2 b, float r) { + float2 q = abs(p) - b + r; + return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r; +} + +// ============================================================================= +// 标准顶点着色器模板 +// ============================================================================= + +#define STANDARD_VERTEX_SHADER(name) \ + DECLARE_VERTEX_GLOBALS \ + \ + [shader("vertex")] \ + VertexShaderOutput name(Vertex2D input) { \ + VertexShaderOutput output; \ + \ + float2 pos = input.position; \ + \ + /* 应用旋转 */ \ + if (abs(g_draw.rotation) > EPSILON) { \ + pos -= g_draw.pivot; \ + pos = rotate2D(pos, g_draw.rotation); \ + pos += g_draw.pivot; \ + } \ + \ + /* 应用模型变换 */ \ + float4 worldPos = mul(g_draw.modelMatrix, float4(pos, 0.0, 1.0)); \ + output.clipPos = mul(g_scene.viewProjection, worldPos); \ + output.worldPos = worldPos.xy; \ + \ + /* UV变换 */ \ + output.texCoord = transformUV(input.texCoord, g_draw.uvTransform); \ + \ + /* 颜色 */ \ + output.color = input.color * g_draw.tintColor; \ + \ + return output; \ + } + +// ============================================================================= +// 标准像素着色器模板 +// ============================================================================= + +#define STANDARD_PIXEL_SHADER(name, code) \ + DECLARE_PIXEL_GLOBALS \ + DECLARE_STANDARD_TEXTURES \ + \ + [shader("fragment")] \ + float4 name(VertexShaderOutput input) : SV_Target { \ + float4 color = g_mainTexture.Sample(g_linearSampler, input.texCoord); \ + color *= input.color; \ + \ + /* 用户代码 */ \ + code \ + \ + /* 应用材质参数 */ \ + color.rgb = adjustBrightness(color.rgb, g_material.brightness); \ + color.rgb = adjustContrast(color.rgb, g_material.contrast); \ + color.rgb = adjustSaturation(color.rgb, g_material.saturation); \ + color.rgb = adjustHue(color.rgb, g_material.hue); \ + color.a *= g_material.opacity; \ + \ + return color; \ + } + +#endif // SDL_2D_COMMON_H diff --git a/shaders/core.slang b/shaders/core.slang new file mode 100644 index 0000000..3b44636 --- /dev/null +++ b/shaders/core.slang @@ -0,0 +1,110 @@ +// ============================================================================= +// sprite_shader.slang - 使用全局变量的精灵着色器 +// ============================================================================= + +#include "common_2d.slang" + +// 自动生成标准顶点着色器 +STANDARD_VERTEX_SHADER(vertexMain) + +// 简单的像素着色器 +STANDARD_PIXEL_SHADER(pixelMain, { + // 这里可以添加自定义代码 + // color 变量已经包含了采样后的纹理颜色 +}) + +// 带发光效果的像素着色器 +DECLARE_PIXEL_GLOBALS +DECLARE_STANDARD_TEXTURES + +[shader("fragment")] +float4 pixelMainGlow(VertexShaderOutput input) : SV_Target { + float4 color = g_mainTexture.Sample(g_linearSampler, input.texCoord); + color *= input.color; + + // 发光效果 + if (g_effect.glowSize > 0.0) { + float2 texelSize = g_scene.invScreenSize; + float4 glow = float4(0.0); + + // 简单的发光采样 + for (int y = -2; y <= 2; y++) { + for (int x = -2; x <= 2; x++) { + float2 offset = float2(x, y) * texelSize * g_effect.glowSize; + float4 sample = g_mainTexture.Sample(g_linearSampler, input.texCoord + offset); + float weight = 1.0 / (1.0 + length(float2(x, y))); + glow += sample * weight; + } + } + + glow *= g_effect.glowColor; + color.rgb += glow.rgb * g_effect.glowColor.a; + } + + // 应用标准材质参数 + color.rgb = adjustBrightness(color.rgb, g_material.brightness); + color.rgb = adjustContrast(color.rgb, g_material.contrast); + color.rgb = adjustSaturation(color.rgb, g_material.saturation); + color.a *= g_material.opacity; + + return color; +} + +// 文字渲染着色器 +DECLARE_PIXEL_GLOBALS +DECLARE_STANDARD_TEXTURES + +[shader("fragment")] +float4 pixelMainText(VertexShaderOutput input) : SV_Target { + // 文字通常存储在alpha通道 + float alpha = g_mainTexture.Sample(g_linearSampler, input.texCoord).a; + + // SDF文字渲染 + float distance = alpha; + float smoothing = fwidth(distance) * 0.75; + alpha = smootherstep(0.5 - smoothing, 0.5 + smoothing, distance); + + // 应用颜色 + float4 color = float4(input.color.rgb, input.color.a * alpha); + + // 文字阴影 + if (g_effect.shadowDistance > 0.0) { + float2 shadowOffset = float2( + cos(g_effect.shadowAngle), + sin(g_effect.shadowAngle) + ) * g_effect.shadowDistance * g_scene.invScreenSize; + + float shadowAlpha = g_mainTexture.Sample(g_linearSampler, input.texCoord - shadowOffset).a; + shadowAlpha = smootherstep(0.5 - smoothing * g_effect.shadowSoftness, 0.5 + smoothing * g_effect.shadowSoftness, shadowAlpha); + + // 混合阴影 + color.rgb = lerp(float3(0.0, 0.0, 0.0), color.rgb, alpha); + color.a = max(color.a, shadowAlpha * 0.5); + } + + return color; +} + +// 形状渲染着色器(使用SDF) +DECLARE_PIXEL_GLOBALS + +[shader("fragment")] +float4 pixelMainShape(VertexShaderOutput input) : SV_Target { + float2 p = input.texCoord * 2.0 - 1.0; // 转换到[-1, 1]空间 + + // 圆角矩形SDF + float d = sdRoundedBox(p, float2(0.8, 0.6), 0.1); + + // 抗锯齿边缘 + float alpha = 1.0 - smoothstep(-0.01, 0.01, d); + + // 渐变填充 + float gradient = (p.y + 1.0) * 0.5; + float3 color = lerp( + g_effect.gradientColors[0].rgb, + g_effect.gradientColors[1].rgb, + gradient + ); + + return float4(color * input.color.rgb, alpha * input.color.a * g_material.opacity); +} diff --git a/shaders/test.slang b/shaders/test.slang new file mode 100644 index 0000000..e79189f --- /dev/null +++ b/shaders/test.slang @@ -0,0 +1,221 @@ +// ===== 平台检测 ===== +#ifdef __METAL_VERSION__ + #define METAL_PLATFORM +#endif + +#ifdef SPIRV + #define SPIRV_PLATFORM +#endif + +// ===== 基础类型定义 ===== +#ifdef METAL_PLATFORM + // Metal类型别名 + typealias Texture2D_float = texture2d; + typealias Texture2D_float4 = texture2d; + typealias RWTexture2D_float4 = texture2d; + typealias SamplerState = sampler; + + // Metal属性包装器 + struct MetalAttribute { + T value; + }; +#else + // HLSL/SPIR-V使用原生类型 + typealias Texture2D_float = Texture2D; + typealias Texture2D_float4 = Texture2D; + typealias RWTexture2D_float4 = RWTexture2D; +#endif + +// ===== 资源声明辅助函数 ===== + +// 顶点着色器资源 +#ifdef METAL_PLATFORM + #define VERTEX_TEXTURE(Type, Name, Binding) \ + [[texture(Binding)]] Type Name + + #define VERTEX_SAMPLER(Name, Binding) \ + [[sampler(Binding)]] sampler Name + + #define VERTEX_STORAGE_TEXTURE(Type, Name, Binding) \ + [[texture(Binding)]] texture2d Name + + #define VERTEX_UNIFORM_BUFFER(Type, Name, Binding) \ + [[buffer(Binding)]] constant Type& Name + + #define VERTEX_STORAGE_BUFFER(Type, Name, Binding) \ + [[buffer(Binding)]] device Type* Name +#else + #define VERTEX_TEXTURE(Type, Name, Binding) \ + [[vk::binding(Binding, 0)]] \ + Type Name : register(t##Binding, space0) + + #define VERTEX_SAMPLER(Name, Binding) \ + [[vk::binding(Binding, 0)]] \ + SamplerState Name : register(s##Binding, space0) + + #define VERTEX_STORAGE_TEXTURE(Type, Name, Binding) \ + [[vk::binding(Binding, 0)]] \ + RWTexture2D Name : register(t##Binding, space0) + + #define VERTEX_UNIFORM_BUFFER(Type, Name, Binding) \ + [[vk::binding(Binding, 1)]] \ + ConstantBuffer Name : register(b##Binding, space1) + + #define VERTEX_STORAGE_BUFFER(Type, Name, Binding) \ + [[vk::binding(Binding, 0)]] \ + RWStructuredBuffer Name : register(t##Binding, space0) +#endif + +// 片元着色器资源 +#ifdef METAL_PLATFORM + #define FRAGMENT_TEXTURE(Type, Name, Binding) \ + [[texture(Binding)]] Type Name + + #define FRAGMENT_SAMPLER(Name, Binding) \ + [[sampler(Binding)]] sampler Name + + #define FRAGMENT_STORAGE_TEXTURE(Type, Name, Binding) \ + [[texture(Binding)]] texture2d Name + + #define FRAGMENT_UNIFORM_BUFFER(Type, Name, Binding) \ + [[buffer(Binding)]] constant Type& Name + + #define FRAGMENT_STORAGE_BUFFER(Type, Name, Binding) \ + [[buffer(Binding)]] device Type* Name +#else + #define FRAGMENT_TEXTURE(Type, Name, Binding) \ + [[vk::binding(Binding, 2)]] \ + Type Name : register(t##Binding, space2) + + #define FRAGMENT_SAMPLER(Name, Binding) \ + [[vk::binding(Binding, 2)]] \ + SamplerState Name : register(s##Binding, space2) + + #define FRAGMENT_STORAGE_TEXTURE(Type, Name, Binding) \ + [[vk::binding(Binding, 2)]] \ + RWTexture2D Name : register(t##Binding, space2) + + #define FRAGMENT_UNIFORM_BUFFER(Type, Name, Binding) \ + [[vk::binding(Binding, 3)]] \ + ConstantBuffer Name : register(b##Binding, space3) + + #define FRAGMENT_STORAGE_BUFFER(Type, Name, Binding) \ + [[vk::binding(Binding, 2)]] \ + RWStructuredBuffer Name : register(t##Binding, space2) +#endif + +// ===== 更灵活的Slang风格接口方案 ===== + +// 定义资源接口 +interface IShaderResources { + // 这里可以定义通用的资源访问方法 +} + +// 顶点着色器资源包装器 +struct VertexResources : IShaderResources { + // 根据目标平台选择不同的实现 +#ifdef METAL_PLATFORM + struct Textures { + [[texture(0)]] texture2d tex0; + [[texture(1)]] texture2d tex1; + }; + + struct Samplers { + [[sampler(0)]] sampler samp0; + [[sampler(1)]] sampler samp1; + }; + + struct Uniforms { + [[buffer(0)]] constant T& data; + }; +#else + struct Textures { + [[vk::binding(0, 0)]] Texture2D tex0 : register(t0, space0); + [[vk::binding(1, 0)]] Texture2D tex1 : register(t1, space0); + }; + + struct Samplers { + [[vk::binding(0, 0)]] SamplerState samp0 : register(s0, space0); + [[vk::binding(1, 0)]] SamplerState samp1 : register(s1, space0); + }; + + struct Uniforms { + [[vk::binding(0, 1)]] ConstantBuffer data : register(b0, space1); + }; +#endif +} + +// 片元着色器资源包装器 +struct FragmentResources : IShaderResources { +#ifdef METAL_PLATFORM + struct Textures { + [[texture(0)]] texture2d tex0; + [[texture(1)]] texture2d tex1; + }; + + struct Samplers { + [[sampler(0)]] sampler samp0; + [[sampler(1)]] sampler samp1; + }; + + struct Uniforms { + [[buffer(0)]] constant T& data; + }; +#else + struct Textures { + [[vk::binding(0, 2)]] Texture2D tex0 : register(t0, space2); + [[vk::binding(1, 2)]] Texture2D tex1 : register(t1, space2); + }; + + struct Samplers { + [[vk::binding(0, 2)]] SamplerState samp0 : register(s0, space2); + [[vk::binding(1, 2)]] SamplerState samp1 : register(s1, space2); + }; + + struct Uniforms { + [[vk::binding(0, 3)]] ConstantBuffer data : register(b0, space3); + }; +#endif +} + +// ===== 使用示例 ===== +/* +// 定义统一数据结构 +struct MyVertexUniforms { + float4x4 mvpMatrix; + float4 color; +}; + +struct MyFragmentUniforms { + float4 tintColor; + float opacity; +}; + +// 顶点着色器 +VERTEX_TEXTURE(Texture2D, vertexTexture, 0); +VERTEX_SAMPLER(vertexSampler, 0); +VERTEX_UNIFORM_BUFFER(MyVertexUniforms, vertexUniforms, 0); + +// 或者使用结构化方式 +VertexResources::Textures vertTextures; +VertexResources::Samplers vertSamplers; +VertexResources::Uniforms vertUniforms; + +// 片元着色器 +FRAGMENT_TEXTURE(Texture2D, fragmentTexture, 0); +FRAGMENT_SAMPLER(fragmentSampler, 0); +FRAGMENT_UNIFORM_BUFFER(MyFragmentUniforms, fragmentUniforms, 0); + +// 着色器函数 +[shader("vertex")] +float4 vertexMain(float3 position : POSITION) : SV_Position { + float4 color = vertexTexture.Sample(vertexSampler, float2(0.5, 0.5)); + return mul(vertexUniforms.mvpMatrix, float4(position, 1.0)); +} + +[shader("fragment")] +float4 fragmentMain(float2 uv : TEXCOORD0) : SV_Target { + float4 color = fragmentTexture.Sample(fragmentSampler, uv); + return color * fragmentUniforms.tintColor * fragmentUniforms.opacity; +} +*/ diff --git a/src/main.cpp b/src/main.cpp index d0adbaa..f49da3f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "SDL3/SDL_video.h" #include "SDL3/SDL_log.h" #include "SDL3/SDL_timer.h" +#include "SDL3/SDL_gpu.h" #include "SDL3_ttf/SDL_ttf.h" int main(int argc, char* argv[]) { @@ -15,12 +16,13 @@ int main(int argc, char* argv[]) { SDL_Log("Could not create window: %s", SDL_GetError()); return 1; } - SDL_Renderer* renderer = SDL_CreateRenderer(window, "direct3d11"); + SDL_Renderer* renderer = SDL_CreateRenderer(window, "direct3d12,metal,vulkan"); if (renderer == nullptr) { SDL_Log("Could not create renderer: %s", SDL_GetError()); SDL_DestroyWindow(window); return 1; } + auto gpu_device = (SDL_GPUDevice*)SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, NULL); TTF_Init(); @@ -32,7 +34,7 @@ int main(int argc, char* argv[]) { return 1; } // 设置字体hinting为轻量级 - TTF_SetFontHinting(font, TTF_HINTING_LIGHT); + TTF_SetFontHinting(font, TTF_HINTING_LIGHT_SUBPIXEL); // 设置字体为 SDF 模式 // TTF_SetFontSDF(font, true); // 设置渲染器的混合模式 @@ -40,7 +42,7 @@ int main(int argc, char* argv[]) { SDL_Color color = { 255, 255, 255, 255 }; // 白色文字 SDL_Color bg_color = { 0, 0, 0, 255 }; // 背景颜色 - auto text_surface = TTF_RenderText_LCD_Wrapped(font, "Hello World!\n你好,世界!", 0, color, bg_color, 0); + auto text_surface = TTF_RenderText_LCD_Wrapped(font, "Hello World!\n你好,世界!🆒", 0, color, bg_color, 0); if (text_surface == nullptr) { SDL_Log("Could not render text: %s", SDL_GetError()); TTF_CloseFont(font); @@ -65,6 +67,23 @@ int main(int argc, char* argv[]) { SDL_GetTextureSize(texture, &text_width, &text_height); SDL_FRect dest_rect = { 0, 0, text_width, text_height }; + SDL_GPUShaderCreateInfo shader_info; + shader_info.code_size = 10; + shader_info.code = nullptr; // 这里需要填入实际的着色器代码 + shader_info.entrypoint = "main"; + shader_info.format = SDL_GPU_SHADERFORMAT_DXIL; + shader_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT; + shader_info.num_samplers = 0; + shader_info.num_storage_textures = 0; + shader_info.num_uniform_buffers = 0; + shader_info.num_storage_buffers = 0; + auto shader = SDL_CreateGPUShader(gpu_device, &shader_info); + + SDL_GPURenderStateDesc desc; + SDL_INIT_INTERFACE(&desc); + desc.fragment_shader = shader; + auto render_state = SDL_CreateGPURenderState(renderer, &desc); + SDL_Event e; bool running = true; while (running) { @@ -79,6 +98,7 @@ int main(int argc, char* argv[]) { SDL_RenderClear(renderer); // 先清屏 SDL_RenderTexture(renderer, texture, nullptr, &dest_rect); // 然后绘制文字 SDL_RenderPresent(renderer); // 最后呈现 + SDL_RenderLines(renderer, nullptr, 0); // 确保没有多余的线条 std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS } diff --git a/src/shader_handle.cpp b/src/shader_handle.cpp new file mode 100644 index 0000000..ecb3aa3 --- /dev/null +++ b/src/shader_handle.cpp @@ -0,0 +1,21 @@ +// +// Created by 46944 on 25-6-6. +// +#include "shader_handle.h" + +#include "tmpxm05mgxl.layout.h" + +SDL_GPUGraphicsPipeline* pixel_shader_handle_t::create_graphics_pipeline(SDL_GPUDevice* in_gpu_device) { + SDL_GPUGraphicsPipelineCreateInfo desc = {}; + desc.vertex_shader = vertex_shader_; + desc.fragment_shader = fragment_shader_; + desc.vertex_input_state = g_vertexInputState; + desc.primitive_type = primitive_type_; + desc.rasterizer_state.fill_mode = fill_mode_; + desc.rasterizer_state.cull_mode = cull_mode_; + desc.rasterizer_state.front_face = front_face_; + desc.multisample_state.sample_count = sample_count_; + desc.depth_stencil_state.enable_depth_test = false; + + return SDL_CreateGPUGraphicsPipeline(in_gpu_device, &desc); +} diff --git a/src/shader_handle.h b/src/shader_handle.h new file mode 100644 index 0000000..eb12cbf --- /dev/null +++ b/src/shader_handle.h @@ -0,0 +1,87 @@ +// +// Created by 46944 on 25-6-6. +// +#pragma once +#include +#include +#include + +class shader_handle_t { +public: + virtual ~shader_handle_t() = default; + virtual std::expected init(SDL_GPUDevice* in_gpu_device) = 0; + virtual void clear(SDL_GPUDevice* in_gpu_device) = 0; + + +}; + +class pixel_shader_handle_t : public shader_handle_t { +public: + virtual std::expected init(SDL_GPUDevice* in_gpu_device) override { + vertex_shader_ = create_vertex_shader(in_gpu_device); + if (!vertex_shader_) { + return std::unexpected("Failed to create vertex shader"); + } + fragment_shader_ = create_fragment_shader(in_gpu_device); + if (!fragment_shader_) { + clear(in_gpu_device); + return std::unexpected("Failed to create fragment shader"); + } + graphics_pipeline_ = create_graphics_pipeline(in_gpu_device); + if (!graphics_pipeline_) { + clear(in_gpu_device); + return std::unexpected("Failed to create graphics pipeline"); + } + return true; + } + + virtual void clear(SDL_GPUDevice* in_gpu_device) override { + if (graphics_pipeline_) { + SDL_ReleaseGPUGraphicsPipeline(in_gpu_device, graphics_pipeline_); + graphics_pipeline_ = nullptr; + } + if (fragment_shader_) { + SDL_ReleaseGPUShader(in_gpu_device, fragment_shader_); + fragment_shader_ = nullptr; + } + if (vertex_shader_) { + SDL_ReleaseGPUShader(in_gpu_device, vertex_shader_); + vertex_shader_ = nullptr; + } + } + +protected: + virtual SDL_GPUShader* create_vertex_shader(SDL_GPUDevice* in_gpu_device) { return nullptr; } + virtual SDL_GPUShader* create_fragment_shader(SDL_GPUDevice* in_gpu_device) = 0; + virtual SDL_GPUGraphicsPipeline* create_graphics_pipeline(SDL_GPUDevice* in_gpu_device); +private: + SDL_GPUShader* vertex_shader_ = nullptr; + SDL_GPUShader* fragment_shader_ = nullptr; + SDL_GPUGraphicsPipeline* graphics_pipeline_ = nullptr; + SDL_GPUPrimitiveType primitive_type_ = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST; + SDL_GPUFillMode fill_mode_ = SDL_GPU_FILLMODE_FILL; + SDL_GPUCullMode cull_mode_ = SDL_GPU_CULLMODE_NONE; + SDL_GPUFrontFace front_face_ = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE; + SDL_GPUSampleCount sample_count_ = SDL_GPU_SAMPLECOUNT_1; +}; + +class compute_shader_handle_t : public shader_handle_t { +public: + virtual std::expected init(SDL_GPUDevice* in_gpu_device) override { + compute_shader_ = create_compute_shader(in_gpu_device); + if (!compute_shader_) { + return std::unexpected("Failed to create compute shader"); + } + compute_pipeline_ = SDL_CreateGPUComputePipeline(in_gpu_device, compute_shader_); + if (!compute_pipeline_) { + clear(in_gpu_device); + return std::unexpected("Failed to create compute pipeline"); + } + return true; + } +protected: + virtual SDL_GPUShader* create_compute_shader(SDL_GPUDevice* in_gpu_device) = 0; +private: + SDL_GPUShader* compute_shader_ = nullptr; + SDL_GPUComputePipeline* compute_pipeline_ = nullptr; +}; diff --git a/src/test.shader.h b/src/test.shader.h new file mode 100644 index 0000000..0dae75c --- /dev/null +++ b/src/test.shader.h @@ -0,0 +1,122 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace SDL3GPU { + + class testShaderBindings { + public: + static constexpr uint8_t vertex_main_blob[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x5f, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x5f, 0x43, 0x6f, 0x6c, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x73, 0x74, 0x64, 0x31, 0x34, 0x30, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x64, 0x31, 0x34, 0x30, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x47, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x47, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x44, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x47, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 + }; + static constexpr uint8_t pixel_main_blob[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 + }; + struct Resource { + enum Type { + SampledTexture, + StorageTexture, + StorageBuffer, + UniformBuffer, + Sampler + }; + + std::string name; + Type type; + int binding = -1; + int set = -1; + int space = -1; + int index = -1; + }; + + struct ShaderInfo { + std::string entryPoint; + SDL_GPUShaderStage stage; + std::vector resources; + }; + + private: + std::unordered_map m_shaderInfos; + + public: + ShaderBindings() { + // vertex_main + { + ShaderInfo info; + info.entryPoint = "vertex_main"; + info.stage = SDL_GPU_SHADERSTAGE_VERTEX; + { + Resource r; + r.name = "param_buffer"; + r.type = Resource::UniformBuffer; + r.binding = 0; + r.set = 1; + info.resources.push_back(r); + } + m_shaderInfos["vertex_main"] = std::move(info); + } + + // pixel_main + { + ShaderInfo info; + info.entryPoint = "pixel_main"; + info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT; + { + Resource r; + r.name = "param_buffer"; + r.type = Resource::UniformBuffer; + r.binding = 0; + r.set = 3; + info.resources.push_back(r); + } + m_shaderInfos["pixel_main"] = std::move(info); + } + + } + + void bindResources( + SDL_GPUCommandBuffer* cmd, + const std::string& shaderName, + const std::unordered_map& resources) { + auto it = m_shaderInfos.find(shaderName); + if (it == m_shaderInfos.end()) { + return; + } + + const auto& info = it->second; + + // 根据着色器阶段和资源类型进行绑定 + // 这里需要根据SDL3 GPU的实际API来实现 + for (const auto& res : info.resources) { + auto resIt = resources.find(res.name); + if (resIt == resources.end()) { + continue; + } + + void* resource = resIt->second; + + // 示例绑定逻辑 + switch (res.type) { + case Resource::SampledTexture: + // SDL_BindGPUVertexSamplers(cmd, ...); + break; + case Resource::StorageBuffer: + // SDL_BindGPUVertexStorageBuffers(cmd, ...); + break; + // ... 其他资源类型 + default: + break; + } + } + } + + const ShaderInfo* getShaderInfo(const std::string& shaderName) const { + auto it = m_shaderInfos.find(shaderName); + return it != m_shaderInfos.end() ? &it->second : nullptr; + } + }; + +} // namespace SDL3GPU diff --git a/src/tmpxm05mgxl.layout.h b/src/tmpxm05mgxl.layout.h new file mode 100644 index 0000000..05acd54 --- /dev/null +++ b/src/tmpxm05mgxl.layout.h @@ -0,0 +1,126 @@ +#pragma once + +#include +#include + +// Auto-generated from: C:\Users\46944\AppData\Local\Temp\tmpufk9_wv_.json + +// Auto-generated vertex structure +typedef struct Vertex { + float position[2]; + // location: 0, semantic: POSITION + float uv[2]; + // location: 1, semantic: TEXCOORD + float color[4]; + // location: 2, semantic: COLOR + float param_a[4]; + // location: 3, semantic: TEXCOORD1 + float param_b[4]; + // location: 4, semantic: TEXCOORD2 + float param_c[4]; + // location: 5, semantic: TEXCOORD3 +} Vertex; + +// Uniform buffer structures +typedef struct ParamBuffer { + float transform[4][4]; +} ParamBuffer; +// Binding: 0, Size: 64 bytes + +// Vertex attribute descriptions +#define VERTEX_ATTRIBUTE_COUNT 6 + +static const SDL_GPUVertexAttribute g_vertexAttributes[] = { + { + .location = 0, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, + .offset = 0 + }, // position + { + .location = 1, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, + .offset = 8 + }, // uv + { + .location = 2, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, + .offset = 16 + }, // color + { + .location = 3, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, + .offset = 32 + }, // param_a + { + .location = 4, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, + .offset = 48 + }, // param_b + { + .location = 5, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, + .offset = 64 + } // param_c +}; + +// Vertex buffer description +static const SDL_GPUVertexBufferDescription g_vertexBufferDesc = { + .slot = 0, + .pitch = 80, // sizeof(Vertex) + .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, + .instance_step_rate = 0 +}; + +// Vertex input state +static const SDL_GPUVertexInputState g_vertexInputState = { + .vertex_buffer_descriptions = &g_vertexBufferDesc, + .num_vertex_buffers = 1, + .vertex_attributes = g_vertexAttributes, + .num_vertex_attributes = VERTEX_ATTRIBUTE_COUNT +}; + +// Helper functions + +static SDL_GPUBuffer* createVertexBuffer(SDL_GPUDevice* device, + const Vertex* vertices, + Uint32 vertexCount) { + SDL_GPUBufferCreateInfo bufferInfo = { + .usage = SDL_GPU_BUFFERUSAGE_VERTEX, + .size = static_cast(sizeof(Vertex)) * vertexCount + }; + + SDL_GPUBuffer* buffer = SDL_CreateGPUBuffer(device, &bufferInfo); + + SDL_GPUTransferBufferCreateInfo transferInfo = { + .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, + .size = bufferInfo.size + }; + + // Upload vertex data + SDL_GPUTransferBuffer* transfer = SDL_CreateGPUTransferBuffer(device, &transferInfo); + + void* mapped = SDL_MapGPUTransferBuffer(device, transfer, false); + SDL_memcpy(mapped, vertices, bufferInfo.size); + SDL_UnmapGPUTransferBuffer(device, transfer); + + // Copy to GPU + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(device); + SDL_GPUCopyPass* copy = SDL_BeginGPUCopyPass(cmd); + + SDL_GPUTransferBufferLocation src = {.transfer_buffer = transfer, .offset = 0}; + SDL_GPUBufferRegion dst = {.buffer = buffer, .offset = 0, .size = bufferInfo.size}; + + SDL_UploadToGPUBuffer(copy, &src, &dst, false); + SDL_EndGPUCopyPass(copy); + SDL_SubmitGPUCommandBuffer(cmd); + + SDL_ReleaseGPUTransferBuffer(device, transfer); + return buffer; +} +