本文主要是介绍计算机图形学 -- 变换之旋转一 [金字塔旋转] [各种详解哦],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
OpenGL之变换
这一次用到的有双缓冲、双缓存技术,空闲调用函数,激活函数(启用功能),平移和旋转等
Code:
#include<GL/glut.h>
#include<stdlib.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
GLfloat rtri; //金字塔旋转角度,==这个东西叫金字塔貌似不怎么样。。。只是因为底面没有填充。。void init()
{glClearColor(0.0f,0.0f,0.0f,0.0f);glShadeModel(GL_SMOOTH); //GL_FLAT和GL_SMOOTH在这里的区别很明显哟glEnable(GL_DEPTH_TEST);/*激活深度测试,也就是,如果通过比较后深度值发生变化了,会进行更新深度缓冲区的操作。启动它,OpenGL就可以跟踪Z轴上的像素,这样,它只会在那个像素前方没有东西时,才会绘画这个像素。通俗的说,就是根据坐标的远近自动隐藏被遮住的图形(材料)*/}void mydisplay()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f,0.2f,-4.0f); //平移,三个方向的偏移量,缩小一下glRotatef(rtri,0.0f,1.0f,0.0f); //旋转,沿各个不同方向glBegin(GL_TRIANGLES);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(1.0f,-1.0f,1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(1.0f,0.0f,1.0f);glVertex3f(1.0f,-1.0f,1.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);glEnd();rtri += 0.1f; //这家伙可以控制旋转角度,也就是速度,单位时间内转过的角度,当然越大越快了glutSwapBuffers();
}void reshape(int width,int height)
{ glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();
} int main(int argc,char * argv[])
{glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowPosition(300,100);glutInitWindowSize(650,500);glutCreateWindow("change");init();glutDisplayFunc(mydisplay);glutReshapeFunc(reshape);glutIdleFunc(mydisplay); //设置空闲时调用的函数,idle就是空闲的、闲置的意思glutMainLoop();return 0;
}
下面来说说以前没见过的函数的用法~
(各处总结来的,讲的都特别好~)
双缓冲技术
在计算机上的动画与实际的动画有些不同:实际的动画都是先画好了,播放的时候直接拿出来显示就行。
计算机动画则是画一张,就拿出来一张,再画下一张,再拿出来。
如果所需要绘制的图形很简单,那么这样也没什么问题。
但一旦图形比较复杂,绘制需要的时间较长,问题就会变得突出。
让我们把计算机想象成一个画图比较快的人,
假如他直接在屏幕上画图,而图形比较复杂,则有可能在他只画了某幅图的一半的时候就被观众看到。
而后面虽然他把画补全了,但观众的眼睛却又没有反应过来,还停留在原来那个残缺的画面上。
也就是说,有时候观众看到完整的图象,有时却又只看到残缺的图象,这样就造成了屏幕的闪烁。
如何解决这一问题呢?
我们设想有两块画板,画图的人在旁边画,画好以后把他手里的画板与挂在屏幕上的画板相交换。
这样以来,观众就不会看到残缺的画了。这一技术被应用到计算机图形中,称为双缓冲技术。
即:在存储器(很有可能是显存)中开辟两块区域,一块作为发送到显示器的数据,一块作为绘画的区域,
在适当的时候交换它们。由于交换两块内存区域实际上只需要交换两个指针,
这一方法效率非常高,所以被广泛的采用。
注意:虽然绝大多数平台都支持双缓冲技术,但这一技术并不是 OpenGL 标准中的内容。
OpenGL 为了保证更好的可移植性,允许在实现时不使用双缓冲技术。当然,我们常用
的 PC 都是支持双缓冲技术的。
要启动双缓冲功能,最简单的办法就是使用 GLUT 工具包。我们以前在 main 函数里面
写:glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
其中 GLUT_SINGLE 表示单缓冲,如果改成 GLUT_DOUBLE就是双缓冲了。
当然还有需要更改的地方——每次绘制完成时,我们需要交换两个缓冲区,把绘制好的
信息用于屏幕显示(否则无论怎么绘制,还是什么都看不到)。如果使用 GLUT 工具包,
也可以很轻松的完成这一工作,只要在绘制完成时简单的调用 glutSwapBuffers函数就可
以了。-- 交换双缓存函数
总之一句话,使用双缓存,以避免把计算机作图的过程都表现出来,或者为了平滑地实现动画。
GLUT_DEPTH 和 GL_DEPTH_TEST
在glutInitDisplayMode()参数说明GLUT_DEPTH,表明窗口使用深度缓存
在glEnable里激活GL_DEPTH_TEST,说明启用深度测试,也就是,如果通过比较后深度值发生变化了,会进行更新深度缓冲区的操作。启动它,OpenGL就可以跟踪Z轴上的像素,这样,它只会在那个像素前方没有东西时,才会绘画这个像素。通俗的说,就是根据坐标的远近自动隐藏被遮住的图形(材料)
在glutInitDisplayMode()里还有很多别的参数如下:
值 | 对应宏定义 | 意义 |
GLUT_RGB | 0x0000 | 指定 RGB 颜色模式的窗口 |
GLUT_RGBA | 0x0000 | 指定 RGBA 颜色模式的窗口 |
GLUT_INDEX | 0x0001 | 指定颜色索引模式的窗口 |
GLUT_SINGLE | 0x0000 | 指定单缓存窗口 |
GLUT_DOUBLE | 0x0002 | 指定双缓存窗口 |
GLUT_ACCUM | 0x0004 | 窗口使用累加缓存 |
GLUT_ALPHA | 0x0008 | 窗口的颜色分量包含 alpha 值 |
GLUT_DEPTH |
这篇关于计算机图形学 -- 变换之旋转一 [金字塔旋转] [各种详解哦]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!