Search code examples
pythonopenglpyglet

Drawing GL_LINE_STRIP using Pyglet in a Batch


I'm trying to draw two GL_LINE_STRIP objects, but they become connected to eachother.

Pyglet documentation says:

When using GL_LINE_STRIP, GL_TRIANGLE_STRIP or GL_QUAD_STRIP care must be taken to insert degenerate vertices at the beginning and end of each vertex list. For example, given the vertex list:

A, B, C, D

the correct vertex list to provide the vertex list is:

A, A, B, C, D, D

But it has absolutely no effect whether I add it or not.

Here is a code sample:

import pyglet

window = pyglet.window.Window()

main_batch = pyglet.graphics.Batch()

p1 = [ 300, 400, 300, 400, 162, 408, 303, 453, 300, 400, 300, 400]
p2 = [ 500, 400, 500, 400, 558, 315, 586, 372, 500, 400, 500, 400]

main_batch.add(len(p1) // 2, pyglet.gl.GL_LINE_STRIP, None, ("v2i", p1))
main_batch.add(len(p2) // 2, pyglet.gl.GL_LINE_STRIP, None, ("v2i", p2))

@window.event
def on_draw():
    window.clear()
    main_batch.draw()

pyglet.app.run()

The result

What can I do to separate these objects? Using different batches or GL_LINES is not an option.


Solution

  • You have to group the vertex lists:

    import pyglet
    
    window = pyglet.window.Window()
    
    main_batch = pyglet.graphics.Batch()
    
    grp1 = pyglet.graphics.Group()
    grp2 = pyglet.graphics.Group()
    
    p1 = [ 300, 400, 300, 400, 162, 408, 303, 453, 300, 400, 300, 400]
    p2 = [ 500, 400, 500, 400, 558, 315, 586, 372, 500, 400, 500, 400]
    
    main_batch.add(len(p1) // 2, pyglet.gl.GL_LINE_STRIP, grp1, ("v2i", p1))
    main_batch.add(len(p2) // 2, pyglet.gl.GL_LINE_STRIP, grp2, ("v2i", p2))
    
    @window.event
    def on_draw():
        window.clear()
        main_batch.draw()
    
    pyglet.app.run()
    

    Vertices in 1 group are treated to be one single list of vertices. See pyglet.graphics, thus vertex lists can be add to different group. Each group is a separated mesh.


    In my opinion the documentation is wrong. The approach will work for GL_TRIANGLE_STRIP or GL_QUAD_STRIP, because this primitive types draw a filled polygon. If the area of a (part of the) polygon is 0, then nothing is drawn at all.
    The line primitive GL_LINE_STRIP will always draw a line between to consecutive vertices.
    See OpenGL Primitive.

    For instance GL_TRIANGLE_STRIP:

    p1 = [ 300, 400, 300, 400, 162, 408, 303, 453, 300, 400, 300, 400]
    p2 = [ 500, 400, 500, 400, 558, 315, 586, 372, 500, 400, 500, 400]
    
    main_batch.add(len(p1) // 2, pyglet.gl.GL_TRIANGLE_STRIP, None, ("v2i", p1))
    main_batch.add(len(p2) // 2, pyglet.gl.GL_TRIANGLE_STRIP, None, ("v2i", p2))