OpenGL 编程指南(第八版)学习笔记——1 OpenGL概述
转载自 https://blog.csdn.net/wlk1229/article/details/79394115
什么是OpenGL
- OpenGL是一种应用程序编程接口 API.
- OpenGL被设计为一个现代化的 / 硬件无关的接口.
- 一个用来渲染图像的OpenGL程序需要执行的主要操作是:
- 从OpenGL的几何图元中设置数据,用于构建形状
- 使用不同的着色器(shader)对输入的图元数据执行计算操作,判断它们的位置,颜色,以及其他渲染属性.
- 将输入的图元的数学描述转换为与屏幕位置对应的像素片元(gragment).这一步叫光栅化.
- 最后针对光栅化过程所产生的每个片元,执行片元着色器(fragment),从而决定这个片元的最终颜色和位置.
- 如果有必要,还需要对每个片元执行一些额外操作.例如,判断片元对应的对象是否可见,或着将片元的颜色与当前屏幕位置的颜色进行融合
- 绘制流水线
![img](https://i-blog.csdnimg.cn/blog_migrate/68a8245080b987c10771679823f21a9d.png)
- OpenGL另一个本质的概念叫 着色器
- 最常用的包括: 顶点着色器,片元着色器
- 顶点着色器:处理顶点数据
- 片元着色器:处理光栅化后的片元数据.
- 最后生成的图像包含了屏幕上绘制的所有像素点.
- 像素是显示器上最小的可见单元.
- 所有像素都保存到
帧缓存framebuffer
. 这是图形硬件设备管理的一块独立内存区域. 可以直接映射到最终的显示设备上.
OpenGL语法
OpenGL渲染管线
准备向OpenGL传递数据
- OpenGL将所有的数据都保存到帧缓存对象中.它相当于由OpenGL服务器维护的一块内存区域.
glBufferData()
将数据传递到OpenGL
顶点着色
细分着色
- 细分着色器会用Patch来描述一个物体的形状
- 并且模型的外观变得更为平滑
几何着色
图元装配
- 图元装配阶段将这些顶点与相关的集合图元之间组织起来.
剪切
- 顶点可能回落在视口之外,也就是绘制的窗口之外.此时与顶点相关的图元会做出改动.保证相关的像素不会在视点外绘制.这叫剪切.
光栅化
- 将剪切后的图元传递给光栅化单元,生成对应的面片.可以将一个片元视为一个候选的像素.也就是放置在帧缓存中的像素.
片元着色
- 使用着色器来计算片元的最终颜色和深度值.
- 片元着色器非常强大,在这里回使用纹理映射的方式,对顶点处理阶段计算的颜色值进行补充.
逐片元操作
- 深度测试 | z-buffering
- 决定一个片元是否可见
使用OpenGL
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(512, 512);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow(argv[0]);
if (glewInit())
{
cout << "Unable to initialize GLEW.. " << endl;
return 1;
}
init();
glutDisplayFunc(display);
glutMainLoop();
}
#version 430 core
layout(location = 0) in vec4 vPosition;
void
main()
{
vec4 p = vPosition;
gl_Position = p;
}
#version 430 core
out vec4 fColor;
void
main()
{
fColor = vec4(0.0, 0.0, 1.0, 1.0);
}
enum VAO_IDs {Triangles, NumVAOs};
enum Buffer_IDs {ArrayBuffer, NumBuffers};
enum Attrib_IDs {vPosition = 0};
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
void init()
{
glGenVertexArrays(NumVAOs, VAOs);
glBindVertexArray(VAOs[Triangles]);
GLfloat vertices[NumVertices][2] = {
{-0.9f,-0.9f},
{0.85f,-0.90f},
{-0.90f, 0.85f},
{0.90f, -0.85f},
{0.90f,0.90f},
{-0.85f, 0.90f}
};
glGenBuffers(NumBuffers, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
ShaderInfo shaders[] = { {GL_VERTEX_SHADER, "triangles.vert"},{GL_FRAGMENT_SHADER, "triangles.frag"},{GL_NONE, NULL} };
program = LoadShaders(shaders);
glUseProgram(program);
GLuint pos = glGetAttribLocation(program, "vPosition");
glVertexAttribPointer(pos, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(pos);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAOs[Triangles]);
glDrawArrays(GL_TRIANGLES, 0, 6);
glFlush();
Sleep(30);
}
- 启用或禁用 OpenGL的操作
glEnable
glDisable
- 有很多枚举量可以作为模式参数传入.