#include #include #include "test.shader.h" #include "SDL3/SDL_init.h" #include "SDL3/SDL_render.h" #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" #include #include #include "test_layout.h" void EnableD3D12DebugLayer() { ID3D12Debug* debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { debugController->EnableDebugLayer(); // 启用 GPU 验证(可选,但有助于发现更多问题) ID3D12Debug1* debugController1; if (SUCCEEDED(debugController->QueryInterface(IID_PPV_ARGS(&debugController1)))) { debugController1->SetEnableGPUBasedValidation(TRUE); debugController1->Release(); } debugController->Release(); } } int main(int argc, char* argv[]) { EnableD3D12DebugLayer(); SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("Hello World", 640, 480, 0); if (window == nullptr) { SDL_Log("Could not create window: %s", SDL_GetError()); return 1; } SDL_GPUDevice* gpu_device; auto renderer = SDL_CreateGPURenderer(window, SDL_GPU_SHADERFORMAT_DXIL, &gpu_device); if (renderer == nullptr) { SDL_Log("Could not create renderer: %s", SDL_GetError()); SDL_DestroyWindow(window); return 1; } SDL3GPU::test_shader_handle_t shader_handle; auto result = shader_handle.init(gpu_device); if (!result) { SDL_Log("Failed to initialize shader handle: %s", result.error().c_str()); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); return 1; } test_shader::vertex_t v1{}; test_shader::vertex_t v2{}; test_shader::vertex_t v3{}; v1.position[0] = 0.f; v1.position[1] = 1.f; // 上 v1.uv[0] = 0.0f; v1.uv[1] = 1.0f; v2.position[0] = -1.f; v2.position[1] = -1.f; // 左 v2.uv[0] = 1.0f; v2.uv[1] = 1.0f; v3.position[0] = 1.f; v3.position[1] = -1.f; // 右 v3.uv[0] = 0.0f; v3.uv[1] = 0.0f; std::array vertexs = { v1, v2, v3 }; auto vertex_buffer = test_shader::create_vertex_buffer(gpu_device, vertexs.data(), vertexs.size()); if (!vertex_buffer) { SDL_Log("Failed to create vertex buffer: %s", SDL_GetError()); shader_handle.clear(gpu_device); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); return 1; } TTF_Init(); TTF_Font* font = TTF_OpenFont("C:/Windows/Fonts/msyh.ttc", 24); if (font == nullptr) { SDL_Log("Could not open font: %s", SDL_GetError()); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); return 1; } // 设置字体hinting为轻量级 TTF_SetFontHinting(font, TTF_HINTING_LIGHT_SUBPIXEL); // 设置字体为 SDF 模式 // TTF_SetFontSDF(font, true); // 设置渲染器的混合模式 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); 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); if (text_surface == nullptr) { SDL_Log("Could not render text: %s", SDL_GetError()); TTF_CloseFont(font); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); return 1; } SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, text_surface); SDL_DestroySurface(text_surface); // 释放surface if (texture == nullptr) { SDL_Log("Could not create texture: %s", SDL_GetError()); TTF_CloseFont(font); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); return 1; } // SDL3 新方法获取纹理尺寸 float text_width, text_height; SDL_GetTextureSize(texture, &text_width, &text_height); SDL_FRect dest_rect = { 0, 0, text_width, text_height }; SDL_GPURenderStateDesc desc{}; SDL_INIT_INTERFACE(&desc); desc.fragment_shader = shader_handle.get_fragment_shader(); desc.num_sampler_bindings = 0; desc.num_storage_textures = 0; desc.num_storage_buffers = 0; auto render_state = SDL_CreateGPURenderState(renderer, &desc); SDL_FRect shader_rect = { 0, text_height, text_width, text_height }; // 生成随机数 std::random_device rd; SDL_Event e; bool running = true; while (running) { while (SDL_PollEvent(&e)) { if (e.type == SDL_EVENT_QUIT) { running = false; } } // 正确的渲染顺序 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // 清空屏幕 SDL_RenderClear(renderer); // 绘制文字 SDL_RenderTexture(renderer, texture, nullptr, &dest_rect); test_shader::ParamBuffer param_buffer{}; // 随机颜色 param_buffer.color[0] = static_cast(rd() % 256) / 255.0f; // R param_buffer.color[1] = static_cast(rd() % 256) / 255.0f; // G param_buffer.color[2] = static_cast(rd() % 256) / 255.0f; // B param_buffer.color[3] = 1.0f; // A SDL_SetGPURenderStateFragmentUniforms(render_state, 0, ¶m_buffer, sizeof(param_buffer)); // 绘制自定义图形 SDL_SetRenderGPUState(renderer, render_state); // 使用自定义着色器绘制一个面片 SDL_RenderFillRect(renderer, &shader_rect); // 重置GPUState SDL_SetRenderGPUState(renderer, nullptr); SDL_RenderPresent(renderer); // 最后呈现 std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS } // 清理资源 SDL_DestroyTexture(texture); TTF_CloseFont(font); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); TTF_Quit(); SDL_Quit(); return 0; }