学习 XGE 的透视投影相机,理解 FOV、近远裁剪面的含义,实现 2.5D 透视效果。
透视投影模拟人眼观察——远处的物体看起来更小。XGE 虽然是 2D 引擎,但通过透视相机 + xgeDrawQuad3D 可以实现 2.5D 效果(如倾斜的棋盘地面、卡片翻转动画)。
fFovY:垂直视场角(度),越大视野越广、物体越小fNearZ:近裁剪面,比这更近的物体不渲染fFarZ:远裁剪面,比这更远的物体不渲染
| 函数 | 说明 |
|---|---|
xge_camera_t xgeCameraPerspective(float fWidth, float fHeight, float fFovY, float fNearZ, float fFarZ) | 创建透视投影相机 |
void xgeCameraSet(const xge_camera_t* pCamera) | 设置当前相机 |
xge_camera_t xgeCameraGet(void) | 获取当前相机 |
gcc -O2 -I. -o ch15.exe ch15_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch15.exe
| 字段 | 典型值 | 说明 |
|---|---|---|
iProjectionMode | XGE_CAMERA_PERSPECTIVE (1) | 标记为透视模式 |
fFovY | 45°–90° | 垂直视场角(度) |
fNearZ | 0.1 | 近裁剪面距离 |
fFarZ | 1000.0 | 远裁剪面距离 |
fPerspectiveDistance | 自动计算 | 相机到投影平面的距离 |
static int onFrame(void* pUser) {
xgeClear(0x081114FF);
// 创建透视相机
xge_camera_t cam = xgeCameraPerspective(
800.0f, // 视口宽度
600.0f, // 视口高度
60.0f, // 垂直 FOV 60 度
0.1f, // 近裁剪面
1000.0f // 远裁剪面
);
xgeCameraSet(&cam);
// 开启深度测试(透视场景推荐)
xgeDepthTestSet(1);
// 绘制 3D 四边形(透视效果)
// xgeDrawQuad3D(...);
xgeDepthTestSet(0);
return XGE_OK;
}// 窄 FOV → 类似长焦镜头,透视变形小
xge_camera_t tele = xgeCameraPerspective(800, 600, 30.0f, 0.1f, 500.0f);
// 标准 FOV → 接近人眼
xge_camera_t normal = xgeCameraPerspective(800, 600, 60.0f, 0.1f, 500.0f);
// 广角 FOV → 夸张透视,边缘畸变
xge_camera_t wide = xgeCameraPerspective(800, 600, 110.0f, 0.1f, 500.0f);
// 按 1/2/3 键切换
if (xgeKeyPressed('1')) xgeCameraSet(&tele);
if (xgeKeyPressed('2')) xgeCameraSet(&normal);
if (xgeKeyPressed('3')) xgeCameraSet(&wide);static int onFrame(void* pUser) {
double t = xgeTimer();
// FOV 在 50°~70° 之间正弦呼吸
float fov = 60.0f + 10.0f * (float)sin(t * 0.8);
xge_camera_t cam = xgeCameraPerspective(800, 600, fov, 0.1f, 800.0f);
xgeCameraSet(&cam);
xgeClear(0x081114FF);
// ... 绘制场景 ...
return XGE_OK;
}| 特性 | 正交 (ORTHO) | 透视 (PERSPECTIVE) |
|---|---|---|
| 远处物体 | 大小不变 | 变小 |
| 平行线 | 保持平行 | 汇聚于灭点 |
| 典型用途 | 2D 游戏、UI、CAD | 2.5D 效果、卡片动画 |
| 深度测试 | 通常不需要 | 推荐开启 |
| 创建函数 | xgeCameraDefault | xgeCameraPerspective |
将以下代码保存为 ch15_main.c,编译后运行即可观察动态 FOV 呼吸效果:
#include "xge.h"
#include <math.h>
static int onFrame(void* pUser) {
(void)pUser;
double t = xgeTimer();
// FOV 在 50°~70° 之间正弦呼吸
float fov = 60.0f + 10.0f * (float)sin(t * 0.8);
xge_camera_t cam = xgeCameraPerspective(800.0f, 600.0f, fov, 0.1f, 800.0f);
xgeCameraSet(&cam);
xgeClear(0x081114FF);
// 绘制参考图形(透视效果下会随 FOV 变化)
xgeShapeRectFill(250, 200, 300, 200, 0x4FD8C2FF);
xgeShapeCircleFill(400, 300, 60, 0xFFB454FF);
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch15 - Perspective Camera";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xgeRun(onFrame, NULL);
xgeUnit();
return 0;
}xgeCameraPerspective(w, h, fov, near, far) 创建透视相机,fov 单位为度。xgeTimer() 返回引擎启动以来的秒数,驱动 FOV 正弦动画。xgeDepthTestSet(1)。xgeDrawQuad3D)。普通 2D Shape 绘制仍使用屏幕坐标。xgeDrawQuad3D 绘制一个旋转的立方体(6 个面)。