一些opengl和glm解释
Posted
技术标签:
【中文标题】一些opengl和glm解释【英文标题】:some opengl and glm explanation 【发布时间】:2011-11-04 18:10:12 【问题描述】:有人可以解释一下以下几行的作用吗?
glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
angle = (GLfloat) (i % 360);
glm::mat4 View = glm::mat4(1.);
View = glm::translate(View, glm::vec3(0.f, 0.f, -5.0f));
View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f));
glm::mat4 Model = glm::mat4(1.0);
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "mvpmatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
他们将单位转换为像素,但我不确定他们是否这样做。我的另一个问题,更一般的问题是,我如何将一个数字(即 sin(90) = 1)表示为 10 像素、40 或任何数字?我如何指定 (0,0) 将在屏幕中间? glm 库是否已处理上述所有问题?
【问题讨论】:
【参考方案1】:第一行创建一个透视投影,相当于调用 gluPerspective(45.0f, 1.0f, 0.1f, 100.0f)。如果你不知道 gluPerspective 做什么,请查看link
glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
下一行只是将旋转角度取模为 360,以确保我们的投影角度小于 360 度。
angle = (GLfloat) (i % 360);
接下来的几行定义了我们的视图矩阵。这基本上是您的相机视口,即您在监视器上看到的内容。 translate 和 rotate 函数调用是用于将我们的相机移动到适当位置的转换函数调用
glm::mat4 View = glm::mat4(1.);
View = glm::translate(View, glm::vec3(0.f, 0.f, -5.0f));
View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f));
下一行定义我们模型的位置。在这种情况下,它将是 (1.0f, 1.0f, 1.0f, 1.0f)。如果你想知道为什么有 4 个参数而不是 3 个参数,请阅读 OpenGL 橙皮书或查看***homogeneous coordinates
glm::mat4 Model = glm::mat4(1.0);
最后两行通过计算模型视图投影矩阵并将其传递给 OpenGL 来完成我们的场景设置。
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "mvpmatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
总体而言,您的代码块所做的是模拟 OpenGL 的绘图管道,将模型坐标转换为视图坐标。
关于你问的第二个问题。我不明白第一部分,您将数字转换为像素是什么意思?您是否尝试将 1D 矩阵中的点映射到 2D 矩阵?如果是这种情况,只需执行标准映射,例如 pixel[index/rows][index%rows] 其中 pixel 是您的屏幕像素对象,index 是您的数组索引,row 是您的屏幕宽度。对于第二部分(如何将 (0,0) 设置为屏幕中间),我认为您需要做的只是为屏幕原点添加一个偏移量,因为 OpenGL 使用左手坐标系,即屏幕原点即 (0,0) 点将位于屏幕的左下角。因此,如果您希望您的系统位于屏幕中间,只需添加一个偏移量 (-width/2, -height/2) 以将您的点转换为 OpenGL 空间或 (width/2, height/2) 反之亦然投影。但建议不要考虑使用自己制定的标准。
【讨论】:
【参考方案2】:设置透视相机变换:
glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
将相机沿 Z 轴向下移动一点:
View = glm::translate(View, glm::vec3(0.f, 0.f, -5.0f));
围绕 X 轴向后旋转相机:
View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f));
围绕 Y 轴和 Z 轴旋转相机的速度是 X 轴的一半:
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f));
【讨论】:
以上是关于一些opengl和glm解释的主要内容,如果未能解决你的问题,请参考以下文章
opengl - 黑色纹理,如何在缓冲区上使用 glm::vec*?
Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?
我的OpenGL学习进阶之旅OpenGL ES开发如何引入GLM(OpenGL Mathematics)库?以及#include< >和#include“ ”的区别