0

こんにちは、 、 、およびの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();

しかし、何かが非常に間違っています。写真が 2 つの特定のフレームの間で切り替わる。2つのフレームを印刷しました。見てみな:

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

まだ次の詳細があります。上の最初のフレームが正しい限り、変化は見られません。つまり、正方形は動かないということです。

どうすれば修正できますか?または、簡単なアニメーションを作成する方法は?

4

2 に答える 2

2

OpenGL コンテキストを持たないスレッドから OpenGL コマンドを発行することはできません。

次の 2 つのオプションがあります。

  • wglMakeCurrent を使用して、OpenGL コンテキストを新しいスレッドに移動します。(その場合、メイン スレッドは OpenGL コマンドを発行しなくなる可能性があります。)
  • イベントをフックし、そのApplication.Idle中でループします。新しい Windows メッセージが到着するたびに、ループから抜け出します。

TaoSimpleOpenGlControlは、着信する Windows メッセージをチェックする方法を提供していません。Tao フレームワークの最初のメンテナーの 1 人として、代わりに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;

不明な識別子を右クリックして [解決] を選択することにより、不足している using ディレクティブを追加するように Visual / Xamarin Studio に依頼できます。

于 2014-03-27T17:52:33.733 に答える