//--------------------------------------------------------------------------- #include #pragma hdrstop #include "Orbit.h" #include #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; #define DISTANCE_DIV 5000000.0f #define SUN_RADIUS_DIV 500000.0f #define RADIUS_DIV 3000.0f #define SPEED_MUL 1000.0f #define SUN_RADIUS 1390000.0f/SUN_RADIUS_DIV #define SUN_COLOR_RED 1.0f #define SUN_COLOR_GREEN 1.0f #define SUN_COLOR_BLUE 0.0f #define SUN_COLOR_ALPHA 1.0f #define MERCURY_RADIUS 2439.7f/RADIUS_DIV #define MERCURY_DISTANCE 57909175.0f/DISTANCE_DIV #define MERCURY_ROTATION_SPEED ((47.8725f*360)/(2*M_PI*57909175.0f))*SPEED_MUL #define MERCURY_COLOR_RED 0.4f #define MERCURY_COLOR_GREEN 0.4f #define MERCURY_COLOR_BLUE 0.4f #define MERCURY_COLOR_ALPHA 1.0f #define VENUS_RADIUS 2439.7f/RADIUS_DIV #define VENUS_DISTANCE 108208930.0f/DISTANCE_DIV #define VENUS_ROTATION_SPEED ((35.0214f*360)/(2*M_PI*108208930.0f))*SPEED_MUL #define VENUS_COLOR_RED 0.4f #define VENUS_COLOR_GREEN 0.4f #define VENUS_COLOR_BLUE 0.8f #define VENUS_COLOR_ALPHA 1.0f #define EARTH_RADIUS 6378.14f/RADIUS_DIV #define EARTH_DISTANCE 149597890.0f/DISTANCE_DIV #define EARTH_ROTATION_SPEED ((29.7859f*360)/(2*M_PI*149597890.0f))*SPEED_MUL #define EARTH_COLOR_RED 0.0f #define EARTH_COLOR_GREEN 0.4f #define EARTH_COLOR_BLUE 0.6f #define EARTH_COLOR_ALPHA 1.0f #define MARS_RADIUS 3397.0f/RADIUS_DIV #define MARS_DISTANCE 227936640.0f/DISTANCE_DIV #define MARS_ROTATION_SPEED ((24.1309f*360)/(2*M_PI*227936640.0f))*SPEED_MUL #define MARS_COLOR_RED 1.0f #define MARS_COLOR_GREEN 0.1f #define MARS_COLOR_BLUE 0.1f #define MARS_COLOR_ALPHA 1.0f #define JUPITER_RADIUS 71492.0f/RADIUS_DIV #define JUPITER_DISTANCE 778412020.0f/DISTANCE_DIV #define JUPITER_ROTATION_SPEED ((13.0697f*360)/(2*M_PI*778412020.0f))*SPEED_MUL #define JUPITER_COLOR_RED 1.0f #define JUPITER_COLOR_GREEN 0.5f #define JUPITER_COLOR_BLUE 0.5f #define JUPITER_COLOR_ALPHA 1.0f #define SATURN_RADIUS 60268.0f/RADIUS_DIV #define SATURN_DISTANCE 1426725400.0f/DISTANCE_DIV #define SATURN_ROTATION_SPEED ((9.6724f*360)/(2*M_PI*1426725400.0f))*SPEED_MUL #define SATURN_COLOR_RED 0.8f #define SATURN_COLOR_GREEN 0.5f #define SATURN_COLOR_BLUE 0.6f #define SATURN_COLOR_ALPHA 1.0f #define URANUS_RADIUS 25559.0f/RADIUS_DIV #define URANUS_DISTANCE 2870972200.0f/DISTANCE_DIV #define URANUS_ROTATION_SPEED ((6.8352f*360)/(2*M_PI*2870972200.0f))*SPEED_MUL #define URANUS_COLOR_RED 0.3f #define URANUS_COLOR_GREEN 0.4f #define URANUS_COLOR_BLUE 1.0f #define URANUS_COLOR_ALPHA 1.0f #define NEPTUNE_RADIUS 24764.0f/RADIUS_DIV #define NEPTUNE_DISTANCE 4498252900.0f/DISTANCE_DIV #define NEPTUNE_ROTATION_SPEED ((5.4778f*360)/(2*M_PI*4498252900.0f))*SPEED_MUL #define NEPTUNE_COLOR_RED 0.3f #define NEPTUNE_COLOR_GREEN 0.3f #define NEPTUNE_COLOR_BLUE 0.8f #define NEPTUNE_COLOR_ALPHA 1.0f #define PLUTO_RADIUS 1195.0f/RADIUS_DIV #define PLUTO_DISTANCE 5906376200.0f/DISTANCE_DIV #define PLUTO_ROTATION_SPEED ((4.7490f*360)/(2*M_PI*5906376200.0f))*SPEED_MUL #define PLUTO_COLOR_RED 0.6f #define PLUTO_COLOR_GREEN 0.6f #define PLUTO_COLOR_BLUE 0.6f #define PLUTO_COLOR_ALPHA 1.0f //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { // initalise the view position to something sensible Rotation[0]=0.0f; Rotation[1]=0.0f; Rotation[2]=0.0f; Zoom=2000.0f; OldMouseX=OldMouseY=0; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { float MercuryColor[4]= { MERCURY_COLOR_RED, MERCURY_COLOR_GREEN, MERCURY_COLOR_BLUE, MERCURY_COLOR_ALPHA }; float VenusColor[4]= { VENUS_COLOR_RED, VENUS_COLOR_GREEN, VENUS_COLOR_BLUE, VENUS_COLOR_ALPHA }; float EarthColor[4]= { EARTH_COLOR_RED, EARTH_COLOR_GREEN, EARTH_COLOR_BLUE, EARTH_COLOR_ALPHA }; float MarsColor[4]= { MARS_COLOR_RED, MARS_COLOR_GREEN, MARS_COLOR_BLUE, MARS_COLOR_ALPHA }; float JupiterColor[4]= { JUPITER_COLOR_RED, JUPITER_COLOR_GREEN, JUPITER_COLOR_BLUE, JUPITER_COLOR_ALPHA }; float SaturnColor[4]= { SATURN_COLOR_RED, SATURN_COLOR_GREEN, SATURN_COLOR_BLUE, SATURN_COLOR_ALPHA }; float UranusColor[4]= { URANUS_COLOR_RED, URANUS_COLOR_GREEN, URANUS_COLOR_BLUE, URANUS_COLOR_ALPHA }; float NeptuneColor[4]= { NEPTUNE_COLOR_RED, NEPTUNE_COLOR_GREEN, NEPTUNE_COLOR_BLUE, NEPTUNE_COLOR_ALPHA }; float PlutoColor[4]= { PLUTO_COLOR_RED, PLUTO_COLOR_GREEN, PLUTO_COLOR_BLUE, PLUTO_COLOR_ALPHA }; float LightColor[4]={1.0f, 1.0f, 1.0f, 1.0f}; // get a device context to draw through hdc=GetDC(OpenGLDisplayPanel->Handle); if(hdc == NULL) { ShowMessage("Could not create a device context"); exit(0); } // set the pixel format in the device context SetPixelFormatDescriptor(); // create a rendering context to render OpenGL through hrc = wglCreateContext(hdc); if(hrc == NULL) { ShowMessage("Could not create a rendering context"); exit(0); } // tell OpenGL to use the newly created device and rendering // contexts to draw to if(wglMakeCurrent(hdc, hrc) == false) { ShowMessage("Could not create a make rendering context current"); exit(0); } // enable depth testing, so that objects further away from the // viewer aren't drawn over closer objects glEnable(GL_DEPTH_TEST); // set OpenGL to recognise the counter clockwise defined side of a polygon // as its 'front' for lighting and culling purposes glFrontFace(GL_CCW); // enable face culling, so that polygons facing away (defines by front face) // from the viewer aren't drawn (for efficieny). glEnable(GL_CULL_FACE); // enable lighting glEnable(GL_LIGHTING); // set polygons to be smoothly shaded (i.e. interpolate lighting equations // between points on polygons). glShadeModel(GL_SMOOTH); // create a light: glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, LightColor); glLightfv(GL_LIGHT0, GL_SPECULAR, LightColor); // enable the light glEnable(GL_LIGHT0); // set the background color that the color buffer clears to as // a dark blue glClearColor(0.01f, 0.01f, 0.2f, 1.0f); // tell OpenGL to use glColor() to get material properties for.. glEnable(GL_COLOR_MATERIAL); // ..the front face's ambient and diffuse components glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // create the sun Sun.CreateGLObject(true); // set its parameters Sun.m_Radius=SUN_RADIUS; Sun.m_Color[0]=SUN_COLOR_RED; Sun.m_Color[1]=SUN_COLOR_GREEN; Sun.m_Color[2]=SUN_COLOR_BLUE; Sun.m_Color[3]=SUN_COLOR_ALPHA; // add Mercury Sun.AddMoon(MERCURY_ROTATION_SPEED, MERCURY_DISTANCE, MERCURY_RADIUS, MercuryColor); // add Venus Sun.AddMoon(VENUS_ROTATION_SPEED, VENUS_DISTANCE, VENUS_RADIUS, VenusColor); // add the Earth Sun.AddMoon(EARTH_ROTATION_SPEED, EARTH_DISTANCE, EARTH_RADIUS, EarthColor); // add Mars Sun.AddMoon(MARS_ROTATION_SPEED, MARS_DISTANCE, MARS_RADIUS, MarsColor); // add Jupiter Sun.AddMoon(JUPITER_ROTATION_SPEED, JUPITER_DISTANCE, JUPITER_RADIUS, JupiterColor); // add Saturn Sun.AddMoon(SATURN_ROTATION_SPEED, SATURN_DISTANCE, SATURN_RADIUS, SaturnColor); // add Uranus Sun.AddMoon(URANUS_ROTATION_SPEED, URANUS_DISTANCE, URANUS_RADIUS, UranusColor); // add Neptune Sun.AddMoon(NEPTUNE_ROTATION_SPEED, NEPTUNE_DISTANCE, NEPTUNE_RADIUS, NeptuneColor); // add Pluto Sun.AddMoon(PLUTO_ROTATION_SPEED, PLUTO_DISTANCE, PLUTO_RADIUS, PlutoColor); // set the application to call UpdateOpenGLScene when it is idle Application->OnIdle=UpdateOpenGLScene; // cause the display to update OpenGLDisplayPanelResize(this); } //--------------------------------------------------------------------------- void __fastcall TForm1::UpdateOpenGLScene(System::TObject* Sender, bool &Done) { float LightPos[4]={0.0f, 0.0f, 0.0f, 1.0f}; Done=false; // clear the buffers (depth and color) glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); // reset the transformation matrix glLoadIdentity(); // translate out to view distance glTranslatef(0.0f, 0.0f, -Zoom); // rotate to view angle glRotatef(Rotation[0], 1.0f, 0.0f, 0.0f); glRotatef(Rotation[1], 0.0f, 1.0f, 0.0f); // draw the stars Stars.Draw(); // clever bit: clear just the depth buffer so that all drawing goes // over the stars glClear(GL_DEPTH_BUFFER_BIT); // reset the light position to reflect the transformations glLightfv(GL_LIGHT0, GL_POSITION, LightPos); // save the tranform matrix glPushMatrix(); // draw the sun and all its heiracy Sun.Draw(); // get the transform matrix back to reset to the viewer pos glPopMatrix(); // draw the suns orbit and all its heiracies orbits Sun.DrawOrbit(); // get OpenGL to complete all the drawing glFlush(); // flip the double buffer SwapBuffers(hdc); } void __fastcall TForm1::SetPixelFormatDescriptor() { int PixelFormat; // create an apropriate pixel format PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0,0,0,0,0,0,0,0, 32, 0,0, PFD_MAIN_PLANE, 0,0,0,0 }; PixelFormat = ChoosePixelFormat(hdc, &pfd); // set the pixel format SetPixelFormat(hdc, PixelFormat, &pfd); } //--------------------------------------------------------------------------- void __fastcall TForm1::OpenGLDisplayPanelResize(TObject *Sender) { float Aspect; // set the actual viewing window to the whole display panel glViewport(0, 0, OpenGLDisplayPanel->Width, OpenGLDisplayPanel->Height); // set the matrix mode to projection glMatrixMode(GL_PROJECTION); // reset the matrix glLoadIdentity(); // get an aspect ration from the display panels width/height Aspect=(float)OpenGLDisplayPanel->Width/(float)OpenGLDisplayPanel->Height; // set a perspective view matrix gluPerspective(60.0f, Aspect, 1.0f, 20000.0f); // go back to transform matrix mode glMatrixMode(GL_MODELVIEW); // reset the matrix glLoadIdentity(); } //--------------------------------------------------------------------------- void __fastcall TForm1::OrbitUpdateTimerTimer(TObject *Sender) { // if the play button has been pressed then ... if(Playing) // ... update all the satallites positions Sun.UpdateOrbit(PlaySpeedBar->Position); } //--------------------------------------------------------------------------- void __fastcall TForm1::OpenGLDisplayPanelMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { // if user has left mouse button down then ... if(Shift.Contains(ssLeft)) { // ... rotate the view based on thier mouse movement Rotation[0]+=(OldMouseY-Y)/30.0f; Rotation[1]+=(OldMouseX-X)/30.0f; } // if user has right mouse button down then ... if(Shift.Contains(ssRight)) { // ... zoom the view based on thier mouse movement Zoom+=(OldMouseY-Y); // if they have zoomed in to the sun then clamp the zoom // value back again if(ZoomCaption="Play"; } // otherwise they want to play else { Playing=true; PlayButton->Caption="Stop"; } } //---------------------------------------------------------------------------