Bluely Engine 开发手册
📖 目录
-
引擎概述
-
快速开始
-
核心系统
-
图形渲染
-
输入系统
-
音频系统
-
资源管理
-
场景管理
-
性能优化
-
调试工具
-
API参考
🎯 引擎概述
特性概览
· 多API渲染: 支持DX9/DX12,可扩展支持OpenGL/Vulkan
· 现代化架构: 基于组件,支持ECS模式
· 跨平台: Windows优先,可扩展至其他平台
· 高性能: 多线程渲染,异步资源加载
· 工具链完整: 调试、分析、热重载工具
系统要求
· 操作系统: Windows 10/11 (64位)
· 编译器: Visual Studio 2019+ 或支持C++17的编译器
· 内存: 4GB RAM (建议8GB)
· 显卡: 支持DirectX 9.0c或更高
🚀 快速开始
项目设置
- 创建新项目
```cpp
// main.cpp
#include "BluelyEngine.h"
class MyGame : public bluely::core::GameApplication {
public:
bool Initialize() override {
// 引擎初始化
if (!bluely::Engine::GetInstance().Initialize()) {
return false;
}
// 创建窗口
m_window = bluely::platform::CreateWindow("My Game", 1280, 720);
// 初始化渲染器
m_renderer = bluely::graphics::RenderSystem::GetInstance().CreateRenderer();
// 加载启动资源
LoadInitialResources();
return true;
}
void Update(float deltaTime) override {
// 更新游戏逻辑
UpdateGameLogic(deltaTime);
// 更新输入
bluely::input::InputSystem::GetInstance().Update();
// 更新物理
m_physicsWorld.StepSimulation(deltaTime);
}
void Render() override {
// 开始渲染帧
m_renderer->BeginFrame();
// 渲染场景
m_sceneManager.Render(m_renderer);
// 渲染UI
m_uiSystem.Render();
// 结束渲染帧
m_renderer->EndFrame();
m_renderer->Present();
}
void Shutdown() override {
// 清理资源
bluely::Engine::GetInstance().Shutdown();
}
};
// 程序入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
MyGame game;
return game.Run();
}
```
- CMake配置
```cmake
cmake_minimum_required(VERSION 3.15)
project(MyGame)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
包含引擎
add_subdirectory(BluelyEngine)
创建可执行文件
add_executable(MyGame main.cpp)
链接引擎库
target_link_libraries(MyGame PRIVATE
BluelyCore
BluelyGraphics
BluelyInput
BluelyAudio
BluelyPhysics
)
设置输出目录
set_target_properties(MyGame PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
```
⚙️ 核心系统
配置系统
```cpp
// 引擎配置
bluely::core::EngineConfig config;
config.appName = "My Game";
config.screenWidth = 1280;
config.screenHeight = 720;
config.fullscreen = false;
config.vsync = true;
config.multisampleCount = 4;
config.renderAPI = bluely::graphics::RenderAPI::DirectX12;
// 初始化引擎
bluely::Engine::GetInstance().Initialize(config);
// 运行时配置修改
bluely::Engine::GetInstance().SetVSync(true);
bluely::Engine::GetInstance().SetResolution(1920, 1080);
```
内存管理
```cpp
// 智能指针
auto texture = bluely::core::MakeShared<bluely::graphics::Texture>();
auto mesh = bluely::core::MakeUnique<bluely::graphics::Mesh>();
// 内存池
bluely::core::MemoryPool pool(1024 * 1024); // 1MB池
void* data = pool.Allocate(256); // 分配256字节
// 内存统计
bluely::core::MemoryStats stats = bluely::core::MemoryManager::GetStats();
LOG_INFO("内存使用: {} MB", stats.used / (1024 * 1024));
```
日志系统
```cpp
// 基本日志
LOG_TRACE("详细调试信息");
LOG_DEBUG("调试信息");
LOG_INFO("普通信息");
LOG_WARNING("警告信息");
LOG_ERROR("错误信息");
LOG_FATAL("致命错误");
// 格式化日志
LOG_INFO("玩家 {} 获得了 {} 分", playerName, score);
// 条件日志
LOG_IF(infoLevel > 0, "显示额外信息");
// 性能日志
PERF_SCOPE("渲染循环");
{
PERF_SCOPE("场景渲染");
// 渲染代码...
}
// 日志配置
bluely::debug::Console::GetInstance().SetLogLevel(
bluely::debug::LogLevel::Info
);
bluely::debug::Console::GetInstance().EnableFileOutput("game.log");
```
🎨 图形渲染
初始化渲染器
```cpp
// 创建渲染器配置
bluely::graphics::RenderConfig renderConfig;
renderConfig.windowHandle = window->GetHandle();
renderConfig.width = 1280;
renderConfig.height = 720;
renderConfig.vsync = true;
renderConfig.msaaLevel = 4;
// 初始化渲染系统
bluely::graphics::RenderSystem::GetInstance().Initialize(renderConfig);
// 获取渲染设备
auto device = bluely::graphics::RenderSystem::GetInstance().GetDevice();
```
创建材质
```cpp
// 材质定义
auto material = bluely::core::MakeShared<bluely::graphics::Material>();
// 设置着色器
material->SetShader(bluely::graphics::ShaderType::Vertex, "shaders/basic.vs");
material->SetShader(bluely::graphics::ShaderType::Pixel, "shaders/basic.ps");
// 设置纹理
auto diffuseTex = bluely::graphics::Texture::Load("textures/diffuse.png");
auto normalTex = bluely::graphics::Texture::Load("textures/normal.png");
material->SetTexture("DiffuseMap", diffuseTex);
material->SetTexture("NormalMap", normalTex);
// 材质参数
material->SetParameter("Color", bluely::math::Vector4(1.0f, 1.0f, 1.0f, 1.0f));
material->SetParameter("Roughness", 0.5f);
material->SetParameter("Metallic", 0.0f);
// 渲染状态
material->SetBlendState(bluely::graphics::BlendState::Opaque);
material->SetDepthState(bluely::graphics::DepthState::Default);
material->SetRasterizerState(bluely::graphics::RasterizerState::Default);
// 保存材质
material->Save("materials/basic.mat");
```
网格渲染
```cpp
// 加载网格
auto mesh = bluely::graphics::Mesh::Load("models/character.fbx");
// 创建渲染组件
auto meshRenderer = bluely::core::MakeShared<bluely::graphics::MeshRenderer>();
// 设置网格和材质
meshRenderer->SetMesh(mesh);
meshRenderer->SetMaterial(0, material); // 为子网格0设置材质
// 添加到实体
entity->AddComponent(meshRenderer);
// 实例化渲染
bluely::graphics::InstanceData instanceData;
instanceData.worldMatrix = transform->GetWorldMatrix();
instanceData.color = bluely::math::Vector4(1.0f, 1.0f, 1.0f, 1.0f);
meshRenderer->AddInstance(instanceData);
```
后期处理
```cpp
// 创建后期处理管线
auto postProcess = bluely::core::MakeShared<bluely::graphics::PostProcessPipeline>();
// 添加效果
postProcess->AddEffect(bluely::graphics::PostEffectType::Bloom);
postProcess->AddEffect(bluely::graphics::PostEffectType::SSAO);
postProcess->AddEffect(bluely::graphics::PostEffectType::ToneMapping);
postProcess->AddEffect(bluely::graphics::PostEffectType::FXAA);
// 配置效果参数
auto bloom = postProcess->GetEffect<bluely::graphics::BloomEffect>();
bloom->SetIntensity(0.8f);
bloom->SetThreshold(0.7f);
bloom->SetRadius(4.0f);
auto ssao = postProcess->GetEffect<bluely::graphics::SSAOEffect>();
ssao->SetRadius(0.5f);
ssao->SetPower(2.0f);
ssao->SetBias(0.025f);
// 应用到渲染器
bluely::graphics::RenderSystem::GetInstance().SetPostProcessPipeline(postProcess);
```
2D渲染
```cpp
// 创建2D渲染器
auto spriteRenderer = bluely::core::MakeShared<bluely::graphics::SpriteRenderer>();
// 加载精灵
auto sprite = bluely::graphics::Sprite::Load("sprites/character.png");
// 创建动画
auto animation = bluely::core::MakeShared<bluely::graphics::SpriteAnimation>();
animation->AddFrame(sprite, 0.1f); // 帧持续0.1秒
animation->SetLoop(true);
// 创建精灵组件
auto spriteComponent = bluely::core::MakeShared<bluely::graphics::SpriteComponent>();
spriteComponent->SetAnimation(animation);
spriteComponent->SetPosition(bluely::math::Vector2(100, 100));
spriteComponent->SetScale(2.0f);
spriteComponent->SetColor(bluely::math::Color::White);
// 批处理渲染
bluely::graphics::SpriteBatch batch;
batch.Begin();
batch.Draw(sprite, position, rotation, scale, color);
batch.DrawString(font, "Hello World!", textPosition, textColor);
batch.End();
```
UI系统
```cpp
// 创建UI管理器
auto uiManager = bluely::core::MakeShared<bluely::ui::UIManager>();
// 创建窗口
auto window = bluely::core::MakeShared<bluely::ui::Window>();
window->SetTitle("设置");
window->SetSize(bluely::math::Vector2(400, 300));
window->SetPosition(bluely::math::Vector2(100, 100));
// 添加控件
auto label = bluely::core::MakeShared<bluely::ui::Label>();
label->SetText("音量:");
label->SetPosition(bluely::math::Vector2(20, 50));
auto slider = bluely::core::MakeShared<bluely::ui::Slider>();
slider->SetRange(0.0f, 1.0f);
slider->SetValue(0.7f);
slider->SetPosition(bluely::math::Vector2(80, 50));
slider->SetSize(bluely::math::Vector2(200, 20));
slider->OnValueChanged([](float value) {
bluely::audio::AudioSystem::GetInstance().SetMasterVolume(value);
});
auto button = bluely::core::MakeShared<bluely::ui::Button>();
button->SetText("确定");
button->SetPosition(bluely::math::Vector2(150, 200));
button->SetSize(bluely::math::Vector2(100, 30));
button->OnClick([]() {
window->Close();
});
// 添加到窗口
window->AddChild(label);
window->AddChild(slider);
window->AddChild(button);
// 添加到UI管理器
uiManager->AddWindow(window);
```
🎮 输入系统
基础输入
```cpp
// 初始化输入系统
bluely::input::InputSystem::GetInstance().Initialize(windowHandle);
// 每帧更新
void Update(float deltaTime) {
bluely::input::InputSystem::GetInstance().Update();
// 键盘输入
if (bluely::input::InputSystem::GetInstance().IsKeyPressed(
bluely::input::KeyCode::Space)) {
Jump();
}
// 鼠标输入
if (bluely::input::InputSystem::GetInstance().IsMouseButtonPressed(
bluely::input::MouseButton::Left)) {
Shoot();
}
auto mousePos = bluely::input::InputSystem::GetInstance().GetMousePosition();
auto mouseDelta = bluely::input::InputSystem::GetInstance().GetMouseDelta();
// 游戏手柄输入
if (bluely::input::InputSystem::GetInstance().IsGamepadButtonPressed(
0, bluely::input::GamepadButton::A)) {
Confirm();
}
float leftStickX = bluely::input::InputSystem::GetInstance().GetGamepadAxis(
0, bluely::input::GamepadAxis::LeftStickX);
}
```
输入映射
```cpp
// 创建输入上下文
auto inputContext = bluely::core::MakeShared<bluely::input::InputContext>("Gameplay");
// 定义动作
inputContext->AddAction("MoveForward", {
.keys = { bluely::input::KeyCode::W },
.gamepadButtons = { bluely::input::GamepadButton::DPadUp },
.gamepadAxes = { bluely::input::GamepadAxis::LeftStickY }
});
inputContext->AddAction("Jump", {
.keys = { bluely::input::KeyCode::Space },
.gamepadButtons = { bluely::input::GamepadButton::A }
});
inputContext->AddAction("Attack", {
.mouseButtons = { bluely::input::MouseButton::Left },
.gamepadButtons = { bluely::input::GamepadButton::X }
});
// 激活上下文
bluely::input::InputSystem::GetInstance().PushContext(inputContext);
// 使用动作
void Update(float deltaTime) {
float moveForward = bluely::input::InputSystem::GetInstance().GetActionValue("MoveForward");
if (moveForward > 0) {
MoveForward(moveForward);
}
if (bluely::input::InputSystem::GetInstance().IsActionPressed("Jump")) {
Jump();
}
if (bluely::input::InputSystem::GetInstance().IsActionHeld("Attack")) {
Attack();
}
}
```
输入配置
```cpp
// 保存输入配置
bluely::input::InputConfig config;
// 设置键盘映射
config.SetKeyMapping("MoveForward", { bluely::input::KeyCode::W });
config.SetKeyMapping("MoveBackward", { bluely::input::KeyCode::S });
config.SetKeyMapping("MoveLeft", { bluely::input::KeyCode::A });
config.SetKeyMapping("MoveRight", { bluely::input::KeyCode::D });
// 设置鼠标灵敏度
config.SetMouseSensitivity(0.5f);
config.SetInvertYAxis(false);
// 设置游戏手柄死区
config.SetGamepadDeadZone(bluely::input::GamepadAxis::LeftStickX, 0.15f);
config.SetGamepadDeadZone(bluely::input::GamepadAxis::LeftStickY, 0.15f);
// 保存到文件
config.Save("config/input.json");
// 从文件加载
config.Load("config/input.json");
// 应用到系统
bluely::input::InputSystem::GetInstance().ApplyConfig(config);
```
🔊 音频系统
基础音频
```cpp
// 初始化音频系统
bluely::audio::AudioConfig audioConfig;
audioConfig.sampleRate = 44100;
audioConfig.channels = bluely::audio::AudioChannels::Stereo;
audioConfig.enable3DAudio = true;
audioConfig.maxVoices = 64;
bluely::audio::AudioSystem::GetInstance().Initialize(audioConfig);
// 加载音频
auto bgm = bluely::audio::AudioSystem::GetInstance().LoadSound(
"bgm", "audio/music/bgm.ogg", true); // 流式播放
auto sfxJump = bluely::audio::AudioSystem::GetInstance().LoadSound(
"jump", "audio/sfx/jump.wav");
// 播放音频
bluely::audio::PlaybackParams params;
params.volume = 0.8f;
params.loopMode = bluely::audio::LoopMode::Loop;
params.bus = bluely::audio::AudioBus::Music;
auto bgmInstance = bluely::audio::AudioSystem::GetInstance().PlaySound("bgm", params);
// 播放音效
bluely::audio::PlaybackParams sfxParams;
sfxParams.volume = 1.0f;
sfxParams.pitch = 1.0f;
sfxParams.bus = bluely::audio::AudioBus::SFX;
bluely::audio::AudioSystem::GetInstance().PlaySound("jump", sfxParams);
// 控制播放
bgmInstance->SetVolume(0.5f);
bgmInstance->Pause();
bgmInstance->Resume();
bgmInstance->Stop();
```
3D音频
```cpp
// 设置监听器(通常是玩家摄像机)
auto& listener = bluely::audio::AudioSystem::GetInstance().GetListener();
listener.SetPosition(camera->GetPosition());
listener.SetOrientation(camera->GetForward(), camera->GetUp());
// 创建3D音效
bluely::audio::PlaybackParams spatialParams;
spatialParams.spatialMode = bluely::audio::Audio3DMode::Absolute;
spatialParams.position = enemy->GetPosition();
spatialParams.minDistance = 5.0f;
spatialParams.maxDistance = 50.0f;
auto spatialSound = bluely::audio::AudioSystem::GetInstance().PlaySound(
"enemy_growl", spatialParams);
// 更新位置
void Update(float deltaTime) {
spatialSound->SetPosition(enemy->GetPosition());
spatialSound->SetVelocity(enemy->GetVelocity());
}
// 环境音效
auto ambientSound = bluely::audio::AudioSystem::GetInstance().PlaySound(
"forest_ambient", {
.volume = 0.3f,
.loopMode = bluely::audio::LoopMode::Loop,
.bus = bluely::audio::AudioBus::Ambient
});
```
音频混合
```cpp
// 获取音频总线
auto masterBus = bluely::audio::AudioSystem::GetInstance().GetBus(
bluely::audio::AudioBus::Master);
auto musicBus = bluely::audio::AudioSystem::GetInstance().GetBus(
bluely::audio::AudioBus::Music);
auto sfxBus = bluely::audio::AudioSystem::GetInstance().GetBus(
bluely::audio::AudioBus::SFX);
// 设置总线音量
masterBus->SetVolume(1.0f);
musicBus->SetVolume(0.7f);
sfxBus->SetVolume(1.0f);
// 静音特定总线
musicBus->SetMuted(true); // 静音音乐
sfxBus->SetPaused(true); // 暂停音效
// 添加效果器到总线
auto reverbEffect = bluely::core::MakeShared<bluely::audio::ReverbEffect>();
reverbEffect->SetEnabled(true);
reverbEffect->UpdateParams(&bluely::audio::ReverbParams{
.decayTime = 2.0f,
.density = 0.8f,
.diffusion = 0.7f
});
musicBus->AddEffect(reverbEffect);
// 动态音量控制(淡入淡出)
bluely::audio::AudioSystem::GetInstance().FadeBusVolume(
bluely::audio::AudioBus::Music,
0.0f, // 目标音量
2.0f // 淡出时间(秒)
);
```
音频分析
```cpp
// 启用音频分析
bluely::audio::AudioSystem::GetInstance().EnableAnalysis(true);
// 获取分析数据
void Update(float deltaTime) {
const auto& analysis = bluely::audio::AudioSystem::GetInstance()
.GetGlobalAnalysis();
// 音量信息
float rms = analysis.rms; // 均方根音量
float peak = analysis.peak; // 峰值音量
// 频谱数据(可用于可视化)
for (int i = 0; i < 256; i++) {
float frequencyAmplitude = analysis.spectrum[i];
// 绘制频谱条
}
// 节拍检测
if (analysis.beatDetected) {
OnBeat(); // 触发节拍事件
}
// BPM信息
float bpm = analysis.beatsPerMinute;
}
// 自定义音频可视化
void RenderAudioVisualizer() {
const auto& analysis = bluely::audio::AudioSystem::GetInstance()
.GetGlobalAnalysis();
bluely::graphics::SpriteBatch batch;
batch.Begin();
float barWidth = 5.0f;
float barSpacing = 2.0f;
float maxHeight = 100.0f;
for (int i = 0; i < 64; i++) { // 使用前64个频段
float amplitude = analysis.spectrum[i];
float barHeight = amplitude * maxHeight;
float x = i * (barWidth + barSpacing);
float y = 0;
// 绘制频谱条
bluely::graphics::Rectangle barRect(
x, y, barWidth, barHeight);
// 根据频率设置颜色
bluely::math::Color color = bluely::math::Color::Lerp(
bluely::math::Color::Blue,
bluely::math::Color::Red,
i / 64.0f
);
batch.DrawRectangle(barRect, color);
}
// 绘制峰值指示器
float peakX = analysis.peak * (64 * (barWidth + barSpacing));
batch.DrawLine(
bluely::math::Vector2(peakX, 0),
bluely::math::Vector2(peakX, maxHeight),
bluely::math::Color::Yellow,
2.0f
);
batch.End();
}
```
📦 资源管理
资源加载
```cpp
// 异步资源加载
bluely::resource::ResourceManager::GetInstance().LoadAsync(
"characters/hero.fbx",
bluely::resource::ResourceType::Mesh,
\](const bluely::resource::ResourceHandle\& handle) {
if (handle.IsValid()) {
auto mesh = handle.GetResource\();
// 使用网格...
}
}
);
// 批量加载
bluely::resource::ResourceBundle bundle;
bundle.Add("textures/diffuse.png", bluely::resource::ResourceType::Texture);
bundle.Add("textures/normal.png", bluely::resource::ResourceType::Texture);
bundle.Add("models/character.fbx", bluely::resource::ResourceType::Mesh);
bundle.Add("shaders/basic.shader", bluely::resource::ResourceType::Shader);
bluely::resource::ResourceManager::GetInstance().LoadBundle(
bundle,
\[\](const bluely::resource::ResourceBundle\& loadedBundle) {
// 所有资源加载完成
StartGame();
}
);
// 流式加载
bluely::resource::StreamingManager::GetInstance().SetStreamingRadius(100.0f);
bluely::resource::StreamingManager::GetInstance().AddStreamingZone(
player-\>GetPosition(), 50.0f, "zone1"
);
// 资源预加载
bluely::resource::Preloader preloader;
preloader.PreloadScene("levels/forest.level");
preloader.SetProgressCallback(\[\](float progress) {
UpdateLoadingScreen(progress);
});
\`\`\`
资源热重载
\`\`\`cpp
// 启用文件监视
bluely::resource::ResourceManager::GetInstance().EnableHotReload(true);
// 设置资源目录
bluely::resource::ResourceManager::GetInstance().AddResourceDirectory(
"assets/textures"
);
// 监听资源变化
bluely::resource::ResourceManager::GetInstance().OnResourceReloaded(
\[\](const String\& resourcePath, bluely::resource::ResourceType type) {
LOG_INFO("资源已重新加载: {}", resourcePath);
if (type == bluely::resource::ResourceType::Texture) {
// 更新材质
UpdateMaterialTextures();
}
}
);
// 手动重载
bluely::resource::ResourceManager::GetInstance().ReloadResource(
"shaders/basic.shader"
);
// 重新加载所有资源
bluely::resource::ResourceManager::GetInstance().ReloadAllResources();
\`\`\`
---
🌳 场景管理
场景图
\`\`\`cpp
// 创建场景
auto scene = bluely::core::MakeShared\("MainScene");
// 创建实体
auto player = scene-\>CreateEntity("Player");
auto enemy = scene-\>CreateEntity("Enemy");
auto camera = scene-\>CreateEntity("MainCamera");
// 添加组件
player-\>AddComponent\();
player-\>AddComponent\();
player-\>AddComponent\();
player-\>AddComponent\();
// 设置层级关系
scene-\>SetParent(camera, player); // 摄像机跟随玩家
// 查询实体
auto players = scene-\>FindEntitiesWithComponent\();
auto renderables = scene-\>FindEntitiesWithComponent\();
// 保存场景
scene-\>Save("scenes/main.scene");
// 加载场景
auto loadedScene = bluely::scene::Scene::Load("scenes/main.scene");
bluely::scene::SceneManager::GetInstance().SetActiveScene(loadedScene);
\`\`\`
实体组件系统
\`\`\`cpp
// 定义组件
class HealthComponent : public bluely::ecs::Component {
public:
float maxHealth = 100.0f;
float currentHealth = 100.0f;
float regenerationRate = 1.0f;
void Update(float deltaTime) override {
currentHealth = std::min(maxHealth,
currentHealth + regenerationRate \* deltaTime);
}
void TakeDamage(float damage) {
currentHealth -= damage;
if (currentHealth \<= 0) {
OnDeath();
}
}
float GetHealthPercentage() const {
return currentHealth / maxHealth;
}
};
// 定义系统
class HealthSystem : public bluely::ecs::System {
public:
void Update(float deltaTime) override {
ForEach\(\[\](bluely::ecs::Entity entity,
HealthComponent\& health) {
health.Update(deltaTime);
// 检查死亡
if (health.currentHealth \<= 0) {
entity.Destroy();
}
});
}
void HealAll(float amount) {
ForEach\(\[amount\](bluely::ecs::Entity entity,
HealthComponent\& health) {
health.currentHealth = std::min(health.maxHealth,
health.currentHealth + amount);
});
}
};
// 使用ECS
auto ecsWorld = bluely::core::MakeShared\();
// 注册组件和系统
ecsWorld-\>RegisterComponent\();
ecsWorld-\>RegisterSystem\();
// 创建实体
auto entity = ecsWorld-\>CreateEntity();
entity.AddComponent\({
.maxHealth = 150.0f,
.currentHealth = 150.0f,
.regenerationRate = 2.0f
});
// 更新系统
ecsWorld-\>Update(deltaTime);
\`\`\`
---
⚡ 性能优化
渲染优化
\`\`\`cpp
// 实例化渲染
bluely::graphics::InstanceBatch instanceBatch;
instanceBatch.SetMesh(treeMesh);
instanceBatch.SetMaterial(treeMaterial);
for (const auto\& tree : trees) {
bluely::graphics::InstanceData data;
data.worldMatrix = tree.transform.GetMatrix();
data.color = tree.color;
instanceBatch.AddInstance(data);
}
// 每帧渲染
instanceBatch.Render();
// 遮挡剔除
bluely::graphics::OcclusionCuller culler;
culler.SetCamera(camera);
culler.SetOcclusionBufferSize(512, 512);
// 添加遮挡物
for (const auto\& occluder : largeObjects) {
culler.AddOccluder(occluder-\>GetBounds());
}
// 检查可见性
if (culler.IsVisible(object-\>GetBounds())) {
object-\>Render();
}
// LOD系统
bluely::graphics::LODGroup lodGroup;
lodGroup.AddLODLevel(treeMeshHigh, 0.0f, 50.0f); // 0-50米:高模
lodGroup.AddLODLevel(treeMeshMedium, 50.0f, 150.0f); // 50-150米:中模
lodGroup.AddLODLevel(treeMeshLow, 150.0f, 500.0f); // 150-500米:低模
// 根据距离自动选择LOD
auto mesh = lodGroup.GetLODMesh(cameraDistance);
\`\`\`
内存优化
\`\`\`cpp
// 内存池配置
bluely::core::MemoryPoolConfig poolConfig;
poolConfig.poolSize = 64 \* 1024 \* 1024; // 64MB
poolConfig.smallBlockSize = 64; // 小块大小
poolConfig.mediumBlockSize = 1024; // 中块大小
poolConfig.largeBlockSize = 16384; // 大块大小
bluely::core::MemoryManager::GetInstance().Initialize(poolConfig);
// 使用内存池
void\* smallData = bluely::core::MemoryManager::AllocateSmall(32);
void\* mediumData = bluely::core::MemoryManager::AllocateMedium(512);
void\* largeData = bluely::core::MemoryManager::AllocateLarge(8192);
// 自动释放
{
bluely::core::ScopedAllocation allocation(256); // 自动释放
// 使用分配的内存...
}
// 内存分析
bluely::core::MemoryProfiler profiler;
profiler.StartSession("Gameplay");
// ... 游戏逻辑 ...
profiler.EndSession();
auto report = profiler.GetReport();
LOG_INFO("峰值内存: {} MB", report.peakMemory / (1024 \* 1024));
LOG_INFO("分配次数: {}", report.allocationCount);
LOG_INFO("内存泄漏: {} 字节", report.leakedMemory);
\`\`\`
---
🔧 调试工具
调试绘制
\`\`\`cpp
// 启用调试绘制
bluely::debug::DebugDraw::GetInstance().SetEnabled(true);
// 绘制几何体
bluely::debug::DebugDraw::GetInstance().DrawLine(
startPos, endPos, bluely::math::Color::Red, 2.0f
);
bluely::debug::DebugDraw::GetInstance().DrawSphere(
center, radius, bluely::math::Color::Green, 16
);
bluely::debug::DebugDraw::GetInstance().DrawAABB(
min, max, bluely::math::Color::Blue
);
bluely::debug::DebugDraw::GetInstance().DrawFrustum(
frustum, bluely::math::Color::Yellow
);
// 绘制文本
bluely::debug::DebugDraw::GetInstance().DrawText(
position, "调试信息", bluely::math::Color::White
);
// 绘制网格
bluely::debug::DebugDraw::GetInstance().DrawGrid(
origin, size, cellSize, bluely::math::Color::Gray
);
// 绘制路径
bluely::debug::DebugDraw::GetInstance().DrawPath(
pathPoints, bluely::math::Color::Cyan, true
);
// 每帧清除
bluely::debug::DebugDraw::GetInstance().Clear();
\`\`\`
性能分析
\`\`\`cpp
// CPU性能分析
PERF_SCOPE("游戏循环");
{
PERF_SCOPE("物理更新");
physicsWorld.StepSimulation(deltaTime);
}
{
PERF_SCOPE("AI更新");
aiSystem.Update(deltaTime);
}
{
PERF_SCOPE("渲染");
renderer-\>Render();
}
// GPU性能分析
bluely::graphics::GPUProfiler profiler;
profiler.BeginFrame();
{
auto scope = profiler.BeginScope("阴影渲染");
shadowRenderer.Render();
}
{
auto scope = profiler.BeginScope("主渲染");
mainRenderer.Render();
}
{
auto scope = profiler.BeginScope("后期处理");
postProcess.Render();
}
profiler.EndFrame();
// 获取性能数据
auto cpuStats = bluely::profiler::CPUProfiler::GetStats();
auto gpuStats = profiler.GetStats();
// 显示性能信息
bluely::debug::PerformanceDisplay display;
display.SetPosition(10, 10);
display.AddStat("FPS", bluely::time::FPSCounter::GetFPS());
display.AddStat("CPU帧时间", cpuStats.frameTime \* 1000.0f);
display.AddStat("GPU帧时间", gpuStats.frameTime \* 1000.0f);
display.AddStat("三角形数量", gpuStats.triangleCount);
display.AddStat("绘制调用", gpuStats.drawCallCount);
\`\`\`
控制台命令
\`\`\`cpp
// 注册控制台命令
bluely::debug::Console::GetInstance().RegisterCommand(
"godmode",
"启用无敌模式",
\[\](const bluely::debug::ConsoleArgs\& args) {
player-\>SetInvincible(true);
return "无敌模式已启用";
}
);
bluely::debug::Console::GetInstance().RegisterCommand(
"spawn",
"生成实体 \[类型\] \[数量\]",
\[\](const bluely::debug::ConsoleArgs\& args) {
if (args.size() \< 2) return "用法: spawn \<类型\> \[数量\]";
String type = args\[0\];
int count = args.size() \> 1 ? std::stoi(args\[1\]) : 1;
for (int i = 0; i \< count; i++) {
SpawnEntity(type);
}
return "已生成 " + std::to_string(count) + " 个 " + type;
}
);
bluely::debug::Console::GetInstance().RegisterCommand(
"teleport",
"传送到坐标 \[x\] \[y\] \[z\]",
\[\](const bluely::debug::ConsoleArgs\& args) {
if (args.size() \< 3) return "用法: teleport \ \ \";
float x = std::stof(args\[0\]);
float y = std::stof(args\[1\]);
float z = std::stof(args\[2\]);
player-\>SetPosition(bluely::math::Vector3(x, y, z));
return "已传送到 (" + args\[0\] + ", " + args\[1\] + ", " + args\[2\] + ")";
}
);
// 执行命令
bluely::debug::Console::GetInstance().Execute("godmode");
bluely::debug::Console::GetInstance().Execute("spawn enemy 5");
bluely::debug::Console::GetInstance().Execute("teleport 100 50 200");
// 变量系统
bluely::debug::Console::GetInstance().RegisterVariable(
"game_speed",
"游戏速度倍率",
1.0f,
\[\](float value) {
bluely::time::GameTimer::GetInstance().SetTimeScale(value);
}
);
bluely::debug::Console::GetInstance().RegisterVariable(
"render_distance",
"渲染距离",
1000.0f,
\[\](float value) {
camera-\>SetFarPlane(value);
}
);
// 修改变量
bluely::debug::Console::GetInstance().SetVariable("game_speed", 2.0f);
float gameSpeed = bluely::debug::Console::GetInstance().GetVariable("game_speed");
\`\`\`
---
📚 API参考
核心类
类名 描述 主要方法
Engine 引擎主类 Initialize(), Shutdown(), Update(), Render()
Window 窗口管理 Create(), Show(), Close(), GetHandle()
GameTimer 游戏计时 Tick(), GetDeltaTime(), GetTotalTime()
MemoryManager 内存管理 Allocate(), Deallocate(), GetStats()
Logger 日志系统 Log(), SetLevel(), EnableFileOutput()
图形类
类名 描述 主要方法
Renderer 渲染器 Initialize(), BeginFrame(), EndFrame(), Present()
Texture 纹理 Load(), Create(), Bind(), GetSize()
Mesh 网格 Load(), Render(), GetBounds()
Material 材质 SetShader(), SetTexture(), SetParameter()
Camera 摄像机 SetPosition(), SetRotation(), GetViewMatrix()
Light 光源 SetColor(), SetIntensity(), SetType()
输入类
类名 描述 主要方法
InputSystem 输入系统 Initialize(), Update(), IsKeyPressed()
Keyboard 键盘 GetKeyState(), IsKeyDown(), IsKeyUp()
Mouse 鼠标 GetPosition(), GetDelta(), IsButtonDown()
Gamepad 游戏手柄 IsConnected(), GetButtonState(), GetAxis()
音频类
类名 描述 主要方法
AudioSystem 音频系统 Initialize(), PlaySound(), StopAll()
Sound 声音 Play(), Stop(), Pause(), SetVolume()
Music 音乐 Play(), Stop(), FadeIn(), FadeOut()
AudioListener 音频监听器 SetPosition(), SetOrientation()
物理类
类名 描述 主要方法
PhysicsWorld 物理世界 Initialize(), StepSimulation(), Raycast()
RigidBody 刚体 SetMass(), ApplyForce(), GetVelocity()
Collider 碰撞器 SetShape(), SetTrigger(), GetBounds()
RaycastHit 射线检测结果 GetPoint(), GetNormal(), GetDistance()
数学类
类名 描述 主要方法
Vector2 2D向量 Length(), Normalize(), Dot(), Cross()
Vector3 3D向量 Length(), Normalize(), Dot(), Cross()
Quaternion 四元数 FromEuler(), ToEuler(), Slerp(), Normalize()
Matrix4 4x4矩阵 Transpose(), Inverse(), TransformPoint()
Color 颜色 Lerp(), ToRGBA(), FromRGBA(), GammaCorrect()
实用工具
类名 描述 主要方法
Random 随机数 Range(), GetFloat(), GetInt(), GetVector()
FileSystem 文件系统 ReadFile(), WriteFile(), Exists(), GetSize()
Json JSON解析 Parse(), Serialize(), GetValue(), SetValue()
Profiler 性能分析 Begin(), End(), GetResults()
DebugDraw 调试绘制 DrawLine(), DrawSphere(), DrawText()
---
🎮 示例项目
简单2D游戏
\`\`\`cpp
class Simple2DGame : public bluely::core::GameApplication {
public:
bool Initialize() override {
// 初始化引擎
bluely::EngineConfig config;
config.appName = "Simple 2D Game";
config.screenWidth = 800;
config.screenHeight = 600;
bluely::Engine::GetInstance().Initialize(config);
// 加载资源
playerTexture = bluely::graphics::Texture::Load("player.png");
backgroundTexture = bluely::graphics::Texture::Load("background.png");
jumpSound = bluely::audio::Sound::Load("jump.wav");
// 初始化玩家
playerPosition = bluely::math::Vector2(400, 300);
playerVelocity = bluely::math::Vector2::Zero;
return true;
}
void Update(float deltaTime) override {
// 处理输入
auto\& input = bluely::input::InputSystem::GetInstance();
if (input.IsKeyPressed(bluely::input::KeyCode::Left)) {
playerVelocity.x = -200.0f;
} else if (input.IsKeyPressed(bluely::input::KeyCode::Right)) {
playerVelocity.x = 200.0f;
} else {
playerVelocity.x = 0.0f;
}
if (input.IsKeyPressed(bluely::input::KeyCode::Space) \&\& isGrounded) {
playerVelocity.y = -400.0f;
jumpSound-\>Play();
isGrounded = false;
}
// 应用重力
playerVelocity.y += 980.0f \* deltaTime;
// 更新位置
playerPosition += playerVelocity \* deltaTime;
// 边界检查
if (playerPosition.y \> 550) {
playerPosition.y = 550;
playerVelocity.y = 0;
isGrounded = true;
}
}
void Render() override {
auto renderer = bluely::graphics::RenderSystem::GetInstance().GetRenderer();
renderer-\>BeginFrame();
// 渲染背景
renderer-\>DrawTexture(backgroundTexture,
bluely::math::Vector2::Zero,
bluely::math::Vector2(800, 600));
// 渲染玩家
renderer-\>DrawTexture(playerTexture,
playerPosition - bluely::math::Vector2(32, 32),
bluely::math::Vector2(64, 64));
renderer-\>EndFrame();
renderer-\>Present();
}
private:
bluely::graphics::TexturePtr playerTexture;
bluely::graphics::TexturePtr backgroundTexture;
bluely::audio::SoundPtr jumpSound;
bluely::math::Vector2 playerPosition;
bluely::math::Vector2 playerVelocity;
bool isGrounded = true;
};
\`\`\`
3D场景
\`\`\`cpp
class Simple3DScene : public bluely::core::GameApplication {
public:
bool Initialize() override {
// 初始化引擎
bluely::EngineConfig config;
config.appName = "Simple 3D Scene";
config.screenWidth = 1280;
config.screenHeight = 720;
config.enable3D = true;
bluely::Engine::GetInstance().Initialize(config);
// 创建场景
scene = bluely::scene::Scene::Create();
// 创建摄像机
camera = bluely::core::MakeShared\();
camera-\>SetPosition(bluely::math::Vector3(0, 5, -10));
camera-\>SetTarget(bluely::math::Vector3::Zero);
scene-\>AddEntity(camera);
// 加载模型
auto character = bluely::graphics::Mesh::Load("character.fbx");
auto characterEntity = scene-\>CreateEntity("Character");
auto meshRenderer = characterEntity-\>AddComponent\();
meshRenderer-\>SetMesh(character);
// 创建灯光
auto directionalLight = scene-\>CreateEntity("DirectionalLight");
auto light = directionalLight-\>AddComponent\();
light-\>SetType(bluely::graphics::LightType::Directional);
light-\>SetColor(bluely::math::Color::White);
light-\>SetIntensity(1.0f);
directionalLight-\>GetTransform()-\>SetRotation(
bluely::math::Quaternion::FromEuler(45, 45, 0)
);
return true;
}
void Update(float deltaTime) override {
// 更新摄像机
static float cameraAngle = 0;
cameraAngle += deltaTime \* 30.0f;
float radius = 10.0f;
float x = sinf(bluely::math::Math::ToRadians(cameraAngle)) \* radius;
float z = cosf(bluely::math::Math::ToRadians(cameraAngle)) \* radius;
camera-\>SetPosition(bluely::math::Vector3(x, 5, z));
camera-\>SetTarget(bluely::math::Vector3::Zero);
// 更新场景
scene-\>Update(deltaTime);
}
void Render() override {
auto renderer = bluely::graphics::RenderSystem::GetInstance().GetRenderer();
renderer-\>BeginFrame();
// 设置摄像机
renderer-\>SetCamera(camera);
// 渲染场景
scene-\>Render(renderer);
renderer-\>EndFrame();
renderer-\>Present();
}
private:
bluely::scene::ScenePtr scene;
bluely::graphics::CameraPtr camera;
};
\`\`\`
---
🛠️ 故障排除
常见问题
1. 启动失败
\`\`\`
检查: 显卡驱动是否最新
检查: DirectX运行时是否安装
检查: 资源文件是否存在
\`\`\`
2. 性能问题
\`\`\`
优化: 降低渲染分辨率
优化: 减少阴影质量
优化: 启用遮挡剔除
优化: 使用LOD系统
\`\`\`
3. 内存泄漏
\`\`\`
检查: 使用内存分析工具
检查: 资源是否正确释放
检查: 循环引用问题
\`\`\`
4. 渲染错误
\`\`\`
检查: 着色器编译错误
检查: 纹理格式支持
检查: 显卡特性支持
\`\`\`
调试技巧
1. 启用调试层
\`\`\`cpp
bluely::EngineConfig config;
config.enableDebugLayer = true;
config.enableGPUValidation = true;
\`\`\`
1. 日志级别设置
\`\`\`cpp
bluely::debug::Logger::GetInstance().SetLevel(
bluely::debug::LogLevel::Verbose
);
\`\`\`
1. 性能分析
\`\`\`cpp
// 在性能关键代码周围添加性能标记
PERF_SCOPE("关键代码");
\`\`\`
---
📖 更新日志
v1.0.0 (2024-01-01)
· ✅ 初始版本发布
· ✅ 核心引擎框架
· ✅ DirectX 9/12 渲染器
· ✅ 完整的输入系统
· ✅ 音频系统支持
· ✅ 资源管理系统
· ✅ 场景和实体系统
· ✅ 调试和性能工具
v1.1.0 (计划中)
· 🔄 Vulkan 渲染器支持
· 🔄 跨平台支持 (Linux/macOS)
· 🔄 物理引擎集成
· 🔄 网络系统
· 🔄 脚本系统 (Lua/Python)
· 🔄 编辑器工具
---
📞 支持与贡献
获取帮助
· 📚 在线文档
· 💬 Discord社区
· 🐛 GitHub Issues
贡献指南
1. Fork 仓库
2. 创建功能分支 (git checkout -b feature/amazing-feature)
3. 提交更改 (git commit -m 'Add amazing feature')
4. 推送到分支 (git push origin feature/amazing-feature)
5. 打开 Pull Request
行为准则
· 尊重所有贡献者
· 建设性讨论
· 包容性环境
· 专业交流
---
📄 许可证
Bluely Engine 基于 MIT 许可证开源。
\`\`\`
MIT License
Copyright (c) 2024 Bluely Engine Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\`\`\`
---
Bluely Engine - 打造你的游戏梦想
🎮 快乐开发! 🚀