Add OpenGL test infrastructure - Phase 1: Device, Buffer, Fence tests (17 tests)

- Create test directory structure at tests/RHI/OpenGL/
- Implement OpenGLTestFixture with GLFW/GLAD initialization
- Add Device tests: CreateRenderWindow, InitializeWithExistingWindow, GetDeviceInfo, SwapBuffers, PollEvents
- Add Buffer tests: VertexBuffer, IndexBuffer, UniformBuffer, Dynamic, Bind/Unbind, Map/Unmap
- Add Fence tests: Initialize (signaled/unsignaled), Signal, Wait, IsSignaled, GetStatus
- Add CMakeLists.txt with proper GLFW/GLAD/GTest linking
- Create implementation plan document at docs/OpenGL测试实施计划.md
This commit is contained in:
2026-03-17 12:26:21 +08:00
parent f42a0795fb
commit 745f3ab225
8 changed files with 864 additions and 0 deletions

View File

@@ -0,0 +1,410 @@
# OpenGL 测试实施计划
## 1. 概述
本文档是 `docs/OpenGL后端测试设计.md` 的实施细化计划,基于设计文档中的 5 阶段实现优先级,结合 D3D12 测试经验54 个测试)制定。
### 1.1 目标
- 搭建完整的 OpenGL 后端测试框架
- 实现与 D3D12 对齐的 54+ 个测试用例
- 确保 CI 环境可用
- 支持无头渲染headless测试
### 1.2 测试组件总览
| # | 组件 | 测试数量 | 文件 | 优先级 |
|---|------|:--------:|------|:------:|
| 1 | OpenGLDevice | 6 | test_device.cpp | Phase 1 |
| 2 | OpenGLBuffer | 6 | test_buffer.cpp | Phase 1 |
| 3 | OpenGLFence | 5 | test_fence.cpp | Phase 1 |
| 4 | OpenGLTexture | 5 | test_texture.cpp | Phase 2 |
| 5 | OpenGLSampler | 4 | test_sampler.cpp | Phase 2 |
| 6 | OpenGLShader | 4 | test_shader.cpp | Phase 3 |
| 7 | OpenGLPipelineState | 3 | test_pipeline_state.cpp | Phase 3 |
| 8 | OpenGLVertexArray | 4 | test_vertex_array.cpp | Phase 3 |
| 9 | OpenGLCommandList | 8 | test_command_list.cpp | Phase 4 |
| 10 | OpenGLRenderTargetView | 4 | test_render_target_view.cpp | Phase 4 |
| 11 | OpenGLDepthStencilView | 4 | test_depth_stencil_view.cpp | Phase 4 |
| 12 | OpenGLSwapChain | 3 | test_swap_chain.cpp | Phase 5 |
| **总计** | | **56** | | |
---
## 2. 实施阶段
### Phase 1: 核心基础设施(约 1 天)
#### 2.1 创建目录结构
```
tests/RHI/OpenGL/
├── CMakeLists.txt
├── fixtures/
│ ├── OpenGLTestFixture.h
│ └── OpenGLTestFixture.cpp
└── Res/
├── Shader/
├── Texture/
└── Data/
```
#### 2.2 实现测试夹具
**OpenGLTestFixture** 是所有测试的基础:
| 功能 | 描述 |
|------|------|
| `SetUpTestSuite()` | 创建隐藏 GLFW 窗口和 GL 上下文 |
| `TearDownTestSuite()` | 销毁窗口,终止 GLFW |
| `SetUp()` | 确保上下文激活,清除 GL 错误 |
| `TearDown()` | 重置 GL 状态,检查泄漏 |
| `CheckGLError()` | 检查并报告 GL 错误 |
**GL 错误检查宏**
```cpp
#define GL_CLEAR_ERRORS() do { while (glGetError() != GL_NO_ERROR); } while(0)
#define GL_CHECK(call) do { call; ASSERT_TRUE(CheckGLError(__FILE__, __LINE__)); } while(0)
#define GL_EXPECT_SUCCESS(call) do { call; EXPECT_EQ(glGetError(), GL_NO_ERROR); } while(0)
```
#### 2.3 OpenGLDevice 测试6 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `CreateRenderWindow_ValidParams` | 窗口创建成功 |
| `CreateRenderWindow_DebugMode` | 调试模式创建 |
| `InitializeWithExistingWindow` | 现有窗口初始化 |
| `GetDeviceInfo_ReturnsValid` | 供应商/渲染器/版本信息 |
| `SwapBuffers_NoErrors` | 交换缓冲区无错误 |
| `PollEvents_ReturnsTrue` | 事件轮询正常 |
#### 2.4 OpenGLBuffer 测试6 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_VertexBuffer` | 顶点缓冲创建 |
| `Initialize_IndexBuffer` | 索引缓冲创建 |
| `Initialize_UniformBuffer` | Uniform 缓冲创建 |
| `Initialize_Dynamic` | 动态缓冲创建 |
| `Bind_Unbind` | 缓冲绑定/解绑 |
| `Map_Unmap` | 数据映射操作 |
#### 2.5 OpenGLFence 测试5 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_Unsignaled` | 未 signaled 状态创建 |
| `Initialize_Signaled` | signaled 状态创建 |
| `Signal_SetsValue` | Signal 设置值 |
| `Wait_Blocks` | Wait 阻塞等待 |
| `IsSignaled_ReturnsState` | signaled 状态查询 |
#### 2.6 验证步骤
```bash
# 构建
cmake --build build --config Debug
# 运行测试
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Device*:OpenGLTestFixture.Buffer*:OpenGLTestFixture.Fence*
# 预期结果
[==========] 17 tests from OpenGLTestFixture
[ PASSED ] 17 tests
```
---
### Phase 2: 资源管理(约 1 天)
#### 2.7 OpenGLTexture 测试5 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_2DTexture` | 2D 纹理创建 |
| `Initialize_CubeMap` | 立方体纹理创建 |
| `Bind_Unbind` | 纹理绑定/解绑 |
| `GenerateMipmap` | Mipmap 生成 |
| `SetFiltering_SetWrapping` | 过滤/环绕参数 |
#### 2.8 OpenGLSampler 测试4 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_Default` | 默认采样器创建 |
| `Initialize_Custom` | 自定义采样器创建 |
| `Bind_Unbind` | 采样器绑定/解绑 |
| `GetID_ReturnsValid` | 采样器 ID 有效 |
#### 2.9 验证步骤
```bash
# 运行资源管理测试
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Texture*:OpenGLTestFixture.Sampler*
# 预期结果
[==========] 9 tests from OpenGLTestFixture
[ PASSED ] 9 tests
```
---
### Phase 3: 渲染管线(约 1.5 天)
#### 2.10 OpenGLShader 测试4 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Compile_VertexFragment` | 顶点和片段着色器编译 |
| `Compile_WithGeometry` | 几何着色器编译 |
| `Compile_InvalidSource` | 无效源码编译失败 |
| `SetUniforms` | Uniform 设置 (int/float/vec3/mat4) |
#### 2.11 OpenGLPipelineState 测试3 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `SetDepthStencilState` | 深度/模板状态设置 |
| `SetBlendState` | 混合状态设置 |
| `SetViewport_SetScissor` | 视口/裁剪矩形 |
#### 2.12 OpenGLVertexArray 测试4 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_CreatesVAO` | VAO 创建 |
| `AddVertexBuffer` | 顶点缓冲添加 |
| `SetIndexBuffer` | 索引缓冲设置 |
| `Bind_Unbind` | VAO 绑定/解绑 |
#### 2.13 验证步骤
```bash
# 运行渲染管线测试
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Shader*:OpenGLTestFixture.PipelineState*:OpenGLTestFixture.VertexArray*
# 预期结果
[==========] 11 tests from OpenGLTestFixture
[ PASSED ] 11 tests
```
---
### Phase 4: 命令与视图(约 1.5 天)
#### 2.14 OpenGLCommandList 测试8 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Clear_ColorBuffer` | 清除颜色缓冲 |
| `Clear_DepthStencil` | 清除深度/模板 |
| `SetVertexBuffer` | 设置顶点缓冲 |
| `SetIndexBuffer` | 设置索引缓冲 |
| `Draw_Triangles` | 绘制三角形 |
| `DrawIndexed_Indices` | 索引绘制 |
| `DrawInstanced` | 实例化绘制 |
| `Dispatch_ComputeShader` | 计算着色器分发 |
#### 2.15 OpenGLRenderTargetView 测试4 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_Texture2D` | 2D 纹理 RTV 创建 |
| `Initialize_Default` | 默认帧缓冲 RTV |
| `Bind_Unbind` | RTV 绑定/解绑 |
| `Clear_Color` | 清除颜色 |
#### 2.16 OpenGLDepthStencilView 测试4 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_Texture2D` | 2D 纹理 DSV 创建 |
| `Initialize_DepthOnly` | 仅深度 DSV |
| `Bind_Unbind` | DSV 绑定/解绑 |
| `ClearDepthStencil` | 清除深度/模板 |
#### 2.17 验证步骤
```bash
# 运行命令与视图测试
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.CommandList*:OpenGLTestFixture.RenderTargetView*:OpenGLTestFixture.DepthStencilView*
# 预期结果
[==========] 16 tests from OpenGLTestFixture
[ PASSED ] 16 tests
```
---
### Phase 5: 窗口管理(约 0.5 天)
#### 2.18 OpenGLSwapChain 测试3 个)
| 测试用例 | 验证内容 |
|----------|----------|
| `Initialize_Window` | 交换链初始化 |
| `Present_VSync` | 垂直同步显示 |
| `Resize_ChangesSize` | 调整大小 |
#### 2.19 验证步骤
```bash
# 运行窗口管理测试
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.SwapChain*
# 预期结果
[==========] 3 tests from OpenGLTestFixture
[ PASSED ] 3 tests
```
---
## 3. 完整验证
### 3.1 运行所有测试
```bash
# 完整测试
cmake --build build --config Debug
ctest --test-dir build -C Debug --output-on-failure
# 预期结果
[==========] 56 tests from 1 test suite.
[ PASSED ] 56 tests
```
### 3.2 测试分类统计
| 分类 | 数量 | 占比 |
|------|:----:|:----:|
| 初始化测试 | 18 | 32% |
| 绑定/解绑测试 | 10 | 18% |
| 数据操作测试 | 8 | 14% |
| 状态设置测试 | 10 | 18% |
| 绘制/执行测试 | 10 | 18% |
---
## 4. CI 配置
### 4.1 GitHub Actions
```yaml
# .github/workflows/opengl-tests.yml
name: OpenGL Tests
on: [push, pull_request]
jobs:
test:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Configure
run: cmake -B build -S . -G "Visual Studio 17 2022"
- name: Build
run: cmake --build build --config Debug
- name: Run Tests
run: ctest --test-dir build -C Debug --output-on-failure
```
### 4.2 Linux CI可选
Linux 下需要配置 Mesa 软件渲染:
```yaml
- name: Run Tests
env:
MESA_GL_VERSION_OVERRIDE: 4.6
MESA_GALLIUM_DRIVER: llvmpipe
run: ctest --test-dir build -C Debug --output-on-failure
```
---
## 5. 任务清单
### 阶段 1基础设施
- [ ] 1.1 创建 `tests/RHI/OpenGL/CMakeLists.txt`
- [ ] 1.2 创建 `tests/RHI/OpenGL/fixtures/OpenGLTestFixture.h`
- [ ] 1.3 创建 `tests/RHI/OpenGL/fixtures/OpenGLTestFixture.cpp`
- [ ] 1.4 实现 `test_device.cpp`6 个测试)
- [ ] 1.5 实现 `test_buffer.cpp`6 个测试)
- [ ] 1.6 实现 `test_fence.cpp`5 个测试)
- [ ] 1.7 构建验证17 个测试)
### 阶段 2资源管理
- [ ] 2.1 实现 `test_texture.cpp`5 个测试)
- [ ] 2.2 实现 `test_sampler.cpp`4 个测试)
- [ ] 2.3 构建验证9 个测试)
### 阶段 3渲染管线
- [ ] 3.1 实现 `test_shader.cpp`4 个测试)
- [ ] 3.2 实现 `test_pipeline_state.cpp`3 个测试)
- [ ] 3.3 实现 `test_vertex_array.cpp`4 个测试)
- [ ] 3.4 构建验证11 个测试)
### 阶段 4命令与视图
- [ ] 4.1 实现 `test_command_list.cpp`8 个测试)
- [ ] 4.2 实现 `test_render_target_view.cpp`4 个测试)
- [ ] 4.3 实现 `test_depth_stencil_view.cpp`4 个测试)
- [ ] 4.4 构建验证16 个测试)
### 阶段 5窗口管理
- [ ] 5.1 实现 `test_swap_chain.cpp`3 个测试)
- [ ] 5.2 完整测试验证56 个测试)
- [ ] 5.3 提交并推送
---
## 6. 关键注意事项
### 6.1 窗口依赖
- OpenGL 必须有 GLFW 窗口上下文
- 使用 `GLFW_VISIBLE = GLFW_FALSE` 创建隐藏窗口
- 每个测试前 `glfwMakeContextCurrent()`
### 6.2 GL 状态污染
- OpenGL 状态是全局的,必须隔离
- `TearDown()` 中重置所有 GL 状态
- 测试结束后 `glBindBuffer(..., 0)`
### 6.3 错误检查
- 使用 `GL_CHECK()` 宏验证每个 GL 调用
- 测试开始时 `GL_CLEAR_ERRORS()`
- 捕获 GL 错误并转换为测试失败
### 6.4 与 D3D12 对齐
- 保持相同的测试数量级54+
- 使用相同的 TEST_F 宏
- 遵循相同的命名约定
---
## 7. 后续工作
- [ ] 资源泄漏检测工具
- [ ] 性能基准测试
- [ ] 截图对比测试
- [ ] Linux CI 配置
- [ ] macOS 支持
---
**文档版本**1.0
**创建日期**2026年3月17日
**基于文档**`docs/OpenGL后端测试设计.md``tests/RHI/D3D12/`

View File

@@ -39,6 +39,7 @@ add_subdirectory(threading)
add_subdirectory(debug)
add_subdirectory(D3D12)
add_subdirectory(RHI/D3D12)
add_subdirectory(RHI/OpenGL)
# ============================================================
# Test Summary

View File

@@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.15)
project(OpenGLEngineTests)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
get_filename_component(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)
find_package(OpenGL REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/tests/OpenGL/package/include/)
include_directories(${PROJECT_ROOT_DIR}/engine/include)
include_directories(${PROJECT_ROOT_DIR}/engine/src)
link_directories(${CMAKE_SOURCE_DIR}/tests/OpenGL/package/lib/)
find_package(GTest REQUIRED)
set(TEST_SOURCES
${CMAKE_SOURCE_DIR}/tests/OpenGL/package/src/glad.c
fixtures/OpenGLTestFixture.cpp
test_device.cpp
test_buffer.cpp
test_fence.cpp
)
add_executable(opengl_engine_tests ${TEST_SOURCES})
target_link_libraries(opengl_engine_tests PRIVATE
opengl32
glfw3
XCEngine
GTest::gtest
GTest::gtest_main
)
target_include_directories(opengl_engine_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/fixtures
${PROJECT_ROOT_DIR}/engine/include
${PROJECT_ROOT_DIR}/engine/src
)
target_compile_definitions(opengl_engine_tests PRIVATE
TEST_RESOURCES_DIR="${PROJECT_ROOT_DIR}/tests/RHI/OpenGL/Res"
)
enable_testing()
add_test(NAME OpenGLEngineTests COMMAND opengl_engine_tests)

View File

@@ -0,0 +1,138 @@
#include "OpenGLTestFixture.h"
using namespace XCEngine::RHI;
GLFWwindow* OpenGLTestFixture::m_window = nullptr;
bool OpenGLTestFixture::m_contextInitialized = false;
OpenGLDevice* OpenGLTestFixture::m_device = nullptr;
void OpenGLTestFixture::SetUpTestSuite() {
if (!glfwInit()) {
GTEST_SKIP() << "Failed to initialize GLFW";
return;
}
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
m_window = glfwCreateWindow(640, 480, "OpenGL Tests", nullptr, nullptr);
if (!m_window) {
GTEST_SKIP() << "Failed to create GLFW window";
glfwTerminate();
return;
}
glfwMakeContextCurrent(m_window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
GTEST_SKIP() << "Failed to initialize GLAD";
glfwDestroyWindow(m_window);
m_window = nullptr;
glfwTerminate();
return;
}
m_contextInitialized = true;
m_device = new OpenGLDevice();
m_device->CreateRenderWindow(640, 480, "Test Window", false);
}
void OpenGLTestFixture::TearDownTestSuite() {
if (m_device) {
delete m_device;
m_device = nullptr;
}
if (m_window) {
glfwDestroyWindow(m_window);
m_window = nullptr;
}
glfwTerminate();
m_contextInitialized = false;
}
void OpenGLTestFixture::SetUp() {
if (!m_window || !m_contextInitialized) {
GTEST_SKIP() << "OpenGL context not available";
return;
}
glfwMakeContextCurrent(m_window);
ClearGLErrors();
}
void OpenGLTestFixture::TearDown() {
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
}
ResetGLState();
}
void OpenGLTestFixture::MakeContextCurrent() {
if (m_window) {
glfwMakeContextCurrent(m_window);
}
}
void OpenGLTestFixture::DoneContextCurrent() {
glfwMakeContextCurrent(nullptr);
}
void OpenGLTestFixture::ClearGLErrors() {
while (glGetError() != GL_NO_ERROR);
}
bool OpenGLTestFixture::CheckGLError(const char* file, int line) {
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
ADD_FAILURE() << "OpenGL Error: " << error
<< " (" << GetGLErrorString(error) << ")"
<< " at " << file << ":" << line;
return false;
}
return true;
}
const char* OpenGLTestFixture::GetGLErrorString(GLenum error) {
switch (error) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
default: return "Unknown error";
}
}
void OpenGLTestFixture::ResetGLState() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glUseProgram(0);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
for (int i = 0; i < 16; ++i) {
glBindTexture(GL_TEXTURE_2D, 0);
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glDisable(GL_SCISSOR_TEST);
glDepthFunc(GL_LESS);
glStencilFunc(GL_ALWAYS, 0, 0xFF);
glBlendFunc(GL_ONE, GL_ZERO);
}

View File

@@ -0,0 +1,53 @@
#pragma once
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <gtest/gtest.h>
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
namespace XCEngine {
namespace RHI {
class OpenGLTestFixture : public ::testing::Test {
protected:
static void SetUpTestSuite();
static void TearDownTestSuite();
void SetUp() override;
void TearDown() override;
GLFWwindow* GetWindow() { return m_window; }
void MakeContextCurrent();
void DoneContextCurrent();
void ClearGLErrors();
bool CheckGLError(const char* file, int line);
const char* GetGLErrorString(GLenum error);
void ResetGLState();
private:
static GLFWwindow* m_window;
static bool m_contextInitialized;
static OpenGLDevice* m_device;
};
} // namespace RHI
} // namespace XCEngine
#define GL_CLEAR_ERRORS() \
do { while (glGetError() != GL_NO_ERROR); } while(0)
#define GL_CHECK(call) \
do { \
call; \
ASSERT_TRUE(XCEngine::RHI::OpenGLTestFixture::CheckGLError(__FILE__, __LINE__)) \
<< "GL error after " << #call; \
} while(0)
#define GL_EXPECT_SUCCESS(call) \
do { \
call; \
EXPECT_EQ(glGetError(), GL_NO_ERROR) \
<< "GL error after " << #call; \
} while(0)

View File

@@ -0,0 +1,89 @@
#include "fixtures/OpenGLTestFixture.h"
#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h"
using namespace XCEngine::RHI;
TEST_F(OpenGLTestFixture, Buffer_Initialize_VertexBuffer) {
OpenGLBuffer buffer;
float vertices[] = { 0.0f, 0.0f, 0.5f, 0.5f };
bool result = buffer.InitializeVertexBuffer(vertices, sizeof(vertices));
ASSERT_TRUE(result);
EXPECT_NE(buffer.GetID(), 0u);
EXPECT_EQ(buffer.GetSize(), sizeof(vertices));
EXPECT_EQ(buffer.GetType(), OpenGLBufferType::Vertex);
buffer.Shutdown();
}
TEST_F(OpenGLTestFixture, Buffer_Initialize_IndexBuffer) {
OpenGLBuffer buffer;
unsigned int indices[] = { 0, 1, 2 };
bool result = buffer.InitializeIndexBuffer(indices, sizeof(indices));
ASSERT_TRUE(result);
EXPECT_NE(buffer.GetID(), 0u);
EXPECT_EQ(buffer.GetSize(), sizeof(indices));
buffer.Shutdown();
}
TEST_F(OpenGLTestFixture, Buffer_Initialize_UniformBuffer) {
OpenGLBuffer buffer;
float data[16] = {};
bool result = buffer.Initialize(OpenGLBufferType::Uniform, sizeof(data), data, true);
ASSERT_TRUE(result);
EXPECT_TRUE(buffer.IsDynamic());
EXPECT_EQ(buffer.GetType(), OpenGLBufferType::Uniform);
buffer.Shutdown();
}
TEST_F(OpenGLTestFixture, Buffer_Initialize_Dynamic) {
OpenGLBuffer buffer;
bool result = buffer.Initialize(OpenGLBufferType::CopyRead, 256, nullptr, true);
ASSERT_TRUE(result);
EXPECT_TRUE(buffer.IsDynamic());
EXPECT_EQ(buffer.GetSize(), 256u);
buffer.Shutdown();
}
TEST_F(OpenGLTestFixture, Buffer_Bind_Unbind) {
OpenGLBuffer buffer;
buffer.InitializeVertexBuffer(nullptr, 16);
buffer.Bind();
GLint boundBuffer = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer);
EXPECT_EQ(boundBuffer, static_cast<GLint>(buffer.GetID()));
buffer.Unbind();
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer);
EXPECT_EQ(boundBuffer, 0);
buffer.Shutdown();
}
TEST_F(OpenGLTestFixture, Buffer_Map_Unmap) {
OpenGLBuffer buffer;
buffer.Initialize(OpenGLBufferType::CopyRead, 256, nullptr, true);
void* mappedData = buffer.Map();
ASSERT_NE(mappedData, nullptr);
memset(mappedData, 0xAB, 256);
buffer.Unmap();
GLenum error = glGetError();
EXPECT_EQ(error, GL_NO_ERROR);
buffer.Shutdown();
}

View File

@@ -0,0 +1,63 @@
#include "fixtures/OpenGLTestFixture.h"
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
using namespace XCEngine::RHI;
TEST_F(OpenGLTestFixture, Device_CreateRenderWindow_ValidParams) {
OpenGLDevice device;
bool result = device.CreateRenderWindow(800, 600, "Test Window", false);
ASSERT_TRUE(result);
ASSERT_NE(device.GetWindow(), nullptr);
}
TEST_F(OpenGLTestFixture, Device_CreateRenderWindow_DebugMode) {
OpenGLDevice device;
bool result = device.CreateRenderWindow(640, 480, "Debug Window", true);
ASSERT_TRUE(result);
ASSERT_NE(device.GetWindow(), nullptr);
}
TEST_F(OpenGLTestFixture, Device_InitializeWithExistingWindow) {
OpenGLDevice device;
GLFWwindow* existingWindow = GetWindow();
bool result = device.InitializeWithExistingWindow(existingWindow);
ASSERT_TRUE(result);
ASSERT_EQ(device.GetWindow(), existingWindow);
}
TEST_F(OpenGLTestFixture, Device_GetDeviceInfo_ReturnsValid) {
OpenGLDevice device;
device.CreateRenderWindow(800, 600, "Test", false);
const auto& info = device.GetDeviceInfo();
EXPECT_FALSE(info.vendor.empty());
EXPECT_FALSE(info.renderer.empty());
EXPECT_GE(info.majorVersion, 3);
EXPECT_GE(info.minorVersion, 0);
}
TEST_F(OpenGLTestFixture, Device_SwapBuffers_NoErrors) {
OpenGLDevice device;
device.CreateRenderWindow(800, 600, "Test", false);
device.SwapBuffers();
GLenum error = glGetError();
EXPECT_EQ(error, GL_NO_ERROR);
}
TEST_F(OpenGLTestFixture, Device_PollEvents_ReturnsTrue) {
OpenGLDevice device;
device.CreateRenderWindow(800, 600, "Test", false);
bool result = device.PollEvents();
EXPECT_TRUE(result);
}

View File

@@ -0,0 +1,61 @@
#include "fixtures/OpenGLTestFixture.h"
#include "XCEngine/RHI/OpenGL/OpenGLFence.h"
using namespace XCEngine::RHI;
TEST_F(OpenGLTestFixture, Fence_Initialize_Unsignaled) {
OpenGLFence fence;
bool result = fence.Initialize(false);
ASSERT_TRUE(result);
EXPECT_EQ(fence.GetStatus(), FenceStatus::Unsignaled);
fence.Shutdown();
}
TEST_F(OpenGLTestFixture, Fence_Initialize_Signaled) {
OpenGLFence fence;
bool result = fence.Initialize(true);
ASSERT_TRUE(result);
fence.Shutdown();
}
TEST_F(OpenGLTestFixture, Fence_Signal_Wait) {
OpenGLFence fence;
fence.Initialize(false);
fence.Signal(1);
fence.Wait(1);
EXPECT_TRUE(fence.IsSignaled());
EXPECT_EQ(fence.GetCompletedValue(), 1u);
fence.Shutdown();
}
TEST_F(OpenGLTestFixture, Fence_IsSignaled_ReturnsState) {
OpenGLFence fence;
fence.Initialize(false);
fence.Signal(1);
fence.Wait(1);
EXPECT_TRUE(fence.IsSignaled());
fence.Shutdown();
}
TEST_F(OpenGLTestFixture, Fence_GetStatus_ReturnsCorrect) {
OpenGLFence fence;
fence.Initialize(false);
FenceStatus status = fence.GetStatus();
EXPECT_TRUE(status == FenceStatus::Signaled || status == FenceStatus::Unsignaled);
fence.Shutdown();
}