Membuat HUD / GUI dengan OpenGL (LWJGL)

15

Saya berada pada tahap pengembangan game saya di mana saya perlu membuat HUD atau GUI. Saya tidak pernah sampai di bagian ini, jadi saya tidak tahu bagaimana caranya. Saya mencoba merender quad sederhana pada posisi tetap di layar, tetapi ada masalah. Untuk membuat kamera saya berfungsi dengan ortografis, saya menggunakan ini:

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

Saya tidak melihat bagaimana saya dapat membuat sesuatu diperbaiki di layar menggunakan metode ini? Ada jalan lain? Terima kasih :)

smoth190
sumber
Saya tidak akan menjawab karena ini dari sudut pandang Direct3D, tetapi jika Anda menggunakan koordinat ([0...1], [0...1], 0, 1)tanpa proyeksi, tampilan atau matriks dunia, mereka akan selalu mendarat di ruang layar.
Jonathan Dickinson
stackoverflow.com/questions/5467218/opengl-2d-hud-over-3d
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

13

Ini dari mesin game berbasis OpenGL lama yang saya coba tulis sekitar tujuh tahun yang lalu ditulis dalam C ++ begitu telanjang ketika saya mencoba menjelaskan bagaimana saya menangani dunia 3D dan operasi rendering GUI 2D di dalamnya. Saya menggunakan empat metode utama dalam kelas renderer OpenGL saya (OGLRender) di antaranya adalah:

  • ready3D () untuk mempersiapkan OpenGL untuk membuat adegan dunia 3D.
  • ready2D () untuk mempersiapkan OpenGL untuk merender GUI 2D.
  • render3D () untuk gambar adegan dunia 3D aktual.
  • render2D () untuk gambar 2D GUI yang sebenarnya.

    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 ...
    }

Dan kemudian di loop utas utama saya pada dasarnya hanya akan memanggil metode dalam urutan berikut:

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

    SDL_GL_SwapBuffers(); // make drawn frame visible
}

Jadi, apa yang saya lakukan adalah saya menggambar adegan dunia 3D saya terlebih dahulu dan kemudian saya menggambar GUI saya terakhir sehingga GUI selalu di atas panggung dunia. metode ready3D () membuat proyeksi dunia 3D siap untuk menggambar adegan dunia dan metode ready2D () membuat adegan 2D ortho siap untuk menggambar GUI. m_Setup.widthdan m_Setup.heighthanya dimensi layar port tampilan.

Apa yang istimewa tentang metode ready2D () adalah bahwa gluOrtho2D()fungsi dipanggil dengan argumen yang memberi tahu ketika kita menggambar primitif GUI kita menggambar mereka di koordinat layar yang ditentukan untuk mencocokkan Windows, Mac, dan sistem koordinat layar desktop lainnya. Seperti kiri atas adalah (0,0) dalam format (X, Y) sedangkan kanan bawah (ViewportWidth-1, ViewportHeight-1). Dan glTranslatef()digunakan untuk mengoreksi posisi akurat per-pixel. Sehingga ketika kita menggambar garis dari (0,0) hingga (0,9) maka garis tersebut akan benar-benar menarik dari kiri-atas dan lurus ke bawah sepuluh piksel panjang total dan satu piksel lebar.

Secara keseluruhan Anda kemungkinan besar hanya tertarik pada apa yang dilakukan metode ready2D () . Saya memberikan contoh kode sumber metode lain untuk memberi Anda gambaran tentang bagaimana umumnya game melakukan adegan dunia 3D dan urutan gambar GUI.

NAM TRON
sumber
Terima kasih, saya hanya tidak tahu apakah beralih antara orto dan perspektif akan berdampak buruk untuk kinerja, karena bagi saya sepertinya operasi besar (tentu saja saya hampir tidak tahu bagaimana OpenGL bekerja ... masih belajar!) Tetapi di mana-mana saya sudah terlihat, dan apa yang Anda katakan, sarankan melakukan ini. Jadi saya rasa saya akan :)
smoth190
Saya suka jawaban ini agak apa yang saya pikirkan lakukan. Saya hanya ingin tahu apakah itu bisa dilakukan lebih baik dengan mendorong Anda matriks proyeksi pada setiap render 2D kemudian muncul setelahnya. Itu berarti Anda hanya dapat mengatur 3D sekali saja? Maka Anda hanya perlu memanggil pengaturan 3D Anda lagi untuk perubahan ukuran jendela jika Anda mengatasinya.
Lightbulb1