简单的动画用陶.框架(c# - Open GL)更新缓冲区不工作

本文关键字:GL Open 更新 缓冲区 工作 动画 框架 简单 | 更新日期: 2023-09-27 17:54:13

你好,我从OpenGL开始使用C#, Tao.FrameworkTao.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

仍然有以下细节。虽然上面的第一帧是正确的,但它没有显示变化,我的意思是正方形没有移动。

我该如何修复它?或者如何构建一个简单的动画?

简单的动画用陶.框架(c# - Open GL)更新缓冲区不工作

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

你有两个选择:

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

Tao SimpleOpenGlControl不提供检查传入的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通过右键单击未知标识符并选择"Resolve"来添加缺失的using指令。

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

smpl.SwapBuffers();

效果很好