glDrawArrays 指定不同的偏移量
glDrawArrays specify different offsets
考虑以下情况:
设 A,B
为 VBO,使得 size(A)=N*size(B)
。将执行 N glDrawArrays
个调用。顶点着色器可以计算以下输入之一。
in VA: a1 a2 a3 a4 a5 ...
in VB: b1 b2 b3 b4 b5 ...
in VA: a1 a2 a3 a4 a5 ...
in VB: b6 b7 b8 b9 b10 ...
...
在此示例中,将有以下 VBO
A = (a1,a2,a3,a4,a5,...)
B1 = (b1,b2,b3,b4,b5,...)
B2 = (b6,b7,b8,b9,b10,...)
...
BN = ( ... , B_(size(A)*N-1)), B_(size(A)*N))
使用 VAO
V1 = (VA->A,VB->B1)
V2 = (VA->A,VB->B2)
...
VN = (VA->A,VB->BN)
VA->A
表示顶点属性VA
指向VBOA
。
情况是我使用互操作性在 OpenCL 中计算数据。从 OpenCL 计算的角度来看,使用将输出写入 单个缓冲区 的内核非常优雅,这也是我的 VBO。
所以 B 看起来像这样:
B = (b1, b2, b3, ..., B_(size(A)*N))
现在我知道每个数据块对应的 x 轴看起来像:
A = (a1, a2, a3, ... x_size(A))
为了绘制数据,我的第一次尝试是创建一个 VBO X
,它基本上是
X = (A, A, ...) = (a1, a2, a3, ... x_size(A), a1, a2, a3, ...)
然后使用 glDrawArrays
的 position, length
个参数从中呈现每个图形。
如果我有可能只使用所描述的 A,B
而不是将 B
拆分成几个 VBO 或将 X
复制到一个大 VBO 中,这对我来说将是一个很好的功能A
。这可能吗?如果不是:什么是好的策略?
使用 OpenGL >=4.3 或 ARB_vertex_attrib_binding 您可以使用 glBindVertexBuffer()
快速将 B 属性重新绑定到不同的缓冲区或同一缓冲区中的不同位置。您最终仍会遇到多个绘制调用,并且在这些绘制调用之间发生状态更改,但这是一个相当便宜的状态更改(就状态更改而言,它是最便宜的之一):
// Note: assuming A and B are just regular float, not vec2 or anything
// Omitted: VAO binding, enabling attributes, uniforms...
// Attribute locations
const int ATTRIB_A = 0, ATTRIB_B = 1;
// VBOs for A and B
GLuint buf_a, buf_b;
// Size of A = n, size of B = n * m
int n, m;
// Set the format for A and B
// Note: You can bind multiple attributes to each binding point,
// so hypothetical attribute C could share with A or B.
glVertexAttribFormat(ATTRIB_A, 1, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(ATTRIB_A, 1, GL_FLOAT, GL_FALSE, 0);
// Set the VBO binding points for A and B
glVertexAttribBinding(ATTRIB_A, 0);
glVertexAttribBinding(ATTRIB_B, 1);
// Bind your buffer for A
glBindVertexBuffer(0, buf_a, 0, sizeof(float));
for (int i = 0; i < m; i++) {
// Bind part of the buffer for B
glBindVertexBuffer(1, buf_b, i * n * sizeof(float), sizeof(float));
// Draw...
glDrawArrays(GL_POINTS, 0, n);
}
对于旧版本的 OpenGL,如果没有 ARB_vertex_attrib_binding,您可以在循环中调用 glVertexAttribPointer()
而不是 glBindVertexBuffer()
。
考虑以下情况:
设 A,B
为 VBO,使得 size(A)=N*size(B)
。将执行 N glDrawArrays
个调用。顶点着色器可以计算以下输入之一。
in VA: a1 a2 a3 a4 a5 ...
in VB: b1 b2 b3 b4 b5 ...
in VA: a1 a2 a3 a4 a5 ...
in VB: b6 b7 b8 b9 b10 ...
...
在此示例中,将有以下 VBO
A = (a1,a2,a3,a4,a5,...)
B1 = (b1,b2,b3,b4,b5,...)
B2 = (b6,b7,b8,b9,b10,...)
...
BN = ( ... , B_(size(A)*N-1)), B_(size(A)*N))
使用 VAO
V1 = (VA->A,VB->B1)
V2 = (VA->A,VB->B2)
...
VN = (VA->A,VB->BN)
VA->A
表示顶点属性VA
指向VBOA
。
情况是我使用互操作性在 OpenCL 中计算数据。从 OpenCL 计算的角度来看,使用将输出写入 单个缓冲区 的内核非常优雅,这也是我的 VBO。
所以 B 看起来像这样:
B = (b1, b2, b3, ..., B_(size(A)*N))
现在我知道每个数据块对应的 x 轴看起来像:
A = (a1, a2, a3, ... x_size(A))
为了绘制数据,我的第一次尝试是创建一个 VBO X
,它基本上是
X = (A, A, ...) = (a1, a2, a3, ... x_size(A), a1, a2, a3, ...)
然后使用 glDrawArrays
的 position, length
个参数从中呈现每个图形。
如果我有可能只使用所描述的 A,B
而不是将 B
拆分成几个 VBO 或将 X
复制到一个大 VBO 中,这对我来说将是一个很好的功能A
。这可能吗?如果不是:什么是好的策略?
使用 OpenGL >=4.3 或 ARB_vertex_attrib_binding 您可以使用 glBindVertexBuffer()
快速将 B 属性重新绑定到不同的缓冲区或同一缓冲区中的不同位置。您最终仍会遇到多个绘制调用,并且在这些绘制调用之间发生状态更改,但这是一个相当便宜的状态更改(就状态更改而言,它是最便宜的之一):
// Note: assuming A and B are just regular float, not vec2 or anything
// Omitted: VAO binding, enabling attributes, uniforms...
// Attribute locations
const int ATTRIB_A = 0, ATTRIB_B = 1;
// VBOs for A and B
GLuint buf_a, buf_b;
// Size of A = n, size of B = n * m
int n, m;
// Set the format for A and B
// Note: You can bind multiple attributes to each binding point,
// so hypothetical attribute C could share with A or B.
glVertexAttribFormat(ATTRIB_A, 1, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(ATTRIB_A, 1, GL_FLOAT, GL_FALSE, 0);
// Set the VBO binding points for A and B
glVertexAttribBinding(ATTRIB_A, 0);
glVertexAttribBinding(ATTRIB_B, 1);
// Bind your buffer for A
glBindVertexBuffer(0, buf_a, 0, sizeof(float));
for (int i = 0; i < m; i++) {
// Bind part of the buffer for B
glBindVertexBuffer(1, buf_b, i * n * sizeof(float), sizeof(float));
// Draw...
glDrawArrays(GL_POINTS, 0, n);
}
对于旧版本的 OpenGL,如果没有 ARB_vertex_attrib_binding,您可以在循环中调用 glVertexAttribPointer()
而不是 glBindVertexBuffer()
。