Opengl GLDRAW数组指定不同的偏移

Opengl GLDRAW数组指定不同的偏移,opengl,opencl,Opengl,Opencl,考虑以下情况: 设A,B为VBO,使size(A)=N*size(B)。NglDrawArrays将执行调用。顶点着色器可以计算以下输入之一 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,...)

考虑以下情况:

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
指向VBO
A

情况是,我使用互操作性在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_绑定,您可以使用
glBindVertexBuffer()
将B属性快速重新绑定到不同的缓冲区或同一缓冲区中的不同位置。最终仍然会有多个绘制调用,并且这些绘制调用之间会发生状态更改,但这是一种相当便宜的状态更改(就状态更改而言,它是最便宜的一种):

//注意:假设A和B只是常规浮点,而不是vec2或任何东西
//省略:VAO绑定、启用属性、制服。。。
//属性位置
常数int ATTRIB_A=0,ATTRIB_B=1;
//A和B的VBO
GLuint buf_a,buf_b;
//A的尺寸=n,B的尺寸=n*m
int n,m;
//设置A和B的格式
//注意:可以将多个属性绑定到每个绑定点,
//所以假设属性C可以与A或B共享。
glVertexAttribFormat(属性A,1,GL\u浮点,GL\u假,0);
glVertexAttribFormat(属性A,1,GL\u浮点,GL\u假,0);
//设置A和B的VBO绑定点
glVertexAttribBinding(ATTRIB_A,0);
glVertexAttribBinding(ATTRIB_B,1);
//将缓冲区绑定为
glBindVertexBuffer(0,buf_a,0,sizeof(float));
for(int i=0;i

使用较旧版本的OpenGL,并且没有ARB_vertex_attrib_绑定,您可以在循环中调用
glVertexAttribPointer()
,而不是
glBindVertexBuffer()

我对这里的内存布局感到困惑。VBO是一个连续的内存段,就像您从
malloc()
获得的一样。如果A是VBO,它怎么可能在两个地方?你的意思是A和B是不同的顶点属性吗?你能把你想要的内存布局画成一条直线,而不是这个有点模棱两可的2D布局吗?或者换句话说,我不确定这是否意味着
a1 a2。。。一个b1 b2。。。bna1a2。。。英国国民+1亿+2。。。b2N
,或者如果它的意思是
a1 b1 a2 b2。。。一个bN…
对不起,我的第一个问题不准确,我更新了问题。希望情况变得更清楚now@keksnicoh:“如果我能像上面描述的那样只使用a,B,而不是将B拆分成几个VBO或将X复制成一个大的VBO a,这对我来说将是一个很好的功能。”谁说你不能这样做?@Nicol Bolas:没人,但我不知道怎么做。glBindVertexBuffer是我的拿手好戏!我坚持使用mac上的core profile 4.1。glVertexAttribPointer在这里对我有帮助吗?我不能用这个命令定义偏移量。啊,是的,我和你一样痛苦。偏移量实际上是
glvertexattributepointer
的最后一个参数。它看起来只是一个指针,但实际上是一个偏移量。是的,我在这一刻读到:。谢谢你的提示,看起来我可以像我希望的那样解决我的问题——即使是在OpenGL4.1CoreProfile中。
// 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);
}