2013-11-20 1 views
0

У меня есть мозаичный движок, использующий орфографическую проекцию в непосредственном режиме, и я просто пытаюсь нарисовать 3d-куб поверх моей сцены плитки, в надежде, что в конечном итоге я смогу включить 3d-модели в свой движок а не просто спрайты/текстурированные квадрациклы. Я также хотел бы сделать плитки 3d для этого небольшого количества дополнительных глазных конфет. Надеюсь, я смогу в конечном итоге преобразовать это, чтобы использовать современный OpenGL, чтобы я мог воспользоваться этими дополнительными функциями. На данный момент не входит в список приоритетов. Так на вопрос.Переключение OpenGL между орто и перспективой

Я инициализация OpenGL с этим:

void initGL() 
{ 
    glDisable(GL_DEPTH_TEST); 

    glViewport(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); 

    //Initialize Projection Matrix 
    glMatrixMode(GL_PROJECTION); 
    glPushMatrix(); 
    glLoadIdentity(); 

    //Initialize Modelview Matrix 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glLoadIdentity();  

    glOrtho(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,0,1); 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);  
    //...setting some various other attributes, omitted for brevity... 

    glEnable(GL_TEXTURE_2D); 
    glClearColor(0, 0, 0, 0); 
} 

У меня есть функция для рисования куба, который работает.

void draw_cube() 
{ 
    /* position object */ 
    glRotatef(30.0F, 1.0F, 0.0F, 0.0F); 
    glRotatef(30.0F, 0.0F, 1.0F, 0.0F);  

    /* draw six faces of a cube */ 
    glBegin(GL_QUADS); 
    ...vertices... (removed for brevity) 
    glEnd();    
} 

Я сделал 2 функции для настройки режимов 2d и 3d.

void set3d() 
{ 
    glEnable(GL_DEPTH_TEST); 
    glClear(GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(0,SCREEN_WIDTH,0,SCREEN_HEIGHT, 0,1); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 
void set2d() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glDisable(GL_DEPTH_TEST); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,0,1); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

Для полноты картины, некоторые псевдокода моего текстурированного четырехъядерного чертежа ..

pushmatrix(); 
translate(); 
rotate(); 
-translate(); 

glbegin(); 
...vertices 
glend(); 
popmatrix(); 

До сих пор мне удалось получить куб рисовать поверх плитки, но он исчезает примерно через 1 секунду, чтобы его больше не видели, пока я снова не запустил программу.

В основном то, что я делаю в основном цикле это:

move objects around, process collisions, etc. 

set2d(); 
draw textured quads, lines, text, etc. in 2d mode. 

set3d(); 
draw_cube(); 

Мой вопрос: Почему куб исчезает, и есть какая-либо ошибка в моей set2d() и set3d функции()?

+0

Вы пытались называть 'draw_cube()' прежде, чем вы нарисуете квадроциклы? Кроме того, какова глубина 2D-квадов, нарисованных? Я думаю, что куб есть, это только за ваши текстурированные квадратики ... возможно, попробуйте просто визуализировать куб без текстурированных квадрациклов и посмотреть, останется ли он на экране. – Reanimation

+0

Ваша проблема в том, что я думаю в функции glFrustum, точнее в параметре zNear. Он НИКОГДА не должен быть равен нулю, и хотя общее правило состоит в том, чтобы сделать его маленьким, вы всегда должны быть осторожны с этим; слишком короткое значение zNear будет вызывать глубинные артефакты даже в малых моделях, а 0 приведет к особенностям математических вычислений (в основном, из-за «деления на нуль»), что приводит к полному исчезновению изображения. –

+0

Хорошо пятнистый Павел. Я также был бы склонен увеличить 'farVal'. Стоит отметить, что оба значения должны быть положительными. – Reanimation

ответ

3

У вас довольно много проблем в этом коде, слишком много, чтобы перечислить в комментариях на самом деле.

  1. Ваши проекционные матрицы меняют ручность вашего постпроектированного координатного пространства, что повлияет на полигональную обмотку.

    • Придерживайтесь одной хиральности, если вы не хотите, чтобы изменить направление, используемое для фронт-/назад, обращенные полигональных граней (glFrontFace (...)) - это CCW по умолчанию, но вы должны изменить его на CW, когда вы используйте set3d (...) для поддержания последовательного поведения.
    • Эта проблема возникает потому, что у вас есть Y-оси происходит в разных направлениях

  2. Поведение вашего описываете, где объект появляется на короткое время, а затем исчезает, свидетельствует о проблеме с вашего стека матрицы.

    • Вы звоните initGL (...) несколько раз в свое программное обеспечение? Если вы сделаете это достаточно времени, вы столкнетесь с переполнением стека, так как вы ненужно нажимаете текущую матрицу на стек и никогда не будете ее выталкивать.

  3. Вы не можете использовать 0.0 для zNear с матрицей перспективных проекций, это приведет к выигрышной математике во время шага разнесения перспективы, который приходит после преобразование в клип-пространство; буфер глубины будет работать неправильно.

    • На самом деле, glFrustum (...) будет генерировать ошибку GL_INVALID_VALUE и не делают точно ничего, если передать значение & # x2264; 0.0 для zNear. В соответствующей заметке gluPerspective (...) этого не сделает, поскольку на самом деле это не часть OpenGL, но это недействительное поведение, чтобы передать такое значение gluPerspective (...).
+0

Спасибо Андон и все остальные, кто ответил. Я по ошибке повернул ось Y в glFrustum(). Спасибо, что указали это. Я не вызываю initGL() более одного раза. Я дважды проверял весь свой код и обнаружил 2 места, где у меня были glEnd() и glPopMatrix(), которые были отменены по ошибке. Что касается пункта 3: я смог заставить куб рисовать поверх плиток с помощью glFrustum (0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1,1); в set3d() и glOrtho (0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1,1); в set2d(); поэтому, очевидно, вы можете установить zNear в

+0

, и я думаю, что вы можете удалить вызовы glPushMatrix() из initGl() вообще ..Имейте в виду, что минимальный размер матричных стеков в OpenGL не такой большой, и для матриц GL_PROJECTION у вас действительно есть только 2 гарантированных пятна в стеке ... –

Смежные вопросы