经历前两节课,想必大家能够编写一些基本的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。多边形本身不要相交,且最好是凸多边形。如果顶点不满足这些条件,也许正确,也许不正确。
该程序代码如下所示。
View Code
#include <windows.h>
#include <gl/Gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#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(); // 进入主循环
}