code: def on_initialize(self, event):
      # Build & activate program
      self.program = gl.glCreateProgram()
      vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
      fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
      gl.glShaderSource(vertex, vertex_code)
      gl.glShaderSource(fragment, fragment_code)
      gl.glCompileShader(vertex)
      gl.glCompileShader(fragment)
      gl.glAttachShader(self.program, vertex)
      gl.glAttachShader(self.program, fragment)
      gl.glLinkProgram(self.program)
      gl.glDetachShader(self.program, vertex)
      gl.glDetachShader(self.program, fragment)
      gl.glUseProgram(self.program)
  
      # Build vertex buffer
      n = 10000
      self.data = np.zeros(
          n,
          dtype=[
              ("lifetime", np.float32),
              ("start", np.float32, 3),
              ("end", np.float32, 3),
          ],
      )
      vbuffer = gl.glCreateBuffer()
      gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbuffer)
      gl.glBufferData(gl.GL_ARRAY_BUFFER, self.data, gl.GL_DYNAMIC_DRAW)
  
      # Bind buffer attributes
      stride = self.data.strides[0]
  
      offset = 0
      loc = gl.glGetAttribLocation(self.program, "lifetime")
      gl.glEnableVertexAttribArray(loc)
      gl.glVertexAttribPointer(
          loc, 1, gl.GL_FLOAT, False, stride, offset
      )
  
      offset = self.data.dtype["lifetime"].itemsize
      loc = gl.glGetAttribLocation(self.program, "start")
      gl.glEnableVertexAttribArray(loc)
      gl.glVertexAttribPointer(
          loc, 3, gl.GL_FLOAT, False, stride, offset
      )
  
      offset = self.data.dtype["start"].itemsize
      loc = gl.glGetAttribLocation(self.program, "end")
      gl.glEnableVertexAttribArray(loc)
      gl.glVertexAttribPointer(
          loc, 3, gl.GL_FLOAT, False, stride, offset
      )
  
      # OpenGL initalization
      self.elapsed_time = 0
      gl.glClearColor(0, 0, 0, 1)
      gl.glDisable(gl.GL_DEPTH_TEST)
      gl.glEnable(gl.GL_BLEND)
      gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE)
      gl.glEnable(34370)  # gl.GL_VERTEX_PROGRAM_POINT_SIZE
      gl.glEnable(34913)  # gl.GL_POINT_SPRITE
      gl.glViewport(0, 0, *self.physical_size)
      self.new_explosion()
      self.timer = app.Timer("auto", self.on_timer, start=True)
  
file_path: vispy/examples/gloo/gl/fireworks.py
imports: import numpy
  from vispy import app
  from vispy.gloo import gl
label_desc: Use image node_id 2 for calling the Canvas obj's underlying member method code with example usage: obj.on_initialize(event) without return types