本来以为这个事情很容易做到,突然发现网上的各种东西都太杂乱。。已经一个小时过去了我还没有找到最简单的方法,突然觉得自己写的东西哪天某个初学者看起来很清楚的话也能算我大功一件了。
这个工程量果然比之前的大很多。。终于解决了之前出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.
void glMatrixMode(
GLenum
mode
)
;
void gluLookAt(
GLdouble
eyeX, GLdouble
eyeY, GLdouble
eyeZ, GLdouble
centerX, GLdouble
centerY, GLdouble
centerZ, GLdouble
upX, GLdouble
upY, GLdouble
upZ
)
;
为了能让我们的程序能够使用双缓冲,我们需要改变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;
}