Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've got what seems like a very ugly little piece of code that I seem to keep on resorting back to whenever I'm trying to draw arrays with pyglet, of the form:

vertPoints = someArray.flatten().astype(ctypes.c_float)
vertices_gl = vertPoints.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

Which I cobbled together based on the few resources I could find using numpy with pyglet. Is there a more elegant way to get a pointer to a numpy array as c_floats?

Here's the code above in the context of a small example I wrote:

import numpy as np; import ctypes
import pyglet; import pyglet.gl as gl

def drawArray(someArray):

    vertPoints = someArray[:,:2].flatten().astype(ctypes.c_float)
    vertices_gl = vertPoints.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

    vertColors = someArray[:,2:].flatten().astype(ctypes.c_float)
    colors_gl = vertColors.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

    gl.glVertexPointer(2, gl.GL_FLOAT, 0, vertices_gl)
    gl.glColorPointer(3,  gl.GL_FLOAT, 0, colors_gl)
    gl.glDrawArrays(gl.GL_POINTS, 0, len(vertPoints) // 2)

window = pyglet.window.Window(400,400)

@window.event
def on_draw():
    gl.glPointSize(10.0)
    gl.glEnable(gl.GL_POINT_SMOOTH)
    gl.glEnable(gl.GL_BLEND)
    gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_COLOR_ARRAY)

    points = np.random.random((50,5))*np.array([400,400,1,1,1])
    drawArray(points)

pyglet.app.run()
share|improve this question
1  
If you use dtype=np.float32 and use separate arrays for the vertices and colors, then you don't need to flatten (copy the data to contiguous memory) or use astype (create a whole new array), and the pointer is just vertices_gl = verticesArray.ctypes.data, etc. – eryksun Mar 25 at 0:24

2 Answers

I think you don't need to convert the address of data to a float pointer, you can pass the address directly:

gl.glVertexPointer(2, gl.GL_FLOAT, 0, vertPoints.ctypes.data)
gl.glColorPointer(3,  gl.GL_FLOAT, 0, vertColors.ctypes.data)
share|improve this answer

You can use Numpy float arrays directly with vertex buffer objects. I haven't used them in the context of Pyglet though. Something like:

from OpenGL.arrays import vbo

# setup
vertices_gl = vbo.VBO(vertPoints)
colours_gl = vbo.VBO(vertPoints)

# in drawing code
vertices.bind()
colours.bind()
glVertexPointer(2, gl.GL_FLOAT, 0, vertices_gl)
glColorPointer(2, gl.GL_FLOAT, 0, vertices_gl)
share|improve this answer
So far as I know, that does work in PyOpenGL, but won't in Pyglet because of the different way that the bindings are generated. PyOpenGL does a lot more for you in terms of facilitating simple interfaces, whereas Pyglet expects things to be passed as ctypes. While I've considered switch to PyOpenGL for that reason, it's become a curiosity thing at this point; there must be some kind of clean syntax for generating a c_float pointer into a numpy array. – TheONP Mar 24 at 21:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.