I’m trying to use an additional attribute in a transform feedback shader, and I just can’t get it to work. The idea is to create particle trails- I pass in a position and texture holding the previous values. The positions are being updated by a simple rotation matrix that changes over time. I need to pass in the original position of the particle as well as the previous positions in the texture.
If the vertex is at the head of the trail, I update it’s position using the new value of the matrix; if it’s further down the trail, I use the previous position that has been passed in.
The attribute I’m trying to set is called position
, and I’m setting it with the contents of feedbackSourceBuffer
below.
// particleGen is creating a list of vec4s to use as positions
// transformManager is (currently) just updating a rotation matrix
void ofApp::setupTrails() {
int i, j;
// Feedback settings
feedbackSettings.shaderFiles[GL_VERTEX_SHADER] = "shaders/transformShader.vert";
feedbackSettings.bindDefaults = true;
feedbackSettings.varyingsToCapture = { "outputVec" };
feedbackShader.setup(feedbackSettings);
numTrails = particleGen.numParticles;
// Allocate the buffers to use
feedbackSourceBuffer.allocate(sizeof(glm::vec4) * numTrails * pointsPerTrail, GL_STATIC_DRAW);
feedbackBuffer1.allocate(sizeof(glm::vec4) * numTrails * pointsPerTrail, GL_DYNAMIC_DRAW);
feedbackBuffer2.allocate(sizeof(glm::vec4) * numTrails * pointsPerTrail, GL_DYNAMIC_DRAW);
// Create some pointers to make flip-flop easier
fromBuffer = &feedbackBuffer1;
toBuffer = &feedbackBuffer2;
std::vector<float> init;
std::vector<int> indices;
// These are the indices of the trails. There's extra being added because I'm using line strips with
// primitive restart at a particular index
trailIndexBuffer.allocate(sizeof(int) * (numTrails * pointsPerTrail + numTrails), GL_STATIC_DRAW);
// Set the initial values from those generated in the particleGen
for (i = 0; i < numTrails; i++) {
for (j = 0; j < pointsPerTrail; j++) {
init.insert(init.end(), {
particleGen.particleValues[i * 4],
particleGen.particleValues[i * 4 + 1],
particleGen.particleValues[i * 4 + 2],
particleGen.particleValues[i * 4 + 3]
});
indices.insert(indices.end(), i * pointsPerTrail + j);
}
indices.insert(indices.end(), restartIndex);
}
// Set the data in the buffers
feedbackSourceBuffer.setData(init, GL_DYNAMIC_DRAW);
feedbackSourceBuffer.copyTo(*toBuffer);
feedbackSourceBuffer.copyTo(*fromBuffer);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!! If I do this, I end up with a blank screen, as if nothing has been processed
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//trailsVbo.setVertexBuffer(feedbackSourceBuffer);
trailsVbo.setVertexBuffer(*toBuffer, 4, 0, 0);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!! For some reason I can't use this attribute?
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
trailsVbo.setAttributeBuffer(feedbackShader.getAttributeLocation("position"), feedbackSourceBuffer, 4, sizeof(glm::vec4));
trailsVbo.enableIndices();
trailIndexBuffer.setData(indices, GL_STATIC_DRAW);
trailsVbo.setIndexBuffer(trailIndexBuffer);
// Run feedback a few times to set the initial trails up
for (i = 0; i < pointsPerTrail; i++) {
transformManager.update(timeStepf * i);
doFeedback();
}
}
void ofApp::doFeedback() {
// Reallocate the texture that gets read in
feedbackTexture.allocateAsBufferTexture(*fromBuffer, GL_RGBA32F);
feedbackShader.beginTransformFeedback(GL_POINTS, *toBuffer);
feedbackShader.setUniformMatrix4f("modelMatrix", transformManager.matrix);
feedbackShader.setUniformTexture("tex", feedbackTexture, 0);
feedbackShader.setUniform1i("trailSize", pointsPerTrail);
trailsVbo.draw(GL_POINTS, 0, numTrails * pointsPerTrail);
feedbackShader.endTransformFeedback(*toBuffer);
// Swap the buffers over
ofBufferObject* tmp = fromBuffer;
fromBuffer = toBuffer;
toBuffer = tmp;
}
and then in the shader…
#version 330
uniform int trailSize;
uniform samplerBuffer tex;
uniform mat4 modelMatrix;
in vec4 position;
out vec4 outputVec;
void main() {
int id = gl_VertexID;
outputVec = position;
if (id % trailSize == 0) {
outputVec = texelFetch(tex, id) * position; // this just displays blank
outputVec = texelFetch(tex, id) * modelMatrix; // this works fine, but isn't right - if I keep updating the model matrix, this explodes
}
else {
outputVec = texelFetch(tex, id - 1);
}
}
Can anyone see what I’m doing wrong here? Thanks in advance!