OpenGL (LWJGL) ile HUD / GUI oluşturma


15

HUD veya GUI yapmam gereken oyun geliştirme aşamasındayım. Bu bölüme hiç girmedim, bu yüzden nasıl yapıldığını bilmiyorum. Ekranda sabit bir konumda basit bir dörtlü oluşturmayı denedim, ancak bir sorun var. Kameranın ortografik olarak çalışmasını sağlamak için şunu kullanıyorum:

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);
}

Bu yöntemi kullanarak ekranda sabit bir şeyi nasıl yapabileceğimi görmüyorum? Bunun herhangi bir yolu var mı? Teşekkürler :)


Bu bir Direct3D perspektifinden olduğu için cevap vermeyeceğim, ancak ([0...1], [0...1], 0, 1)NO projeksiyon, görünüm veya dünya matrisi ile koordinatları kullanırsanız, her zaman ekran alanına inerler.
Jonathan Dickinson

Yanıtlar:


13

Bu, yaklaşık yedi yıl önce C ++ ile yazılmış, içinde 3D dünya ve 2D GUI oluşturma işlemlerini nasıl ele aldığımı açıklamaya çalıştığım için çok çıplak yazmaya çalıştığım eski bir OpenGL tabanlı oyun motorundan. Benim OpenGL oluşturucu sınıf (OGLRender) içinde dört ana yöntem kullandım:

  • 3D dünya sahnesini oluşturmak için OpenGL'yi hazırlamak için ready3D () .
  • 2D GUI'yi oluşturmak üzere OpenGL'yi hazırlamak için ready2D () .
  • Gerçek 3D dünya sahne çizimi için render3D () .
  • Gerçek 2D GUI çizimi için 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 ...
    }

Ve sonra ana iş parçacığı döngüsünde temelde yöntemleri aşağıdaki sırayla çağırırsınız:

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

    SDL_GL_SwapBuffers(); // make drawn frame visible
}

Yaptığım şey, önce 3D dünya sahnemi çiziyorum ve daha sonra GUI'mi son olarak GUI her zaman dünya sahnesinin üstünde olacak şekilde çiziyorum. ready3D () yöntemi, 3D dünya projeksiyonunu dünya sahne çizimi için hazır hale getirir ve ready2D () yöntemi 2D orto sahnesini GUI çizimi için hazır hale getirir. m_Setup.widthve m_Setup.heightsadece görünümü liman ekran boyutları bulunmaktadır.

Ready2D () yöntemi hakkında özel gluOrtho2D()olan, Windows, Mac ve diğer masaüstü ekran koordinat sistemleriyle eşleşmek için belirtilen ekran koordinatlarında çizdiğimiz GUI ilkelerini çizdiğimizde ona işlev gösteren argümanlarla çağrılmasıdır. Sol üst gibi (X, Y) biçiminde (0,0) sağ alt olduğu gibi (ViewportWidth-1, ViewportHeight-1). Ve glTranslatef()piksel başına doğru konumlandırmayı düzeltmek için kullanılır. Böylece (0,0) - (0,9) arasında bir çizgi çizdiğimizde, çizgi aslında sol üst ve tam aşağı on piksel uzunluğunda ve bir piksel genişliğinde düz çizer.

Genel olarak, büyük olasılıkla ready2D () yönteminin ne yaptığıyla ilgileniyorsunuzdur . Genelde çoğu oyunun 3D dünya sahnesini ve GUI çizim sırasını nasıl yaptığına dair bir fikir vermek için diğer yöntemlerin kaynak kodu örneklerini sağladım.


Teşekkürler, orto ve perspektif arasında geçişin performans için kötü olup olmadığını bilmiyordum, çünkü bana göre büyük bir operasyon gibi görünüyor (elbette OpenGL'nin nasıl çalıştığını neredeyse bilmiyorum ... hala öğreniyorum!) gördüğünüz ve söyledikleriniz bunu yapmanızı önerir. Sanırım yapacağım :)
smoth190

Bu yanıtı yapmayı düşündüğüm türden bir cevap. Ben sadece her 2D render projeksiyon matrisi itip sonra sonra haşhaş daha iyi yapılabilir eğer olsa merak ediyordum. Bu kesinlikle 3D'yi bir kez kurabileceğiniz anlamına mı gelir? O zaman 3B kurulumunuzu yalnızca pencere boyutu değişiklikleri için yeniden çağırmanız gerekir.
Lightbulb1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.