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

Tagged as

3D Plaza in C# with opengl Exploration

, 15 Jul 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple 3D exploration of a plaza in OpenGL and C#

 

cover

Introduction

First of all, this article is mainly to break the myth that 3D programming is out of reach of the average programmer. With the tools that exist today, almost any programmer can get into this matter without to much effort.

This demo makes use of the TAO framework, that is, basically an Interop library from .NET with windows OpenGL. It also contains a small engine made by myself called ShadowEngine that encapsulates tasks such as graphic initialization, texture and model loading, among others.

OK, let me explain the project step by step.

SkyBox.cs

This class is for drawing the sky and the mountains that you see on the demo, is basically a box with images. This technique is used in 90 percent of the games you see nowadays, of course mixing it with other techniques to make it more realistic.

Take a look at how I draw a portion of the skybox:

Gl.glEnable(Gl.GL_TEXTURE_2D);    // enable opengl texturing  
Gl.glBindTexture(Gl.GL_TEXTURE_2D,ContentManager.GetTextureByName
    ("back.bmp"));        //enabling texture for the portion of the skybox

Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(-1, 1, 1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x + width, y, z);
Gl.glNormal3d(-1, -1, 1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z);
Gl.glNormal3d(1, -1, 1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x, y + height, z);
Gl.glNormal3d(1, 1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x, y, z);
Gl.glEnd();

With Gl.glVertex3d I draw a point of the square on the screen, with Gl.glTexCoord2f I tell OpenGL where the image on the square will be and with Gl.glNormal3d I tell openGL the direction of the square. All these calls are made between Gl.glBegin(Gl.GL_QUADS) and Gl.glEnd();

Plaza.cs and Collisions

This class handles the drawing of the plaza that is basically to draw the 3D model with textures. This process is encapsulated so you only see this in the create function:

m = ContentManager.GetModelByName("plaza.3DS"); // get the model
m.CreateDisplayList();    // this loads the model in opengl memory(displays lists)

And this on the Draw function:

Gl.glPushMatrix();
Gl.glTranslatef(0, 1.4f, 0); 
Gl.glScalef(0.2f, 0.2f, 0.2f); 
m.DrawWithTextures();
Gl.glPopMatrix();

The plaza has collisions implemented in a very easy way and is only for learning purposes, because games these days implement a very complex architecture for handling collisions, which leaves out of game to the normal people living on earth. The collision is for the camera and there are two types of collisions, the first is a collision point, for example the fountain and the stick holding the flag, for that collision you only have to tell the collision manager the 3D location of this points and then a number that is how much do you want the camera to get close to it before firing a collision. The other is a collision line, for example it will be four collision lines if you don’t want the user to leave the plaza, here is a sample of the code.

public void CreateCollisions()
{
    CollisionPoint c1 = new CollisionPoint();
    c1.point = new Point3D(1.5f, 9.0f, 0);
    c1.ColitionDistance = 2.3f;
    c1.enabled = true; 

    CollisionPoint c2 = new CollisionPoint();
    c2.point = new Point3D(-0.35f, -3.97f, 0);
    c2.ColitionDistance = 0.3f;
    c2.enabled = true;

    Collision.AddCollisionPoint(c1);
    Collision.AddCollisionPoint(c2); 
 
    Collision.AddCollisionSegment(new Point3D(-14.4f, 28.3f, 0), 
                new Point3D(-14.5f, -11.6f, 0), 0.5f);
    Collision.AddCollisionSegment(new Point3D(-14.4f, -11.6f, 0), 
                new Point3D(20.1f, -11.7f, 0), 0.5f);
}  

Flag.cs

The explanation of how flag is made goes beyond the scope of this article I’ve borrowed most of the code from the flag tutorial at www.nehe.com. To make a difficult explanation easy, I tell that the flag is a grid of points that are multiplied by a sine function, and why a sine function, look how a sin function looks and you will understand.

3DPlazaInCSharp/image002.png

Then every frame I draw, I translate all the points one step from left to right and the last point to the right I translate it to the first left point. And voila, you see a waving flag. Here is a piece of the code:

for (int x = 0; x < 47; x++)
     {
     // Loop Through The Y Plane
     for (int y = 0; y < 10; y++)
         {
             // Apply The Wave To Our Mesh
             points[x, y, 0] = (float)((x / 5.0f) - 0.1f);
             points[x, y, 1] = (float)((y / 1.125f) - 0.1f);
             points[x, y, 2] = 
(float)(Math.Sin(Helper.DegreeToRad(((x/ 5.0f) * 40.0f)) * 2.0f));
          }      
     }

Camera.cs

This class is for handling the camera movement; it has a First Person Shooter Camera. The idea is to place the mouse on the center of the screen and translate every mouse movement in X and Y into angles rotations and then put the mouse again on the screen center. Also the camera queries the collision manager before moving in a direction. Here is a sample:

if (!Collision.CheckCollision(new Point3D(-newEyeX, -newEyeZ, 0)))
   {
      eyex = newEyeX;
      eyez = newEyeZ;
   }

MainClass.cs and Mainform.cs

Mainclass is the Manager class, it contains all the objects that will be drawn on the screen if you want and object not to be drawn just comment the object in the draw function:

public void DrawScene()
        {
            plaza.Draw();
            sky.Draw();
            flag.Draw();  
            //DebugMode.WriteCamaraPos(200, 200); //work only in
                                                 32bits system
            Collision.DrawColissions();         
        }

Mainform is the Windows Form that displays the project. It contains a timer for drawing and updating the entire scene.

I am hoping to receive feedback from this example. If you like it, you can visit my blog www.vasilydev.blogspot.com and leave a comment.

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

 
QuestionWork perfectly Pinprofessionalugo.marchesini16-Jul-14 0:24 
SuggestionI would like to see more than what is here PinmemberSlacker00711-Jan-12 0:24 
GeneralRe: I would like to see more than what is here PinmemberGL_Terminator11-Jan-12 6:29 
GeneralMy vote of 2 PinmemberxComaWhitex11-Jan-12 0:21 
GeneralRe: My vote of 2 PinmemberGL_Terminator11-Jan-12 6:26 
GeneralGood example Pinmemberpwasser10-Jan-12 18:47 
Converted to vs 2010 - no problems. Nice example.
Peter Wasser

QuestionNo uploaded source? Pinmemberpwasser10-Jan-12 14:17 
AnswerRe: No uploaded source? PinmemberGL_Terminator10-Jan-12 17:39 
GeneralRe: No uploaded source? Pinmemberpwasser10-Jan-12 18:30 

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
Web04 | 2.8.141223.1 | Last Updated 15 Jul 2014
Article Copyright 2012 by Vasily Tserekh
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid