Mesh: fix and document Mesh instruction + add an example. Closes #64

This commit is contained in:
Mathieu Virbel 2011-11-25 16:35:33 +01:00
parent c31995b2ff
commit dde62fe43e
4 changed files with 111 additions and 5 deletions

52
examples/canvas/mesh.py Normal file
View File

@ -0,0 +1,52 @@
'''
Mesh test
=========
'''
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.graphics import Mesh
from functools import partial
from math import cos, sin, pi
class MeshTestApp(App):
def change_mode(self, mode, *largs):
self.mesh.mode = mode
def build_mesh(self):
vertices = []
indices = []
step = 10
istep = (pi * 2) / float(step)
for i in xrange(step):
x = 300 + cos(istep * i) * 100
y = 300 + sin(istep * i) * 100
vertices.extend([x, y, 0, 0])
indices.append(i)
return Mesh(vertices=vertices, indices=indices)
def build(self):
wid = Widget()
with wid.canvas:
self.mesh = self.build_mesh()
layout = BoxLayout(size_hint=(1, None), height=50)
for mode in ('points', 'line_strip', 'line_loop', 'lines',
'triangle_strip', 'triangle_fan'):
button = Button(text=mode)
button.bind(on_release=partial(self.change_mode, mode))
layout.add_widget(button)
root = BoxLayout(orientation='vertical')
root.add_widget(wid)
root.add_widget(layout)
return root
if __name__ == '__main__':
MeshTestApp().run()

View File

@ -29,6 +29,7 @@ cdef class VertexBatch:
cdef Buffer elements
cdef Buffer vbo_index
cdef GLuint mode
cdef str mode_str
cdef void clear_data(self)
cdef void set_data(self, vertex_t *vertices, int vertices_count,
@ -37,4 +38,5 @@ cdef class VertexBatch:
unsigned short *indices, int indices_count)
cdef void draw(self)
cdef void set_mode(self, str mode)
cdef str get_mode(self)
cdef int count(self)

View File

@ -160,6 +160,7 @@ cdef class VertexBatch:
cdef void set_mode(self, str mode):
# most common case in top;
self.mode_str = mode
if mode is None:
self.mode = GL_TRIANGLES
elif mode == 'points':
@ -177,6 +178,9 @@ cdef class VertexBatch:
else:
self.mode = GL_TRIANGLES
cdef str get_mode(self):
return self.mode_str
cdef int count(self):
return self.elements.count()

View File

@ -357,11 +357,35 @@ cdef class Bezier(VertexInstruction):
cdef class Mesh(VertexInstruction):
'''A 2d mesh.
The format of vertices are actually fixed, this might change in a future
release. Right now, each vertex is described with 2D coordinates (x, y) and
a 2D texture coordinate (u, v).
In OpenGL ES 2.0 and in our graphics implementation, you cannot have more
than 65535 indices.
A list of vertices is described as::
vertices = [x1, y1, u1, v1, x2, y2, u2, v2, ...]
| | | |
+---- i1 ----+ +---- i2 ----+
If you want to draw a triangles, put 3 vertices, then you can make an
indices list as:
indices = [0, 1, 2]
.. versionadded:: 1.0.10
:Parameters:
`vertices`: list
List of points in the format (x1, y1, x2, y2...)
List of vertices in the format (x1, y1, u1, v1, x2, y2, u2, v2...)
`indices`: list
List of indices in the format (i1, i2, i3...)
`mode`: str
Mode of the vbo. Check :data:`mode` for more information. Default to
'points'.
'''
cdef list _vertices
cdef list _indices
@ -370,21 +394,25 @@ cdef class Mesh(VertexInstruction):
VertexInstruction.__init__(self, **kwargs)
self.vertices = kwargs.get('vertices', [])
self.indices = kwargs.get('indices', [])
self.batch.set_mode('points')
self.mode = kwargs.get('mode', 'points')
cdef void build(self):
cdef int i, vcount = len(self._vertices) / 2
cdef int i, vcount = len(self._vertices) / 4
cdef int icount = len(self._indices)
cdef vertex_t *vertices = NULL
cdef int *indices = NULL
cdef unsigned short *indices = NULL
cdef list lvertices = self._vertices
cdef list lindices = self._indices
if vcount == 0 or icount == 0:
self.batch.clear_data()
return
vertices = <vertex_t *>malloc(vcount * sizeof(vertex_t))
if vertices == NULL:
raise MemoryError('vertices')
indices = <int *>malloc(icount * sizeof(int))
indices = <unsigned short *>malloc(icount * sizeof(unsigned short))
if indices == NULL:
free(vertices)
raise MemoryError('indices')
@ -404,6 +432,10 @@ cdef class Mesh(VertexInstruction):
free(indices)
property vertices:
'''List of x, y, u, v, ... used to construct the Mesh. Right now, the
Mesh instruction doesn't allow you to change the format of the vertices,
mean it's only x/y + one texture coordinate.
'''
def __get__(self):
return self._vertices
def __set__(self, value):
@ -411,12 +443,28 @@ cdef class Mesh(VertexInstruction):
self.flag_update()
property indices:
'''Vertex indices used to know which order you wanna do for drawing the
mesh.
'''
def __get__(self):
return self._indices
def __set__(self, value):
if len(value) > 65535:
raise GraphicException(
'Cannot upload more than 65535 indices'
'(OpenGL ES 2 limitation)')
self._indices = list(value)
self.flag_update()
property mode:
'''VBO Mode used for drawing vertices/indices. Can be one of: 'points',
'line_strip', 'line_loop', 'lines', 'triangle_strip', 'triangle_fan'
'''
def __get__(self):
self.batch.get_mode()
def __set__(self, mode):
self.batch.set_mode(mode)
cdef class Point(VertexInstruction):