class_docstr: Draws points at a list of 3D positions.
code: def paint(self):
      if self.pos is None:
          return
  
      self.setupGLState()
  
      glEnable(GL_POINT_SPRITE)
  
      glActiveTexture(GL_TEXTURE0)
      glEnable(GL_TEXTURE_2D)
      glBindTexture(GL_TEXTURE_2D, self.pointTexture)
  
      glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)
      # glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)    ## use texture color exactly
      # glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )  ## texture modulates current color
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
      glTexParameteri(
          GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE
      )
      glTexParameteri(
          GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE
      )
      glEnable(GL_PROGRAM_POINT_SIZE)
  
      with self.shader:
          # glUniform1i(self.shader.uniform('texture'), 0)  ## inform the shader which texture to use
          glEnableClientState(GL_VERTEX_ARRAY)
          try:
              pos = self.pos
              # if pos.ndim > 2:
              # pos = pos.reshape((-1, pos.shape[-1]))
              glVertexPointerf(pos)
  
              if isinstance(self.color, np.ndarray):
                  glEnableClientState(GL_COLOR_ARRAY)
                  glColorPointerf(self.color)
              else:
                  color = self.color
                  if isinstance(color, QtGui.QColor):
                      color = color.getRgbF()
                  glColor4f(*color)
  
              if not self.pxMode or isinstance(self.size, np.ndarray):
                  glEnableClientState(GL_NORMAL_ARRAY)
                  norm = np.zeros(pos.shape, dtype=np.float32)
                  if self.pxMode:
                      norm[..., 0] = self.size
                  else:
                      gpos = self.mapToView(pos.transpose()).transpose()
                      if self.view():
                          pxSize = self.view().pixelSize(gpos)
                      else:
                          pxSize = (
                              self.parentItem().view().pixelSize(gpos)
                          )
                      norm[..., 0] = self.size / pxSize
  
                  glNormalPointerf(norm)
              else:
                  glNormal3f(
                      self.size, 0, 0
                  )  ## vertex shader uses norm.x to determine point size
                  # glPointSize(self.size)
              glDrawArrays(GL_POINTS, 0, pos.shape[0])
          finally:
              glDisableClientState(GL_NORMAL_ARRAY)
              glDisableClientState(GL_VERTEX_ARRAY)
              glDisableClientState(GL_COLOR_ARRAY)
              # posVBO.unbind()
              ##fixes #145
              glDisable(GL_TEXTURE_2D)
  
file_path: pyqtgraph/pyqtgraph/opengl/items/GLScatterPlotItem.py
imports: from OpenGL.GL import *
  import numpy
  from ...None import functions
  from ...Qt import QtGui
  from ..None import shaders
  from ..GLGraphicsItem import GLGraphicsItem
label_desc: Use image node_id 4 for calling the GLScatterPlotItem obj's underlying member method code with example usage: obj.paint() without return types