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

https://www.jianshu.com/p/8e1ff345cf53

1. 利用openGL画点、线、面

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

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

  • 画点 GL_POINTS
    示例 (所有代码展示皆为display中的语句)
    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();

效果

绘制两点

 

  • 画线 GL_LINES
    示例
    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);

只剩下了反面的图形

 

剔除正面

你可能感兴趣的:(openGL)