1

我正在浏览“C# Game Programming For Serious Game Creation”一书中的示例,并且看到了一些奇怪的行为。我设置了一个视口和正射投影,然后尝试绘制一个 50px 宽的三角形。起初我只看到三角形的一小部分,但是当我调整窗口大小(例如,最大化然后恢复)时,三角形突然显示为正确的大小。

这是一个重现该问题的简单示例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tao.OpenGl;

namespace SimpleExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            _openGLControl.InitializeContexts();
        }

        protected override void OnClientSizeChanged(EventArgs e)
        {
            base.OnClientSizeChanged(e);

            int width = ClientSize.Width;
            int height = ClientSize.Height;
            double halfWidth = (double)width / 2;
            double halfHeight = (double)height / 2;

            Gl.glViewport(0, 0, width, height);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Gl.glOrtho(-halfWidth, halfWidth, -halfHeight, halfHeight, -100, 100);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
        }

        private void _openGLControl_Paint(object sender, PaintEventArgs e)
        {
            Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

            Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
            {
                Gl.glColor4d(1.0, 0.0, 0.0, 0.5);
                Gl.glVertex3d(-50, 0, 0);
                Gl.glColor3d(0.0, 1.0, 0.0);
                Gl.glVertex3d(50, 0, 0);
                Gl.glColor3d(0.0, 0.0, 1.0);
                Gl.glVertex3d(0, 50, 0);

            }
            Gl.glEnd();
            Gl.glFinish();
        }
    }
}

OnClientSizeChanged 事件在绘制三角形之前程序启动时确实会触发,但在我调整窗口大小之前,视口/正交似乎没有任何改变。

我正在使用 OpenTk 库,包括 Tao.OpenGL(如您所见)。我在将 Dock 设置为 Fill 的表单上使用 SimpleOpenGlControl。在 Windows 7 上的 VS2012 中运行。我想尽可能贴近书中的示例,而不使用 glut 或任何额外的库。谁能指出我做错了什么?

4

2 回答 2

2

我的猜测是OnClientSizeChanged调用了初始值,InitializeComponent();这意味着它还_openGLControl.InitializeContexts();没有被调用,并且对视口的更改不会应用于您的控件。因此,要修复它,我会在您初始化控件的上下文后设置视口。

于 2013-06-03T19:10:36.200 回答
2

更改 OpenGL 视图的任何方面都需要完全重绘场景。由于典型的 OpenGL 渲染将包括覆盖(HUD、注释等),因此将视口和投影矩阵与绘图分开设置是没有意义的。因此 glViewport 和投影矩阵设置应该在绘图例程中执行。

无论如何,窗口大小或其他查看方面的任何更改都必须触发完整的重绘,并且在绘图例程中设置视口和投影可以解决这个问题,而无需进一步考虑。

于 2013-06-03T19:04:29.517 回答