繁体   English   中英

着色器存储缓冲区中的OpenGL顶点

[英]OpenGL vertices in shader storage buffer

我现在正在使用计算着色器处理粒子系统。 我将所有粒子都放在着色器存储缓冲区中。 粒子包含两个顶点,即当前位置和前一个位置。

struct Particle{
    glm::vec4   _currPosition;
    glm::vec4   _prevPosition;
};

在我调度计算着色器之后,我想直接从着色器存储缓冲区中绘制所有粒子。 所以这就是我做的:

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBufferID);
_shaderManager->useProgram("computeProg");
glDispatchCompute((_numParticles/WORK_GROUP_SIZE)+1, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
_shaderManager->useProgram("shaderProg");
glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBufferID);
glVertexPointer(4,GL_FLOAT, sizeof(glm::vec4), (GLvoid*)0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, _numParticles);
glDisableClientState(GL_VERTEX_ARRAY);

问题是我在屏幕上看到了_numParticles,但是一半是用我的粒子结构的_prevPosition属性渲染的。 这意味着一个粒子被解释为在屏幕上绘制的两个顶点。 但我希望他跳过每个粒子结构中的_prevPosition属性。 哪里是我的错?

也许我初始化着色器存储缓冲区的方式很重要:

GLuint shaderStorageBufferID;

glGenBuffers(1, &shaderStorageBufferID);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferID);
glBufferData(GL_SHADER_STORAGE_BUFFER, numParticles*sizeof(Particle), NULL ,GL_STATIC_DRAW);
struct Particle* particles = (struct Particle*) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, numParticles*sizeof(Particle), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
for(int i = 0; i < numParticles; ++i){
    particles[i]._currPosition = glm::vec4(i, 0, 0.0, 1.0f);
    particles[i]._prevPosition = glm::vec4(i, 0, 1.0, 1.0f);
}

你的Particle结构包含两个vec4 您的计算着色器 vec4每个数组元素写入两个vec4

然而这一行:

glVertexPointer(4,GL_FLOAT, sizeof(glm::vec4), (GLvoid*)0);

告诉OpenGL你传递了一系列vec4 你不是。 你正在传递一个数组,其中每个元素都是两个 vec4 你想跳过第二个。

因此,告诉OpenGL,通过提供适当的步幅:

glVertexPointer(4, GL_FLOAT, sizeof(Particle), (GLvoid*)0);

哦,顺便说一句:你还在使用错误的障碍 仅仅因为你的代码发生功能并不意味着它是有保证的。 除非您正确地执行所有操作,否则不同步的加载/存储操作可能会非常棘手。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM