跳转到内容

OpenGL 编程/基础/二维对象

来自维基教科书,开放世界中的开放书籍

绘制三角形和四边形

[编辑 | 编辑源代码]

glRectf() 虽然有用,但它不允许我们对矩形的单个顶点进行太多控制。为了给我们更多控制,并能够绘制更复杂的形状,我们必须使用不同的函数。

独立的顶点定义形状

[编辑 | 编辑源代码]

开始一个顶点定义的形状

[编辑 | 编辑源代码]

要开始一个由顶点定义的形状,我们使用 glBegin() 函数。glBegin() 接受一个参数:你想创建的形状类型。以下是一些可能的参数

  • GL_TRIANGLES
  • GL_QUADS
  • GL_POLYGON

四边形是任何具有 4 个顶点的形状:矩形、正方形、梯形等。顶点的位置将定义它是哪种类型的形状。

虽然多边形听起来很适合绘制复杂形状,但请向下滚动查看有关多边形限制的警告:多边形有很多限制,在某些情况下你可能最好使用一系列连接的四边形或三角形。

定义顶点

[编辑 | 编辑源代码]

在调用 glBegin() 之后,我们实际上使用 glVertex2f(float xPosition, float yPosition) 来定义顶点。

glBegin(GL_XYZ);
glVertex2f(-1.0f,-0.5f);
glVertex2f(1.0f,-0.25f);
...

重要提示:你定义顶点的顺序很重要!一般来说,如果你按逆时针顺序定义顶点,则正面将朝向你,这通常是你想要的。这种区别在我们进入 3D 时变得非常重要,所以请确保按逆时针顺序定义你的顶点,除非你知道自己在做什么!如果你想按顺时针顺序定义顶点,请确保在你的 setup() 函数中包含此函数

glFrontFace(GL_CW);

它将允许你仅按顺时针顺序绘制。

要结束一个顶点定义的形状,只需调用 glEnd(),它不接受任何参数。

此显示函数将在我们的屏幕中央绘制一个黑色的梯形。

void display() {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glColor3f(0.0f, 0.0f, 0.0f); // sets color to black.
       glBegin(GL_QUADS);
               glVertex2f(-0.25f, 0.25f); // vertex 1
               glVertex2f(-0.5f, -0.25f); // vertex 2
               glVertex2f(0.5f, -0.25f); // vertex 3
               glVertex2f(0.25f, 0.25f); // vertex 4
       glEnd();
       glutSwapBuffers();
}

关于样式的说明:对 glVertex() 的调用有时会缩进以将其与 glBegin() 和 glEnd() 分开。前面示例中的缩进不是错误。

高效地绘制一系列连接的形状

[编辑 | 编辑源代码]

如果我们要绘制一系列形状,其中每个形状都与另一个形状共享一条边或顶点,那么没有理由重复对 glVertex2f() 的如此多次调用。相反,我们使用一个特殊参数调用 glBegin() 以指示我们要绘制这些对象的“条带”。

使用 glBegin 与 GL_TRIANGLE_STRIP 或 GL_QUAD_STRIP

[编辑 | 编辑源代码]

当我们使用这两个参数中的任何一个调用 glBegin() 时,我们可以绘制一系列三角形或四边形,其中每个三角形或四边形都与另一个三角形或四边形共享一条边。这一个很好的用途是绘制复杂的形状,例如一个 2D 圣诞树。

三角形条带由用于三角形的 3 个初始顶点定义,然后每个额外的三角形由一个顶点定义。任何给定的三角形都是由它的一个顶点和它前面的两个顶点形成的。

四边形条带由用于四边形的 4 个初始顶点定义,然后每个额外的四边形由两个顶点定义。任何给定的四边形都是由它的两个顶点和它前面的两个顶点形成的。

该程序的示例输出

以下代码使用三角形条带定义一个房子的形状,它有一个倾斜的屋顶。

void display() {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glColor3f(0.0f, 0.0f, 0.0f); // sets color to black.
       glBegin(GL_TRIANGLE_STRIP); // draw in triangle strips
               glVertex2f(0.0f, 0.75f); // top of the roof
               glVertex2f(-0.5f, 0.25f); // left corner of the roof
               glVertex2f(0.5f, 0.25f); // right corner of the roof
               glVertex2f(-0.5f, -0.5f); // bottom left corner of the house
               glVertex2f(0.5f, -0.5f); //bottom right corner of the house
       glEnd();
       glutSwapBuffers();
}

在这里,定义了三个三角形,一个用于屋顶,一个用于房子的左上角,一个用于房子的右下角。

使用 glBegin 与 GL_TRIANGLE_FAN

[编辑 | 编辑源代码]

如果我们要绘制一堆三角形,其中每个三角形都共享一个预定义的顶点(例如,在原点),我们可以使用三角形扇形。三角形扇形通过奇数个顶点定义一个形状。第一个顶点定义一个中心点,每个三角形都将该点作为顶点。然后,每两个顶点都与初始顶点一起使用来定义一个三角形。

#include <GL/glut.h>

void init(){ 
    glClearColor(0,0,0,0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0,100,0,200);
}
void Display(){
     glClear(GL_COLOR_BUFFER_BIT);
     glBegin(GL_TRIANGLE_FAN);
         glColor3f(1,0,0);
         glVertex2f(0,0.5);
         glVertex2f(-0.4,0);
 	 glVertex2f(0.4,0);
         glColor3f(0,1,0);
 	 glVertex2f(0,-0.5);
     glEnd();
     glFlush(); 
} 

int main(int argc, char **argv){ 	
    glutInit(& argc, argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(200,200);
    glutCreateWindow("line");
    glutDisplayFunc(Display);
    init();
    glutMainLoop();
	
    return 0;
}

内置于 GLUT 的形状

[编辑 | 编辑源代码]

GLUT 有一些内置对象,只需调用一个简单的函数就可以使用它们。这些对象中最有趣和最有用的对象是

函数 二维形状 三维形状 注释
glutSolidSphere(float radius, int slices, int stacks) 圆形 球体 为 slices 和 stacks 参数选择一个 20-100 的整数;数字越大,球体/圆形越准确。
glutSolidCube(double size) 正方形 立方体
glutSolidCone(double base, double height, int slices, int stacks) 三角形 圆锥体 slices 参数越大,圆锥体看起来越平滑。
glutSolidTorus(double innerRadius, double outerRadius, int nSides, int rings) 环面
glutSolidTeapot(float radius) 茶壶 茶壶 是的,一个茶壶。请参阅维基百科文章“Utah 茶壶”,了解为什么选择了一个茶壶。
华夏公益教科书