Here’s some quick and dirty code showing how to do that in Panda. I may clean up the code a bit when I have time.
from random import random
from panda3d.core import *
loadPrcFileData("init-ms-meter", """
show-frame-rate-meter true
frame-rate-meter-milliseconds true
frame-rate-meter-ms-text-pattern %0.2f ms
""")
from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor
NUM_INSTANCES = 3600
vshad = """#version 330
uniform mat4 p3d_ModelViewProjectionMatrix;
in vec4 vertex;
in vec2 texcoord;
//in mat4 transform;
in vec4 offset;
out vec2 tcset;
void main() {
gl_Position = p3d_ModelViewProjectionMatrix * (vertex + offset);
tcset = texcoord;
}"""
fshad = """#version 330
uniform sampler2D p3d_Texture0;
out vec4 p3d_FragColor;
in vec2 tcset;
void main() {
p3d_FragColor = texture(p3d_Texture0, tcset);
}
"""
base = ShowBase()
node = Actor('panda-model', {'walk' : 'panda-walk4'})
node.loop('walk')
node.setScale(0.01)
shader = Shader.make(Shader.SL_GLSL, vshad, fshad)
node.setShader(shader)
node.reparentTo(render)
gnode = node.find("**/+GeomNode").node()
iformat = GeomVertexArrayFormat()
iformat.setDivisor(1)
iformat.addColumn("offset", 4, Geom.NT_stdfloat, Geom.C_other)
format = GeomVertexFormat(gnode.getGeom(0).getVertexData().getFormat())
format.addArray(iformat)
format = GeomVertexFormat.registerFormat(format)
vdata = gnode.modifyGeom(0).modifyVertexData()
vdata.setFormat(format)
poswriter = GeomVertexWriter(vdata.modifyArray(2), 0)
for i in range(NUM_INSTANCES):
poswriter.add_data3((i % 60) * 700 + random() * 100, (i // 60) * 1200 + random() * 200, 0)
poswriter = None
vdata = None
geom = None
node.setInstanceCount(NUM_INSTANCES)
node.node().setBounds(OmniBoundingVolume())
node.node().setFinal(True)
base.trackball.node().set_pos(4.7, 172.7, -49.7)
base.trackball.node().set_hpr(61.5281, 12.0915, -18.2124)
base.run()
It’s also possible to pass a matrix using this method, by using C_matrix
instead of C_other
and add_matrix4
instead of add_data3
. However, I can’t get that to work right now. I’ll try to come back to it later.