OpenGL растянутые формы - соотношение сторон

Я получил представление openGL размером (скажем,..) 800 (ширина) x600 (высота). Затем я получил 2D-объект коордов:

0.0 , 0.0
0.1 , 0.0
0.1 , 0.1
0.0 , 0.1

это, как вы понимаете, должно быть квадратом (по аналогии). Но в моем представлении openGL это растягивается. Теперь я понимаю, почему это происходит. Его в основном потому, что im работает над матрицей по умолчанию -1,1. И поскольку мое разрешение 800x600 не имеет соотношения сторон 1, моя форма растягивается.

Теперь я больше заинтересован в том, как это исправить. Ive читал о таких функциях, как glFrustum, glOrtho, glViewPort, которые происходят на матрице проекций и могут решать такие проблемы. Дело в том, что я не уверен в их использовании. То, что я в основном хочу, это сохранить вышеописанные координаты при создании квадрата и на самом деле отображаться как квадрат на моем представлении.

Каков правильный способ решения этой проблемы?

Ответ 1

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float)width / (float)height;
glOrtho(-aspect, aspect, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Обновление: Объяснение, что произойдет

OpenGL - это конечный автомат, а в случае OpenGL-2.1 и ниже поддерживается набор матриц преобразования. Вершина ↑ v сначала умножается на матрицу модели, чтобы получить верхушку координаты глаза ↑ v ', которая используется для подсчета освещения. Затем ↑ v ' умножается на матрицу проекции, чтобы достичь так называемого пространства клипов ↑ v' ', где (название указывает на это) выполняются операции отсечения (или по крайней мере, их результат определяется). Из пространства клипа так называемые координаты нормализованных устройств (NDC) достигаются путем вычисления ↑ v # {x, y, z, w} = ↑ v {x, y, г, ш}/ ↑ v _W

↑ v # определяется как находящийся в диапазоне [-1... 1], который отображается для заполнения выбранного прямоугольника просмотра. Видовой экран не влияет на матрицы преобразования! Это только преобразование от NDC к координатам окна, которые он определяет.

В вышеприведенном коде я устанавливаю матрицу просмотра модели на тождество, т.е. вершины попадают в проекцию так, как они есть. Сама проекция представляет собой ортопроекцию, которая отображает диапазон значений х [-аспект... аспект] → [-1... 1] и диапазон значений y [-1... 1] → [-1... 1] (т.е. без изменений для y). Таким образом, вершины преобразуются в аспект окна, чтобы вписаться в диапазон значений в области просмотра.

И почему я сказал вам, что OpenGL - это конечный автомат? Потому что это означает, что вы можете переключать проекции и преобразования в любое время. Поэтому, если вам нужно отобразить мини-карту, не пытайтесь ее помещать в 3D-сцену. Просто установите для него видовое окно и проекцию. В общем случае вы должны установить все состояние отображения (что означает все матрицы) в функции рисования. Обработчики событий окна (кроме обработчика перерисовывания) вообще не должны выполнять никаких операций OpenGL.