Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Transform feedback and VAO + Indices

  1. #1
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251

    Question Transform feedback and VAO + Indices

    Hey, it seems, like i don't quite get how does TF interact with VAO's and GL_ELEMENT_ARRAY_BUFFER's. I try to make my animation system to work with transform feedback. So i have initial VAO1 containing all necessary attributes and i want to draw it with transform feedback enabled, outputting results into ARRAY_BUFFER, which is bound to another VAO2 used to finally draw.

    Here's initialization of TF and related buffers:
    Code :
    //transform feedback
            if(isAnimated) {
                //setup transform feedback
                glGenTransformFeedbacks(1, &transformFeedbackObject);
                glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackObject);
     
                //create output VAO
                glGenVertexArrays(1, &animationOutputVAO);
                glBindVertexArray(animationOutputVAO);
     
                glGenBuffers(1, &animationOutputBufferObject);
                glBindBuffer(GL_ARRAY_BUFFER, animationOutputBufferObject);
                glBufferData(GL_ARRAY_BUFFER, modelStorage[modelId].data.numVertices * sizeof(float), NULL, GL_DYNAMIC_COPY);
     
                glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, animationOutputBufferObject); //bind as TF output
     
     
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelStorage[modelId].data.indexObject); //use original indices
     
                //i thought, maybe i can't just bind orginal element array here, but this doesn't make any difference:
                /*glGenBuffers(1, &animationOutputIndexObject);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, animationOutputIndexObject);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, modelStorage[modelId].data.indices.size() * sizeof(short), &modelStorage[modelId].data.indices[0], GL_DYNAMIC_DRAW);*/
     
                //vx, nx, tx
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * attributeStride, BUFFER_OFFSET(0));
                glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * attributeStride, BUFFER_OFFSET(12));
                glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * attributeStride, BUFFER_OFFSET(24));
     
                //bone ids, bone weight
                glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(float) * attributeStride, BUFFER_OFFSET(32));
                glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(float) * attributeStride, BUFFER_OFFSET(44));
     
     
                glEnableVertexAttribArray(0);
                glEnableVertexAttribArray(1);
                glEnableVertexAttribArray(2);
                glEnableVertexAttribArray(3);
                glEnableVertexAttribArray(4);
     
                glBindVertexArray(0);
                glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
            }
    disclamer: some function call order is a consequence of a bit of desperation.

    Drawing to TF:

    Code :
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackObject);
     
            currentShader.applyProgram(15, 0);
            glUniformMatrix4fv(currentShader.uniform_bones, maxNumBones, GL_FALSE, &boneMatrices[0]);
     
            glBindVertexArray(modelStorage[modelId].data.vertexArrayObject); //source VAO
     
            glBeginTransformFeedback(GL_TRIANGLES);
            for(unsigned s = 0, off = 0; s < modelStorage[modelId].data.numSurfaces; s++)
            {
                glDrawElements(GL_TRIANGLES, modelStorage[modelId].data.numIndices[s], GL_UNSIGNED_SHORT, BUFFER_OFFSET(off));
                off += modelStorage[modelId].data.numIndices[s] * sizeof(short);
            }
            glEndTransformFeedback();
     
            glBindVertexArray(0);
            glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

    So... When i draw animationOutputVAO with glDrawElements, i get just a mess of triangles. Any clues on what am i doing wrong? The problem is that couple of examples on TF i found are used for particles and they don't use neither VAO, nor element buffers, so i'm not sure how do i accomplish what i'm trying to do. So i'm resorting to forum and heavy documentation + source code googling.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,216
    Quote Originally Posted by Nowhere-01 View Post
    Hey, it seems, like i don't quite get how does TF interact with VAO's and GL_ELEMENT_ARRAY_BUFFER's.
    Separate TF from the latter two in your mind. TF is just another way to run the graphics pipeline.

    VAOs capture all of the vertex array and element array bindings and enables within the VAO. The ELEMENT_ARRAY_BUFFER binding is one piece of information stored within a VAO. Bind a VAO and all of the bindings and enables stored within it are re-bound and re-enabled.

    Search for the "vertex array object state" table in the OpenGL 4.4 Spec. You'll notice there there are no bindings here related to transform feedback. So basically you don't need your TF object bound while you are initializing your VAO state. It shouldn't make any difference as nothing about it is stored within the VAO.

    The TF object is what captures your TF buffer binding. Search for the "transform feedback state" table in the spec for what's captured within a TF object.
    Last edited by Dark Photon; 12-21-2013 at 03:53 PM.

  3. #3
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    Hey, Dark Photon, thanks for the clarification. That's how i kind of expected things to be.

    I've also forgot to post vertex shader i use for TF. it's going to be a lot bigger, but it outputs garbage even with a passthrough VS:
    Code :
    #version 330
    layout(location=0) in vec3 inVertex;
    layout(location=1) in vec3 inNormal;
    layout(location=2) in vec2 inTexCoord;
     
     
    layout(location=3) in vec3 inBoneIds;
    layout(location=4) in vec3 inBoneWeight;
     
    out vec3 outVertex;
    out vec3 outNormal;
    out vec2 outTexCoord;
     
    out vec3 outBoneIds;
    out vec3 outBoneWeight;
     
    void main() {
        outVertex = inVertex;
        outNormal = inNormal;
        outTexCoord = inTexCoord;
        outBoneIds = inBoneIds;
        outBoneWeight = inBoneWeight;
    }

    i do specify all the TF varyings and program links correctly. also, if i fill output buffer with correct data and disable tranform feedback, it renders correctly. but as soon as i execute drawing with transform feedback, it's filled with garbage.

    upd: if i use glDrawArrays to render TF output, it also draws random garbage.
    Last edited by Nowhere-01; 12-22-2013 at 05:33 AM.

  4. #4
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    fixed it. it turns out i've actually forgot about one of my vertex attributes, ruining output vertex layout. it does work, but the fact that i need to use glDrawArrays is really inconvenient. i would really like to have same drawing code for animated and non-animated objects, only binding different VAO's. - nevermind me being a silly dummy. i was drawing to transform feedback with glDrawElements, so it was, predictably, unfolding indices. if i draw with glDrawArrays, it doesn't happen and i can use pre-setup VAO with original indices to draw results.
    Last edited by Nowhere-01; 12-22-2013 at 11:32 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •