填充区的属性

填充区的属性有:填充图案、纹理和插值图案、线框图、前向面等等。

填充图案

填充图案可由类似位图的形式实现,从屏幕左下角开始平铺,与多边形相交部分显示。

纹理和插值图案

为了达到真实的效果,经常需要对不同顶点赋以不同颜色,中间的颜色渐变即为插值颜色。使用方法与线的插值类似。

线框图

对于一个多边形,可以选择只显示边、只显示点等。需要用到这个函数:

glPolygonMode(face, displayMode);

第一个参数指定前向面还是后向面,第二个参数指定填充方式。

对于一个三维多边形,由于算法误差,填充多边形的方法可能在边之间生成缝隙,称作缝线。为了消除边的不重叠,可以使用如下函数:

glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(factor1, factor2);

第二个函数用来调整位移。具体计算公式为depthOffset = factor1 • maxSlope + factor2 • const
emmm以后再说吧。。

在显示线框图的时候,有一些边我们并不希望它显示,这时候可以用glEdgeFlag来屏蔽接下来的点生成的边。与顶点数组类似,也有边标志数组,用法为:

glEnableClientState(GL_EDGE_FLAG_ARRAY);
glEdgeFlagPointer(offset, edgeFlagArray);

当然喜欢的话也可以搞交错数组。。

前向面

默认逆时针是前向面,但是也可以通过

//GL_CW or GL_CCW
glFrontFace(vertexOrder);

来修改

填充图案、插值图案、线框图示例

#include<Windows.h>
#include<GL/glut.h>

GLubyte fillPattern[] =
{
    0xff, 0x00, 0xff,
    0x00, 0xff, 0x00,
    0xff, 0x00, 0xff
};

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glPolygonStipple(fillPattern);
    glEnable(GL_POLYGON_STIPPLE);
    glColor3d(1.0, 0.0, 0.0);
    glBegin(GL_POLYGON);
    {
        glVertex2i(300, 300);
        glVertex2i(400, 300);
        glVertex2i(500, 400);
        glVertex2i(400, 400);
    }
    glEnd();
    glDisable(GL_POLYGON_STIPPLE);

    glShadeModel(GL_SMOOTH);
    glBegin(GL_TRIANGLES);
    {
        glColor3d(1.0, 0.0, 0.0);
        glVertex2i(100, 100);
        glColor3d(0.0, 1.0, 0.0);
        glVertex2i(200, 100);
        glColor3d(0.0, 0.0, 1.0);
        glVertex2i(150, 173);
    }
    glEnd();

    glPolygonMode(GL_FRONT, GL_LINE);
    glBegin(GL_TRIANGLES);
    {
        glVertex2i(300, 100);
        glEdgeFlag(GL_FALSE);//下个点引出的边将不可见
        glVertex2i(400, 100);
        glEdgeFlag(GL_TRUE);
        glVertex2i(350, 173);
    }
    glEnd();
    glPolygonMode(GL_FRONT, GL_FILL);

    glFlush();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("fill");
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 800.0, 0.0, 600.0);

    glutDisplayFunc(display);

    glutMainLoop();
}