From bd752a5030e69ec57b67eebe244a275a4c3ad714 Mon Sep 17 00:00:00 2001
From: 1i9h7_b1u3 <1012796366@qq.com>
Date: Thu, 23 Jan 2025 11:58:59 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E2=80=9C=E5=AE=9E=E4=BE=8B?=
=?UTF-8?q?=E5=8C=96=E2=80=9D=E4=B8=AD=E7=9A=84=E6=BA=90=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=E4=BB=A5=E5=8F=8A=E6=96=87=E6=9C=AC=E6=8E=92=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/04 Advanced OpenGL/10 Instancing.md | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/docs/04 Advanced OpenGL/10 Instancing.md b/docs/04 Advanced OpenGL/10 Instancing.md
index 55f8771..46b2cb6 100644
--- a/docs/04 Advanced OpenGL/10 Instancing.md
+++ b/docs/04 Advanced OpenGL/10 Instancing.md
@@ -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);
```
-glDrawArraysInstanced的参数和glDrawArrays完全一样,除了最后多了个参数用来设置需要绘制的实例数量。因为我们想要在10x10网格中显示100个四边形,我们将它设置为100.运行代码之后,你应该能得到熟悉的100个五彩的四边形。
+glDrawArraysInstanced的参数和glDrawArrays完全一样,除了最后多了个参数用来设置需要绘制的实例数量。因为我们想要在10x10网格中显示100个四边形,我们将它设置为100。运行代码之后,你应该能得到熟悉的100个五彩的四边形。
## 实例化数组
-虽然之前的实现在目前的情况下能够正常工作,但是如果我们要渲染远超过100个实例的时候(这其实非常普遍),我们最终会超过最大能够发送至着色器的uniform数据大小[上限](http://www.opengl.org/wiki/Uniform_(GLSL)#Implementation_limits)。它的一个代替方案是实例化数组(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。
+虽然之前的实现在目前的情况下能够正常工作,但是如果我们要渲染远超过100个实例的时候(这其实非常普遍),我们最终会超过最大能够发送至着色器的uniform数据大小[上限](https://www.khronos.org/opengl/wiki/GLSL_Uniform#Implementation_limits)。它的一个代替方案是实例化数组(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。
使用顶点属性时,顶点着色器的每次运行都会让GLSL获取新一组适用于当前顶点的属性。而当我们将顶点属性定义为一个实例化数组时,顶点着色器就只需要对每个实例,而不是每个顶点,更新顶点属性的内容了。这允许我们对逐顶点的数据使用普通的顶点属性,而对逐实例的数据使用实例化数组。
@@ -171,7 +167,7 @@ glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribDivisor(2, 1);
```
-这段代码很有意思的地方在于最后一行,我们调用了glVertexAttribDivisor。这个函数告诉了OpenGL该**什么时候**更新顶点属性的内容至新一组数据。它的第一个参数是需要的顶点属性,第二个参数是属性除数(Attribute Divisor)。默认情况下,属性除数是0,告诉OpenGL我们需要在顶点着色器的每次迭代时更新顶点属性。将它设置为1时,我们告诉OpenGL我们希望在渲染一个新实例的时候更新顶点属性。而设置为2时,我们希望每2个实例更新一次属性,以此类推。我们将属性除数设置为1,是在告诉OpenGL,处于位置值2的顶点属性是一个实例化数组。
+这段代码很有意思的地方在于最后一行,我们调用了glVertexAttribDivisor。这个函数告诉了OpenGL该**什么时候**更新顶点属性的内容至新一组数据。它的第一个参数是需要的顶点属性,第二个参数是属性除数(Attribute Divisor)。默认情况下,属性除数是0,告诉OpenGL我们需要在顶点着色器的每次迭代时更新顶点属性。将它设置为1时,我们告诉OpenGL我们希望在渲染一个新实例的时候更新顶点属性。而设置为2时,我们希望每2个实例更新一次属性,以此类推。我们将属性除数设置为1,是在告诉OpenGL,处于位置值2的顶点属性是一个实例化数组。
如果我们现在使用glDrawArraysInstanced,再次渲染四边形,会得到以下输出:
@@ -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);