在OpenGL(OpenTK)中将2D相机旋转到太空船的航向

时间:2016-07-12 23:34:28

标签: opengl box2d opentk

该游戏是一款自上而下的2D太空飞船游戏 - 想想“小行星”。

Box2Dx是物理引擎,我扩展了包含的基于OpenTK的DebugDraw,以绘制其他游戏对象。移动相机,使其始终以玩家的船为中心,完美地放大和缩小工作。但是,我真的需要相机随着船一起旋转,所以它总是面向同一个方向。也就是说,船舶将在屏幕中心处冻结,并且游戏世界的其余部分在转动时围绕它旋转。

我尝试过修改代码示例,但没有任何作用。我能够实现的最好的是歪曲和截止渲染。

渲染循环:

        // Clear.
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

        // other rendering omitted (planets, ships, etc.)

        this.OpenGlControl.Draw();

更新视图 - 船舶中心和旋转以匹配其角度。现在,我只是试图以任意角度旋转它以进行概念验证,但没有骰子:

    public void RefreshView()
    {
        int width = this.OpenGlControl.Width;
        int height = this.OpenGlControl.Height;

        Gl.glViewport(0, 0, width, height);

        Gl.glMatrixMode(Gl.GL_PROJECTION);
        Gl.glLoadIdentity();

        float ratio = (float)width / (float)height;

        Vec2 extents = new Vec2(ratio * 25.0f, 25.0f);
        extents *= viewZoom;

        // rotate the view
        var shipAngle = 180.0f; // just a test angle for proof of concept
        Gl.glRotatef(shipAngle, 0, 0, 0);

        Vec2 lower = this.viewCenter - extents;
        Vec2 upper = this.viewCenter + extents;

        // L/R/B/T
        Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y);

        Gl.glMatrixMode(Gl.GL_MODELVIEW);
    }

现在,我显然做错了。 0度和180度将保持正面向上或翻转,但任何其他度数实际上会放大/缩小或仅导致黑度,没有任何渲染。以下是示例:

如果出货角度为0.0f,则游戏世界符合预期: enter image description here

度数为180.0f垂直翻转......看起来很有希望: enter image description here

45度变焦并且根本不旋转......这很奇怪: enter image description here

90度返回全黑。如果您从未见过黑色: enter image description here

请帮忙!

1 个答案:

答案 0 :(得分:0)

首先,2-4个参数是轴,所以请按照@pingul的说明正确说明。

更重要的是,旋转应用于投影矩阵。

    // L/R/B/T
    Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y);

在此行中,您的正交2D投影矩阵将与之前的旋转相乘并应用于投影矩阵。我相信这不是你想要的。

解决方案是在选择模型视图矩阵模式后将旋转调用移动到某个位置,如下所示

    // L/R/B/T
    Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y);

    Gl.glMatrixMode(Gl.GL_MODELVIEW);

    // rotate the view
    var shipAngle = 180.0f; // just a test angle for proof of concept
    Gl.glRotatef(shipAngle, 0.0f, 0.0f, 1.0f);

现在您的旋转将应用于模型视图矩阵堆栈。 (我相信这是你想要的效果)。请记住,glRotatef()会创建一个旋转矩阵,并将其与所选堆栈顶部的矩阵相乘。

如果可能的话,我也强烈建议你按照@BDL的建议离开固定功能管道。