2014-10-21 2 views
2

Я пытался понять OpenGL немного глубже, и я застрял с проблемой ниже.Понимание интерпретации координат окон в OpenGL

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

glViewport(0, 0 ,800, 480); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glTranslatef(0, 0, -1); 
glRotatef(0, 0, 0, 1); 

glBegin(GL_QUADS); 
    glVertex3f(-128, -128, 0.0f); 
    glVertex3f(128, -128, 0.0f); 
    glVertex3f(128, 128, 0.0f); 
    glVertex3f(-128, 128, 0.0f); 
glEnd(); 

Координаты окна (WX, WY, Wz) для вышеуказанного фрагмента являются

  • (272,00000286102295, +111,99999332427979, 5.9604644775390625e-008)
  • (+527,99999713897705, +111,99999332427979, 5.9604644775390625e-008)
  • (+527,99999713897705, +368,00000667572021, 5.9604644775390625e-008)
  • (+272,00000286102295, +368,00000667572021, 5.9604644775390625e-008)

Я сделал glReadPixels() и сбрасывал в файл BMP. На изображении я получаю квадрат, как ожидалось, с упомянутым выше (Wx, Wy) (с момента появления изображений начало координат находится в левом верхнем углу, а при проверке изображения bmp я позаботился о вычитании высоты окна i.e 480). Этот результат был в моем понимании - (Wx, Wy) будет использоваться в качестве 2D-координаты, а Wz будет использоваться для целей глубины.

Теперь проблема. Я попробовал приведенный ниже фрагмент кода.

glViewport(0, 0 ,800, 480); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glTranslatef(100, 0, -1); 
glRotatef(30, 0, 1, 0); 

glBegin(GL_QUADS); 
    glVertex3f(-128, -128, 0.0f); 
    glVertex3f(128, -128, 0.0f); 
    glVertex3f(128, 128, 0.0f); 
    glVertex3f(-128, 128, 0.0f); 
glEnd() 

окно координаты для приведенного выше фрагмента являются

  • (+400,17224205479812, +242,03174613770986, 1.0261343689191909)
  • (403.24386530741430, 238.03076912806583, 0.99456100555566640)
  • (+403,24386530741430, +241,96923087193414, 0.99456100555566640)
  • (400.17224205479812, 237.96825386229017, 1.0261343689191909)

Когда я выгрузил вывод в файл BMP, я ожидал иметь очень маленький параллелограмм (приблизительно как квадрат 4 x 4, преобразованный в параллелограмм) на основе вышеизложенного (Wx, Wy). Но это было не так. Изображение имело другой набор координат, как показано ниже

  • (403, 238)
  • (499, 113)
  • (499, 366)
  • (403, 241)

Я упомянул координаты в направлении CW, как видно на изображении.

Я здесь потерялся. Может кто-нибудь помочь в понимании, что и почему это происходит во втором случае ?? Как получилось, что на экране появилось очко (499, 113), когда в расчетных координатах окна не было?

Я использовал gluProject() в координатах окна.

Примечание: Я использую OpenGL 2.0.Я просто пытаюсь понять понятия здесь, поэтому, пожалуйста, не предлагайте использовать версии> OpenGL 3.0.


редактировать

Этого обновление для ответа разместила derhass

гомогенных координат после матрицы проекции для второго случая является следующим

  • (-0.027128123630699719, -0.53333336114883423, -66.292930483818054, -63.000000000000000)
  • (0.52712811245482882, -0.5333333611488342 3, +64,292930722236633, 65,00000000000000)
  • (0,52712811245482882, +0,53333336114883423, 64,292930722236633, 65,000000000000000)
  • (-0,027128123630699719, 0,53333336114883423, -66,292930483818054, 63,000000000000000)

Так вот для вершин, где г> -1, то вершины будут обрезаны в ближней плоскости. Когда это так, не следует ли GL использовать проецируемую точку в плоскости z = -1?

+0

«Итак, здесь для вершин, где z> -1, вершины будут обрезаны в ближней плоскости. Если это так, не следует использовать GL-проецируемую точку в плоскости z = -1?" Вы неправильно интерпретируете координаты пространства клипа. Наблюдающий усеченный угол [-w, w] во всех трех измерениях есть, поэтому плоскость z = -1 здесь совершенно бессмысленна. Конечно, отсечение будет генерировать вершины, которые, если бы их преобразовали в пространство глаз, лежали на плоскости z = -1. – derhass

+0

спасибо за вывод, указывающий, что объем просмотра [-w, w] во всех направлениях перед разрывом перспективы. Я так и не думал об этом. Я только имел в виду, что объем просмотра будет [-1,1] во всех направлениях после перспективы разделения. –

ответ

0

То, что вам не хватает, это clipping.

После этого

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0); 

вы в основном имеют камеру на происхождение, глядя вдоль -z направлении, и вблизи плоскости на z=-1 дальняя плоскость в z=-100. Теперь вы рисуете квадрат 128x128, повернутый на 30 градусов по оси y (вверх), и сдвинутый на -1 вдоль z (и 100 по x, но это не является решающим моментом здесь). Поскольку Вы повернули квадрат вокруг его центральной точки, значение z для двух точек будет проходить до ближайшей плоскости, в то время как другие два должны попасть в усечение. (И вы также можете видеть, что, поскольку эти два пункта соответствуют вашим ожиданиям).

Теперь прямо проецирование всех 4 точек на оконное пространство - это не то, что делает GL. Он преобразует точки в clip space, пересекает примитивы со всеми 6 сторонами смотрового усечения и, наконец, проектирует обрезанные примитивы в пространство окна для растеризации.

Проецирование, которое вы сделали, фактически имеет смысл только для точек, которые лежат внутри усеченного конуса. Два из ваших очков лежат за camrea, а проецирующие точки за камерой создают зеркальное изображение этих точек перед камерой.

+0

Предполагая, что искатель правильно рассчитал свои значения: не следует ли вырезать новые точки только внутри незакрепленного полигона? например его значения x варьируются от 400 до 403, как можно обрезать точку при x = 499? – BDL

+1

@BDL: Нет, не следует. Он должен делать это только перед тем, как разделение перспективы (и пространство клипа названо так по какой-то причине), но не в пространстве окна. Конечно, вы также можете закрепить в пространстве для глаз. Поэтому, если искатель пересечет этот повернутый квадрат с плоскостью z = -1 и проецирует полученные точки на оконное пространство, он должен также точно получить точки, созданные GL. – derhass

+0

спасибо за объяснение – BDL

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