gluPerspective, glViewport, gluLookAt и матрицы GL_PROJECTION и GL_MODELVIEW
Оригинальный вопрос
Я хочу использовать "gluPerspective", "glViewport" и "gluLookAt" для управления моей камерой и экраном.
Какие функции я применяю к какому режиму матрицы? И в каком порядке я / я должен их использовать?
Например, я пытаюсь настроить свой экран и камеру следующим образом: (но это не работает!)
glMatrixMode(GL_PROJECTION) // Apply following to projection matrix - is this correct?
glLoadIdentity(); // Reset first
glPerspective(45.0, (double)w/(double)h, 1.0, 200.0); // Set perspective
glViewport(0, 0, w, h); // Set viewport
glMatrixMode(GL_MODELVIEW); // Apply following to modelview - should glViewport come under here?
glLoadIdentity(); // Reset first
gluLookAt(px, py, pz, cx, cy, cz, ux, uy, uz); // Set position, centre and then up vectors
// This surely comes after calling GL_MODELVIEW?
Я искал онлайн документацию, и я понимаю функции, только не там, где они должны идти и в каком порядке!
Некоторое время спустя...
Прошло несколько месяцев, и я добавляю быстрое редактирование, чтобы показать систему, которую я использую для рендеринга с помощью OpenGL. Это поможет другим, кто увидит этот вопрос в будущем.
Я в основном использую два метода.
Способ 1:
Этот метод группирует все вместе.
// Firstly, the window may have been resized so re-create the viewing area
glViewport(0, 0, width_of_window_rendering_area, height_of_window_rendering area);
Это воссоздает область просмотра для рендеринга по всей области внутренней части окна. С sfml вы бы сделали что-то вроде window.width() или window.height(), или что-то похожее, в зависимости от того, какой инструментарий для работы с окнами вы используете (glut, glfw, sdl и т. Д.)...
// The second step is to add a projection matrix. There are three main ones I like to use
// Uncomment the one you want
glMatrixMode(GL_PROJECTION); // Tell OpenGL to manipulate the correct matrix stack
glLoadIdentity(); // Reset the projection matrix, or bad things happen after multiple calls to below functions!
// glOrtho( ... ) // Uncomment to use 2D rendering
// gluPerspective( ... ) // Uncomment to use (easy) 3D rendering
glFrustrum( ... ) // Uncomment to use (harder/less intuitive?) 3D rendering
glMatrixMode(GL_MODELVIEW); // I always prefer to leave OpenGL in the modelview manipulation mode.
// I consider it the "default" and safest mode to leave OpenGL in, as any rogue
// calls to functions changing its contents is likely to mess up your geometry
// which should be visible as a problem on the screen, which tells you you need
// to fix something! Manipulating the other matrix stacks may not show obvious
// problems.
Вам нужно будет выбрать один из трех вариантов: "glOrtho", "gluPerspective" и "glFrustrum". Существует также "gluOrtho2D", но используйте это с осторожностью! (Я предпочитаю указывать ближнюю и дальнюю плоскости самостоятельно с помощью "glOrtho".) Вам также необходимо заменить "..." аргументами функции.
// The third step is to clear the screen and set your camera / geometry position
glClear(GL_COLOR_BUFFER_BIT); // use bitwise OR ('||') with 'GL_DEPTH_BUFFER_BIT' and 'GL_STENCIL_BUFFER_BIT' if required
gluLookAt( ... );
// I like to use gluLookAt, or at least I _italic_used to! Now I implement my own camera...
// That is another fun thing you should try if you are comfortable with 3D geometry and hard math!
// The fourth step is to draw your scene. You may want to put lighting stuff first or in with the drawing
glutWireTeapot( ... );
Способ 2:
Второй метод такой же, как и выше, но для перемещения первого шага в отдельную функцию. Затем вы должны обнаружить события изменения размера окна и вызвать эту функцию. С переизбытком, вы можете указать обратный вызов. С SFML вы можете обнаружить событие при изменении размера окна. Я забыл, как работает SDL, но это похоже. Я еще не узнал, как работает GLFW.
Надеюсь, это поможет вам.
Некоторые новички в OpenGL (возможно, я в свое время включен) пытаются указать трансляцию камеры в матрице PROJECTION. Не делай этого - у меня в голове портится освещение и, возможно, другие вещи.
1 ответ
Я определяю мою функцию обратного вызова в форме:
Вызов glViewport(...)
один раз в начале.
Затем перезагрузите матрицу проекции с единичной матрицей:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
Затем:
glPerspective(...)
glMatrixMode(GL_MODELVIEW);
gluLookAt(...)
может быть вызван в любое время позже, если вам нужно изменить положение камеры.
Работает для моих простых целей.