OpenGL:使用顶点数组法绘制正六面体
在今天的opengl的课程以及实验中,我们学习了如何使用顶点数组的方法来绘制图形,但相信还有很多同学对它的实际使用方法不太了解,我们就用我们今天实验课上的实例来简单讲解一下
题目及要求
绘制一个正六面体,正面以填充方式绘制,背面以轮廓线的形式绘制,坐标自拟
思路解析
首先,我们需要定义一个数组,用来存放所有的顶点,为了方便理解,我们可以画一个草图:
这样,我们就可以写出顶点坐标数组:
1 //存放所有顶点坐标的数组 2 float vertex_list[][3] = 3 { 4 {0,0,0}, 5 {1,0,0}, 6 {1,1,0}, 7 {0,1,0}, 8 9 {0,1,1}, 10 {1,1,1}, 11 {1,0,1}, 12 {0,0,1} 13 };
接下来,我们需要一个顶点坐标的索引数组,索引数组用来表示的是顶点被绘制的顺序,每个点的编号代表的是顶点坐标数组中该点对应的下标。
例如,点(0,0,0)用数组表示为 vertex_list[0],则(0,0,0)为0号点,则上述数组中所有点的编号为:
我们将顶点编号完毕之后,我们就可以来定义点的绘制顺序了。
我们用0123的顺序绘制第一个面,4567的顺序绘制第二个面,2761的顺序绘制第二个面,3450的顺序绘制第四个面。
写成数组形式如下:
1 //存放数组索引的数组,可以近似地理解为顶点被绘制的顺序 2 int index_list[] = 3 { 4 0,1,2,3, 5 4,5,6,7, 6 2,7,6,1, 7 3,4,5,0 8 };
这样一来,四个侧面都绘制完毕,由于上下两个面直接由四个侧面拼接而成了,所以没有必要非要绘制。
顶点数组和索引数组都被定义完毕,接下来我们可以进行正式的代码书写了。
完整代码及其结果
1 #include<gl/glut.h> 2 //存放所有顶点坐标的数组 3 float vertex_list[][3] = 4 { 5 {0,0,0}, 6 {1,0,0}, 7 {1,1,0}, 8 {0,1,0}, 9 10 {0,1,1}, 11 {1,1,1}, 12 {1,0,1}, 13 {0,0,1} 14 }; 15 16 //存放数组索引的数组,可以近似地理解为顶点被绘制的顺序 17 int index_list[] = 18 { 19 0,1,2,3, 20 4,5,6,7, 21 2,7,6,1, 22 3,4,5,0 23 }; 24 25 void display(void) 26 { 27 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 28 glOrtho(-1, 2, -1, 2, -1, 2); //设置屏幕的显示范围 29 glPolygonMode(GL_FRONT, GL_FILL); //设置正面为填充类型 30 glPolygonMode(GL_BACK, GL_LINE); //设置背面为轮廓线类型 31 glFrontFace(GL_CCW); //将逆时针设置为正面 32 glRotatef(45, -1, 1, 0); //将图形旋转一下以便看得更直观 33 34 glEnableClientState(GL_VERTEX_ARRAY); //启用顶点数组 35 glVertexPointer(3, GL_FLOAT, 0, vertex_list); //指定顶点数组 36 //按照索引数组中指出的数组依次调用glVertex函数,16表示的是调用的次数 37 glDrawElements(GL_QUADS, 16, GL_UNSIGNED_INT, index_list); 38 39 glFlush(); 40 } 41 int main(int argc, char**argv) 42 { 43 glutInit(&argc, argv); 44 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); 45 glutInitWindowPosition(200, 200); 46 glutInitWindowSize(500, 500); 47 glutCreateWindow("正六面体"); 48 glutDisplayFunc(display); 49 glutMainLoop(); 50 return 0; 51 }