简体   繁体   English

Pyglet绘制具有颜色的基元

[英]Pyglet drawing Primitives with color

I am creating a cellular automata with a grid, but when I try to give the cell a color I get an error. 我正在创建一个带有网格的细胞自动机,但是当我尝试给该细胞一个颜色时,我得到了一个错误。 If i remove the "('c3B', (255,0,0))" everything works. 如果我删除"('c3B', (255,0,0))"一切正常。

def on_draw(self):
    self.clear()
    self.predatorAndPrey.draw()

And here is the function: 这是功能:

    def draw(self):
    for row in range(0, self.grid_height):
        for col in range(0, self.grid_width):
            square_cords = (
                row * self.cell_size, col * self.cell_size,
                row * self.cell_size, col * self.cell_size + self.cell_size,
                row * self.cell_size + self.cell_size, col * self.cell_size + self.cell_size,
                row * self.cell_size + self.cell_size, col * self.cell_size
            )
            if self.cells[row][col][0] == 1:

                pyglet.graphics.draw_indexed(4, pyglet.gl.GL_QUADS,
                                             [0,1,2,3],
                                             ('v2i', square_cords),
                                             ('c3B', (255,0,0))
                                             )

Here is the Error: 这是错误:

File "E:/Python/Cellular Automata/Predator and Prey/Cellular Automata.py", line 23, in on_draw
    self.predatorAndPrey.draw()
  File "E:\Python\Cellular Automata\Predator and Prey\predator_and_prey.py", line 39, in draw
    ('c3B', (255,0,0))
  File "E:\Python\Cellular Automata\venv\lib\site-packages\pyglet\graphics\__init__.py", line 230, in draw_indexed
    'Data for %s is incorrect length' % format
AssertionError: Data for c3B is incorrect length

I have never used the Pyglet but have you tried to just add a last 0 for alpha: (255,0,0,0)? 我从未使用过Pyglet,但您是否尝试过为alpha添加最后一个0:(255,0,0,0)? Reading the documentation it looks like it is needed. 阅读文档似乎很必要。

Since my comment apparently made sense, here's a detailed explanation of why it works, with a example of how to use it properly. 由于我的评论显然是有道理的,因此这里有一个解释为什么起作用的详细说明,并举例说明了如何正确使用它。

The function draw_indexed() is a way to draw primitives in a indexed ordered. 函数draw_indexed()是一种以索引顺序绘制基元的方法。 A primitive can be anything supported under the pyglet.gl context, in this case GL_QUADS . pyglet.gl上下文中可以支持任何原语,在本例中为GL_QUADS The GL_QUAD object requires at least one thing, and that's the cordinates of all the primitives four corners. GL_QUAD对象至少需要一件事情,那就是所有图元的四个角的GL_QUAD You supply them in square_cords , and they come in pairs of two (X,Y) * 4 corners (total of 8 items). 您以square_cords提供它们,它们成对成两个(X,Y) * 4角(总共8个项目)。

Optionally, you can supply color information to the GL_QUAD object. (可选)您可以将颜色信息提供给GL_QUAD对象。 This instructs the rendering process what color each corner should be mapped against. 这指示渲染过程应映射每个角的颜色。 In your case, you've chosen to send along the color information. 在您的情况下,您已选择发送颜色信息。

All this is based on two things: v2i meaning vertext information, 2 components per vertex (meaning 2D space) and the data supplied is of type i (integer). 所有这一切基于两件事: v2i表示vertext信息,每个顶点2组件(表示2D空间),提供的数据类型为i (整数)。

The color follows a similar meaning/definition. 颜色遵循类似的含义/定义。 where c3B means c for color, 3 means 3 items per data blob (RGB in this case) and is of type B (unsigned int). 其中c3B表示颜色的c3表示每个数据blob(在这种情况下为RGB)3个项目,类型B (无符号int)。 But the color is "tricky" , since it is heavily tied together to the number of vertex definitions earlier in v2i . 但是颜色是“稀疏的” ,因为它与v2i早期的顶点定义数目紧密地联系在一起。 Meaning the color is tied to each pair (corner) in your QUAD. 这意味着颜色与QUAD中的每一对(角)相关。 If it was a line, it would be tied to start and end of the line. 如果是一行,它将与行的开头和结尾相关联。 And in a dot, it would be a single color definition since a dot only has one element of (x,y) to it. 在一个点中,这将是一个单一的颜色定义,因为一个点只有一个元素(x,y) But it's always tied to the number of definitions expected in the primitive - so again - your quad has 4 definitions/corners - so you'll need 4 color pairs. 但这总是与基元中预期的定义数量相关联-同样,您的四边形有4个定义/角-因此您将需要4个颜色对。

So you will need to multiply your color definition (255, 0, 0) as many times as you have corners. 因此,您需要将颜色定义(255, 0, 0)乘以有角的次数。 (255, 0, 0) because you used 3B . (255, 0, 0)因为您使用了3B And you have 4 corners , so (255, 0, 0) * 4 . 并且您有4个角 ,所以(255, 0, 0) * 4 The easiest way to achieve this - would be to do (255,0,0) * int(len(square_cords)/2) . 实现此目的的最简单方法是(255,0,0) * int(len(square_cords)/2) The /2 is because there's 2 pairs per corner in square_cords (x,y) - but you only want to count the amount of corners not positions. /2是因为square_cords (x,y)中每个角有2对-但是您只想计算角的数量而不是位置。 I hope that makes sense. 我希望这是有道理的。

So, as a practical example, here's a piece of code illustrating how this ties together and hopefully this will have taught you something about vertexes, color and how the GL_*** context expects certain things to be/behave. 因此,作为一个实际的示例,这是一段代码,说明如何将它们联系在一起,并希望这将教给您一些有关顶点,颜色以及GL_***上下文如何期望某些行为的知识。 Best of luck to you. 祝你好运。

from pyglet import *
from pyglet.gl import *

key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
        super(main, self).__init__(width, height, *args, **kwargs)
        self.x, self.y = 0, 0

        self.keys = {}

        self.mouse_x = 0
        self.mouse_y = 0

        self.cell_size = 20

        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_mouse_motion(self, x, y, dx, dy):
        self.mouse_x = x

    def on_key_release(self, symbol, modifiers):
        try:
            del self.keys[symbol]
        except:
            pass

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE: # [ESC]
            self.alive = 0

        self.keys[symbol] = True

    def render(self):
        self.clear()

        square_cords = (
            self.cell_size, self.cell_size,
            self.cell_size, self.cell_size + self.cell_size,
            self.cell_size + self.cell_size, self.cell_size + self.cell_size,
            self.cell_size + self.cell_size, self.cell_size
        )

        color_pairs = (255,0,0) * int(len(square_cords)/2)

        pyglet.graphics.draw_indexed(4, pyglet.gl.GL_QUADS,
                                        [0,1,2,3],
                                        ('v2i', square_cords),
                                        ('c3B', color_pairs)
        )

        self.flip()

    def run(self):
        while self.alive == 1:
            self.render()

            # -----------> This is key <----------
            # This is what replaces pyglet.app.run()
            # but is required for the GUI to not freeze
            #
            event = self.dispatch_events()

if __name__ == '__main__':
    x = main()
    x.run()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM