C++游戏引擎开发指南:实现基础相机系统

C++游戏引擎开发指南:实现基础相机系统

cpp-game-engine-book 从零编写游戏引擎教程 Writing a game engine tutorial from scratch cpp-game-engine-book 项目地址: https://gitcode.com/gh_mirrors/cp/cpp-game-engine-book

相机在游戏引擎中的重要性

在3D游戏引擎中,相机(Camera)是决定玩家如何观察虚拟世界的核心组件。它定义了场景的视角、视野范围和可见区域,相当于现实世界中的"眼睛"。本文将基于一个C++游戏引擎项目,讲解如何实现一个基础的相机系统。

相机的基本原理

相机在3D图形学中主要通过两个矩阵来定义:

  1. 视图矩阵(View Matrix):决定相机的位置和朝向
  2. 投影矩阵(Projection Matrix):决定相机的视野范围和裁剪平面

在之前的实现中,我们直接在代码中使用GLM数学库提供的函数来创建这两个矩阵:

glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0,0), glm::vec3(0, 1, 0));
glm::mat4 projection=glm::perspective(glm::radians(60.f),ratio,1.f,1000.f);

这种直接使用的方式虽然简单,但缺乏封装性和灵活性。接下来我们将这些功能封装到一个Camera类中。

Camera类的设计与实现

1. 基础Camera类结构

我们创建一个Camera类来封装相机的核心功能:

class Camera {
public:
    /// 设置相机视图参数
    /// @param cameraForward 相机朝前方向
    /// @param cameraUp 相机朝上方向
    void SetView(const glm::vec3& cameraForward, const glm::vec3& cameraUp);
    
    /// 设置相机投影参数
    /// @param fovDegrees 视野角度(度)
    /// @param aspectRatio 宽高比
    /// @param nearClip 近裁剪面距离
    /// @param farClip 远裁剪面距离
    void SetProjection(float fovDegrees, float aspectRatio, float nearClip, float farClip);
    
    // 获取视图矩阵
    glm::mat4& view_mat4() { return view_mat4_; }
    
    // 获取投影矩阵
    glm::mat4& projection_mat4() { return projection_mat4_; }
    
private:
    glm::mat4 view_mat4_;        // 视图矩阵
    glm::mat4 projection_mat4_;  // 投影矩阵
};

2. 关键方法实现

SetView方法

SetView方法使用GLM的lookAt函数创建视图矩阵:

void Camera::SetView(const glm::vec3& cameraForward, const glm::vec3& cameraUp) {
    // 假设相机位置由关联的Transform组件决定
    view_mat4_ = glm::lookAt(transform_->position(), cameraForward, cameraUp);
}
SetProjection方法

SetProjection方法使用GLM的perspective函数创建透视投影矩阵:

void Camera::SetProjection(float fovDegrees, float aspectRatio, float nearClip, float farClip) {
    projection_mat4_ = glm::perspective(glm::radians(fovDegrees), aspectRatio, nearClip, farClip);
}

在游戏引擎中使用Camera

1. 创建相机对象

在游戏引擎中,我们通常将Camera作为组件(Component)附加到游戏对象(GameObject)上:

// 创建相机游戏对象
auto go_camera = new GameObject("main_camera");

// 添加Transform组件并设置位置
auto transform_camera = dynamic_cast<Transform*>(go_camera->AddComponent("Transform"));
transform_camera->set_position(glm::vec3(0, 0, 10));

// 添加Camera组件
auto camera = dynamic_cast<Camera*>(go_camera->AddComponent("Camera"));

2. 每帧更新相机参数

在游戏主循环中,我们需要每帧更新相机参数:

while (!glfwWindowShouldClose(window)) {
    // 设置相机视图和投影
    camera->SetView(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
    camera->SetProjection(60.f, ratio, 1.f, 1000.f);
    camera->Clear();
    
    // 渲染场景
    mesh_renderer->SetView(camera->view_mat4());
    mesh_renderer->SetProjection(camera->projection_mat4());
    mesh_renderer->Render();
}

相机参数详解

1. 视图矩阵参数

  • 相机位置:通过Transform组件设置
  • 观察目标点:相机看向的点
  • 上向量:定义相机的"向上"方向

2. 投影矩阵参数

  • 视野角度(FOV):决定相机的视野宽度,单位通常为度
  • 宽高比:通常为窗口的宽度/高度
  • 近裁剪面:比这个距离近的物体不会被渲染
  • 远裁剪面:比这个距离远的物体不会被渲染

实际应用中的注意事项

  1. 性能考虑:视图矩阵每帧都需要更新,但投影矩阵可以在窗口大小改变时才更新

  2. 坐标系一致性:确保相机的坐标系与游戏世界的坐标系一致

  3. 相机移动平滑:在实际游戏中,相机移动通常会加入插值或缓动效果

  4. 多相机支持:高级引擎需要支持多相机切换或画中画效果

总结

本文介绍了如何在C++游戏引擎中实现一个基础的相机系统。通过封装视图矩阵和投影矩阵的计算逻辑到Camera类中,我们提高了代码的可维护性和扩展性。这是游戏引擎开发中的重要一步,为后续实现更复杂的相机行为(如跟随相机、自由视角相机等)奠定了基础。

在后续开发中,我们可以进一步扩展Camera类,添加如视口控制、相机动画、后期处理效果等功能,使游戏画面表现更加丰富和专业。

cpp-game-engine-book 从零编写游戏引擎教程 Writing a game engine tutorial from scratch cpp-game-engine-book 项目地址: https://gitcode.com/gh_mirrors/cp/cpp-game-engine-book

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经梦鸽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值