OpenGL超级宝典学习笔记——画直线


3D中画直线

在3D中画直线需要指定两个顶点。如下代码:会在两点之间画一条直线

glBegin(GL_LINES);

    glVertex3f(0.0f, 0.0f, 0.0f);

    glVertex3f(50.0f, 25.0f, 0.0f);

glEnd();

这里用两个顶点指定了一个图元。注意如果为GL_LINES指定奇数个顶点,那么最后一个顶点将被忽略。

static void RenderScene()

{

  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(0.0f, 1.0f, 0.0f);

  GLfloat x, y, z, angle;

  z = -50.0f;

  //画线

  glBegin(GL_LINES);

  for (angle = 0.0f; angle <= 2*GL_PI*3; angle +=0.5f)

  {

    x = 50.0f * cos(angle);

    y = 50.0f * sin(angle);

    //设置两个顶点

    glVertex3f(0.0f, 0.0f, 0.0f);

    glVertex3f(x, y, z);

    z += 0.5f;

  }

  glEnd();

  glutSwapBuffers();

}

效果如下图:

Image


连续的线以及线环

绘制一条连续的线,使用GL_LINE_STRIP,会绘制一条经过所有这些顶点的连续的线。实例如下:

glBegin(GL_LINE_STRIP);

    glVertex3f(0.0f, 0.0f, 0.0f);

    glVertex3f(50.0f, 50.0f, 0.0f);

    glVertex3f(50.0f, 100.0f, 0.0f);

glEnd();

Image(1)

GL_LINE_LOOP,与GL_LINE_STRIP相似。只是最后一个顶点和第一个顶点之间也会绘制一条直线,形成闭合的线。

Image(2)

用直线绘制近似的曲线

绘制近似曲线可以使用GL_LINE_STRIP来链接所有的点。当点之间的距离越来越近时,就可以形成一条平滑的曲线。示例如下:

//绘制场景

static void RenderSences()

{

  GLfloat z = -50.0f; 

  //清空画布

  glClear(GL_COLOR_BUFFER_BIT);

  //设置画图使用的颜色

  glColor3f(1.0f, 0.0f, 0.0f);

  //保存矩阵

  glPushMatrix();

  //旋转, 如果不旋转,那些不同层次的点都重叠在一起,看不出3D效果了。

  glRotatef(200.0f, 1.0f, 0.0f, 0.0f);

  glRotatef(120.5f, 0.0f, 1.0f, 0.0f);

  glBegin(GL_LINE_STRIP);

  for (GLfloat a = 0.0; a < GL_PI * 3.0f; a += 0.1f)

  {

    GLfloat x = 50.0f * cos(a);

    GLfloat y = 50.0f * sin(a);

    //设置点的大小

    //设置顶点

    glVertex3f(x, y, z);

    //调整z值

    z += 0.5f;

  }

  glEnd();

  glPopMatrix();

  glFlush();

}

Image(3)


设置直线的宽度

与设置点的宽度类似,我们也可以设置直线的宽度。但直线的宽度设置也是有限制的。我们可以取得直线宽度的范围,以及其宽度增长的最小间隔。

代码如下

GLfloat width[2];  //存储直线的宽度范围
GLfloat step;  //存储受支持的直线宽度增量

//获取受支持的直线宽度范围和增量 
glGetFloatv(GL_LINE_WIDTH_RANGE, width);
glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);

示例:

static void RenderScene()

{

  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(0.0f, 1.0f, 0.0f);

  //获取直线的宽度

  GLfloat width[2];

  GLfloat step;

  glGetFloatv(GL_LINE_WIDTH_RANGE, width);

  glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);

  GLfloat y, curWidht;

  curWidht = width[0];

  curWidht += step;

  //画线

  for (y = 80.0f; y > -80.0f; y -= 10.0f)

  {

    glLineWidth(curWidht);

    curWidht += step;

    glBegin(GL_LINES);

      glVertex2f(-50.0f, y);

      glVertex2f(50.0f, y);

    glEnd();

  }

  glutSwapBuffers();

}

Image(4)


直线点画

使用点线或虚线模式来绘制直线,称为点画。启用点画模式glEnable(GL_LINE_STIPPLE);

然后可以使用glLineStipple函数创建这种模式。

C Specification

void glLineStipple(
GLint 
factor,

GLushort 
pattern);

 

其中pattern参数是一个16位的值, 它指定了一个模式,供绘直线所用。它的每个位都表示线段的一部分是画还是不画。在默认情况下,每个位对应一个像素,但factor参数可以作为乘法因子增加模式的宽度。例如把factor设置为5会导致模式中的每个位代表一行中的连续5个像素。模式的第0位(最低有效位)首先被用于指定直线。

Image(5)

注意:模式的顺序是反过来的,这样的原因是OpenGL左移一位获得下一个掩码值的速度更快。

例子:

static void RenderScene()

{

  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(0.0f, 1.0f, 0.0f);

  //开启stipple模式

  glEnable(GL_LINE_STIPPLE);

  GLfloat y;

  GLint factor = 1;

  GLushort patter = 0x5555;

  //画线

  for (y = 80.0f; y > -80.0f; y -= 10.0f)

  {

    //设置因子和模式

    glLineStipple(factor, patter);

    glBegin(GL_LINES);

      glVertex2f(-50.0f, y);

      glVertex2f(50.0f, y);

    glEnd();

    factor++;

  }

  glutSwapBuffers();

}

Image(6)

示例代码地址:https://github.com/sweetdark/openglex/tree/master/drawline

OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见 

OpenGL编程指南(原书第7版)中文扫描版PDF 下载

OpenGL 渲染篇

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL  

更多《OpenGL超级宝典学习笔记》相关知识 见 

相关内容