gpt4 book ai didi

c++ - 不同大小的着色器存储缓冲区内容 "transfered"到数组缓冲区

转载 作者:太空宇宙 更新时间:2023-11-04 13:23:55 24 4
gpt4 key购买 nike

我在计算着色器中计算出的位置实例化一个对象。我想将包含位置的计算着色器的输出绑定(bind)到用于绘制的数组缓冲区,但我无法让它工作。我对索引算法表示歉意,我对内存对齐非常偏执并放弃了所有 vector 。

相关代码简化:

初始化:

//x, y, z, 1 stored in succession
/*float*/positions = new float[maxPositionCount * 4];

//initialize positions_vbo
glGenBuffers(1, &position_vbo);
glBindBuffer(GL_ARRAY_BUFFER, position_vbo);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//initialize positionsOUT_ssbo
glGenBuffers(1, &positionsOUT_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, positionsOUT_ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * maxPositionCount * sizeof(float), NULL, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, positionsOUT_ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

//initialize positionCounter
glGenBuffers(1, &positionCount_acb);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, positionCount_acb);
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 7, positionCount_acb);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);

绘制循环:

//initialize the counter
posCount = 0;
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 7, positionCount_acb);
glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &posCount);

//send other data to compute shader in order to calculate positions
//dispatch and wait
//....

//retrieve the counter
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 7, positionCount_acb);
glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &positionCount_acb);

//retrieve the positions (1)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, positionsOUT_ssbo);
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, posCount * 4 * sizeof(float), positions);

//bind position_vbo (2)
glBindBuffer(GL_ARRAY_BUFFER, position_vbo);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(float) * posCount, posCount > 0 ? &positions[0] : NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glVertexAttribDivisor(2, 1);

//instead of (1)+(2) I would like to know if something like this is possible
//glBindBuffer(GL_ARRAY_BUFFER, positionsOUT_ssbo);
//glEnableVertexAttribArray(2);
//glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
//glVertexAttribDivisor(2, 1);

//bind vertex array and draw the object instances
glBindVertexArray(vertexArrayOfTheObjectImDrawing);
glDrawElementsInstanced(GL_TRIANGLES, objectSharedVertexCount, GL_UNSIGNED_SHORT, 0, posCount);

计算着色器:

layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in;

//just in case they are relevant somehow
//can set and get them fine but they have fixed size (maxPositionCount)
//---------v
layout(std430, binding=4) buffer A {
int a[ ];
};
layout(std430, binding=5) buffer B {
int b[ ];
};
layout(std430, binding=6) buffer C {
int c1,c2,c3,c4,c5;
};
//----------^

layout(binding = 7, offset = 0) uniform atomic_uint returnedPositionsIndex;

layout(std430, binding=8) buffer pos_Out
{
float positionsOUT[ ];
};

void main()
{
ivec3 currentPos = gl_GlobalInvocationID.xyz;

if (I_want_that_position_returned(currentPos))
{
uint i = atomicCounterIncrement(returnedPositionsIndex);
positionsOUT[i * 4 + 0] = float(index3D.x);
positionsOUT[i * 4 + 1] = float(index3D.y);
positionsOUT[i * 4 + 2] = float(index3D.z);
positionsOUT[i * 4 + 3] = 1.0;
}
}

顶点着色器:

uniform mat4 worldViewProjection;
layout(location = 1) in vec4 vertPosition;
layout(location = 2) in vec4 position;
int main() {
gl_Position = worldViewProjection * (vertPosition + position);
}

目前它崩溃了

glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, posCount * 4 * sizeof(float),  positions);

调用,即使它是程序中唯一未注释的行。调试错误:

Exception thrown at 0x0000000001A132A9 (atio6axx.dll) in asd.exe:
0xC0000005: Access violation writing location 0x0000000000000000.

我已经尝试通过预先调用 glBufferData(...positions) 来初始化数据。使用正确的计数检索原子计数器。另外,有没有办法在不复制和绑定(bind)到 positions_vbo 的情况下从 positionsOUT_ssbo 发送位置数据?

编辑:崩溃已修复,初始化时重新声明变量“positions”..

EDIT2:我在上面评论的行确实是一种将 ssbo 的内容直接“绑定(bind)”到数组缓冲区的方法。如果有更好的方法,请随时分享。

最佳答案

Well that was embarassing. I redeclared the class variable positions in the initializing phase, shadowing the one in the draw loop. Works fine now. Thanks for pointing me in the right direction!

根据您的评论,我在下面复制了我的原始评论作为回复。


我看到你有 float* positions = new float[maxPositionCount * 4]; 但我从来没有看到值实际添加到这个数组中的时间,所以据我所知它是一个未初始化的内存块可以告诉。

然后您调用 glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, posCount * 4 * sizeof(float), positions); 它似乎发送了这个未初始化的内存块,它可能被设置为零,并且会解释为什么您收到 访问冲突写入位置 0x0000000000000000. 错误。

关于c++ - 不同大小的着色器存储缓冲区内容 "transfered"到数组缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33993877/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com