fix: encapsulate OpenGL types in VertexAttribute to eliminate raw GL API usage in tests

- Add VertexAttributeType and VertexAttributeNormalized enums in OpenGLVertexArray.h
- Add ToGLAttributeType() converter in OpenGLVertexArray.cpp
- Remove glActiveTexture() call from quad test (already handled by texture.Bind())
- Remove #include <glad/glad.h> from triangle test
- Update unit tests to use encapsulated enums

All three OpenGL integration tests (minimal, triangle, quad) pass with 0% pixel difference.
This commit is contained in:
2026-03-22 14:33:57 +08:00
parent 1f129ed20f
commit 1797e7fe17
10 changed files with 61 additions and 112 deletions

View File

@@ -1,89 +0,0 @@
# AudioClip
**命名空间**: `XCEngine::Resources`
**类型**: `class`
**描述**: 音频片段资源类,管理音频样本数据、格式信息和播放参数。
## 概述
`AudioClip` 是 XCEngine 中的音频资源类,继承自 `IResource`。它管理音频的原始样本数据、采样率、通道数、位深度、时长、格式类型和播放参数。AudioClip 支持 WAV、OGG、MP3、FLAC 等多种音频格式,可用于音效、音乐、语音和环境音等不同用途。
## 公共方法
| 方法 | 描述 |
|------|------|
| [`AudioClip`](audio-clip.md) | 构造函数 |
| [`~AudioClip`](dtor.md) | 析构函数 |
| [`GetType`](get-type.md) | 获取资源类型 |
| [`GetName`](get-name.md) | 获取音频名称 |
| [`GetPath`](get-path.md) | 获取音频路径 |
| [`GetGUID`](get-guid.md) | 获取全局唯一标识符 |
| [`IsValid`](is-valid.md) | 检查音频是否有效 |
| [`GetMemorySize`](get-memory-size.md) | 获取内存大小 |
| [`Release`](release.md) | 释放音频资源 |
| [`SetAudioData`](setaudiodata.md) | 设置音频数据 |
| [`GetAudioData`](get-audio-data.md) | 获取音频数据 |
| [`SetSampleRate`](set-sample-rate.md) | 设置采样率 |
| [`GetSampleRate`](get-sample-rate.md) | 获取采样率 |
| [`SetChannels`](set-channels.md) | 设置通道数 |
| [`GetChannels`](get-channels.md) | 获取通道数 |
| [`SetBitsPerSample`](set-bits-per-sample.md) | 设置位深度 |
| [`GetBitsPerSample`](get-bits-per-sample.md) | 获取位深度 |
| [`SetDuration`](set-duration.md) | 设置时长 |
| [`GetDuration`](get-duration.md) | 获取时长 |
| [`SetAudioFormat`](set-audio-format.md) | 设置音频格式 |
| [`GetAudioFormat`](get-audio-format.md) | 获取音频格式 |
| [`SetAudioType`](set-audio-type.md) | 设置音频类型 |
| [`GetAudioType`](get-audio-type.md) | 获取音频类型 |
| [`SetIs3D`](set-is-3d.md) | 设置是否为 3D 音频 |
| [`Is3D`](is-3d.md) | 检查是否为 3D 音频 |
| [`SetLoop`](set-loop.md) | 设置是否循环播放 |
| [`IsLoop`](is-loop.md) | 检查是否循环播放 |
| [`GetRHIResource`](get-rhi-resource.md) | 获取 RHI 音频缓冲区 |
| [`SetRHIResource`](set-rhi-resource.md) | 设置 RHI 音频缓冲区 |
## 使用示例
```cpp
#include "Resources/AudioClip.h"
#include "Resources/ResourceManager.h"
#include "Resources/ResourceFileSystem.h"
using namespace XCEngine::Resources;
AudioClip* CreateExplosionSound() {
AudioClip* clip = new AudioClip();
auto wavData = ResourceFileSystem::Get().ReadResource("sounds/explosion.wav");
clip->SetAudioData(wavData);
clip->SetSampleRate(44100);
clip->SetChannels(2);
clip->SetBitsPerSample(16);
clip->SetDuration(1.5f);
clip->SetAudioFormat(AudioFormat::WAV);
clip->SetAudioType(AudioType::SoundEffect);
clip->SetLoop(false);
clip->SetIs3D(false);
return clip;
}
void PlaySoundEffect() {
ResourceHandle<AudioClip> sfx = ResourceManager::Get().Load<AudioClip>("sounds/explosion.wav");
if (sfx->IsValid()) {
uint32_t sampleRate = sfx->GetSampleRate();
float duration = sfx->GetDuration();
bool loop = sfx->IsLoop();
AudioFormat format = sfx->GetAudioFormat();
AudioType type = sfx->GetAudioType();
}
}
```
## 相关文档
- [IResource](../iresource/iresource.md) - 资源基类
- [Resources](../resources.md) - 资源模块总览

View File

@@ -6,11 +6,32 @@
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
enum class VertexAttributeType {
Float = 0,
Int,
UnsignedInt,
Short,
UnsignedShort,
Byte,
UnsignedByte,
Double,
HalfFloat,
Fixed,
Int2101010Rev,
UnsignedInt2101010Rev,
UnsignedInt10F11F11FRev
};
enum class VertexAttributeNormalized {
False = 0,
True
};
struct VertexAttribute { struct VertexAttribute {
unsigned int index; unsigned int index;
int count; int count;
unsigned int type; VertexAttributeType type;
bool normalized; VertexAttributeNormalized normalized;
size_t stride; size_t stride;
size_t offset; size_t offset;
}; };

View File

@@ -4,6 +4,25 @@
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
static unsigned int ToGLAttributeType(VertexAttributeType type) {
switch (type) {
case VertexAttributeType::Float: return GL_FLOAT;
case VertexAttributeType::Int: return GL_INT;
case VertexAttributeType::UnsignedInt: return GL_UNSIGNED_INT;
case VertexAttributeType::Short: return GL_SHORT;
case VertexAttributeType::UnsignedShort: return GL_UNSIGNED_SHORT;
case VertexAttributeType::Byte: return GL_BYTE;
case VertexAttributeType::UnsignedByte: return GL_UNSIGNED_BYTE;
case VertexAttributeType::Double: return GL_DOUBLE;
case VertexAttributeType::HalfFloat: return GL_HALF_FLOAT;
case VertexAttributeType::Fixed: return GL_FIXED;
case VertexAttributeType::Int2101010Rev: return GL_INT_2_10_10_10_REV;
case VertexAttributeType::UnsignedInt2101010Rev: return GL_UNSIGNED_INT_2_10_10_10_REV;
case VertexAttributeType::UnsignedInt10F11F11FRev: return GL_UNSIGNED_INT_10F_11F_11F_REV;
default: return GL_FLOAT;
}
}
OpenGLVertexArray::OpenGLVertexArray() OpenGLVertexArray::OpenGLVertexArray()
: m_vao(0) : m_vao(0)
, m_indexBuffer(0) , m_indexBuffer(0)
@@ -24,8 +43,9 @@ void OpenGLVertexArray::AddVertexBuffer(unsigned int buffer, const VertexAttribu
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(attribute.index); glEnableVertexAttribArray(attribute.index);
glVertexAttribPointer(attribute.index, attribute.count, attribute.type, glVertexAttribPointer(attribute.index, attribute.count,
attribute.normalized ? GL_TRUE : GL_FALSE, ToGLAttributeType(attribute.type),
attribute.normalized == VertexAttributeNormalized::True ? GL_TRUE : GL_FALSE,
attribute.stride, (void*)attribute.offset); attribute.stride, (void*)attribute.offset);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);

View File

@@ -127,8 +127,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
VertexAttribute posAttr = {}; VertexAttribute posAttr = {};
posAttr.index = 0; posAttr.index = 0;
posAttr.count = 4; posAttr.count = 4;
posAttr.type = GL_FLOAT; posAttr.type = VertexAttributeType::Float;
posAttr.normalized = GL_FALSE; posAttr.normalized = VertexAttributeNormalized::False;
posAttr.stride = sizeof(Vertex); posAttr.stride = sizeof(Vertex);
posAttr.offset = 0; posAttr.offset = 0;
vertexArray.AddVertexBuffer(vertexBuffer.GetID(), posAttr); vertexArray.AddVertexBuffer(vertexBuffer.GetID(), posAttr);
@@ -136,8 +136,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
VertexAttribute texAttr = {}; VertexAttribute texAttr = {};
texAttr.index = 1; texAttr.index = 1;
texAttr.count = 2; texAttr.count = 2;
texAttr.type = GL_FLOAT; texAttr.type = VertexAttributeType::Float;
texAttr.normalized = GL_FALSE; texAttr.normalized = VertexAttributeNormalized::False;
texAttr.stride = sizeof(Vertex); texAttr.stride = sizeof(Vertex);
texAttr.offset = sizeof(float) * 4; texAttr.offset = sizeof(float) * 4;
vertexArray.AddVertexBuffer(vertexBuffer.GetID(), texAttr); vertexArray.AddVertexBuffer(vertexBuffer.GetID(), texAttr);
@@ -200,7 +200,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
pipelineState.Bind(); pipelineState.Bind();
vertexArray.Bind(); vertexArray.Bind();
glActiveTexture(GL_TEXTURE0);
texture.Bind(0); texture.Bind(0);
sampler.Bind(0); sampler.Bind(0);

View File

@@ -5,8 +5,6 @@
#include <windows.h> #include <windows.h>
#include <glad/glad.h>
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h" #include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
#include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h" #include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h"
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h" #include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
@@ -124,8 +122,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
VertexAttribute posAttr = {}; VertexAttribute posAttr = {};
posAttr.index = 0; posAttr.index = 0;
posAttr.count = 4; posAttr.count = 4;
posAttr.type = GL_FLOAT; posAttr.type = VertexAttributeType::Float;
posAttr.normalized = GL_FALSE; posAttr.normalized = VertexAttributeNormalized::False;
posAttr.stride = sizeof(Vertex); posAttr.stride = sizeof(Vertex);
posAttr.offset = 0; posAttr.offset = 0;
vertexArray.AddVertexBuffer(vertexBuffer.GetID(), posAttr); vertexArray.AddVertexBuffer(vertexBuffer.GetID(), posAttr);
@@ -133,8 +131,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
VertexAttribute colAttr = {}; VertexAttribute colAttr = {};
colAttr.index = 1; colAttr.index = 1;
colAttr.count = 4; colAttr.count = 4;
colAttr.type = GL_FLOAT; colAttr.type = VertexAttributeType::Float;
colAttr.normalized = GL_FALSE; colAttr.normalized = VertexAttributeNormalized::False;
colAttr.stride = sizeof(Vertex); colAttr.stride = sizeof(Vertex);
colAttr.offset = sizeof(float) * 4; colAttr.offset = sizeof(float) * 4;
vertexArray.AddVertexBuffer(vertexBuffer.GetID(), colAttr); vertexArray.AddVertexBuffer(vertexBuffer.GetID(), colAttr);

View File

@@ -54,8 +54,8 @@ TEST_F(OpenGLTestFixture, CommandList_Draw_VAO) {
VertexAttribute attr; VertexAttribute attr;
attr.index = 0; attr.index = 0;
attr.count = 3; attr.count = 3;
attr.type = GL_FLOAT; attr.type = VertexAttributeType::Float;
attr.normalized = false; attr.normalized = VertexAttributeNormalized::False;
attr.stride = sizeof(float) * 3; attr.stride = sizeof(float) * 3;
attr.offset = 0; attr.offset = 0;
vao.AddVertexBuffer(vbo.GetID(), attr); vao.AddVertexBuffer(vbo.GetID(), attr);

View File

@@ -25,8 +25,8 @@ TEST_F(OpenGLTestFixture, VertexArray_AddVertexBuffer) {
VertexAttribute attr; VertexAttribute attr;
attr.index = 0; attr.index = 0;
attr.count = 3; attr.count = 3;
attr.type = GL_FLOAT; attr.type = VertexAttributeType::Float;
attr.normalized = false; attr.normalized = VertexAttributeNormalized::False;
attr.stride = sizeof(float) * 3; attr.stride = sizeof(float) * 3;
attr.offset = 0; attr.offset = 0;
@@ -84,16 +84,16 @@ TEST_F(OpenGLTestFixture, VertexArray_Bind_MultipleAttributes) {
VertexAttribute attrPos; VertexAttribute attrPos;
attrPos.index = 0; attrPos.index = 0;
attrPos.count = 2; attrPos.count = 2;
attrPos.type = GL_FLOAT; attrPos.type = VertexAttributeType::Float;
attrPos.normalized = false; attrPos.normalized = VertexAttributeNormalized::False;
attrPos.stride = sizeof(float) * 2; attrPos.stride = sizeof(float) * 2;
attrPos.offset = 0; attrPos.offset = 0;
VertexAttribute attrColor; VertexAttribute attrColor;
attrColor.index = 1; attrColor.index = 1;
attrColor.count = 4; attrColor.count = 4;
attrColor.type = GL_FLOAT; attrColor.type = VertexAttributeType::Float;
attrColor.normalized = false; attrColor.normalized = VertexAttributeNormalized::False;
attrColor.stride = sizeof(float) * 4; attrColor.stride = sizeof(float) * 4;
attrColor.offset = 0; attrColor.offset = 0;