OpenGL Separating Polygons Inside VBO

1.8k views Asked by At

I am trying to use one VBO to draw polygons separated from each other. When i draw the polygons, OpenGL cannot know where to start a new polygon and draws the polygons united.

How can i put a break point on VBO (or IBO) to tell OpenGL to start a fresh polygon.

Sorry it seems a newbie question, i searched for questions and tutorials but couldn't find the answer.

Thank you for your comments:)

I am trying to create a dxf viewer. Dxf files has polygons with solid hatch so i thought that it would be faster to use GL_POLYON rather than tessellation (i might have been wrong here).

My drawing function looks at each object and makes a draw call for every primitive in file. It looks that this type of approach is slow. So i decided to use one vertex array and one buffer for every uniqe type.

For lines, there is no need to know the endings since every line must have 2 vertices. But polygons may have different number of vertices and i should tell opengl where a new polygon begins.

void draw_scene(/*function variables*/){
    Shader::shader_use();

    glEnableClientState(GL_VERTEX_ARRAY);
    unsigned long int i;
    unsigned long int count = objects.size();
    for(i = 0; i < objects.size(); i++){
        glBindVertexArray(objects[i]->vao);
        glDrawArrays(objects[i]->primitive_type, 0, objects[i]->vertice_count);
        glBindVertexArray(0);
    }
    glDisableClientState(GL_VERTEX_ARRAY);
    Shader::shader_close();
}

The above code hasn't been optimised yet. I want to draw the objects with same primitive type in one call. Thought that if could put them in one vertex buffer then i would be able to draw them in one call. So there will be one VAO for each type (points, lines etc).

In fact i don't know if there might be a better solution. Because even if i can put those in one buffer, then it would be hard to modify primitive vertices since they all would have been put in one array. Modifying one vertice would cause all vertices of same type to be re-read.

I also searched to bind multiple vao's at once to not to make too many draw calls. But i couldn't find a method.

Thank you very much for your help:)

1

There are 1 answers

1
Reto Koradi On BEST ANSWER

Part of this was already covered in the comments.

Replacement of GL_POLYGON

The GL_POLYGON primitive type is deprecated, and not available in the OpenGL Core Profile. Fortunately it can easily be replace with GL_TRIANGLE_FAN. GL_TRIANGLE_FAN uses the same vertex order, so you can directly replace GL_POLYGON with GL_TRIANGLE_FAN, without changing anything else.

Only convex polygons can directly be drawn with GL_TRIANGLE_FAN without using any more elaborate triangulation. But the same was true for GL_POLYGON, so that's not a new restriction.

Drawing multiple polygons with a single draw call

There are a couple of approaches:

  1. You can use glMultiDrawArrays(). Where glDrawArrays() takes one start index and one size, glMultiDrawArrays() takes an array of each. So it can be used to replace an arbitrary number of glDrawArrays() calls with a single call.

  2. You can use primitive restart. The downside of this is that you need an index array, which may not have been necessary otherwise. Apart from that, it's straightforward. You enable it with:

    glPrimitiveRestartIndex(0xffff);
    glEnable(GL_PRIMITIVE_RESTART);
    

    You can use any index you want as the restart index, but it's common policy to use the maximum possible index, which is 0xffff if you use indices of type GL_UNSIGNED_SHORT. If you use at least OpenGL 4.3, or OpenGL ES 3.0, you can also replace the above with:

    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    

    Then you set up an index array where you insert a 0xffff value at every position you want to start a new polygon, and bind the index array as usual. Then you can draw all the polygons with a single glDrawElements() call.