(十六)視圖變換 正交投影 透視投影

視圖變換

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

代碼實驗

#include <glad/glad.h>//glad必須在glfw頭文件之前包含
#include <GLFW/glfw3.h>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"//GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}
void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
}GLuint program = 0;
GLuint vao = 0;
GLuint texture = 0;
glm::mat4 transform(1.0f);//4×4單位矩陣
glm::mat4 viewMatrix(1.0f);void prepareCamera()
{//lookat:生成一個viewMatrix//eye:當前攝像機所在的位置//center:當前攝像機看向的那個點//up:穹頂向量viewMatrix = glm::lookAt(glm::vec3(0.5f, 0.0f, 0.5f), glm::vec3(0.5f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
}
void prepareVAO()
{//positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,};//顏色float colors[] = {1.0f, 0.0f,0.0f,0.0f, 1.0f,0.0f,0.0f, 0.0f,1.0f};//索引unsigned int indices[] = {0, 1, 2,};//uv坐標float uvs[] = {0.0f, 0.0f,1.0f, 0.0f,0.5f, 1.0f,};//2 VBO創建GLuint posVbo = 0;GLuint colorVbo = 0;GLuint uvVbo = 0;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);glGenBuffers(1, &uvVbo);glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);//3 EBO創建GLuint ebo = 0;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//4 VAO創建vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//5 綁定vbo ebo 加入屬性描述信息//5.1 加入位置屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.2 加入顏色屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.3 加入uv屬性描述數據glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);//5.2 加入ebo到當前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBindVertexArray(0);
}
void prepareShader() {//1 完成vs與fs的源代碼,并且裝入字符串//aPos作為attribute(屬性)傳入shader不允許更改的const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""layout (location = 1) in vec3 aColor;\n""layout (location = 2) in vec2 aUV;\n""out vec3 color;\n""out vec2 uv;\n""uniform mat4 transform;\n""uniform mat4 viewMatrix;\n""void main()\n""{\n""   vec4 position = vec4(aPos, 1.0);\n""   position = viewMatrix * transform * position;\n""   gl_Position = position;\n""   color = aColor;\n""   uv = aUV;\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""in vec3 color;\n""in vec2 uv;\n""uniform sampler2D sampler;\n""void main()\n""{\n""   FragColor = texture(sampler, uv);\n""}\n\0";//2 創建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 為shader程序輸入shader代碼glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 執行shader代碼編譯 glCompileShader(vertex);//檢查vertex編譯結果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//檢查fragment編譯結果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 創建一個Program殼子program = glCreateProgram();//6 將vs與fs編譯好的結果放到program這個殼子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 執行program的鏈接操作,形成最終可執行shader程序glLinkProgram(program);//檢查鏈接錯誤glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void prepareTextrue()
{//1 stbImage 讀取圖片int width, height, channels;//--反轉y軸stbi_set_flip_vertically_on_load(true);unsigned char* data = stbi_load("goku.jpg", &width, &height, &channels, STBI_rgb_alpha);//2 生成紋理并且激活單元綁定glGenTextures(1, &texture);//--激活紋理單元--glActiveTexture(GL_TEXTURE0);//--綁定紋理對象--glBindTexture(GL_TEXTURE_2D, texture);//3 傳輸紋理數據,開辟顯存glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);//***釋放數據stbi_image_free(data);//4 設置紋理的過濾方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//5 設置紋理的包裹方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//uglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//v
}void render()
{//執行opengl畫布清理操作glClear(GL_COLOR_BUFFER_BIT);//1.綁定當前的programglUseProgram(program);//2 更新Uniform的時候,一定要先UserProgram//2.1 通過名稱拿到Uniform變量的位置LocationGLint location = glGetUniformLocation(program, "sampler");//2.2 通過Location更新Uniform變量的值glUniform1f(location, 0);GLint locationTransform = glGetUniformLocation(program, "transform");//transpose參數:表示是否對傳輸進去的矩陣數據進行轉置glUniformMatrix4fv(locationTransform, 1, GL_FALSE, glm::value_ptr(transform));GLint locationviewMatrix = glGetUniformLocation(program, "viewMatrix");//transpose參數:表示是否對傳輸進去的矩陣數據進行轉置glUniformMatrix4fv(locationviewMatrix, 1, GL_FALSE, glm::value_ptr(viewMatrix));//3 綁定當前的vaoglBindVertexArray(vao);//4 發出繪制指令//glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
}int main()
{//初始化glfw環境glfwInit();//設置opengl主版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//設置opengl次版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//設置opengl啟用核心模式glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//創建窗體對象GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr);//設置當前窗體對象為opengl的繪制舞臺glfwMakeContextCurrent(window);//窗體大小回調glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc);//鍵盤相應回調glfwSetKeyCallback(window, glfwKeyCallback);//使用glad加載所有當前版本opengl的函數if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化glad失敗" << std::endl;return -1;};//設置opengl視口大小和清理顏色glViewport(0, 0, 800, 600);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//shaderprepareShader();//vaoprepareVAO();//textureprepareTextrue();prepareCamera();//執行窗體循環while (!glfwWindowShouldClose(window)){//接受并分發窗體消息//檢查消息隊列是否有需要處理的鼠標、鍵盤等消息//如果有的話就將消息批量處理,清空隊列glfwPollEvents();//渲染操作render();//切換雙緩存glfwSwapBuffers(window);}//推出程序前做相關清理glfwTerminate();return 0;
}

glm中的lookat參數可以生成視圖變換矩陣,設置給VS即可。

正交投影

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

總結

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

案例分析

在這里插入圖片描述

#include <glad/glad.h>//glad必須在glfw頭文件之前包含
#include <GLFW/glfw3.h>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"//GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}
void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
}GLuint program = 0;
GLuint vao = 0;
GLuint texture = 0;
glm::mat4 transform(1.0f);//4×4單位矩陣
glm::mat4 viewMatrix(1.0f);
glm::mat4 orthoMatrix(1.0f);
void prepareCamera()
{//lookat:生成一個viewMatrix//eye:當前攝像機所在的位置//center:當前攝像機看向的那個點//up:穹頂向量viewMatrix = glm::lookAt(glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
}
void prepareOrtho()
{//參數為盒體上下左右遠近orthoMatrix = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 2.0f, -2.0f);
}
void prepareVAO()
{//positionsfloat positions[] = {-1.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f,0.0f,  1.0f, 0.0f,};//顏色float colors[] = {1.0f, 0.0f,0.0f,0.0f, 1.0f,0.0f,0.0f, 0.0f,1.0f};//索引unsigned int indices[] = {0, 1, 2,};//uv坐標float uvs[] = {0.0f, 0.0f,1.0f, 0.0f,0.5f, 1.0f,};//2 VBO創建GLuint posVbo = 0;GLuint colorVbo = 0;GLuint uvVbo = 0;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);glGenBuffers(1, &uvVbo);glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);//3 EBO創建GLuint ebo = 0;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//4 VAO創建vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//5 綁定vbo ebo 加入屬性描述信息//5.1 加入位置屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.2 加入顏色屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.3 加入uv屬性描述數據glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);//5.2 加入ebo到當前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBindVertexArray(0);
}
void prepareShader() {//1 完成vs與fs的源代碼,并且裝入字符串//aPos作為attribute(屬性)傳入shader不允許更改的const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""layout (location = 1) in vec3 aColor;\n""layout (location = 2) in vec2 aUV;\n""out vec3 color;\n""out vec2 uv;\n""uniform mat4 transform;\n""uniform mat4 viewMatrix;\n""uniform mat4 orthoMatrix;\n""void main()\n""{\n""   vec4 position = vec4(aPos, 1.0);\n""   position = orthoMatrix * viewMatrix * transform * position;\n""   gl_Position = position;\n""   color = aColor;\n""   uv = aUV;\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""in vec3 color;\n""in vec2 uv;\n""uniform sampler2D sampler;\n""void main()\n""{\n""   FragColor = texture(sampler, uv);\n""}\n\0";//2 創建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 為shader程序輸入shader代碼glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 執行shader代碼編譯 glCompileShader(vertex);//檢查vertex編譯結果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//檢查fragment編譯結果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 創建一個Program殼子program = glCreateProgram();//6 將vs與fs編譯好的結果放到program這個殼子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 執行program的鏈接操作,形成最終可執行shader程序glLinkProgram(program);//檢查鏈接錯誤glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void prepareTextrue()
{//1 stbImage 讀取圖片int width, height, channels;//--反轉y軸stbi_set_flip_vertically_on_load(true);unsigned char* data = stbi_load("goku.jpg", &width, &height, &channels, STBI_rgb_alpha);//2 生成紋理并且激活單元綁定glGenTextures(1, &texture);//--激活紋理單元--glActiveTexture(GL_TEXTURE0);//--綁定紋理對象--glBindTexture(GL_TEXTURE_2D, texture);//3 傳輸紋理數據,開辟顯存glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);//***釋放數據stbi_image_free(data);//4 設置紋理的過濾方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//5 設置紋理的包裹方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//uglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//v
}void render()
{//執行opengl畫布清理操作glClear(GL_COLOR_BUFFER_BIT);//1.綁定當前的programglUseProgram(program);//2 更新Uniform的時候,一定要先UserProgram//2.1 通過名稱拿到Uniform變量的位置LocationGLint location = glGetUniformLocation(program, "sampler");//2.2 通過Location更新Uniform變量的值glUniform1f(location, 0);GLint locationTransform = glGetUniformLocation(program, "transform");//transpose參數:表示是否對傳輸進去的矩陣數據進行轉置glUniformMatrix4fv(locationTransform, 1, GL_FALSE, glm::value_ptr(transform));GLint locationviewMatrix = glGetUniformLocation(program, "viewMatrix");glUniformMatrix4fv(locationviewMatrix, 1, GL_FALSE, glm::value_ptr(viewMatrix));GLint locationorthoMatrix = glGetUniformLocation(program, "orthoMatrix");glUniformMatrix4fv(locationorthoMatrix, 1, GL_FALSE, glm::value_ptr(orthoMatrix));//3 綁定當前的vaoglBindVertexArray(vao);//4 發出繪制指令//glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
}int main()
{//初始化glfw環境glfwInit();//設置opengl主版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//設置opengl次版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//設置opengl啟用核心模式glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//創建窗體對象GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr);//設置當前窗體對象為opengl的繪制舞臺glfwMakeContextCurrent(window);//窗體大小回調glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc);//鍵盤相應回調glfwSetKeyCallback(window, glfwKeyCallback);//使用glad加載所有當前版本opengl的函數if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化glad失敗" << std::endl;return -1;};//設置opengl視口大小和清理顏色glViewport(0, 0, 800, 600);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//shaderprepareShader();//vaoprepareVAO();//textureprepareTextrue();prepareCamera();prepareOrtho();//執行窗體循環while (!glfwWindowShouldClose(window)){//接受并分發窗體消息//檢查消息隊列是否有需要處理的鼠標、鍵盤等消息//如果有的話就將消息批量處理,清空隊列glfwPollEvents();//渲染操作render();//切換雙緩存glfwSwapBuffers(window);}//推出程序前做相關清理glfwTerminate();return 0;
}

在vao中給入模型坐標,模型坐標經過變換后轉換成世界坐標,世界坐標經過視圖變換矩陣變換為相機坐標,相機坐標經過正交投影變換為NDC坐標。
在構造正交投影矩陣過程中,傳入的參數為盒體的大小,只有在盒體范圍內的坐標點才會保留,范圍外的將會被裁剪。

透視投影

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

例子

在這里插入圖片描述
在這里插入圖片描述

#include <glad/glad.h>//glad必須在glfw頭文件之前包含
#include <GLFW/glfw3.h>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"//GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}
void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
}GLuint program = 0;
GLuint vao = 0;
GLuint texture = 0;
glm::mat4 transform(1.0f);//4×4單位矩陣
glm::mat4 viewMatrix(1.0f);
glm::mat4 orthoMatrix(1.0f);
glm::mat4 perspectiveMatrix(1.0f);
void prepareCamera()
{//lookat:生成一個viewMatrix//eye:當前攝像機所在的位置//center:當前攝像機看向的那個點//up:穹頂向量viewMatrix = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
}
void prepareOrtho()
{//參數為盒體上下左右遠近orthoMatrix = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 2.0f, -2.0f);
}
void preparePerspective()
{//fovy:y軸方向的視張角,弧度單位//aspect:近平面的橫縱百分比//near:近平面距離//far:遠平面距離perspectiveMatrix = glm::perspective(glm::radians(60.0f), 800.0f / 600, 0.1f, 1000.0f);
}
void prepareVAO()
{//positionsfloat positions[] = {-1.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f,0.0f,  1.0f, 0.0f,};//顏色float colors[] = {-1.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f,0.0f,  1.0f, 0.0f,};//索引unsigned int indices[] = {0, 1, 2,};//uv坐標float uvs[] = {0.0f, 0.0f,1.0f, 0.0f,0.5f, 1.0f,};//2 VBO創建GLuint posVbo = 0;GLuint colorVbo = 0;GLuint uvVbo = 0;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);glGenBuffers(1, &uvVbo);glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);//3 EBO創建GLuint ebo = 0;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//4 VAO創建vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//5 綁定vbo ebo 加入屬性描述信息//5.1 加入位置屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.2 加入顏色屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.3 加入uv屬性描述數據glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);//5.2 加入ebo到當前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBindVertexArray(0);
}
void prepareShader() {//1 完成vs與fs的源代碼,并且裝入字符串//aPos作為attribute(屬性)傳入shader不允許更改的const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""layout (location = 1) in vec3 aColor;\n""layout (location = 2) in vec2 aUV;\n""out vec3 color;\n""out vec2 uv;\n""uniform mat4 transform;\n""uniform mat4 viewMatrix;\n""uniform mat4 perspectiveMatrix;\n""void main()\n""{\n""   vec4 position = vec4(aPos, 1.0);\n""   position = perspectiveMatrix * viewMatrix * transform * position;\n""   gl_Position = position;\n""   color = aColor;\n""   uv = aUV;\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""in vec3 color;\n""in vec2 uv;\n""uniform sampler2D sampler;\n""void main()\n""{\n""   FragColor = texture(sampler, uv);\n""}\n\0";//2 創建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 為shader程序輸入shader代碼glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 執行shader代碼編譯 glCompileShader(vertex);//檢查vertex編譯結果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//檢查fragment編譯結果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 創建一個Program殼子program = glCreateProgram();//6 將vs與fs編譯好的結果放到program這個殼子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 執行program的鏈接操作,形成最終可執行shader程序glLinkProgram(program);//檢查鏈接錯誤glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void prepareTextrue()
{//1 stbImage 讀取圖片int width, height, channels;//--反轉y軸stbi_set_flip_vertically_on_load(true);unsigned char* data = stbi_load("goku.jpg", &width, &height, &channels, STBI_rgb_alpha);//2 生成紋理并且激活單元綁定glGenTextures(1, &texture);//--激活紋理單元--glActiveTexture(GL_TEXTURE0);//--綁定紋理對象--glBindTexture(GL_TEXTURE_2D, texture);//3 傳輸紋理數據,開辟顯存glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);//***釋放數據stbi_image_free(data);//4 設置紋理的過濾方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//5 設置紋理的包裹方式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//uglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//v
}void render()
{//執行opengl畫布清理操作glClear(GL_COLOR_BUFFER_BIT);//1.綁定當前的programglUseProgram(program);//2 更新Uniform的時候,一定要先UserProgram//2.1 通過名稱拿到Uniform變量的位置LocationGLint location = glGetUniformLocation(program, "sampler");//2.2 通過Location更新Uniform變量的值glUniform1f(location, 0);GLint locationTransform = glGetUniformLocation(program, "transform");//transpose參數:表示是否對傳輸進去的矩陣數據進行轉置glUniformMatrix4fv(locationTransform, 1, GL_FALSE, glm::value_ptr(transform));GLint locationviewMatrix = glGetUniformLocation(program, "viewMatrix");glUniformMatrix4fv(locationviewMatrix, 1, GL_FALSE, glm::value_ptr(viewMatrix));GLint locationperspectiveMatrix = glGetUniformLocation(program, "perspectiveMatrix");glUniformMatrix4fv(locationperspectiveMatrix, 1, GL_FALSE, glm::value_ptr(perspectiveMatrix));//3 綁定當前的vaoglBindVertexArray(vao);//4 發出繪制指令//glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
}int main()
{//初始化glfw環境glfwInit();//設置opengl主版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//設置opengl次版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//設置opengl啟用核心模式glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//創建窗體對象GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr);//設置當前窗體對象為opengl的繪制舞臺glfwMakeContextCurrent(window);//窗體大小回調glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc);//鍵盤相應回調glfwSetKeyCallback(window, glfwKeyCallback);//使用glad加載所有當前版本opengl的函數if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化glad失敗" << std::endl;return -1;};//設置opengl視口大小和清理顏色glViewport(0, 0, 800, 600);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//shaderprepareShader();//vaoprepareVAO();//textureprepareTextrue();prepareCamera();preparePerspective();//執行窗體循環while (!glfwWindowShouldClose(window)){//接受并分發窗體消息//檢查消息隊列是否有需要處理的鼠標、鍵盤等消息//如果有的話就將消息批量處理,清空隊列glfwPollEvents();//渲染操作render();//切換雙緩存glfwSwapBuffers(window);}//推出程序前做相關清理glfwTerminate();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43841.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43841.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43841.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++初探究(2)

引用 對于一個常量&#xff0c;想要將其進行引用&#xff0c;則使用普通的引用相當于權限擴大&#xff08;常量為只讀&#xff0c;但此處的引用參數為可讀可寫&#xff09;&#xff0c;C編譯器會報錯. 例如&#xff1a; const int a 10;int& ra a;//權限放大&#xff0…

邏輯回歸不是回歸嗎?那為什么叫回歸?

RNN 邏輯回歸不是回歸嗎&#xff1f;那為什么叫回歸&#xff1f;邏輯回歸的基本原理邏輯函數&#xff08;Sigmoid函數&#xff09;二元分類 為什么叫做“回歸”&#xff1f;邏輯回歸的應用場景總結 邏輯回歸不是回歸嗎&#xff1f;那為什么叫回歸&#xff1f; 邏輯回歸&#x…

Python大數據分析——決策樹和隨機森林

Python大數據分析——決策樹和隨機森林 決策樹決策樹節點字段的選擇信息熵條件熵信息增益信息增益率 基尼指數條件基尼指數基尼指數增益 決策樹函數 隨機森林函數 決策樹 圖中的決策樹呈現自頂向下的生長過程&#xff0c;深色的橢圓表示樹的根節點&#xff1b;淺色的橢圓表示樹…

Java項目:基于SSM框架實現的農家樂信息管理平臺含前后臺【ssm+B/S架構+源碼+數據庫+答辯PPT+開題報告+畢業論文】

一、項目簡介 本項目是一套基于SSM框架實現的農家樂信息管理平臺 包含&#xff1a;項目源碼、數據庫腳本等&#xff0c;該項目附帶全部源碼可作為畢設使用。 項目都經過嚴格調試&#xff0c;eclipse或者idea 確保可以運行&#xff01; 該系統功能完善、界面美觀、操作簡單、功…

招投標信息采集系統:讓您的企業始終站在行業前沿

一、為何招投標信息如此關鍵&#xff1f; 在經濟全球化的大背景下&#xff0c;招投標活動日益頻繁&#xff0c;成為企業獲取項目、拓展市場的主流方式之一。招投標信息采集&#xff0c;作為企業戰略決策的前置環節&#xff0c;其重要性不言而喻。它不僅關乎企業能否第一時間發…

WPF 初識依賴屬性

依賴屬性的意義和作用 核心模塊內存共享&#xff0c;節省空間數據綁定、樣式、模板、動畫。。。。如果沒有依賴屬性&#xff0c;這個框架就是一個控件框架 相當于Winform 依賴屬性的基本定義 基本過程&#xff1a;聲明、注冊、包裝 在需要寫依賴屬性的類中&#xff0c;繼承…

快速將一個網址打包成一個exe可執行文件

一、電腦需要node環境 如果沒有下面有安裝教程&#xff1a; node.js安裝及環境配置超詳細教程【Windows系統安裝包方式】 https://blog.csdn.net/weixin_44893902/article/details/121788104 我的版本是v16.13.1 二、安裝nativefier 這是一個GitHub上的開源項目&#xff1a…

C 語言函數

1.0 函數的創建和使用 在C語言中&#xff0c;函數是一種封裝了特定功能的代碼塊&#xff0c;可以被程序中的其他部分調用。函數可以接受輸入參數&#xff0c;并且可以返回一個值。定義一個函數的基本語法如下 #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" …

numpy、ffmpeg都在cpu上面跑

ffmpeg: ffmpeg不支持在GPU上運行。ffmpeg是一個用于處理多媒體數據的工具&#xff0c;它主要在CPU上運行。雖然某些特定的ffmpeg功能&#xff08;如某些視頻編解碼器&#xff09;可以利用GPU進行硬件加速&#xff0c;但這需要特定的硬件和驅動支持&#xff0c;并且并非所有操…

阿里云人工智能平臺PAI部署開源大模型chatglm3之失敗記錄--update:最后成功了!

想學習怎么部署大模型&#xff0c;跟著網上的帖子部署了一個星期&#xff0c;然而沒有成功。失敗的經歷也是經歷&#xff0c;記在這里。 我一共創建了3個實例來部署chatglm3&#xff0c;每個實例都是基于V100創建的&#xff08;當時沒有A10可選了&#xff09;&#xff0c;其顯…

算法工程師第六天(● 454.四數相加II ● 383. 贖金信 ● 15. 三數之和 ● 18. 四數之和 ● 總結 )

參考文獻 代碼隨想錄 一、四數相加 II 給你四個整數數組 nums1、nums2、nums3 和 nums4 &#xff0c;數組長度都是 n &#xff0c;請你計算有多少個元組 (i, j, k, l) 能滿足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#…

x86芯片定制,Ethercat芯片定制,IP服務,適用于運動控制,工業總線等軟硬一體機

x86芯片定制&#xff0c;Ethercat芯片定制 X86平臺 我們的研發工程師已經積累了非常豐富的主板、整機設計經驗&#xff0c;對接您的產品規格場景需求&#xff0c;快速交付樣機&#xff0c;包含主板、BOX整機、平板電腦、CPCI等形態產品。降本、長生命周期、快速交付、及時響應…

C# 如何防止反編譯?C#程序加密混淆保護方法大全

在C#開發中&#xff0c;由于.NET程序集&#xff08;assemblies&#xff09;是基于中間語言&#xff08;Intermediate Language, IL&#xff09;編譯的&#xff0c;這些程序集可以被反編譯回接近原始源代碼的形式。為了保護代碼不被輕易反編譯&#xff0c;開發者可以采取以下幾種…

springsecurity(學習自用)

springsecurity 學習資源&#xff1a; https://blog.csdn.net/qq_45525848/article/details/131142179 springbootspring security 認證&#xff1a; 判斷用戶是否是系統合法用戶過程授權: 判斷系統內用戶可以訪問或具有訪問那些資源權限過程 創建一個springboot項目 如果只…

IEC62056標準體系簡介-2.IEC62056標準體系及對象標識系統(OBIS)

1. IEC 62056標準體系 IEC 62056標準體系目前共包括六部分&#xff0c;見圖1&#xff1a; 第61部分&#xff1a;對象標識系統第62部分&#xff1a;接口類第53部分&#xff1a;COSEM應用層第46部分&#xff1a;使用HDLC&#xff08;High Level Data Link Control&#xff09;協…

Linux多進程和多線程(八)多線程

多線程 線程定義線程與進程線程資源 線程相關命令 pidstat 命令 top 命令ps 命令常見的并發方案 1. 多進程模式2. 多線程模式 創建線程 1. pthread_create() 示例:創建一個線程 2. pthread_exit() 退出線程3. pthread_join() 等待線程結束 示例: 線程分離 創建多個線程 示例 1:…

前端面試題35(在iOS和Android平臺上,實現WebSocket協議有哪些常見的庫或框架?)

在iOS和Android平臺上&#xff0c;實現WebSocket協議有許多成熟且被廣泛使用的庫和框架。下面是一些推薦的選項&#xff1a; iOS 平臺 SocketRocket 簡介&#xff1a;這是由Facebook開源的庫&#xff0c;專門為iOS和Mac OS X設計&#xff0c;提供WebSocket連接的功能。它基于S…

Blender新手入門筆記收容所(一)

基礎篇 基礎操作 視角的控制 控制觀察視角&#xff1a;鼠標中鍵平移視圖&#xff1a;Shift鼠標中鍵縮放視圖&#xff1a;滾動鼠標中鍵滾輪 選中物體后&#xff1a;移動物體快捷鍵G&#xff0c;移動后單擊鼠標就會定下來。 進入移動狀態后&#xff1a;按Y會沿著Y軸移動進入移動…

LY/T 3359-2023 耐化學腐蝕高壓裝飾層積板檢測

耐化學腐蝕高壓裝飾層積板是指用酚醛樹脂浸漬的層狀植物纖維材料為基材&#xff0c;與涂布以丙烯酸樹脂為主體的裝飾紙的飾面層&#xff0c;在高溫高壓下層積壓制而成的具有化學腐蝕功能的高壓裝飾層積板。 LY/T 3359-2023 耐化學腐蝕高壓裝飾層積板檢測項目&#xff1a; 測試…

HW期間——應急響應

01HW中應急響應的流程 001應急響應所處位置&#xff08;應急處置組&#xff09; 監控研判組發現的一些安全時間提供給應急處置組&#xff0c;應急處置組通過上機取證把線索給到溯源反制組。但是溯源反制組可能已經沒有了&#xff0c;有些單位有&#xff0c;有些單位取消了。有…