Путать обмотки треугольника и трансформации
Прежде всего, я хочу извиниться за такой длинный вопрос. Вам не нужно читать это. Вы можете сразу перейти к части вопросов, а затем искать детали, если это необходимо (я постарался предоставить как можно больше информации, потому что по моему опыту слишком много кода лучше, чем слишком мало). Так,...
Я немного озадачен обмоткой треугольника и трансформациями, которые, как мне показалось, я понял. Я пытаюсь нарисовать куб, который определяется следующим образом:
const float a = 0.5f; //half of the cube side length
float positions[nComponents] =
{
//front face
-a, -a, -a,
a, -a, -a,
a, a, -a,
-a, -a, -a,
a, a, -a,
-a, a, -a,
//back face
-a, -a, a,
a, a, a,
a, -a, a,
-a, -a, a,
-a, a, a,
a, a, a,
//up face
-a, a, -a,
a, a, -a,
a, a, a,
-a, a, -a,
a, a, a,
-a, a, a,
//down face
-a, -a, -a,
a, -a, a,
a, -a, -a,
-a, -a, -a,
-a, -a, a,
a, -a, a,
//right face
a, -a, -a,
a, -a, a,
a, a, a,
a, -a, -a,
a, a, a,
a, a, -a,
//left face
-a, -a, -a,
-a, a, a,
-a, -a, a,
-a, -a, -a,
-a, a, -a,
-a, a, a,
};
И это предполагаемые цвета моих лиц:
float face_colors[nFaces * dim] =
{
1,0,0, //front RED
1,1,1, //back WHITE
0,0,1, //up BLUE
0,1,1, //down SKY BLUE
0,1,0, //right GREEN
1,1,0, //left YELLOW
};
Как видно из комментариев, я использую термины "вверх", "вниз", "влево", "вправо" и т. Д. Эти слова приобретают смысл, если предположить, что мы смотрим на куб с позиции, скажем, (0, 0, -3a)
в мировых координатах. Теперь, как я понимаю, передние грани моего куба намотаны против часовой стрелки (то есть, если мы посмотрим на куб с любой точки за его пределами и перечислим вершины в треугольниках, которые мы видим, мы получим намотку против часовой стрелки),
Итак, мне нужно 1. Включить отбраковку. 2. Скажите, что против часовой стрелки - передняя поверхность. 3. Отберите заднюю поверхность. Вот код для этого:
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
Моя матрица проекций - это матрица перспективных проекций, а матрица modelView - это просто матрица LookAt. Они подаются в форме для вершинного шейдера.
ProjectionMatrix = glm::perspective(45.0f, (float)w/h, 0.1f, 100.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 eye(1.0f, 2.0f, -3.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
ModelViewMatrix = glm::lookAt(eye, center, up);
glUniformMatrix4fv(locP, 1, false, glm::value_ptr(ProjectionMatrix));
glUniformMatrix4fv(locMV, 1, false, glm::value_ptr(ModelViewMatrix));
Мой вершинный шейдер определяется следующим образом:
#version 400
layout(location = 0) in vec4 vVertex;
layout(location = 1) in vec4 vColor;
uniform mat4 P;
uniform mat4 MV;
out vec4 vFragColor;
void main(void)
{
vFragColor = vColor;
gl_Position = P * MV * vVertex;
}
Мой фрагментный шейдер тривиален - он просто выводит интерполированный цвет.
Теперь... вот вывод, который я получаю:
Если я изменю glFrontFace(GL_CCW);
в glFrontFace(GL_CW);
или, альтернативно, изменить glCullFace(GL_BACK)
в glCullFace(GL_FRONT)
Я получаю ожидаемый (по крайней мере, более ожидаемый, чем предыдущий, см. Второй и третий вопросы) рендеринг:
Я вижу здесь три проблемы, каждая из которых описана в вопросе:
АКТУАЛЬНЫЕ ВОПРОСЫ:
Q1: Почему обмотка обратная, что я задумал? Разве я не наматывал вершины против часовой стрелки для лицевых поверхностей?
Q2 Почему мое "левое" лицо и "правое" лицо поменялись местами? Левое лицо должно было быть желтым, а правое зеленым, а не наоборот! Что не так с моей трансформацией?
Q3 Что-то не так с моим преобразованием, потому что координата x моего вектора глаза положительна, что означает, что я должен видеть немного правой стороны, а не левой стороны!
Я задавал эти вопросы вместе, потому что я думаю, что они все связаны, и, вероятно, с чем-то очень базовым, что мне не хватает. Большое спасибо, что нашли время прояснить эти вещи.
1 ответ
OpenGL по умолчанию предполагает правостороннюю систему координат, то есть положительную ось Z, указывающую OUT экрана. Ваше положение вершин куба указывает на то, что вы принимаете левостороннюю систему координат. Однако, если вы поместите эти значения в RHS, то ваши координаты LHS против часовой стрелки станут по часовой стрелке (1), грани на одной оси поменяются местами (2), и ваши предполагаемые преобразования глаз пойдут в противоположном направлении (3).