#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
#include <windows.h>
#include <atlimage.h>
#include <gl/glew.h>
#pragma comment(lib,"glew32.lib")
#include <gl/glut.h>
#define PI (GLfloat(3.1415926))
#define CELESTIAL_Sun 0
#define CELESTIAL_Mercury 1
#define CELESTIAL_Venus 2
#define CELESTIAL_Earth 3
#define CELESTIAL_Mars 4
#define CELESTIAL_Jupiter 5
#define CELESTIAL_Saturn 6
#define CELESTIAL_Uranus 7
#define CELESTIAL_Neptune 8
#define CELESTIAL_MOON 9
#define CELESTIAL_STAR 10
#define CELESTIAL_TUXING 11
#define CELESTIAL_HALO 12
#define CELESTIAL_COUNT 13
GLUquadricObj* celestials[CELESTIAL_COUNT];
GLuint textures[CELESTIAL_COUNT];
const wchar_t* szTextureFiles[CELESTIAL_COUNT] = {
L"data/sun.bmp",
L"data/Mercury.jpg",
L"data/Venus.jpg",
L"data/Earth.bmp",
L"data/Mars.jpg",
L"data/Jupiter.jpg",
L"data/Saturn.jpg",
L"data/Uranus.jpg",
L"data/Neptune.jpg",
L"data/MOON.jpg",
L"data/STAR.bmp",
L"data/TUXING.bmp",
L"data/HALO.png",
};
GLfloat year;
GLfloat month;
GLfloat day;
GLfloat angle_sun;
GLfloat angle_screen=0;
GLfloat sun_halo_radius = 10.0f;
GLfloat sun_halo_color_ry = 1.0f;
GLfloat* pStarPosition;
GLfloat angle_star;
GLfloat star_z;
GLuint star_color_r = 0;
GLuint star_color_g = 0;
GLuint star_color_b = 1;
#define STAR_NUM 5000
GLuint isCrazyMode = FALSE;
GLuint isStop = FALSE;
GLuint curCelestial = CELESTIAL_Earth;
void init()
{
// gen stars
angle_star = 0;
star_z = 0;
int temp = 50;
pStarPosition = new GLfloat[STAR_NUM*3];
srand(unsigned int(time(0)));
for (int i=0; i<STAR_NUM; i++)
{
GLfloat theta = 2*PI*GLfloat(rand())/RAND_MAX;
GLfloat z = -GLfloat(rand())/RAND_MAX; // [-1,0]
pStarPosition[3*i] = temp * cos(theta);
pStarPosition[3*i+1] = temp * sin(theta);
pStarPosition[3*i+2] = 1000*z;
}
glPointSize(20.0);
glTexEnvi(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE);
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN,GL_LOWER_LEFT);
glEnable(GL_POINT_SPRITE);
//////////////////////////////////////////////////////////////////////////
year = 30;
month = 30;
day = 0;
angle_sun = 30;
CImage image;
GLubyte* pixeldata;
glGenTextures(CELESTIAL_COUNT,textures);
for (int i=0; i<CELESTIAL_COUNT-1; i++)
{
celestials[i] = gluNewQuadric();
gluQuadricTexture(celestials[i],GL_TRUE);
image.Load(szTextureFiles[i]);
glBindTexture(GL_TEXTURE_2D,textures[i]);
if(image.GetPitch()<0)
pixeldata=(BYTE *)image.GetPixelAddress(0,image.GetHeight()-1);
else
pixeldata=(BYTE *)image.GetPixelAddress(0,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,image.GetWidth(),image.GetHeight(),0,GL_BGR_EXT,GL_UNSIGNED_BYTE,pixeldata);
image.Destroy();
}
//////////////////////////////////////////////////////////////////////////
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_HALO]);
image.Load(szTextureFiles[CELESTIAL_HALO]);
if(image.GetPitch()<0)
pixeldata=(BYTE *)image.GetPixelAddress(0,image.GetHeight()-1);
else
pixeldata=(BYTE *)image.GetPixelAddress(0,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,image.GetWidth(),image.GetHeight(),0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,pixeldata);
glEnable(GL_TEXTURE_2D);
//////////////////////////////////////////////////////////////////////////
glClearColor(0,0,0,0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
GLfloat ambient[] = {1.0,1.0,1.0,1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient);
GLfloat position[] = {0.0,0.0,-30.0,1.0};
glLightfv(GL_LIGHT0,GL_POSITION,position);
}
void clearSystem()
{
for (int i = 0; i < CELESTIAL_COUNT; i++)
{
gluDeleteQuadric(celestials[i]);
}
glDeleteTextures(CELESTIAL_COUNT,textures);
}
void drawStar()
{
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE);
glColor3f(star_color_r*1.0f,star_color_g*1.0f,star_color_b*1.0f);
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_STAR]);
glPushMatrix();
glRotatef(angle_star,0,0,1);
glBegin(GL_POINTS);
for (int i=0; i<STAR_NUM; i++)
{
float z = pStarPosition[3*i+2] + star_z;
if (z>0) z-=1000.0f;
if (isCrazyMode)
{
glColor3f(GLfloat(rand())/RAND_MAX,GLfloat(rand())/RAND_MAX,GLfloat(rand())/RAND_MAX);
}
glVertex3f(pStarPosition[3*i],pStarPosition[3*i+1],z);
}
if (isCrazyMode)
{
glEnd();
glPopMatrix();
glPushMatrix();
glRotatef(-angle_star,0,0,1);
glBegin(GL_POINTS);
for (int i=STAR_NUM/2; i<STAR_NUM; i++)
{
float z = pStarPosition[3*i+2] + star_z;
if (z>0) z-=1000.0f;
if (isCrazyMode)
{
glColor3f(GLfloat(rand())/RAND_MAX,GLfloat(rand())/RAND_MAX,GLfloat(rand())/RAND_MAX);
}
glVertex3f(pStarPosition[3*i],pStarPosition[3*i+1],z);
}
}
glEnd();
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
void drawOrbit( GLfloat radius )
{
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glColor3f(0.5,0.5,0.5);
glPushMatrix();
glBegin(GL_LINE_LOOP);
for (GLfloat i=0;i<2*PI;i+=.1f)
{
glVertex3f(radius*cos(i),0,radius*sin(i));
}
glEnd();
glPopMatrix();
glEnable(GL_TEXTURE_2D);
}
void drawSun()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat ambient[] = {1.0,1.0,1.0,1.0};
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glPushMatrix();
GLuint scale = isCrazyMode ? 100 : 1;
glRotated(scale*angle_sun,0,1,0);
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_Sun]);
gluSphere(celestials[CELESTIAL_Sun],5.0,20,20);
glPopMatrix();
}
void drawSunHalo()
{
glPushMatrix();
glTranslatef(0.0f,0.0f,5.0f);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_HALO]);
GLfloat radius = sun_halo_radius;
glColor3f(0.5f,0.5f*sun_halo_color_ry,0.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,1.0f);glVertex3f(-radius, radius,0.0f);
glTexCoord2f(0.0f,0.0f);glVertex3f(-radius,-radius,0.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f( radius,-radius,0.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f( radius, radius,0.0f);
glEnd();
glDisable(GL_BLEND);
glPopMatrix();
}
void drawCelestia(GLuint curCelestial, GLfloat radius = 2.0f)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat ambient[] = {0.2f,0.2f,0.2f,1.0f};
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glPushMatrix();
glRotated(270,1,0,0);
glRotated(day,0,0,1);
glBindTexture(GL_TEXTURE_2D,textures[curCelestial]);
gluSphere(celestials[curCelestial],radius,20,20);
if (curCelestial == CELESTIAL_Saturn)
{
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_TUXING]);
glColor3f(1.0f,1.0f,1.0f);
glDisable(GL_LIGHTING);
glBegin(GL_QUAD_STRIP);
for (int i=0; i<102; i++)
{
glTexCoord2f(0.0f,0.0f);glVertex3f(2.5f*cos(i*PI/50),2.5f*sin(i*PI/50),0.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f(4.5f*cos(i*PI/50),4.5f*sin(i*PI/50),0.0f);
}
glEnd();
glEnable(GL_LIGHTING);
}
glPopMatrix();
if (curCelestial == CELESTIAL_Earth)
{
glPushMatrix();
glRotatef(45,0,0,1);
glRotatef(month,0,1,0);
glTranslatef(3,0,0);
glBindTexture(GL_TEXTURE_2D,textures[CELESTIAL_MOON]);
gluSphere(celestials[CELESTIAL_MOON],0.6,20,20);
glPopMatrix();
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT |