I’ve sort of stagnated on pushing this limit. I got up to 160,000 pairs of triangles at 10 fps.
This is a helper class for storing the GeomVertexData and NodePath objects.
class VerticesWrap:
def __init__( self ):
geomformat = GeomVertexFormat.getV3c4t2( )
self.vdata = GeomVertexData( 'blank', geomformat, Geom.UHStatic )
self.vertex = GeomVertexWriter( self.vdata, 'vertex')
self.color = GeomVertexWriter( self.vdata, 'color')
self.texcoord = GeomVertexWriter( self.vdata, 'texcoord')
self.prim = GeomTriangles( Geom.UHStatic )
self.count = 0
geom = Geom(self.vdata)
geom.addPrimitive(self.prim)
node = GeomNode('gnode')
node.addGeom(geom)
self.gpath = NodePath(node)
self.gpath.reparentTo( render )
def add_square( self, tl, br = None ):
if br is None:
br = tl[ 0 ] + 1, tl[ 1 ] + 1 # default size: 1, 1
vertex, color, texcoord= self.vertex, self.color, self.texcoord
prim= self.prim
vertex.addData3f( tl[ 0 ], 0, tl[ 1 ] )
color.addData4f(1, 1, 1, 1)
texcoord.addData2f(0, 0)
vertex.addData3f( br[ 0 ], 0, tl[ 1 ] )
color.addData4f(1, 1, 1, 1)
texcoord.addData2f(1, 0)
vertex.addData3f( br[ 0 ], 0, br[ 1 ] )
color.addData4f(1, 1, 1, 1)
texcoord.addData2f(1, 1)
vertex.addData3f( tl[ 0 ], 0, br[ 1 ] )
color.addData4f(1, 1, 1, 1)
texcoord.addData2f(0, 1)
index = self.count * 4
prim.addVertices( index+ 0, index+ 1, index+ 3 )
prim.closePrimitive()
prim.addVertices( index+ 1, index+ 2, index+ 3 )
prim.closePrimitive()
self.count+= 1
I create arrays of 40 of each, then fill them. NotG is ‘not’ in disguise, so as to not conflict with the language’s keywords.
xorwraps= [ VerticesWrap( ) for _ in range( 40 ) ]
for xorwrap in xorwraps:
xorwrap.gpath.setTexture( xortext )
xorwrap= xorwraps[ 0 ]
nandwraps= [ VerticesWrap( ) for _ in range( 40 ) ]
for nandwrap in nandwraps:
nandwrap.gpath.setTexture( nandtext )
nandwrap= nandwraps[ 0 ]
notgwraps= [ VerticesWrap( ) for _ in range( 40 ) ]
for notgwrap in notgwraps:
notgwrap.gpath.setTexture( notgtext )
notgwrap= notgwraps[ 0 ]
wraps= [ xorwraps, nandwraps, notgwraps ]
for i in range( 160000 ):
x, y= i % 400, i / 400
wrap= wraps[ i% len( wraps ) ]
j= 0
while wrap[ j ].count>= 1500:
j+= 1
wrap[ j ].add_square( ( x, y ), ( x+ .8, y+ .8 ) )
I’d like to know where these cutoffs occur. I understand that each VerticesWrap instance is a separate batch. I would really like to max out the GPU, so how big is a batch, and how many batches can I have? Or where do the CPU or bus start to be the bottleneck agent? When should I use UHDynamic instead of UHStatic for my flags?
The other attributes of the instances become invalid after the first frame; they should be deleted.
Here’s the toggleFlood function, which changes colors of the index in each of the 3 wraps at index N in their respective arrays.
def toggleFlood(self,indx):
self.col= 1- self.col
for vdata in xorwrap.vdata, nandwrap.vdata, notgwrap.vdata:
color = GeomVertexWriter( vdata, 'color')
color.setRow( 4*indx )
for _ in range( 4 ):
if self.col== 0:
color.setData4f( 1, .776, 0, 1 )
else:
color.setData4f( 0, .620, 1, 1 )
Each square begins at 4 x its index, since it takes up 4 vertices and thus 4 entries. The ‘setData’ function advances the row pointer, so just call it 4 times after finding the index. Then do that for each of the lists of VertexWraps, and each call will toggle the first ‘indx’ instances in the scene.
The application is kind of specialized: many instances of a small number of rasters with live color changes. It would be nice to examine what existing encapsulations could accomplish this.