#include "SDL/sdl.h"
#include "SDL/sdl_opengl.h"
#include "SDL_image.h"
#include <string>
#include <ctime>
#include <cmath>
#include <iostream>
#include "Planet.h"
const float PI = 3.1415926f;
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 800;
const int SCREEN_BPP = 32;
const float ZoomMax = 10.0;
int CameraPos[2];
float Zoom;
int* GUIPosition(int x,int y);
float toDeg(float rad);
float toRad(float deg);
GLuint loadTexture(const std::string &fileName);
int main( int argc, char* args[] )
{
CameraPos[0] = 0;
CameraPos[1] = 1;
Zoom = 0.1;
SDL_Init( SDL_INIT_EVERYTHING );
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_WM_SetCaption("Solar system", NULL);
SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP, SDL_OPENGL);
glClearColor(0,0,0,1);
glViewport(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,0.1,ZoomMax);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
SDL_Event event;
srand(time(NULL));
//Variables
bool Running = true;
int Tick = 0;
int Sizes[9] = {1399830,4900,12000,12760,6800,143000,120000,52000,2300};
float Speed[9] = {0,47.9,35.0,29.8,24.1,13.1,9.6,6.8,5.4};//km/s
float Scale = 0.01;
bool isRight=false,isLeft=false;
bool ShowMarkers = true;
int Devider = 100;
int num_segments = 30;
int CameraSpeed = 20;
unsigned int Arrow = 0;
Arrow = loadTexture("Arrow.png");
enum//Scenes
{
sceneIntro,
sceneProp,//Proportional model
sceneOverview//Overview model
};
int CurrentScene = sceneOverview;
Planet Sun(Sizes[0]*Scale,0,loadTexture("Sun.png"));
Sun.SetPosition(0,0);
Planet Mercury(Sizes[1]*Scale,58000000*Scale,loadTexture("Mercury.png"));
Planet Venus(Sizes[2]*Scale,108000000*Scale,loadTexture("Venus.png"));
Planet Earth(Sizes[3]*Scale,150000000*Scale,loadTexture("VLd.png"));
Planet Mars(Sizes[4]*Scale,228000000*Scale,loadTexture("VLd.png"));
Planet Jupiter(Sizes[5]*Scale,778000000*Scale,loadTexture("VLd.png"));
Planet Saturn(Sizes[6]*Scale,1427000000*Scale,loadTexture("VLd.png"));
Planet Uranus(Sizes[7]*Scale,2871000000u*Scale,loadTexture("VLd.png"));
Planet Neptune(Sizes[8]*Scale,4497000000*Scale,loadTexture("VLd.png"));
Planet Planets[9] = {Sun,Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune};
//Gameloop
while(Running)
{
//Events
while(SDL_PollEvent(&event))
{
if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
Running = false;
break;
case SDLK_LEFT:
isLeft = true;
break;
case SDLK_RIGHT:
isRight = true;
break;
case SDLK_F1:
ShowMarkers = not ShowMarkers;
break;
case SDLK_F2:
if(CurrentScene==sceneProp)
Zoom = ZoomMax;
break;
case SDLK_F3:
if(CurrentScene==sceneProp)
Zoom = 0.1;
break;
case SDLK_F4:
CurrentScene = sceneOverview;
Zoom = 0.1;
CameraPos[0] = 0;
CameraPos[1] = 0;
Devider=100;
break;
case SDLK_F5:
CurrentScene = sceneProp;
Zoom=10;
break;
default:
break;
}
}else if(event.type == SDL_QUIT) Running = false;
else if(event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_LEFT:
isLeft = false;
break;
case SDLK_RIGHT:
isRight = false;
break;
default:
break;
}
}else if(event.type == SDL_MOUSEBUTTONDOWN)
{
switch(event.button.button)
{
case 4:
if(Zoom>0.2&&CurrentScene==sceneProp)
Zoom-=0.1;
else if (Devider>1&&CurrentScene==sceneOverview)
Devider--;
break;
case 5:
if(Zoom<ZoomMax&&CurrentScene==sceneProp)
Zoom+=0.1;
else if(CurrentScene==sceneOverview)
Devider++;
break;
default:
break;
}
}
}
//Logic
if(CurrentScene==sceneOverview)
{
for(int x=1;x<9;x++)
{
int rad = 20+(pow(x,2)+x*30);
float deg = (Speed[x]/Devider)*Tick;
Planets[x].SetPosition(cos(toRad(deg))*rad,sin(toRad(deg))*rad);
}
}else if(CurrentScene==sceneProp)
{
//if(isDown) CameraPos[1]-=100*Zoom;
//if(isUp) CameraPos[1]+=100*Zoom;
if(isRight)
{
if(CameraPos[0]>-Planets[8].GetDistance())
{
CameraPos[0]-=CameraSpeed*(10*Zoom);
}else
{
CameraPos[0] = -Planets[8].GetDistance();
}
}
if(isLeft)
{
if(CameraPos[0]<0)
{
CameraPos[0]+=CameraSpeed*(10*Zoom);
}else
{
CameraPos[0] = 0;
}
}
for(int x=1;x<9;x++)
{
int dist = Planets[x].GetDistance();
Planets[x].SetPosition(dist,0);
}
}
//Rendering
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(CameraPos[0]+SCREEN_WIDTH*(Zoom*5),CameraPos[1]+SCREEN_HEIGHT*(Zoom*5),-Zoom);
glColor4f(1,1,1,1);
if(CurrentScene==sceneOverview)
{///Overview model rendering
glColor4f(1,1,1,0.5);
for(int xx=1;xx<9;xx++)
{
int r = 20+(pow(xx,2)+xx*30);
int cx = 0;
int cy = 0;
float theta = 2 * 3.1415926 / float(num_segments);
float c = cosf(theta);
float s = sinf(theta);
float t;
float x = r;
float y = 0;
glBegin(GL_LINE_LOOP);
for(int ii = 0; ii < num_segments; ii++)
{
glVertex2f(x + cx, y + cy);
t = x;
x = c * x - s * y;
y = s * t + c * y;
}
glEnd();
}
glColor4f(1,1,1,1);
glEnable(GL_TEXTURE_2D);
for(int x=0;x<9;x++)
{
glBindTexture(GL_TEXTURE_2D,Planets[x].GetTexture());
glBegin(GL_QUADS);
int Pos[2] = {Planets[x].GetX(),Planets[x].GetY()};
int rad = Planets[x].GetRadius()/200;
if(x==0)
rad = 15;
else
rad = 3+rad;
glTexCoord2d(0,0); glVertex2f(Pos[0]-rad,Pos[1]-rad);
glTexCoord2d(0,1); glVertex2f(Pos[0]-rad,Pos[1]+rad);
glTexCoord2d(1,1); glVertex2f(Pos[0]+rad,Pos[1]+rad);
glTexCoord2d(1,0); glVertex2f(Pos[0]+rad,Pos[1]-rad);
glEnd();
}
glDisable(GL_TEXTURE_2D);
}else if(CurrentScene==sceneProp)
{///Proportional model rendering
glEnable(GL_TEXTURE_2D);
for(int x=0;x<9;x++)
{
glBindTexture(GL_TEXTURE_2D,Planets[x].GetTexture());
glBegin(GL_QUADS);
int Pos[2] = {Planets[x].GetX(),Planets[x].GetY()};
int rad = Planets[x].GetRadius();
glTexCoord2d(0,0); glVertex2f(Pos[0]-rad,Pos[1]-rad);
glTexCoord2d(0,1); glVertex2f(Pos[0]-rad,Pos[1]+rad);
glTexCoord2d(1,1); glVertex2f(Pos[0]+rad,Pos[1]+rad);
glTexCoord2d(1,0); glVertex2f(Pos[0]+rad,Pos[1]-rad);
glEnd();
}
glDisable(GL_TEXTURE_2D);
if(ShowMarkers)
{
glColor4f(1,0,0,0.5);
glBegin(GL_QUADS);
for(int x=0;x<9;x++)
{
int Pos[2] = {Planets[x].GetX(),Planets[x].GetY()};
int rad = 500*Zoom;
glVertex2f(Pos[0]-rad,Pos[1]-rad);
glVertex2f(Pos[0]-rad,Pos[1]+rad);
glVertex2f(Pos[0]+rad,Pos[1]+rad);
glVertex2f(Pos[0]+rad,Pos[1]-rad);
}
glEnd();
}
glColor4f(1,1,1,1);
glBegin(GL_QUADS);
int* Pos;
Pos = GUIPosition(50,SCREEN_HEIGHT-50);
int xSize=(SCREEN_WIDTH-100)*(10*Zoom),ySize=(10*Zoom);
glVertex2f(Pos[0],Pos[1]);
glVertex2f(Pos[0]+xSize,Pos[1]);
glVertex2f(Pos[0]+xSize,Pos[1]+ySize);
glVertex2f(Pos[0],Pos[1]+ySize);
xSize=(10*Zoom);
ySize=3*(10*Zoom);
for(int x=0;x<9;x++)
{
Pos=GUIPosition(50+((float)Planets[x].GetDistance()/Planets[8].GetDistance())*((SCREEN_WIDTH-100)),SCREEN_HEIGHT-53);
glVertex2f(Pos[0],Pos[1]);
glVertex2f(Pos[0]+xSize,Pos[1]);
glVertex2f(Pos[0]+xSize,Pos[1]+ySize);
glVertex2f(Pos[0],Pos[1]+ySize);
}
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,Arrow);
glBegin(GL_QUADS);
Pos=GUIPosition(36-(SCREEN_WIDTH-100)*((CameraPos[0]+0.1)/Planets[8].GetDistance()),SCREEN_HEIGHT-49);
xSize=28*(10*Zoom);
ySize=28*(10*Zoom);
glTexCoord2d(0,0); glVertex2f(Pos[0],Pos[1]);
glTexCoord2d(1,0); glVertex2f(Pos[0]+xSize,Pos[1]);
glTexCoord2d(1,1); glVertex2f(Pos[0]+xSize,Pos[1]+ySize);
glTexCoord2d(0,1); glVertex2f(Pos[0],Pos[1]+ySize);
glEnd();
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
SDL_GL_SwapBuffers();
//End
Tick++;
SDL_Delay(10);
}
SDL_Quit();
return 0;
}
float toRad(float deg)
{
return deg*(PI/180);
}
float toDeg(float rad)
{
return rad*(180/PI);
}
int* GUIPosition(int x,int y)
{
int* Info;
int Cam[2];
Info = Cam;
Cam[0] = -(CameraPos[0]+SCREEN_WIDTH*(Zoom*5))+(x*(Zoom*10));
Cam[1] = -(CameraPos[1]+SCREEN_HEIGHT*(Zoom*5))+(y*(Zoom*10));
std::cout<<"";
return Info;
}
GLuint loadTexture(const std::string &fileName)
{
SDL_Surface *image = IMG_Load( fileName.c_str() );
SDL_DisplayFormatAlpha(image);
unsigned object(0);
glGenTextures(1, &object);
glBindTexture(GL_TEXTURE_2D, object);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
SDL_FreeSurface(image);
return object;
}