未完成的低配 MC
0. 概述
参考资料:
设想目标和实现目标
目标 | 实现状态 |
---|---|
基于 OpenGL 的方块渲染 | DONE |
第一人称视角控制 | DONE |
射线检测 | DONE |
人物与世界交互 | DONE |
仿 MC 世界控制(放置方块/挖掘方块) | DONE |
不同特性的方块 | 只做了不同皮肤 |
人物渲染 | orz |
物理系统 | orz |
世界随机生成算法 | orz |
总的来说,从类的设计到具体实现都很不专业,还有很大的改进空间
github 项目地址 | MineCraft_Yishiyu_Edition
效果展示:
(只实现了石头方块和草方块,左键挖掘右键放置)
1. 第三方库
1.1 OpenGL
[OpenGL 是什么 | 陈嘉栋 | 知乎]
OpenGL 是 Khronos Group 开发维护的一个规范,它主要为我们定义了用来操作图形和图片的一系列函数的 API,需要注意的是 OpenGL 本身并非 API.GPU 的硬件开发商则需要提供满足 OpenGL 规范的实现,这些实现通常被称为“驱动”,它们负责将 OpenGL 定义的 API 命令翻译为 GPU 指令.简而言之 OpenGL 是一个绘图引擎,同为绘图引擎的还有微软开发的 DirectX 系列,Qt 引擎等
OpenGL 的优势在于其跨平台,但是其已经逐渐过时(Vulkan 是其指定接班人).不过关于 OpenGL 的教程和资料比较多,可以绘图引擎的入门之选
然后是 opengl 和 opencv 之间的关系
- opengl:连接程序和显卡驱动的库(知道数据,渲染出图像)
- opencv:图形处理库(已知图像,从中提取信息)
安装方法:安装支持 OpenGL 的显卡驱动即可
1.2 vcpkg
vcpkg 是 windows 上的 c++包管理系统(类似于 python 中的 pip,linux 上的 apt-get(?))
VisualStudio 可以很方便地使用 vcpkg 安装的包
安装方法vcpkg 安装:
1 | 克隆项目 |
后面的包安装步骤中的
1.3 GLAD
首先 opengl 并不是一个库,而是一个 API 接口标准,不同的显卡厂商实现其具体函数 GLAD 是一个负责找到并初始化 opengl 具体实现的库
1.4 SFML
SFML(Simple and Fast Multimedia Library):[SFML | 官方网站]
一个轻量级多媒体库,支持窗口控制,音频控制,系统控制,图形渲染,网络通信
2. 渲染系统
2.1 整体结构
完善了渲染系统之后,针对每个模型(Model)及其对应的纹理(TextureAtlas)进行渲染(为了实现不同的方块)
整体结构:
- RenerMaster:游戏渲染管理器,每帧由 Application 实例调用一次其 finishRender 函数
- drawQuad:绘制单独的一个四边形(由其成员变量 QuadRenderer 实例完成)
- drawCube:绘制一个方块(由成员变量 CubeRenderer 实例实现)
- drawSection:渲染一个游戏区块(区域)(由成员变量 SectionRenderer 实例完成)
- QuadRenderer/CubeRenderer/SectionRenderer:四边形/方块/区块渲染器
- add:添加一个被渲染的四边形/方块/区块模型
- render:执行一次渲染
2.2 OpenGL 渲染
以最方块渲染类 CubeRenderer 为例:
1 | // |
1 | // |
3. 第一人称视角控制
- Entity:
- position:实体位置
- rotation:实体旋转
- Player:Entity 的子类
- m_velocity:玩家的速度
- handleInput:处理一帧的控制输入(鼠标/键盘)
- update:更新玩家状态(根据速度计算新位置/旋转)
- Cameara:Entity 的子类
- hookEntity:绑定一个其他 Entity 对象
- update:根据绑定的 Entity 对象更新自身状态(位置/角度)
- m_projectionMatrix:投影变换矩阵
- m_viewMatrix:视图变换矩阵
- m_projViewMatrix:投影视图变换矩阵(由前两个矩阵计算得到)
4. 世界管理
- IChunk:区块管理接口
- setBlock:设置方块
- getBlock:获取方块类型
- Section:小区块(实现了 IChunk 接口)(实现中大小为 16x16x16 个 block)
- Chunk:大区块(实现了 IChunk 接口)(实现中每个 Chunk 包含不同高度的 3 个 Section)
- World:世界(实现了 IChunk 接口)(管理游戏中所有的 Chunk)
5. 射线检测
- Ray:射线类
- m_rayStart:起始位置
- m_rayEnd:终止位置(初始为起始位置,后不断沿着射线方向扩充)
- m_direction:射线方向
- getLength:获取射线长度
- step:射线朝 m_direction 方向前进一段(来检测物体)
- getEnd:获取当前射线终止位置
- World->getBlock:检测目标位置方块
射线检测核心代码
1 | // StatePlaying.cpp 41 |
6. 游戏管理
总体来说 Application 是一个状态栈,不同游戏状态都继承自状态基类
通过不同游戏状态实现不同的游戏模式
- StateBase:状态基类
- handleEvent
- handleInput
- update
- render
- StatePlaying:StateBase 的子类