Ортогональная проекция для 2D-рендеринга с помощью современного OpenGL

Я пытаюсь портировать старую игру SDL, которую я написал некоторое время назад, на 3.3+ OpenGL, и у меня возникли некоторые проблемы с получением правильной ортогональной матрицы и соответствующей ей точки зрения.

    glm::mat4 proj = glm::ortho( 0.0f, static_cast<float>(win_W), static_cast<float>(win_H), 0.0f,-5.0f, 5.0f);

Если я просто использую эту проекцию и попытаюсь отобразить, скажем, четырехугольник в границах win_W и win_H, это сработает. Однако, если вместо этого я пытаюсь смоделировать камеру, используя:

   glm::mat4 view = glm::lookAt(
glm::vec3(0.0f, 0.0f, 1.0f),//cam pos
glm::vec3(0.0f, 0.0f, 0.0f),//looking at
glm::vec3(0.0f, 0.0f, 1.0f)//floored
);

Я ничего не получаю. Даже при размещении квадратора в центре, то же самое, если вместо этого я центрирую вид:

  glm::mat4 view = glm::lookAt(
glm::vec3(static_cast<float>(win_W), static_cast<float>(winH), 1.0f),//cam pos
glm::vec3(static_cast<float>(win_W), static_cast<float>(winH), 0.0f),//looking at
glm::vec3(0.0f, 0.0f, 1.0f)//floored
);

Учитывая, что SDL обычно вычитает значения камеры из вершин в игре, чтобы имитировать вид, лучше просто заменить мою MVP-операцию в шейдере следующим образом:

#version 150

in vec2 position;
in vec3 color;

out vec3 Color;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 camera;

void main()
{
Color = color;
//faulty view
//gl_Position = projection *view * model * vec4(position, 0.0, 1.0);
//new SDL style camera
mat4 newPosition = projection * model * vec4(position, 0.0, 1.0);
gl_Position = newPosition - camera;
}

К сожалению, источник, из которого я учусь (книга ArcSynthesis), не охватывает вид, который включает систему координат, отличную от NDC по умолчанию. И по какой-то причине даже сегодня большинство дискуссий об opengl касаются устаревших версий.
Короче говоря, каков наилучший способ настроить представление на матрицу ортогональной проекции для простого 2D-рендеринга в современном opengl?

1

Решение

Ваш поисковый вызов на самом деле не имеет смысла вообще, так как ваш up вектор (0,0,1) является коллинеарным направлению обзора (0,0, -1). Это не даст полезную матрицу.

Вы, вероятно, хотите (0,1,0) как up вектор. Однако, даже если вы измените это, вы можете быть удивлены результатом. В сочетании с установленной матрицей проекции точка, указанная вами в качестве целевой цели, будет отображаться не в центре, а на угол экрана. Ваша проекция не отображается (0,0) на центр, что обычно предполагается при использовании некоторых LookAt функция.

Я согласен с комментарием полковника тридцать второго: не использовать LookAt в этом сценарии, если у вас нет очень веских причин.

1

Другие решения


По вопросам рекламы [email protected]