1
0
mirror of https://github.com/LearnOpenGL-CN/LearnOpenGL-CN.git synced 2025-08-23 04:35:28 +08:00

更新“实例化”中的源代码以及文本排版

This commit is contained in:
1i9h7_b1u3
2025-01-23 11:58:59 +08:00
parent e18ffe0694
commit bd752a5030

View File

@@ -107,11 +107,7 @@ for(int y = -10; y < 10; y += 2)
shader.use();
for(unsigned int i = 0; i < 100; i++)
{
stringstream ss;
string index;
ss << i;
index = ss.str();
shader.setVec2(("offsets[" + index + "]").c_str(), translations[i]);
shader.setVec2(("offsets[" + std::to_string(i) + "]"), translations[i]);
}
```
@@ -124,11 +120,11 @@ glBindVertexArray(quadVAO);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100);
```
<fun>glDrawArraysInstanced</fun>的参数和<fun>glDrawArrays</fun>完全一样除了最后多了个参数用来设置需要绘制的实例数量。因为我们想要在10x10网格中显示100个四边形我们将它设置为100.运行代码之后你应该能得到熟悉的100个五彩的四边形。
<fun>glDrawArraysInstanced</fun>的参数和<fun>glDrawArrays</fun>完全一样除了最后多了个参数用来设置需要绘制的实例数量。因为我们想要在10x10网格中显示100个四边形我们将它设置为100运行代码之后你应该能得到熟悉的100个五彩的四边形。
## 实例化数组
虽然之前的实现在目前的情况下能够正常工作但是如果我们要渲染远超过100个实例的时候这其实非常普遍我们最终会超过最大能够发送至着色器的uniform数据大小[上限](http://www.opengl.org/wiki/Uniform_(GLSL)#Implementation_limits)。它的一个代替方案是<def>实例化数组</def>(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。
虽然之前的实现在目前的情况下能够正常工作但是如果我们要渲染远超过100个实例的时候这其实非常普遍我们最终会超过最大能够发送至着色器的uniform数据大小[上限](https://www.khronos.org/opengl/wiki/GLSL_Uniform#Implementation_limits)。它的一个代替方案是<def>实例化数组</def>(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。
使用顶点属性时顶点着色器的每次运行都会让GLSL获取新一组适用于当前顶点的属性。而当我们将顶点属性定义为一个实例化数组时顶点着色器就只需要对每个实例而不是每个顶点更新顶点属性的内容了。这允许我们对逐顶点的数据使用普通的顶点属性而对逐实例的数据使用实例化数组。
@@ -171,7 +167,7 @@ glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribDivisor(2, 1);
```
这段代码很有意思的地方在于最后一行,我们调用了<fun>glVertexAttribDivisor</fun>。这个函数告诉了OpenGL该**什么时候**更新顶点属性的内容至新一组数据。它的第一个参数是需要的顶点属性,第二个参数是属性除数(Attribute Divisor)。默认情况下属性除数是0告诉OpenGL我们需要在顶点着色器的每次迭代时更新顶点属性。将它设置为1时我们告诉OpenGL我们希望在渲染一个新实例的时候更新顶点属性。而设置为2时我们希望每2个实例更新一次属性以此类推。我们将属性除数设置为1是在告诉OpenGL处于位置值2的顶点属性是一个实例化数组。
这段代码很有意思的地方在于最后一行,我们调用了<fun>glVertexAttribDivisor</fun>。这个函数告诉了OpenGL该**什么时候**更新顶点属性的内容至新一组数据。它的第一个参数是需要的顶点属性,第二个参数是<def>属性除数</def>(Attribute Divisor)。默认情况下属性除数是0告诉OpenGL我们需要在顶点着色器的每次迭代时更新顶点属性。将它设置为1时我们告诉OpenGL我们希望在渲染一个新实例的时候更新顶点属性。而设置为2时我们希望每2个实例更新一次属性以此类推。我们将属性除数设置为1是在告诉OpenGL处于位置值2的顶点属性是一个实例化数组。
如果我们现在使用<fun>glDrawArraysInstanced</fun>,再次渲染四边形,会得到以下输出:
@@ -312,7 +308,7 @@ for(unsigned int i = 0; i < rock.meshes.size(); i++)
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)0);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(vec4Size));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(1 * vec4Size));
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(2 * vec4Size));
glEnableVertexAttribArray(6);