OpenGL学习-第一章

重返GLM

在较新的GLM 版本中,创建一个矩阵时*切记一定*要给出初值(对角线初值),否则计算结果会严重出错:

glm::mat4 trans;//NO

trans = glm::translate(trans, glm::vec3(1, 1, 0));//结果严重出错

trans = glm::translate(glm::mat4(1), glm::vec3(1, 1, 0));//结果正确无误

(一般初值都为1)

另外,结果矩阵是列主序的,而不是行主序的

什么是行主序or列主序?对于一个矩阵m来说:

m[i][j];//行主序

M[j][i];//列主序

虽然实现都是二维数组,但两者对元素的逻辑排列顺序不同,行主序先从左往右,再从上往下阅读,列主序先从上往下,再从左往右阅读,这是因为OpenGL内部就是使用列主序的矩阵的,而DirectX则使用行主序

关于两者的关系:
M()=M()转置(Transpose)

另外,在使用GLM的过程中,尽量使用弧度制而非角度制,避免遇到计算错误

摄像机类源码解析

源码地址:https://learnopengl.com/code_viewer.php?type=header&code=camera

(注意上面写的内容,对里面内容做少量修改)

前置准备工作

这是整个摄像机类的成员组成,其中私有成员函数updateCameraVector用于根据之上的公有成员来修改该摄像机的欧拉角参数,接下来逐个解释各个成员的实现细节

1.PositionFrontUpRightWorldUp分别表示摄像机位置、摄像机前轴、摄像机上轴、摄像机右轴、世界上轴(这5个向量组成了一个完整的摄像机坐标系)

2.YawPitch分别表示偏航角和俯仰角,用于鼠标控制摄像机,主要影响前轴,从而影响上轴和右轴

3.MovementSpeedMouseSensitivityZoom为杂项,字面意思

该类拥有两个构造函数:前者接受PositionUp(均为向量)YawPitch(都具有默认参数),其余值默认给定,其中Front默认置为(0,0,-1),其余同理。

后者接受posX,posY....upX..upZ(标量)、YawPitch,其余同上,两者作用一致,一个接受向量,一个接受标量而已。

注意在其最后调用的updateCameraVector,其根据给定的Yaw和Pitch值计算出一个摄像机的初始朝向(毕竟在构造函数里我们没有指定右轴)

GetViewMatrix根据得到的摄像机位置、前轴和上轴提供给GLM供其构造lookAt矩阵

ProcessKeyboard函数由外界的按键回调函数调用,根据按下键值更新摄像机位置值。

ProcessMouseMovement由外界鼠标动作回调函数调用,这里的xoffsetyoffset已经由调用方计算好,作为参数传递入内,另外防止俯仰角超出90度发生错误,最后调用updateCameraVector更新摄像机的3个轴。

ProcessMouseScroll函数处理鼠标滚轮操作,只需要滚轮垂直方向的偏移yoffset

updateCameraVector,唯一的私有成员函数,front根据YawPitch的值更新其3个分量,至于为什么是这么写的:(在硬盘报废前才写过,再写一遍也无妨了)

之前说过,摄像机的3个轴(前轴、上轴、右轴)共同构成了一个右手坐标系(前轴对应y轴,上轴对应z轴,右轴对应x轴),在已知偏航和俯仰角的情况下,怎么计算出前轴的各个分量(毕竟前轴关乎摄像机的指向)?这是一个典型的球坐标转笛卡尔坐标的问题:

上轴(Y)蓝色,前轴(Z)绿色,右轴(X)红色,俯仰角定义为A,偏航角定义为B(是的,就是这个角,定义的就是这样,很诡异)

得到:

y=sinA

x=cosAcosB

z=cosAsinB

问题解决

之后根据得到的Front更新计算右轴和上轴即可

PS.在源码里为什么要写成lastY-yoffset?,因为在NDC和屏幕坐标里,y轴正方向是相反的,NDC里向上,屏幕里向下

*最后再提一下位置值这个东西

教程第一章有两个地方出现了位置值,第一次是顶点属性指针,第二次是纹理单元

所以这个“位置值”到底应该怎么理解

借用一下VAO的图:

直观的来看,VAO是一个容器,其中内含着顶点属性指针,注意看这些指针最后的那个数字,那个就是“位置值”,所以从这个角度来看位置值是用于区分同类型对象的

再看一下顶点着色器:

layout (location = 0) in vec3 position;

location代表的就是位置值的意思,position是这个vec3变量的名字,这句的意思就是:”位置值为0的顶点属性指针指向的数据,应当作为position的内容,进入顶点着色器中“

那么在配置顶点属性指针时有:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);

第一个参数指定了该顶点属性指针的位置值,在这里,手动的将位置值设置为0 ,而该顶点属性指针配置的就是位置坐标。

最后再激活该顶点属性指针即可,参数为要激活的顶点属性指针的位置值:

glEnableVertexAttribArray(0);

纹理单元中的位置值含义同上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值