3

I have some class for render coordinate axis in pyglet:

class Axis(object):
    def __init__(self,
                 position=(0.0, 0.0, 0.0),
                 x_color=(1.0, 0.0, 0.0),
                 y_color=(0.0, 1.0, 0.0),
                 z_color=(0.0, 0.0, 1.0),
                 length=1.0):

        self.position = list(position)

        self.x_color = map(float, list(x_color))
        self.y_color = map(float, list(y_color))
        self.z_color = map(float, list(z_color))

        self.length = float(length)

        lines = (
            0, 1,
            0, 2,
            0, 3
        )

        vertices = (
            self.position[0], self.position[1], self.position[2],
            self.length, 0.0, 0.0,
            0.0, self.length, 0.0,
            0.0, 0.0, self.length
        )

        colors = (
            self.x_color[0], self.x_color[1], self.x_color[2],
            self.y_color[0], self.y_color[1], self.y_color[2],
            self.z_color[0], self.z_color[1], self.z_color[2]
        )

        self.vertex_list = pyglet.graphics.vertex_list_indexed(
            len(vertices) / 3,
            lines,
            ('v3f', vertices),
            ('c3f', colors),
        )

    def draw(self):
        self.vertex_list.draw(GL_LINES)

When I use this code in my program i get exception:

Traceback (most recent call last):
  File "/home/linch/Project/modelviewer/window.py", line 163, in <module>
    window = ModelViewerWindow()
  File "/home/linch/Project/modelviewer/window.py", line 79, in __init__
    self.axis = Axis()
  File "/home/linch/Project/modelviewer/window.py", line 47, in __init__
    ('c4f', colors),
  File "/usr/local/lib/python2.7/dist-packages/pyglet/graphics/__init__.py", line 301, in vertex_list_indexed
    return _get_default_batch().add_indexed(count, 0, None, indices, *data)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/graphics/__init__.py", line 385, in add_indexed
    vlist._set_attribute_data(i, array)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/graphics/vertexdomain.py", line 413, in _set_attribute_data
    region.array[:] = data
ValueError: Can only assign sequence of same size

If remove ('c3f', colors) everything works, but without color. What am I doing wrong?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Linch
  • 511
  • 4
  • 11

1 Answers1

2

You use 4 vertices, but your color array has only 3 entries. The sizes of those arrays need to match. You need a vertex for each distinct combination of position and color. So to draw 3 lines in 3 different colors, you will need 6 vertices. The fact that 3 of them share the same position doesn't make a difference, because you need vertices with 3 different colors at that position.

Also, if I correctly understand what you're trying to do, the vertex positions look partly wrong. The 2nd, 3rd, and 4th vertex look like they are relative to the 1st vertex, but they all need to be absolute coordinates.

Overall, these arrays should get you what you're looking for:

vertices = (
    self.position[0], self.position[1], self.position[2],
    self.position[0] + self.length, self.position[1], self.position[2],
    self.position[0], self.position[1], self.position[2],
    self.position[0], self.position[1] + self.length, self.position[2],
    self.position[0], self.position[1], self.position[2],
    self.position[0], self.position[1], self.position[2] + self.length
)

colors = (
    self.x_color[0], self.x_color[1], self.x_color[2],
    self.x_color[0], self.x_color[1], self.x_color[2],
    self.y_color[0], self.y_color[1], self.y_color[2],
    self.y_color[0], self.y_color[1], self.y_color[2],
    self.z_color[0], self.z_color[1], self.z_color[2]
    self.z_color[0], self.z_color[1], self.z_color[2]
)

You will also need to adjust the index list accordingly to match the new vertex definitions:

lines = (
    0, 1,
    2, 3,
    4, 5
)

However, since there's no opportunity to share vertices, it's most likely easier to use non-indexed geometry in this case.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Thank for your answer. This work for vertex_list, but not for vertex_list_indexed. – Linch Jun 08 '14 at 18:40
  • There's not much of a point in using indexed geometry in this case, since it's using each vertex only once. I'll amend the answer. – Reto Koradi Jun 08 '14 at 18:56