title: How to correctly use QOpenGLBuffer's allocate/read/write in PyQt5?
body: <p><a href="https://doc.qt.io/qt-5/qopenglbuffer.html#allocate" rel="nofollow noreferrer">This</a> requires a void * data input. So, I got it working with something like this,</p>
  
  <pre><code>vbo = QtGui.QOpenGLBuffer(QtGui.QOpenGLBuffer.VertexBuffer)
  vrtxAttrs = [1., 1., 1., 0., 0.1, 0.1, 1.0,
               -1., -1., -1., 1.0, 0.9, 0.9, 1.0] # a list of interleaved positions xyz and colors rgba
  data = numpy.array(vrtxAttrs, dtype=numpy.float32)
  </code></pre>
  
  <p>I will be honest, I don't know how I got here. I tried numerous things and stumbled upon using <code>data.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)).contents</code>. Please tell me this is awful and there is a better way to do it.</p>
  
  <pre><code># How I allocate..
  vbo.allocate(data.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)).contents,
                            sys.getsizeof(data))
  </code></pre>
  
  <pre><code># How I write.. (I believe this calls glBufferSubData internally)
  # I intend to change the second vertex's position and color.
  newdata = [2., 2., 2., 0.5, 0.4, 0.4, 1.]
  toWrite = numpy.array(newdata, dtype=numpy.float32)
  offset = 1 * 7 * 4 # this has to be in bytes. (1 is the index, 7 the stride, 4 the bytesize.)
  count = len(newdata) * 4 # this has to be in bytes.
  vbo.write(offset, data.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)).contents, count)
  </code></pre>
  
  <pre><code># How I read,
  # I don't read, since I don't know what weird cast I need to do to read.
  # The usage is documented as bool QOpenGLBuffer::read(int offset, void *data, int count)
  </code></pre>
  
  <p>The python documentation for these are ridiculous, yeah we know how to use them in C++, what about python? For starters, I am looking for answers that explain <a href="https://www.riverbankcomputing.com/static/Docs/PyQt5/gotchas.html#support-for-void" rel="nofollow noreferrer">sip.voidptr</a></p>