基础绘画

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]可以有v2iv3fv4d等表达格式。格式中的字符是用来声明数据类型的,一般情况下常用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()方法来将批量创建的点列表一次性绘制出来。