您的位置:首页 > 运维架构

OpenGL(三)图形变换之几何变换

2016-07-08 11:18 274 查看
通常,为了把一组图形融合为一个场景,必须把他们按照批次之间的关系和与观察这的关系排列起来,这就要用到变换。变换使得能够把3D坐标投影到2D场景成为可能,变换包括旋转对象,移动对象,甚至拉伸、压缩和玩去他们,

变换修改的是坐标系。

通过演示一个三角形进行的平移、旋转和缩放等变换,学习相关知识点。

<span style="font-size:18px;">#include<windows.h>
#include<gl/gl.h>
#include<gl/glut.h>

//默认视角:在原点往z轴负方向看

void SetupRC(void)
{
//设置窗口背景颜色为白色
glClearColor(1.0f, 1.0f, 1.0f,1.0f);
}

//绘制三角形
void DrawTriangle(void)
{
glBegin(GL_TRIANGLES);
glVertex2f(0.0f,0.0f);
glVertex2f(40.0f,0.0f);
glVertex2f(20.0f,40.0f);
glEnd();
}

void ChangeSize(int w,int h)
{
if (h == 0)
h = 1;
glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

//设置裁剪空间
if (w <= h)
glOrtho(-100.0f, 100.0f, -100.0f*h/w, 100.0f*h/w, -100.0f, 100.0f);
else
glOrtho(-100.0f*w/h, 100.0f*w/h, -100.0f, 100.0f, -100.0f, 100.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);

//设置当前操作矩阵为模型视图矩阵,并复位为单位矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//绘制黑色的坐标轴
glColor3f(0.0f,0.0f,0.0f);
glBegin(GL_LINES);
glVertex2f(-100.0f,0.0f);
glVertex2f(100.0f,0.0f);
glVertex2f(0.0f, -100.0f);
glVertex2f(0.0f, 100.0f);
glEnd();

//绘制出第一个红色的三角形
glColor3f(1.0f,0.0f,0.0f);
DrawTriangle();

//绘制出逆时针旋转200度角的绿色三角形

glRotatef(200.0f,0.0f,0.0f,1.0f);
glColor3f(0.0f,1.0f,0.0f);
DrawTriangle();

//这一步非常关键, 因为OpenGL效果累加,必须回到原点
glLoadIdentity();

//绘制出沿x轴负反向平移60单位的黄色三角形
glTranslatef(-60.0f,0.0f,0.0f);
glColor3f(1.0f,1.0f,0.0f);
DrawTriangle();

//glLoadIdentity();
glTranslatef(120.0f,0.0f,0.0f); //向x轴正方向平移120
glScalef(1.0f,2.0f,100.0f);
glColor3f(0.0f,0.0f,1.0f);
DrawTriangle();

//交换两个缓冲区的指针
//功能:防止复杂绘制时屏幕闪烁
glutSwapBuffers();

}

int main(int argc,char *argv[])
{
//glutInit is used to initialize the GLUT library
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutCreateWindow("变换示例");

glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);

SetupRC();
glutMainLoop();
return 0;
}
</span>

运行结果:



OpenGL中常用的变换包括视图变换、模型变换、模型视图变换、投影变换和视见区变换。(了解)



在计算机图形学中,物体进行的几何变换可以分解成多个基本几何变换,而三维几何变换矩阵是多个基本几何变换矩阵相乘的结果。

而OpenGL提供了一些函数用于把任意矩阵设置成当前操作的矩阵(模型视图矩阵或投影矩阵):

OpenGL常用的高级矩阵函数(学习重点):

1、平移函数

void glTranslated(GLdouble x,GLdouble y,GLdouble z);

void glTranslatef( GLfloat x,GLfloat  y,GLfloat  z);

三个参数就是目标分别沿三个轴的正向平移的偏移量

2、旋转变换

void glRotated(GLdouble angle,GLdouble x,GLdouble y,GLdouble z);

void glRotatef( GLfloat angle, GLfloat x,GLfloat  y,GLfloat  z);

函数中第一个参数表示目标从目标改点到指定点(x,y,z)的方向适量逆时针旋转的角度
后三个参数则是指定旋转方向矢量的坐标.

3、缩放变换

void glScaled(GLdouble x,GLdouble y,GLdouble z);

void glScalef( GLfloat x,GLfloat  y,GLfloat  z);

三个参数值就是目标分别沿三个轴缩放的比例因子
4、解决效果累计



最后再来理解一下glutSwapBuffers函数;

来自百度百科的解释:

glutSwapBuffers函数是OpenGLGLUT工具包中用于实现双缓冲技术的一个重要函数。该函数的功能是交换两个缓冲区指针

通常, 我们所看到的窗体、文字、图像,从根本上来说都是“画”出来的。比如,制作一个简单的五子棋, 我们可能先要绘制棋盘,然后绘制棋子,我们可能还要绘制一些提示信息。虽然这些绘制操作有一定的先后顺序,通常情况下,操作系统的这些绘制速度非常的快,使人眼误认为这些绘制操作是同时完成的。

但当我们进行复杂的绘图操作时,画面便可能有明显的闪烁。解决这个问题的关键在于使绘制的东西同时出现在屏幕上。所谓双缓冲技术, 是指使用两个缓冲区: 前台缓冲和后台缓冲。前台缓冲即我们看到的屏幕,后台缓冲则在内存当中,对我们来说是不可见的。每次的所有绘图操作都在后台缓冲中进行, 当绘制完成时, 把绘制的最终结果复制到屏幕上, 这样, 我们看到所有GDI元素同时出现在屏幕上,从而解决了频繁刷新导致的画面闪烁问题。

在OpenGL中实现双缓冲技术的一种简单方法:

1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);。这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲。

2. 调用glutDisplayFunc(display)注册回调函数时,
在回调函数中所有绘制操作完成后调用glutSwapBuffers()交换两个缓冲区指针。

3. 调用glutIdleFunc注册一个空闲时绘制操作函数, 注册的这个函数再调用display函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: