183 lines
6.0 KiB
C++
183 lines
6.0 KiB
C++
#include <thread>
|
|
#include <chrono>
|
|
|
|
#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 <d3d12.h>
|
|
#include <random>
|
|
|
|
#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<float>(rd() % 256) / 255.0f; // R
|
|
param_buffer.color[1] = static_cast<float>(rd() % 256) / 255.0f; // G
|
|
param_buffer.color[2] = static_cast<float>(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;
|
|
}
|