今天我们来看一下在OpenGL中如何绘制点线面。
我们使用glBegin,和glEnd两个函数进行所要绘制图形的描述。绘制的内容要放在这两个函数之间。
glBegin(GLenum mode);
//给出数据点
glEnd();
一,首先来了解一下OpenGl图元的模式标识
点 GL_POINTS
线 GL_LINES
条带线 GL_LINE_STRIP
循环线 GL_LINE_LOOP
独立三角形 GL_TRIANGLES
三角形条带 GL_TRIANGLE_STRIP
三角形扇面 GL_TRIANGLE_FAN
二、点
点,对应到屏幕上是一个像素,它通过坐标确定位置。通过调用glBegin()函数传递GL_POINTS参数,即可绘制点。
代码:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
def drawFunc():
glClearColor(0.0, 0.0, 0.0,0.0)
glClear(GL_COLOR_BUFFER_BIT)
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0)
# 设置点大小
glPointSize(5)
# 只绘制端点
glBegin(GL_POINTS)
# 第一个点
glColor3f(1.0, 0.0, 0.0)
glVertex3f(0.25, 0.25, 0)
# 第二个点
glColor3f(0.0, 1.0, 0.0)
glVertex3f(0.75, 0.25, 0)
# 第三个点
glColor3f(0.0, 0.0, 1.0)
glVertex3f(0.75, 0.75, 0)
# 第四个点
glColor3f(1.0, 1.0, 1.0)
glVertex3f(0.25, 0.75, 0)
glEnd()
glFlush()
if __name__ == '__main__':
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)
glutCreateWindow(b"First")
glutDisplayFunc(drawFunc)
glutMainLoop()
效果如下
main()函数这里就不多说了,不清楚的参看 https://blog.csdn.net/bigboysunshine/article/details/80308284这里讲解drawFunc()函数:
1,首先,我们要清除帧缓存的数据再进行渲染。清除的工作由glClear(GL_COLOR_BUFFER_BIT)完成。
void glClear(GLbitfield mask);
清除指定的缓存数据并重置为当前的清除值。mask是一个可以通过逻辑“或”操作来指定多个数值的参数,主要有三个:
颜色缓存:GL_COLOR_BUFFER_BIT
深度缓存:GL_DEPTH_BUFFER_BIT
模板缓存:GL_STENCIL_BUFFER_BIT
2,如果要改变清除颜色的数值,可以使用glClearColor()
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
举例说明清除颜色的用法,比如我们希望将当前视口的背景颜色设置为白色,那么需要调用glClearColor(1, 1, 1, 1)。但是我们应该在什么时候调用这个函数呢?当然,我们可以直接在drawFunc() 函数中调用glClear() 之前调用它。但是这样的话,除了第一次进入循环之时,其他所有对glClearColor() 的调用都是多余的—因为OpenGL 在每次渲染时都会重复设置清除颜色的状态值为白色。另一个效率更高的方法是在init() 函数中设置清除颜色。事实上,这样我们就可以避免冗余的状态切换;所有在程序运行时不会发生变化的数值都应该在init() 中设置。当然,冗余的函数调用本身并没有危害,但是它会造成程序运行速度稍微变慢。
3,画点
画点操作从 glBegin(GL_POINTS)开始,到glEnd()结束
glColor3f(1,0,0)用来设置颜色。
glVertex3f(0,0,0)用来画点。
glPointSize(5)来设置圆点半径大小
4,glFlush()
最后在drawFunc()函数中调用glFunc(),即强制所有进行中的OpenGL 命令立即完成并传输到OpenGL 服务端处理。
三、线
线的绘制和点差不多
def drawLine():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0, 1.0, 0.0)
glLineWidth(2)
glBegin(GL_LINES)
glVertex3f(-0.5, -0.5, 0.0)
glVertex3f(-0.5, 0.5, 0.0)
glVertex3f(0.5, -0.5, 0.0)
glVertex3f(0.5, 0.5, 0.0)
glEnd()
glFlush()
效果:
通过glLineWidth(2)设置线段的宽度,glVertex3f(-0.5, -0.5, 0.0)设置线段的端点
由于一条线段有两个端点,所以glVertex3f()成对出现,如果改动上面的代码上如下
def drawLine():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0, 1.0, 0.0)
glLineWidth(2)
glBegin(GL_LINES)
glVertex3f(-0.5, -0.5, 0.0)
glVertex3f(-0.5, 0.5, 0.0)
glVertex3f(0.5, -0.5, 0.0)
glVertex3f(0.5, 0.5, 0.0)
glVertex3f(0.0, 0.0, 0.0)
glEnd()
glFlush()
则显示结果和上面的是一样的。
前面我们已经提到线主要有三种,上面的是一种还有条带线(GL_LINE_STRIP)和循环线(GL_LINE_LOOP)
上面的代码,我们把GL_LINES改为GL_LINE_STRIP
结果为:
把GL_LINES改为GL_LINE_LOOP结果为: