Click here to Skip to main content
Click here to Skip to main content

Tagged as

3D solar system with OpenGL and C#

, 17 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
A demo of a solar system programmed in OpenGL and C#.

Introduction

Hello this is a 3D solar system implementation with OpenGL and C#. I tried to keep it simple because this demo it’s only for educational purposes. It contains the sun, the planets, our moon, the planet’s orbit and some stars. It is programmed in Visual Studio 2008 and I have upgraded it to Visual Studio 2010 without any kind of issue.  I used for this demo the TAO namespace which it’s an interop between the OpenGL dll and the .NET Framework. I also used Shadowengine, a small graphic framework developed by me to get rid you of the tedium of hard coding the loading of textures, the initialization of the graphic context among others.

A solar system viewed form a 3D programmer point of view 

Well, what does a solar system contains? Planets, Sun Satellites, the universe, the stars on the background, etc. As a 3D programmer you should think in how you will translate those entities to a programming environment. For example the universe it’s all black with having a black background you will solve that problem. OpenGL has that function already Gl.glClearColor(0, 0, 0, 1);//red green blue alpha will set the background color to black. About the stars, they are just bright dots, and then you could make use of the OpenGL primitives that handles the drawing of points. You can make use of random functions to generate a lot of stars if you are too lazy to place them one by one, you just have to make sure they don’t fall inside the solar system. The planets are just spheres with textures; they also have orbit and a rotation on its own axis so you have to keep track of those using variables and updating them because they change over the time. If you don’t want to make a sphere in 3D max you may use OpenGL quadrics because it defines a set of basic trigonometric shapes and also define texture coordinates for them. Satellites are the same that planets the only difference is that the axis of their rotation is located on a planet not on the sun. 

Using the code 

References in the project include those to ShadowEngine and TAO.OpenGL. I will like to point out that I don’t create a graphic context in a standalone window Like XNA, GLUT, ETC. My graphic context it’s created in a common .NET win form. This is very convenient because you can draw 3D content in any window mixing it with 2D components. Later on you will see that you can draw 3D content in almost any 2D component. The OpenGL initialization function only needs a valid component handler to start drawing 3D.

Here is the list of project classes:

Camara.cs

This is a classic FPS (First Person Shooter) camera. The explanation of how a FPS works goes beyond the scope of this article. They work the following way:

  • The mouse it’s centered on the middle of the screen.
  • When the user moves the mouse a delta X and Delta Y are calculated from the beginning point.
  • Those Delta X and Delta Y are translated into angles and how is how the camera it’s rotated.
  • When you wish to move forward or backward the camera will move in the direction that are the angles pointing.
  • You may take a look at  public void Update(int pressedButton) at the camera class to have a better understanding

MainForm.cs 

This class name its self explanatory, it is the main and only form of the project. It contains the call to the texture loading, the 3D context initialization, the drawing of the 3D content, among others. It also handles the user key and mouse input. Because the 3D content requires at least 30 frames per second to be drawn I used a timer and placed all the drawing code inside it.  One point of interest would be that I start a 3D context on a panel, so I can set the panel in any position I want inside the form.  Here is the code of the 3D initialization on the project:

hdc = (uint)pnlViewPort.Handle;
string error = "";
OpenGLControl.OpenGLInit(ref hdc, pnlViewPort.Width, pnlViewPort.Height, ref error);

Here its the code the load the textures into OpenGL memory:

ContentManager.SetTextureList("texturas\\");
ContentManager.LoadTextures();  

My small engine takes care to load all the textures located on that folder, the texture format acepted is TGA JPG and BMP. The textures may not be NPOT (Non Power Of Two) and still will load correctly.

Here its the code that draws all the scene:

private void tmrPaint_Tick(object sender, EventArgs e)
{
    // clears OpenGL
    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
    //updates the camera
    solarSystem.Camara.Update(moving);
    //draws the scene
    solarSystem.DrawsScene();
    //swaps buffers
    Winapi.SwapBuffers(hdc);
    //finish drawing operations
    Gl.glFlush();
}

Planet.cs

A planet contains the following variables:

  • Position
  • Texture
  • Orbit (current distance from the sun)
  • Current rotation angle
  • Current orbit rotation angle 
  • Current orbit speed 

I used OpenGL quadrics to draw the planets sphere. Quadrics are OpenGL predefined shapes to help in small drawing tasks. Quadrics come, for example, with texture coordinates so I don't have to use a 3D editor like 3D Max to correctly apply texture to each planet. In each frame the planet moves through its orbit according to its orbit speed. Also there is a bool variable called hasMoon to specify if you want to draw a moon for that planet. I have only our moon but if you like, for example, to draw mars moons Phobos and Deimos you can use that code. Another interesting function that contains the planet class is the one used to draw its orbit. First I generate the points with a sin function and then I connect them using GL_LINE_STRIP. Here is the code:  

public void DrawOrbit()
{
    Gl.glBegin(Gl.GL_LINE_STRIP);
    for (int i = 0; i < 361; i++)
    {
        Gl.glVertex3f(p.x * (float)Math.Sin(i * Math.PI / 180), 0, p.x * (float)Math.Cos(i * Math.PI / 180));
    }
    Gl.glEnd(); 
}

Note that the planets almost always have an elliptical orbit  this is a circular orbit. The 2 angle variables that holds the planets class are used to maintain the rotation of a planet around its axis and to maintain the rotation around the sun.

Satellite.cs

A satellite contains everything that a planet does. The only difference is that it’s rotation point it’s not the sun but the planet that contains it. So anytime it draws it has to receive the position of its containing planet.  You will note it on its draw function.

SolarSystem.cs

This is the class that contains the list of planets, stars and satellites. It only creates and draws them.  The planets are saved into a list and when I call DrawScene() from the main form it makes a foreach loop invoking the Draw method on the planets.

Star.cs

This is the class the draws the stars. The stars are single GL_POINTS which are generated in random positions. This is the function that generates them:

public void CreateStars(int amount)
{
    Random r = new Random();
    int count = 0;

    while (count != amount)
    {
        Position p = default(Position);
        p.x = (r.Next(110)) * (float)Math.Pow(-1, r.Next());
        p.z = (r.Next(110)) * (float)Math.Pow(-1, r.Next());
        p.y = (r.Next(110)) * (float)Math.Pow(-1, r.Next());
        if (Math.Pow(Math.Pow(p.x, 2) + Math.Pow(p.y, 2) + Math.Pow(p.z, 2), 1 / 3f) > 15)
        {
            stars.Add(p);
            count++;
        }
    }
}

What this code does its to generate a random point and calculate its distance to the sun, and if the distance is less that a predefined value, discard the point. In this case the predefined value is twice the radius of the solar system. This operation will be repeated until it reach the desired amount of stars.

Sun.cs

The sun class is the most simple it’s like the planet class only it has no orbit. It has only a rotation around its axis.  The sun its drawn at the OpenGL 3D coordinates of (0,0,0).

Points of Interest

In this demo you will learn how OpenGL rotation works and how to rotate a mesh around an arbitrary axis. Also you will make use of the main OpenGL primitives: Point, Line and Triangles.  Well, these are all the classes involving this project I hope it is useful and that will encourage developers to start in 3D programming. Feel yourself free to play with the code and to ask any question you want. If you like this demo you can visit my personal dev blog at http://vasilydev.blogspot.com.

History 

This is the first version of the demo.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Vasily Tserekh
Software Developer
United States United States
born on 86, had my first computer at the age of 8, wrote my first code at the age of 15(pascal), began to study informatic engineering at 2005 and graduated in 2010, now I am currently working on a software development department in my company. Working with extjs mysql and php. I have a dev blog www.vasilydev.blogspot.com. My real pasion is 3D game programming and playing guitar. Ive programmed stuff in C#, python, Delphi, PHP, C++, JS, QT and others...
Follow on   LinkedIn

Comments and Discussions

 
QuestionContentManager.cs not found PinmemberMember 1077177515-Dec-14 4:52 
Questionclose and reload the MainForm problem Pinmemberdakeen14-Sep-14 21:37 
AnswerRe: close and reload the MainForm problem PinmemberVasily Tserekh15-Sep-14 5:41 
GeneralNice! My vote of 5! PinprofessionalSharath C V12-Aug-14 21:41 
QuestionReally nice PinmemberMember 1048801525-Dec-13 22:09 
GeneralMessage Automatically Removed PinmemberMember 973361412-Aug-13 9:06 
Questiondll hell Pinmemberloise8511-Jul-13 2:22 
After I have converted the project to Visual studio 2010, the Shadowengine reference and TAO reference don't work anymore.
 
Where can I find these dll's?
AnswerRe: dll hell PinmemberVasily Tserekh11-Jul-13 4:04 
GeneralRe: dll hell [modified] Pinmemberloise8511-Jul-13 9:29 
GeneralRe: dll hell Pinmemberloise8511-Jul-13 10:55 
GeneralRe: dll hell PinmemberVasily Tserekh11-Jul-13 11:28 
GeneralRe: dll hell Pinmemberloise8511-Jul-13 11:53 
GeneralMy vote of 5 PinmemberSarah salem11-May-13 2:27 
GeneralMy vote of 5 PinmemberMihai MOGA10-May-13 19:39 
GeneralMy vote of 5 PinmemberAli Javani9-May-13 1:25 
GeneralMy vote of 5 PinmemberHumayun Kabir Mamun9-May-13 0:45 
GeneralMy vote of 5 Pinmemberfredatcodeproject8-May-13 14:10 
QuestionMuch Better PinmemberHaythamsss23-Apr-13 13:20 
AnswerRe: Much Better PinmemberVasily Tserekh23-Apr-13 16:38 
QuestionNo way to do that PinmemberHaythamsss20-Apr-13 2:05 
AnswerRe: No way to do that PinmemberVasily Tserekh20-Apr-13 7:24 
AnswerSteps for making the form Full screen PinmemberVasily Tserekh23-Apr-13 9:48 
QuestionFull Screen PinmemberHaythamsss19-Apr-13 10:08 
AnswerRe: Full Screen PinmemberVasily Tserekh19-Apr-13 16:39 
QuestionPlanet proportions PinmemberVasily Tserekh19-Apr-13 7:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 17 Apr 2013
Article Copyright 2013 by Vasily Tserekh
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid