OpenGL使用的是管线的方式,利用GPU加速对简单的信息进行渲染,然后投影在屏幕上的方法,下图展示的就是信息在OpenGL里面的处理管线,Vertex信息由用户定义,保存在CPU中,随后在用户定义的GPU存储单元中做流程化的处理,然后把最终的图像投影在屏幕上。
1. CPU中定义vertex (e.g. vec3)
2. 把3D的顶点数据,转换成屏幕中的二维数据,range(-1,1),这个过程称为normalized device coordinates(NDC)
3. primitive assembly, 根据用户的输入(e.g. POINTS, GL_REIANGLES..),把所有顶点组合成形状(primitive)
4. 可以增加新的vertices来形成新的形状(primitive)
5. map这些形状到屏幕上的像素
6. 计算pixel的最终颜色,所以frag shader有颜色和光 阴影等信息
GPU的优势是可以其拥有需要小的处理核心core,可以并行的对简单的处理进行快速处理,处理的方式使用OpenGL里面的GLSL language,进行shader编写的小程序。这些小程序可以使我们更加细腻的知道GPU对数据的处理,来达到我们预期的效果。
下面需要理解的概念:
vertex buffer objects (VBO): 在GPU中储存顶点的内存空间,优势是可以同时传送大量的顶点数据在GPU的内存块上,在GPU内存块上后,shader可以极快的访问和储存。
# this buffer has a unique ID corresponding to that buffer, so we can generate one with a buffer ID using the glGenBuffers function
unsigned int VBO;
glGenBuffers(1, &VBO); #(number of buffer, ID of VBO)
#OpenGL allows us to bind to several buffers at once as long as they have a different buffer type. We can bind the newly created buffer to the GL_ARRAY_BUFFER target with the glBindBuffer function
#From that point on any buffer calls we make (on the GL_ARRAY_BUFFER target) will be used to configure the currently bound buffer, which is VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
#Then we can make a call to the glBufferData function that copies the previously defined vertex data into the buffer's memory
# type of buffer size in byte actual data how GPU manage
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
# GL_STREAM_DRAW: the data is set only once and used by the GPU at most a few times.
# GL_STATIC_DRAW: the data is set only once and used many times.
# GL_DYNAMIC_DRAW: the data is changed a lot and used many times.
# If, for instance, one would have a buffer with data that is likely to change frequently, a usage type of GL_DYNAMIC_DRAW ensures the graphics card will place the data in memory that allows for faster writes