在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();
}
效果如下图:
绘制一条连续的线,使用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();
GL_LINE_LOOP,与GL_LINE_STRIP相似。只是最后一个顶点和第一个顶点之间也会绘制一条直线,形成闭合的线。
绘制近似曲线可以使用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();
}
与设置点的宽度类似,我们也可以设置直线的宽度。但直线的宽度设置也是有限制的。我们可以取得直线宽度的范围,以及其宽度增长的最小间隔。
代码如下
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();
}
使用点线或虚线模式来绘制直线,称为点画。启用点画模式glEnable(GL_LINE_STIPPLE);
然后可以使用glLineStipple函数创建这种模式。
void glLineStipple(
GLint?
factor,
GLushort?
pattern);
?
注意:模式的顺序是反过来的,这样的原因是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();
}
示例代码地址:https://github.com/sweetdark/openglex/tree/master/drawline