opengl实验四【太阳系】
学院专业班学号
姓名:教师评定:
#include
#include
#include
#include
#include
#pragma comment(lib,"glaux.lib") //将glaux.lib连接到工程enum //枚举鼠标变量
{
BUTTON_LEFT ,//鼠标左键
};
int mButton = -1;
int mOldY, mOldX;
float z=0,c=0;
float eye[3] = {0.0f, 0.0f, 2.0f}; //观察视角
float rot[3] = {45.0f, 45.0f, 0.0f}; //旋转变量
const int GL_WIN_WIDTH = 800; //窗口大小
const int GL_WIN_HEIGHT = 600;
const int GL_WIN_INITIAL_X = 0;
const int GL_WIN_INITIAL_Y = 0;
const int n = 1000,m=20;
const float R = 1.2f,r=0.15f;//半径
const float Pi = 3.1415926536f;
GLuint g_TexturesArray[7];//纹理指针
int iMode=1;
void ProcessMenu(int value)//弹出处理函数
{
iMode=value;
glutPostRedisplay();//强制刷新显示
}
void CreatePopMenu()//生成弹出式菜单函数
{
int nMainMenu;//主菜单变量
nMainMenu=glutCreateMenu(ProcessMenu);//生成一个主菜单并指定菜单处理函数
glutAddMenuEntry("填充",1);//添加一个主菜单
glutAddMenuEntry("轮廓",2);//添加一个主菜单
glutAttachMenu(GLUT_RIGHT_BUTTON);//指定激活菜单的鼠标右键}
bool LoadBMP(char *filename, GLuint &texture) //调贴图大小为2的幂{
AUX_RGBImageRec *pImage = NULL;
pImage = auxDIBImageLoad(filename); // 装入位图
if(pImage == NULL) return false; // 位图没装入返回错误glGenTextures(1, &texture); // 生成贴图(纹理)
glBindT exture (GL_TEXTURE_2D,texture);// 捆绑贴图(纹理) gluBuild2DMipmaps(GL_TEXTURE_2D,4, //建立图形
pImage->sizeX, // 图形宽pImage->sizeX
pImage->sizeY, // 图形高pImage->sizeY,
GL_RGB, GL_UNSIGNED_BYTE,
pImage->data // 图形数据
);
free(pImage->data); // 释放位图数据占据的内存资源free(pImage);
return true; // 返回成功
}
void Init()
{
glEnable(GL_DEPTH_TEST); //开启深度缓冲glClearColor(0.0,0.0,0.0,1.0);
glEnable(GL_TEXTURE_2D); //启用二维文理
//----------------载入图片--------------
LoadBMP("data/11.bmp",g_TexturesArray[0]); LoadBMP("data/12.bmp",g_TexturesArray[1]); LoadBMP("data/13.bmp",g_TexturesArray[2]); LoadBMP("data/14.bmp",g_TexturesArray[3]); LoadBMP("data/15.bmp",g_TexturesArray[4]); LoadBMP("data/16.bmp",g_TexturesArray[5]); LoadBMP("data/17.bmp",g_TexturesArray[6]);
}
void glutResize(int width, int height)//重置OpenGL窗口大小{
glViewport(0, 0, width, height); //重置当前视口glMatrixMode(GL_PROJECTION); //选择投影矩阵glLoadIdentity(); //重置投影矩阵
gluPerspective(45.0, (float)width/(float)height, 1.0, 300.0);//设置视口大小}
void glutDisplay(void) //显示函数
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//表示物体的前向和后向面用填充面显示
glPushMatrix(); //入栈
glTranslatef (-eye[0], -eye[1], -10); //视口
glBindT exture(GL_TEXTURE_2D, g_TexturesArray[0]);
//----------------背景------------
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(8,-8,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(8,8,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-8,8,0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-8,-8,0);
glEnd();
glPopMatrix(); //出栈
glPushMatrix(); //入栈
glTranslatef (-eye[0], -eye[1], -eye[2]);
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
//---------------太阳--------------
if(iMode==1)
{
GLUquadricObj * quadric1; //建立一个曲面对象指针
quadric1 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric1,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric1,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[1]);//绑定纹理gluSphere(quadric1,0.3f,64,64);//画一个填充太阳
}
else if(iMode==2)
{
glDisable(GL_TEXTURE_2D);//取消纹理
glColor3f(1.0,1.0,1.0);
glutWireSphere(0.3f,32,32);//画一个线条太阳
glEnable(GL_TEXTURE_2D);//启用纹理
}
//-----------土星公转轨道------------
glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_LOOP);
for(int j=0; j glVertex3f(R*cos(2*Pi/n*j),0,R*sin(2*Pi/n*j)); glEnd(); glEnable(GL_TEXTURE_2D);//启用纹理 //-----------地球公转轨道--------------- glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_LOOP); for(j=0; j glVertex3f(0.7*cos(2*Pi/n*j),0,0.7*sin(2*Pi/n*j)); glEnd(); glEnable(GL_TEXTURE_2D);//启用纹理 //------------------土星--------------------------- glPushMatrix();//入栈 glRotatef(z, 0.0f, 1.0f, 0.0f); glTranslatef (1.2, 0, 0); glPushMatrix(); //入栈 glRotatef(c, 0.0f, 1.0f, 0.0f); glRotatef(90, 1.0f, 0.0f, 0.0f); if(iMode==1) { GLUquadricObj * quadric2; ////建立一个曲面对象指针 quadric2 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric2,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric2,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[2]);//绑定纹理gluSphere(quadric2,0.12f,64,64);//画一个填充土星 } else if(iMode==2) { glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glutWireSphere(0.12f,25,25);//画一个线条土星 glEnable(GL_TEXTURE_2D);//启用纹理 } glPopMatrix(); //出栈 //---------------土星一号卫星----------------- glPushMatrix();//入栈 glRotatef(c, 0.0f, 0.0f, 1.0f); glTranslatef (0.25, 0, 0); if(iMode==1) { GLUquadricObj * quadric3; ////建立一个曲面对象指针 quadric3 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric3,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric3,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[3]);//绑定纹理gluSphere(quadric3,0.03f,64,64);//画一个填充卫星 } else if(iMode==2) { glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glutWireSphere(0.03f,25,25);//画一个线条卫星 glEnable(GL_TEXTURE_2D);//启用纹理 } glPopMatrix();//出栈 //-----------------土星一号卫星轨道-------------- glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_LOOP); for(j=0; j glVertex3f(0.25*cos(2*Pi/n*j),0.25*sin(2*Pi/n*j),0); glEnd(); glEnable(GL_TEXTURE_2D); //启用纹理 //------------------土星二号卫星-------------------- glPushMatrix(); //入栈 glRotatef(c, 1.0f, 0.0f, 0.0f); glTranslatef (0, 0, 0.25); if(iMode==1) { GLUquadricObj * quadric4; ////建立一个曲面对象指针 quadric4 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric4,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric4,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[4]);//绑定纹理gluSphere(quadric4,0.03f,64,64);//画一个填充卫星 } else if(iMode==2) { glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glutWireSphere(0.03f,25,25);//画一个线条卫星 glEnable(GL_TEXTURE_2D);//启用纹理 } glPopMatrix();//出栈 //----------------土星二号卫星轨道------------------- glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_LOOP); for(j=0; j glVertex3f(0,0.25*cos(2*Pi/n*j),0.25*sin(2*Pi/n*j)); glEnd(); glEnable(GL_TEXTURE_2D);//启用纹理 //------------------土星的行星环-------------- glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); for(int i=0; i { glBegin(GL_LINE_LOOP); for(int j=0; j glVertex3f((r+i*0.004)*cos(2*Pi/n*j),0,(r+i*0.004)*sin(2*Pi/n*j)); glEnd(); } glEnable(GL_TEXTURE_2D); //启用纹理 glPopMatrix();//出栈 //------------------地球------------------- glPushMatrix();//入栈 glRotatef(z*2, 0.0f, 1.0f, 0.0f); glTranslatef (0, 0, 0.7); glPushMatrix(); //入栈 glRotatef(c, 0.0f, 1.0f, 0.0f); glRotatef(-90, 1.0f, 0.0f, 0.0f); if(iMode==1) { GLUquadricObj * quadric5; ////建立一个曲面对象指针 quadric5 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric5,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric5,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[5]);//绑定纹理gluSphere(quadric5,0.1f,64,64);//画一个填充地球 } else if(iMode==2) { glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glutWireSphere(0.1f,25,25);//画一个线条地球 glEnable(GL_TEXTURE_2D);//启用纹理 } glPopMatrix(); //出栈 //-----------------月亮-------------- glPushMatrix();//入栈 glRotatef(c, 1.0f, 0.0f, 0.0f); glTranslatef (0, 0, 0.15); if(iMode==1) { GLUquadricObj * quadric6; ////建立一个曲面对象指针 quadric6 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric6,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric6,GLU_FILL); //用面填充绘制场景glBindT exture(GL_TEXTURE_2D, g_TexturesArray[6]);//绑定纹理gluSphere(quadric6,0.025f,64,64);//画一个填充月亮 } else if(iMode==2) { glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glutWireSphere(0.025f,25,25);//画一个线条月亮 glEnable(GL_TEXTURE_2D);//启用纹理 } glPopMatrix();//出栈 //-----------------月亮轨道--------------- glDisable(GL_TEXTURE_2D);//取消纹理 glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_LOOP); for(j=0; j glVertex3f(0,0.15*cos(2*Pi/n*j),0.15*sin(2*Pi/n*j)); glEnd(); glEnable(GL_TEXTURE_2D); //启用纹理glPopMatrix();//出栈 z+=0.05; c+=0.3; glPopMatrix();//出栈 glFlush(); glutSwapBuffers(); } void clamp(float *v) { int i; for (i = 0; i < 3; i ++) //图像旋转一周后回到原地if (v[i] > 360 || v[i] < -360) v[i] = 0; } void glutMotion(int x, int y) //图像移动函数 { if (mButton == BUTTON_LEFT) //按下左键时可以任意旋转图像{ rot[0] -= (mOldY - y); rot[1] -= (mOldX - x); clamp (rot); } mOldX = x; mOldY = y; } void glutMouse(int button, int state, int x, int y)//鼠标控制函数{ if(state == GLUT_DOWN) { mOldX = x; mOldY = y; mButton = BUTTON_LEFT; } else if (state == GLUT_UP) mButton = -1; } void glutKeyboard(unsigned char key, int x, int y) //键盘控制函数{ switch (key) { case 's': //按S键放大图像 case 'S':eye[2] -= 0.05;break; case 'W': //按W键缩小图像 case 'w':eye[2] += 0.05;break; } } int main(int argc, char** argv) //主函数 { glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); glutInitWindowPosition( GL_WIN_INITIAL_X, GL_WIN_INITIAL_Y ); glutInitWindowSize( GL_WIN_WIDTH, GL_WIN_HEIGHT ); glutInit( &argc, argv ); glutCreateWindow("太阳系"); glutDisplayFunc(glutDisplay); glutIdleFunc(glutDisplay); glutReshapeFunc(glutResize); Init(); glutMouseFunc(glutMouse); glutMotionFunc(glutMotion); glutKeyboardFunc(glutKeyboard); CreatePopMenu(); glutMainLoop(); return 0; }