我们重写 GameWindow 中的哪个方法来使用 OpenTk 绘制对象?
Which method inside GameWindow do we override to draw an object with OpenTk?
问题
我正在做一个视频游戏环境设计研究,我碰巧从 OpenGL 的基础知识开始 OpenTk
-OpenGL
的 C# 变体。我从该站点获得了使用 OpenTk
在我的 GameWindow 中绘制立方体对象的代码。我为我的 GameWindow
对象重写方法 OnLoad
并调用该方法来绘制立方体但没有任何反应,代码绘制了 GameWindow
和 NativeWIndow
没有任何图形对象。
预期
我希望代码在 GameWindow
对象内绘制立方体。
应用代码
//extend the GameWindow object to access methods from the super
class MyWindow : GameWindow
{
public MyWindow(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings) : base(gameWindowSettings, nativeWindowSettings)
{
WindowState = OpenTK.Windowing.Common.WindowState.Maximized;
}
//when the window is loaded, draw the cube
protected override void OnLoad()
{
this.DrawBox(10);
}
//method to draw the cube
private void DrawBox(float size)
{
float[,] n = new float[,]{
{-1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, -1.0f}
};
int[,] faces = new int[,]{
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3}
};
float[,] v = new float[8, 3];
int i;
v[0, 0] = v[1, 0] = v[2, 0] = v[3, 0] = -size / 2;
v[4, 0] = v[5, 0] = v[6, 0] = v[7, 0] = size / 2;
v[0, 1] = v[1, 1] = v[4, 1] = v[5, 1] = -size / 2;
v[2, 1] = v[3, 1] = v[6, 1] = v[7, 1] = size / 2;
v[0, 2] = v[3, 2] = v[4, 2] = v[7, 2] = -size / 2;
v[1, 2] = v[2, 2] = v[5, 2] = v[6, 2] = size / 2;
GL.Begin(BeginMode.Quads);
for (i = 5; i >= 0; i--)
{
GL.Normal3(ref n[i, 0]);
GL.Vertex3(ref v[faces[i, 0], 0]);
GL.Vertex3(ref v[faces[i, 1], 0]);
GL.Vertex3(ref v[faces[i, 2], 0]);
GL.Vertex3(ref v[faces[i, 3], 0]);
}
GL.End();
}
}
//instantiation in the main method
GameWindowSettings gameWindowSettings= new GameWindowSettings();
NativeWindowSettings nativeWindowSettings = new NativeWindowSettings();
gameWindowSettings.IsMultiThreaded = false;
new MyWindow(gameWindowSettings, nativeWindowSettings).Run();
请帮我完成这项工作。
您必须实施 OnUpdateFrame
事件回调。您还需要调用 Context.SwapBuffers();
来更新显示:
class MyWindow : GameWindow
{
// [...]
protected override void OnUpdateFrame(FrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
this.DrawBox(0.5f);
Context.SwapBuffers();
base.OnUpdateFrame(e);
}
}
如果您不使用投影矩阵,坐标必须在 [-1.0, 1.0] 范围内。 Normalized Device Space 是一个独特的立方体,具有左、下、近角 (-1, -1, -1) 和右、上、远角 (1, 1, 1)。如果没有投影矩阵,这个立方体也是观察体积(投影在视口上的 space)。
因为您正在使用 Legacy OpenGL (glBegin
/glEnd
) you need to create a Compatibility profile OpenGL Context:
nativeWindowSettings.API = ContextAPI.OpenGL;
nativeWindowSettings.Profile = ContextProfile.Compatability;
有关使用“现代”OpenGL 的非常基本的示例,请参阅 c_sharp_opengl/OpenTK_hello_triangle。
问题
我正在做一个视频游戏环境设计研究,我碰巧从 OpenGL 的基础知识开始 OpenTk
-OpenGL
的 C# 变体。我从该站点获得了使用 OpenTk
在我的 GameWindow 中绘制立方体对象的代码。我为我的 GameWindow
对象重写方法 OnLoad
并调用该方法来绘制立方体但没有任何反应,代码绘制了 GameWindow
和 NativeWIndow
没有任何图形对象。
预期
我希望代码在 GameWindow
对象内绘制立方体。
应用代码
//extend the GameWindow object to access methods from the super
class MyWindow : GameWindow
{
public MyWindow(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings) : base(gameWindowSettings, nativeWindowSettings)
{
WindowState = OpenTK.Windowing.Common.WindowState.Maximized;
}
//when the window is loaded, draw the cube
protected override void OnLoad()
{
this.DrawBox(10);
}
//method to draw the cube
private void DrawBox(float size)
{
float[,] n = new float[,]{
{-1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, -1.0f}
};
int[,] faces = new int[,]{
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3}
};
float[,] v = new float[8, 3];
int i;
v[0, 0] = v[1, 0] = v[2, 0] = v[3, 0] = -size / 2;
v[4, 0] = v[5, 0] = v[6, 0] = v[7, 0] = size / 2;
v[0, 1] = v[1, 1] = v[4, 1] = v[5, 1] = -size / 2;
v[2, 1] = v[3, 1] = v[6, 1] = v[7, 1] = size / 2;
v[0, 2] = v[3, 2] = v[4, 2] = v[7, 2] = -size / 2;
v[1, 2] = v[2, 2] = v[5, 2] = v[6, 2] = size / 2;
GL.Begin(BeginMode.Quads);
for (i = 5; i >= 0; i--)
{
GL.Normal3(ref n[i, 0]);
GL.Vertex3(ref v[faces[i, 0], 0]);
GL.Vertex3(ref v[faces[i, 1], 0]);
GL.Vertex3(ref v[faces[i, 2], 0]);
GL.Vertex3(ref v[faces[i, 3], 0]);
}
GL.End();
}
}
//instantiation in the main method
GameWindowSettings gameWindowSettings= new GameWindowSettings();
NativeWindowSettings nativeWindowSettings = new NativeWindowSettings();
gameWindowSettings.IsMultiThreaded = false;
new MyWindow(gameWindowSettings, nativeWindowSettings).Run();
请帮我完成这项工作。
您必须实施 OnUpdateFrame
事件回调。您还需要调用 Context.SwapBuffers();
来更新显示:
class MyWindow : GameWindow
{
// [...]
protected override void OnUpdateFrame(FrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
this.DrawBox(0.5f);
Context.SwapBuffers();
base.OnUpdateFrame(e);
}
}
如果您不使用投影矩阵,坐标必须在 [-1.0, 1.0] 范围内。 Normalized Device Space 是一个独特的立方体,具有左、下、近角 (-1, -1, -1) 和右、上、远角 (1, 1, 1)。如果没有投影矩阵,这个立方体也是观察体积(投影在视口上的 space)。
因为您正在使用 Legacy OpenGL (glBegin
/glEnd
) you need to create a Compatibility profile OpenGL Context:
nativeWindowSettings.API = ContextAPI.OpenGL;
nativeWindowSettings.Profile = ContextProfile.Compatability;
有关使用“现代”OpenGL 的非常基本的示例,请参阅 c_sharp_opengl/OpenTK_hello_triangle。