0

您好,我从OpenGL使用C#,Tao.Framework和开始Tao.Plataform.Windows SimpleOpenGlControl,到目前为止,我使用了以下代码段:

// in Form.Load handler
Gl.glOrtho(0, 10, 0, 10, -1, 1);

Gl.glClearColor(0f, 0f, 0f, 0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

Gl.glBegin(Gl.GL_POLYGON);

Gl.glVertex2f(0f, 0f);
Gl.glVertex2f(0f, 1f);
Gl.glVertex2f(1f, 1f);
Gl.glVertex2f(1f, 0f);

Gl.glEnd();

到现在为止还挺好。现在我正在尝试添加一些动画效果。我试图像一个在我的客户区域四肢弹跳的球一样移动正方形。我的代码是这样的:

Gl.glOrtho(0, 10, 0, 10, -1, 1);

new Thread(() =>
{
    int x = 3, incX = 1;
    int y = 7, incY = 1;

    while (true)
    {
        Gl.glClearColor(0f, 0f, 0f, 0f);
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

        Gl.glBegin(Gl.GL_POLYGON);

        Gl.glVertex2f(x + 0f, y + 0f);
        Gl.glVertex2f(x + 0f, y + 1f);
        Gl.glVertex2f(x + 1f, y + 1f);
        Gl.glVertex2f(x + 1f, y + 0f);

        Gl.glEnd();

        simpleOpenGlControl1.SwapBuffers();

        if (x == 0 || x == 9) incX *= -1;
        if (y == 0 || y == 9) incY *= -1;

        x += incX;
        y += incY;

        Thread.Sleep(1000);
    }
}).Start();

但是有一点很不对劲。我的图片不断在两个特定帧之间切换。我打印了两个框架。看看这个:

http://www.jonataspiazzi.xpg.com.br/outpost/example_frame.png

还有以下细节。尽管上面的第一帧是正确的,但它没有显示任何变化,我的意思是正方形不会移动。

我该如何解决?或者如何构建一个简单的动画?

4

2 回答 2

2

您不能从没有 OpenGL 上下文的线程发出 OpenGL 命令。

你有两个选择:

  • 使用 wglMakeCurrent 将 OpenGL 上下文移动到新线程。(在这种情况下,主线程可能不再发出 OpenGL 命令。)
  • 钩住Application.Idle事件并在其中循环。每当有新的 Windows 消息到达时,就从循环中中断。

TaoSimpleOpenGlControl不提供检查传入 Windows 消息的方法。作为 Tao 框架的原始维护者之一,我建议改用OpenTK.GLControl。在这种情况下,你会写:

// in Form.Load handler - separate thread
glControl.Context.MakeCurrent(null);
Thread thread = new Thread(() =>
{
    glControl.MakeCurrent();
    while (!exit)
    {
        GL.ClearColor(0f, 0f, 0f, 0f);
        GL.Clear(ClearBufferMode.ColorBufferBit);

        GL.Begin(PrimitiveType.Quads);

        GL.Vertex(x + 0f, y + 0f);
        GL.Vertex(x + 0f, y + 1f);
        GL.Vertex(x + 1f, y + 1f);
        GL.Vertex(x + 1f, y + 0f);

        GL.End();

        glControl.SwapBuffers();

        if (x == 0 || x == 9) incX *= -1;
        if (y == 0 || y == 9) incY *= -1;

        x += incX;
        y += incY;
    }
};

或(如果您不想使用单独的线程):

// in Form.Load handler - main thread
Application.Idle += (sender, e) =>
{
    while (glControl.IsIdle)
    {
        GL.ClearColor(0f, 0f, 0f, 0f);
        GL.Clear(ClearBufferMode.ColorBufferBit);

        GL.Begin(PrimitiveType.Quads);

        GL.Vertex(x + 0f, y + 0f);
        GL.Vertex(x + 0f, y + 1f);
        GL.Vertex(x + 1f, y + 1f);
        GL.Vertex(x + 1f, y + 0f);

        GL.End();

        glControl.SwapBuffers();

        if (x == 0 || x == 9) incX *= -1;
        if (y == 0 || y == 9) incY *= -1;

        x += incX;
        y += incY;
    }
};

编辑:在这两种情况下,您都需要以下 using 指令。

using OpenTK;
using OpenTK.GLControl;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;

您可以要求 Visual / Xamarin Studio 通过右键单击未知标识符并选择“解决”来添加缺少的 using 指令。

于 2014-03-27T17:52:33.733 回答
0

如果您的 SimpleOpenGlControl 是 smpl 那么,您可以调用,

smpl.SwapBuffers();

效果很好

于 2019-02-25T17:59:40.057 回答