当前位置: 首页 > news >正文

中级OpenGL教程 010:Object 类设计与模型矩阵完全实现

中级OpenGL教程 010:Object 类设计与模型矩阵完全实现

  • Bilibili 同步视频
  • 一、Object 类:3D 物体的「空间管理者」
    • 1.1 文件结构与基础配置
  • 二、成员变量设计:protected 权限的精妙选择
    • 2.1 三大核心变换变量
  • 三、旋转逻辑:本地坐标系 + Unity 标准顺序
    • 3.1 本地坐标系旋转
    • 3.2 旋转顺序:严格遵循 Unity 引擎标准
  • 四、接口封装:简洁易用的变换 API
    • 4.1 核心接口声明
    • 4.2 接口实现(object.cpp)
  • 五、模型矩阵计算:渲染管线的「核心输出」
    • 5.1 矩阵计算完整实现
    • 5.2 关键细节勘误(必看)
  • 六、Object 类的价值与扩展方向
    • 6.1 核心价值
    • 6.2 扩展方向
  • 结语

Bilibili 同步视频

中级OpenGL教程 010:Object 类设计与模型矩阵完全实现

在 3D 图形渲染的世界里,一切可见元素都可被抽象为「物体」—— 无论是场景中的模型、角色、道具,还是粒子特效,都需要一套统一的框架来管理其空间变换。Object 类正是这套框架的核心,它封装了物体的位移、旋转、缩放三大基础变换,最终输出渲染管线必需的模型矩阵(Model Matrix),为后续 MVP 矩阵计算与片元着色打下坚实基础。

本文将从零拆解 Object 类的设计思路、成员变量定义、接口封装与模型矩阵计算逻辑,搭配可直接落地的 C++ 代码实现,帮你快速搭建 3D 引擎的物体管理模块✨。


一、Object 类:3D 物体的「空间管理者」

Object 类的核心使命只有一个:管理物体的空间变换,输出标准模型矩阵
它是所有可渲染物体的基类,场景中的模型、相机、灯光等实体,都可继承此类复用变换逻辑。因此在设计时,权限控制、变量封装、接口易用性是三大关键原则。

1.1 文件结构与基础配置

我们将 Object 类置于GL framework核心模块,方便全工程复用,创建两个核心文件:

  • object.h:类定义、变量声明、接口声明

  • object.cpp:函数实现、矩阵计算逻辑

头文件必须添加#pragma once预编译指令,杜绝头文件二次编译,避免重复定义报错;同时引入核心依赖库(GLM 数学库、框架核心文件),为矩阵运算、向量操作提供支撑。

// object.h 基础配置#pragmaonce#include"core.h"// 包含 GLM 数学库、框架核心工具

二、成员变量设计:protected 权限的精妙选择

物体的空间变换,本质是位置、旋转、缩放三组数据的组合。
在权限设计上,我们放弃private,选择protected修饰所有成员变量 —— 这是为了让子类能直接访问父类变换数据,保证继承体系的灵活性(比如模型类、角色类可直接修改位置、旋转角度)。

2.1 三大核心变换变量

  1. 位置变量:m_position
    记录物体在世界坐标系中的坐标,用glm::vec3存储,初始化为(0.0f, 0.0f, 0.0f),代表物体默认位于世界原点。

  2. 旋转变量:m_angle_x /m_angle_y/m_angle_z
    采用欧拉角旋转方案,分别记录物体绕 X、Y、Z 本地轴的旋转角度,这是游戏 / 引擎中最通用的旋转方式:

    • Pitch(绕 X 轴):上下俯仰(类比「点头」)

    • Yaw(绕 Y 轴):左右转向(类比「摇头」)

    • Roll(绕 Z 轴):滚筒旋转(类比「滚床单」)

  3. 缩放变量:m_scale
    glm::vec3存储物体在 X、Y、Z 轴的缩放比例,默认值必须为 1.0f(代表无缩放),若设为 0 会导致物体完全消失。

// object.h 成员变量定义classObject{protected:// 1. 位置:世界坐标系坐标glm::vec3 m_position{0.0f,0.0f,0.0f};// 2. 旋转:欧拉角(绕本地X/Y/Z轴)floatm_angle_x{0.0f};floatm_angle_y{0.0f};floatm_angle_z{0.0f};// 3. 缩放:三轴缩放比例glm::vec3 m_scale{1.0f,1.0f,1.0f};public:// 后续接口声明...};

三、旋转逻辑:本地坐标系 + Unity 标准顺序

旋转是 3D 变换中最易出错的环节,核心要解决两个问题:基于什么坐标系旋转?旋转的先后顺序是什么?

3.1 本地坐标系旋转

我们采用本地坐标系(局部坐标系)旋转规则:
物体的旋转始终围绕自身当前的坐标轴,而非世界坐标系坐标轴。
比如物体先绕 X 轴旋转 30°,再绕 Z 轴旋转时,Z 轴是物体旋转后的本地 Z 轴,而非世界 Z 轴 —— 这符合现实中物体的运动直觉(如飞机、汽车的运动)。

3.2 旋转顺序:严格遵循 Unity 引擎标准

为保证旋转结果可预期,固定旋转顺序至关重要,我们直接沿用工业级标准(Unity 引擎):
先 Pitch(X 轴)→ 再 Yaw(Y 轴)→ 最后 Roll(Z 轴)
此顺序能最大程度避免万向锁问题,适配绝大多数 3D 场景需求。


四、接口封装:简洁易用的变换 API

Object 类对外提供极简接口,支持设置位置、增量旋转、设置缩放三大操作,区分「赋值式设置」与「增量式修改」,符合引擎开发习惯。

4.1 核心接口声明

// object.h 公共接口public:Object()=default;~Object()=default;// 1. 设置位置:赋值式(直接覆盖世界坐标)voidsetPosition(constglm::vec3&position);// 2. 增量旋转:在原有角度基础上累加voidrotateX(floatangle);voidrotateY(floatangle);voidrotateZ(floatangle);// 3. 设置缩放:赋值式(直接覆盖三轴缩放)voidsetScale(constglm::vec3&scale);// 4. 核心:计算并返回模型矩阵glm::mat4getModelMatrix();

4.2 接口实现(object.cpp)

旋转接口采用增量累加逻辑,每调用一次rotateX,就在原有角度上叠加新角度,适配帧更新的旋转逻辑;位置与缩放为直接赋值,保证精准控制。

// object.cpp 接口实现#include"object.h"// 设置位置voidObject::setPosition(constglm::vec3&position){m_position=position;}// 增量旋转 X 轴voidObject::rotateX(floatangle){m_angle_x+=angle;}// 增量旋转 Y 轴voidObject::rotateY(floatangle){m_angle_y+=angle;}// 增量旋转 Z 轴voidObject::rotateZ(floatangle){m_angle_z+=angle;}// 设置缩放voidObject::setScale(constglm::vec3&scale){m_scale=scale;}

五、模型矩阵计算:渲染管线的「核心输出」

getModelMatrix()是 Object 类的灵魂函数,它将位移、旋转、缩放三组离散数据,组合为渲染管线必需的模型矩阵,变换顺序严格遵循 Unity 标准:
先缩放 → 再旋转 → 最后平移
⚠️ 关键规则:平移必须在最后,且基于世界坐标系执行,保证物体最终定位到指定世界坐标。

5.1 矩阵计算完整实现

// object.cpp 模型矩阵计算glm::mat4Object::getModelMatrix(){// 1. 初始化单位矩阵glm::mat4 transform=glm::mat4(1.0f);// 2. 第一步:缩放变换(本地坐标系)transform=glm::scale(transform,m_scale);// 3. 第二步:旋转变换(本地坐标系,严格按 X→Y→Z 顺序)// 旋转需转弧度:GLM 仅支持弧度运算,角度必须转换!transform=glm::rotate(transform,glm::radians(m_angle_x),glm::vec3(1.0f,0.0f,0.0f));transform=glm::rotate(transform,glm::radians(m_angle_y),glm::vec3(0.0f,1.0f,0.0f));transform=glm::rotate(transform,glm::radians(m_angle_z),glm::vec3(0.0f,0.0f,1.0f));// 4. 第三步:平移变换(世界坐标系,单独计算后相乘)transform=glm::translate(glm::mat4(1.0f),m_position)*transform;// 返回最终模型矩阵returntransform;}

5.2 关键细节勘误(必看)

GLM 数学库的旋转函数仅支持弧度值,但我们设计的m_angle_x/y/z是角度值,必须用glm::radians()转换,否则旋转结果完全错误,这是 3D 开发高频踩坑点❗


六、Object 类的价值与扩展方向

6.1 核心价值

  1. 统一抽象:将所有 3D 物体的变换逻辑收敛到一个基类,减少重复代码

  2. 标准输出:输出合规模型矩阵,无缝对接渲染管线

  3. 易于继承:子类可快速扩展(如 Model 类添加网格数据、Light 类添加光照参数)

6.2 扩展方向

  • 新增resetTransform()重置所有变换

  • 添加欧拉角转四元数,解决万向锁问题

  • 支持父物体 / 子物体的父子坐标系变换


结语

Object 类是 3D 渲染框架的「最小可用单元」,它没有复杂的逻辑,却承载了物体空间变换的核心能力。从变量权限设计、旋转规则制定,到模型矩阵计算,每一步都遵循工业级引擎标准,代码简洁、可直接落地到 OpenGL/ES 3D 项目中。

掌握 Object 类,你就掌握了 3D 场景中物体运动的底层逻辑,后续再扩展相机、光照、材质等模块,都会变得水到渠成🌊。

http://www.jsqmd.com/news/1036873/

相关文章:

  • NXP DPAA硬件加速实战:报文头操作与CAAM加密引擎配置详解
  • 2026 安徽哪所学校护理升学强?5大高升学率中职招生名单 - 小途xt
  • 包包有磨损、无配件?沈阳正规回收解决方案 - 开心测评
  • 2026年论文写作AI工具怎么用?豆包等工具详细使用教程 - 掌桥科研-AI论文写作
  • 2026滁州家长注意!离南京这么近,孩子学建筑去这所公办中职,比在南京打工强 - 我叫小周
  • 7 款无会员去水印工具实测,自媒体 2026 清单 - 时时资讯
  • 2026东莞寄卖回收一体奢品店推荐,不急出手可托管售卖到手收益更可观 - 名奢变现站
  • 50行Python实现人脸检测:OpenCV+Haar级联原理与实战
  • 2026重庆高端珠宝首饰回收排行 权威鉴定实测靠谱商家榜单 - 名奢变现站
  • Python自动化测试实战:从框架选型到工程化落地
  • 高价无损专业核验,2026哈尔滨回收百年灵手表优选榜单 - 名奢变现站
  • Linux Shell脚本结构化命令:条件判断与循环控制实战指南
  • 2026佛山宝格丽首饰回收正规门店实力排名:四大维度实测盘点靠谱变现渠道 - 薛定谔的梨花猫
  • 汇编语言工程实践:标签系统与伪指令在嵌入式开发中的核心应用
  • Windows Server 2016镜像获取、验证与部署实战指南
  • 新手部署 OpenClaw 完整操作流程 自动适配 Git/Node 运行依赖工具(含安装包)
  • 海南企业跨境出海必备|海南出口退税代办、海南ODI备案办理专业机构TOP5,海南ODI备案办理、海南出口退税代办哪家专业? - GrowthUME
  • 2026佛山不锈钢幕墙 售楼部金属门楼定制厂家推荐|佛山众亿金属,自有全套数控生产线,非标定制仿古镀铜、异形幕墙 - 热点速览
  • 论文写作AI工具有哪些?精选6款实用工具,科研必备 - 掌桥科研-AI论文写作
  • 从效率角度看公众号编辑器:如何用AI重构内容生产流程 - 行业产品测评专家
  • 口碑好的天津暖气片品牌生产厂家有哪些 - 资讯速览
  • 上海口碑优质企业财务合规咨询公司分梯队推荐 - GrowthUME
  • DisneyF1名创优品:多IP联名视频的AIGC制作复盘,版权边界内的符号化设计与视觉一致性控制
  • 长沙县郡优教育培训学校有限公司官方联系方式 - 第三方测评
  • SmartDSP OS内存与MMU管理:嵌入式实时系统的性能基石
  • 2026 海淀区靠谱门窗公司推荐,断桥铝门窗、老房换窗、全屋换窗、保温节能门窗、落地窗、推拉门、平开窗高性价比优选指南 - 品牌智鉴榜
  • 2026安徽省淮南中考2百多分可以上什么学校?——安徽合肥医药卫生学校3+2直升大学! - 小张zc
  • Google Colab零配置运行Tesseract-OCR中文识别实战
  • 多维PTE问题与组合设计的数学结构解析
  • 2026年临沂短视频供应商:官方权威发布与深度数据报告 - GrowthUME