0

我尝试使用transform特性来创建粒子系统,所以有2个transform buffer和2个array buffer,使用乒乓切换。

而且我的着色器很简单,只需保持添加源位置即可。

gs_Position = vs_Position[0] + vec3(1, 0, 1);

如果使用glDrawTransformFeedback(),2个缓冲区将保留原始数据,不会改变。但是如果我切换到glDrawArrays(),那么乒乓球工作,位置值不断增加。

初始代码

shader.setupShaderFromFile(GL_VERTEX_SHADER, "feedback.vert");
shader.setupShaderFromFile(GL_GEOMETRY_SHADER, "feedback.geom");
const GLchar* feedbackVaryings[] = { "gs_Position", "gs_Velocity" };
glTransformFeedbackVaryings(shader.getProgram(), 2, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
shader.linkProgram();

glGenTransformFeedbacks(2, tfo);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

Particle* p = new Particle[2];
p[0].position = glm::vec3(1, 2, 3);
p[1].position = glm::vec3(2, 3, 4);

glGenBuffers(2, bfo);
glBindBuffer(GL_ARRAY_BUFFER, bfo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Particle)*2, p, GL_STATIC_DRAW);

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo[0]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bfo[0]);

glBindBuffer(GL_ARRAY_BUFFER, bfo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Particle)*2, nullptr, GL_STATIC_READ);

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo[1]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bfo[1]);

执行转换

int from = pid;
int to = (pid + 1) % 2;

glEnable(GL_RASTERIZER_DISCARD);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo[to]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bfo[to]);

shader.begin();

glBindBuffer(GL_ARRAY_BUFFER, bfo[from]);
{
    GLint inputAttrib = shader.getAttributeLocation("a_Position");
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(inputAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (void*)offsetof(Particle, position));
}
{
    GLint inputAttrib = shader.getAttributeLocation("a_Velocity");
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(inputAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (void*)offsetof(Particle, velocity));
}

glBeginTransformFeedback(GL_POINTS);
//glDrawArrays(GL_POINTS, 0, 2);
glDrawTransformFeedback(GL_POINTS, tfo[from]);
glEndTransformFeedback();

shader.end();

glDisable(GL_RASTERIZER_DISCARD);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
4

0 回答 0