基本状态管理
OpenGl维护了许多状态和状态变量。物体在进行渲染时可能会使用光照,纹理,隐藏表面消除,雾以及其它影响物体外观的状态。在默认情况下这些状态大部分是处于不活动状态的,激活这些状态可能需要较大开销。
打开关闭使用这些状态以下函数:可以向以下函数传枚举值作为参数
Void glEnable();
Void glDiasble();
可以使用GLboolean glIsEnabled()函数查询某种状态是处于开启还是禁用。
大部分OpenGL函数可以用来设置更为复杂的状态变量,可以使用以下五个查询函数查询当前许多状态的当前值
glGetBooleanv(),glGetIntegerv(),glGetFloatv(),glGetDouble(),glGetPointerv();
显示点直线和多边形
点
为了控制被渲染点的大小,可以使用glPointSize()函数,并在参数中提供一个参数,标示所需要点的大小(像素单位)。
直线
可以指定不同宽度直线,也可以指定不同点画模式的直线。Void glLineWidth();
为了创建点画线可以使用glLineStipple()函数定义点画模式 然后用glEnable()函数启用直线点画的功能
glLineStipple(1,0x3F07);
glEnable(GL_LINE_STIPPLE);
函数原型 void glLineStipple(Glint factor,GLushort pattern);
Pattern是一个由0或者1组成的16位序列,它们根据需要进行重复,对一条特定直线进行点画处理。从这个模式的低位开始,一个像素一个像素的进行处理。如果模型中对应1,就绘制,否则不绘制。模式可以使用factor参数扩展,它与1和0的连续子序列相乘,因此如果模式中出现了3个连续1,并且factor是2就扩展为6个1.
void drawOneLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
glBegin(GL_LINES);
glVertex2f((x1),(y1));
glVertex2f((x2),(y2));
glEnd();
}
void Init()
{
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_FLAT);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
//
glEnable(GL_LINE_STIPPLE);
glLineStipple(1,0x0101);
drawOneLine(50.0,125.0,150.0,125.0);
glLineStipple(1,0x00ff);
drawOneLine(150.0,125.0,250.0,125.0);
glLineStipple(1,0x1C47);
drawOneLine(250.0,125.0,350.0,125.0);
//
glLineWidth(5.0);
drawOneLine(50.0,100.0,150.0,125.0);
glLineStipple(1,0x00ff);
drawOneLine(150.0,100.0,250.0,125.0);
glLineStipple(1,0x1C47);
drawOneLine(250.0,100.0,350.0,125.0);
//
glLineStipple(5,0x1C47);
drawOneLine(50,25,350,25);
glDisable(GL_LINE_STIPPLE);
glFlush();
}
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei) w,(GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);
}
int _tmain(int argc, _TCHAR* argv[])
{
glutInit(&argc,(char**)argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("绘制几条线");
Init();
glutDisplayFunc(&myDisplay);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
点,轮廓或实心形式的多边形
多边形具有正反两面。取决于哪一面朝向观察者,多边形可能会被渲染成不同的样子。
glPolygonMode(GLenum face,GLenum mode)函数 控制一个多边形正面和背面的绘图模式。
Face参数可以是正反或者正或反。Mode参数可以是点,线或者填充,对应多边形被画成点,轮廓或者填充形式,在默认情况下,多边形正面和背面都是填充。
例如
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_LINE);
反转和剔除多边形表面
按照约定,如果多边形的顶点以逆时针顺序出现在屏幕上,称为正面。
可以使用glFrontFace()函数向他传递一个参数表示希望他把多边形的哪一面作为正面,从而交换了OpenGL的正面和背面的概念
Void glFrontFace(GLenum mode);
默认情况下model是GL_CCW标示窗口坐标上的投影多边形的顶点顺序为逆时针方向的表面为正面。
GL_CW标示顺时针为正面。
在一个完全封闭的表面上,所有的背面多边形都是不可见的,因为它们总是被多边形正面所遮挡。如果观察者位于这个表面的外侧,可以启用剔除功能,丢弃那些被OpenGL认定为背面的多边形。类似的如果观察者位于物体的内侧,只有背面是可见。为了告诉OpenGL丢弃那些不可见的背面和反面多边形,可以使用glCullFace()函数。当然在此之前需要打开剔除功能。
点画多边形
除了实心模式绘制,还有一种窗口对齐的点画模式
glPolygonStipple()函数用于指定多边形点画模式。
void glPolyaonStipple(const GLubyte *mask);
定义填充多边形当前点画模式。Mask参数是一个指向32X32位图的指针,后者被解释为0和1的掩码。如果是1绘制0不绘制。
void Init()
{
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_FLAT);
}
void myDisplay()
{
GLubyte fly[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0x80,0x01,0xc0,0x06,0xc0,0x03,0x60,
0x40,0x60,0x06,0x20,0x04,0x30,0x0c,0x20,
0x04,0x18,0x18,0x20,0x04,0x0c,0x30,0x20,
0x04,0x06,0x60,0x20,0x44,0x03,0xc0,0x22,
0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
0x44,0x01,0x80,0x22,0x44,0x01,0x80,0xcc,
0x66,0x01,0x80,0x66,0x33,0x01,0x80,0xcc,
0x19,0x81,0x81,0x98,0x0c,0xc1,0x83,0x30,
0x07,0xe1,0x87,0xe0,0x03,0x3f,0xfc,0xc0,
0x03,0x31,0x8c,0xc0,0x03,0x33,0xcc,0xc0,
0x06,0x64,0x26,0x60,0x0c,0xcc,0x33,0x30,
0x18,0xcc,0x33,0x18,0x10,0xc4,0x23,0x08,
0x10,0x63,0xc6,0x08,0x10,0x30,0x0c,0x08,
0x10,0x18,0x18,0x08,0x10,0x00,0x00,0x08
};
GLubyte halftone[] ={
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
};
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
glRectf(25.0,25.0,125.0,125.0);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(fly);
glRectf(125.0,25.0,225.0,125.0);
glPolygonStipple(halftone);
glRectf(225.0,25.0,325.0,125.0);
glDisable(GL_POLYGON_STIPPLE);
glFlush();
}
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei) w,(GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);
}
int _tmain(int argc, _TCHAR* argv[])
{
glutInit(&argc,(char**)argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("绘制若干个多边形");
Init();
glutDisplayFunc(&myDisplay);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
后面的章节使用显示列表来存储多边形点画模式来效率最大化