1.前言
绘制一个旋转的方块,主要为了说明glutSwapBuffers()函数的用法。
同时也为了学习如何使用GLUT控制输入设备,并打开或关闭空闲处理函数。
2.OpenGL编程及程序剖析
/****************************************************************
*Rendering a rotating square,display how to use glutSwapBuffers()
*Author:Ziheng H. Shen @ Graduate School of Tsinghua Univ.
****************************************************************/
#include <vgl.h>
static GLfloat spin = 0.0;
void init(void)
{
glClearColor(0.0,0.0,0.0,0.0); //清空当前所偶有颜色
glShadeModel(GL_FLAT); //设置着色模式
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //清除viewport的缓冲区
glPushMatrix();//将当前矩阵保存入堆栈顶(保存当前矩阵)
glRotatef(spin,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
glRectf(-25.0,-25.0,25.0,25.0);
glPopMatrix();
glutSwapBuffers();//实现双缓冲技术,交换两个缓冲区指针。
}
void spinDisplay(void)
{
spin = spin + 2.0;
if(spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay(); // 标记当前窗口需要重新绘制
}
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION); //指定哪一个矩阵是当前矩阵
glLoadIdentity(); //重置当前指定的矩阵为单位矩阵
glOrtho(-50,50,-50,50,-1,1); //将当前的可视空间设置为正投影空间
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/**************************************************/
void mouse(int button, int state, int x,int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
glutIdleFunc(spinDisplay);//全局的回调函数,响应鼠标左键操作,更新图像旋转之后结果
break;
case GLUT_RIGHT_BUTTON:
if(state == GLUT_DOWN)
glutIdleFunc(NULL); //全局回调函数,响应鼠标中键操作
break;
default:
break;
}
}
/*
*Request double buffer display mode.
*Register mouse input callback functions.
*/
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(250,250);
glutInitWindowPosition(0,0);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape); //窗口改变的时候调用的函数
glutMouseFunc(mouse); //响应鼠标事件
glutMainLoop();
return 0;
}输出结果:
3.函数解析
3.1 glClearColor
通过glClear使用红,绿,蓝以及AFA值来清除颜色缓冲区的,并且都被归一化在(0,1)之间的值,其实就是清空当前的所有颜色。
3.2 glShadeModel
void glShadeModel ( GLenum mode)
是OpenGL1.0提供的接口。作用是设置着色模式。参数mode可以是GL_SMOOTH(默认值)或GL_FLAT。采用恒定着色时(即GL_FLAT),使用图元中某个顶点的颜色来渲染整个图元。在使用光滑着色时(即GL_SMOOTH),独立的处理图元中各个顶点的颜色。对于线段图元,线段上各点的颜色将根据两个顶点的颜色通过差值得到。对于多边形图元,多边形内部区域的颜色将根据所有顶点的颜色差值得到。
3.3 glClear
void glClear(GLbitfield mask); 参数说明: GLbitfield:可以使用 | 运算符组合不同的缓冲标志位,表明需要清除的缓冲,例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位 GL_COLOR_BUFFER_BIT: 当前可写的颜色缓冲 GL_DEPTH_BUFFER_BIT: 深度缓冲 GL_ACCUM_BUFFER_BIT: 累积缓冲 GL_STENCIL_BUFFER_BIT: 模板缓冲
3.4 glPushMatrix && glPopMatrix
glPushMatrix(),glPopMatrix()这两个函数是搭配使用的,中间放置几何变换。glPushMatrix()的作用是把矩阵压入栈中保存起来,留着以后再用,就好象把子弹压入枪膛一样。但这个压子弹不是简单滴丫,它是把和弹夹的最顶的那颗子弹一模一样的子弹压入弹夹。假如说弹夹的子弹从下往上装的子弹各不相同,依次为A1型子弹,B2型子弹,C3型子弹glPushMatrix()的作用就是现时打造一颗C3型子弹并把它压入弹夹,于是弹夹最顶端的两颗子弹是一样的,都是C3型的子弹,随后所作的平移变化旋转变换等都是在最上面那颗C3子弹上所作的,并不影响下面的那颗C3子弹,直到glPopMatrix()把最上面的那颗C3子弹发射出去,让下面的那颗C3子弹成为弹夹最顶上的那颗。
3.5 glutSwapBuffers
glutSwapBuffers函数是OpenGL中GLUT工具包中用于实现双缓冲技术的一个重要函数。该函数的功能是交换两个缓冲区指针。
3.6 glutPostRedisplay
glutPostRedisplay 标记当前窗口需要重新绘制。通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。多次调用glutPostRedisplay,在下一个显示回调只产生单一的重新显示回调。
3.7 glutIdleFunc
glutIdleFunc设置全局的回调函数,当没有窗口事件到达时,GLUT程序功能可以执行后台处理任务或连续动画。如果启用,这个idle function会被不断调用,直到有窗口事件发生。回调函数没有参数。
3.8 glutReshapeFunc与glutDisplayFunc
glutReshapeFunc是窗口改变的时候调用的函数,在这个里面可以根据缩放后的窗口重新设置camera的内部参数,比如横纵比啥的;
glutDisplayFunc是显示的时候调用,可见改变窗口后调用glutReshapeFunc后还是会调用glutDisplayFunc进行显示的。 不可以不用glutDisplayFunc,比如你想实现动画效果,也就是说窗口大小不变而里面的内容发生变化,这时候通过设置glutIdelFunc,在里面最后调用glutPostdisplay,来通知glutdisplayFuc重画,实现动画。 简单的说,glutReshapeFunc与glutIdelFunc这些函数都不去直接处理显示,而是设置好相应的参数,让glutdisplayfunc来执行绘制。
4.参看资料
[1]施莱尔, GrahamSellers, JohnKessenich,等. OpenGL编程指南[M]. 机械工业出版社, 2014.
转载请注明原文地址: https://ju.6miu.com/read-39535.html