We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
opengl\items\GLScatterPlotItem.py, Argument pos
### Description
pos is defined as an **empty list** in line 17 instead of an array which causes for exceptions when `pose.shape`, `pos.transpose()`, and `pos.size` are used.


### Behavior
```
    |==============================>>
    |  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>.
```

### Additional context
I honestly have no idea how to fix it since I tried some of the trivia fixes, and they did not solve the problem. (
newbie)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyqtgraph/opengl/items/GLScatterPlotItem.py`
Content:
```
1 from OpenGL.GL import *
2 from OpenGL.arrays import vbo
3 from .. GLGraphicsItem import GLGraphicsItem
4 from .. import shaders
5 from ... import QtGui
6 import numpy as np
7 
8 __all__ = ['GLScatterPlotItem']
9 
10 class GLScatterPlotItem(GLGraphicsItem):
11     """Draws points at a list of 3D positions."""
12     
13     def __init__(self, **kwds):
14         GLGraphicsItem.__init__(self)
15         glopts = kwds.pop('glOptions', 'additive')
16         self.setGLOptions(glopts)
17         self.pos = []
18         self.size = 10
19         self.color = [1.0,1.0,1.0,0.5]
20         self.pxMode = True
21         #self.vbo = {}      ## VBO does not appear to improve performance very much.
22         self.setData(**kwds)
23         self.shader = None
24     
25     def setData(self, **kwds):
26         """
27         Update the data displayed by this item. All arguments are optional; 
28         for example it is allowed to update spot positions while leaving 
29         colors unchanged, etc.
30         
31         ====================  ==================================================
32         **Arguments:**
33         pos                   (N,3) array of floats specifying point locations.
34         color                 (N,4) array of floats (0.0-1.0) specifying
35                               spot colors OR a tuple of floats specifying
36                               a single color for all spots.
37         size                  (N,) array of floats specifying spot sizes or 
38                               a single value to apply to all spots.
39         pxMode                If True, spot sizes are expressed in pixels. 
40                               Otherwise, they are expressed in item coordinates.
41         ====================  ==================================================
42         """
43         args = ['pos', 'color', 'size', 'pxMode']
44         for k in kwds.keys():
45             if k not in args:
46                 raise Exception('Invalid keyword argument: %s (allowed arguments are %s)' % (k, str(args)))
47             
48         args.remove('pxMode')
49         for arg in args:
50             if arg in kwds:
51                 setattr(self, arg, kwds[arg])
52                 #self.vbo.pop(arg, None)
53                 
54         self.pxMode = kwds.get('pxMode', self.pxMode)
55         self.update()
56 
57     def initializeGL(self):
58         if self.shader is not None:
59             return
60         
61         ## Generate texture for rendering points
62         w = 64
63         def fn(x,y):
64             r = ((x-(w-1)/2.)**2 + (y-(w-1)/2.)**2) ** 0.5
65             return 255 * (w/2. - np.clip(r, w/2.-1.0, w/2.))
66         pData = np.empty((w, w, 4))
67         pData[:] = 255
68         pData[:,:,3] = np.fromfunction(fn, pData.shape[:2])
69         #print pData.shape, pData.min(), pData.max()
70         pData = pData.astype(np.ubyte)
71         
72         if getattr(self, "pointTexture", None) is None:
73             self.pointTexture = glGenTextures(1)
74         glActiveTexture(GL_TEXTURE0)
75         glEnable(GL_TEXTURE_2D)
76         glBindTexture(GL_TEXTURE_2D, self.pointTexture)
77         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pData.shape[0], pData.shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, pData)
78         
79         self.shader = shaders.getShaderProgram('pointSprite')
80         
81     #def getVBO(self, name):
82         #if name not in self.vbo:
83             #self.vbo[name] = vbo.VBO(getattr(self, name).astype('f'))
84         #return self.vbo[name]
85         
86     #def setupGLState(self):
87         #"""Prepare OpenGL state for drawing. This function is called immediately before painting."""
88         ##glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)  ## requires z-sorting to render properly.
89         #glBlendFunc(GL_SRC_ALPHA, GL_ONE)
90         #glEnable( GL_BLEND )
91         #glEnable( GL_ALPHA_TEST )
92         #glDisable( GL_DEPTH_TEST )
93         
94         ##glEnable( GL_POINT_SMOOTH )
95 
96         ##glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)
97         ##glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (0, 0, -1e-3))
98         ##glPointParameterfv(GL_POINT_SIZE_MAX, (65500,))
99         ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,))
100         
101     def paint(self):
102         self.setupGLState()
103         
104         glEnable(GL_POINT_SPRITE)
105         
106         glActiveTexture(GL_TEXTURE0)
107         glEnable( GL_TEXTURE_2D )
108         glBindTexture(GL_TEXTURE_2D, self.pointTexture)
109     
110         glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)
111         #glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)    ## use texture color exactly
112         #glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )  ## texture modulates current color
113         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
114         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
115         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
116         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
117         glEnable(GL_PROGRAM_POINT_SIZE)
118         
119             
120         with self.shader:
121             #glUniform1i(self.shader.uniform('texture'), 0)  ## inform the shader which texture to use
122             glEnableClientState(GL_VERTEX_ARRAY)
123             try:
124                 pos = self.pos
125                 #if pos.ndim > 2:
126                     #pos = pos.reshape((-1, pos.shape[-1]))
127                 glVertexPointerf(pos)
128             
129                 if isinstance(self.color, np.ndarray):
130                     glEnableClientState(GL_COLOR_ARRAY)
131                     glColorPointerf(self.color)
132                 else:
133                     if isinstance(self.color, QtGui.QColor):
134                         glColor4f(*fn.glColor(self.color))
135                     else:
136                         glColor4f(*self.color)
137                 
138                 if not self.pxMode or isinstance(self.size, np.ndarray):
139                     glEnableClientState(GL_NORMAL_ARRAY)
140                     norm = np.empty(pos.shape)
141                     if self.pxMode:
142                         norm[...,0] = self.size
143                     else:
144                         gpos = self.mapToView(pos.transpose()).transpose()
145                         pxSize = self.view().pixelSize(gpos)
146                         norm[...,0] = self.size / pxSize
147                     
148                     glNormalPointerf(norm)
149                 else:
150                     glNormal3f(self.size, 0, 0)  ## vertex shader uses norm.x to determine point size
151                     #glPointSize(self.size)
152                 glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))
153             finally:
154                 glDisableClientState(GL_NORMAL_ARRAY)
155                 glDisableClientState(GL_VERTEX_ARRAY)
156                 glDisableClientState(GL_COLOR_ARRAY)
157                 #posVBO.unbind()
158                 ##fixes #145
159                 glDisable( GL_TEXTURE_2D )
160                                 
161         #for i in range(len(self.pos)):
162             #pos = self.pos[i]
163             
164             #if isinstance(self.color, np.ndarray):
165                 #color = self.color[i]
166             #else:
167                 #color = self.color
168             #if isinstance(self.color, QtGui.QColor):
169                 #color = fn.glColor(self.color)
170                 
171             #if isinstance(self.size, np.ndarray):
172                 #size = self.size[i]
173             #else:
174                 #size = self.size
175                 
176             #pxSize = self.view().pixelSize(QtGui.QVector3D(*pos))
177             
178             #glPointSize(size / pxSize)
179             #glBegin( GL_POINTS )
180             #glColor4f(*color)  # x is blue
181             ##glNormal3f(size, 0, 0)
182             #glVertex3f(*pos)
183             #glEnd()
184 
185         
186         
187         
188         
189
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pyqtgraph/opengl/items/GLScatterPlotItem.py b/pyqtgraph/opengl/items/GLScatterPlotItem.py
--- a/pyqtgraph/opengl/items/GLScatterPlotItem.py
+++ b/pyqtgraph/opengl/items/GLScatterPlotItem.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 from OpenGL.GL import *
 from OpenGL.arrays import vbo
 from .. GLGraphicsItem import GLGraphicsItem
@@ -14,7 +15,7 @@
         GLGraphicsItem.__init__(self)
         glopts = kwds.pop('glOptions', 'additive')
         self.setGLOptions(glopts)
-        self.pos = []
+        self.pos = None
         self.size = 10
         self.color = [1.0,1.0,1.0,0.5]
         self.pxMode = True
@@ -99,6 +100,9 @@
         ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,))
         
     def paint(self):
+        if self.pos is None:
+            return
+
         self.setupGLState()
         
         glEnable(GL_POINT_SPRITE)

{"golden_diff": "diff --git a/pyqtgraph/opengl/items/GLScatterPlotItem.py b/pyqtgraph/opengl/items/GLScatterPlotItem.py\n--- a/pyqtgraph/opengl/items/GLScatterPlotItem.py\n+++ b/pyqtgraph/opengl/items/GLScatterPlotItem.py\n@@ -1,3 +1,4 @@\n+# -*- coding: utf-8 -*-\n from OpenGL.GL import *\n from OpenGL.arrays import vbo\n from .. GLGraphicsItem import GLGraphicsItem\n@@ -14,7 +15,7 @@\n         GLGraphicsItem.__init__(self)\n         glopts = kwds.pop('glOptions', 'additive')\n         self.setGLOptions(glopts)\n-        self.pos = []\n+        self.pos = None\n         self.size = 10\n         self.color = [1.0,1.0,1.0,0.5]\n         self.pxMode = True\n@@ -99,6 +100,9 @@\n         ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,))\n         \n     def paint(self):\n+        if self.pos is None:\n+            return\n+\n         self.setupGLState()\n         \n         glEnable(GL_POINT_SPRITE)\n", "issue": "opengl\\items\\GLScatterPlotItem.py, Argument pos\n### Description\r\npos is defined as an **empty list** in line 17 instead of an array which causes for exceptions when `pose.shape`, `pos.transpose()`, and `pos.size` are used.\r\n\r\n\r\n### Behavior\r\n```\r\n    |==============================>>\r\n    |  Traceback (most recent call last):\r\n    |    File \"filename.py\", line 358, in <module>\r\n    |      sys.exit(app.exec_())\r\n    |    File \"...\\AppData\\Roaming\\Python\\Python38\\site-packages\\pyqtgraph\\opengl\\GLViewWidget.py\", line 193, in paintGL      \r\n    |      self.drawItemTree(useItemNames=useItemNames)\r\n    |    File \"...\\AppData\\Roaming\\Python\\Python38\\site-packages\\pyqtgraph\\opengl\\GLViewWidget.py\", line 233, in drawItemTree \r\n    |      self.drawItemTree(i, useItemNames=useItemNames)\r\n    |    File \"...\\AppData\\Roaming\\Python\\Python38\\site-packages\\pyqtgraph\\opengl\\GLViewWidget.py\", line 214, in drawItemTree \r\n    |      debug.printExc()\r\n    |    --- exception caught here ---\r\n    |    File \"...\\AppData\\Roaming\\Python\\Python38\\site-packages\\pyqtgraph\\opengl\\GLViewWidget.py\", line 211, in drawItemTree \r\n    |      i.paint()\r\n    |    File \"...\\AppData\\Roaming\\Python\\Python38\\site-packages\\pyqtgraph\\opengl\\items\\GLScatterPlotItem.py\", line 152, in paint\r\n    |      glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))\r\n    |  AttributeError: 'list' object has no attribute 'size'\r\n    |==============================<<\r\nError while drawing item <pyqtgraph.opengl.items.GLScatterPlotItem.GLScatterPlotItem(0xf20aa30) at 0x101A63A8>.\r\n```\r\n\r\n### Additional context\r\nI honestly have no idea how to fix it since I tried some of the trivia fixes, and they did not solve the problem. (\r\nnewbie)\n", "before_files": [{"content": "from OpenGL.GL import *\nfrom OpenGL.arrays import vbo\nfrom .. GLGraphicsItem import GLGraphicsItem\nfrom .. import shaders\nfrom ... import QtGui\nimport numpy as np\n\n__all__ = ['GLScatterPlotItem']\n\nclass GLScatterPlotItem(GLGraphicsItem):\n    \"\"\"Draws points at a list of 3D positions.\"\"\"\n    \n    def __init__(self, **kwds):\n        GLGraphicsItem.__init__(self)\n        glopts = kwds.pop('glOptions', 'additive')\n        self.setGLOptions(glopts)\n        self.pos = []\n        self.size = 10\n        self.color = [1.0,1.0,1.0,0.5]\n        self.pxMode = True\n        #self.vbo = {}      ## VBO does not appear to improve performance very much.\n        self.setData(**kwds)\n        self.shader = None\n    \n    def setData(self, **kwds):\n        \"\"\"\n        Update the data displayed by this item. All arguments are optional; \n        for example it is allowed to update spot positions while leaving \n        colors unchanged, etc.\n        \n        ====================  ==================================================\n        **Arguments:**\n        pos                   (N,3) array of floats specifying point locations.\n        color                 (N,4) array of floats (0.0-1.0) specifying\n                              spot colors OR a tuple of floats specifying\n                              a single color for all spots.\n        size                  (N,) array of floats specifying spot sizes or \n                              a single value to apply to all spots.\n        pxMode                If True, spot sizes are expressed in pixels. \n                              Otherwise, they are expressed in item coordinates.\n        ====================  ==================================================\n        \"\"\"\n        args = ['pos', 'color', 'size', 'pxMode']\n        for k in kwds.keys():\n            if k not in args:\n                raise Exception('Invalid keyword argument: %s (allowed arguments are %s)' % (k, str(args)))\n            \n        args.remove('pxMode')\n        for arg in args:\n            if arg in kwds:\n                setattr(self, arg, kwds[arg])\n                #self.vbo.pop(arg, None)\n                \n        self.pxMode = kwds.get('pxMode', self.pxMode)\n        self.update()\n\n    def initializeGL(self):\n        if self.shader is not None:\n            return\n        \n        ## Generate texture for rendering points\n        w = 64\n        def fn(x,y):\n            r = ((x-(w-1)/2.)**2 + (y-(w-1)/2.)**2) ** 0.5\n            return 255 * (w/2. - np.clip(r, w/2.-1.0, w/2.))\n        pData = np.empty((w, w, 4))\n        pData[:] = 255\n        pData[:,:,3] = np.fromfunction(fn, pData.shape[:2])\n        #print pData.shape, pData.min(), pData.max()\n        pData = pData.astype(np.ubyte)\n        \n        if getattr(self, \"pointTexture\", None) is None:\n            self.pointTexture = glGenTextures(1)\n        glActiveTexture(GL_TEXTURE0)\n        glEnable(GL_TEXTURE_2D)\n        glBindTexture(GL_TEXTURE_2D, self.pointTexture)\n        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pData.shape[0], pData.shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, pData)\n        \n        self.shader = shaders.getShaderProgram('pointSprite')\n        \n    #def getVBO(self, name):\n        #if name not in self.vbo:\n            #self.vbo[name] = vbo.VBO(getattr(self, name).astype('f'))\n        #return self.vbo[name]\n        \n    #def setupGLState(self):\n        #\"\"\"Prepare OpenGL state for drawing. This function is called immediately before painting.\"\"\"\n        ##glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)  ## requires z-sorting to render properly.\n        #glBlendFunc(GL_SRC_ALPHA, GL_ONE)\n        #glEnable( GL_BLEND )\n        #glEnable( GL_ALPHA_TEST )\n        #glDisable( GL_DEPTH_TEST )\n        \n        ##glEnable( GL_POINT_SMOOTH )\n\n        ##glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)\n        ##glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (0, 0, -1e-3))\n        ##glPointParameterfv(GL_POINT_SIZE_MAX, (65500,))\n        ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,))\n        \n    def paint(self):\n        self.setupGLState()\n        \n        glEnable(GL_POINT_SPRITE)\n        \n        glActiveTexture(GL_TEXTURE0)\n        glEnable( GL_TEXTURE_2D )\n        glBindTexture(GL_TEXTURE_2D, self.pointTexture)\n    \n        glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)\n        #glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)    ## use texture color exactly\n        #glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )  ## texture modulates current color\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)\n        glEnable(GL_PROGRAM_POINT_SIZE)\n        \n            \n        with self.shader:\n            #glUniform1i(self.shader.uniform('texture'), 0)  ## inform the shader which texture to use\n            glEnableClientState(GL_VERTEX_ARRAY)\n            try:\n                pos = self.pos\n                #if pos.ndim > 2:\n                    #pos = pos.reshape((-1, pos.shape[-1]))\n                glVertexPointerf(pos)\n            \n                if isinstance(self.color, np.ndarray):\n                    glEnableClientState(GL_COLOR_ARRAY)\n                    glColorPointerf(self.color)\n                else:\n                    if isinstance(self.color, QtGui.QColor):\n                        glColor4f(*fn.glColor(self.color))\n                    else:\n                        glColor4f(*self.color)\n                \n                if not self.pxMode or isinstance(self.size, np.ndarray):\n                    glEnableClientState(GL_NORMAL_ARRAY)\n                    norm = np.empty(pos.shape)\n                    if self.pxMode:\n                        norm[...,0] = self.size\n                    else:\n                        gpos = self.mapToView(pos.transpose()).transpose()\n                        pxSize = self.view().pixelSize(gpos)\n                        norm[...,0] = self.size / pxSize\n                    \n                    glNormalPointerf(norm)\n                else:\n                    glNormal3f(self.size, 0, 0)  ## vertex shader uses norm.x to determine point size\n                    #glPointSize(self.size)\n                glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))\n            finally:\n                glDisableClientState(GL_NORMAL_ARRAY)\n                glDisableClientState(GL_VERTEX_ARRAY)\n                glDisableClientState(GL_COLOR_ARRAY)\n                #posVBO.unbind()\n                ##fixes #145\n                glDisable( GL_TEXTURE_2D )\n                                \n        #for i in range(len(self.pos)):\n            #pos = self.pos[i]\n            \n            #if isinstance(self.color, np.ndarray):\n                #color = self.color[i]\n            #else:\n                #color = self.color\n            #if isinstance(self.color, QtGui.QColor):\n                #color = fn.glColor(self.color)\n                \n            #if isinstance(self.size, np.ndarray):\n                #size = self.size[i]\n            #else:\n                #size = self.size\n                \n            #pxSize = self.view().pixelSize(QtGui.QVector3D(*pos))\n            \n            #glPointSize(size / pxSize)\n            #glBegin( GL_POINTS )\n            #glColor4f(*color)  # x is blue\n            ##glNormal3f(size, 0, 0)\n            #glVertex3f(*pos)\n            #glEnd()\n\n        \n        \n        \n        \n", "path": "pyqtgraph/opengl/items/GLScatterPlotItem.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom OpenGL.GL import *\nfrom OpenGL.arrays import vbo\nfrom .. GLGraphicsItem import GLGraphicsItem\nfrom .. import shaders\nfrom ... import QtGui\nimport numpy as np\n\n__all__ = ['GLScatterPlotItem']\n\nclass GLScatterPlotItem(GLGraphicsItem):\n    \"\"\"Draws points at a list of 3D positions.\"\"\"\n    \n    def __init__(self, **kwds):\n        GLGraphicsItem.__init__(self)\n        glopts = kwds.pop('glOptions', 'additive')\n        self.setGLOptions(glopts)\n        self.pos = None\n        self.size = 10\n        self.color = [1.0,1.0,1.0,0.5]\n        self.pxMode = True\n        #self.vbo = {}      ## VBO does not appear to improve performance very much.\n        self.setData(**kwds)\n        self.shader = None\n    \n    def setData(self, **kwds):\n        \"\"\"\n        Update the data displayed by this item. All arguments are optional; \n        for example it is allowed to update spot positions while leaving \n        colors unchanged, etc.\n        \n        ====================  ==================================================\n        **Arguments:**\n        pos                   (N,3) array of floats specifying point locations.\n        color                 (N,4) array of floats (0.0-1.0) specifying\n                              spot colors OR a tuple of floats specifying\n                              a single color for all spots.\n        size                  (N,) array of floats specifying spot sizes or \n                              a single value to apply to all spots.\n        pxMode                If True, spot sizes are expressed in pixels. \n                              Otherwise, they are expressed in item coordinates.\n        ====================  ==================================================\n        \"\"\"\n        args = ['pos', 'color', 'size', 'pxMode']\n        for k in kwds.keys():\n            if k not in args:\n                raise Exception('Invalid keyword argument: %s (allowed arguments are %s)' % (k, str(args)))\n            \n        args.remove('pxMode')\n        for arg in args:\n            if arg in kwds:\n                setattr(self, arg, kwds[arg])\n                #self.vbo.pop(arg, None)\n                \n        self.pxMode = kwds.get('pxMode', self.pxMode)\n        self.update()\n\n    def initializeGL(self):\n        if self.shader is not None:\n            return\n        \n        ## Generate texture for rendering points\n        w = 64\n        def fn(x,y):\n            r = ((x-(w-1)/2.)**2 + (y-(w-1)/2.)**2) ** 0.5\n            return 255 * (w/2. - np.clip(r, w/2.-1.0, w/2.))\n        pData = np.empty((w, w, 4))\n        pData[:] = 255\n        pData[:,:,3] = np.fromfunction(fn, pData.shape[:2])\n        #print pData.shape, pData.min(), pData.max()\n        pData = pData.astype(np.ubyte)\n        \n        if getattr(self, \"pointTexture\", None) is None:\n            self.pointTexture = glGenTextures(1)\n        glActiveTexture(GL_TEXTURE0)\n        glEnable(GL_TEXTURE_2D)\n        glBindTexture(GL_TEXTURE_2D, self.pointTexture)\n        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pData.shape[0], pData.shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, pData)\n        \n        self.shader = shaders.getShaderProgram('pointSprite')\n        \n    #def getVBO(self, name):\n        #if name not in self.vbo:\n            #self.vbo[name] = vbo.VBO(getattr(self, name).astype('f'))\n        #return self.vbo[name]\n        \n    #def setupGLState(self):\n        #\"\"\"Prepare OpenGL state for drawing. This function is called immediately before painting.\"\"\"\n        ##glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)  ## requires z-sorting to render properly.\n        #glBlendFunc(GL_SRC_ALPHA, GL_ONE)\n        #glEnable( GL_BLEND )\n        #glEnable( GL_ALPHA_TEST )\n        #glDisable( GL_DEPTH_TEST )\n        \n        ##glEnable( GL_POINT_SMOOTH )\n\n        ##glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)\n        ##glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (0, 0, -1e-3))\n        ##glPointParameterfv(GL_POINT_SIZE_MAX, (65500,))\n        ##glPointParameterfv(GL_POINT_SIZE_MIN, (0,))\n        \n    def paint(self):\n        if self.pos is None:\n            return\n\n        self.setupGLState()\n        \n        glEnable(GL_POINT_SPRITE)\n        \n        glActiveTexture(GL_TEXTURE0)\n        glEnable( GL_TEXTURE_2D )\n        glBindTexture(GL_TEXTURE_2D, self.pointTexture)\n    \n        glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)\n        #glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)    ## use texture color exactly\n        #glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )  ## texture modulates current color\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)\n        glEnable(GL_PROGRAM_POINT_SIZE)\n        \n            \n        with self.shader:\n            #glUniform1i(self.shader.uniform('texture'), 0)  ## inform the shader which texture to use\n            glEnableClientState(GL_VERTEX_ARRAY)\n            try:\n                pos = self.pos\n                #if pos.ndim > 2:\n                    #pos = pos.reshape((-1, pos.shape[-1]))\n                glVertexPointerf(pos)\n            \n                if isinstance(self.color, np.ndarray):\n                    glEnableClientState(GL_COLOR_ARRAY)\n                    glColorPointerf(self.color)\n                else:\n                    if isinstance(self.color, QtGui.QColor):\n                        glColor4f(*fn.glColor(self.color))\n                    else:\n                        glColor4f(*self.color)\n                \n                if not self.pxMode or isinstance(self.size, np.ndarray):\n                    glEnableClientState(GL_NORMAL_ARRAY)\n                    norm = np.empty(pos.shape)\n                    if self.pxMode:\n                        norm[...,0] = self.size\n                    else:\n                        gpos = self.mapToView(pos.transpose()).transpose()\n                        pxSize = self.view().pixelSize(gpos)\n                        norm[...,0] = self.size / pxSize\n                    \n                    glNormalPointerf(norm)\n                else:\n                    glNormal3f(self.size, 0, 0)  ## vertex shader uses norm.x to determine point size\n                    #glPointSize(self.size)\n                glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))\n            finally:\n                glDisableClientState(GL_NORMAL_ARRAY)\n                glDisableClientState(GL_VERTEX_ARRAY)\n                glDisableClientState(GL_COLOR_ARRAY)\n                #posVBO.unbind()\n                ##fixes #145\n                glDisable( GL_TEXTURE_2D )\n                                \n        #for i in range(len(self.pos)):\n            #pos = self.pos[i]\n            \n            #if isinstance(self.color, np.ndarray):\n                #color = self.color[i]\n            #else:\n                #color = self.color\n            #if isinstance(self.color, QtGui.QColor):\n                #color = fn.glColor(self.color)\n                \n            #if isinstance(self.size, np.ndarray):\n                #size = self.size[i]\n            #else:\n                #size = self.size\n                \n            #pxSize = self.view().pixelSize(QtGui.QVector3D(*pos))\n            \n            #glPointSize(size / pxSize)\n            #glBegin( GL_POINTS )\n            #glColor4f(*color)  # x is blue\n            ##glNormal3f(size, 0, 0)\n            #glVertex3f(*pos)\n            #glEnd()\n\n        \n        \n        \n        \n", "path": "pyqtgraph/opengl/items/GLScatterPlotItem.py"}]}