学习是一件开心的额事情
顶点是啥? 顶点就是坐标位置,不管你是画直线,三角形,正方体,球体,以及3D游戏人物等,都需要顶点来确定其形状。 顶点坐标创建 1.记住顶点的坐标数据类型都设置为GLfloat 类型,这个是OpenGL 要求的,4个字节长度 2.顶点可可以被定为为2维或者三维,这个看你的实际情况!但是你要注意,所有的内部计算都是建立在三维数据的基础之上,比如:你定义一个点(x,y) 是二维形式,OpenGL默认把它的z设置为0,看到这里你以为三维就是(x,y,z)的形式吗?不是的,OpenGL 是根据三维投影几何的齐次方程坐标进行操作的,因此在内部计算是都是用4个浮点坐标值表示(x,y,z,w) 如果w不等于0 那么这些坐标值就对应于与欧几里德三维点(x/w,y/w,z/w)。一般情况下w默认为1.0.
多变形 通过介绍多变型绘制,帮大家建立起几个概念. 多变型是由线段构成的单闭合环,其中线段是由他们的顶点位置的顶点指定的。一般情况下,在绘制多变形时,有这样几种形态: 1.内部的像素将被填充 2.绘制外边的边框 3.只绘制点
绘制面 不管绘制平面和绘制立体图形,我们都是在面上进行操作的,要绘制一个面,需要绘制多个小三角形。 我们就拿绘制四面体举例子:
F30063E6-2137-4756-A627-4EA0022240E2.png
我们先把它的顶点坐标写设定一下:
static GLfloat vertex[4\*3] = {
0,0.5,0, //V0
-0.5,0,0, //V1
0.5,0,0, //V2
0,0,-0.5 // V3
}
我们有两个绘制顶点的方法可供选择:
void glDrawArrays (GLenum mode, GLint first, GLsizei count);
void glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
我们下面讲的内容将围绕这两个函数展开, 先看两个函数的参数:都有mode,那么这个mode 代表什么意思的,其实就是绘制模式:
下面这个是我从苹果的头文件复制的
#define GL_POINTS 0x0000
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
#define GL_LINE_STRIP 0x0003
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRIANGLE_FAN 0x0006
我来讲讲它们怎么使用! 刚才说了,绘制多面体,就是要绘制多个三角形,以三角形为最小单位绘制,记住这句话!
GL_POINTS
,如果你选择这个模式,一般四面体的顶点数据就要放在一个数组中:
static GLfloat vertex[4\*3\*3] = {
// 第一个三角形
0,0.5,0,
-0.5,0,0,
0,0,0.5
// 第二个三角形
0,0.5,0,
0.5,0,0,
0,0,0.5
// 第三个三角形
-0.5,0,0,
0,0.5,0,
0,0,0.5
// 第四个三角形
-0.5,0,0,
0,0,0.5
0,0.0,0.5,
}
那么我们绘制的方法相应的会选择 :
void glDrawArrays (GLenum mode, GLint first, GLsizei count);
我解释一下参数的含义: 参数1 :Mode :这个不用说,绘制模式,在这种方式我们选择GL_POINTS 参数2: first :从数组的那个位置开始,一般如果数组没有其他类型的数据,只有顶点数据,我们就填 0 参数3: count 就是绘制顶点的个数, 例子中是4*3*3
mode:GL_LINES 它的绘制过程是这样的:先绘制V0,V1一条直线, 然后绘制V2,V3,又是一条直线。如下图:
FCE77035-AE23-45CB-8311-FE85455B40CE.png
问:如果顶点的数据为奇数怎么办? 答: 最后一个顶点被忽略,就这么任性!
效果如下:
GL_LINE_STRIP
绘制方式总结一下: 如果你有n个顶点,先绘制 V0到V1,接着绘制V1到V2,最后绘制Vn-2 到Vn-1 ,因此有n-1 条直线,如果n 不是大于1的,就不会绘制任何直线。
GL_LINE_LOOP
绘制步骤: V0到V1,V1到V2,V2到V3,V3到V0
重点来了,下面是绘制立体图形比较重要的几种方式
GL_TRIANGLES
下面这个两种主要用于顶点索引,使用到的绘制函数为:
void glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
当然 解释一下: 参数1: mode : 绘制方式 参数2:顶点索引个数 参数3:索引数据类型 参数4:顶点索引数组地址
四面体
我们把这个面从V0 开始,裁剪组合成4个三角形
12D70C2D-FBE2-4F76-B05D-E91519397B41.png
看这张图,如果使用GL_TRANGLE_STRIP 顶点索引应该是怎么的排列呢?
顶点坐标:
static GLfloat vertex[4*3] = {
0,0.5,0, //V0
-0.5,0,0, //V1
0.5,0,0, //V2
0,0,-0.5 // V3
}
坐标索引
static GLuint index[] = {
3,1,0,2,3,1
}
// 执行绘制
glDrawElements(GL_TRIANGLE_STRIP,6,GL_GL_UNSIGNED_BYTE,index);
计算机其实是这样实现的: 首先我们把点按照顺序排列好(3,1,0,2,3,1) (3,1,0) (1,0,2) 变换前两个位置 (0,1,2) (0,2,3) (2,3,1) 变换前两个位置(3,2,1)
保证绘制的每个三角形顺序(逆时针)一致。
四面体
GL_TRIANGLE_FAN
顶点索引数组
static GLuint index1[5] = {
0,1,2,3,1
}
static GLuint index2[3] = {
1,3,2
}
调用绘制方法的时候,需要调用两次
glDrawElements(GL_TRIANGLE_FAN,5,GL_GL_UNSIGNED_BYTE,index1);
glDrawElements(GL_TRIANGLE_FAN,3,GL_GL_UNSIGNED_BYTE,index2);
问: GL_TRIANGLE_STRIP 和 GL_TRIANGLE_FAN 方式能使用函数 void glDrawArrays (GLenum mode, GLint first, GLsizei count); 吗? 当然可以,只要你的排列方式符合其绘制规则即可!
顶点坐标概念非常重要,希望你能够掌握!如有疑问,请加群:578734141