1.freeglut的配置
因为我使用的编译环境是Visual Studio2015(VS2022可以直接通过Nuget进行下载,速度很快),所以这里我下载的是freelgut3.0.0的MVSC版本,即编译好的,这样可以省去Cmake的步骤(下载链接),下载好之后按照下方放置freeglut文件(记住区分32位,64位的区别,不然非常容易报错)由于大部分代码均为64位,所以我仅仅配置了64位的
1)将上面所取到的freeglut.lib放入到:D:\Download\VS2015\VC\lib\amd64,,这里注意按照自己的VS安装位置进行选择。
2)freeglut.dll有32位和64位两个版本,分别放入,C:\Windows\SysWOW64和C:\Windows\System32
3)将D:\freeglut-3.0.0\include\GL下*.h头文件放入D:\Download\VS2015\VC\include\GL,,没有GL文件夹可以自己创建一个
经过验证,程序可以正常执行:
2.freeglut相关函数
使用freeglut绘制图像,在main函数中需要执行这七个最基本的步骤:
1 初始化
glutInit(&argc, argv);
234 设定窗口位置、窗口大小、显示模式
glutInitWindowPosition(100, 100);
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
5 创建窗口并设定窗口名
glutCreateWindow("窗口名");
6 调用外部函数进行绘制
glutDisplayFunc(display函数名);
7 进入主循环
glutMainLoop();
以下为各函数介绍:
1)glutInit(&argc, argv):这个函数用来初始化 GLUT 库.这个函数从 main 函数获取其两个参数.对应main 函数的形式应是:int main(int argc,char* argv[]);
2)glutInitWindowPositon(int x,int y):用来确定窗口位置
X: 距离屏幕左边的像素数。-1是默认值,意思就是由窗口管理程序决定窗口出现在哪里。如果不使用默认值,那你就自己设置一个值。
Y:距离屏幕上边的像素数。和X一样。
3)glutInitWindowSize(int width,int height):用来设置窗口的大小
Width:窗口的宽度。
Height:窗口的高度。
4)glutInitDisplayMode():定义显示方式
用法使用:glutInitDisplayMode(unsighed int mode)
Mode参数是一个GLUT库里预定义的可能的布尔组合。你使用mode去指定颜色模式,数量和缓冲区类型。
指定颜色模式的预定义常量有:
1:GLUT_RGBA或者GLUT_RGB。指定一个RGBA窗口,这是一个默认的颜色模式。
2:GLUT_INDEX。指定颜色索引模式。
这个显示模式还允许你选择单缓冲区或双缓冲区窗口。
1:GLUT_SINGLE.单缓冲区窗口。
2:GLUT_BUFFER.双缓冲区窗口,这是产生流畅动画必须选的。
还可以指定更多,如果你想指定一组特殊的缓冲的话,用下面的变量:
1:GLUT_ACCUM.累积缓冲区。
2:GLUT_STENCIL.模板缓冲区。
3:GLUT_DEPTH.深度缓冲区。
我实现的是RGB显示并且双缓冲窗口显示,故代码为:glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
5)glutCreateWindow():设置Glut窗口名称
glutCreateWindow("xxxxxxxxx")
6)glutDisplayFunc(display函数名):display为绘图函数,其为自动调用,也就是程序运行时,自动调用display函数重新绘制窗口
7)glutMainLoop():进入 GLUT 事件处理循环。此例程在 GLUT 程序中最多应调用一次。一旦调用,此例程将永远不会返回。它将根据需要调用已注册的任何回调。
下面开始进入绘制图形的步骤:
1)display函数
a.glViewport():
默认情况下,视口被设置为占据打开窗口的整个像素矩形;
glViewport(GLint x,GLint y,GLsizei width,GLsizei height)为其函数原型。
X,Y即以像素为单位,指定了 视口的左下角(在第一象限内,以(0,0)为原点的)位置。 width,height————表示这个视口矩形的宽度和高度,根据窗口的实时变化重绘窗口。
b.glClearColor():
函数原型为:void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);
glClearColor:red、green、blue、alpha分别是红、绿、蓝、不透明度,值域均为[0,1]。即设置颜色,为后面的glClear做准备,默认值为(0,0,0,0)。切记:此函数仅仅设定颜色,并不执行清除工作
c. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
用glClearClolr设定的颜色值清除缓存区
d.glLoadIdentity():用于将当前矩阵重置为单位矩阵,也就是执行一个新的变换的时候,需要将当前矩阵重置为单位矩阵
e.gluLookAt():
函数原型:
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
该 函数定义一个视图 矩阵,并与当前矩阵相乘。
第一组eyex, eyey,eyez 相机在世界坐标的位置
第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置
第三组upx,upy,upz 相机向上的方向在世界坐标中的方向
你把相机想象成为你自己的脑袋:
第一组数据就是脑袋的位置
第二组数据就是眼睛看的物体的位置
第三组就是头顶朝向的方向(因为你可以歪着头看同一个物体)。
f.glPushMatrix():
栈操作函数,用于将当前矩阵压入栈中。
调用该函数之后,当前矩阵会被复制一份并且压入栈中,在之后的操作中使用栈顶的矩阵进行变换而不会影响之前的变换。下面为调用举例,绘制两个不同位置的圆柱体。
glPushMatrix()
glTranslatef(1.0, 0.0, 0.0)
glRotatef(30, 0.0, 1.0, 0.0)
drawCylinder()
glPopMatrix()
glPushMatrix()
glTranslatef(-1.0, 0.0, 0.0)
glRotatef(-30, 0.0, 1.0, 0.0)
drawCylinder()
glPopMatrix()
g.glTranslatef():
函数原型:
void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
函数功能:
沿X轴正方向平移x个单位(x是有符号数)
沿Y轴正方向平移y个单位(y是有符号数)
沿Z轴正方向平移z个单位(z是有符号数)
h.glRotatef():
函数原型:
void glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
函数功能:以点(0,0,0)到点(x,y,z)为轴,旋转angle角度;
i. glScalef():
为opengl中的模型缩放函数,就是把当前的矩阵与另外一个表示沿着各个轴对物体进行拉伸、压缩、反射的矩阵相乘
函数原型:void glScalef(GLfloat x,GLfloat y,GLfloat z);
例如:glScalef(2.0f,3.0f,4.0f);将模型按x,y,z方向分别拉伸了2,3,4倍,参数也可取负数,也可以理解为先关于某轴翻转180°,再缩放。
作完图之后的处理步骤:
a.glFlush():作用是强制把指令送到驱动里面进行处理
glFlush()就是强制刷新,OpenGL是使用一条渲染管线线性处理命令的,一般情况下,我们提交给OpenGL的指令并不是马上送到驱动程序里执行的,而是放到一个缓冲区里面,等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的。
b.glutSwapBuffers():用于实现双缓冲技术的一个重要函数
作用是交换前后缓存,会在后台缓冲区绘制图形,调用该函数时,会将后台缓冲区中的图形拷贝到前台缓冲区中,并且显示在屏幕上面。