Как использовать glOrtho () в OpenGL?
Я не могу понять использование glOrtho. Может кто-нибудь объяснить для чего он используется?
используется ли он для установки диапазона X Y и Z координат предела?
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
это означает, что диапазон x, y и z составляет от -1 до 1?
3 ответов:
взгляните на эту картинку:Графические Проекции
The
glOrthoкоманда создает "косую" проекцию, которую вы видите в нижней строке. Независимо от того, как далеко вершины находятся в направлении z, они не будут отступать на расстояние.я использую glOrtho каждый раз, когда мне нужно сделать 2D-графику в OpenGL (например, бары здоровья, меню и т. д) используя следующий код каждый раз, когда окно размер:
glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, windowWidth, windowHeight, 0.0f, 0.0f, 1.0f);это приведет к переназначению координат OpenGL в эквивалентные значения пикселей (X от 0 до windowWidth и Y от 0 до windowHeight). Обратите внимание, что я перевернул значения Y, потому что координаты OpenGL начинаются с нижнего левого угла окна. Поэтому, перевернув, я получаю более обычный (0,0), начиная с верхнего левого угла окна.
glOrtho: 2D игры, объекты близко и далеко появляются одного и того же размера:
glFrustrum: более реальная жизнь, как 3D, идентичные объекты дальше появляются меньше:
код
#include <stdlib.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> static int ortho = 0; static void display(void) { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); if (ortho) { } else { /* This only rotates and translates the world around to look like the camera moved. */ gluLookAt(0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } glColor3f(1.0f, 1.0f, 1.0f); glutWireCube(2); glFlush(); } static void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (ortho) { glOrtho(-2.0, 2.0, -2.0, 2.0, -1.5, 1.5); } else { glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); } glMatrixMode(GL_MODELVIEW); } int main(int argc, char** argv) { glutInit(&argc, argv); if (argc > 1) { ortho = 1; } glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return EXIT_SUCCESS; }- схемы
Ortho: камера представляет собой плоскость, видимый объем прямоугольник:
разочарование: камера-это точка, видимый объем срез пирамиды:
параметры
мы всегда смотрим от +z до-z с +y вверх:
glOrtho(left, right, bottom, top, near, far)
leftминимальныеxмы видимright: Максxмы видимbottomминимальныеyмы видимtop: Максyмы смотрите-near: минимумzмы видим. да, это-1времениnear. Таким образом, отрицательный вход означает положительныйz.-far: Максzмы видим. Тоже отрицательно.схема:
как это работает под капотом
в конце концов, OpenGL всегда "использует":
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);если мы не используем ни один
glOrtho, ниglFrustrum, вот что мы получаем.
glOrthoиglFrustrumпросто линейные преобразования (АКА умножение матрицы) такие, что:
glOrtho: принимает заданный 3D прямоугольник в куб по умолчаниюglFrustrum: принимает заданный раздел пирамиды в куб по умолчаниюэта трансформация применяется ко всем вершинам. Вот что я имею в виду 2D:
последний шаг после преобразования прост:
- удалите все точки за пределами Куба (отбраковка): просто убедитесь, что
x,yиzв[-1, +1]- игнорировать
zкомпонент и взять толькоxиy, который теперь можно поместить в 2D-экранС
glOrtho,zигнорируется, так что вы может всегда использовать0.одна из причин, по которой вы можете использовать
z != 0это сделать спрайты скрыть фон с буфером глубины.осуждение
glOrthoосуждается по состоянию на OpenGL 4.5: профиль совместимости 12.1. "Преобразования вершин с фиксированной функцией" выделены красным цветом.так что не используйте его для производства. В любом случае, понимание этого-хороший способ получить некоторый OpenGL понимание.
современные программы OpenGL 4 вычисляют матрицу преобразования (которая мала) на CPU, а затем дают матрицу и все точки, которые будут преобразованы в OpenGL, что может сделать тысячи матричных умножений для разных точек Очень быстро параллельно.
написано вручную вершинных шейдеров затем выполните умножение явно, обычно с удобными векторными типами данных языка затенения OpenGL.
С тех пор вы пишете шейдер явно, это позволяет настроить алгоритм в соответствии с вашими потребностями. Такая гибкость является основной особенностью более современных графических процессоров, которые в отличие от старых, которые делали фиксированный алгоритм с некоторыми входными параметрами, теперь могут выполнять произвольные вычисления. См. также: https://stackoverflow.com/a/36211337/895245
с явным
GLfloat transform[]это будет выглядеть примерно так:#include <math.h> #include <stdio.h> #include <stdlib.h> #define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h> #include "common.h" static const GLuint WIDTH = 800; static const GLuint HEIGHT = 600; /* ourColor is passed on to the fragment shader. */ static const GLchar* vertex_shader_source = "#version 330 core\n" "layout (location = 0) in vec3 position;\n" "layout (location = 1) in vec3 color;\n" "out vec3 ourColor;\n" "uniform mat4 transform;\n" "void main() {\n" " gl_Position = transform * vec4(position, 1.0f);\n" " ourColor = color;\n" "}\n"; static const GLchar* fragment_shader_source = "#version 330 core\n" "in vec3 ourColor;\n" "out vec4 color;\n" "void main() {\n" " color = vec4(ourColor, 1.0f);\n" "}\n"; static GLfloat vertices[] = { /* Positions Colors */ 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }; int main(void) { GLint shader_program; GLint transform_location; GLuint vbo; GLuint vao; GLFWwindow* window; double time; glfwInit(); window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, WIDTH, HEIGHT); shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source); glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); /* Position attribute */ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); /* Color attribute */ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader_program); transform_location = glGetUniformLocation(shader_program, "transform"); /* THIS is just a dummy transform. */ GLfloat transform[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; time = glfwGetTime(); transform[0] = 2.0f * sin(time); transform[5] = 2.0f * cos(time); glUniformMatrix4fv(transform_location, 1, GL_FALSE, transform); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); glfwSwapBuffers(window); } glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glfwTerminate(); return EXIT_SUCCESS; }генерируется выходной: http://imgur.com/QVW14Gu
матрица для
glOrthoочень просто, состоит только из масштабирования и перевода:scalex, 0, 0, translatex, 0, scaley, 0, translatey, 0, 0, scalez, translatez, 0, 0, 0, 1как говорится в OpenGL 2 docs.
The
glFrustumматрица не слишком трудно вычислить вручную либо,но начинает раздражать. Обратите внимание, что усечение не может быть составлено только с масштабированием и переводами, такими какglOrtho, подробнее на: https://gamedev.stackexchange.com/a/118848/25171математическая библиотека GLM OpenGL C++ является популярным выбором для вычисления таких матриц. http://glm.g-truc.net/0.9.2/api/a00245.html документы оба
orthoиfrustumоперации.
glOrtho описывает преобразование, которое производит параллельно проекция. Текущая матрица (см. glMatrixMode) умножается на эту матрицу, и результат заменяет текущую матрицу, как если бы glMultMatrix вызывалась со следующей матрицей в качестве ее аргумента:
документация OpenGL (моя дерзость)
числа определяют расположение плоскостей отсечения (слева, справа, снизу, сверху, рядом и дальний.)
" нормальная " проекция-это перспективная проекция, которая создает иллюзию глубины. Википедия определяет параллельную проекцию как:
параллельные проекции имеют линии проекции, которые параллельны как в реальности, так и в плоскости проекции.
параллельная проекция соответствует перспективной проекции с гипотетической точкой зрения-например, когда камера находится на бесконечном расстоянии от объекта и имеет бесконечное фокусное расстояние, или "зум".







Comments