绘制几何体(二)

基本状态管理
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;
}

后面的章节使用显示列表来存储多边形点画模式来效率最大化

原文地址:https://www.cnblogs.com/yutingliuyl/p/7119945.html