Frage

I cannot figure out how to use an Indexed VBO, IMHO there's a lack of information about it (for example the lwjgl site in which the indexed vbo page is missing ATM).

The structure i'm using in my vertex buffer is {pos.x, pos.y pos.z}, {tex.u, tex.v tex.W} and {norm.x, norm.y norm.z}, my index buffer structure is {posIndex, texIndex, normIndex} I'm reading all this data from an .obj file, if tex or norm is missing i set it to{-1,-1,-1}.

Here's the code part in which i send data to the GPUs buffers:

    this.VBOSize = Vertices.size();
    FloatBuffer vbo = BufferUtils.createFloatBuffer(this.VBOSize);
    for (int i = 0; i < this.VBOSize; i++) {
        vbo.put(Vertices.get(i));
    }
    vbo.flip();
    glBindBuffer(GL_ARRAY_BUFFER, VBOHandle);
    glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW);

    this.IBOSize = Indices.size();
    IntBuffer ibo = BufferUtils.createIntBuffer(this.IBOSize);
    for (int i = 0; i < this.IBOSize; i++) {
        ibo.put(Indices.get(i));
    }
    ibo.flip();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOHandle);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

and here's how i [incorrectly] render it:

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, Object3D.getVBOHandle());
    glVertexAttribPointer(0, 3, GL_FLOAT, true, 12, 0);//3 floats * 4 sizeof(float)
    glVertexAttribPointer(1, 3, GL_FLOAT, true, 12, 13);
    glVertexAttribPointer(2, 3, GL_FLOAT, true, 12, 25);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Object3D.getIBOHandle());
    glDrawElements(GL_TRIANGLES, Object3D.getIBOSize(), GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
War es hilfreich?

Lösung

THis is not how opengl works. In openGL, a vertex is a set of attributes like position, normal, color, textcoord, whatever. Indexed rendering just references vertices. You cannot have different indices for the various attributes, but just one index for the whole set. If you have the situation where two vertices share their position, but, not the texcoords, they are entirely _different_ vertices, as far as the GL is concerned. You cannot directly use the data from lightwave .obj files but have to preprocess the data to generate the vertex arrays OpenGL can work this.

There is the GL_AMD_interleaved_elements extension which somewhat implements the feature you want to use. It still uses 32-Bit indices, but allowes one to split them into 2 16-Bit or 4 8-Bit indices to use different indices for different attributes, but this extension is far from being in core GL, isn't widely supported and is still very limited.

Nowadays with the programmable pipeline, one could also do the index dereferencing manually in the shaders, basically (mis)using the vertex attributes and accessing the real attribute arrays via a texture buffer object, but that is quite advanced and the performance implications are not clear.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top