openGL 基础知识(一)绘制简单图形

2018-09-09  本文已影响0人  正经龙

1. 利用openGL画点、线、面

glBegin(所画类型)
这里设置画图所需要的点
glEnd()

openGL中,需要画点、线、面都是包含在两条语句中
glBeginglEnd中,所画图形的不同都是通过设置glBegin中的参数来决定。

    glClearColor(0.0f, 0.0f, 0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_POINTS);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();

效果

绘制两点
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();
    glClearColor(0.0f, 0.0f, 0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

效果

绘制直线

除此之外还有
GL_LINE_STRIP(很多个点直接连接),GL_LINE_LOOP(收尾相连的闭合线),GL_TRIANGLES(绘制三角形),GL_TRIANGLE_STRIP(确保绘制的三角形都是同方向的),GL_TRIANGLE_FAN等各种绘制方式。

区别
区别2
static int n = 20;
static GLfloat R = 0.5;
static const GLfloat PI= 3.141592653;
void display(void) {
    glClearColor(0.0f, 0.0f, 0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_POLYGON);
    for (int i = 0; i < n; i++) {
        glVertex2f(R*cos(2 * PI / n * i), R*sin(2 * PI / n * i));
    }
    glEnd();
    glFlush();
}
画圆

注意到,这里使用了GL_POLYGON,这种绘图方式会将图形内部进行自动填充。如若使用GL_LINE_LOOP则会产生这种效果:

不填充
void display(void) {
    GLfloat x;
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_LINES);
    glVertex2f(-1.0f, 0.0f);
    glVertex2f(1.0f, 0.0f);         // 以上两个点可以画x轴
    glVertex2f(0.0f, -1.0f);
    glVertex2f(0.0f, 1.0f);         // 以上两个点可以画y轴
    glEnd();
    glBegin(GL_LINE_STRIP);
    for (x = -1.0f / factor; x<1.0f / factor; x += 0.01f)
    {
        glVertex2f(x*factor, sin(x)*factor);
    }
    glEnd();
    glFlush();
}

效果

image.png

2. 关于点与直线

点的大小默认为1个像素,但也可以改变之。改变的命令为glPointSize,其函数原型如下:
void glPointSize(GLfloat size);
size必须大于0.0f,默认值为1.0f,单位为“像素”。

(1)直线可以指定宽度:
void glLineWidth(GLfloat width);
其用法跟glPointSize类似。

(2)画虚线。
首先,使用glEnable(GL_LINE_STIPPLE);来启动虚线模式(使用glDisable(GL_LINE_STIPPLE)可以关闭之)。
然后,使用glLineStipple来设置虚线的样式。
void glLineStipple(GLint factor, GLushort pattern);
pattern是由1和0组成的长度为16的序列,从最低位开始看,如果为1,则直线上接下来应该画的factor个点将被画为实的;如果为0,则直线上接下来应该画的factor个点将被画为虚的。

___示例

void display(void) {
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(2, 0x0f0f);
    glLineWidth(10.0f);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
    glEnd();
    glFlush();
}
虚线

3. 关于多边形的正反面

多边形在我们的二维坐标系中,我们一般把朝向我们的一面认为是正面,而把背朝着我们的一面认为是反面,在openGL中也存在着正反两面。接下来我们将通过一个示例,来讲解正反两面的写法与区别。

我们在进行绘制正反面之前,我们约定,逆时针方向绘制的面为正面,顺时针方向绘制的面为反面。我们通过

glFrontFace(GL_CCW);   // 设置CCW方向为“正面”,CCW即CounterClockWise,逆时针

设置逆时针方向为正面。

为了体现出正反两面的区别,我们设置正面为填充模式,反面为线性绘制模式。接下来看我们的示例代码

     glClear(GL_COLOR_BUFFER_BIT);
     glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式
     glPolygonMode(GL_BACK, GL_LINE);   // 设置反面为线形模式
     glFrontFace(GL_CCW);               // 设置逆时针方向为正面
     glBegin(GL_POLYGON);               // 按逆时针绘制一个正方形,在左下方
         glVertex2f(-0.5f, -0.5f);
         glVertex2f(0.0f, -0.5f);
         glVertex2f(0.0f, 0.0f);
         glVertex2f(-0.5f, 0.0f);
     glEnd();
     glBegin(GL_POLYGON);               // 按顺时针绘制一个正方形,在右上方
         glVertex2f(0.0f, 0.0f);
         glVertex2f(0.0f, 0.5f);
         glVertex2f(0.5f, 0.5f);
         glVertex2f(0.5f, 0.0f);
     glEnd();
     glFlush();

效果

正反两面

在三位绘图中,我们难免会遇到遮挡的问题,当我们面朝着正面的时候,反面难免会被遮挡而无法看到,所以这个时候我们就可以通过剔除来节约我们的计算空间。

首先需要通过glEnable(GL_GULL_FACE)来允许剔除(可通过glDisable去除)

glCullFace的参数可以是GL_FRONT,GL_BACK或者GL_FRONT_AND_BACK,分别表示剔除正面、剔除反面、剔除正反两面的多边形。

在上面的代码中加上这两句

    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);

只剩下了反面的图形


剔除正面
上一篇下一篇

猜你喜欢

热点阅读