Skip to content

Instantly share code, notes, and snippets.

@rdb
Last active April 12, 2023 19:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdb/e8c0d048285d465f1566f0cb6ab4284c to your computer and use it in GitHub Desktop.
Save rdb/e8c0d048285d465f1566f0cb6ab4284c to your computer and use it in GitHub Desktop.
Snippet demonstrating vertex pulling in Panda3D
from panda3d.core import *
#load_prc_file_data("", "gl-version 3 3")
from array import array
# Create two silly triangles.
data = array('f', [
0, 4, 0,
1, 4, 1,
0, 4, 1,
-2, 4, -1,
1, 4, 2,
-2, 4, 1,
])
num_verts = len(data) // 3
# Create a buffer texture and initialize it with the data.
tex = Texture("vertex-data")
tex.setup_buffer_texture(num_verts, Texture.T_float, Texture.F_rgb32, GeomEnums.UH_static)
tex.set_ram_image(data.tobytes())
# Create a dummy vertex data object.
if True:
format = GeomVertexFormat.get_empty()
vdata = GeomVertexData('abc', format, GeomEnums.UH_static)
else:
# Before 1.10, you needed to do this instead:
aformat = GeomVertexArrayFormat("vertex", 1, GeomEnums.NT_uint8, GeomEnums.C_other)
format = GeomVertexFormat.register_format(GeomVertexFormat(aformat))
vdata = GeomVertexData('abc', format, GeomEnums.UH_static)
vdata.set_num_rows(num_verts)
# This represents a draw call, indicating how many vertices we want to draw.
tris = GeomTriangles(GeomEnums.UH_static)
tris.add_next_vertices(num_verts)
# We need to set a bounding volume so that Panda doesn't try to cull it.
# You could be smarter about this by assigning a bounding volume that encloses
# the vertices.
geom = Geom(vdata)
geom.add_primitive(tris)
geom.set_bounds(OmniBoundingVolume())
node = GeomNode("node")
node.add_geom(geom)
shader = Shader.make(Shader.SL_GLSL, """
#version 140
uniform samplerBuffer vdata;
uniform mat4 p3d_ModelViewProjectionMatrix;
void main() {
vec4 vertex = texelFetch(vdata, gl_VertexID);
gl_Position = p3d_ModelViewProjectionMatrix * vertex;
}
""", """
#version 140
void main() {
// Just paint each triangle with a solid red color.
gl_FragColor = vec4(1, 0, 0, 1);
}
""")
from direct.showbase.ShowBase import ShowBase
base = ShowBase()
# Put our node in the scene graph and apply the texture containing the data.
path = base.render.attach_new_node(node)
path.set_shader(shader)
path.set_shader_input('vdata', tex)
base.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment