Library tutorials & articles

OpenGL and C# - Part 1

Our Cube Class

What we going to do now is making a class which will draw a cube. This cube can rotate, change color and even shrink or grow.I will just show you the code and I’m going to explain it to you later on.

using System;
using System.Drawing;
using CsGL.OpenGL;
namespace SimpleOpenGL
{
    public class Cube
    {
        protected float[] fColor = new float[3];
        /// <summary>
        /// How much Red between 0.00 and 1.00
        /// </summary>
        public float CubeColorRed
        {
            get { return fColor[0]; }
            set { fColor[0] = value ; }
        }
        /// <summary>
        /// How much Green between 0.00 and 1.00
        /// </summary>
        public float CubeColorGreen
        {
            get { return fColor[1]; }
            set { fColor[1] = value ; }
        }
        /// <summary>
        /// How much Blue between 0.00 and 1.00
        /// </summary>
        public float CubeColorBlue
        {
            get { return fColor[2]; }
            set { fColor[2] = value ; }
        }
        protected float fPlusPosition;
        protected float fMinusPosition;
        /// <summary>
        /// How big ??
        /// </summary>
        public float Scale
        {
            set
            {
                fPlusPosition = value;
                fMinusPosition = (0 - value);
            }
        }
        public float fRotate;
        protected bool bRotateCheck;
        /// <summary>
        /// Wanna rotate???
        /// default is false
        /// </summary>
        public bool Rotate
        {
            get { return bRotateCheck; }
            set { bRotateCheck = value; }
        }
        protected float fViewPort;
        /// <summary>
        /// With this you can zoom
        /// </summary>
        public float ViewPort
        {
            get { return fViewPort; }
            set { fViewPort = (-6 + value); }
        }
        /// <summary>
        /// Default Contructor
        /// </summary>
        public Cube()
        {
            for (int i = 0; i < 3; i++)
            {
                fColor[i] = 1.0f;
            }
            bRotateCheck = false;
            this.ViewPort = 0;
            this.fMinusPosition = 0f;
            this.Position = 2f;
        }
        /// <summary>
        /// Do the Draws
        /// </summary>
        public void glDrawCube()// To be in OpenGL style it I gave it a gl prefix
        {
            GL.glTranslatef(0.0f,0.0f, fViewPort);     // viewport = 0 0 0 and this is 6 deep
            if (bRotateCheck == true)
            {
                GL.glRotatef(fRotate, 1.0f, 1.0f, 1.0f);
            }
            GL.glBegin(GL.GL_QUADS);// start drawin the cube
                    GL.glColor3fv(fColor); // Color with an array of floats
                // Draw Top of the Cube
                GL.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);                    
                GL.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                
                GL.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                
                GL.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                    
                // Draw Bottom of the Cube
                GL.glVertex3f( fPlusPosition, fMinusPosition, fPlusPosition);                    
                GL.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);                    
                GL.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);                    
                GL.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);                
                // Draw Front of the Cube
                GL.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                
                GL.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                
                GL.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);                
                GL.glVertex3f( fPlusPosition,fMinusPosition, fPlusPosition);        
                // Draw Back of the Cube
                GL.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);    
                GL.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);                
                GL.glVertex3f(fMinusPosition, fPlusPosition, fMinusPosition);                    
                GL.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);                    
                // Draw Left of the Cube
                GL.glVertex3f(fMinusPosition, fPlusPosition, fPlusPosition);                
                GL.glVertex3f(fMinusPosition, fPlusPosition, fMinusPosition);                    
                GL.glVertex3f(fMinusPosition,fMinusPosition, fMinusPosition);            
                GL.glVertex3f(fMinusPosition,fMinusPosition, fPlusPosition);            
                // Draw Right of the Cube
                GL.glVertex3f( fPlusPosition, fPlusPosition, fMinusPosition);            
                GL.glVertex3f( fPlusPosition, fPlusPosition, fPlusPosition);                    
                GL.glVertex3f( fPlusPosition,fMinusPosition, fPlusPosition);                
                GL.glVertex3f( fPlusPosition,fMinusPosition, fMinusPosition);    
            GL.glEnd();// end drawing the cube    
           
            if (bRotateCheck == true)
            {
                fRotate += 2.5f;
            }
        }
    }
}

What I’m going to explain the following functions.

glTranslatef

Which is defined like this glTranslatef(float x, float y, float z) or like glTranslated(double x, double y, double z) which uses doubles instead of floats.

This function will set the drawing point. In this application we want to draw the cube right in the center of the screen so we set x and y to zero. So to make the cube visible we have to draw it a bit deeper then that we are looking so to go deeper we set the z variable in a minus position like mine apps default -6.

glRotatef

Which is defined like this glRotatef(float angle, float x, float y, float z) or like glRotated(double angle, double x, double y, double z).

To let it rotate we have to make the angle every time a bit larger like we did. For the “x y z” you just have to play with it to really get to know it.

glBegin & glEnd

Which is defined like this glBegin(uint mode) and the glEnd( void ). Those functions always come in pairs.

This function is to say against OpenGL start drawing mode or something like that. The glBegin function we used has GL_QUADS but can be much more than only quads. I will go on more detail for glBegin in the next article.

glColor3fv

This function has many others and here they are.

glColor3b(sbyte red, sbyte green, sbyte blue)
glColor3bv(sbyte[] v)
glColor3d(double red, double green, double blue)
glColor3dv(double[] v)
glColor3f(float red, float green, float blue)
glColor3fv(float[] v)
glColor3i(int red, int green, int blue)
glColor3iv(int[] v)
glColor3s(short red, short green, short blue)
glColor3sv(short[] v)

And the unsigned versions of them which are defined with a U before the type prefix. There’s also an alpha version of all this functions and have a 4 instead of a 3 where the last type variable is the alpha. This will give the quad a color where red, green and blue can be between 0.0 and 1.0

gllVertex3f

this function has also many others and here they are.

glVertex3d(double x, double y, double z)
glVertex3dv(double[] v)
glVertex3f(float x, float y, float z)
glVertex3fv(float[] v)
glVertex3i(int x, int y, int z)
glVertex3iv(int[] v)
glVertex3s(short x, short y, short z)
glVertex3sv(short[] v)

And then you can change 3 to 2 or 4. At the 2nd version of this row of functions there is no z axis. And with the 4th version of these functions there is also a w axis. This function will point a place where to draw. I will go deeper into the OpenGL coordinate at the next article so try to play with it for now.

Comments

  1. 07 Oct 2009 at 09:29

    Thanks for the tutorial, unfortunately it does not work for me. All I see is white background with a red cross of which I don't know where it comes from... Thanks for any help...

  2. 12 Sep 2009 at 20:54

    Strange, I've added a menu in the top of the window and now everything works perfectly :) thx for the tutorial. Without it I would never start. We Polish used to say "The first step is the hardest"

  3. 10 Sep 2009 at 23:49

    First of all there is no csgl-base.dll in a package csgl.dll.zip downloaded from project site. Secound of all can anybody tell me why it doesn't work? Sometimes I have to change widnow size to see the scene, sometimes it never showes up :| why? What I'm doing wrong? uffff F1 F1 F1 HELP!

  4. 01 Sep 2009 at 16:27

    the solution i know is:

        CheckForIllegalCrossThreadCalls = false;
    

    which is simpler

  5. 01 Sep 2009 at 16:26

    the solution i know is:

        CheckForIllegalCrossThreadCalls = false;
    

    which is simpler

  6. 13 Aug 2009 at 11:01

    private void OpenGL_Start() { if( this.view.InvokeRequired) { ThreadStart aDelegate = new ThreadStart(this.view.Refresh); for( ; ; ) { Thread.Sleep(1000); if( !thrOpenGL.IsAlive ) return; this.Invoke(aDelegate); } } else { for( ; ; ) { // infinity loop for rendering Thread.Sleep(1000); this.view.Refresh(); } } }

  7. 08 Aug 2009 at 14:14

    (sorry for not marking the code as code in the comment above...)

    Hi Johnny, Still there? I know it's been a while since 2003... But if you are still around, or anyone else, I have a question:

    How do I draw two separate sets of drawing in parallel? I want to draw an Anaglyph. Let's say, a blue cube and a red cude. each in a different color and at a slightly different angle acording to two POV (points of view).

    Any suggestions?

    All the best. Amir

  8. 08 Aug 2009 at 14:08

    Hi All, I ran into some trouble with the thread above, but, I found a solution... Aperantly, while using Visual Studio 2008 such a cross thread action is considered unsafe. Anyway, the "Invoke" method can take care of that with just a few lines of code:

    private void OpenGL_Start() { if( this.view.InvokeRequired) { ThreadStart aDelegate = new ThreadStart(this.view.Refresh); for( ; ; ) { Thread.Sleep(1000); if( !thrOpenGL.IsAlive ) return; this.Invoke(aDelegate); } } else { for( ; ; ) { // infinity loop for rendering Thread.Sleep(1000); this.view.Refresh(); } } }

    The 'if' statement check to see if the action is done on the current thread or not and uses the "invoke" when necessary.

    I hope I saved someone the 60 minutes it took me... ;-)

Leave a comment

Sign in or Join us (it's free).

Johnny I'm doing first year Informatica at academy of Amsterdam

Related podcasts

  • Object-Oriented Programming in Ruby

    In this episode, I talk with Scott Bellware about object-oriented programming in Ruby, and Ruby's object model. This is taken from a private conversation, and the audio quality suffers at times. Much thanks to Scott for allowing this to be released.This episode of the Alt.NET Podcast is bro...

Want to stay in touch with what's going on? Follow us on twitter!