OpenGL(LWJGL)でHUD / GUIを作成する


15

ゲーム開発の段階で、HUDまたはGUIを作成する必要があります。私はこの部分に行ったことがないので、どのように行われたのかわかりません。画面上の固定位置に単純な四角形をレンダリングしようとしましたが、問題があります。カメラを正投影で動作させるには、次を使用します。

public void lookThrough()
{
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(position.x, position.x + Display.getDisplayMode().getWidth()/zoom, position.y + Display.getDisplayMode().getHeight()/zoom, position.y, -1, 1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
}

この方法を使用して画面上で何かを修正する方法がわかりませんか?これを回避する方法はありますか?ありがとう:)


これはDirect3Dの観点からのものであるため、回答しませんが、([0...1], [0...1], 0, 1)投影、ビュー、またはワールドマトリックスなしで座標を使用すると、常に画面空間に表示されます。
ジョナサンディキンソン

回答:


13

これは、約7年前にC ++で記述しようとしていた古いOpenGLベースのゲームエンジンからのもので、3Dワールドと2D GUIレンダリング操作をその中でどのように処理するかを説明しようとしています。OpenGLレンダラークラス(OGLRender)内で次の4つの主要なメソッドを使用しました。

  • 3DワールドシーンをレンダリングするOpenGLを準備するためのready3D()
  • 2D GUIをレンダリングするためにOpenGLを準備するためのready2D()
  • 実際の3Dワールドシーン描画用のrender3D()
  • 実際の2D GUI描画用のrender2D()

    void OGLRender::ready3D()
    {
        glViewport(0, 0, m_Setup.width, m_Setup.height);
        glMatrixMode(GL_PROJECTION);
    
        glLoadIdentity();
        gluPerspective(45, (float) m_Setup.width / m_Setup.height, 0.1, 5000.0);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);
    }
    
    void OGLRender::ready2D()
    {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    
        gluOrtho2D(0.0f, m_Setup.width, m_Setup.height, 0.0f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.375, 0.375, 0.0);
    
        glDisable(GL_DEPTH_TEST);
    }
    
    void OGLRender::render3D()
    {
        this->ready3D();
    
        // ... draw 3D world scene here ...
    }
    
    void OGLRender::render2D()
    {
        this->ready2D();
    
        // ... draw GUI here ...
    }

そして、メインスレッドループでは、基本的に次の順序でメソッドを呼び出します。

while(m_drawFrame)
{
    gm_Render->render3D(); // draw 3D scene
    gm_Render->render2D(); // draw GUI

    SDL_GL_SwapBuffers(); // make drawn frame visible
}

ですから、私がやっていることは、最初に3Dワールドシーンを描画し、次にGUIを常にワールドシーンの一番上に描画することです。ready3D()メソッドは、3Dワールドプロジェクションを取得し、ワールドシーンの描画と ready2D()メソッドは、GUI描画に対応した2Dオルソシーンを取得します。m_Setup.widthそしてm_Setup.heightちょうどビューポートの画面サイズです。

ready2D()メソッドの特別な点はgluOrtho2D()、GUIプリミティブを描画するときに、Windows、Mac、およびその他のデスクトップ画面座標系に一致するように指定された画面座標で描画することを伝える引数で関数が呼び出されることです。たとえば、左上は(X、Y)形式では(0,0)で、右下は(ViewportWidth-1, ViewportHeight-1)です。そしてglTranslatef()ピクセルごとの正確な位置決めを修正するために使用されます。(0,0)から(0,9)まで線を引くと、実際には線は左上からまっすぐ下に、合計10ピクセルの長さと1ピクセルの幅で描画されます。

全体的に、ready2D()メソッドが何をしているのかに興味があるだけでしょう。他のメソッドのソースコード例を提供して、ほとんどのゲームが3DワールドシーンとGUIの描画順序をどのように行うかについての一般的なアイデアを示します。


おかげで、オルソとパースペクティブの切り替えがパフォーマンスに悪いかどうかわかりませんでした。なぜなら、私にとっては大きな操作のように思えるからです(もちろん、OpenGLがどのように動作するのかほとんどわかりません...まだ学んでいます!)見て、あなたが言ったことは、これを行うことをお勧めします。だから私は:)
smoth190

私はこの答えが好きです。ただ、各2Dレンダーで投影マトリックスをプッシュしてからポップすることで、もっとうまくできるのではないかと思っていました。それは、3Dを確実にセットアップできるということですか?その後、それを処理する場合にのみ、ウィンドウサイズの変更のために3Dセットアップを再度呼び出す必要があります。
電球1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.