0评论

OpenGL glm矩阵变换

文章来自https://blog.csdn.net/lixiaoguang20/article/details/79483080 2019-03-14 37浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏开发行业精英群711501594

我们给我们的图形,设置好顶点坐标后,通过Model Matrix 变换为世界坐标,然后 view Matrix相机坐标,Projection Matrix 屏幕坐标x,y ∈(-1,1)。

矩阵变换的结果是把三维的世界最终裁剪为二维的屏幕,数学的说法就是从一个集合到另一个集合的映射。
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "glm.hpp"
#include "ext.hpp"
int main(void)
{
	GLFWwindow* window;
	/* Initialize the library */
	if (!glfwInit())
		return -1;
	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}
	/* Make the window's context current */
	glfwMakeContextCurrent(window);
	// Needed in core profile
	if( glewInit() != GLEW_OK)
	{
		glfwTerminate();
		return -1;
	}
	// An array of 3 vectors which represents 3 vertices
	static const GLfloat g_vertex_buffer_data[] = {
		-1.0f,-1.0f,0.0f,
		1.0f,-1.0f,0.0f,
		0.0f,1.0f,0.0f,
	};
	//This will identify our vertex buffer
	GLuint vertexbuffer;
	//Generate 1 buffer,put the resulting identifier in vertexbuffer
	glGenBuffers(1,&vertexbuffer);		
	//The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
	//Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
	GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
	glUseProgram(programID);
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
	/* Loop until the user closes the window */
	// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit  100 units
	//glm::mat4 Projection = glm::ortho(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, 0.1f, 100.0f);
	glm::mat4 Projection = glm::perspective(45.0f,4.0f/3.0f,0.1f,100.f);
	glm::mat4 View = glm::lookAt(
		glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
		glm::vec3(0,0,0), // and looks at the origin
		glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)		
		);
	// Model matrix : an identity matrix (model will be at the origin)
	glm::mat4 Model = glm::mat4(1.0f);
	Model = glm::translate(Model,glm::vec3(2.0f,0.0f,0.0f));
	Model = glm::rotate(Model,45.f,glm::vec3(0.0f,1.0f,0.0f));
	Model = glm::scale(Model,glm::vec3(1.0f,2.0f,1.0f));
	// Our ModelViewProjection : multiplication of our 3 matrices
	glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around
	// Get a handle for our "MVP" uniform.
	// Only at initialisation time.
	GLuint MatrixID = glGetUniformLocation(programID,"MVP");
	// Send our transformation to the currently bound shader,
	// in the "MVP" uniform
	// For each model you render, since the MVP will be different (at least the M part)
	glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);
	while (!glfwWindowShouldClose(window))
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(
			0,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			3,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			0,			// stride
			(void*)0	// array buffer offset
			);
		glDrawArrays(GL_TRIANGLES,0,3);// Starting from vertex 0; 3 vertices total -> 1 triangle
		glDisableVertexAttribArray(0);
		/* Swap front and back buffers */
		glfwSwapBuffers(window);
		/* Poll for and process events */
		glfwPollEvents();
	}
	glfwTerminate();
	return 0;
}

首先,model为一个单位矩阵,glm::mat4 Model = glm::mat4(1.0f);

然后平移,旋转,缩放,
Model = glm::translate(Model,glm::vec3(2.0f,0.0f,0.0f));
Model = glm::rotate(Model,45.f,glm::vec3(0.0f,1.0f,0.0f));
Model = glm::scale(Model,glm::vec3(1.0f,2.0f,1.0f));

最后通过矩阵乘法,连接到一起。

glm::mat4 Projection = glm::perspective(45.0f,4.0f/3.0f,0.1f,100.f);
glm::mat4 View = glm::lookAt(
glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);

// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around

得到shader中变量指针

GLuint MatrixID = glGetUniformLocation(programID,"MVP");

将矩阵传入shader

glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);

来看shader的语法:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;
void main(){
	vec4 v = vec4(vertexPosition_modelspace,1);
	gl_Position = MVP * v;
}

shader里将当前顶点与之前矩阵相乘。