图列说明网站开发的流程,10月上海娱乐场所又要关门了,广州电子商城网站,重庆房产信息网官网房产查询文章目录 一些概念坐标转换阶段顶点着色器片段着色器VBOVAO 实战简介main.cppCMakeLists.txt最终效果 一些概念
坐标转换阶段
概述#xff1a; 模型空间、世界空间、视图空间和裁剪空间是对象在3D场景中经历的不同坐标变换阶段。每个空间对应渲染管道的一个步骤#xff0c;… 文章目录 一些概念坐标转换阶段顶点着色器片段着色器VBOVAO 实战简介main.cppCMakeLists.txt最终效果 一些概念
坐标转换阶段
概述 模型空间、世界空间、视图空间和裁剪空间是对象在3D场景中经历的不同坐标变换阶段。每个空间对应渲染管道的一个步骤逐步将模型从其初始位置转换到最终屏幕上的位置
模型空间
定义这是对象的本地坐标系是模型创建时的坐标作用模型空间定义了物体的基本形状和几何信息不受场景中其他物体位置的影响。每个模型都有自己的模型空间坐标转换通过模型矩阵可以将模型空间的坐标转换为世界空间
世界空间
定义这是整个场景的坐标系所有模型在世界空间中都有唯一的位置和方向可以视为“全局坐标系”作用将所有对象放置在同一个坐标系统中确保它们相对位置正确转换通过应用视图矩阵将世界空间的坐标转换为视图空间视图矩阵通常基于摄像机的位置和方向
视图空间
定义又称为“摄像机空间“是以摄像机位置为原点的坐标系此时场景中的所有对象都以摄像机为参考重新定位作用使得所有对象相对于摄像机的位置和方向变得更直观便于确定哪些对象可见、如何投影到屏幕转换使用投影矩阵将视图空间转换为裁剪空间这一步决定了图像的投影类型如透视投影或正交投影
裁剪空间
定义应用投影变换后的空间此时3D场景的坐标被转换为一个标准化的3D盒子所有可见的坐标xyz值均被限制在-1到1之间作用裁剪空间便于对视锥外部的物体进行裁剪只保留可见部分。裁剪后的坐标将进行透视除法映射到2D屏幕上的坐标即归一化设备坐标转换裁剪空间进一步转换为屏幕空间经过视口变换使坐标适配屏幕的分辨率和比例
顶点着色器
概述 顶点着色器Vertex Shader是对输入的顶点进行处理顶点是组成几何体的基本元素比如三角形的每个角都是一个顶点
作用
顶点位置变换顶点着色器通常会将顶点从模型空间即对象的局部坐标系转换到世界空间、视图空间最后转换到裁剪空间以便在屏幕上正确显示顶点属性处理除了位置顶点着色器还可以处理其他与顶点相关的属性比如法线、纹理坐标、颜色等光照计算在某些情况下顶点着色器可以进行基础的光照计算如使用法线来计算顶点的光照效果
输入 顶点的坐标、法线、纹理坐标等数据
输出 处理后的顶点坐标如变换后的顶点位置和其他顶点属性供后续的图形流水线使用
片段着色器
概述 片段着色器Framgment Shader是屏幕上每个像素的潜在颜色值在光栅化阶段之后每个几何体被转换为一系列像素片段片段着色器负责确定这些片段的最终颜色
作用
颜色计算片段着色器通过对纹理、光照、材质等信息的处理确定每个像素的颜色它通常会结合插值后的顶点属性如纹理坐标或颜色进行复杂的颜色计算光照效果片段着色器可以进行精确的光照计算以便生成更逼真的阴影和高光效果纹理映射片段着色器可以从纹理中采样根据纹理坐标获取纹理颜色并应用到片段上
输入 每个片段的插值属性如纹理坐标、颜色、发现等
输出 每个片段的最终颜色值传递给屏幕或帧缓冲区
VBO
概述 VBO(Vertex Buffer Object)是一个存储在GPU内存中的缓冲区用于存放顶点数据。通常顶点数据包含顶点的坐标、颜色、法线、纹理坐标等信息。通过使用VBO程序可以将这些顶点数据传输到GPU这样GPU可以在渲染时快速访问它们而不需要每帧都从CPU传输数据
关键步骤
创建VBO使用glGenBuffers()创建一个VBO绑定VBO使用glBindBuffer()绑定VBO指定将要存储的缓冲数据类型如顶点数据GL_ARRY_BUFFER填充VBO使用glBufferData()将顶点数据传输到VBO中
VAO
概述 VAO(Vertex Array Object)是一个用于保存VBO配置的对象它记录了与绘制顶点相关的所有状态信息。VAO不仅仅是VBO的一个包装器它还保存了顶点属性指针和启用状态。例如每个顶点的布局、数据的解释方式如步幅、偏移量以及使用的VBO。使用VAO可以简化渲染过程因为当VAO被绑定时所有与其关联的VBO和顶点属性信息都会自动生效。
关键步骤
创建VAO使用glGenVertexArrays()创建一个VAO绑定VAO使用glBindVertexArray()绑定VAO设置顶点属性指针使用glVertexAttribPointer()设置顶点属性指针告诉OpenGL如何解释顶点数据启用顶点属性使用glEnableVertexAttribArray()启用顶点属性
实战
简介
怎么在vscode上使用cmake构建项目具体可以看这篇Windows上如何使用CMake构建项目 - 凌云行者的博客
目的 绘制一个三角形
环境
编译工具链使用msys2安装的mingw-gcc依赖项glfw3:x64-mingw-staticglad:x64-mingw-static通过vcpkg安装
main.cpp
#include glad/glad.h
#include GLFW/glfw3.h
#include iostreamusing std::cout;
using std::endl;// 屏幕宽度
const unsigned int SCR_WIDTH 800;
// 屏幕高度
const unsigned int SCR_HEIGHT 600;// 窗口大小改变的回调函数
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {// 确保视口与新窗口尺寸匹配注意在视网膜显示器上宽度和高度会显著大于指定值glViewport(0, 0, width, height);
}// 处理输入
void process_input(GLFWwindow* window) {// 按下ESC键时进入if块if (glfwGetKey(window, GLFW_KEY_ESCAPE) GLFW_PRESS)// 关闭窗口glfwSetWindowShouldClose(window, true);
}// 顶点着色器源码
const char *vertexShaderSource #version 330 core\n // 指定了GLSLOpenGL着色器语言的版本layout (location 0) in vec3 aPos;\n // 定义了一个输入变量aPos它是一个vec3类型的变量, 并且指定了它的位置值为0, 这意味着顶点属性数组的第一个属性将被绑定到这个变量void main()\n{\n gl_Position vec4(aPos.x, aPos.y, aPos.z, 1.0);\n // 将输入的顶点位置aPos转换为一个四维向量gl_Postion是OpengGL固定功能管线中用于存储顶点位置的变量}\0;// 片段着色器源码
const char *fragmentShaderSource #version 330 core\n // 指定了GLSLOpenGL着色器语言的版本out vec4 FragColor;\n // 定义了一个输出变量FragColor它是一个vec4类型的变量表示片段颜色out关键字表示这个变量将输出到渲染管线的下一个阶段void main()\n{\n FragColor vec4(1.0f, 0.5f, 0.2f, 1.0f);\n // 将输出颜色设置为橙色}\n\0;int main() {// 初始化glfwglfwInit();// 设置opengl版本glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 使用核心模式确保不使用任何被弃用的功能glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 创建glfw窗口GLFWwindow* window glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, I am window title, NULL, NULL);if (window NULL) {cout Failed to create glfw window endl;// 终止GLFWglfwTerminate();return -1;}// 设置当前窗口的上下文glfwMakeContextCurrent(window);// 设置窗口大小改变的回调函数glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// 加载opengl函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {cout Failed to initialize GLAD endl;return -1;}// 构建并编译顶点着色程序// 创建一个着色器对象GL_VERTEX_SHADER表示顶点着色器unsigned 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);cout ERROR::SHADER::VERTEX::COMPILATION_FAILED\n infoLog endl;}// 构建并编译片段着色器// 创建一个着色器对象GL_FRAGMENT_SHADER表示片段着色器unsigned int fragmentShader glCreateShader(GL_FRAGMENT_SHADER);// 将着色器源码附加到着色器对象上glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL);// 编译着色器glCompileShader(fragmentShader);// 检查着色器是否编译成功glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, success);if (!success) {glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);cout ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n infoLog endl;}// 创建着色器程序对象unsigned int shaderProgram glCreateProgram();// 将着色器对象附加到着色器程序上glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);// 链接程序对象glLinkProgram(shaderProgram);// 检查链接是否成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);cout ERROR::SHADER::PROGRAM::LINKING_FAILED\n infoLog endl; }// 删除着色器对象glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 设置三角形的顶点数据float vertices[] {-0.5f, -0.5f, 0.0f, // 左下角0.5f, -0.5f, 0.0f, // 右下角0.0f, 0.5f, 0.0f // 顶部};// 生成一个VAOunsigned int VAO;glGenVertexArrays(1, VAO);// 绑定VAO使其成为当前操作的VAOglBindVertexArray(VAO);// 生成一个VBOunsigned int VBO;glGenBuffers(1, VBO);// 绑定VBO, 使其成为当前操作的VBOGL_ARRAY_BUFFER表示顶点缓冲区glBindBuffer(GL_ARRAY_BUFFER, VBO);// 为当前绑定的VBO创建并初始化数据存储GL_STATIC_DRAW表示数据将一次性提供给缓冲区并且在之后的绘制过程中不会频繁更改glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 定义顶点属性的布局// - index顶点属性的索引// - size每个顶点属性的数量每个顶点有三个分享// - type数据类型// - normalized是否将非浮点数值归一化// - stride连续顶点属性之间的间隔// - pointer数据在缓冲区中的偏移量glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);// 启用顶点属性数组glEnableVertexAttribArray(0);// 解绑VBOglBindBuffer(GL_ARRAY_BUFFER, 0);// 解绑VAOglBindVertexArray(0);// 循环渲染while (!glfwWindowShouldClose(window)) { // 检查是否应该关闭窗口// 处理输入process_input(window);// 清空屏幕所用的颜色glClearColor(0.2f, 0.3f, 0.3f, 1.0f);// 清空颜色缓冲主要目的是为每一帧的渲染准备一个干净的画布glClear(GL_COLOR_BUFFER_BIT);// 使用着色器程序glUseProgram(shaderProgram);// 绑定VAOglBindVertexArray(VAO);// 绘制三角形glDrawArrays(GL_TRIANGLES, 0 ,3);// 交换缓冲区glfwSwapBuffers(window);// 处理所有待处理事件去poll所有事件看看哪个没处理的glfwPollEvents();}// 删除VAOglDeleteVertexArrays(1, VAO);// 删除VBOglDeleteBuffers(1, VBO);// 删除着色器程序glDeleteProgram(shaderProgram);// 终止GLFW清理GLFW分配的资源glfwTerminate();return 0;
}CMakeLists.txt
# 设置CMake的最低版本要求
cmake_minimum_required(VERSION 3.10)
# 设置项目名称
project(HelloTriangle)# vcpkg集成, 这里要换成你自己的vcpkg工具链文件和共享库路径
set(VCPKG_ROOT D:/software6/vcpkg/)
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
set(CMAKE_PREFIX_PATH ${VCPKG_ROOT}/installed/x64-mingw-static/share)# 查找所需的包
find_package(glad CONFIG REQUIRED)
find_package(glfw3 CONFIG REQUIRED)# 添加可执行文件
add_executable(HelloTriangle main.cpp)# 链接所需的库
target_link_libraries(HelloTriangle PRIVATE glad::glad glfw)最终效果