0

如何向绘制的四边形添加轨迹球效果?

在此示例中,创建了一个 Cube 并添加了运行良好的轨迹球效果。

//  Create a sphere.
Cube cube = new Cube();
cube.AddEffect(arcBallEffect);

//  Add it.
sceneControl1.Scene.SceneContainer.AddChild(cube);

这是完整的代码,我想要的是在drawCube函数内部绘制的四边形添加一个轨迹球效果。

public partial class SharpGLForm : Form
{
    private double max_dimension = 100;

    /// <summary>
    /// The current rotation.
    /// </summary>
    private float rotation = 0.0f;
    private ArcBallEffect arcBallEffect = new ArcBallEffect();
    /// <summary>
    /// Initializes a new instance of the <see cref="SharpGLForm"/> class.
    /// </summary>
    public SharpGLForm()
    {
        InitializeComponent();
        sceneControl1.MouseDown += new MouseEventHandler(FormSceneSample_MouseDown);
        sceneControl1.MouseMove += new MouseEventHandler(FormSceneSample_MouseMove);
        sceneControl1.MouseUp += new MouseEventHandler(openGLControl_MouseUp);

        //  Add some design-time primitives.
        sceneControl1.Scene.SceneContainer.AddChild(new
            SharpGL.SceneGraph.Primitives.Grid());
        sceneControl1.Scene.SceneContainer.AddChild(new
            SharpGL.SceneGraph.Primitives.Axies());

        //  Create a light.
        Light light = new Light()
        {
            On = true,
            Position = new Vertex(3, 10, 3),
            GLCode = OpenGL.GL_LIGHT0
        };

        //  Add the light.
        //sceneControl1.Scene.SceneContainer.AddChild(light);

        //  Create a sphere.
        Cube cube = new Cube();
        cube.AddEffect(arcBallEffect);

        //  Add it.
        sceneControl1.Scene.SceneContainer.AddChild(cube);

    }

    void FormSceneSample_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            arcBallEffect.ArcBall.MouseMove(e.X, e.Y);
        }
    }

    void FormSceneSample_MouseDown(object sender, MouseEventArgs e)
    {
        arcBallEffect.ArcBall.SetBounds(sceneControl1.Width, sceneControl1.Height);
        arcBallEffect.ArcBall.MouseDown(e.X, e.Y);
    }

    /// <summary>
    /// Handles the OpenGLDraw event of the openGLControl control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="RenderEventArgs"/> instance containing the event data.</param>
    private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
    {
        //  Get the OpenGL object.
        OpenGL gl = sceneControl1.OpenGL;

        //  Clear the color and depth buffer.
        gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

        //  Load the identity matrix.
        gl.LoadIdentity();

        //  Rotate around the Y axis.
        //gl.Rotate(rotation, 0.5f, 0.5f, 0.5f);
        gl.Scale(5f, 5f, 5f); 
        gl.Disable(OpenGL.GL_BLEND);

        //30 100 100
        //0 0 0 50 90 20
        //50 0 0 30 30 10
        //80 0 0 20 20 10
        //50 0 10 10 10 10

        drawCube(100, 100, 30, 0, 0, 0, true); // Draw big box
        drawCube(50, 90, 20, 0, 0, 0, false);
        drawCube(30, 30, 10, 50, 0, 0, true);
        drawCube(20, 20, 10, 80, 0, 0, false);
        drawCube(10, 10, 10, 50, 0, 10, true);

        //drawCube(100, 100,30, 0, 0, 0, true); // Draw big box
        //drawCube(20, 40, 20, 0, 0, 0, false);
        //drawCube(30, 30, 10, 20, 0, 0, true);
        //drawCube(20, 20, 10, 50, 0, 0, false);
        //drawCube(10, 10, 10, 70, 0, 0, true);

        //  Nudge the rotation.
        //rotation += 3.0f;
    }

    private void drawCube(double length, double height, double width, double posX, double posY, double posZ, bool isWireframe)
    {
        OpenGL gl = openGLControl.OpenGL;
        Random r = new Random();
        int range = 255;
        double scaledLength = length / max_dimension;
        double scaledWidth = width / max_dimension;
        double scaledHeight = height / max_dimension;
        double scaledPosX = posZ / max_dimension;
        double scaledPosY = posY / max_dimension;
        double scaledPosZ = posX / max_dimension;

        if (isWireframe)
        {
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_LINE);
        }
        else
        {
            gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL);
            gl.Color(r.NextDouble() * range, r.NextDouble() * range, r.NextDouble() * range);
        }
        gl.Begin(OpenGL.GL_QUADS);

        // Front face
        gl.Vertex(0.0f + scaledPosX, 0.0f + scaledPosY, 0.0f + scaledPosZ);
        gl.Vertex(0.0f + scaledPosX, scaledHeight + scaledPosY, 0.0f + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, 0.0f + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, 0.0f + scaledPosY, 0.0f + scaledPosZ);

        gl.Vertex(0f + scaledPosX, 0.0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, 0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(0f + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);

        //top face
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(0f + scaledPosX, scaledHeight + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(0f + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);

        //bottom face
        gl.Vertex(scaledWidth + scaledPosX, 0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(0f + scaledPosX, 0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(0f + scaledPosX, 0f + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, 0f + scaledPosY, 0f + scaledPosZ);

        //left face
        gl.Vertex(scaledWidth + scaledPosX, 0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, 0f + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(scaledWidth + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);

        //right face
        gl.Vertex(0f + scaledPosX, 0f + scaledPosY, 0f + scaledPosZ);
        gl.Vertex(0f + scaledPosX, 0f + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(0f + scaledPosX, scaledHeight + scaledPosY, scaledLength + scaledPosZ);
        gl.Vertex(0f + scaledPosX, scaledHeight + scaledPosY, 0f + scaledPosZ);

        gl.End();
    }

    /// <summary>
    /// Handles the OpenGLInitialized event of the openGLControl control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
    {
        //  TODO: Initialise OpenGL here.

        //  Get the OpenGL object.
        OpenGL gl = openGLControl.OpenGL;

        //  Set the clear color.
        gl.ClearColor(0, 0, 0, 0);
    }

    /// <summary>
    /// Handles the Resized event of the openGLControl control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void openGLControl_Resized(object sender, EventArgs e)
    {
        //  TODO: Set the projection matrix here.

        //  Get the OpenGL object.
        OpenGL gl = openGLControl.OpenGL;

        //  Set the projection matrix.
        gl.MatrixMode(OpenGL.GL_PROJECTION);

        //  Load the identity.
        gl.LoadIdentity();

        //  Create a perspective transformation.
        gl.Perspective(20.0f, (double)Width / (double)Height, 0.01, 100.0);

        //  Use the 'look at' helper function to position and aim the camera.
        gl.LookAt(-35, 0, 0, 0, 0, 0, 0, 1, 0);

        //  Set the modelview matrix.
        gl.MatrixMode(OpenGL.GL_MODELVIEW);
    }

    private void openGLControl_MouseUp(object sender, MouseEventArgs e)
    {
        arcBallEffect.ArcBall.MouseUp(e.X, e.Y);
    }
}

}

这是这个程序的输出,右边可以旋转,我想在左边应用同样的效果 在此处输入图像描述

4

1 回答 1

0

为了完成这项工作,我添加了 mousemove 监听器并分别更改 x-rotation 和 y-rotation

        void FormSceneSample_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                double deltaDirection_X = currentPositionX - e.X;
                double deltaDirection_Y = currentPositionY - e.Y;
                var direction_X = deltaDirection_X > 0 ? 1 : -1;
                var direction_Y = deltaDirection_Y > 0 ? 1 : -1;

                if (direction_X == 1)
                    xRotation -= 1.0f;
                else
                    xRotation += 1.0f;

                if (direction_Y == 1)
                    yRotation -= 1.0f;
                else
                    yRotation += 1.0f;

                currentPositionX = e.X;
                currentPositionY = e.Y;
            }
        }

在我计算了移动是向右还是向左、顶部或底部之后,新的计算值现在被提供给旋转 API

gl.Rotate(xRotation, 0f, xRotation, yRotation);

输出不是很流畅,我目前正在尝试轨迹球效果

于 2016-10-25T07:26:37.840 回答