learnOpenGL-摄像机

glm::lookAt(eye, center, up);
eye 表示摄像机所在位置,
center 表示摄像机要看向的中心点的位置,即正在查看的位置(一个位置)。如果要使用方向向量D而不是中心位置,则可以简单地使用eye + D作为中心位置,其中D可以是单位向量
up 表示摄像机的三个方位向量中的up向量。

main.cpp

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "shader.h"
#include "stb_image.h"
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Camera.h"

GLfloat vertices[] = {
    
    
	-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
	 0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
	-0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

	-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f
};

GLuint indices[] = {
    
    
	0, 1, 3,
	1, 2, 3
};

GLfloat mixAlpha = 0.2;

//十个立方体的位置向量
glm::vec3 cubePositions[] = {
    
    
  glm::vec3(0.0f,  0.0f,  0.0f),
  glm::vec3(2.0f,  5.0f, -15.0f),
  glm::vec3(-1.5f, -2.2f, -2.5f),
  glm::vec3(-3.8f, -2.0f, -12.3f),
  glm::vec3(2.4f, -0.4f, -3.5f),
  glm::vec3(-1.7f,  3.0f, -7.5f),
  glm::vec3(1.3f, -2.0f, -2.5f),
  glm::vec3(1.5f,  2.0f, -2.5f),
  glm::vec3(1.5f,  0.2f, -1.5f),
  glm::vec3(-1.3f,  1.0f, -1.5f)
};

Camera* myCamera = new Camera(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));

void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
    
    
	myCamera->mouseCb(xpos, ypos);
};

void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
    
    
	myCamera->scrollCb(xoffset, yoffset);
}

GLfloat deltaTime = 0.0f;   // 当前帧与上一帧的时间差
GLfloat lastFrame = 0.0f;   // 上一帧的时间

void processInput(GLFWwindow* window) {
    
    
	GLfloat currentFrame = glfwGetTime();
	deltaTime = currentFrame - lastFrame;
	lastFrame = currentFrame;
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
	if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
    
    
		mixAlpha += 0.1;
		if (mixAlpha > 1.0) mixAlpha = 1.0;
	}
	if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
		mixAlpha -= 0.1;
		if (mixAlpha < 0.0) mixAlpha = 0.0;
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
    
    
		myCamera->pressKeyW(deltaTime);
	}
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
    
    
		myCamera->pressKeyS(deltaTime);
	}
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
    
    
		myCamera->pressKeyA(deltaTime);
	}
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
    
    
		myCamera->pressKeyD(deltaTime);
	}
}

int main()
{
    
    
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(800, 600, "test", nullptr, nullptr);
	if (window == nullptr)
	{
    
    
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//隐藏光标,并捕捉(Capture)它

	glfwSetCursorPosCallback(window, mouse_callback);
	glfwSetScrollCallback(window, scroll_callback);

	glewExperimental = GL_TRUE;
	if (glewInit() != GLEW_OK)
	{
    
    
		std::cout << "Failed to initialize GLEW" << std::endl;
		glfwTerminate();
		return -1;
	}

	glViewport(0, 0, 800, 600);

	GLuint VAO;
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	GLuint VBO;
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	GLuint EBO;
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);

	glBindVertexArray(0);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	int width, height;
	unsigned char* image = stbi_load("container.jpg", &width, &height, 0, 0);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

	glGenerateMipmap(GL_TEXTURE_2D);

	stbi_image_free(image);

	glBindTexture(GL_TEXTURE_2D, 0);

	GLuint texture1;
	glGenTextures(1, &texture1);
	glBindTexture(GL_TEXTURE_2D, texture1); 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	int width1, height1;
	unsigned char* image1 = stbi_load("awesomeface.png", &width1, &height1, 0, 0);
	if (image1) {
    
    
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width1, height1, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else {
    
    
		std::cout << "Failed to load texture" << std::endl;
	}
	stbi_image_free(image1);

	//glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);//定义摄像机位置

	//glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);
	//glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);
	摄像机方向,注意是指向的向量,朝z轴正向,而非注视的方向
	方向向量是指向它到目标向量的相反方向,上述是摄像机指向远点(0,0,0)目标向量(z轴3.0指向0.0)的相反方向,即z轴正向。

	//glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);//定义一个上向量
	//glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
	上向量与摄像机方向向量叉乘,获得右向量(指向摄像机空间x轴的正向)。交换叉乘顺序,则指向x轴负向。

	//glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);//摄像机x轴与z轴叉乘,获取摄像机y轴

	/* 三个轴加一个平移向量可创建lookAt矩阵,以此矩阵乘任何向量,即可将向量变换至摄像机的坐标空间。
		lookAt矩阵[ Rx,Ry,Rz,0		[1,0,0,-Px
					Ux,Uy,Uz,0		 0,1,0,-Py
					Dx,Dy,Dz,0   *	 0,0,1,-Pz
					0, 0, 0, 1]		 0,0,0, 1]
		R是右向量,U是上向量,D是方向向量,P为摄像机位置。
	*/

	/*glm::mat4 view;
	view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f),
		glm::vec3(0.0f, 0.0f, 0.0f),
		glm::vec3(0.0f, 1.0f, 0.0f));*/
	//lookAt直接创建观察矩阵。参数:1.摄像机位置,2.目标位置,3.上向量

	Shader* testShader = new Shader("test.vert", "test.frag");

	//创建模型矩阵
	glm::mat4 model;

	//投影矩阵
	glm::mat4 projection;

	glEnable(GL_DEPTH_TEST);

	testShader->Use();
	//给shader传值前,先激活要使用的program

	while (!glfwWindowShouldClose(window))
	{
    
    
		processInput(window);
		glfwPollEvents();

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);//清除前一帧的深度信息

		/*direction.y = sin(glm::radians(pitch));
		direction.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
		direction.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));*/

		/*GLfloat radius = 10.0f;
		GLfloat camX = sin(glfwGetTime()) * radius;
		GLfloat camZ = cos(glfwGetTime()) * radius;
		glm::mat4 view;
		view = glm::lookAt(glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));*/
		//围绕场景旋转的观察矩阵

		glm::mat4 view = myCamera->getViewMat4();
		glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "view"), 1, GL_FALSE, glm::value_ptr(view));

		projection = glm::perspective(glm::radians(myCamera->getFov()), 800.0f / 600.0f, 0.1f, 100.0f);
		glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture); 
		glUniform1i(glGetUniformLocation(testShader->getProgram(), "ourTexture"), 0); 

		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture1);
		glUniform1i(glGetUniformLocation(testShader->getProgram(), "ourTexture1"), 1);

		glUniform1f(glGetUniformLocation(testShader->getProgram(), "mixAlpha"), mixAlpha);

		glBindVertexArray(VAO);
		//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		for (GLuint i = 0; i < 10; i++)
		{
    
    
			glm::mat4 model;
			model = glm::translate(model, cubePositions[i]);
			GLfloat angle = 20.0f * i;
			if (i % 3 == 0) model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f));
			glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "model"), 1, GL_FALSE, glm::value_ptr(model));

			glDrawArrays(GL_TRIANGLES, 0, 36);
		}

		glBindVertexArray(0);

		glfwSwapBuffers(window);
	}


	glfwTerminate();
	return 0;
}

Camera.h

#pragma once
#ifndef CAMERA_H
#define CAMERA_H
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>

class Camera
{
    
    
	public:
		Camera(glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 cameraUp);
		void mouseCb(double xpos, double ypos);
		void scrollCb(double xoffset, double yoffset);
		void pressKeyW(GLfloat deltaTime);
		void pressKeyS(GLfloat deltaTime);
		void pressKeyA(GLfloat deltaTime);
		void pressKeyD(GLfloat deltaTime);

		glm::mat4 getViewMat4();
		GLfloat getFov() {
    
     return this->fov; };
	private:
		GLfloat cameraSpeed = 0.05f;
		glm::vec3 cameraPos;
		glm::vec3 cameraFront;
		glm::vec3 cameraUp;

		GLfloat lastX = 400, lastY = 300;//鼠标初始位置
		GLfloat pitch = 0.0f, yaw = -90.0f;
		bool firstMouse = true;

		GLfloat fov = 45.0f;
};

#endif

Camera.cpp

#include "Camera.h"

Camera::Camera(glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 cameraUp) {
    
    
	this->cameraPos = cameraPos;
	this->cameraFront = cameraFront;
	this->cameraUp = cameraUp;
}

//xpos和ypos代表当前鼠标的位置。储存上一帧鼠标的位置,通关当前鼠标与上一帧鼠标位置差值计算偏航角与俯仰角
void Camera::mouseCb(double xpos, double ypos) {
    
    
	if (this->firstMouse)
	{
    
    
		this->lastX = xpos;
		this->lastY = ypos;
		this->firstMouse = false;
	}
	GLfloat xoffset = xpos - this->lastX;
	GLfloat yoffset = this->lastY - ypos; // 注意这里是相反的,因为y坐标的范围是从下往上的

	this->lastX = xpos;
	this->lastY = ypos;

	GLfloat sensitivity = 0.05f;
	xoffset *= sensitivity;
	yoffset *= sensitivity;

	this->yaw += xoffset;
	this->pitch += yoffset;
	//限制不能高于89度,90度时视角会逆转
	if (this->pitch > 89.0f)
		this->pitch = 89.0f;
	if (this->pitch < -89.0f)
		this->pitch = -89.0f;

	glm::vec3 front;
	front.x = cos(glm::radians(this->pitch)) * cos(glm::radians(this->yaw));
	front.y = sin(glm::radians(this->pitch));
	front.z = cos(glm::radians(this->pitch)) * sin(glm::radians(this->yaw));
	this->cameraFront = glm::normalize(front);
}

//鼠标滚轮控制视野,yoffset为滚动大小
void Camera::scrollCb(double xoffset, double yoffset)
{
    
    
	if (this->fov >= 1.0f && this->fov <= 45.0f)
		this->fov -= yoffset;
	if (this->fov <= 1.0f)
		this->fov = 1.0f;
	if (this->fov >= 45.0f)
		this->fov = 45.0f;
}

void Camera::pressKeyW(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyS(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyA(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

void Camera::pressKeyD(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

glm::mat4 Camera::getViewMat4() {
    
    
	//摄像机位置加定义的方向向量,保证摄像机无论在哪,都会注视目标
	return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
}

练习一:

#include "Camera.h"

Camera::Camera(glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 cameraUp) {
    
    
	this->cameraPos = cameraPos;
	this->cameraFront = cameraFront;
	this->cameraUp = cameraUp;
}

//xpos和ypos代表当前鼠标的位置。储存上一帧鼠标的位置,通关当前鼠标与上一帧鼠标位置差值计算偏航角与俯仰角
void Camera::mouseCb(double xpos, double ypos) {
    
    
	if (this->firstMouse)
	{
    
    
		this->lastX = xpos;
		this->lastY = ypos;
		this->firstMouse = false;
	}
	GLfloat xoffset = xpos - this->lastX;
	GLfloat yoffset = this->lastY - ypos; // 注意这里是相反的,因为y坐标的范围是从下往上的

	this->lastX = xpos;
	this->lastY = ypos;

	GLfloat sensitivity = 0.05f;
	xoffset *= sensitivity;
	yoffset *= sensitivity;

	this->yaw += xoffset;
	this->pitch += yoffset;
	//限制不能高于89度,90度时视角会逆转
	if (this->pitch > 89.0f)
		this->pitch = 89.0f;
	if (this->pitch < -89.0f)
		this->pitch = -89.0f;

	glm::vec3 front;
	front.x = cos(glm::radians(this->pitch)) * cos(glm::radians(this->yaw));
	front.y = sin(glm::radians(this->pitch));
	front.z = cos(glm::radians(this->pitch)) * sin(glm::radians(this->yaw));
	this->cameraFront = glm::normalize(front);
}

//鼠标滚轮控制视野,yoffset为滚动大小
void Camera::scrollCb(double xoffset, double yoffset)
{
    
    
	if (this->fov >= 1.0f && this->fov <= 45.0f)
		this->fov -= yoffset;
	if (this->fov <= 1.0f)
		this->fov = 1.0f;
	if (this->fov >= 45.0f)
		this->fov = 45.0f;
}

void Camera::pressKeyW(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyS(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyA(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

void Camera::pressKeyD(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

glm::mat4 Camera::getViewMat4() {
    
    
	//摄像机位置加定义的方向向量,保证摄像机无论在哪,都会注视目标
	this->cameraPos.y = 0.0f;
	return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
}

练习二

#include "Camera.h"

Camera::Camera(glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 cameraUp) {
    
    
	this->cameraPos = cameraPos;
	this->cameraFront = cameraFront;
	this->cameraUp = cameraUp;
}

//xpos和ypos代表当前鼠标的位置。储存上一帧鼠标的位置,通关当前鼠标与上一帧鼠标位置差值计算偏航角与俯仰角
void Camera::mouseCb(double xpos, double ypos) {
    
    
	if (this->firstMouse)
	{
    
    
		this->lastX = xpos;
		this->lastY = ypos;
		this->firstMouse = false;
	}
	GLfloat xoffset = xpos - this->lastX;
	GLfloat yoffset = this->lastY - ypos; // 注意这里是相反的,因为y坐标的范围是从下往上的

	this->lastX = xpos;
	this->lastY = ypos;

	GLfloat sensitivity = 0.05f;
	xoffset *= sensitivity;
	yoffset *= sensitivity;

	this->yaw += xoffset;
	this->pitch += yoffset;
	//限制不能高于89度,90度时视角会逆转
	if (this->pitch > 89.0f)
		this->pitch = 89.0f;
	if (this->pitch < -89.0f)
		this->pitch = -89.0f;

	glm::vec3 front;
	front.x = cos(glm::radians(this->pitch)) * cos(glm::radians(this->yaw));
	front.y = sin(glm::radians(this->pitch));
	front.z = cos(glm::radians(this->pitch)) * sin(glm::radians(this->yaw));
	this->cameraFront = glm::normalize(front);
}

//鼠标滚轮控制视野,yoffset为滚动大小
void Camera::scrollCb(double xoffset, double yoffset)
{
    
    
	if (this->fov >= 1.0f && this->fov <= 45.0f)
		this->fov -= yoffset;
	if (this->fov <= 1.0f)
		this->fov = 1.0f;
	if (this->fov >= 45.0f)
		this->fov = 45.0f;
}

void Camera::pressKeyW(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyS(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= this->cameraSpeed * this->cameraFront;
}

void Camera::pressKeyA(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos -= glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

void Camera::pressKeyD(GLfloat deltaTime) {
    
    
	this->cameraSpeed = 2.5f * deltaTime;
	this->cameraPos += glm::normalize(glm::cross(this->cameraFront, this->cameraUp)) * this->cameraSpeed;
}

glm::mat4 Camera::getViewMat4() {
    
    
	//摄像机位置加定义的方向向量,保证摄像机无论在哪,都会注视目标
	this->cameraPos.y = 0.0f;
	//return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
	glm::vec3 cameraZ = glm::normalize(cameraPos - cameraFront);
	glm::vec3 cameraX = glm::normalize(glm::cross(cameraUp, cameraZ));
	glm::vec3 cameraY = glm::cross(cameraZ, cameraX);

	//注意:mat4是按列存储矩阵信息。即mat4数组第一行为矩阵第一列的信息。
	glm::mat4 translation = glm::mat4(1.0f);
	translation[0][0] = cameraX.x;
	translation[0][1] = cameraY.x;
	translation[0][2] = cameraZ.x;
	translation[1][0] = cameraX.y;
	translation[1][1] = cameraY.y;
	translation[1][2] = cameraZ.y;
	translation[2][0] = cameraX.z;
	translation[2][1] = cameraY.z;
	translation[2][2] = cameraZ.z;
	glm::mat4 translation1 = glm::mat4(1.0f);
	translation1[3][0] = -cameraPos.x;
	translation1[3][1] = -cameraPos.y;
	translation1[3][2] = -cameraPos.z;
	return translation * translation1;
}

猜你喜欢

转载自blog.csdn.net/Mhypnos/article/details/130629451