资源介绍
视点变换,旋转,加速减速,星空背景
太阳,光晕
各行星纹理
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "winmm.lib")
#pragma comment(lib,"wininet")
// 纹理图像结构
typedef struct
{
int imgWidth; // 纹理宽度
int imgHeight; // 纹理高度
unsigned char byteCount; // 每个象素对应的字节数,3:24位图,4:带alpha通道的24位图
unsigned char *data; // 纹理数据
}TEXTUREIMAGE;
// BMP文件头
#pragma pack(2)
typedef struct {
unsigned short bfType; // 文件类型
unsigned long bfSize; // 文件大小
unsigned short bfReserved1; // 保留位
unsigned short bfReserved2; // 保留位
unsigned long bfOffBits; // 数据偏移位置
}BMPFILEHEADER;
#pragma pack()
// BMP信息头
typedef struct {
unsigned long biSize; // 此结构大小
long biWidth; // 图像宽度
long biHeight; // 图像高度
unsigned short biPlanes; // 调色板数量
unsigned short biBitCount; // 每个象素对应的位数,24:24位图,32:带alpha通道的24位图
unsigned long biCompression; // 压缩
unsigned long biSizeImage; // 图像大小
long biXPelsPerMeter;// 横向分辨率
long biYPelsPerMeter;// 纵向分辨率
unsigned long biClrUsed; // 颜色使用数
unsigned long biClrImportant; // 重要颜色数
}BMPINFOHEADER;
// 定义窗口的标题、宽度、高度、全屏布尔变量
#define WIN_TITLE "模拟太阳系各星球的转动"
const int WIN_WIDTH = 800;
const int WIN_HEIGHT = 600;
BOOL isFullScreen = FALSE; // 初始不为全屏
#define DEG_TO_RAD 0.017453
float angle=0.0;
static GLdouble viewer[]= {0,0,0,0,0}; // 初始化视角
GLUquadricObj *quadric; // 建立二次曲面对象
GLfloat angle_Z; // 星空旋转角度
bool g_bOrbitOn = true; // 控制转动暂停
float g_fSpeedmodifier = 1.0f;
// 时间控制
float g_fElpasedTime;
double g_dCurrentTime;
double g_dLastTime;
GLfloat LightAmbient[] = { 1.0f, 1.0f, 1.0f, 0.0f }; // 环境光参数
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 0.0f }; // 漫射光参数
GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 光源的位置
// 纹理图象
TEXTUREIMAGE skyImg;
TEXTUREIMAGE sunImg;
TEXTUREIMAGE rayImg;
TEXTUREIMAGE mercuImg;
TEXTUREIMAGE venusImg;
TEXTUREIMAGE earthImg;
TEXTUREIMAGE marsImg;
TEXTUREIMAGE jupiterImg;
TEXTUREIMAGE saturnImg;
TEXTUREIMAGE uranusImg;
TEXTUREIMAGE neptuneImg;
TEXTUREIMAGE moonImg;
GLuint texture[12]; // 纹理数组
// 星球速度定义
static float fSunSpin = 0.0f; // 太阳自转速度
static float fMercuSpin = 0.0f; // 水星自转速度
static float fMercuOrbit = 0.0f; // 水星公转速度
static float fVenusSpin = 0.0f; // 金星自转速度
static float fVenusOrbit = 0.0f; // 金星公转速度
static float fEarthSpin = 0.0f; // 地球自转速度
static float fEarthOrbit = 0.0f; // 地球公转速度
static float fMarsSpin = 0.0f; // 火星自转速度
static float fMarsOrbit = 0.0f; // 火星公转速度
static float fJupiterSpin = 0.0f; // 木星自转速度
static float fJupiterOrbit = 0.0f; // 木星公转速度
static float fSaturnSpin = 0.0f; // 土星自转速度
static float fSaturnOrbit = 0.0f; // 土星公转速度
static float fUranusSpin = 0.0f; // 天王星自转速度
static float fUranusOrbit = 0.0f; // 天王星公转速度
static float fNeptuneSpin = 0.0f; // 海王星自转速度
static float fNeptuneOrbit = 0.0f; // 海王星公转速度
static float fMoonSpin = 0.0f; // 月亮自转速度
static float fMoonOrbit = 0.0f; // 月亮公转速度
void MakeTexture(TEXTUREIMAGE textureImg, GLuint * texName) //转换为纹理
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //对齐像素字节函数
glGenTextures(1,texName); //第一个参数指定表明获取多少个连续的纹理标识符
glBindTexture(GL_TEXTURE_2D , *texName);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureImg.imgWidth,textureImg.imgHeight, 0,
GL_RGB, GL_UNSIGNED_BYTE, textureImg.data);
}
// 初始化OpenGL
void InitGL(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //设置黑色背景
glClearDepth(2.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); //启动深度测试
glDepthFunc(GL_LEQUAL); //深度小或相等的时候渲染
glShadeModel(GL_SMOOTH); //启动阴影平滑
glEnable(GL_CULL_FACE); //开启剔除操作效果
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //使用质量最好的模式指定颜色和纹理坐标的插值质量
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫反射光
glEnable(GL_LIGHTING); // 打开光照
glEnable(GL_LIGHT1); // 打开光源1
// 载入纹理
glEnable(GL_TEXTURE_2D); // 开启2D纹理映射
MakeTexture(skyImg, &texture;[0]);
MakeTexture(sunImg, &texture;[1]);
MakeTexture(rayImg, &texture;[2]);
MakeTexture(mercuImg, &texture;[3]);
MakeTexture(venusImg, &texture;[4]);
MakeTexture(earthImg, &texture;[5]);
MakeTexture(marsImg, &texture;[6]);
MakeTexture(jupiterImg, &texture;[7]);
MakeTexture(saturnImg, &texture;[8]);
MakeTexture(uranusImg, &texture;[9]);
MakeTexture(neptuneImg, &texture;[10]);
MakeTexture(moonImg, &texture;[11]);
quadric = gluNewQuadric(); // 建立一个曲面对象指针
gluQuadricTexture(quadric, GLU_TRUE); // 建立纹理坐标
gluQuadricDrawStyle(quadric, GLU_FILL); // 面填充
}
void Display(void)
{
glLoadIdentity();
// 设置观察点的位置和观察的方向
gluLookAt(viewer[0],viewer[1],viewer[2],viewer[3],viewer[4],-5,0,1,0);
//摄像机x,摄像机y,摄像机z, 目标点x,目标点y,目标点z, 摄像机顶朝向x,摄像机顶朝向y,摄像机顶朝向z
// 获得系统时间使太阳系有动态效果
g_dCurrentTime = timeGetTime();
g_fElpasedTime = (float)((g_dCurrentTime - g_dLastTime) * 0.0005);
g_dLastTime = g_dCurrentTime;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW ); //指定GL_MODELVIEW是下一个矩阵操作的目标
glTranslatef(0.0f, 0.0f, -5.0f); // 将坐标系移入屏幕5.0f
glRotatef(10, 1.0f ,0.0f, 0.0f); // 将坐标系绕x轴旋转10度
glEnable(GL_LIGHT0); // 打开光源0
/**********************************绘制背景星空********************************************/
glPushMatrix (); // 当前模型矩阵入栈
glTranslatef(-10.0f, 3.0f, 0.0f);
glRotatef(angle_Z, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]); // 星空纹理
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f( 50.0f, 50.0f, -50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, 50.0f, -50.0f);
glEnd();
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, -1.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f( 50.0f, -50.0f, 50.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, 50.0f, 50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, 50.0f);
glEnd();
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f( 50.0f, -50.0f, 50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f);
glEnd();
glBegin(GL_QUADS);
glNormal3f( 0.0f, -1.0f, 0.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, 50.0f, -50.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, 50.0f, 50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f( 50.0f, 50.0f, -50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, 50.0f);
glEnd();
glBegin(GL_QUADS);
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, 50.0f, 50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, -50.0f);
glEnd();
glBegin(GL_QUADS);
glNormal3f( -1.0f, 0.0f, 0.0f);
glTexCoord2f(6.0f, 6.0f); glVertex3f(50.0f, -50.0f, -50.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(50.0f, 50.0f, 50.0f);
glTexCoord2f(6.0f, 0.0f); glVertex3f(50.0f, -50.0f, 50.0f);
glTexCoord2f(0.0f, 6.0f); glVertex3f(50.0f, 50.0f, -50.0f);
glEnd();
glPopMatrix (); // 当前模型矩阵出栈
/**********************************绘制太阳************************************************/
glBindTexture(GL_TEXTURE_2D, texture[2]); // 光晕纹理
glEnable(GL_BLEND); // 开启混合
glDisable(GL_DEPTH_TEST); // 关闭深度测试
// 绘制太阳光晕
glDisable(GL_LIGHTING); // 关闭光照
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // 半透明混合函数
glColor4f(1.0f, 0.5f, 0.0f, 0.5f); // 设置RGBA值
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glDisable(GL_BLEND); // 关闭混合
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING); // 开启光照
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // 设置光源1位置
glBindTexture(GL_TEXTURE_2D, texture[1]); // 太阳纹理
// 将坐标系绕Y轴旋转fSunSpin角度,控制太阳自转
glRotatef(fSunSpin,0.0,1.0,0.0);
gluSphere(quadric, 0.3f, 32, 32); // 绘制太阳球体
/**********************************绘制水星************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fMercuOrbit角度,控制水星公转
glRotatef(fMercuOrbit, 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(0.5f, 0.0f, 0.0f); // 将坐标系右移0.5f
glBindTexture(GL_TEXTURE_2D, texture[3]); // 水星纹理
// 将坐标系绕Z轴旋转fMercuSpin角度 控制水星自转
glRotatef(fMercuSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.04f, 32, 32); // 水星球体
glPopMatrix (); // 当前模型视图矩阵出栈
// 绘制轨道
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(0.5f*sin(DEG_TO_RAD*angle),0,0.5f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制金星************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fVenusOrbit角度,控制金星公转
glRotatef(fVenusOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);// 将坐标系绕X轴旋转-90度
glTranslatef(0.8f, 0.0f, 0.0f); // 将坐标系右移0.8f
glBindTexture(GL_TEXTURE_2D, texture[4]); // 金星纹理
// 将坐标系绕Z轴旋转fVenusSpin角度,控制金星自转
glRotatef(fVenusSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.06f, 32, 32); // 金星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(0.8f*sin(DEG_TO_RAD*angle),0,0.8f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制地球************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fEarthOrbit角度,控制地球公转
glRotatef(fEarthOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);// 将坐标系绕X轴旋转-90度
glTranslatef(1.1f, 0.0f, 0.0f); // 将坐标系右移1.1f
glBindTexture(GL_TEXTURE_2D, texture[5]); // 地球纹理
// 将坐标系绕Z轴旋转fEarthSpin角度,控制地球自转
glRotatef(fEarthSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.08f, 32, 32); // 地球球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(1.1f*sin(DEG_TO_RAD*angle),0,1.1f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制火星************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fMarsOrbit角度,控制火星公转
glRotatef(fMarsOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(1.4f, 0.0f, 0.0f); // 将坐标系右移1.4f
glBindTexture(GL_TEXTURE_2D, texture[6]); // 火星纹理
// 将坐标系绕Z轴旋转fMarsSpin角度,控制火星自转
glRotatef(fMarsSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.04f, 32, 32); // 火星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(1.4f*sin(DEG_TO_RAD*angle),0,1.4f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制木星************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fJupiterOrbit角度,控制木星公转
glRotatef(fJupiterOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(1.7f, 0.0f, 0.0f); // 将坐标系右移1.7f
glBindTexture(GL_TEXTURE_2D, texture[7]); // 木星纹理
// 将坐标系绕Z轴旋转fJupiterSpin角度,控制木星自转
glRotatef(fJupiterSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.13f, 32, 32); // 木星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(1.7f*sin(DEG_TO_RAD*angle),0,1.7f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制土星************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fSaturnOrbit角度,控制土星公转
glRotatef(fSaturnOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(1.9f, 0.0f, 0.0f); // 将坐标系右移1.9f
glBindTexture(GL_TEXTURE_2D, texture[8]); // 土星纹理
// 将坐标系绕Z轴旋转fSaturnSpin角度,控制土星自转
glRotatef(fSaturnSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.1f, 32, 32); // 土星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(1.9f*sin(DEG_TO_RAD*angle),0,1.9f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制天王星**********************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fUranusOrbit角度,控制天王星公转
glRotatef(fUranusOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(2.1f, 0.0f, 0.0f); // 将坐标系右移2.1f
glBindTexture(GL_TEXTURE_2D, texture[9]); // 天王星纹理
// 将坐标系绕Z轴旋转fUranusSpin角度,控制天王星自转
glRotatef(fUranusSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.1f, 32, 32); // 天王星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(2.1f*sin(DEG_TO_RAD*angle),0,2.1f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制海王星**********************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D ); // 开启纹理
glPushMatrix (); // 当前模型视图矩阵入栈
// 将坐标系绕Y轴旋转fNeptuneOrbit角度,控制海王星公转
glRotatef(fNeptuneOrbit , 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度
glTranslatef(2.3f, 0.0f, 0.0f); // 将坐标系右移2.3f
glBindTexture(GL_TEXTURE_2D, texture[10]); // 海王星纹理
// 将坐标系绕Z轴旋转fNeptuneSpin角度,控制海王星自转
glRotatef(fNeptuneSpin , 0.0f, 0.0f, 1.0f);
gluSphere(quadric, 0.08f, 32, 32); // 海王星球体
glPopMatrix ();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(2.3f*sin(DEG_TO_RAD*angle),0,2.3f*cos(DEG_TO_RAD*angle));
glEnd();
/**********************************绘制月亮************************************************/
glDisable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D );
// glBindTexture(GL_TEXTURE_2D, texture[11]); // 月亮纹理
glPushMatrix ();
// 将坐标系绕Y轴旋转fEarthOrbit角度,控制月亮跟随地球
glRotatef(fEarthOrbit , 0.0f, 1.0f, 0.0f);
glTranslatef(1.1f, 0.0f, 0.0f); // 将坐标系右移1.1f
// 将坐标系绕Y轴旋转fMoonOrbit角度,控制月亮公转
glRotatef(fMoonOrbit , 0.0f, 1.0f, 0.0f);
glTranslatef(0.15f, 0.0f, 0.0f);
// 将坐标系绕Y轴旋转fMoonSpin角度,控制月亮自转
glBindTexture(GL_TEXTURE_2D, texture[11]);
glRotatef(fMoonSpin , 0.0f, 1.0f, 0.0f);
gluSphere(quadric, 0.02, 32, 32); // 月亮球体
glPopMatrix ();
// 控制各星球转动的速度
if( g_bOrbitOn == true )
{
fSunSpin -= g_fSpeedmodifier * (g_fElpasedTime * 10.0f);
fMercuSpin -= g_fSpeedmodifier * (g_fElpasedTime * 15.0f);
fMercuOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 40.0f);
fVenusSpin -= g_fSpeedmodifier * (g_fElpasedTime * 10.0f);
fVenusOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 30.0f);
fEarthSpin -= g_fSpeedmodifier * (g_fElpasedTime * 100.0f);
fEarthOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 20.0f);
fMarsSpin -= g_fSpeedmodifier * (g_fElpasedTime * 30.0f);
fMarsOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 50.0f);
fJupiterSpin -= g_fSpeedmodifier * (g_fElpasedTime * 90.0f);
fJupiterOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 35.0f);
fSaturnSpin -= g_fSpeedmodifier * (g_fElpasedTime * 90.0f);
fSaturnOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 25.0f);
fUranusSpin -= g_fSpeedmodifier * (g_fElpasedTime * 70.0f);
fUranusOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 15.0f);
fNeptuneSpin -= g_fSpeedmodifier * (g_fElpasedTime * 40.0f);
fNeptuneOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 5.0f);
fMoonSpin -= g_fSpeedmodifier * (g_fElpasedTime * 50.0f);
fMoonOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 200.0f);
}
angle_Z += 0.01f; // 星空旋转
glutSwapBuffers(); // 交换双缓存
glFlush();
}
void Reshape(int width, int height)
{
if (height==0)
height=1; // 改变窗口
glViewport(0,0,width,height); // 设置视口
// 设置投影矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewer[0],viewer[1],viewer[2],viewer[3],viewer[4],-5,0,1,0);
}
void keyboard(unsigned char key, int x, int y)
{
switch(key) {
case 'r': case 'R': // 视点上下左右移动
if(viewer[0]<=4.5)
viewer[0]+=0.5;
break;
case 'l': case 'L':
if(viewer[0]>=-6.0)
viewer[0]-=0.5;
break;
case 'u': case 'U':
if(viewer[1]<=4.5)
viewer[1]+=0.1;
break;
case 'd': case 'D':
if(viewer[1]>=-6.0)
viewer[1]-=0.1;
break;
case'+': case '=': // 加速,减速,暂停
g_fSpeedmodifier+=1.0f;
glutPostRedisplay();
break;
case ' ':
g_bOrbitOn = !g_bOrbitOn;
glutPostRedisplay();
break;
case'-': //按'-'减小运行速度
g_fSpeedmodifier-=1.0f;
glutPostRedisplay();
break;
case VK_ESCAPE: // 按ESC键时退出
exit(0);
break;
default:
break;
}
}
void special_keys(int s_keys, int x, int y)
{
switch(s_keys) {
case GLUT_KEY_F1: // 按F1键时切换窗口/全屏模式
if(isFullScreen)
{
glutReshapeWindow(WIN_WIDTH, WIN_HEIGHT);
glutPositionWindow(30, 30);
isFullScreen = FALSE;
}
else
{
glutFullScreen();
isFullScreen = TRUE;
}
break;
case GLUT_KEY_RIGHT: // 视角上下左右旋转
if(viewer[3]<=4.5)
viewer[3]+=0.1;
break;
case GLUT_KEY_LEFT:
if(viewer[3]>=-3.0)
viewer[3]-=0.1;
break;
case GLUT_KEY_UP:
if(viewer[4]<=4.5)
viewer[4]+=0.1;
break;
case GLUT_KEY_DOWN:
if(viewer[4]>=-4.5)
viewer[4]-=0.1;
break;
default:
break;
}
}
void mouse(int btn, int state, int x, int y) // 远近视角
{
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
viewer[2]+=0.3;
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN&&viewer;[2]>=-3.9)
viewer[2]-=0.3;
}
void LoadBmp(char *filename, TEXTUREIMAGE *textureImg) // 载入图片
{
int i, j;
FILE *file;
BMPFILEHEADER bmpFile;
BMPINFOHEADER bmpInfo;
int pixel_size;
// 初始化纹理数据
textureImg->imgWidth = 0;
textureImg->imgHeight = 0;
if (textureImg->data != NULL)
{
delete []textureImg->data;
}
// 打开文件
file = fopen(filename, "rb");
if (file == NULL)
{
return;
}
// 获取文件头
rewind(file);
fread(&bmpFile;, sizeof(BMPFILEHEADER), 1, file);
fread(&bmpInfo;, sizeof(BMPINFOHEADER), 1, file);
// 验证文件类型
if (bmpFile.bfType != 0x4D42)
{
return;
}
// 获取图像色彩数
pixel_size = bmpInfo.biBitCount >> 3;
// 读取文件数据
textureImg->data = new unsigned char[bmpInfo.biWidth * bmpInfo.biHeight * pixel_size];
for(i = 0 ; i < bmpInfo.biHeight; i++)
{
fseek(file, bmpFile.bfOffBits + (bmpInfo.biHeight - i - 1) * bmpInfo.biWidth * pixel_size, SEEK_SET);
for (j = 0; j < bmpInfo.biWidth; j++)
{
// 红色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 2, sizeof(unsigned char), 1, file);
// 绿色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 1, sizeof(unsigned char), 1, file);
// 蓝色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 0, sizeof(unsigned char), 1, file);
// Alpha分量
if (pixel_size == 4)
{
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 3, sizeof(unsigned char), 1, file);
}
}
}
// 记录图像相关参数
textureImg->imgWidth = bmpInfo.biWidth;
textureImg->imgHeight = bmpInfo.biHeight;
textureImg->byteCount = pixel_size;
fclose(file);
}
// 程序主函数
void main(int argc, char** argv)
{
//读图片
LoadBmp("Picture//Sky.bmp" , &skyImg;);
LoadBmp("Picture//Sun.bmp" , &sunImg;);
LoadBmp("Picture//Ray.bmp" , &rayImg;);
LoadBmp("Picture//Mercu.bmp" , &mercuImg;);
LoadBmp("Picture//Venus.bmp" , &venusImg;); //金星
LoadBmp("Picture//Earth.bmp" , &earthImg;);
LoadBmp("Picture//Mars.bmp" , &marsImg;); //火星
LoadBmp("Picture//Jupiter.bmp" , &jupiterImg;); //木星
LoadBmp("Picture//Saturn.bmp" , &saturnImg;); //土星
LoadBmp("Picture//Uranus.bmp" , &uranusImg;); //天王星
LoadBmp("Picture//Neptune.bmp" , &neptuneImg;); //海王星
LoadBmp("Picture//Moon.bmp" , &moonImg;);
glutInit(&argc;, argv); // 初始化GLUT库
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); // 初始化显示模式
glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT); // 初始化窗口大小
glutInitWindowPosition(20,20); // 初始化窗口位置
GLuint window = glutCreateWindow(WIN_TITLE); // 建立窗口
InitGL(); // 初始化OpenGL
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special_keys);
glutMouseFunc(mouse);
glutIdleFunc(Display); // 设置窗口空闲时的处理函数
glutMainLoop(); // 进入事件处理循环
}