Справка OpenGL о координатах в перспективе

#c #opengl

#c #opengl

Вопрос:

Это то, что долгое время (десятки часов) расстраивало меня перед компьютером и Google, но я все еще не решил это. Я довольно новичок в OpenGL, и последние 2-3 месяца я начал читать учебные пособия в сети, а также экспериментировать с некоторым кодом. Моя главная проблема заключается в том, что когда я перешел от ортографической проекции к перспективе, я все время ломал голову над тем, как управлять простой фигурой на экране и рисовать ее. Я очень мало знаю о матрицах, но дело в том, что в ортогональной проекции я указываю координаты x, y, z объекта, и это координаты окна. В перспективе я ничего не видел, как применяются координаты. Я видел диапазоны от -1 до 1 или даже от -20 до 20 и т.д. Я читал, что вы можете указать координаты в OpenGL, но как я должен это сделать? В орфографическом я делаю это:

Размер окна 800×600 я хочу, чтобы окно занимало все окно, поэтому,

 glVertex2i( 0, 600 );
glVertex2i( 0, 0 );
glVertex2i( 800, 0 );
glVertex2i( 800, 600 );
  

Но как насчет проекции?
Когда я ставлю 1, это в конце окна и -1 в начале.
Как opengl определяет начало / конец окна и почему это от -1 до 1???
Это чертовски запутанно, если бы кто-нибудь мог мне помочь, я был бы действительно признателен.
Спасибо.

Комментарии:

1. Ваше «Привет всем» было удалено из-за этого. meta.stackexchange.com/questions/2950/… Обратите внимание, что вы можете комментировать свои собственные вопросы

2. По сути, вы спрашиваете, как работают преобразования и как работает перспективная проекция. Это слишком сложно для ответа здесь, но мой учебник охватывает это (и многое другое). Обратите внимание, что, хотя это для начинающих, в нем используются шейдеры и избегается фиксированная функция.

3. спасибо 🙂 @NicolBolas я немного прочитал о преобразованиях и перспективе в Google, но это кажется очень глупым или, я должен сказать, не очень полезным. Конвейер рендеринга имеет несколько этапов, бла-бла-бла, которые преобразуют то-то и то-то в диапазон от -1 до 1, бла-бла-бла. Я не нашел в этом никакой важности, потому что ничто не упоминает ничего другого, кроме -1 и 1. Это сводит меня с ума… В любом случае, я загляну также в ваш tut и надеюсь, что что-нибудь узнаю. Большое спасибо

Ответ №1:

Сначала вы настраиваете свою проекцию и матрицы modelview для 3D-проекции:

 glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ratio, near_clip, far_clip);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz);
  

gluLookAt принимает 3 вектора: положение «глаза» камеры, вид в точку и «вектор вверх». Если вы вызываете gluLookAt(0.0, 0.0, -10.0, 0,0,0, 0,1,0) Это означает, что камера расположена на 0,0,-10 и смотрит вдоль оси z в начало координат 0,0,0, а «вверх» — вдоль положительной оси y. Если вы затем выполните простой вызов draw в opengl для одного квадрата, он должен появиться в вашем рендеринге:

 glColor3f(1.0f,1.0f,1.0f); //set white color (or any contrast to your background)
glBegin(GL_QUADS);
    glVertex3f(-1.0f, 1.0f, 0.0f);
    glVertex3f( 1.0f, 1.0f, 0.0f);
    glVertex3f( 1.0f,-1.0f, 0.0f);
    glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
  

Вы рисуете либо по часовой стрелке, либо против нее, но не в сочетании этих двух направлений. Вы можете управлять отбраковкой с помощью glEnable / Disable(GL_CULL_FACE) и glCullFace.

Размер окна 800×600 я хочу, чтобы окно занимало все окно, поэтому

При работе с 2D-проекциями (ортогональными) вы можете легко установить размер вашей системы координат в соответствии с размером вашего окна / видового экрана. Это неприменимо в 3D-проекции, поскольку теперь границами является усеченная точка 3D-просмотра или 3D-объем от ближнего клипа до дальних плоскостей клипа. Затем координаты проецируются на 2D-поверхность с помощью матрицы модель-вид-проекция. Вы можете легко ввести координаты, например, для квадрата шириной 800 и высотой 600, но чтобы увидеть это, вам нужно отвести камеру далеко, чтобы захватить весь квадрат в поле зрения.

Цитата из комментариев:

Предполагается, что gluPerspective (45.0f, (double) w / (double) h, 1.0f, 100.0f) задает перспективу с ближним = 1 и дальним = 100. Но поскольку OpenGL работает для правой руки, положительный z находится за пределами экрана, поэтому ближний должен быть равен 100, а дальний 1. Почему в каждом руководстве я вижу «близко» меньше, чем «далеко»? Это не имеет смысла..

Ответ (см. ссылку выше для просмотра в 3D-формате):

Усеченное изображение — это объем 3D в сцене, расположенный относительно камеры в окне просмотра. Форма объема влияет на то, как модели проецируются из пространства камеры на экран

Комментарии:

1. я знаю все это о настройке, моя главная проблема заключается в том, почему экран меняется с -1 на 1, а не на размер, который я установил (например, 800×600).

2. хм, так это означает, что если я введу координаты, которые я хочу для квадрата (в данном случае 800×600), я должен установить gluLookAt так, чтобы он располагался довольно далеко?

3. @Dimitris точно 🙂 если вам нужна перспективная / 3d проекция.

4. ага, большое спасибо 🙂 у меня есть еще один вопрос, такой: предполагается, что gluPerspective (45.0f, (double) w / (double) h, 1.0f, 100.0f) задает перспективу с ближним = 1 и дальним = 100. Но поскольку OpenGL работает для правой руки, положительный z находится за пределами экрана, поэтому ближний должен быть равен 100, а дальний 1. Почему в каждом руководстве я вижу «близко» меньше, чем «далеко»? Это не имеет смысла..

5. @Dimitris Плоскости отсечения расположены относительно камеры, поэтому независимо от ориентации камеры, например, при взгляде вдоль положительной оси z или отрицательной, это все равно что сказать «ближняя плоскость отсечения находится на расстоянии 1,0 фута от глаза, в то время как дальняя плоскость находится на расстоянии 100,0 фута от нее»