这篇文章通过建筑工地的比喻,生动解释了GPU渲染流程。CPU像设计师,将顶点数据(积木)和索引数据(说明书)发送到GPU显存(仓库)。GPU工人根据索引找到顶点,经顶点着色器(工头)处理,拼成三角形(墙),再通过片元着色器(画匠)上色。代码示例展示了OpenGL中如何上传数据、设置着色器和发起绘制命令。整个过程自动高效,GPU负责从数据处理到最终显示的完整渲染流程。
一、形象比喻
1. 你是建筑设计师,GPU是工地上的工人
你(CPU)把“积木清单”(顶点数据)和“拼装说明书”(索引数据)快递到工地仓库(GPU显存)。
工人(GPU)拿到这些资料后,开始按照说明书拼房子(渲染图形)。
2. 施工流程
工人先看说明书(索引),找到需要的积木(顶点)。
每块积木都要经过工头(顶点着色器)检查、加工(比如变换位置)。
工人把三块积木拼成一面墙(三角形)。
画匠(片元着色器)给墙上色、贴砖(纹理)。
最后,房子建好,展示给大家看(显示到屏幕)。
二、代码实现(以OpenGL为例)
我们用一个简单的三角形为例,展示GPU收到数据后是怎么一步步用起来的。
1. 上传数据到GPU(准备阶段)
// 顶点数据:三角形的三个点
float vertices[] = {
// 位置 // 颜色
0.0f, 0.5f, 1.0f, 0.0f, 0.0f, // 顶点1:红色
-0.5f,-0.5f, 0.0f, 1.0f, 0.0f, // 顶点2:绿色
0.5f,-0.5f, 0.0f, 0.0f, 1.0f // 顶点3:蓝色
};
unsigned int indices[] = { 0, 1, 2 }; // 三角形
// 创建并上传到GPU
GLuint vbo, vao, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 设置顶点属性指针
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // 位置
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float))); // 颜色
glEnableVertexAttribArray(1);
glBindVertexArray(0);
2. GPU怎么用这些数据?(渲染阶段)
2.1 你发出“开工”命令
glUseProgram(shaderProgram); // 使用着色器 glBindVertexArray(vao); // 绑定VAO glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); // 画三角形
2.2 GPU内部流程(自动完成)
拿说明书(索引):GPU读indices,知道要用第0、1、2号顶点。
找积木(顶点):GPU去vertices里找对应数据。
工头加工(顶点着色器):每个顶点送进顶点着色器,做变换、传递颜色。
拼三角形:GPU把三个顶点拼成一个三角形。
画匠上色(片元着色器):三角形覆盖的每个像素都执行片元着色器,决定颜色。
展示成果:最终像素写入帧缓冲,显示到屏幕。
2.3 着色器代码(工头和画匠)
顶点着色器(工头)
#version 330 core
layout(location = 0) in vec2 aPos; // 位置
layout(location = 1) in vec3 aColor; // 颜色
out vec3 ourColor; // 传给片元着色器
void main()
{
gl_Position = vec4(aPos, 0.0, 1.0); // 变换到屏幕坐标
ourColor = aColor; // 传递颜色
}
片元着色器(画匠)
#version 330 core
in vec3 ourColor; // 从顶点着色器来的颜色
out vec4 FragColor; // 输出到屏幕
void main()
{
FragColor = vec4(ourColor, 1.0); // 上色
}
三、流程串联
你上传数据 → GPU仓库有了积木和说明书。
你发指令(DrawCall) → 工人开始施工。
GPU按说明书找积木 → 每块积木送工头加工。
拼三角形 → 画匠给每块墙上色。
成果展示 → 房子建好,大家看到。
四、总结
GPU收到数据后怎么用?
就是根据索引,找顶点,送进着色器加工,拼成三角形,给每个像素上色,最后显示到屏幕。
代码实现
你只需上传数据、写好着色器、发起DrawCall,剩下的拼装和上色,GPU全自动高效完成!
版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33060405/article/details/148294626





