Nikhil Malhotra's picture

Required a 3D cube in winforms c sharp which rotates along x and y axis with mouse drag.

Project:The Open Toolkit library
Version:all versions
Component:Miscellaneous
Category:support request
Priority:critical
Assigned:Unassigned
Status:closed (invalid)
Description

hi All,
please help i am new to 3d world. i want to draw a cube in 3d which i can rotate along x and y axis with mouse drag. i.e. if mouse is dragged from left to right cube should rotate counter clockwise around y axis and if mouse is dragged from top to bottom then cube should rotate along x axis.
And i tried simply GL.Rotate() but i am not able to predict rotation its weird.
i read something about QUATERNION as well. but, was not successful.
If any one please give suggestions for implementation of QUATERNIONS or anything better i'll be very thankful.
i am new to 3d so, a little explained suggestion will be best.
Thanks a lot.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
migueltk's picture

#1

Try this.

Program.cs

using System;
using System.Collections.Generic;
 
using OpenTK.Graphics;
 
namespace OtkTemplate
{
	/// <summary>
	/// Class with program entry point.
	/// </summary>
	internal sealed class Program
	{
		/// <summary>
		/// Program entry point.
		/// </summary>
		[STAThread]
		private static void Main(string[] args)
		{
            var aa_modes = new List<int>();
            int aa = 0;
            do
            {
                var mode = new GraphicsMode(32, 0, 0, aa);
                if (!aa_modes.Contains(mode.Samples))
                    aa_modes.Add(aa);
                aa += 2;
            } while (aa <= 32);
 
			using (MainWindow win = new MainWindow(aa_modes[aa_modes.Count-1]))
			{
				win.Run();
			}
		}
 
	}
}

MainWindow.cs

using System;
using System.Drawing;
 
using OpenTK;
using OpenTK.Input;
using OpenTK.Graphics.OpenGL;
 
namespace OtkTemplate
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public class MainWindow : GameWindow
    {
        static float CAMERA_FOVY = 45.0f;
        static float CAMERA_ZFAR = 1000.0f;
        static float CAMERA_ZNEAR = 0.1f;
 
        static float MOUSE_ORBIT_SPEED = 0.30f;     // 0 = SLOWEST, 1 = FASTEST
        static float MOUSE_DOLLY_SPEED = 0.02f;     // same as above...but much more sensitive
        static float MOUSE_TRACK_SPEED = 0.005f;    // same as above...but much more sensitive
 
        float g_heading;
        float g_pitch;
        float dx = 0.0f;
        float dy = 0.0f;
        ECameraMode camera_mode = ECameraMode.CAMERA_NONE;
 
        public static bool Available_VBO_IBO = false;
        public static bool Available_GLSL = false;
 
        Point mouse_previous = new Point();
        Point mouse_current = new Point();
        float[] g_cameraPos = new float[3];
        float[] g_targetPos = new float[3];
 
        public MainWindow(int samples)
            : base(800, 600, new OpenTK.Graphics.GraphicsMode(32, 16, 0, samples))
        {
            Title = "OpenTK 3D Template";
 
            this.VSync = OpenTK.VSyncMode.On;
            Keyboard.KeyDown += new EventHandler<KeyboardKeyEventArgs>(Keyboard_KeyDown);
 
            var VersionOpenGL = GL.GetString(StringName.Version);
            var MajorOpenGLVersion = int.Parse(VersionOpenGL[0].ToString());
            var MinorOpenGLVersion = int.Parse(VersionOpenGL[2].ToString());
            //MajorOpenGLVersion = 1;
            //MinorOpenGLVersion = 4;
 
            if (MajorOpenGLVersion == 1 && MinorOpenGLVersion < 4)
                throw new Exception("Trixion necesita para funcionar OpenGL 1.4 o superior");
 
            if (MajorOpenGLVersion > 1 || (MajorOpenGLVersion == 1 && MinorOpenGLVersion >= 5))
                Available_VBO_IBO = true;
            Available_GLSL = MajorOpenGLVersion >= 2;
 
            Mouse.ButtonDown += new EventHandler<MouseButtonEventArgs>(Mouse_ButtonDown);
            Mouse.ButtonUp += new EventHandler<MouseButtonEventArgs>(Mouse_ButtonUp);
            Mouse.Move += new EventHandler<MouseMoveEventArgs>(Mouse_Move);
 
            ResetCamera();
 
            GL.Enable(EnableCap.DepthTest); // Está desactivado por defecto en OpenGL
            GL.Enable(EnableCap.CullFace); // Está desactivado por defecto en OpenGL
            GL.Enable(EnableCap.Lighting);
            GL.Enable(EnableCap.Light0);
            GL.Enable(EnableCap.ColorMaterial);
        }
 
        void Mouse_Move(object sender, MouseMoveEventArgs e)
        {
            mouse_current.X = Mouse.X;
            mouse_current.Y = Mouse.Y;
 
            // Now use mouse_delta to move the camera
 
            switch (camera_mode)
            {
                case ECameraMode.CAMERA_TRACK:
                    dx = mouse_current.X - mouse_previous.X;
                    dx *= MOUSE_TRACK_SPEED;
 
                    dy = mouse_current.Y - mouse_previous.Y;
                    dy *= MOUSE_TRACK_SPEED;
 
                    g_cameraPos[0] -= dx;
                    g_cameraPos[1] += dy;
 
                    g_targetPos[0] -= dx;
                    g_targetPos[1] += dy;
 
                    break;
 
                case ECameraMode.CAMERA_DOLLY:
                    dy = mouse_current.Y - mouse_previous.Y;
                    dy *= MOUSE_DOLLY_SPEED;
 
                    g_cameraPos[2] -= dy;
 
                    if (g_cameraPos[2] < 1 + CAMERA_ZNEAR)
                        g_cameraPos[2] = 1 + CAMERA_ZNEAR;
 
                    if (g_cameraPos[2] > CAMERA_ZFAR - 10)
                        g_cameraPos[2] = CAMERA_ZFAR - 10;
 
                    break;
 
                case ECameraMode.CAMERA_ORBIT:
                    dx = mouse_current.X - mouse_previous.X;
                    dx *= MOUSE_ORBIT_SPEED;
 
                    dy = mouse_current.Y - mouse_previous.Y;
                    dy *= MOUSE_ORBIT_SPEED;
 
                    g_heading += dx;
                    g_pitch += dy;
 
                    if (g_pitch > 90.0f)
                        g_pitch = 90.0f;
 
                    if (g_pitch < -90.0f)
                        g_pitch = -90.0f;
 
                    break;
            }
            mouse_previous.X = mouse_current.X;
            mouse_previous.Y = mouse_current.Y;
        }
 
        void Mouse_ButtonUp(object sender, MouseButtonEventArgs e)
        {
            camera_mode = ECameraMode.CAMERA_NONE;
        }
 
        void Mouse_ButtonDown(object sender, MouseButtonEventArgs e)
        {
            switch (e.Button)
            {
                case MouseButton.Left:
                    camera_mode = ECameraMode.CAMERA_TRACK;
                    break;
                case MouseButton.Middle:
                    camera_mode = ECameraMode.CAMERA_DOLLY;
                    break;
                case MouseButton.Right:
                    camera_mode = ECameraMode.CAMERA_ORBIT;
                    break;
            }
            mouse_previous.X = Mouse.X;
            mouse_previous.Y = Mouse.Y;
        }
        void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    Close();
                    break;
            }
        }
 
        #region Glu
 
        internal void gluPerspective(double fovy, double aspect, double zNear, double zFar)
        {
            double xmin, xmax, ymin, ymax;
 
            ymax = zNear * Math.Tan(fovy * Math.PI / 360.0);
            ymin = -ymax;
 
            xmin = ymin * aspect;
            xmax = ymax * aspect;
 
            GL.Frustum(xmin, xmax, ymin, ymax, zNear, zFar);
        }
 
        Vector3 forward = new Vector3();
        Vector3 up = new Vector3();
        Vector3 right = new Vector3();
 
        /// <summary>
        /// From Mesa Lib
        /// </summary>
        /// <param textureFileName="eyex">Posición X de la cámara</param>
        /// <param textureFileName="eyey">Posición Y de la cámara</param>
        /// <param textureFileName="eyez">Posición Z de la cámara</param>
        /// <param textureFileName="centerx">Posición X a donde mira la cámara</param>
        /// <param textureFileName="centery">Posición Y a donde mira la cámara</param>
        /// <param textureFileName="centerz">Posición Z a donde mira la cámara</param>
        /// <param textureFileName="upx"></param>
        /// <param textureFileName="upy"></param>
        /// <param textureFileName="upz"></param>
        void gluLookAt(float eyex, float eyey, float eyez,
                       float centerx, float centery, float centerz,
                       float upx, float upy, float upz)
        {
            float[] m = new float[16];
 
            forward.X = centerx - eyex;
            forward.Y = centery - eyey;
            forward.Z = centerz - eyez;
 
            up.X = upx;
            up.Y = upy;
            up.Z = upz;
 
            forward.Normalize();
 
            /* Side = tForward x tUp */
            Vector3.Cross(ref forward, ref up, out right);
            right.Normalize();
 
            /* Recompute tUp as: tUp = tRight x tForward */
            Vector3.Cross(ref right, ref forward, out up);
 
            // set right vector
            m[0] = right.X; m[1] = up.X; m[2] = -forward.X; m[3] = 0;
            // set up vector
            m[4] = right.Y; m[5] = up.Y; m[6] = -forward.Y; m[7] = 0;
            // set forward vector
            m[8] = right.Z; m[9] = up.Z; m[10] = -forward.Z; m[11] = 0;
            // set translation vector
            m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
 
            GL.MultMatrix(m);
            GL.Translate(-eyex, -eyey, -eyez);
        }
        #endregion Glu
 
        #region override OnXXX()
 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
        protected override void OnResize(EventArgs e)
        {
            if (Width != 0 && Height != 0)
            {
                GL.Viewport(0, 0, Width, Height);
                double aspectRatio = Width / (double)Height;
 
                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();
 
                gluPerspective(CAMERA_FOVY, aspectRatio, CAMERA_ZNEAR, CAMERA_ZFAR);
            }
        }
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);
 
        }
 
        #region private void DrawCube()
 
        private void DrawCube()
        {
            GL.Begin(BeginMode.Quads);
 
            GL.Color3(Color.Silver);
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
 
            GL.Color3(Color.Honeydew);
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
 
            GL.Color3(Color.Moccasin);
 
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
 
            GL.Color3(Color.IndianRed);
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
 
            GL.Color3(Color.PaleVioletRed);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
 
            GL.Color3(Color.ForestGreen);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
 
            GL.End();
        }
 
        #endregion
 
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.ClearColor(0.3f, 0.5f, 0.9f, 0.0f);
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
 
            gluLookAt(g_cameraPos[0], g_cameraPos[1], g_cameraPos[2],
                      g_targetPos[0], g_targetPos[1], g_targetPos[2],
                      0.0f, 1.0f, 0.0f);
 
            GL.Rotate(g_pitch, 1.0f, 0.0f, 0.0f);
            GL.Rotate(g_heading, 0.0f, 1.0f, 0.0f);
 
            GL.Disable(EnableCap.Lighting);
            DrawCube();
 
            SwapBuffers();
        }
 
        protected override void OnDisposed(EventArgs e)
        {
            base.OnDisposed(e);
        }
        #endregion override OnXXX()
 
        void ResetCamera()
        {
            g_targetPos[0] = 0; g_targetPos[1] = 0; g_targetPos[2] = 0;
 
            g_cameraPos[0] = g_targetPos[0];
            g_cameraPos[1] = g_targetPos[1];
            g_cameraPos[2] = g_targetPos[2] + 10 + CAMERA_ZNEAR + 0.4f;
 
            g_pitch = 0.0f;
            g_heading = 0.0f;
        }
    }
    enum ECameraMode
    {
        CAMERA_NONE, CAMERA_TRACK, CAMERA_DOLLY, CAMERA_ORBIT
    }
}
account_deleted's picture

#2

Component:Code» Miscellaneous
Category:task» support request
Status:open» closed (invalid)

Basic questions should go to the forums, not issue reporting.