Как адаптировать матрицы мира / вида / проекции в стиле DirectX для OpenGL? - PullRequest
1 голос
/ 12 сентября 2010

У меня есть приложение, которое использует DirectX, и, следовательно, левую систему координат мира, вид, который смотрит вниз на положительный z, и проекцию, которая проецируется в единичный куб, но с z от 0..1.

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

Какой самый простой способ адаптировать матрицы DirectX к OpenGL? Изменение мирового пространства кажется простым, просто перевернув ось X, но я не совсем уверен, как изменить вид / проекцию. Я могу изменить все матрицы по отдельности перед тем, как их умножить и отправить в мой шейдер. Если возможно, я бы хотел придерживаться системы координат на основе DirectX как можно дальше вниз по конвейеру (т. Е. Я не хочу менять место, где я размещаю свои объекты, как я вычисляю свою точку обзора и т. Д. - в идеале, я Я только внесу некоторые изменения в матрицы непосредственно перед передачей их моим шейдерам.)

Ответы [ 3 ]

4 голосов
/ 01 января 2011

Ответ таков: нет необходимости переворачивать что-либо, только чтобы настроить диапазон глубины. OpenGL имеет -1..1, а DX имеет 0..1. Вы можете использовать матрицы DX так же, как и раньше, и умножить матрицу масштаба / смещения только в конце сверху матрицы проекции, чтобы масштабировать значения глубины от 0,1 до -1,1.

0 голосов
/ 13 сентября 2010

Для этого есть старое расширение для OpenGL: GL_ARB_TRANSPOSE_MATRIX . Он транспонирует матрицы на GPU и должен быть доступен на каждой видеокарте.

0 голосов
/ 13 сентября 2010

Не проверено или что-то еще, просто из головы:

oglProj = transpose(dxProj)
glScalef (1., 1., -1.);  // invert z
glScalef(0.5, 0.5, 1); // from [-1,1] to [-0.5, 0.5]
glTranslatef(0.5, 0.5, 0) // from [-0.5, 0.5] to [0,1]

oglView = transpose(dxView)
glScalef (1., 1., -1.);  // invert z

oglModel = transpose(dwModel)
glScalef (1., 1., -1.);  // invert z

oglModelView = oglView * oglModel
...