上一篇介绍了基础图元的绘制,讲到了如何绘制点线面。在MFC中,对笔触的控制我们可以调用
CPen
和CBrush
这两个对象。同样在OpenGL中也有类似的操作,不过稍微复杂一点。
点的属性
点的属性恐怕就只有点的大小了,通过调用void glPointSize(GLfloat size)
函数可以设置点的大小,传入的参数是一个浮点数代表点的像素。
这个设置是支持反走样(antialiasing)的,如果你设置了反走样这个函数同样适用。
有的时候渲染图形会出现锯齿甚至和理想线条相差很大,我们通过反走样技术解决这个问题。OpenGL中通过调用函数
glEnable(GL_POINT_SMOOTH)
来设置为反走样状态,默认状态下不是反走样状态的。
线的属性
线的属性大致有两种,一是线宽,二是样式。
设置线宽和设置点大小一样,通过void glLineWidth(GLfloat width)
函数来设置,传入的参数也是浮点数。同样支持反走样。
线的样式设置比较有意思,通过void glLineStipple(GLint factor,GLushort pattern)
函数来设置。第一个参数是因子,我把它简单的理解为线条样式拉伸的系数,第二个参数比较有趣,它是用来描绘具体样式的16位整数。1对应实线,0对应空白,通过这种方法表现出来样式。
这是我画的虚线,对应的样式是0x0A0A。在设置样式的时候需要调用glEnable(GL_LINE_STIPPLE)
函数打开线段样式渲染状态。
面的属性
即使是二维的平面也分为正面和背面,比如说如果我顺时针方向渲染的点为正面,那么逆时针渲染的点就是背面了。有了这一概念我们就可以单独的对图形的某一个面操作,比如说正面填充背面描边。
void glFrontFace(GLenum mode)
可以设置图形的正面与背面(相反的为背面),参数是顺时针或逆时针。void glPolygonMode(GLenum face,GLenum mode)
可以分别对正面或背面以不同方式渲染。举个例子。
void display()
{
glFrontFace(GL_CCW);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(0.1f, 0.0f);
glVertex2f(0.3f, 0.2f);
glVertex2f(0.0f, 0.2f);
glEnd();
glBegin(GL_POLYGON);
glVertex2f(-0.3f, -0.2f);
glVertex2f(-0.1f, 0.0f);
glVertex2f(-0.0f, -0.2f);
glEnd();
glFlush();
}
我通过顺时针和逆时针两种方式画的两个三角形,渲染结果是不同的。
此外,void glEdgeFlag( GLboolean flag)
函数可以指定边是否是边界,如果不是可以隐藏它。
void display()
{
glFrontFace(GL_CCW);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glEdgeFlag(GL_TRUE);
glVertex2f(0.5f, 0.5f);
glEdgeFlag(GL_FALSE);
glVertex2f(-0.5f, 0.5f);
glEdgeFlag(GL_TRUE);
glVertex2f(0.5f,-0.5f);
glEdgeFlag(GL_FALSE);
glVertex2f(-0.5f,-0.5f);
glEnd();
glFlush();
}
通过这个特性我简单的画了一个“二”。
关于面的属性还有很多。比如样式、纹理甚至雾化效果,这个在现代OpenGL里面再说吧。
下一篇可能会介绍法向向量和顶点数组,之后如果老师布置了坐标变换也会整理进来,希望对后来的学弟学妹有帮助吧。