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

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

变换修改的是坐标系。

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

#include
#include
#include


//默认视角:在原点往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;
}


运行结果:

OpenGL(三)图形变换之几何变换_第1张图片


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

OpenGL(三)图形变换之几何变换_第2张图片

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

而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、解决效果累计

OpenGL(三)图形变换之几何变换_第3张图片


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

来自百度百科的解释:

glutSwapBuffers函数是OpenGL中GLUT工具包中用于实现双缓冲技术的一个重要函数。该函数的功能是交换两个缓冲区指针。
通常, 我们所看到的窗体、文字、图像,从根本上来说都是“画”出来的。比如,制作一个简单的五子棋, 我们可能先要绘制棋盘,然后绘制棋子,我们可能还要绘制一些提示信息。虽然这些绘制操作有一定的先后顺序,通常情况下,操作系统的这些绘制速度非常的快,使人眼误认为这些绘制操作是同时完成的。
但当我们进行复杂的绘图操作时,画面便可能有明显的闪烁。解决这个问题的关键在于使绘制的东西同时出现在屏幕上。所谓双缓冲技术, 是指使用两个缓冲区: 前台缓冲和后台缓冲。前台缓冲即我们看到的屏幕,后台缓冲则在内存当中,对我们来说是不可见的。每次的所有绘图操作都在后台缓冲中进行, 当绘制完成时, 把绘制的最终结果复制到屏幕上, 这样, 我们看到所有GDI元素同时出现在屏幕上,从而解决了频繁刷新导致的画面闪烁问题。
在OpenGL中实现双缓冲技术的一种简单方法:
1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);。这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲。
2. 调用glutDisplayFunc(display)注册回调函数时, 在回调函数中所有绘制操作完成后调用glutSwapBuffers()交换两个缓冲区指针。
3. 调用glutIdleFunc注册一个空闲时绘制操作函数, 注册的这个函数再调用display函数。

你可能感兴趣的:(OpenGL)