将学到的opengl有些坑和知识作些总结,当然了,坑还在挖,所以还会更新的*
1.VAO VBO EBO
这三个东西的功能是非常强大的,VBO是保存顶点有关元数据的,一般情况下,我们不会出错,但是没有很了解的情况下,我们画多个图就会出错,首先我先强调下几点意识
一个绘制对象我们会申请一个VAO VBO,(EBO视情况而定),对象而言你最好有c++类一样的工具或意识来包裹它(因为这有个最大的优点,重用性),如果你认为我说的对象是等同于c++的对象,那么最好请重新设计这个对象,满足我说的这种意识
用glfw的知道,我们绘制opengl是在宿主窗口的while循环里做的,当我们"同时"(这里的“同时”是宿主窗口的一次循环)绘制很多不同的opengl对象呢,这是通过
glBindVertexArray(VAOID)做到的,可是我们又有疑问我们还需要调用glBindBuffer绑定VBO EBO吗,答案是不需要的(只要你不手动解绑就可以了),第二个问题,我们还需要绑定数据吗,我们初始会调用glBufferData推送数据,那么之后该VAO被解绑后还需要再推送数据是不必的(只要你没解绑VBO)
通过以上我们得出个结论,当在一帧绘制不同对象时,只要切换VertexArray的绑定对象就可以了,相当于VBO保存了原始数据 EBO保存了数据索引 VAO保存了他们两且能指定数据的范围及表示方式,只要不破坏这些关系,绘制的就是你想要的对象
2.纹理个数的范围是针对谁的
答案是针对程序的,不是你写的程序,是你写的链接两个着色器的程序,那么当我们切换程序时自然就且切换了GL_TEXTURE_2D所属对象,这个结论就是我们不再需要在每一帧里glBindTexture了
3.局部坐标系是啥?
这个问题我是作了好几个实验才弄明白的
第一:我们所画的对象都是基于视口的,还记得我们新学opengl,不用多说我们都是画的三角形.可是我们都不敢把坐标定位的超过abs(1.0),这是为什么呢?这是因为视口一开始不确定的,所以先通过(-1,1)映射为视口的范围,opengl里所有的坐标系最后生成的都是-1.0-1.0的坐标系,那么我们在一开始定义的坐标是什么坐标系呢?因为我们画的物体都是一开始是被特殊对待的,我们能定义它点与点的关系以及形状,但是我们不能确定他们在世界上的位置(opengl的视口场景),比如我一开始想用c++的类表示一个由opengl绘制的Cube(立方体对象),然后我能够随意指定它在opengl场景的位置就可好了,学的深一点的肯定知道通过矩阵变换就可以啦,不过就是将局部坐标系转换为世界坐标系吗,可是你真的懂局部坐标系吗
首先我们创建一个Cube对象,然后调用draw就好啦,可是我们怎么指定坐标呢?
个人建议:所有对象最大顶点坐标都是abs(-1),比如我们创建一个顶点范围在(-0.5,0.5)三角形对象,然后创建了(-1.0,1.0)的对象,当映射到世界坐标系,对于他们的相对大小你或许觉得还能应付,但是遇到平移指定他们相对位置时就gg了
那么怎么形象化解释局部坐标系和世界坐标系呢
局部坐标系就是物体(-1,1)范围坐标系,世界坐标系就是视口的(-1,1)范围坐标系,我一开始我定义物体坐标系为(-1,1),就像美术老师拿出一张固定大小的纸,然后发给学生每人一张纸,让他们在纸上的不同位置画个图,最后把这些相同大小的纸叠放在老师的纸上,最后学生纸上什么位置的对象就画在老师的纸上,一开始老师的纸是世界坐标系,学生的纸是视口坐标系(虽然还没画),但是每个学生都很有爱心,不想占太多空间,画了较小的东西,于是局部物体就相当于世界坐标系就变小了,那么我们怎么反映这种情况呢?很明显要么扩大世界坐标系,要么直接缩小物体坐标系,因为他们都很小了,所以扩大世界坐标系,因为我们所以对象都是(-1.0,1.0),他们作为一个世界物体始终都是单位一,我们调整比例就可以得出相对大小,而且能够通过坐标轻易的平移
比如一个物体是缩小35倍那么世界坐标就变成了(-35,35),另一个物体是缩小了20倍那么世界坐标系(-20,20),如果要指定他们相对位置,就要计算一波了