目录
1、链接文件夹中的cpp
2、链接资源到输出目录
3、多编译目标
4、cmakelist添加库
4、添加glfw和glad
5、glfw运行
6、NDC、VBO、VAO
7、渐变三角形
8、渲染两个三角形
9、渲染两个三角形,同时基于原来颜色进行渐变
10、三角形渲染模块化
11、纹理渲染
12、双纹理渲染
13、旋转、缩放、平移
14、摄像机角度观察
1、链接文件夹中的cpp
cmake_minimum_required(VERSION 3.12)#本工程的名字
project(OpenGL)#本工程支持的C++版本
set(CMAKE_CXX_STANDARD 17)#将funcs文件夹纳入到编译系统
add_subdirectory(func)#搜索所有的cpp,加入SRCS变量中
aux_source_directory(. SRCS)#本工程主程序文件及输出程序名称
add_executable(glStudy ${SRCS})#将myFuncs.lib链接入softRender
target_link_libraries(glStudy myFuncs)
#递归将本文件夹下所有cpp放到FUNCS中
file(GLOB_RECURSE FUNCS ./ *.cpp)#将FUNCS中所有cpp编译为funcs这个lib库
add_library(myFuncs ${FUNCS})
2、链接资源到输出目录
cmake_minimum_required(VERSION 3.12)#本工程的名字
project(OpenGL)#本工程支持的C++版本
set(CMAKE_CXX_STANDARD 17)#把需要拷贝的资源路径都放在img里
file(GLOB IMG "./img")#把img中目录的内容,都拷贝到可执行文件目录下
file(COPY ${IMG} DESTINATION ${CMAKE_BINARY_DIR})#将funcs文件夹纳入到编译系统
add_subdirectory(func)#搜索所有的cpp,加入SRCS变量中
aux_source_directory(. SRCS)#本工程主程序文件及输出程序名称
add_executable(glStudy ${SRCS})#将myFuncs.lib链接入softRender
target_link_libraries(glStudy myFuncs)
3、多编译目标
cmake_minimum_required(VERSION 3.12)#本工程的名字
project(OpenGL)#本工程支持的C++版本
set(CMAKE_CXX_STANDARD 17)#把需要拷贝的资源路径都放在img里
file(GLOB IMG "./img")#把img中目录的内容,都拷贝到可执行文件目录下
file(COPY ${IMG} DESTINATION ${CMAKE_BINARY_DIR})#将funcs文件夹纳入到编译系统
add_subdirectory(func)#搜索所有的cpp,加入SRCS变量中
#aux_source_directory(. SRCS)#本工程主程序文件及输出程序名称
add_executable(glStudy "main.cpp")
add_executable(main2 "main2.cpp")#将myFuncs.lib链接入softRender
target_link_libraries(glStudy myFuncs)
4、cmakelist添加库
cmake_minimum_required(VERSION 3.12)#本工程的名字
project(learn_GLFW)#本工程支持的C++版本
set(CMAKE_CXX_STANDARD 17)include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/include
)link_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/lib
)#本工程所有cpp文件编译链接,生成exe
add_executable(learnGLFW "main.cpp")target_link_libraries(learnGLFW glfw3.lib)
4、添加glfw和glad
cmake_minimum_required(VERSION 3.12)#本工程的名字
project(learn_GLFW)#本工程支持的C++版本
set(CMAKE_CXX_STANDARD 17)include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/include
)link_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/lib
)#本工程所有cpp文件编译链接,生成exe
add_executable(learnGLFW "main.cpp" "glad.c")target_link_libraries(learnGLFW glfw3.lib)
5、glfw运行
#include <iostream>#include <glad/glad.h>
#include <GLFW/glfw3.h>int main() {//1、初始化GLFW基本环境glfwInit();//1.1设置主版本号,次版本号glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);//1.2设置启用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//2、创建窗体对象GLFWwindow* window = glfwCreateWindow(800, 600, "OpenglStudy", NULL, NULL);//设置当前的窗体对象为Opengl的绘制舞台glfwMakeContextCurrent(window);//3、执行窗体循环while (!glfwWindowShouldClose(window)) {//接受并分发窗体消息//检查消息队列是否有需要处理的鼠标,键盘等消息//如果有的话就将消息批量处理,清空队列glfwPollEvents();}//4、退出程序glfwTerminate();return 0;}
6、NDC、VBO、VAO
7、渐变三角形
方法一:一个VBO绑定到一个VAO上
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为 0
"layout (location = 1) in vec3 aColor;\n"// 颜色变量的属性位置值为 1
"out vec3 ourColor;\n"// 向片段着色器输出一个颜色
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" ourColor = aColor;\n"// 将ourColor设置为我们从顶点数据那里得到的输入颜色
"}\0";const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(ourColor, 1.0f);\n"
"}\n\0";int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {// 位置 // 颜色0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部};unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glBindVertexArray(VAO);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glUseProgram(shaderProgram);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
方法二:两个VBO绑定到VAO上
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为 0
"layout (location = 1) in vec3 aColor;\n"// 颜色变量的属性位置值为 1
"out vec3 ourColor;\n"// 向片段着色器输出一个颜色
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" ourColor = aColor;\n"// 将ourColor设置为我们从顶点数据那里得到的输入颜色
"}\0";const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(ourColor, 1.0f);\n"
"}\n\0";int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {// 位置 // 颜色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 VBO[2];glGenBuffers(2, VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glUseProgram(shaderProgram);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(2, VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
8、渲染两个三角形
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为 0
"layout (location = 1) in vec3 aColor;\n"// 颜色变量的属性位置值为 1
"out vec3 ourColor;\n"// 向片段着色器输出一个颜色
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" ourColor = aColor;\n"// 将ourColor设置为我们从顶点数据那里得到的输入颜色
"}\0";const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(ourColor, 1.0f);\n"
"}\n\0";int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {// 位置 // 颜色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};//4. 设置顶点数据float vertices2[] = {// 位置 // 颜色0.7f, -0.2f, 0.0f, // 右下-0.2f, -0.2f, 0.0f, // 左下0.0f, 0.8f, 0.0f, // 顶部};float colors2[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f};unsigned int VBO[4];glGenBuffers(4, VBO);//执行一次glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//---unsigned int VAO[2];glGenVertexArrays(2, VAO);//执行一次glBindVertexArray(VAO[0]);glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,3 * sizeof(float), (void*)0);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//-第二个三角形glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, VBO[3]);glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);glBindVertexArray(VAO[1]);glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindBuffer(GL_ARRAY_BUFFER, VBO[3]);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.0f, 0.f, 0.f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glUseProgram(shaderProgram);glBindVertexArray(VAO[0]);glDrawArrays(GL_TRIANGLES, 0, 3);glBindVertexArray(VAO[1]);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(2, VAO);glDeleteBuffers(4, VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
9、渲染两个三角形,同时基于原来颜色进行渐变
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>
#include <glm/vec3.hpp>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为 0
"layout (location = 1) in vec3 aColor;\n"// 颜色变量的属性位置值为 1
"out vec3 ourColor;\n"// 向片段着色器输出一个颜色
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" ourColor = aColor;\n"// 将ourColor设置为我们从顶点数据那里得到的输入颜色
"}\0";const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"uniform vec3 dynamicColor;\n"
"void main()\n"
"{\n"
" vec3 finalColor= ourColor + dynamicColor;\n"
" finalColor = clamp(finalColor, 0.0, 1.0);\n"
" FragColor = vec4(finalColor, 1.0);\n"
"}\n\0";int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {// 位置 // 颜色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};//4. 设置顶点数据float vertices2[] = {// 位置 // 颜色0.7f, -0.2f, 0.0f, // 右下-0.2f, -0.2f, 0.0f, // 左下0.0f, 0.8f, 0.0f, // 顶部};float colors2[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f};unsigned int VBO[4];glGenBuffers(4, VBO);//执行一次glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//---unsigned int VAO[2];glGenVertexArrays(2, VAO);//执行一次glBindVertexArray(VAO[0]);glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,3 * sizeof(float), (void*)0);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//-第二个三角形glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, VBO[3]);glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);glBindVertexArray(VAO[1]);glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindBuffer(GL_ARRAY_BUFFER, VBO[3]);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.0f, 0.f, 0.f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glUseProgram(shaderProgram);glBindVertexArray(VAO[0]);glDrawArrays(GL_TRIANGLES, 0, 3);double timeValue = glfwGetTime();float greenValue = static_cast<float>(sin(timeValue) / 2.0 + 0.5);// 假设您要添加的动态颜色只影响绿色分量glm::vec3 dynamicColor = glm::vec3(0.0f, greenValue, 0.0f);int dynamicColorLocation = glGetUniformLocation(shaderProgram, "dynamicColor");glUniform3f(dynamicColorLocation, dynamicColor.x, dynamicColor.y, dynamicColor.z);glBindVertexArray(VAO[1]);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(2, VAO);glDeleteBuffers(4, VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
10、三角形渲染模块化
OpenGL_Learn04-CSDN博客
看最后一个案例
11、纹理渲染
shader.h
#ifndef SHADER_H
#define SHADER_H#include <glad/glad.h>#include <string>
#include <fstream>
#include <sstream>
#include <iostream>class Shader
{
public:unsigned int ID;// constructor generates the shader on the fly// ------------------------------------------------------------------------Shader(const char* vertexPath, const char* fragmentPath){// 1. retrieve the vertex/fragment source code from filePathstd::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// ensure ifstream objects can throw exceptions:vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try{// open filesvShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// read file's buffer contents into streamsvShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();// close file handlersvShaderFile.close();fShaderFile.close();// convert stream into stringvertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();// 2. compile shadersunsigned int vertex, fragment;// vertex shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");// fragment Shaderfragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");// shader ProgramID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");// delete the shaders as they're linked into our program now and no longer necessaryglDeleteShader(vertex);glDeleteShader(fragment);}// activate the shader// ------------------------------------------------------------------------void use(){glUseProgram(ID);}// utility uniform functions// ------------------------------------------------------------------------void setBool(const std::string& name, bool value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);}// ------------------------------------------------------------------------void setInt(const std::string& name, int value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), value);}// ------------------------------------------------------------------------void setFloat(const std::string& name, float value) const{glUniform1f(glGetUniformLocation(ID, name.c_str()), value);}private:// utility function for checking shader compilation/linking errors.// ------------------------------------------------------------------------void checkCompileErrors(unsigned int shader, std::string type){int success;char infoLog[1024];if (type != "PROGRAM"){glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}else{glGetProgramiv(shader, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}}
};
#endif
texture.vs #version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;out vec2 TexCoord;void main(){gl_Position = vec4(aPos, 1.0);TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}texture.fs#version 330 core
out vec4 FragColor;
in vec2 TexCoord;uniform sampler2D texture1;
void main(){FragColor=texture(texture1,TexCoord);
}
注意VAO,VBO,VEO的顺序
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>
#include "shader.h"
#include "stb_image.h"void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}Shader ourShader("./texture.vs", "./texture.fs");//4. 设置顶点数据float vertices[] = {// positions // colors // texture coords0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left };unsigned int indices[] = {0, 1, 3, // first triangle1, 2, 3 // second triangle};unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,8 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6*sizeof(float)));unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//加载和创建纹理unsigned int texture;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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsint width, height, nrChannels;std::string filePath = R"(C:\chenqi\LearnOpenGL\Data\container.jpg)";unsigned char* data = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,data);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);glBindVertexArray(0);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glBindTexture(GL_TEXTURE_2D, texture);//当我们渲染一个物体要使用着色器程序ourShader.use();glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
12、双纹理渲染
shader见11节
texture.vs#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;out vec2 TexCoord;void main(){gl_Position = vec4(aPos, 1.0);TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}texture.fs#version 330 core
out vec4 FragColor;
in vec2 TexCoord;uniform sampler2D texture0;
uniform sampler2D texture1;
void main(){FragColor=mix(texture(texture0,TexCoord),texture(texture1,TexCoord),0.5);
}
注意png和jpg加载不同,rgba和rgb
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>
#include "shader.h"
#include "stb_image.h"void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}Shader ourShader("./texture.vs", "./texture.fs");//4. 设置顶点数据float vertices[] = {// positions // texture coords0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left };unsigned int indices[] = {0, 1, 3, // first triangle1, 2, 3 // second triangle};unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3*sizeof(float)));unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//加载和创建纹理unsigned int texture0;glGenTextures(1, &texture0);glBindTexture(GL_TEXTURE_2D, texture0);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsint width, height, nrChannels;stbi_set_flip_vertically_on_load(true);std::string filePath = R"(C:\chenqi\LearnOpenGL\Data\container.jpg)";unsigned char* data = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,data);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);//加载和创建纹理2unsigned int texture1;glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsfilePath = R"(C:\chenqi\LearnOpenGL\Data\awesomeface.png)";unsigned char* data2 = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data2) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data2);glBindVertexArray(0);ourShader.use();ourShader.setInt("texture0", 0);ourShader.setInt("texture1", 1);// 设置纹理单元一次即可glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture1);// 渲染循环while (!glfwWindowShouldClose(window)) {processInput(window);// 渲染glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
13、旋转、缩放、平移
texture.vs#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;out vec2 TexCoord;
uniform mat4 transform;void main(){gl_Position = transform*vec4(aPos, 1.0);TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}texture.fs#version 330 core
out vec4 FragColor;
in vec2 TexCoord;uniform sampler2D texture0;
uniform sampler2D texture1;
void main(){FragColor=mix(texture(texture0,TexCoord),texture(texture1,vec2(1-TexCoord.x,TexCoord.y)),0.5);
}
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>
#include "shader.h"
#include "stb_image.h"
#include <glm/glm.hpp>
#include <glm/ext/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}Shader ourShader("./texture.vs", "./texture.fs");//4. 设置顶点数据float vertices[] = {// positions // texture coords0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left };unsigned int indices[] = {0, 1, 3, // first triangle1, 2, 3 // second triangle};unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3*sizeof(float)));unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//加载和创建纹理unsigned int texture0;glGenTextures(1, &texture0);glBindTexture(GL_TEXTURE_2D, texture0);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsint width, height, nrChannels;stbi_set_flip_vertically_on_load(true);std::string filePath = R"(C:\chenqi\LearnOpenGL\Data\container.jpg)";unsigned char* data = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,data);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);//加载和创建纹理2unsigned int texture1;glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsfilePath = R"(C:\chenqi\LearnOpenGL\Data\awesomeface.png)";unsigned char* data2 = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data2) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data2);glBindVertexArray(0);ourShader.use();ourShader.setInt("texture0", 0);ourShader.setInt("texture1", 1);// 设置纹理单元一次即可glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture1);//设置变换glm::mat4 trans = glm::mat4(1.0f);trans = glm::rotate(trans, glm::radians(90.f), glm::vec3(0.0, 0.0, 1.0));//旋转的x,y,z轴trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));//缩放trans = glm::translate(trans, glm::vec3(1.f, 0.f, 0.0f));//平移unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));// 渲染循环while (!glfwWindowShouldClose(window)) {processInput(window);// 渲染glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
14、摄像机角度观察
camera.vs#version 330 core
layout(location=0) in vec3 aPos;
layout(location=1) in vec2 aTexCoord;out vec2 TexCoord;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main(){gl_Position=projection*view*model*vec4(aPos,1.0f);TexCoord=vec2(aTexCoord.x,aTexCoord.y);
}camera.fs#version 330 core
out vec4 FragColor;
in vec2 TexCoord;uniform sampler2D texture0;
uniform sampler2D texture1;void main(){FragColor=mix(texture(texture0,TexCoord),texture(texture1,TexCoord),0.2);
}
shader.h
#ifndef SHADER_H
#define SHADER_H#include <glad/glad.h>
#include <glm/glm.hpp>#include <string>
#include <fstream>
#include <sstream>
#include <iostream>class Shader
{
public:unsigned int ID;// constructor generates the shader on the fly// ------------------------------------------------------------------------Shader(const char* vertexPath, const char* fragmentPath){// 1. retrieve the vertex/fragment source code from filePathstd::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// ensure ifstream objects can throw exceptions:vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try{// open filesvShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// read file's buffer contents into streamsvShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();// close file handlersvShaderFile.close();fShaderFile.close();// convert stream into stringvertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();// 2. compile shadersunsigned int vertex, fragment;// vertex shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");// fragment Shaderfragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");// shader ProgramID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");// delete the shaders as they're linked into our program now and no longer necessaryglDeleteShader(vertex);glDeleteShader(fragment);}// activate the shader// ------------------------------------------------------------------------void use() const{glUseProgram(ID);}// utility uniform functions// ------------------------------------------------------------------------void setBool(const std::string& name, bool value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);}// ------------------------------------------------------------------------void setInt(const std::string& name, int value) const{glUniform1i(glGetUniformLocation(ID, name.c_str()), value);}// ------------------------------------------------------------------------void setFloat(const std::string& name, float value) const{glUniform1f(glGetUniformLocation(ID, name.c_str()), value);}// ------------------------------------------------------------------------void setVec2(const std::string& name, const glm::vec2& value) const{glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);}void setVec2(const std::string& name, float x, float y) const{glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);}// ------------------------------------------------------------------------void setVec3(const std::string& name, const glm::vec3& value) const{glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);}void setVec3(const std::string& name, float x, float y, float z) const{glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);}// ------------------------------------------------------------------------void setVec4(const std::string& name, const glm::vec4& value) const{glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);}void setVec4(const std::string& name, float x, float y, float z, float w) const{glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);}// ------------------------------------------------------------------------void setMat2(const std::string& name, const glm::mat2& mat) const{glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}// ------------------------------------------------------------------------void setMat3(const std::string& name, const glm::mat3& mat) const{glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}// ------------------------------------------------------------------------void setMat4(const std::string& name, const glm::mat4& mat) const{glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}private:// utility function for checking shader compilation/linking errors.// ------------------------------------------------------------------------void checkCompileErrors(GLuint shader, std::string type){GLint success;GLchar infoLog[1024];if (type != "PROGRAM"){glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}else{glGetProgramiv(shader, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}}
};
#endif
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>
#include "shader.h"
#include "stb_image.h"
#include <glm/glm.hpp>
#include <glm/ext/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {//1.初始化配置glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}Shader ourShader("./camera.vs", "./camera.fs");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};// world space positions of our cubesglm::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)};unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//只有绑定了vbo,下面的属性才与vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3*sizeof(float)));//加载和创建纹理unsigned int texture0;glGenTextures(1, &texture0);glBindTexture(GL_TEXTURE_2D, texture0);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsint width, height, nrChannels;stbi_set_flip_vertically_on_load(true);std::string filePath = R"(C:\chenqi\LearnOpenGL\Data\container.jpg)";unsigned char* data = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,data);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);//加载和创建纹理2unsigned int texture1;glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1);//设置纹理环绕参数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_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//加载图像和生成mipmapsfilePath = R"(C:\chenqi\LearnOpenGL\Data\awesomeface.png)";unsigned char* data2 = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);if (data2) {glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);glGenerateMipmap(GL_TEXTURE_2D);}else {std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data2);glBindVertexArray(0);ourShader.use();ourShader.setInt("texture0", 0);ourShader.setInt("texture1", 1);// 设置纹理单元一次即可glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture1);//投影矩阵glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);ourShader.setMat4("projection", projection);// 渲染循环while (!glfwWindowShouldClose(window)) {processInput(window);glEnable(GL_DEPTH_TEST);//缺少这一句就有问题,显示有问题,深度测试// 渲染glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);//观察者矩阵glm::mat4 view = glm::mat4(1.0f);float radius = 10.0f;float camX = static_cast<float>(sin(glfwGetTime()) * radius);float camZ = static_cast<float>(cos(glfwGetTime()) * radius);view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));ourShader.setMat4("view", view);glBindVertexArray(VAO);for (unsigned int i = 0; i < 3; i++) {//模型位置转换矩阵glm::mat4 model = glm::mat4(1.0f);model = glm::translate(model, cubePositions[i]);float angle = 20.0f * i;model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));ourShader.setMat4("model", model);glDrawArrays(GL_TRIANGLES, 0, 36);}glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}
换下一章了,太卡了
【B站最好OpenGL】11-工程管理-资源拷贝与多目标编译_哔哩哔哩_bilibili