Ориентация OpenGL. (Идентификация вращения, глядя в отрицательном Z) - PullRequest
1 голос
/ 26 февраля 2012

Я реализую рендерер, который обрабатывает каждую матрицу перевода / просмотра / модели / проекции (я не использую glRotate / glTranslate и т. Д.).

Я поместил несколько синих объектов вдоль положительной оси z и несколько красных объектов на положительной оси x (поэтому я должен видеть красные объекты слева от меня и синие прямо, используя вращение идентичности на моем камера). Это правосторонняя ориентация, верно?

Проблема в том, что мне нужно повернуть на 180 градусов вокруг оси Y, чтобы увидеть мои объекты. Похоже, что поворот идентичности выглядит в -z.

Я строю свою матрицу просмотра, беря обратную матрицу камер [Rot ​​Tr], а затем помещаю ее в массив по столбцам и передаю ее своему шейдеру.

Для объектов (World matrix) я просто передаю матрицу [Rot ​​Tr] по столбцам шейдеру. Должен ли я отменить перевод?

Матрица проекции на данный момент строится в вершинном шейдере, пока я работаю над этим. Как вы можете видеть ниже, я делаю

position = proj*view*model*gl_Vertex;

В настоящее время я использую gl_Vertex (я использую glutSolidCube после загрузки матрицы идентификаторов в качестве объектов моей сцены).

uniform mat4 view;
uniform mat4 model;

varying vec4 pos;

void main()
{   

pos = gl_Vertex;


float aspect = 1.0;
float fovy = 1.5;
float f = 1.0 / tan(fovy * 0.5);
float near = 1.0;
float far = 100.0;
float tt = 1.0 / (near - far);

mat4 proj = mat4(f/aspect, 0.0, 0.0, 0.0,
        0.0, f, 0.0, 0.0,
        0.0, 0.0, (near+far)*tt, -1.0,
        0.0, 0.0, 2.0*near*far*tt, 0.0);

gl_Position = proj * view * model * pos;
}

В моем фрагментном шейдере я установил color = pos, чтобы я мог видеть цвет оси, и цвета кажутся правильными. Я думаю, что объекты правильно размещены в сцене, но с вращением матрицы идентичности я все еще смотрю в обратную сторону.

Что я мог пропустить? Правильно ли я передаю правильные матрицы?

Ответы [ 3 ]

2 голосов
/ 26 февраля 2012

Правая система координат всегда смотрит вниз по оси -Z.Если + X идет вправо, а + Y идет вверх (как работает все OpenGL), и представление выровнено по оси Z, то + Z должно перейти к зритель.Если бы вид смотрел вниз по оси + Z, то пространство было бы левосторонним.

0 голосов
/ 10 февраля 2014

Ладно, полностью переписал это прошлой ночью, и я надеюсь, что вы найдете его полезным, если вы еще не придумали свои собственные решения или кого-то еще, кто приходит с подобным вопросом.смотрит вниз на -Z, правый вектор смотрит вниз на + X, а вектор вверх смотрит вниз на + Y.

Когда вы решаете построить свой мир, действительно не имеет значения, куда вы смотрите, если у вас 128x128Мир X, Z и вы находитесь посередине в 64x64, как любой игрок узнает, что они повернуты на 0 или 180 градусов.Они просто не будут.

Теперь вы упомянули, что вам не нравятся glRotatef и glTranslatef.Я также не буду использовать методы, которые обрабатывают векторную и матричную математику.Во-первых, я использую способ отслеживания векторов вперед, вверх и вправо.Итак, представьте, что вы вращаетесь по кругу, это вы вращаете свой прямой вектор.Поэтому, когда игрок хочет, скажем, бежать прямо вперед.Вы будете перемещать их вдоль X, Z вашего вектора вперед, но, допустим, они также хотят повернуть вправо.Ну, вы все равно будете двигать их по переднему вектору, но представьте, что 90-градусный снимок с прямого вектораПоэтому, если мы смотрим на 45 градусов, мы указываем на сектор -Z и -X.Так что стрельба переместит нас в сектор -Z и + X.Чтобы сделать это, вы просто отрицаете значение греха.Примеры обоих ниже, но это можно сделать по-разному. Ниже приведен грубый пример, чтобы лучше объяснить вышесказанное.

Position.X -= Forward.X; //Run Forward.
Position.Z -= Forward.Z;

Position.X += Forward.Z; //Run Backwards.
Position.Z += Forward.Z 

Position.X += Forward.X; //Strafe Right.
Position.Z -= Forward.Z;

Position.X -= Forward.X; //Strafe Left.
Position.Z += Forward.Z;

Ниже приведен пример инициализации матрицы представления.Это должно быть выполнено только один раз, не помещайте это ни в какой код зацикливания.

glMatrixMode(GL_MODELVIEW);

view_matrix[4] =  0.0f; //UNUSED.

view_matrix[3] =  0.0F; //UNUSED. 
view_matrix[7] =  0.0F; //UNUSED. 
view_matrix[11] = 0.0F; //UNUSED. 
view_matrix[15] = 1.0F; //UNUSED.

update_view();
glLoadMatrix(view_matrix);

Тогда это метод update_view ().Это должно вызываться только во время изменения в матрице вида.

public void update_view()
{
    view_matrix[0] =  Forward[0];
    view_matrix[1] =  Up[1] *  Forward[1];
    view_matrix[2] =  Up[0] * -Forward[1];

    view_matrix[5] =  Up[0];
    view_matrix[6] =  Up[1];

    view_matrix[8] =  Forward[1];
    view_matrix[9] =  Up[1] * -Forward[0];
    view_matrix[10] = Up[0] *  Forward[0];
}

Векторы положения являются матрицами [12], [13] и [14] и отрицаются.Вы можете сохранить их или использовать матрицы [12], [13], [14] в качестве вектора для позиции.

view_matrix[12] =  -Position.x;
view_matrix[13] =  -Position.y;
view_matrix[14] =  -Position.z;
0 голосов
/ 26 февраля 2012

Проблема в том, что мне нужно повернуть на 180 градусов вокруг оси Y, чтобы увидеть мои объекты. Похоже, что поворот идентичности выглядит в -z.

Да, это так. Системы координат, предоставляемые yb OpenGL в форме для glOrtho и glFrustum, правосторонние (возьмите правую руку, подайте большой палец вправо, указательный палец вверх, затем указательный палец будет указывать на вас). Если вы смоделировали свои матричные вычисления в соответствии с ними, то вы также получите правую систему.

...