文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

自从我开始编写代码以来,我就一直梦想着编写自己的游戏。大多数尝试都是非常基本的命令行,各种2D库,Silverlight等。现在我有2个星期的病假,我买了一本书叫做OpenGL超级宝典(第七版),我试着在一个很适合我的病房里读它。但现在我读的相当慢,因为我真的没有那么多的精力,像午睡比阅读或写作。问题是,书中所有的例子都是用C++编写,但我真的不想用C++,所以找了一圈后,我发现Opentk库,opentk包含基本OpenGL API是让你用从C #编写Opengl。

第 1 段(可获 1.9 积分)

所以,在试图学习OpenGL时,我会尝试写下OpenTK中所作的每一步,希望这一过程能使我学到一点东西。: )

建立一个正在工作的窗口

我想,步骤一应该是建立一个我们可以在上面为所欲为的游戏窗口

我假设你已经知道如何在Visual Studio中新建解决方案和新的项目 :)

在 Visual Studio中, 新建一个窗体项目, 我相信你会做,下面是我做的

如果你下载了opentk x64版本一定要把你的生成选项改为x64。

OpenTK.dll添加到reference中.

第 2 段(可获 1.46 积分)

删除解决方案管理器中的 Form1 类。

添加一个名为 MainWindow 的新类。 (我将其放置在 Components 目录中)

using OpenTK;
using OpenTK.Graphics.OpenGL4;
namespace techdump.opengl.Components
{
    public sealed class MainWindow : GameWindow
    {
    }
}

添加 'using OpenTK.Graphics.OpenGL4;' 语句告诉 OpenTK 我们希望希望使用 OpenGL 4 并不想看到旧 API。 仅为我们提供一个干净的环境。

打开 Program.cs 并移除 Main 方法中的所有内容,而替换为下列内容

static class Program
{
    [STAThread]
    static void Main()
    {
        new MainWindow().Run(60);
    }
}
第 3 段(可获 0.73 积分)

Run(60) 告诉 OpenTK 你希望以 60 fps 频率运行。如果你在此时运行程序,将会出现类似下面的一个窗口:

设置重载

OpenTK 提供了一些非常棒的方法,你可以在你的 MainWindow中对其进行重载。

添加一个构造函数并设置你的窗体。

public MainWindow()
    : base(1280, // initial width
        720, // initial height
        GraphicsMode.Default,
        "dreamstatecoding",  // initial title
        GameWindowFlags.Default,
        DisplayDevice.Default,
        4, // OpenGL major version
        0, // OpenGL minor version
        GraphicsContextFlags.ForwardCompatible)
{
    Title += ": OpenGL Version: " + GL.GetString(StringName.Version);
}
第 4 段(可获 0.65 积分)

那么基本来说,这段代码的作用是设置我们窗体的初始状态。我们再次告诉 OpenTK 我们希望使用 OpenGL 4。 出于理智的目的,我们在构造函数体中会使用实际的 OpenGL 版本覆盖窗体标题。

重写 OnResize 方法能够在用户决定调整窗体尺寸时重置我们的 ViewPort

protected override void OnResize(EventArgs e)
{
 GL.Viewport(0, 0, Width, Height);
}

OpenTK 在 GL 静态类中封装了 OpenGL API 。所以上面的 GL.Viewport 对应于 glViewport。 所以基本上你可以阅读 OpenGL API 文档 并确定 OpenTK 方法的名字是什么。

第 5 段(可获 1.2 积分)

接下来是 OnLoad 方法。 这个方法会在我们的窗体载入时执行。是初始化的理想所在。

protected override void OnLoad(EventArgs e)
{
 CursorVisible = true;
}

OnUpdateFrame 方法是所有更新操作所在的位置。该方法会为每一帧所调用。

protected override void OnUpdateFrame(FrameEventArgs e)
{
 HandleKeyboard();
}
private void HandleKeyboard()
{
 var keyState = Keyboard.GetState();

 if (keyState.IsKeyDown(Key.Escape))
 {
  Exit();
 }
}

同时我添加了一个 HandleKeyboard 方法从而我们可以很容易地通过按下 Escape 键关闭窗体。

第 6 段(可获 0.64 积分)

最后一个重载的方法是 OnRenderFrame。这是所有绘制操作发生的位置。也为每一帧所调用。FrameEventArgs 包含一个 Time 属性,告诉我们距离上一帧已过去多长时间。

protected override void OnRenderFrame(FrameEventArgs e)
{
    Title = $"(Vsync: {VSync}) FPS: {1f / e.Time:0}";

    Color4 backColor;
    backColor.A = 1.0f;
    backColor.R = 0.1f;
    backColor.G = 0.1f;
    backColor.B = 0.3f;
    GL.ClearColor(backColor);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    SwapBuffers();
}
第 7 段(可获 0.4 积分)

GL.ClearColor 需要一个 Color4 结构。在 Color4 结构体中有许多预定义的颜色,例如: Color4.AliceBlue。运行后会显示一个深蓝窗体,同时在标题栏中显示一个 fps 计数器,如本文开篇所示。

希望这会帮助到某些人 :)

谢谢阅读。下面是一张两只猫打闹的 GIF。 (完整视频在: https://youtu.be/idObqY19eds)

第 8 段(可获 0.85 积分)

文章评论