65.9K
CodeProject 正在变化。 阅读更多。
Home

使用Tao和C#进行OpenGL 3D导航2 Tao.OpenGL, Tao.freeGlut, EP_OpenGL_CS02

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.38/5 (9投票s)

2008年2月20日

CPOL

2分钟阅读

viewsIcon

123114

downloadIcon

8806

这是一个小型程序,演示了如何使用键盘和鼠标在3D空间中导航。它使用Tao.OpenGl和Tao.freeGlut。它还演示了如何绘制一个3D立方体。

OpenGL3DNavigation2TaoCSharpDemo

引言

此项目基于我之前的项目CS02OpenGL3DNavigationTaoCSharp,但是我添加了更多功能。我认为对于OpenGL初学者来说,学习如何创建3D空间并在其中导航是最重要的知识领域之一。如果你不知道自己实际上在看哪里,可能会非常混乱。此程序演示了如何在3D空间中导航。这是一个初级程序,演示了如何在3D空间中导航。它使用glRotatef()glTranslatef()glLookAt()函数进行导航。它包含键盘事件和鼠标事件的示例。它包含3D立方体和颜色的示例。为了简化操作,我用线条划分了3D空间。x、y、z轴的交点是位置(0,0,0)。线的点划部分是每个轴的负半部分。请注意,z轴不可见,因为我们从(0,0,15)坐标查看空间。

Using the Code

  • 绿色代表 x 轴
  • 红色代表 y 轴
  • 蓝色代表 z 轴
  • x 绕x轴旋转 // 使用glRotatef()函数
  • X 绕x轴反向旋转
  • y 绕y轴旋转
  • Y 绕y轴反向旋转
  • z 绕z轴旋转
  • Z 绕z轴反向旋转
  • left_key - 向左平移 (x轴) // 使用glTranslatef()
  • right_key - 向右平移 (x轴)
  • up_key - 向上平移 (y轴)
  • down_key - 向下平移 (y轴)
  • page_up - 沿z轴平移 (放大)
  • page_down - 沿z轴平移 (缩小)
  • j 沿x轴平移 // 使用glLookAt()
  • J 沿x轴反向平移
  • k 沿y轴平移
  • K 沿y轴反向平移
  • l 沿z轴平移
  • L 沿z轴反向平移
  • b,B 在 x 轴上旋转 (+/-)90 度
  • n,N 在 y 轴上旋转 (+/-)90 度
  • m,M 在 z 轴上旋转 (+/-)90 度
  • o,O 将所有内容重置到起始位置

*********************************************************

新的按键和功能

  • F1 显示/隐藏线条
  • F2 旋转/停止立方体在x,y,z方向上的旋转
  • 鼠标左键按下 在x和y方向平移立方体 (上/下,左/右)
  • 鼠标滚轮 在+/- z方向平移立方体 (放大/缩小)
using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using Tao.FreeGlut;

namespace OpenGLNavigation2TaoCSharp
{
    sealed class Program
    {
        // Declared static (no need for object reference
        static float X = 0.0f;        // Translate screen to x direction (left or right)
        static float Y = 0.0f;        // Translate screen to y direction (up or down)
        static float Z = 0.0f;        // Translate screen to z direction (zoom in or out)
        static float rotX = 0.0f;    // Rotate screen on x axis 
        static float rotY = 0.0f;    // Rotate screen on y axis
        static float rotZ = 0.0f;    // Rotate screen on z axis

        static float rotLx = 0.0f;   // Translate screen by using the glulookAt function 
                                     // (left or right)
        static float rotLy = 0.0f;   // Translate screen by using the glulookAt function 
                                     // (up or down)
        static float rotLz = 0.0f;   // Translate screen by using the glulookAt function 
                                     // (zoom in or out)

        static bool lines = true;       // Display x,y,z lines (coordinate lines)
        static bool rotation = false;   // Rotate if F2 is pressed   
        static int old_x, old_y;        // Used for mouse event
        static int mousePressed;

        // Draw the lines (x,y,z)
        static void drawings()
        {
            // Clear the Color Buffer and Depth Buffer
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glPushMatrix();   // It is important to push the Matrix before 
                                 // calling glRotatef and glTranslatef
            Gl.glRotatef(rotX, 1.0f, 0.0f, 0.0f);            // Rotate on x
            Gl.glRotatef(rotY, 0.0f, 1.0f, 0.0f);            // Rotate on y
            Gl.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);            // Rotate on z

            if (rotation) // If F2 is pressed update x,y,z for rotation of the cube
            {
                rotX += 0.2f;
                rotY += 0.2f;
                rotZ += 0.2f;
            }

            Gl.glTranslatef(X, Y, Z);        // Translates the screen left or right, 
                                             // up or down or zoom in zoom out

            if (lines)  // If F1 is pressed don't draw the lines
            {
                // Draw the positive side of the lines x,y,z
                Gl.glBegin(Gl.GL_LINES);
                Gl.glColor3f(0.0f, 1.0f, 0.0f);                // Green for x axis
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glVertex3f(10f, 0f, 0f);
                Gl.glColor3f(1.0f, 0.0f, 0.0f);                // Red for y axis
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glVertex3f(0f, 10f, 0f);
                Gl.glColor3f(0.0f, 0.0f, 1.0f);                // Blue for z axis
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glVertex3f(0f, 0f, 10f);
                Gl.glEnd();

                // Dotted lines for the negative sides of x,y,z coordinates
                Gl.glEnable(Gl.GL_LINE_STIPPLE); // Enable line stipple to use a 
                                                 // dotted pattern for the lines
                Gl.glLineStipple(1, 0x0101);     // Dotted stipple pattern for the lines
                Gl.glBegin(Gl.GL_LINES);
                Gl.glColor3f(0.0f, 1.0f, 0.0f);                    // Green for x axis
                Gl.glVertex3f(-10f, 0f, 0f);
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glColor3f(1.0f, 0.0f, 0.0f);                    // Red for y axis
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glVertex3f(0f, -10f, 0f);
                Gl.glColor3f(0.0f, 0.0f, 1.0f);                    // Blue for z axis
                Gl.glVertex3f(0f, 0f, 0f);
                Gl.glVertex3f(0f, 0f, -10f);
                Gl.glEnd();
            }

            // I start to draw my 3D cube
            Gl.glBegin(Gl.GL_POLYGON);
            // I'm setting a new color for each corner, this creates a rainbow effect
            Gl.glColor3f(0.0f, 0.0f, 1.0f);             // Set color to blue
            Gl.glVertex3f(3.0f, 3.0f, 3.0f);
            Gl.glColor3f(1.0f, 0.0f, 0.0f);             // Set color to red
            Gl.glVertex3f(3.0f, -3.0f, 3.0f);
            Gl.glColor3f(0.0f, 1.0f, 0.0f);             // Set color to green
            Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
            Gl.glColor3f(1.0f, 0.0f, 1.0f);     // Set color to something 
                                                //(right now I don't know which color)
            Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
            Gl.glColor3f(0.50f, 0.50f, 1.0f);         // Set a new color
            Gl.glVertex3f(3.0f, 3.0f, -3.0f);
            Gl.glVertex3f(3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
            Gl.glColor3f(0.0f, 1.0f, 0.0f);         // Set a new color (green)
            Gl.glVertex3f(3.0f, 3.0f, 3.0f);
            Gl.glVertex3f(3.0f, 3.0f, -3.0f);
            Gl.glVertex3f(3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(3.0f, -3.0f, 3.0f);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
            Gl.glColor3f(0.50f, 1.0f, 0.50f);
            Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
            Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
            Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
            Gl.glColor3f(1.0f, 0.0f, 0.0f);
            Gl.glVertex3f(3.0f, 3.0f, 3.0f);
            Gl.glVertex3f(3.0f, 3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
            Gl.glColor3f(1.0f, 0.50f, 0.50f);
            Gl.glVertex3f(3.0f, -3.0f, 3.0f);
            Gl.glVertex3f(3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
            Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
            Gl.glEnd();

            Gl.glDisable(Gl.GL_LINE_STIPPLE);   // Disable the line stipple
            Glut.glutPostRedisplay();           // Redraw the scene
            Gl.glPopMatrix();                   // Don't forget to pop the Matrix
            Glut.glutSwapBuffers();
        }

        // Initialize the OpenGL window
        static void init()
        {
            Gl.glShadeModel(Gl.GL_SMOOTH);     // Set the shading model to smooth 
            Gl.glClearColor(0, 0, 0, 0.0f);    // Clear the Color
            // Clear the Color and Depth Buffer
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);    
            Gl.glClearDepth(1.0f);          // Set the Depth buffer value (ranges[0,1])
            Gl.glEnable(Gl.GL_DEPTH_TEST);  // Enable Depth test
            Gl.glDepthFunc(Gl.GL_LEQUAL);   // If two objects on the same coordinate 
                                            // show the first drawn
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
        }

        // This function is called whenever the window size is changed
        static void reshape(int w, int h)
        {
            Gl.glViewport(0, 0, w, h);                // Set the viewport
            Gl.glMatrixMode(Gl.GL_PROJECTION);        // Set the Matrix mode
            Gl.glLoadIdentity();
            Glu.gluPerspective(75f, (float)w / (float)h, 0.10f, 500.0f);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            Glu.gluLookAt(rotLx, rotLy, 15.0f + 
                     rotLz, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
        }

        // This function is used for the navigation keys
        public static void keyboard(byte key, int x, int y)
        {
            switch (key)
            {
                // x,X,y,Y,z,Z uses the glRotatef() function
                case 120:    // x             // Rotates screen on x axis 
                    rotX -= 2.0f;
                    break;
                case 88:    // X            // Opposite way 
                    rotX += 2.0f;
                    break;
                case 121:    // y            // Rotates screen on y axis
                    rotY -= 2.0f;
                    break;
                case 89:    // Y            // Opposite way
                    rotY += 2.0f;
                    break;
                case 122:    // z            // Rotates screen on z axis
                    rotZ -= 2.0f;
                    break;
                case 90:    // Z            // Opposite way
                    rotZ += 2.0f;
                    break;

                // j,J,k,K,l,L uses the gluLookAt function for navigation
                case 106:   // j
                    rotLx -= 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 74:    // J
                    rotLx += 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 107:   // k
                    rotLy -= 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 75:    // K
                    rotLy += 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 108: // (l) It has a special case when the rotLZ becomes 
                          // less than -15 the screen is viewed from the opposite side
                    // therefore this if statement below does not allow 
                    // rotLz be less than -15
                    if (rotLz + 14 >= 0)
                        rotLz -= 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 76:    // L
                    rotLz += 2.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0 + rotLz, 
                        0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                    break;
                case 98:    // b        // Rotates on x axis by -90 degree
                    rotX -= 90.0f;
                    break;
                case 66:    // B        // Rotates on y axis by 90 degree
                    rotX += 90.0f;
                    break;
                case 110:    // n        // Rotates on y axis by -90 degree
                    rotY -= 90.0f;
                    break;
                case 78:    // N        // Rotates on y axis by 90 degree
                    rotY += 90.0f;
                    break;
                case 109:    // m        // Rotates on z axis by -90 degree
                    rotZ -= 90.0f;
                    break;
                case 77:    // M        // Rotates on z axis by 90 degree
                    rotZ += 90.0f;
                    break;
                case 111:    // o        // Resets all parameters
                case 80:    // O        // Displays the cube in the starting position
                    rotation = false;
                    X = Y = 0.0f;
                    Z = 0.0f;
                    rotX = 0.0f;
                    rotY = 0.0f;
                    rotZ = 0.0f;
                    rotLx = 0.0f;
                    rotLy = 0.0f;
                    rotLz = 0.0f;
                    Gl.glMatrixMode(Gl.GL_MODELVIEW);
                    Gl.glLoadIdentity();
                    Glu.gluLookAt(rotLx, rotLy, 15.0f + rotLz, 
                        0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
                    break;
            }
            Glut.glutPostRedisplay();    // Redraw the scene
        }

        // Called on special key pressed
        private static void specialKey(int key, int x, int y)
        {
            // Check which key is pressed
            switch (key)
            {
                case Glut.GLUT_KEY_LEFT:    // Rotate on x axis
                    X -= 2.0f;
                    break;
                case Glut.GLUT_KEY_RIGHT:    // Rotate on x axis (opposite)
                    X += 2.0f;
                    break;
                case Glut.GLUT_KEY_UP:        // Rotate on y axis 
                    Y += 2.0f;
                    break;
                case Glut.GLUT_KEY_DOWN:    // Rotate on y axis (opposite)
                    Y -= 2.0f;
                    break;
                case Glut.GLUT_KEY_PAGE_UP:  // Rotate on z axis
                    Z -= 2.0f;
                    break;
                case Glut.GLUT_KEY_PAGE_DOWN:// Rotate on z axis (opposite)
                    Z += 2.0f;
                    break;
                case Glut.GLUT_KEY_F1:      // Enable/Disable coordinate lines
                    lines = !lines;
                    break;
                case Glut.GLUT_KEY_F2:      // Enable/Disable automatic rotation
                    rotation = !rotation;
                    break;
                default:
                    break;
            }
            Glut.glutPostRedisplay();        // Redraw the scene
        }

        // Capture the mouse click event 
        static void processMouseActiveMotion(int button, int state, int x, int y)
        {
            mousePressed = button;          // Capture which mouse button is down
            old_x = x;                      // Capture the x value
            old_y = y;                      // Capture the y value
        }

        // Translate the x,y windows coordinates to OpenGL coordinates
        static void processMouse(int x, int y)
        {
            if ((mousePressed == 0))    // If left mouse button is pressed
            {
                X = (x - old_x) / 15;       // I did divide by 15 to adjust 
                                            // for a nice translation 
                Y = -(y - old_y) / 15;
            }

            Glut.glutPostRedisplay();
        }

        // Get the mouse wheel direction
        static void processMouseWheel(int wheel, int direction, int x, int y)
        {

            Z += direction;  // Adjust the Z value 

            Glut.glutPostRedisplay();
        }

        // Main Starts
        static void Main(string[] args)
        {
            Glut.glutInit();        // Initialize glut
            // Setup display mode to double buffer and RGB color
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_RGB);  
            // Set the screen size
            Glut.glutInitWindowSize(600, 600);                                        
            Glut.glutCreateWindow("OpenGL 3D Navigation Program With Tao");
            init();
            Glut.glutReshapeFunc(reshape);
            Glut.glutDisplayFunc(drawings);
            // Set window's key callback
            Glut.glutKeyboardFunc(new Glut.KeyboardCallback(keyboard));  
            // Set window's to specialKey callback   
            Glut.glutSpecialFunc(new Glut.SpecialCallback(specialKey));  
             // Set window's to Mouse callback
           Glut.glutMouseFunc(new Glut.MouseCallback(processMouseActiveMotion));   
            // Set window's to motion callback
            Glut.glutMotionFunc(new Glut.MotionCallback(processMouse));             
            // Set window's to mouse motion callback
            Glut.glutMouseWheelFunc(new Glut.MouseWheelCallback(processMouseWheel));
            Glut.glutMainLoop();
        }
    }
}

历史

  • 2008年2月20日:初始发布
© . All rights reserved.