目录
答:就是将三维物体映射到摄像机屏幕的过程。
在线性代数中,变换=矩阵,任何3D变化都可以通过矩阵来表示。
那么问题来了,如何将三维物体映射到屏幕空间呢?
答:经过MVP变换。
这里不对MVP变换做过多的展开,详细理论可参考GAMES101的课程。
那么如何变换呢?如何获得物体在观察坐标系下的位置呢?
不失一般性,我们考虑一个简单的情况,即观察坐标系与世界坐标系平行:
但更一般的情况是:摄像机空间与世界空间存在一定的角度:
那此时如何得到物体在摄像机空间的相对位置呢?
答:可以将摄像机移动到世界坐标系原点,然后将摄像机坐标系的三个正交基旋转至与世界坐标系重合。
但问题来了,如何获得这个旋转矩阵呢?这个矩阵并不好算。
但我们可以曲线救国,利用矩阵的逆。
既然直接求摄像机空间旋转至世界空间不好求,那我们可以把世界空间旋转至摄像机空间,并获得一个矩阵,然后再求这个矩阵的逆,即为摄像机空间旋转至世界空间的变换矩阵。
投影分两种:
投影变换的目标是:将空间中的点P变换到摄像机平面坐标系内,并且做成NDC(标准设备坐标)的形式。NDC为了兼容不同窗口的宽高,让x与y的都同一到(-1,1)范围内,之后各自乘以宽高
空间中的点投射到屏幕近剪裁平面的坐标。
过多的数学推导这里不做展示,直接给出结果:
下载并载入glm第三方库:
类似之前实践的思路,我们需要更改和设置:
- #include "Base.h"
- #include "Shader.h"
- #include "ffImage.h"
-
- void framebuffer_size_callback(GLFWwindow* window, int width, int height);
- void processInput(GLFWwindow* window);
- void initModel();
- void initShader(const char* _vertexPath, const char* _fragPath);
- void initTexture();
- void render();
-
- unsigned int VBO = 0;
- unsigned int VAO = 0;
- unsigned int EBO = 0;
- unsigned int _texture = 0;
-
- Shader _shader;
- ffImage* _pImage = nullptr;
-
- glm::mat4 _viewMatrix(1.0f);
- glm::mat4 _projMatrix(1.0f);
- int _width = 800;
- int _height = 600;
-
- int main() {
- //初始化OpenGL上下文环境,OpenGL是一个状态机,会保存当前状态下的渲染状态以及管线的状态
- glfwInit();
- //,3版本以上
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- //用OpenGL核心开发模式
- glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
-
- //创建窗体
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGl Core", nullptr, nullptr);
- if (window == nullptr) {
- std::cout << "Failed to create GLFW window" << std::endl;
- glfwTerminate();
- return -1;
- }
- //把当前上下文绑定至当前窗口
- glfwMakeContextCurrent(window);
-
- //通过glad绑定各种函数指针
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- std::cout << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
-
- //视口:需要渲染的东西在哪里
- glViewport(0, 0, _width, _height);
- //当Frame大小变动,调用回调函数调整视口大小
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
-
- initModel();
- initShader("vertexShader.glsl", "fragmentShader.glsl");
- initTexture();
-
- //防止窗口结束退出
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- render();
-
- //双缓冲
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
-
- //结束,释放资源
- glfwTerminate();
- return 0;
-
- }
-
- void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
- glViewport(0, 0, width, height);
- }
-
- void processInput(GLFWwindow* window) {
- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
- glfwSetWindowShouldClose(window, true);
- }
- }
-
- //渲染
- void render() {
- //擦除画布,用定义的颜色填充
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
-
- //眼睛(摄像机)位置,看向位置,摄像机上方位置
- _viewMatrix = glm::lookAt(
- glm::vec3(3.0f, 3.0f, 3.0f),
- glm::vec3(0.0f, 0.0f, 0.0f),
- glm::vec3(0.0f, 1.0f, 0.0f));
- //透视投影矩阵:视锥角,宽高比,近平面,远平面
- _projMatrix = glm::perspective(
- glm::radians(45.0f),
- (float)_width / (float)_height,
- 0.1f,
- 100.0f);
-
- glBindTexture(GL_TEXTURE_2D, _texture);
- _shader.start();
- _shader.setMatrix("_viewMatrix", _viewMatrix);
- _shader.setMatrix("_projMatrix", _projMatrix);
- glBindVertexArray(VAO);
- glDrawArrays(GL_TRIANGLES, 0, 36);
- _shader.end();
- }
-
- //构建模型数据:VBO,VAO
- void initModel() {
- //float vertices[] = {
- // //顶点信息 颜色信息 纹理信息
- // 0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f,1.0f,
- // 0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.0f, 1.0f,0.0f,
- // -0.5f, -0.5f, 0.0f, 0.0f,0.0f,1.0f, 0.0f,0.0f,
- // -0.5f, 0.5f, 0.0f, 0.0f,1.0f,0.0f, 0.0f,1.0f
- //};
-
- float 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
- };
-
- glGenVertexArrays(1, &VAO);
- glBindVertexArray(VAO);
-
- //之后的VBO便属于了VAO的管理范围
- glGenBuffers(1, &VBO);
- //绑定哪一种buffer,
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- //分配显存:分配哪种buffer,分配显存大小,分配地址,使用数据的方式
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- //对哪个锚点进行操作:layout=0的锚点,读3个顶点,类型为float,不需要归一化,每次步长为3个float大小,从0处开始读
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(sizeof(float)*3));
-
- //打开锚点:激活
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- //解绑
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
-
- //
- void initShader(const char* _vertexPath, const char* _fragPath) {
-
- _shader.initShader(_vertexPath, _fragPath);
- }
-
- void initTexture() {
- _pImage = ffImage::readFromFile("res/wall.jpg");
- //纹理绑定
- glGenTextures(1, &_texture);
- glBindTexture(GL_TEXTURE_2D, _texture);
- //纹理属性设置
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //读入图片数据
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _pImage->getWidth(), _pImage->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,_pImage->getData());
- }
- //vertexShader.glsl
- #version 330 core
- layout (location = 0) in vec3 aPos;
- layout (location = 1) in vec2 aUV;
-
- out vec2 outUV;
-
- uniform mat4 _modelMatrix;
- uniform mat4 _viewMatrix;
- uniform mat4 _projMatrix;
-
-
- void main()
- {
- gl_Position = _projMatrix * _viewMatrix * _modelMatrix * vec4(aPos.x, aPos.y, aPos.z, 1.0);
- outUV = aUV;
- };
- //fragmentShader.glsl
- #version 330 core
- out vec4 FragColor;
-
- in vec2 outUV;
-
- uniform sampler2D outTexture;
-
- void main()
- {
- FragColor = texture(outTexture, outUV) ;
- };
这里绘制10个立方体,对每一个立方体先进行一个平移操作,并且进行旋转操作
- //渲染
- void render() {
- //擦除画布,用定义的颜色填充
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
-
- glm::vec3 modelVecs[] = {
- 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)
- };
-
- _viewMatrix = 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));
- _projMatrix = glm::perspective(glm::radians(45.0f), (float)_width / (float)_height, 0.1f, 100.0f);
-
- glBindTexture(GL_TEXTURE_2D, _texture);
-
- for (int i = 0; i < 10; i++)
- {
- glm::mat4 _modelMatrix(1.0f);//单位阵
- _modelMatrix = glm::translate(_modelMatrix, modelVecs[i]);//平移
- _modelMatrix = glm::rotate(_modelMatrix, glm::radians((float)glfwGetTime() * (i + 1) * 10), glm::vec3(0.0f, 1.0f, 0.0f));
-
- _shader.start();
- _shader.setMatrix("_modelMatrix", _modelMatrix);
- _shader.setMatrix("_viewMatrix", _viewMatrix);
- _shader.setMatrix("_projMatrix", _projMatrix);
- glBindVertexArray(VAO);
- glDrawArrays(GL_TRIANGLES, 0, 36);
- _shader.end();
- }
- }
需要完成的任务:
摄像机类:
- //Camera.h
- #pragma once
- #include "Base.h"
-
- enum class CAMERA_MOVE{
- MOVE_LEFT,
- MOVE_RIGHT,
- MOVE_FRONT,
- MOVE_BACK
- };
-
- class Camera
- {
- private:
- glm::vec3 m_position;
- glm::vec3 m_front;
- glm::vec3 m_up;
- float m_speed;
-
- glm::mat4 m_vMatrix;
-
- public:
- Camera() {
- m_position = glm::vec3(1.0f);
- m_front= glm::vec3(1.0f);
- m_up = glm::vec3(1.0f);
- m_speed = 0.01f;
-
- m_vMatrix = glm::mat4(1.0f);
- }
- ~Camera() {}
-
- void lookAt(glm::vec3 _pos, glm::vec3 _front, glm::vec3 _up);
- void update();
- glm::mat4 getMatrix() { return m_vMatrix; }
- void move(CAMERA_MOVE _mode);
- void setspeed(float _speed);
- };
-
-
- //Camera.cpp
- #include "Camera.h"
-
- void Camera::lookAt(glm::vec3 _pos, glm::vec3 _front, glm::vec3 _up)
- {
- m_position = _pos;
- m_front = glm::normalize(_front);
- m_up = _up;
- m_vMatrix = glm::lookAt(m_position, m_position + m_front, m_up);
- }
-
- void Camera::update()
- {
- m_vMatrix = glm::lookAt(m_position, m_position + m_front, m_up);
- }
-
- void Camera::move(CAMERA_MOVE _mode)
- {
- switch (_mode)
- {
- case CAMERA_MOVE::MOVE_LEFT:
- m_position -= glm::normalize(glm::cross(m_front, m_up)) * m_speed;
- break;
- case CAMERA_MOVE::MOVE_RIGHT:
- m_position += glm::normalize(glm::cross(m_front, m_up)) * m_speed;
- break;
- case CAMERA_MOVE::MOVE_FRONT:
- m_position += m_speed * m_front;
- break;
- case CAMERA_MOVE::MOVE_BACK:
- m_position -= m_speed * m_front;
- break;
- default:
- break;
- }
- }
-
- void Camera::setspeed(float _speed)
- {
- m_speed = _speed;
- }
main.cpp:
- #include "Base.h"
- #include "Shader.h"
- #include "ffImage.h"
- #include "Camera.h"
-
- void framebuffer_size_callback(GLFWwindow* window, int width, int height);
- void processInput(GLFWwindow* window);
- void initModel();
- void initShader(const char* _vertexPath, const char* _fragPath);
- void initTexture();
- void render();
-
- unsigned int VBO = 0;
- unsigned int VAO = 0;
- unsigned int EBO = 0;
- unsigned int _texture = 0;
-
- Shader _shader;
- ffImage* _pImage = nullptr;
- Camera _camera;
-
- glm::mat4 _projMatrix(1.0f);
- int _width = 800;
- int _height = 600;
-
- int main() {
- //初始化OpenGL上下文环境,OpenGL是一个状态机,会保存当前状态下的渲染状态以及管线的状态
- glfwInit();
- //,3版本以上
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- //用OpenGL核心开发模式
- glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
-
- //创建窗体
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGl Core", nullptr, nullptr);
- if (window == nullptr) {
- std::cout << "Failed to create GLFW window" << std::endl;
- glfwTerminate();
- return -1;
- }
- //把当前上下文绑定至当前窗口
- glfwMakeContextCurrent(window);
-
- //通过glad绑定各种函数指针
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- std::cout << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
-
- //视口:需要渲染的东西在哪里
- glViewport(0, 0, _width, _height);
- //当Frame大小变动,调用回调函数调整视口大小
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
-
- _camera.lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
- _camera.setspeed(0.01f);
-
- initModel();
- initShader("vertexShader.glsl", "fragmentShader.glsl");
- initTexture();
-
- //防止窗口结束退出
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- render();
-
- //双缓冲
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
-
- //结束,释放资源
- glfwTerminate();
- return 0;
-
- }
-
- void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
- glViewport(0, 0, width, height);
- }
-
- void processInput(GLFWwindow* window) {
- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
- glfwSetWindowShouldClose(window, true);
- }
- if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
- _camera.move(CAMERA_MOVE::MOVE_FRONT);
- }
- if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
- _camera.move(CAMERA_MOVE::MOVE_BACK);
- }
- if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
- _camera.move(CAMERA_MOVE::MOVE_LEFT);
- }
- if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
- _camera.move(CAMERA_MOVE::MOVE_RIGHT);
- }
- }
-
- //渲染
- void render() {
- //擦除画布,用定义的颜色填充
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
-
- glm::vec3 modelVecs[] = {
- 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.update();
- _projMatrix = glm::perspective(glm::radians(45.0f), (float)_width / (float)_height, 0.1f, 100.0f);
-
- glBindTexture(GL_TEXTURE_2D, _texture);
-
- for (int i = 0; i < 10; i++)
- {
- glm::mat4 _modelMatrix(1.0f);//单位阵
- _modelMatrix = glm::translate(_modelMatrix, modelVecs[i]);//平移
- _modelMatrix = glm::rotate(_modelMatrix, glm::radians((float)glfwGetTime() * (i + 1) * 10), glm::vec3(0.0f, 1.0f, 0.0f));//绕y轴旋转
-
- _shader.start();
- _shader.setMatrix("_modelMatrix", _modelMatrix);
- _shader.setMatrix("_viewMatrix", _camera.getMatrix());
- _shader.setMatrix("_projMatrix", _projMatrix);
- glBindVertexArray(VAO);
- glDrawArrays(GL_TRIANGLES, 0, 36);
- _shader.end();
- }
- }
-
- //构建模型数据:VBO,VAO
- void initModel() {
- //float vertices[] = {
- // //顶点信息 颜色信息 纹理信息
- // 0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f,1.0f,
- // 0.5f, -0.5f, 0.0f, 0.0f,1.0f,0.0f, 1.0f,0.0f,
- // -0.5f, -0.5f, 0.0f, 0.0f,0.0f,1.0f, 0.0f,0.0f,
- // -0.5f, 0.5f, 0.0f, 0.0f,1.0f,0.0f, 0.0f,1.0f
- //};
-
- float 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
- };
-
- glGenVertexArrays(1, &VAO);
- glBindVertexArray(VAO);
-
- //之后的VBO便属于了VAO的管理范围
- glGenBuffers(1, &VBO);
- //绑定哪一种buffer,
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- //分配显存:分配哪种buffer,分配显存大小,分配地址,使用数据的方式
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- //对哪个锚点进行操作:layout=0的锚点,读3个顶点,类型为float,不需要归一化,每次步长为3个float大小,从0处开始读
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(sizeof(float)*3));
-
- //打开锚点:激活
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- //解绑
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
-
- //
- void initShader(const char* _vertexPath, const char* _fragPath) {
-
- _shader.initShader(_vertexPath, _fragPath);
- }
-
- void initTexture() {
- _pImage = ffImage::readFromFile("res/wall.jpg");
- //纹理绑定
- glGenTextures(1, &_texture);
- glBindTexture(GL_TEXTURE_2D, _texture);
- //纹理属性设置
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //读入图片数据
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _pImage->getWidth(), _pImage->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,_pImage->getData());
- }
结果:
front.y:
front.x 和 front.z:
计算方式:
- //Camera.cpp
- #include "Camera.h"
-
- void Camera::lookAt(glm::vec3 _pos, glm::vec3 _front, glm::vec3 _up)
- {
- m_position = _pos;
- m_front = glm::normalize(_front);
- m_up = _up;
- m_vMatrix = glm::lookAt(m_position, m_position + m_front, m_up);
- }
-
- void Camera::update()
- {
- m_vMatrix = glm::lookAt(m_position, m_position + m_front, m_up);
- }
-
- void Camera::move(CAMERA_MOVE _mode)
- {
- switch (_mode)
- {
- case CAMERA_MOVE::MOVE_LEFT:
- m_position -= glm::normalize(glm::cross(m_front, m_up)) * m_speed;
- break;
- case CAMERA_MOVE::MOVE_RIGHT:
- m_position += glm::normalize(glm::cross(m_front, m_up)) * m_speed;
- break;
- case CAMERA_MOVE::MOVE_FRONT:
- m_position += m_speed * m_front;
- break;
- case CAMERA_MOVE::MOVE_BACK:
- m_position -= m_speed * m_front;
- break;
- default:
- break;
- }
- }
-
- void Camera::setspeed(float _speed)
- {
- m_speed = _speed;
- }
-
- void Camera::pitch(float _yOffset)
- {
- m_pitch += _yOffset * m_sensitivity;
- if (m_pitch >= 89.0f) {
- m_pitch = 89.0f;
- }
- if (m_pitch <= -89.0f) {
- m_pitch = -89.0f;
- }
- m_front.y = sin(glm::radians(m_pitch));
- m_front.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
- m_front.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
-
- m_front = glm::normalize(m_front);
- update();
- }
-
- void Camera::yaw(float _xOffset)
- {
- m_yaw += _xOffset * m_sensitivity;
-
- m_front.y = sin(glm::radians(m_pitch));
- m_front.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
- m_front.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
-
- m_front = glm::normalize(m_front);
- update();
- }
-
- void Camera::setSensitivity(float _s)
- {
- m_sensitivity = _s;
- }
-
- void Camera::onMouseMove(double _xpos, double _ypos)
- {
- if (m_firseMove) {
- m_xpos = m_xpos;
- m_ypos = m_ypos;
- m_firseMove = false;
- return;
- }
- float _xOffset = _xpos - m_xpos;
- float _yOffset = -(_ypos - m_ypos);
-
- m_xpos = _xpos;
- m_ypos = _ypos;
-
- pitch(_yOffset);
- yaw(_xOffset);
- }