带有OpenTK包装器的OpenGL无法使投影正常工作 [英] OpenGL with OpenTK wrapper cannot get projections to work

查看:102
本文介绍了带有OpenTK包装器的OpenGL无法使投影正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个简单的程序,该程序可以创建一个多维数据集并使它的后平面成圆周运动.

I have created a simple program that creates a cube and makes its rear plane move in a circle.

当我使用GL.Ortho()进行查看时,它可以正常工作,我可以看到该多维数据集,但是我相信GL.Ortho()用于2D投影,并且我想制作3D游戏,因此我继续尝试投影矩阵.到目前为止,这是我的代码:

When i use GL.Ortho() to view it it works fine, I can see the cube but to my belief GL.Ortho() is for 2D projections and i want to make a 3D game, so I've moved on to attempting projection matrices. Heres my code so far:

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shifted
{
    class Program
    {
        public static double Offset = 0;
        public static Vector3 m_eye;
        public static Vector3 m_target;
        static void Main(string[] args)
        {
            using (GameWindow window = new GameWindow())
            {
                window.Load += (sender, e) =>
                {
                    //Vertical Sync on or off
                    window.VSync = VSyncMode.On;
                    //Set window title
                    window.Title = "Test";
                    //set the "clear color", the colour displayed when nothing is drawn and were looking to infinity
                    GL.ClearColor(Color4.Black);
                    //Set the viewport to match the screen width/height
                    GL.Viewport(0, 0, window.Width, window.Height);

                    m_eye = new Vector3(0, 0, 1f);
                    m_target = new Vector3(0, 0, 0);
                };

                window.Resize += (sender, e) =>
                {
                    //on window resize, resize the viewport. (the "window" were looking into the OpenGL "world" with)
                    GL.Viewport(0, 0, window.Width, window.Height);
                };

                //heres where all game logic should be stored
                window.UpdateFrame += (sender, e) =>
                {
                    Offset += e.Time;
                    KeyboardState keyState = Keyboard.GetState();
                    if (keyState.IsKeyDown(Key.W))
                    {
                        m_eye = m_eye + new Vector3(0f, 0f, .1f);
                        m_target = m_target + new Vector3(0f, 0f, .1f);
                    }
                    if (keyState.IsKeyDown(Key.S))
                    {
                        m_eye = m_eye - new Vector3(0f, 0f, .1f);
                        m_target = m_target - new Vector3(0f, 0f, .1f);
                    }
                    Console.WriteLine(m_eye);
                };

                //heres where everything that draws should go
                window.RenderFrame += (sender, e) =>
                {
                    //Clear the buffer to draw a fresh image
                    GL.Enable(EnableCap.DepthTest);
                    GL.DepthFunc(DepthFunction.Less);
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    //Set draw mode to lines (wiremesh)
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);

                    //GL.LoadIdentity();
                    //GL.Ortho(0.0f, window.Width, 0.0f, window.Height, 0.0f, 1000.0f);
                    GL.MatrixMode(MatrixMode.Projection);
                    GL.LoadIdentity();
                    Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)window.Width / (float)window.Height, 0.1f, 100f);
                    GL.LoadMatrix(ref perspective);
                    GL.MatrixMode(MatrixMode.Modelview);
                    GL.LoadIdentity();
                    Matrix4 lookat = Matrix4.LookAt(m_eye,m_target,Vector3.UnitY);
                    GL.LoadMatrix(ref lookat);
                    GL.LoadIdentity();
                    //Set what colour to draw in
                    GL.Translate(-m_eye);
                    GL.Color3(1.0f, 1.0f, 1.0f);
                    //8 Vertices for a cube
                    double[] vertices = new double[]{100,100,0,
                                                     100,200,0,
                                                     200,200,0,
                                                     200,100,0,
                                                     200+(Math.Sin(Offset)*10),100+(Math.Cos(Offset)*10),-100,
                                                     200+(Math.Sin(Offset)*10),200+(Math.Cos(Offset)*10),-100,
                                                     100+(Math.Sin(Offset)*10),200+(Math.Cos(Offset)*10),-100,
                                                     100+(Math.Sin(Offset)*10),100+(Math.Cos(Offset)*10),-100};
                    //Indice order to draw the cube in, shouldnt have to call this every frame but whatever for now
                    byte[] indices = new byte[] { 0, 1, 2, 2, 3, 0, 2, 3, 4, 4, 5, 2, 2, 1, 6, 6, 5, 2, 0, 1, 7, 7, 6, 1, 7, 6, 5, 5, 4, 7 };
                    //Enable the use of vertex arrays
                    GL.EnableClientState(ArrayCap.VertexArray);
                    //Tell it where to find the vertices
                    GL.Translate(m_eye.X * -1, m_eye.Y * -1, m_eye.Z * -1);
                    GL.VertexPointer(3, VertexPointerType.Double, 0, vertices);
                    //Draw them
                    GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedByte, indices);
                    //Flush it to the buffer
                    GL.Flush();
                    //swap the back buffer we're drawing to to be the front buffer thats displayed
                    window.SwapBuffers();
                };
                //Run at X frames per second. Null = 60 FPS, 200 = no cap, anything in between = that cap.
                window.Run(200);
            }
        }
    }
}

当我移除

GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)window.Width / (float)window.Height, 0.1f, 100f);
GL.LoadMatrix(ref perspective);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
Matrix4 lookat = Matrix4.LookAt(m_eye,m_target,Vector3.UnitY);
GL.LoadMatrix(ref lookat);
GL.LoadIdentity();

并替换为

GL.Ortho(0.0f, window.Width, 0.0f, window.Height, 0.0f, 1000.0f);

它可以很好地渲染,但是如果我尝试使用矩阵,我只会得到一个黑色的窗口.

it renders fine, but if i try and use the matrices I just get a black window.

我在做什么错了?

推荐答案

问题是您没有正确设置矩阵.

The problem is that you are not setting up the matrices correctly.

首先在以下位置声明这些变量:

First declare these variables somewhere:

private Matrix4 projectionMatrix;
private Matrix4 modelViewMatrix;
private Vector3 cameraPosition;
private Vector3 cameraTarget;
private Vector3 cameraUp = Vector3.UnitY; // which way is up for the camera

然后使用以下功能控制您的基本相机:

And then use these functions to control your basic camera:

private void SetPerspectiveProjection (int width, int height, float FOV)
{
    projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * (FOV/180f), width / (float)height, 0.2f, 256.0f);
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadMatrix(ref projectionMatrix); // this replaces the old matrix, no need for GL.LoadIdentity()
}

private void SetOrthographicProjection ()
{
    projectionMatrix = Matrix4.Identity;
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadIdentity(); // reset matrix
    GL.Ortho (-1f, 1f, -1f, 1f, 1000f, -1000f);
}

private void SetLookAtCamera(Vector3 position, Vector3 target, Vector3 up)
{
    modelViewMatrix = Matrix4.LookAt(position, target, up);
    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadMatrix(ref modelViewMatrix);
}

最后,在绘制任何东西之前:

Finally, before drawing anything:

SetPerspectiveProjection(viewWidth, viewHeight, 45); // 45 is in degrees
SetLookAtCamera(cameraPosition, cameraTarget, cameraUp);

// draw 3D models here

SetOrthographicProjection();

// draw user interface elements here

这篇关于带有OpenTK包装器的OpenGL无法使投影正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆