@@ -26,19 +26,20 @@ class VAOError(Exception):
2626
2727class BufferInfo :
2828 """Container for a vbo with additional information"""
29- def __init__ (self , buffer : mgl .Buffer , buffer_format : str , attributes = None ):
29+ def __init__ (self , buffer : mgl .Buffer , buffer_format : str , attributes = None , per_instance = False ):
3030 """
3131 :param buffer: The vbo object
3232 :param format: The format of the buffer
3333 """
3434 self .buffer = buffer
3535 self .attrib_formats = types .parse_attribute_formats (buffer_format )
3636 self .attributes = attributes
37+ self .per_instance = per_instance
3738
3839 # Sanity check byte size
3940 if self .buffer .size % self .vertex_size != 0 :
40- raise VAOError ("Buffer with type {} has size not aligning with {}. Remainder: " .format (
41- buffer_format , self .vertex_size , self .buffer .size % self .vertex_size ,
41+ raise VAOError ("Buffer with type {} has size not aligning with {}. Remainder: {} " .format (
42+ buffer_format , self .vertex_size , self .buffer .size % self .vertex_size
4243 ))
4344
4445 self .vertices = self .buffer .size // self .vertex_size
@@ -61,12 +62,12 @@ def content(self, attributes: List[str]):
6162
6263 attributes .remove (attrib )
6364
64- if len ( attrs ) == 0 :
65+ if not attrs :
6566 return None
6667
6768 return (
6869 self .buffer ,
69- " " .join (formats ),
70+ "{}{}" . format ( " " .join (formats ), '/i' if self . per_instance else '' ),
7071 * attrs
7172 )
7273
@@ -98,21 +99,24 @@ def __init__(self, name, mode=mgl.TRIANGLES):
9899 self .vertex_count = 0
99100 self .vaos = {}
100101
101- def draw (self , shader : ShaderProgram , mode = None ):
102+ def draw (self , shader : ShaderProgram , mode = None , vertices = - 1 , first = 0 , instances = 1 ):
102103 """
103104 Draw the VAO.
104105 Will use ``glDrawElements`` if an element buffer is present
105106 and ``glDrawArrays`` if no element array is present.
106107
107108 :param shader: The shader to draw with
108109 :param mode: Override the draw mode (GL_TRIANGLES etc)
110+ :param vertices: The number of vertices to transform
111+ :param first: The index of the first vertex to start with
112+ :param instances: The number of instances
109113 """
110114 vao = self ._create_vao_instance (shader )
111115
112116 if mode is None :
113117 mode = self .mode
114118
115- vao .render (mode )
119+ vao .render (mode , vertices = vertices , first = first , instances = instances )
116120
117121 def transform (self , shader , buffer : mgl .Buffer , mode = None , vertices = - 1 , first = 0 , instances = 1 ):
118122 """
@@ -132,14 +136,18 @@ def transform(self, shader, buffer: mgl.Buffer, mode=None, vertices=-1, first=0,
132136
133137 vao .transform (buffer , mode = mode , vertices = vertices , first = first , instances = instances )
134138
135- def buffer (self , buffer , buffer_format : str , attribute_names ):
139+ def buffer (self , buffer , buffer_format : str , attribute_names , per_instance = False ):
136140 """
137141 Register a buffer/vbo for the VAO. This can be called multiple times.
138142 adding multiple buffers (interleaved or not)
139143
140144 :param buffer: The buffer object. Can be ndarray or Buffer
141145 :param buffer_format: The format of the buffer ('f', 'u', 'i')
146+ :returns: The buffer object
142147 """
148+ if not isinstance (attribute_names , list ):
149+ attribute_names = [attribute_names , ]
150+
143151 if not isinstance (buffer , mgl .Buffer ) and not isinstance (buffer , numpy .ndarray ):
144152 raise VAOError ("buffer parameter must be a moderngl.Buffer or numpy.ndarray instance" )
145153
@@ -150,9 +158,11 @@ def buffer(self, buffer, buffer_format: str, attribute_names):
150158 if len (formats ) != len (attribute_names ):
151159 raise VAOError ("Format '{}' does not describe attributes {}" .format (buffer_format , attribute_names ))
152160
153- self .buffers .append (BufferInfo (buffer , buffer_format , attribute_names ))
161+ self .buffers .append (BufferInfo (buffer , buffer_format , attribute_names , per_instance = per_instance ))
154162 self .vertex_count = self .buffers [- 1 ].vertices
155163
164+ return buffer
165+
156166 def index_buffer (self , buffer , index_element_size = 4 ):
157167 """
158168 Set the index buffer for this VAO
@@ -198,7 +208,7 @@ def _create_vao_instance(self, shader):
198208 vao_content .append (content )
199209
200210 if len (attributes ) > 0 :
201- raise VAOError ("Did not find a buffer mapping for {}" .format ([n . name for n in attributes ]))
211+ raise VAOError ("Did not find a buffer mapping for {}" .format ([n for n in attributes ]))
202212
203213 if self ._index_buffer :
204214 vao = context .ctx ().vertex_array (shader .program , vao_content ,
0 commit comments