经历前两节课,想必大家能够编写一些基本的OpenGL小程序。但是对这个glBegin里的冬冬,还是心生困惑的。因此我将这里的基本类型给大家列下来。
我们在画一个图元的时候,通常如下,比如Helloj2ee绘制的北斗七星图。
glBegin(g_geotype); glVertex2i(289, 190); // 绘制若干个点 glVertex2i(320, 128); glVertex2i(239, 67); glVertex2i(194, 101); glVertex2i(129, 83); glVertex2i(74, 74); glVertex2i(20,10); glEnd();
同样是点,那么glBegin里面传的参数不一样,则绘制的图形不一样。OpenGL提供了以下10种基本几何图元。
GL_POINTS 为n个顶点的每一个都绘制一个点,以北斗七星为例,如果g_geotype = GL_POINTS,那么得到效果如下图(点是人为标示上去,OpenGL绘制注记,并不像一般图形平台那么容易)。
如果g_geotype = GL_LINES,一对顶点才被解释为一条直线,直线之间并不连接,但是如果不凑巧是奇数个点,那么最后一个点不幸要被忽略掉,因此这里v7这个点就被忽略掉。
如果g_geotype = GL_LINE_STRIP,则是一系列的直线。即从v0到v1,一直到v7。如下图所示:
如果g_geotype = GL_LINE_LOOP,和GL_LINE_STRIP相似,只不过构成一个线环,注意阿,它仍是线,而不是面,只不过是一个闭合的线。
如果g_geotype = GL_TRIANGLES,那么它是一系列的三角形,n只有是3的倍数,那么才能恰好所有点构成三角形,n不是3的倍数,剩下的点就会被忽略。
如果g_geotype = GL_TRIANGLE_STRIP,那么第一个三角形是v1,v3,v2,第二个三角形是v2,v4,v3,依次类推,注意三个点的顺序。要保证所有的三角形是按相同方向绘制。
如果g_geotype = GL_TRIANGLE_FAN,和GL_TRIANGLE_STRIP类似,区别在于一直是以v1开始,v1,v3,v2 和v1 v4 v2等等。
如果g_geotype = GL_QUADS,则是一系列的四边形,首先使用顶点v1,v2,v3,v4,然后不是4的倍数,只能忽略。
如果g_geotype = GL_QUAD_STRIP,绘制一系列四边形,但是四边形的顺序是顶点 2n-1、2n、2n+2和2n+1定义了第n个四边形。由于这并非是一个凸多边形,因此会很怪异。
如果g_geotype = GL_POLYGON,则是绘制一个多边形。点的个数必须大于等于3。多边形本身不要相交,且最好是凸多边形。如果顶点不满足这些条件,也许正确,也许不正确。
该程序代码如下所示。
#include#include #include #include #define E_POINTS 1 #define E_LINES 2 #define E_LINES_STRIP 3 #define E_LINE_LOOP 4 #define E_TRIANGLES 5 #define E_TRIANGLES_STRIP 6 #define E_TRIANGLES_FAN 7 #define E_QUADS 8 #define E_QUAD_STRIP 9 #define E_POLYGON 10 GLenum g_geotype = GL_POINTS; //<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>> void myInit(void) { glClearColor(1.0, 1.0, 1.0, 0.0); // 设置背景颜色为亮白 glColor3f(0.0f, 0.0f, 0.0f); // 设置绘制颜色为黑 glPointSize(4.0); //设置点的大小为4*4像素 glMatrixMode(GL_PROJECTION);// 设置合适的投影矩阵-以后解释 glLoadIdentity();// 以后解释 gluOrtho2D(0.0, 480.0, 0.0, 320.0);// 以后解释 // g_geotype = GL_POINTS; } //<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>> // 重绘函数 void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); // 清屏幕 glBegin(g_geotype); glVertex2i(289, 190); // 绘制若干个点 glVertex2i(320, 128); glVertex2i(239, 67); glVertex2i(194, 101); glVertex2i(129, 83); glVertex2i(74, 74); glVertex2i(20,10); glEnd(); glutSwapBuffers(); // 将所有输出到显示屏上 } void ProcessMenuEvents(int option) { switch(option) { case E_POINTS: g_geotype = GL_POINTS; break; case E_LINES: g_geotype = GL_LINES; break; case E_LINES_STRIP: g_geotype = GL_LINE_STRIP; break; case E_LINE_LOOP: g_geotype = GL_LINE_LOOP; break; case E_TRIANGLES: g_geotype = GL_TRIANGLES; break; case E_TRIANGLES_STRIP: g_geotype = GL_TRIANGLE_STRIP; break; case E_TRIANGLES_FAN: g_geotype = GL_TRIANGLE_FAN; break; case E_QUADS: g_geotype = GL_QUADS; break; case E_QUAD_STRIP: g_geotype = GL_QUAD_STRIP; break; case E_POLYGON: g_geotype = GL_POLYGON; break; } } //<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>> void main(int argc, char **argv) { glutInit(&argc, argv); // 初始化工具包 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 设置显式模式 glutInitWindowSize(640,480); // 设置窗口大小 glutInitWindowPosition(100, 150); // 设置窗口位置 glutCreateWindow("my first attempt"); // 打开屏幕窗口 myInit(); glutDisplayFunc(myDisplay); // 注册绘制函数 glutIdleFunc(myDisplay); glutCreateMenu(ProcessMenuEvents); glutAddMenuEntry("POINTS",E_POINTS); glutAddMenuEntry("LINES",E_LINES); glutAddMenuEntry("LINES_STRIP",E_LINES_STRIP); glutAddMenuEntry("LINE_LOOP",E_LINE_LOOP); glutAddMenuEntry("TRIANGLES",E_TRIANGLES); glutAddMenuEntry("TRIANGLES_STRIP",E_TRIANGLES_STRIP); glutAddMenuEntry("TRIANGLES_FAN",E_TRIANGLES_FAN); glutAddMenuEntry("QUADS",E_QUADS); glutAddMenuEntry("QUAD_STRIP",E_QUAD_STRIP); glutAddMenuEntry("POLYGON",E_POLYGON); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); // 进入主循环 }