通常在引入VBO中的点坐标后就不会再修改它,于是通过变换来得到新图形就是必须的。
transform、translate、scale、rotate、lookAt、ortho、perspective
local、world、view、clip、screen space通过model、view、projection、viewport transform联系
计算变换矩阵通常利用OpenGL Mathematics库(GLM)完成,它是一个header-only库。
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
...
//in render loop
glm::mat4 transform = glm::mat4(1.0f);
//transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
//transform = glm::scale(transform, glm::vec3(0.5f, 1.0f, 1.0f));
//transform = glm::rotate(transform, (float)glm::radians(glfwGetTime()*18), glm::vec3(0.0f, 1.0f, 1.0f));
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(-45.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, 0.9f));
通过在shader源码中使用uniform传入。
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec4 vertexColor;
out vec2 texCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
void main()
{
gl_Position = view *model* vec4(aPos, 1.0);
vertexColor = vec4(aColor, 1.0);
texCoord = aTexCoord;
}
有一些要注意的点。
-
大多数如
glm::rotate()等便捷构造变换矩阵的函数没有对double类型的重载。 -
glm::rotate()是轴角旋转构造。scale、translate都是变换后相对于变换前的参数。(如0.5表示变小0.5或移动+0.5) -
只有在$[-1,1]^3$内的才会被渲染,这意味着如果没有用projection transform构建frustum,将会导致一些奇怪变化。
-
glm::lookAt和glm::ortho、glm::perspective分别是用于构建view和projection transform的简便方式,但是它们的参数含义要能够明确记住。 -
要使
glm::mat4能够传入,需要使用glm::value_ptr转换成指针。
comment 评论区
star_outline 咱快来抢个沙发吧!