好吧,您不必使用 glLoadMatrix 和其他内置矩阵函数,因为它可能比处理您自己的矩阵更困难。
一个没有控制的简单相机示例,它是一个静态相机:
glm::mat4x4 view_matrix = glm::lookAt(
cameraPosition,
cameraPosition+directionVector, //or the focus point the camera is pointing to
upVector);
它返回一个 4x4 矩阵,这是视图矩阵。
glm::mat4x4 projection_matrix =
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 1000.0f);
这是投影矩阵
所以现在你有了视图和投影矩阵,你可以将它发送到着色器:
gShader->bindShader();
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));
bindshader 是glUseProgram(shaderprog);
统一程序最简单的
void sendUniform4x4(const string& name, const float* matrix, bool transpose=false)
{
GLuint location = getUniformLocation(name);
glUniformMatrix4fv(location, 1, transpose, matrix);
}
您的模型矩阵对于您的每个对象都是单独的:
glm::mat4x4 model_matrix= glm::mat4(1); //this is the identity matrix, so its static
model_matrix= glm::rotate(model_matrix,
rotationdegree,
vec3(axis)); //same as opengl function.
这创建了一个模型矩阵,您也可以将其发送到您的着色器
gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));
创建矩阵的glm::value_ptr(...)
二维数组。
在您的着色器代码中不要使用 glModelViewMatrix 和 gl_ProjectionMatrix,矩阵是通过制服发送的。
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*gl_Vertex;
//i wrote gl_Vertex because of the glutSolidTeapot.
}
我从来没有使用过这个内置的网格函数,所以我不知道它是如何工作的,假设它使用 gl_Vertex 将顶点发送到立即模式的着色器。如果您创建自己的网格,请使用 VBO vertexattribpointer 和 drawarrays/elements。
不要忘记在发送制服之前绑定着色器。
所以有一个完整的例子:
glm::mat4x4 view_matrix = glm::lookAt(2,4,2,-1,-1,-1,0,1,0);
glm::mat4x4 projection_matrix =
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 10.0f);
glm::mat4x4 model_matrix= glm::mat4(1); //this remains unchanged
glm::mat4x4 teapot_model_matrix= glm::rotate(model_matrix, //this is the teapots model matrix, apply transformations to this
45,
glm::vec3(1,1,1));
teapot_model_matrix = glm::scale(teapot_model_matrix,vec3(2,2,2);
gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));
glutSolidCube(0.0); //i don't know what the (0.0) stands for :/
glutSwapBuffers();
//////////////////////////////
在你的着色器中:
uniform mat4 projection_matrix; //these are the matrixes you've sent
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*vec4(gl_Vertex.xyz,1);
}
现在你应该有一个位于 2,4,2 的相机,聚焦在 -1,-1,-1,并且向上的向量指向上方:)
茶壶围绕 (1,1,1) 向量旋转 45 度,并在每个方向上按 2 缩放。
更改模型矩阵后,将其发送到着色器,因此如果您有更多要渲染的对象,如果您希望对每个网格应用不同的变换,请在每个对象之后发送它。一个伪代码如下所示:
camera.lookat(camerapostion,focuspoint,updirection); //sets the view
camera.project(fov,aspect ratio,near plane, far plane) //and projection matrix
camera.sendviewmatrixtoshader;
camera.sendprojectionmatrixtoshader;
obj1.rotate(45 degrees, 1,1,1); //these functions should transform the model matrix of the object. Make sure each one has its own.
obj1.sendmodelmatrixtoshader;
obj2.scale(2,1,1);
obj2.sendmodelmatrixtoshader;
如果它不起作用,请尝试使用 vertexBuffer 以及您自己创建的简单三角形或立方体。