本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主
如果我们需要渲染大量物体时, 代码看起来会像这样:
for(int i = 0; i < amount; i++)
{
DoSomeThing()l
glDrawArrays(GL_TRIANGLES, 0, amount_of_veritices);
}
如果将数据一次性发送给GPU,然后使用一个绘制函数让OpenGL利用这些数据绘制多个物体,就会方便了。这就是实例化(Instancing)。
代码:
顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aOffset;
uniform vec2 offsets[100];
out vec3 Color;
void main() {
Color=aNormal;
gl_Position = vec4(aPos, 1.0) + vec4(aOffset, 0.0, 0.0);
}
片段着色器
#version 330 core
out vec4 FragColor;
in vec3 Color;
void main() {
FragColor = vec4(Color, 1.0);
}
主要代码:mesh.cpp
unsigned int instanceVBO;
gl_fn_->glGenBuffers(1, &instanceVBO);
gl_fn_->glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
gl_fn_->glBufferData(GL_ARRAY_BUFFER, sizeof(QVector2D) * 100, &translations[0], GL_STATIC_DRAW);
gl_fn_->glBindBuffer(GL_ARRAY_BUFFER, 0);
......
gl_fn_->glEnableVertexAttribArray(2);
gl_fn_->glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
gl_fn_->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
gl_fn_->glBindBuffer(GL_ARRAY_BUFFER, 0);
gl_fn_->glVertexAttribDivisor(2, 1);
glVertexAttribDivisor函数告诉了OpenGL该什么时候更新顶点属性的内容到新一组数据:
超采样抗锯齿:使用比正常分辨率更高的分辨率,即超采样来渲染场景,当图像输出在帧缓冲中更新时,分辨率会被下采样到正常的分辨率。这些额外的分辨率被用来放置锯齿边缘的产生
多重采样:每个像素中心包含一个采样点,它会被用来决定这个三角形是否遮盖了某个像素
多重采样所做的是将一个采样点编程多个采样点
采样点的数量可以是任意的,更多的采样点能带来更精确的遮盖率
QSurfaceFormat format;
format.setSamples(4);
setFormat(format);
glEnable(GL_MULTISAMPLE);
如果想要使用自己的帧缓冲进行离屏渲染,那么需要手动生成多重采样缓冲
将纹理渲染到multiSamples帧缓冲 --》将multiSamples帧缓冲中的纹理赋值给另外一个自定义的帧缓冲–》使用另外一个自定帧缓冲中的纹理附件作为mesh的纹理,进行绘制。