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

Arcball Module in C# - Tao.OpenGL

By , 11 Jan 2008
 

Introduction

This article is the continuation on my Arcball module for C#. Previously, I had posted a code using CsGL. In this version, I have utilized the Tao.OpenGL wrapper and I have added Rotation/Zoom/Pan functions. I have also made use of Display Lists to speed up plot rendering. The Arcball module written here is general and not limited to OpenGL, and can be used in GDI+ and DirectX as well. Please note that my main focus in this tutorial is on the Arcball module, not on OpenGL application.

Background

Arcball (also know as RollerBall) is probably the most intuitive method to view three dimensional objects. The principle of the Arcball is based on creating a sphere around the object and letting users to click a point on the sphere and drag it to a different location. There is a bit of math involved and you can Google for it. Here are few good links to educate yourself:

The code here is a C# source code implementing an Arcball in OpenGL (Tap.OpenGL).

Screenshot - pic1.png

Here is the same object but zoomed using the mouse middle button:

Screenshot - pic2.png

And, here is when it is panned to the left using the mouse right button:

Screenshot - pic3.png

Using the code

In this version, I am using Display List, Lighting, and Blending functions. I am not going to go into the details of OpenGL programming for the sake of brevity. Create a new form, create an instance of the Arcball class, and make if fill the form rectangle. All plots should go in the public function PlotGL in Form1.cs. I am plotting a torus and a backward torus in this example.

public void PlotGL()
{
    try

    {
        lock (matrixLock)
        {
            ThisTransformation.get_Renamed(matrix);
        }

        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
        Gl.glLoadIdentity();

        Gl.glPushMatrix();                  // NEW: Prepare Dynamic Transform
        Gl.glMultMatrixf(matrix);           // NEW: Apply Dynamic Transform

        #region plot something
        Gl.glPolygonMode(Gl.GL_FRONT, Gl.GL_FILL);
        Gl.glColor3f(0.8f, 0.3f, 0.1f);
        Gl.glCallList(plot_glList1); // plot using display list 

        //Gl.glPolygonMode(Gl.GL_FRONT, Gl.GL_LINE);
        Gl.glColor3f(0.5f, 0.5f, 0.9f);
        Gl.glCallList(plot_glList2); // plot using display list 

        #endregion plot something

        Gl.glPopMatrix(); // NEW: Unapply Dynamic Transform
        Gl.glFlush();     // Flush the GL Rendering Pipeline

        this.simpleOpenGlControl1.Invalidate();


    }
    catch
    {
        return;
    }
}

I have defined the transformation matrices in here (Arcball.cs):

public class Matrix4f
{

...


    public Quat4f Rotation
    {
        set
        {
            float n, s;
            float xs, ys, zs;
            float wx, wy, wz;
            float xx, xy, xz;
            float yy, yz, zz;

            M = new float[4, 4];

            n = (value.x * value.x) + (value.y * value.y) + 
                (value.z * value.z) + (value.w * value.w);
            s = (n > 0.0f) ? 2.0f / n : 0.0f;

            xs = value.x * s;
            ys = value.y * s;
            zs = value.z * s;
            wx = value.w * xs;
            wy = value.w * ys;
            wz = value.w * zs;
            xx = value.x * xs;
            xy = value.x * ys;
            xz = value.x * zs;
            yy = value.y * ys;
            yz = value.y * zs;
            zz = value.z * zs;

            // rotation
            M[0, 0] = 1.0f - (yy + zz);
            M[0, 1] = xy - wz;
            M[0, 2] = xz + wy;

            M[1, 0] = xy + wz;
            M[1, 1] = 1.0f - (xx + zz);
            M[1, 2] = yz - wx;

            M[2, 0] = xz - wy;
            M[2, 1] = yz + wx;
            M[2, 2] = 1.0f - (xx + yy);

            M[3, 3] = 1.0f;

            // translation (pan)
            M[0, 3] = pan.x;
            M[1, 3] = pan.y;

            // scale (zoom)
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    M[i, j] *= scl;


        }
    }

    public float Scale
    {
        set { scl = value; }

    }

    public Vector3f Pan
    {
        set { pan = value; }

    }

}

You don't need to change anything else and the code should work. I have included comments as much as possible, but feel free to contact me if you have questions.

Note: For almost any code, you do not need to modify the Arcball class at all.

History

  • This is release 1.01. Please let me know if you find any bugs.

License

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

About the Author

Kam
Engineer
United States United States
Member
I currently work as a Computational Fluid Dynamics (CFD) consultant in an engineering company in Seattle. I hold a Ph.D. in mechanical engineering. Programming is essential in my "real" projects, but I still consider it a passion of mine. I have extensive experience in C++, FORTRAN, VB but still new to C#; though I like C# the most!

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Layout  Per page   
QuestionWhy do you use lock?membernightrider138 Feb '13 - 23:36 
QuestionThank you very much , but do you know how to do this kind of graphicsmemberderek091925 Nov '11 - 21:12 
QuestionThank youmemberMember 819926712 Sep '11 - 21:18 
GeneralThanks! Keeping Y axis verticalmembernorrisMiou27 Feb '11 - 3:07 
GeneralRe: Thanks! Keeping Y axis verticalmemberKam3 Mar '11 - 10:23 
GeneralRotate cameramembersajmon4423 Sep '10 - 0:30 
GeneralThanks!memberLimeMan26 May '10 - 8:01 
GeneralPan is reversedmemberRajeev Lochan15 Apr '10 - 0:06 
GeneralRe: Pan is reversedmemberKam26 Apr '10 - 20:11 
GeneralZoom and Viewing directions [modified]memberM.Siyamalan19 Mar '10 - 1:22 
GeneralRe: Zoom and Viewing directionsmemberKam30 Mar '10 - 9:57 
GeneralInverse TransformationmemberMember 266410825 Nov '09 - 19:17 
GeneralRe: Inverse TransformationmemberKam27 Nov '09 - 19:34 
Questionhow to implement this in DirectXmemberSodrohu1 Oct '09 - 22:43 
AnswerRe: how to implement this in DirectXmemberKam27 Nov '09 - 19:35 
QuestionStandard viewsmembersamjoe30 Apr '09 - 19:32 
AnswerRe: Standard viewsmemberKam11 Jun '09 - 20:14 
GeneralExcelent workmemberTiagoRibeiro23 Apr '09 - 15:27 
GeneralRe: Excelent workmemberKam28 Apr '09 - 18:24 
GeneralRe: Excelent workmemberFransiscus Herry10 Mar '10 - 20:13 
QuestionHow can I change the BackColor?memberGerber Samuel27 Mar '09 - 0:02 
AnswerRe: How can I change the BackColor?memberGerber Samuel27 Mar '09 - 1:07 
GeneralGoodmemberuaterelelli9 Jan '09 - 2:52 
GeneralRe: GoodmemberKam21 Jan '09 - 14:04 
GeneralRe: GoodmemberTom Reesbeck8 May '10 - 10:36 
GeneralThank youmemberbingqilin1 Dec '08 - 5:42 
GeneralRe: Thank youmemberKam21 Jan '09 - 14:05 
GeneralThanks a lot......memberLB Murali Krishna30 Apr '08 - 8:03 
GeneralRe: Thanks a lot......memberKam30 Apr '08 - 10:20 
GeneralMany thanksmemberSteveAbbott3 Jan '08 - 6:03 
GeneralRe: Many thanksmemberKam3 Jan '08 - 12:11 
GeneralCoolmemberPaul Conrad29 Dec '07 - 10:02 
GeneralNice onemembermirano27 Dec '07 - 8:22 
GeneralRe: Nice onememberKam28 Dec '07 - 4:15 

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 11 Jan 2008
Article Copyright 2007 by Kam
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid