Я возвращаюсь в мир игрового программирования после двухлетнего перерыва. К сожалению, большая часть моих знаний в области трехмерной математики довольно ржавая. Так что терпи меня.

Мой движок и игра изначально были разработаны для DirectX, системы для левшей, использующей матричную структуру с крупными строками. Мой математический код самодельный и отлично работает в рамках этой системы. Я нахожусь в точке, где я хочу дать своей игре средство визуализации OpenGL. Поскольку вся моя математика использует левостороннюю матричную систему с основными строками (например, для создания матрицы проекций), насколько сложно будет перенести мою математику в левостороннюю систему с основными столбцами OpenGL?

Это вопрос транспонирования матрицы и вставки значений в структуру основного столбца? Или я слишком упрощаю это.

0
MarkP 26 Авг 2011 в 05:58

2 ответа

Лучший ответ

Это зависит. Мы говорим об OpenGL на основе шейдеров или с фиксированной функцией (FF)?

В мире FF вам нужно использовать gluPerspective (или glFrustum) для генерации вашей матрицы перспективы, используя аналогичные параметры, которые вы задали бы вашему коду в D3D. Затем вам нужно транспонировать матрицы, которые вы будете вычислять для D3D (без учета компонента проекции вычисления), чтобы сделать столбец главным, как того требует glLoad / MultMatrix.

А затем вам нужно сгенерировать матрицу для переворота вашей сцены, которую вы поместите в самый низ стека GL_MODELVIEW. Самый простой способ понять, что делать, - просто отрендерить все и посмотреть, как мир перевернулся. Затем приклейте туда матрицу, которая инвертирует вдоль оси; если это исправит, все готово.

В псевдокоде вы делаете следующее:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(/*Projection parameters here*/);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(/*Your flip matrix here*/);
glPushMatrix();

//Render your stuff here.
//When rendering an object:
Matrix mat = ComputeD3DModelToCameraMatrixForObject();
mat = Transpose(mat);
glPushMatrix();
glMultMatrixf(GetMatrixAsFloatArray(mat));
//Draw the object.
glPopMatrix();

//When finished rendering stuff:
glPopMatrix();

В шейдерах все проще. Это предполагает, что вы используете свою собственную униформу для передачи матриц в GLSL.

На самом деле, все, что вам нужно сделать, это посмотреть на различия между пространством клипа, которое использует OpenGL, и пространством клипа, которое использует D3D. Clip-space - это пространство позиций вершин, выводимых вершинным шейдером. Вы можете передавать свои матрицы в GLSL как обычно, поскольку функции glUniformMatrix имеют параметр, который позволяет вам указать, транспонируется ли матрица (по строкам). После того, как вы вычислили позиции пространства клипов D3D, как и для D3D, просто измените результаты в зависимости от того, что ожидает OpenGL.

Я не припомню различий, но в разделе 2.13 спецификации OpenGL (в версии 3.3 это может быть другой раздел для других версий) очень подробно описывается ожидаемая система координат, а также последующие преобразования в оконное пространство .

1
Nicol Bolas 26 Авг 2011 в 02:15

Вы можете проверить это:

http://www.opengl.org/wiki/Viewing_and_Transformations#Can_I_make_OpenGL_use_a_left-handed_coordinate_space.3F

0
Bill Yan 26 Авг 2011 в 08:26