解释glOrtho()的用法?

我无法理解glOrtho的用法。 有人可以解释它用于什么吗?

更新

是否用于设置xy和z坐标限制的范围?

 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 

这意味着x,y和z范围从-1到1?

看看这个图片: graphics投影 在这里输入图像说明

glOrtho命令产生一个“斜”的投影,你可以在底部看到。 不pipe多远的顶点在z方向上,它们都不会退到远方。

每当我需要在OpenGL中使用glOrtho(每次窗口大小调整时使用下面的代码)来执行OpenGL中的2Dgraphics(例如健康栏,菜单等)时:

 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, windowWidth, windowHeight, 0.0f, 0.0f, 1.0f); 

这会将OpenGL坐标重新映射到等效像素值(X从0到windowWidth,Y从0到windowHeight)。 请注意,我翻转了Y值,因为OpenGL的坐标是从窗口的左下angular开始的。 所以通过翻转,我得到一个更传统的(0,0)在窗口的左上angular开始。

glOrtho :2D游戏,近远的物体出现相同的大小:

glFrustrum :像3D一样更真实,相同的物体越glFrustrum越显得更小:

 #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:摄像头是一个平面,可见卷为一个矩形:

在这里输入图像说明

Frustrum:相机是一个点,可见音量一个金字塔片:

在这里输入图像说明

图像源 。

参数

我们一直在寻找从+ Z到-Z和+ Y向上:

 glOrtho(left, right, bottom, top, near, far) 
  • left :我们看到的最小x
  • right :最大的x我们看到
  • bottom :我们看到的最小
  • top :我们看到的最大
  • -near :最小z我们看到。 是的 ,这是near -1倍。 所以负input意味着正z
  • 我们看到最大的z 也是负面的。

架构:

图像源 。

它是如何工作的

最后,OpenGL总是“使用”:

 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 

如果我们既不使用glOrtho也不使用glFrustrum ,那就是我们所得到的。

glOrthoglFrustrum只是线性变换(AKAmatrix乘法),所以:

  • glOrtho :将给定的3D矩形放入默认的立方体中
  • glFrustrum :将给定的金字塔部分放入默认的多维数据集中

这个转换然后被应用到所有的顶点。 这是我在2D中的意思:

图像源 。

转型后的最后一步很简单:

  • 删除立方体外的任何点(剔除):只要确保xyz[-1, +1]
  • 忽略z分量,只取xy ,现在可以放入2D屏幕

使用glOrthoz被忽略,所以你可能总是使用0

你可能想要使用z != 0一个原因是使精灵隐藏深度缓冲区的背景。

弃用

glOrtho从OpenGL 4.5开始不推荐使用:兼容性configuration文件12.1。 “固定functionVERTEX转换”是红色的。

所以不要用它来生产。 无论如何,理解这是获得OpenGL洞察力的好方法。

现代OpenGL 4程序在CPU上计算变换matrix(很小),然后给matrix和所有点转换为OpenGL,这样可以对不同的点进行数千个并行的matrix乘法。

手动编写的顶点着色器然后明确地进行乘法运算,通常使用OpenGL Shading Language的便捷vector数据types。

由于您明确地编写着色器,因此可以根据需要调整algorithm。 这种灵活性是更现代化的GPU的一个主要特征,它不同于那些用一些input参数进行固定algorithm的旧的algorithm,现在可以进行任意的计算。 另请参阅: 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的matrix非常简单,仅由缩放和平移组成:

 scalex, 0, 0, translatex, 0, scaley, 0, translatey, 0, 0, scalez, translatez, 0, 0, 0, 1 

正如OpenGL 2文档中提到的那样。

glFrustummatrix也不是很难计算,但开始变得烦人。 请注意,如果仅仅缩放和翻译,比如glOrtho ,就不能构成glOrtho ,更多信息请 glOrtho https://gamedev.stackexchange.com/a/118848/25171

GLM OpenGL C ++math库是计算这种matrix的stream行select。 http://glm.g-truc.net/0.9.2/api/a00245.html文件都是一个;orthofrustum操作。

glOrtho描述了一个产生平行投影的变换。 当前matrix(请参阅glMatrixMode)乘以该matrix,结果将replace当前matrix,就像glMultMatrix以下面的matrix作为参数调用一样:

OpenGL文档 (我的粗体)

数字定义剪辑平面的位置(左,右,下,上,近和远)。

“正常”投影是提供深度幻象的透视投影。 维基百科定义了一个平行投影:

平行投影具有在现实中和在投影平面上平行的投影线。

平行投影对应于具有假设视点的透视投影,例如,相机位于距物体无限远处并具有无限焦距或“缩放”的位置。