Getting data from multiple vertex data

Started by
13 comments, last by Maxjen 11 years, 3 months ago

Wow, so many replies! Thanks!

To clarify what I want to do: The Triangle class will be used only for the ground. For other type of objects I will make seperate classes. And I want to perform the most basic actions on the vertices like move, rotate, scale.(like in blender) This is inspired by the game soldat. This is an example of a map in soldat.

How the drawing is done: In two passes. Somewhere in my main loop I call triangles->draw() and later selection->draw(). The Triangle class manages the vertex buffer for the triangles. It has functions to add/remove triangles and if the buffer is full it automatically creates a new buffer with twice the size and copies the data. The buffer has this structure:



struct Vertex {
    float x, y;      // position
    float u, v;      // texturecoords
    char r, g, b, a; // color
};

The Triangle class also has the index buffer for drawing the triangles.

This is the draw function for the triangles:


void Triangles::draw() {
    glUseProgram(shaderProgram);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
    // vertex
    glVertexAttribPointer(vertexPositionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    // texCoord
    glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(2 * sizeof(float)));
    // color
    glVertexAttribPointer(vertexColorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (GLvoid*)(4 * sizeof(float)));
    glEnableVertexAttribArray(vertexPositionLocation);
    glEnableVertexAttribArray(texCoordLocation);
    glEnableVertexAttribArray(vertexColorLocation);
	
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);

    glEnable(GL_TEXTURE_2D);
    for(int i = 0; i < triangleCount; ++i) {
        if(trianglesData[i].isUsed) {
            glBindTexture(GL_TEXTURE_2D, trianglesData[i].texture->id);
            glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (GLvoid*)(sizeof(Triangle)*i));
        }
    }
    glDisable(GL_TEXTURE_2D);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableVertexAttribArray(vertexColorLocation);
    glDisableVertexAttribArray(texCoordLocation);
    glDisableVertexAttribArray(vertexPositionLocation);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glUseProgram(0);
}

I will also replace the for loop in the future and instead use the spatial tree from Box2D to draw only currently visible triangles.

Now the problem is the draw method of the selection class. Currently I already render white points for the vertices and I reuse the vertex buffer from the Triangle class with a new index buffer. I want to do the same for the edges, however I need additional information. For every edge where at least one vertex is selected I need two booleans to know how to draw the line. e.g. if only one vertex is selected then the line should fade from full white to transparent. I think this information doesn't belong into the Triangle class because I might e.g. use the Triangle class later in the game itself where I don't need selections. So instead I want to create a new buffer with the booleans. What I don't know is how to use them both at once. e.g. can I even do something like this:



glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId);
glVertexAttribPointer(vertexPositionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
glBindBuffer(GL_ARRAY_BUFFER, selectionVertexBufferId);
glVertexAttribPointer(vertexSelectionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Selection), 0);
...
glDrawElements(GL_LINES, ...);

Wouldn't the result be that only the second buffer is bound when I draw the lines? But I need both.

Advertisement

No help? Basically I only want to do what was already suggested I just don't know exactly how to do it in openGL.

For sure, a clean way under the condition of not replicating data would be to use 3 VBOs (1 with the data shared between face and line drawing, 1 with the data used for face drawing only, and 1 with the data used for line drawing only), and 2 IBOs (1 for face drawing and 1 for line drawing).

I want 2 VBOs but how? If I bind one buffer and then the next will the first buffer not be unbound? Or is it enough to bind the buffer, set the vertex attrib pointers and then unbind it again before the draw call?

I want 2 VBOs but how? If I bind one buffer and then the next will the first buffer not be unbound? Or is it enough to bind the buffer, set the vertex attrib pointers and then unbind it again before the draw call?

Bind a VBO and set a pointer, then bind another VBO and set another pointer. Yes, the second binding will unbind the first one, but a vertex attribute pointer depends on the VBO binding when the pointer is set, not when the arrays are drawn.

I want 2 VBOs but how? If I bind one buffer and then the next will the first buffer not be unbound? Or is it enough to bind the buffer, set the vertex attrib pointers and then unbind it again before the draw call?
There is perhaps still a misunderstanding. The vertex positions are the same for the faces, edges, and point handles. You need only 1 VBO with the position, and that is the VBO I've mentioned as "shared". However, you need to transport the edge color as well, and that attribute is unique to edge rendering. Hence create another VBO for the edge color (but notice that it is still given for each vertex; but that isn't a problem with your kind of coloring the edges).

Then do as follows (schematic):
1. bind (shared) VBO with positions
2. set attribute pointer for positions
3. bind VBO with colors
4. set attribute pointer for colors
5. bind index buffer for edges
6. draw edges
7. clean up

If the shared VBO contains colors, too, because you deal with it in face rendering ... it doesn't matter, because you ignore it (i.e. you don't use it with the attribute pointer setting) during edge rendering.

[quote name='Brother Bob' timestamp='1357223653' post='5017111']
Bind a VBO and set a pointer, then bind another VBO and set another pointer. Yes, the second binding will unbind the first one, but a vertex attribute pointer depends on the VBO binding when the pointer is set, not when the arrays are drawn.
[/quote]

Thank you very much, that is all I needed to know!

[quote name='haegarr' timestamp='1357224003' post='5017115']
There is perhaps still a misunderstanding. The vertex positions are the same for the faces, edges, and point handles. You need only 1 VBO with the position, and that is the VBO I've mentioned as "shared". However, you need to transport the edge color as well, and that attribute is unique to edge rendering. Hence create another VBO for the edge color (but notice that it is still given for each vertex; but that isn't a problem with your kind of coloring the edges).
[/quote]

There is no misunderstanding but thanks! What you described is exactly how I was going to do it. There was only the technical problem of how to use more than one vertex buffer.rolleyes.gif

This topic is closed to new replies.

Advertisement