基本名词
图元
图形渲染管道的输入量是几何图元(比如,三角形,点,直线或者四边形),它们都可以通过一个或者若干个几何顶点来描述。OpenGL支持三种类型的几何图元:点,线段和封闭的多边形。它们都是通过顶点来描述。每个顶点都有几个特定的属性,比如位置,颜色,法线和纹理。OpenGL提供了10种图元(如下图)。球体,三维盒子,角锥体都不是图元,它们都是可以通过图元组合生成。
顶点
顶点可以说是用来描述图元的基本单位,三维中,三角形图元需要三个点空间点确认,而这个空间点就是顶点。四边形由四个顶点组成,点图元就使用一个顶点就行。 如上图正方形,由6个四边形图元组成,每个四边形图元又由四个顶点描述。
其他
- Rendering(渲染): 把数学和图形数据转换成3D空间图像的操作或指图像。
- Transformaton(转换): 把2D下的点连接,使得观察者产生3D的错觉。
- Projection(投影): 把3D坐标转换为2D屏幕坐标。
- Rasterization(光栅化): 绘制或填充每个定点之间的像素形成线段。在大多数渲染的情况下,我们并不使用线段,而是用实心三角形进行渲染。将每个图元转换为一系列的碎片。我们可以认为一个碎片就是三维空间中的一个像素,同样具有位置,颜色,法线和纹理属性。
- Shading(着色): 改变顶点间的表面的颜色值。
- Shader(着色器): 在图形硬件上执行的单独程序,用来处理顶点和执行光栅化。
- Texture Mapping(纹理贴图): 把图片贴到三角形或多边形上,使3D效果更加显著。
- Blending(混合): 把不同颜色混在一起。可以在一个图形中绘制另一个图形,使得效果真实。
- 顶点处理:对模型的各个顶点进行计算(着色)以及坐标变换
3D图像渲染管道
包括以下几个主要步骤:
- 顶点处理: 对模型的各个顶点进行计算(着色)以及坐标变换
- 光栅化: 将每个图元转换为一系列的碎片。我们可以认为一个碎片就是三维空间中的一个像素,同样具有位置,颜色,法线和纹理属性。
- 碎片处理: 光栅化之后,我们得到一些列的碎片,这个阶段则是对碎片进行处理(着色)
- 合并输出: 将所有的碎片(3D概念中)转化成二维的颜色像素,最后输出显示到屏幕上
上述步骤中,顶点处理和碎片处理是可编程的。你可以编写顶点着色程序和碎片着色程序,来实现顶点和碎片的自定义运算处理。
一般着色程序使用类似C语言的高级语言编写,比如GLSL(OpenGL Shading Language),HLSL(High-Level Shading Language for Miscrosoft Direct3D),或者Cg(C for Graphics by NVIDIA)。
此外,光栅化和合并输出两个步骤是不可编程的,但是可以配置GPU中处理这两个步骤的一些参数。
opengl接口
可参考文章:https://www.cnblogs.com/linkzijun/p/6196172.html
编程
QT中为我们把OpenGL进行了封装,使用较原生OpenGL简单,除了对OpenGL原生接口的支持,QGLWidget还为OpenGL在多个操作系统平台上的应用进行了浅层封装。
1、在Qt中为OpenGL提供支持的类主要有以下几个:
- OpenGLWindow
- QOpenGLWidget
- QOpenGLFunctions
- QOpenGLBuffer
- QGLWidget:用于渲染OpenGL场景的易于使用的Qt部件。
- QGLColormap:用于在QGLWidget中安装用户自定义的颜色图。
- QGLContext:封装了用于OpenGL渲染的场景。
- QGLFormat:指定OpenGL演染场景的显示模式。
- QGLFrameBufferObject 和 QGLPixelBuffer分别提供了对GL帧缓冲对象和GL像素缓冲的支持。
- QGLPaintEngine:QPaintEngine的派生类,为QPainter提供了OpenGL绘图引擎。
2、项目文件中添加opengl模块。
QT += opengl
3、有时候编译很多报错,动态库方向的,那就是没有添加对应的动态库,项目文件中添加对应库。
win32:LIBS += -lOpengl32 \
-lglu32 \
-lglut
4、在QT中写OpenGL需要继承自QOpenGLWidget,QOpenGLWidget提供了三个虚函数用以重载来实现OpenGL的绘制。
-
initializeGL() 注册函数: 设置GL的渲染绘制属性、定义显示列表、载入固定纹理等初始化工作。在initializeGL()在调用paintGL()之前只被调用一次,之后不再调用。 -
paintGL() 绘制函数: 在此使用OpenGL中的接口进行场景绘制,QGLWidget的paintEvent( QPaintEvent* )将会自动调用 paintGL()进行部件的显示绘制。也可在需要重绘时通过updateGL()时调用paintGL(),和paintEvent使用基本相似。 -
resizeGL() 该函数: 用于处理当部件大小发生改变时,对OpenGL绘图管线各矩阵需要进行的操作。该函数paintGL()第一次调用之前,initializeGL()调用之后被第一次被调用, 之后每当QGLWidget的不见大小发生改变时,都将调用该函数来对视图、投影矩阵等进行相应的设置。
5、绘制一个彩色正方形的opengl代码。
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glColor3f(1.0f, 0.5f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
|