Проблема с созданием 2D интерфейса в 3D мире openGL - PullRequest
5 голосов
/ 27 ноября 2010

Я работаю над проектом, который требует создания 2D-интерфейса, отображаемого "сверху", или трехмерного мира.На некоторых других форумах я читал, что вы можете использовать «GluOrtho2D ()» для этой работы и вернуться к GluPerspective (), как только вы закончите.Единственное, мой тестовый код, который я написал для него, отображает только трехмерный мир, а не двумерный четырехугольник.Однако, когда я отключаю код 3D-рендеринга, квад появляется, где он должен был быть.Я сократил код до операторов openGL only, которые я записал ниже.Код написан на Python с использованием библиотеки Pyglet.


Код инициализации сцены:

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 () создает трехмерную сцену, а пара glBegin-glEnd рисует двумерный квад:

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)

Я действительно надеюсь, что кто-то может указать на мою ошибку!И спасибо, что помогли мне:)

Ответы [ 3 ]

3 голосов
/ 27 ноября 2010

Похоже, вы не звоните glLoadIdentity() после переключения на GL_MODELVIEW. Самый простой способ запомнить это вызывать его каждый раз, когда вы меняете матрицу проекции, переключаетесь на GL_MODELVIEW и вызываете glLoadIdentity() (если вы действительно не хотите сохранить старую).

2 голосов
/ 30 ноября 2010

Многие люди неправильно понимают, как использовать glViewport и тому подобное. Они всегда помещают его в форму обратного вызова, что просто неправильно.

Вы всегда полностью настроены в функции рендеринга, непосредственно перед тем, как вам понадобятся эти настройки. Ваш код должен быть (pesudocode):

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 - это конечный автомат. Если вы не можете доказать, что не произошло никаких неопределенных изменений состояния, вы всегда переустанавливаете / устанавливаете все необходимые состояния до отображения определенной геометрии.

1 голос
/ 27 ноября 2010

Я использую следующие матрицы для 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);
...