簡體   English   中英

在3D openGL世界中創建2D界面的問題

[英]Problem with creating a 2D interface in a 3D openGL world

我正在做一個項目,要求我創建一個“在頂部”渲染的2D界面或3D世界。 在其他一些論壇上,我讀到您可以使用“ GluOrtho2D()”來完成這項工作,並在完成后切換回GluPerspective()。 唯一的是,我為此編寫的測試代碼僅顯示3D世界,而不顯示2D四邊形。 但是,當我禁用3D渲染代碼時,四邊形會出現在原本應有的位置。 我將代碼精簡為僅openGL語句,並將其寫在下面。 該代碼使用Pyglet庫以Python編寫。


場景初始化代碼:

glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/height, .1, 10000.)
glMatrixMode(GL_MODELVIEW)
glClearDepth(1.0)
glShadeModel(GL_FLAT)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL) 
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

框架渲染代碼。 對builder.buildMap()的調用將創建3D場景,而glBegin-glEnd對將繪制2D四邊形:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
stage.set3DMode(window.width, window.height)
builder.buildMap()
stage.set2DMode(window.width, window.height)
glBegin (GL_QUADS)
glVertex2i(0, 0)
glVertex2i(0, 200)
glVertex2i(200, 200)
glVertex2i(200, 0) 
glEnd()

stage.set3DMode函數:

glDisable(GL_DEPTH_TEST) 
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, width, 0, height)
glMatrixMode(GL_MODELVIEW)

和stage.set3DMode函數:

glEnable(GL_DEPTH_TEST) 
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/float(height), .1, 10000.)
glMatrixMode(GL_MODELVIEW)

我真的希望有人能指出我的錯誤! 並感謝您對我的幫助:)

切換到GL_MODELVIEW后,您似乎沒有調用glLoadIdentity() 記住的最簡單方法是,每次更改投影矩陣時都調用它,切換到GL_MODELVIEW並調用glLoadIdentity() (除非您真的想保留舊的)。

很多人誤會如何使用glViewport等。 他們總是將其放置在重塑回調中,這是完全錯誤的。

在需要這些設置之前,您始終要在渲染功能中進行完整設置。 因此,您的代碼應為(偽代碼):

render_scene():
    // first clear the whole window
    glViewport(0, 0, window.width, window.height)
    glClearDepth(1.0)
    glClearColor(1., 1., 1., 1.);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)

    glViewport(3Dstuff.x, 3Dstuff.y, 3Dstuff.w, 3Dstuff.h)
    // maybe also set scissor to clip
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(60.0, float(width)/height, .1, 10000.)
    glMatrixMode(GL_MODELVIEW)
    setup3DstuffModelview()
    glDepthFunc(...)
    glEnable(GL_DEPTH_TEST)
    // other state stuff
    render3Dstuff()

    // now the 2D stuff
    glViewport(2Dstuff.x, 2Dstuff.y, 2Dstuff.w, 2Dstuff.h)
    // clear depth and stencil -- if you need parts of the 3D depth / stencil
    // for some algorithm retain it or save and restore by FBO renderbuffers or
    // glReadPixels, glDrawPixels
    glClearDepth(1.0)
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(...)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    setup2DstuffModelview()
    glDepthFunc(...)
    glDisable(GL_DEPTH_TEST)
    // other state stuff
    render2Dstuff()

    // repeat for all the layers you need

這真的很重要:OpenGL是狀態機。 除非可以證明沒有發生不確定的狀態變化,否則在渲染特定幾何圖形之前,您總是要重新設置所有所需的狀態。

我將以下矩陣用於2D渲染:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, h, 0, 0, 1);
glViewport(0, 0, w, h);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM