OpenGL编程指南4:双缓冲实现运行

    xiaoxiao2021-03-25  74

    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

    最新回复(0)