基础绘画
pyglet提供了pyglet.graphics.draw()函数来向绘图区绘制原始图形物体。pyglet支持的OpenGL图形模式主要有以下这些:
pyglet.gl.GL_POINTS。pyglet.gl.GL_LINES。pyglet.gl.GL_LINE_LOOP。pyglet.gl.GL_LINE_STRIP。pyglet.gl.GL_TRIANGLES。pyglet.gl.GL_TRIANGLES_STRIP。pyglet.gl.GL_TRIABGLES_FAN。pyglet.gl.GL_QUADS。pyglet.gl.GL_QUADS_STRIP。pyglet.gl.GL_POLYGON。
pyglet.graphics.draw(size, mode, *data)函数接受三个参数,第一个参数是一个整型值,用来描述每个形状描述中给定点的数量,第二个参数是要绘制的图形模式,最后一个参数较为复杂,是用于描述组成图形的点的属性的,这将在接下来进行详细描述。另一个可以按照指定索引顺序绘图的函数是pyglet.graphics.draw_indexed(size, mode, indices, *data),它所接受的第三个参数是一个序列,用于指定按照何种顺序使用给定的点的数据。
这里给出一个示例,在后面会对其进行详细解释。
pyglet.graphics.draw(2, pyglet.gl.GL_POINTS,
('v2i', (10, 15, 30, 35),
('c3B', (0, 0, 255, 0, 255, 0))
)
点的描述
点是组成二维图形和三维图形的基本元素,通过描述点的属性,可以定义出二维物体和三维物体。pyglet中对于点的描述是采用一个双元素元组来完成的,其中第一个元素为属性格式字符串,第二个元素为参数元组。
其中常用的属性格式字符串可以按照下表给定的内容进行声明。
| 声明属性 | 可选格式 | 推荐格式 |
|---|---|---|
| 点坐标(Vertex Position) | v[234][sifd] | v[234]f |
| 点颜色(Color) | c[34][bBsSiIfd] | c[34]B |
| 边界标志(Edge flag) | e1[bB] | |
| 法线(Normal) | n3[bsifd] | n3f |
| 第二颜色(Secondary Color) | s[34][bBsSiIfd] | s[34]B |
| 材质坐标(Texture coordinate) | [0-31]?t[234][sifd] | [0-31]?t[234]f |
表中的可选格式和推荐格式都是以正则表达式方式说明其格式的,比如v[234][sifd]可以有v2i、v3f、v4d等表达格式。格式中的字符是用来声明数据类型的,一般情况下常用f(浮点)和B(无符号字节整型)。
现在来回顾一下前面的示例。('v2i', (10, 15, 30, 35)表示其后的参数元组定义的是使用整型数值坐标描述的二维点,即点\((10, 15)\)和点\((30, 35)\)。而('c3B', (0, 0, 255, 0, 255, 0))表示前面定义的这两个点的颜色,第一个点的颜色是rgb(0, 0, 255)(蓝色),第二个点的颜色是rgb(0, 255, 0)(绿色)。
读者可以以此类推来试验其他的图形定义。
点列表
每次绘制都列举点的定义是一件很麻烦的事情,而且一般图形发生变化时,并不需要对图形中的点完全重新定义。这种需求可以使用点列表来满足。
点列表可以使用pyglet.graphics.vertex_list(size, *data)来定义,其接受的参数与pyglet.graphics.draw(size, mode, *data)类似,只是不需要声明图形模式。点列表可以直接使用.draw(mode)方法绘制输出。例如之前的示例可以改写为以下形式。
vertex_list = pyglet.graphics.vertex_list(2,
('v2i', (10, 15, 30, 35),
('c3B', (0, 0, 255, 0, 255, 0))
)
vertex_list.draw(pyglet.gl.GL_POINTS)
点列表在创建之后并不熟一成不变的,而是可以通过以下属性(均为列表类型)进行修改的。
.vertices,点坐标位置。.colors,点颜色。.edge_flags,边界标识。.normals,法线。.secondary_colors,第二眼色。.tex_coords,材质坐标。
点列表的上述属性都是可以使用列表进行重新赋值的,并且还可以使用vertex_list.vertices[:3]=[45, 60]的切片语法进行局部更新。
批量渲染
从优化OpenGL性能的角度来说,在一次draw()调用中应该绘制尽可能多的点列表。为了能够便捷的将点列表收集在一起进行控制,pyglet提供了Batch类。Batch类实例的创建不需要任何参数,直接使用pyglet.graphics.Batch()即可。
Batch类实例通过add()和add_indexed()函数来创建点列表,使用这两个函数来创建点列表时,需要指定点列表的绘制模式,就像是调用draw()函数一样。Batch类实例也提供了.draw()方法来将批量创建的点列表一次性绘制出来。