第一个动作图,让球体转起来

本来以为这个事情很容易做到,突然发现网上的各种东西都太杂乱。。已经一个小时过去了我还没有找到最简单的方法,突然觉得自己写的东西哪天某个初学者看起来很清楚的话也能算我大功一件了。

这个工程量果然比之前的大很多。。终于解决了之前出bug的一个问题,总感觉球体不是在均匀旋转的,后来我利用两个函数修改了一下我是视角,问题得到解决

gluPerspective —设置一个投射投影矩阵


void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

fovy
Specifies the field of view angle, in degrees, in the y direction.
在y方向上的视角

aspect
Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
定义觉得在x方向上的纵横比(屏幕高宽比),其值为x(宽度)比y(高度)

zNear
Specifies the distance from the viewer to the near clipping plane (always positive).

zFar
Specifies the distance from the viewer to the far clipping plane (always positive).
并且在这个函数之前要先载入 glLoadIdentity.

具体参照 https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
另外http://blog.csdn.net/hbuxiaoshe/article/details/5062794文章里写的也特别的好


之后提到glMatrixMode — specify which matrix is the current matrix
确定哪一个函数是当前函数
void glMatrixMode(GLenum  mode );
有三种值可以接受 GL_MODELVIEW, GL_PROJECTION, and GL_TEXTURE.初始值为 GL_MODELVIEW. 如果支持ARB_imaging 扩展 GL_COLOR 也可以.

然后就是设计视角的函数
gluLookAt — 定义了一个视角函数
void gluLookAt(GLdouble  eyeX, GLdouble  eyeY, GLdouble  eyeZ, GLdouble  centerX, GLdouble  centerY, GLdouble  centerZ, GLdouble  upX, GLdouble  upY, GLdouble  upZ );
详细情况见链接
https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml


最后,用的就是制作动画的一点点东西了
首先在主函数中在实现动画这一块,OpenGL给我们提供了双缓冲。当A缓冲区显示时,B缓冲区正在绘制图形。当B绘制完毕时,就交换缓冲区,此时B显示,而A就进行绘画。从而实现平滑地显示每一帧地显示,观众就永远看不到没有完成的画面。计算机的在交换缓冲区的时候,速度很快,所以一般用户是觉察不到的。

为了能让我们的程序能够使用双缓冲,我们需要改变main函数中glutInitDisplayMode()函数的参数,把GLUT_SINGLE改为GLUT_DOUBLE,表示我们现在要使用双缓冲(double)了,以前是单缓冲(single)。

glutInitDisplayMode(GLUT_RGB| GLUT_DOUBLE);
我们使用的GLUT辅助库,帮我们解决了这个问题,我们只用调用glutSwapBuffers();函数就OK了。

所以我们再把Draw函数中的glFlush()函数换成glutSwapBuffers()。就可以了。

这个时候编译运行,画面并没有动起来,因为Draw函数只调用了一次,我们希望程序能不停地显示。怎么做呢?

我们在main函数中使用glutIdleFunc(&myIdle);函数,可以设置一个回调函数Update。设置了以后,Update便会在循环中不断地被调用,直到有窗口消息产生。这里暂时不管窗口消息是啥,我们就知道Update会不断被调用就是了。改为DOUBLE缓存

啰里啰嗦一大堆,来来来,上代码
#include<GL/GLUT.H>  
#include <windows.h>      
#include <math.h>      
#include <gl/GL.h>      

float pi = 3.1415927f;
float r = 0.8f;
GLfloat ra = 45;//rotate angle

void myDisplay(void){

	glClear(GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(100.0f, 1.0f, 1.0f, 10.0f);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.0, 2.0, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);



	glRotatef(ra, 0, 0, 1);
	
	for (int j = 0; j < 20; ++j)
	{
		glBegin(GL_LINE_STRIP);
		for (int i = 0; i <= 20; i++)
		{
			glVertex3f(r*sin(pi*j / 20)*cos(2 * pi*i / 20), r*sin(pi*j / 20)*sin(2 * pi*i / 20), r*cos(pi*j / 20));
		}
		glEnd();

		glBegin(GL_LINE_STRIP);
		for (int i = 0; i <= 20; i++)
		{
			glVertex3f(r*sin(pi*i / 20)*cos(2 * pi*j / 20), r*sin(pi*i / 20)*sin(2 * pi*j / 20), r*cos(pi*i / 20));
		}
		glEnd();
	}

	glutSwapBuffers(); //交换两个缓冲区
}


void myIdle(void)
{
	ra = ra++;
	if (ra >= 360)
		ra = 0;
	//myDisplay(); 
	glutPostRedisplay();
}


int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	//	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("opengl1");
	glutDisplayFunc(&myDisplay);
	glutIdleFunc(&myIdle);
	glutMainLoop();
	return 0;
}  

哦也,具体效果是
第一个动作图,让球体转起来_第1张图片
终于完成了,下次开始学习绘制带颜色的了,加油↖(^ω^)↗

你可能感兴趣的:(图形,OpenGL)