# Buggy code
def paint(self):
    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:
                if isinstance(self.color, QtGui.QColor):
                    glColor4f(*fn.glColor(self.color))
                else:
                    glColor4f(*self.color)

            if not self.pxMode or isinstance(self.size, np.ndarray):
                glEnableClientState(GL_NORMAL_ARRAY)
                norm = np.empty(pos.shape)
                if self.pxMode:
                    norm[..., 0] = self.size
                else:
                    gpos = self.mapToView(pos.transpose()).transpose()
                    pxSize = self.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, int(pos.size / pos.shape[-1]))
        finally:
            glDisableClientState(GL_NORMAL_ARRAY)
            glDisableClientState(GL_VERTEX_ARRAY)
            glDisableClientState(GL_COLOR_ARRAY)
            # posVBO.unbind()
            ##fixes #145
            glDisable(GL_TEXTURE_2D)


# Traceback (AttributeError)
|==============================>>
|  Traceback (most recent call last):
|    File "filename.py", line 358, in <module>
|      sys.exit(app.exec_())
|    File "...\AppData\Roaming\Python\Python38\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 193, in paintGL
|      self.drawItemTree(useItemNames=useItemNames)
|    File "...\AppData\Roaming\Python\Python38\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 233, in drawItemTree
|      self.drawItemTree(i, useItemNames=useItemNames)
|    File "...\AppData\Roaming\Python\Python38\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 214, in drawItemTree
|      debug.printExc()
|    --- exception caught here ---
|    File "...\AppData\Roaming\Python\Python38\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 211, in drawItemTree
|      i.paint()
|    File "...\AppData\Roaming\Python\Python38\site-packages\pyqtgraph\opengl\items\GLScatterPlotItem.py", line 152, in paint
|      glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))
|  AttributeError: 'list' object has no attribute 'size'
|==============================<<
Error while drawing item <pyqtgraph.opengl.items.GLScatterPlotItem.GLScatterPlotItem(0xf20aa30) at 0x101A63A8>.

# Fixed 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:
                if isinstance(self.color, QtGui.QColor):
                    glColor4f(*fn.glColor(self.color))
                else:
                    glColor4f(*self.color)

            if not self.pxMode or isinstance(self.size, np.ndarray):
                glEnableClientState(GL_NORMAL_ARRAY)
                norm = np.empty(pos.shape)
                if self.pxMode:
                    norm[..., 0] = self.size
                else:
                    gpos = self.mapToView(pos.transpose()).transpose()
                    pxSize = self.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, int(pos.size / pos.shape[-1]))
        finally:
            glDisableClientState(GL_NORMAL_ARRAY)
            glDisableClientState(GL_VERTEX_ARRAY)
            glDisableClientState(GL_COLOR_ARRAY)
            # posVBO.unbind()
            ##fixes #145
            glDisable(GL_TEXTURE_2D)