按键导致图像停止移动

本文关键字:移动 图像 | 更新日期: 2023-09-27 18:03:14

我有一个基于Giawa教程1-5的OpenGl程序。基本上我创建一个图像,显示在屏幕上,并使其旋转。我想要完成的就是添加键盘事件来改变图像的某些参数。例如,在我的代码中,我想按F6使图像旋转得更快:

using System;
using Tao.FreeGlut;
using OpenGL;
using System;
using System.Windows;
using System.Windows.Forms;
namespace OpenGLTutorial5
{
    class Program
    {
        private static int width = 640, height = 480;
        private static ShaderProgram program;
        private static VBO<Vector3> top_pyramid, cube, bottom_pyramid;
        private static VBO<Vector3> top_pyramidColor, cubeColor, bottom_pyramidColor;
        private static VBO<int> top_pyramidElements, cubeElements, bottom_pyramidElements;
        private static System.Diagnostics.Stopwatch watch;
        private static float angle;
        private static int rotate = 1;
        static void Main(string[] args)
        {
            // create an OpenGL window
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Glut.glutInitWindowSize(width, height);
            Glut.glutCreateWindow("OpenGL Tutorial");
            // provide the Glut callbacks that are necessary for running this tutorial
            Glut.glutIdleFunc(OnRenderFrame);
            Glut.glutDisplayFunc(OnDisplay);
           // Glut.glutKeyboardFunc(new Glut.KeyboardCallback(OnKeyPress));
            Glut.glutSpecialFunc(new Glut.SpecialCallback(OnKeyPress));
            Glut.glutCloseFunc(OnClose);
            // enable depth testing to ensure correct z-ordering of our fragments
            Gl.Enable(EnableCap.DepthTest);
            // compile the shader program
            program = new ShaderProgram(VertexShader, FragmentShader);
            // set the view and projection matrix, which are static throughout this tutorial
            program.Use();
            program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
            program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(10, 0, 10), Vector3.Zero, Vector3.Up));

            top_pyramid = new VBO<Vector3>(new Vector3[] 
            {
                new Vector3(-1.5, 0, -0.5), new Vector3(-0.5, 1, -0.5), new Vector3(0, 0, -1.5),
                new Vector3(-0.5, 1, -0.5), new Vector3(0.5, 1, -0.5), new Vector3(0, 0, -1.5),
                new Vector3(0.5, 1, -0.5), new Vector3(1.5, 0, -0.5), new Vector3(0, 0, -1.5),
                new Vector3(1.5, 0, -0.5), new Vector3(0.5, -1, -0.5), new Vector3(0, 0, -1.5),
                new Vector3(0.5, -1, -0.5), new Vector3(-0.5, -1, -0.5), new Vector3(0, 0, -1.5),
                new Vector3(-0.5, -1, -0.5), new Vector3(-1.5, 0, -0.5), new Vector3(0, 0, -1.5)
            });
            cube = new VBO<Vector3>(new Vector3[]
            {
                new Vector3(-1.5, 0, -0.5), new Vector3(-0.5, 1, -0.5), new Vector3(-0.5, 1, 0.5), new Vector3(-1.5, 0, 0.5),
                new Vector3(-0.5, 1, -0.5), new Vector3(0.5, 1, -0.5), new Vector3(0.5, 1, 0.5), new Vector3(-0.5, 1, 0.5),
                new Vector3(0.5, 1, -0.5), new Vector3(1.5, 0, -0.5), new Vector3(1.5, 0, 0.5), new Vector3(0.5, 1, 0.5),
                new Vector3(1.5, 0, -0.5), new Vector3(1.5, 0, 0.5), new Vector3(0.5, -1, 0.5), new Vector3(0.5, -1, -0.5),
                new Vector3(0.5, -1, 0.5), new Vector3(0.5, -1, -0.5), new Vector3(-0.5, -1, -0.5), new Vector3(-0.5, -1, 0.5),
                new Vector3(-0.5, -1, -0.5), new Vector3(-0.5, -1, 0.5), new Vector3(-1.5, 0, 0.5), new Vector3(-1.5, 0, -0.5)
             });

            bottom_pyramid = new VBO<Vector3>(new Vector3[]
            {
                new Vector3(-1.5, 0, 0.5), new Vector3(-0.5, 1, 0.5), new Vector3(0, 0, 1.5),
                new Vector3(-0.5, 1, 0.5), new Vector3(0.5, 1, 0.5), new Vector3(0, 0, 1.5),
                new Vector3(0.5, 1, 0.5), new Vector3(1.5, 0, 0.5), new Vector3(0, 0, 1.5),
                new Vector3(1.5, 0, 0.5), new Vector3(0.5, -1, 0.5), new Vector3(0, 0, 1.5),
                new Vector3(0.5, -1, 0.5), new Vector3(-0.5, -1, 0.5), new Vector3(0, 0, 1.5),
                new Vector3(-0.5, -1, 0.5), new Vector3(-1.5, 0, 0.5), new Vector3(0, 0, 1.5)
            });
            top_pyramidColor = new VBO<Vector3>(new Vector3[] 
            {
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), 
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), 
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), 
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), 
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), 
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0)
            });
            cubeColor = new VBO<Vector3>(new Vector3[]
            {
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
                new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0,0,1),
            });
            bottom_pyramidColor = new VBO<Vector3>(new Vector3[]
            {
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0), 
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0), 
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0), 
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0), 
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0), 
                new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(1, 1, 0)
            });
            top_pyramidElements = new VBO<int>(new int[] { 
                0,1,2, 
                3,4,5,
                6,7,8,
                9,10,11,
                12,13,14, 
                15,16,17}, BufferTarget.ElementArrayBuffer);
            cubeElements = new VBO<int>(new int[]{
                0,1,2,3,
                4,5,6,7,
                8,9,10,11,
                12,13,14,15,
                16,17,18,19,
                20,21,22,23}, BufferTarget.ElementArrayBuffer);
            bottom_pyramidElements = new VBO<int>(new int[] { 
                0,1,2, 
                3,4,5,
                6,7,8,
                9,10,11,
                12,13,14, 
                15,16,17}, BufferTarget.ElementArrayBuffer);
            watch = System.Diagnostics.Stopwatch.StartNew();
            Glut.glutMainLoop();
        }

        public static void OnKeyPress(int theKey, int x, int y)
        {
            switch (theKey)
            {
                case Glut.GLUT_KEY_F6:
                    {
                        rotate += 3;
                        Console.WriteLine("Hallo!");
                        Console.ReadLine();
                    }
                   break;
            }   
            Glut.glutPostRedisplay();
        }
        private static void OnClose()
        {
            top_pyramid.Dispose();
            top_pyramidColor.Dispose();
            top_pyramidElements.Dispose();
           program.DisposeChildren = true;
           program.Dispose();
        }
        private static void OnDisplay()
        {
        }
        private static void OnRenderFrame()
        {
           // calculate how much time has elapsed since the last frame
           watch.Stop();
           float deltaTime = (float)watch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency;
           watch.Restart();
           // use the deltaTime to adjust the angle of the cube and pyramid
           angle += deltaTime;

            // set up the OpenGL viewport and clear both the color and depth bits
            Gl.Viewport(0, 0, width, height);
            Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            // use our shader program
            Gl.UseProgram(program);
           //top pyramid
            program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate) * Matrix4.CreateTranslation(new Vector3(0.0f, 0, 1)));
           Gl.BindBufferToShaderAttribute(top_pyramid, program, "vertexPosition");
           Gl.BindBufferToShaderAttribute(top_pyramidColor, program, "vertexColor");
           Gl.BindBuffer(top_pyramidElements);
           //top pyramid
           Gl.DrawElements(BeginMode.Triangles, top_pyramidElements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
           //cubes
           program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate) * Matrix4.CreateTranslation(new Vector3(0.0f, 0, 1)));
           Gl.BindBufferToShaderAttribute(cube, program, "vertexPosition");
           Gl.BindBufferToShaderAttribute(cubeColor, program, "vertexColor");
           Gl.BindBuffer(cubeElements);
           //cubes
           Gl.DrawElements(BeginMode.Quads, cubeElements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
           //bottom pyramid
           program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate) * Matrix4.CreateTranslation(new Vector3(0.0f, 0, 1)));
           Gl.BindBufferToShaderAttribute(bottom_pyramid, program, "vertexPosition");
           Gl.BindBufferToShaderAttribute(bottom_pyramidColor, program, "vertexColor");
           Gl.BindBuffer(bottom_pyramidElements);
           //top pyramid
           Gl.DrawElements(BeginMode.Triangles, bottom_pyramidElements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
            Glut.glutSwapBuffers();
        }
        public static string VertexShader = @"
#version 130
in vec3 vertexPosition;
in vec3 vertexColor;
out vec3 color;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(void)
{
    color = vertexColor;
    gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
        public static string FragmentShader = @"
#version 130
in vec3 color;
out vec4 fragment;
void main(void)
{
    fragment = vec4(color, 1);
}
";
    }
}

图像显示正确,但是当我按下F6图像停止旋转。对如何解决这个问题有什么想法吗?

按键导致图像停止移动

我怀疑你的问题与OpenGL无关。看看F6键的处理程序,它有以下代码:

rotate += 3;
Console.WriteLine("Hallo!");
Console.ReadLine();

这些行的最后一行等待您在标准输入中输入文本。我相信它会阻塞,直到你输入一些东西。取出ReadLine()调用,看看是否解决了问题。