refactor(RHI): 完成 Shader uniform 设置迁移到 CommandList

- 删除 RHIShader 的 OpenGL 风格 SetMat4/SetVec3/SetInt 等方法
- 添加 UniformInfo 结构体和 GetUniformInfos/GetUniformInfo 接口
- D3D12Shader 和 OpenGLShader 实现 CacheUniformInfos
- RHICommandList 添加 SetUniform*/SetGlobal* 统一接口
- D3D12 实现 D3D12PipelineLayout 管理 root signature 映射
- 修复 D3D12CommandList::SetPipelineStateInternal 在 Reset 后未重新应用 root signature 的问题
- 更新 OpenGL 集成测试使用新的 SetUniform* API
- 所有单元测试和集成测试通过 (8/8 integration tests)
This commit is contained in:
2026-03-24 19:47:22 +08:00
parent 135fe9145b
commit 0f5d018c1a
21 changed files with 578 additions and 54 deletions

View File

@@ -1,5 +1,4 @@
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <fstream>
@@ -20,6 +19,7 @@
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
using namespace XCEngine::Debug;
using namespace XCEngine::RHI;
@@ -264,13 +264,9 @@ Model* model = nullptr;
OpenGLShader* shader = nullptr;
OpenGLDevice* device = nullptr;
OpenGLPipelineState* pipeline = nullptr;
OpenGLCommandList* cmdList = nullptr;
int frameCount = 0;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
void Initialize()
{
char exePath[MAX_PATH];
@@ -293,6 +289,8 @@ void Initialize()
shader = new OpenGLShader();
shader->CompileFromFile("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
cmdList = new OpenGLCommandList();
Log("Initialization complete");
}
@@ -336,15 +334,16 @@ void Render()
glm::mat4 modelMat = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
shader->SetMat4("view", &view[0][0]);
shader->SetMat4("model", &modelMat[0][0]);
shader->SetMat4("projection", &projection[0][0]);
shader->SetVec3("viewPos", 0.0f, 0.0f, 3.0f);
shader->SetFloat("material.shininess", 32.0f);
shader->SetVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
shader->SetVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
shader->SetVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
shader->SetVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
cmdList->SetShader(shader);
cmdList->SetUniformMat4("view", &view[0][0]);
cmdList->SetUniformMat4("model", &modelMat[0][0]);
cmdList->SetUniformMat4("projection", &projection[0][0]);
cmdList->SetUniformVec3("viewPos", 0.0f, 0.0f, 3.0f);
cmdList->SetUniformFloat("material.shininess", 32.0f);
cmdList->SetUniformVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
cmdList->SetUniformVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
cmdList->SetUniformVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
cmdList->SetUniformVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
model->Draw(shader);
}
@@ -361,24 +360,34 @@ int main()
if (!device->CreateRenderWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", false))
{
Log("Failed to create window");
glfwTerminate();
return -1;
}
glfwSetFramebufferSizeCallback(device->GetWindow(), framebuffer_size_callback);
const OpenGLDeviceInfo& info = device->GetDeviceInfo();
Log("OpenGL Version: %s", info.version.c_str());
Log("Renderer: %s", info.renderer.c_str());
const RHIDeviceInfo& info = device->GetDeviceInfo();
Log("OpenGL Version: %ls", info.version.c_str());
Log("Renderer: %ls", info.renderer.c_str());
Initialize();
device->PollEvents();
while (!glfwWindowShouldClose(device->GetWindow()))
MSG msg = {};
bool shouldClose = false;
while (!shouldClose)
{
if (glfwGetKey(device->GetWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(device->GetWindow(), GLFW_TRUE);
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
shouldClose = true;
break;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
if (shouldClose)
break;
Render();
device->SwapBuffers();
@@ -389,12 +398,13 @@ int main()
if (frameCount == 30) {
Log("Saving screenshot at frame %d", frameCount);
SaveScreenshot("screenshot.ppm");
glfwSetWindowShouldClose(device->GetWindow(), GLFW_TRUE);
PostMessageW(device->GetWindow(), WM_CLOSE, 0, 0);
}
}
Log("Application closed");
delete cmdList;
delete pipeline;
delete device;
delete shader;

View File

@@ -161,7 +161,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}
Log("[INFO] Shaders compiled successfully");
shader.SetInt("uTexture", 0);
commandList.SetShader(&shader);
commandList.SetUniformInt("uTexture", 0);
OpenGLPipelineState pipelineState;
OpenGLRasterizerState rasterizerState;

View File

@@ -283,10 +283,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
int viewLoc = shader.GetUniformLocation("gViewMatrix");
int projLoc = shader.GetUniformLocation("gProjectionMatrix");
Log("[DEBUG] Uniform locations - gModelMatrix: %d, gViewMatrix: %d, gProjectionMatrix: %d", modelLoc, viewLoc, projLoc);
shader.SetMat4("gModelMatrix", modelMatrix);
shader.SetMat4("gViewMatrix", viewMatrix);
shader.SetMat4("gProjectionMatrix", projectionMatrix);
shader.SetInt("uTexture", 0);
commandList.SetShader(&shader);
commandList.SetUniformMat4("gModelMatrix", modelMatrix);
commandList.SetUniformMat4("gViewMatrix", viewMatrix);
commandList.SetUniformMat4("gProjectionMatrix", projectionMatrix);
commandList.SetUniformInt("uTexture", 0);
OpenGLTexture texture;
if (!texture.LoadFromFile("Res/Image/earth.png", true)) {

View File

@@ -1,5 +1,6 @@
#include "fixtures/OpenGLTestFixture.h"
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
using namespace XCEngine::RHI;
@@ -102,15 +103,17 @@ TEST_F(OpenGLTestFixture, Shader_SetUniforms) {
shader.Compile(vs, fs);
ASSERT_TRUE(shader.IsValid());
shader.Use();
auto cmdList = static_cast<OpenGLCommandList*>(GetDevice()->CreateCommandList(CommandListDesc{}));
ASSERT_NE(cmdList, nullptr);
shader.SetInt("uIntValue", 42);
shader.SetFloat("uFloatValue", 3.14f);
shader.SetVec3("uVec3Value", 1.0f, 2.0f, 3.0f);
cmdList->SetShader(&shader);
cmdList->SetUniformInt("uIntValue", 42);
cmdList->SetUniformFloat("uFloatValue", 3.14f);
cmdList->SetUniformVec3("uVec3Value", 1.0f, 2.0f, 3.0f);
float mat[16] = {};
mat[0] = 1.0f; mat[5] = 1.0f; mat[10] = 1.0f; mat[15] = 1.0f;
shader.SetMat4("uMat4Value", mat);
cmdList->SetUniformMat4("uMat4Value", mat);
GLenum error = glGetError();
EXPECT_EQ(error, GL_NO_ERROR);