psychopy.tools.gltools
¶OpenGL related helper functions.
createFBO ([attachments]) |
Create a Framebuffer Object. |
attach (attachPoint, imageBuffer) |
Attach an image to a specified attachment point on the presently bound FBO. |
isComplete () |
Check if the currently bound framebuffer is complete. |
deleteFBO (fbo) |
Delete a framebuffer. |
blitFBO (srcRect[, dstRect, filter]) |
Copy a block of pixels between framebuffers via blitting. |
useFBO (*args, **kwds) |
Context manager for Framebuffer Object bindings. |
createRenderbuffer (width, height[, …]) |
Create a new Renderbuffer Object with a specified internal format. |
deleteRenderbuffer (renderBuffer) |
Free the resources associated with a renderbuffer. |
createTexImage2D (width, height[, target, …]) |
Create a 2D texture in video memory. |
createTexImage2DMultisample (width, height[, …]) |
Create a 2D multisampled texture. |
deleteTexture (texture) |
Free the resources associated with a texture. |
createVBO (data[, size, dtype, target]) |
Create a single-storage array buffer, often referred to as Vertex Buffer Object (VBO). |
createVAO (vertexBuffers[, indexBuffer]) |
Create a Vertex Array Object (VAO) with specified Vertex Buffer Objects. |
drawVAO (vao[, mode, flush]) |
Draw a vertex array using glDrawArrays. |
deleteVBO (vbo) |
Delete a Vertex Buffer Object (VBO). |
deleteVAO (vao) |
Delete a Vertex Array Object (VAO). |
createMaterial ([params, textures, face]) |
Create a new material. |
useMaterial (material[, useTextures]) |
Use a material for proceeding vertex draws. |
createLight ([params]) |
Create a point light source. |
useLights (lights[, setupOnly]) |
Use specified lights in successive rendering operations. |
setAmbientLight (color) |
Set the global ambient lighting for the scene when lighting is enabled. |
loadObjFile (objFile) |
Load a Wavefront OBJ file (*.obj). |
loadMtlFile (mtlFilePath[, texParameters]) |
Load a material library (*.mtl). |
getIntegerv (parName) |
Get a single integer parameter value, return it as a Python integer. |
getFloatv (parName) |
Get a single float parameter value, return it as a Python float. |
getString (parName) |
Get a single string parameter value, return it as a Python UTF-8 string. |
getOpenGLInfo () |
Get general information about the OpenGL implementation on this machine. |
psychopy.tools.gltools.
createFBO
(attachments=())¶Create a Framebuffer Object.
Parameters: | attachments (list or tuple of tuple ) – Optional attachments to initialize the Framebuffer with. Attachments are
specified as a list of tuples. Each tuple must contain an attachment
point (e.g. GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, etc.) and a
buffer descriptor type (Renderbuffer or TexImage2D). If using a combined
depth/stencil format such as GL_DEPTH24_STENCIL8, GL_DEPTH_ATTACHMENT
and GL_STENCIL_ATTACHMENT must be passed the same buffer. Alternatively,
one can use GL_DEPTH_STENCIL_ATTACHMENT instead. If using multisample
buffers, all attachment images must use the same number of samples!. As
an example, one may specify attachments as ‘attachments=((
GL.GL_COLOR_ATTACHMENT0, frameTexture), (GL.GL_DEPTH_STENCIL_ATTACHMENT,
depthRenderBuffer))’. |
---|---|
Returns: | Framebuffer descriptor. |
Return type: | Framebuffer |
Notes
Examples
# empty framebuffer with no attachments fbo = createFBO() # invalid until attachments are added
# create a render target with multiple color texture attachments colorTex = createTexImage2D(1024,1024) # empty texture depthRb = createRenderbuffer(800,600,internalFormat=GL.GL_DEPTH24_STENCIL8)
# attach images GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo.id) attach(GL.GL_COLOR_ATTACHMENT0, colorTex) attach(GL.GL_DEPTH_ATTACHMENT, depthRb) attach(GL.GL_STENCIL_ATTACHMENT, depthRb) # or attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb) GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)
# above is the same as with useFBO(fbo):
attach(GL.GL_COLOR_ATTACHMENT0, colorTex) attach(GL.GL_DEPTH_ATTACHMENT, depthRb) attach(GL.GL_STENCIL_ATTACHMENT, depthRb)
# examples of userData some custom function might access fbo.userData[‘flags’] = [‘left_eye’, ‘clear_before_use’]
# depth only texture (for shadow mapping?) depthTex = createTexImage2D(800, 600,
internalFormat=GL.GL_DEPTH_COMPONENT24, pixelFormat=GL.GL_DEPTH_COMPONENT)
fbo = createFBO([(GL.GL_DEPTH_ATTACHMENT, depthTex)]) # is valid
# discard FBO descriptor, just give me the ID frameBuffer = createFBO().id
psychopy.tools.gltools.
attach
(attachPoint, imageBuffer)¶Attach an image to a specified attachment point on the presently bound FBO.
:param attachPoint int
: Attachment point for ‘imageBuffer’ (e.g. GL.GL_COLOR_ATTACHMENT0).
:param imageBuffer: Framebuffer-attachable buffer descriptor.
:type imageBuffer: TexImage2D
or Renderbuffer
Returns: | |
---|---|
Return type: | None |
Examples
# with descriptors colorTex and depthRb GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo) attach(GL.GL_COLOR_ATTACHMENT0, colorTex) attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb) GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, lastBoundFbo)
# same as above, but using a context manager with useFBO(fbo):
attach(GL.GL_COLOR_ATTACHMENT0, colorTex) attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb)
psychopy.tools.gltools.
isComplete
()¶Check if the currently bound framebuffer is complete.
Returns: | |
---|---|
Return type: | obj:`bool’ |
psychopy.tools.gltools.
blitFBO
(srcRect, dstRect=None, filter=9729)¶Copy a block of pixels between framebuffers via blitting. Read and draw framebuffers must be bound prior to calling this function. Beware, the scissor box and viewport are changed when this is called to dstRect.
Parameters: |
|
---|---|
Returns: | |
Return type: |
Examples
# bind framebuffer to read pixels from GL.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, srcFbo)
# bind framebuffer to draw pixels to GL.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, dstFbo)
gltools.blitFBO((0,0,800,600), (0,0,800,600))
# unbind both read and draw buffers GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)
psychopy.tools.gltools.
useFBO
(*args, **kwds)¶Context manager for Framebuffer Object bindings. This function yields the framebuffer name as an integer.
:param fbo int
or Framebuffer
: OpenGL Framebuffer Object name/ID or descriptor.
Yields: | int – OpenGL name of the framebuffer bound in the context. |
---|---|
Returns: | |
Return type: | None |
Examples
# FBO bound somewhere deep in our code GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, someOtherFBO)
…
# create a new FBO, but we have no idea what the currently bound FBO is fbo = createFBO()
# use a context to bind attachments with bindFBO(fbo):
attach(GL.GL_COLOR_ATTACHMENT0, colorTex) attach(GL.GL_DEPTH_ATTACHMENT, depthRb) attach(GL.GL_STENCIL_ATTACHMENT, depthRb) isComplete = gltools.isComplete()
# someOtherFBO is still bound!
psychopy.tools.gltools.
createRenderbuffer
(width, height, internalFormat=32856, samples=1)¶Create a new Renderbuffer Object with a specified internal format. A multisample storage buffer is created if samples > 1.
Renderbuffers contain image data and are optimized for use as render targets. See https://www.khronos.org/opengl/wiki/Renderbuffer_Object for more information.
Parameters: |
|
---|---|
Returns: | A descriptor of the created renderbuffer. |
Return type: |
|
Notes
The ‘userData’ field of the returned descriptor is a dictionary that can be used to store arbitrary data associated with the buffer.
psychopy.tools.gltools.
deleteRenderbuffer
(renderBuffer)¶Free the resources associated with a renderbuffer. This invalidates the renderbuffer’s ID.
Returns: | |
---|---|
Return type: | obj:`None’ |
psychopy.tools.gltools.
createTexImage2D
(width, height, target=3553, level=0, internalFormat=32856, pixelFormat=6408, dataType=5126, data=None, unpackAlignment=4, texParameters=())¶Create a 2D texture in video memory. This can only create a single 2D texture with targets GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE.
Parameters: |
|
---|---|
Returns: | A TexImage2D descriptor. |
Return type: |
|
Notes
The ‘userData’ field of the returned descriptor is a dictionary that can be used to store arbitrary data associated with the texture.
Previous textures are unbound after calling ‘createTexImage2D’.
Examples
import pyglet.gl as GL # using Pyglet for now
# empty texture textureDesc = createTexImage2D(1024, 1024, internalFormat=GL.GL_RGBA8)
# load texture data from an image file using Pillow and NumPy from PIL import Image import numpy as np im = Image.open(imageFile) # 8bpp! im = im.transpose(Image.FLIP_TOP_BOTTOM) # OpenGL origin is at bottom im = im.convert(“RGBA”) pixelData = np.array(im).ctypes # convert to ctypes!
width = pixelData.shape[1] height = pixelData.shape[0] textureDesc = gltools.createTexImage2D(
width, height, internalFormat=GL.GL_RGBA, pixelFormat=GL.GL_RGBA, dataType=GL.GL_UNSIGNED_BYTE, data=texture_array.ctypes, unpackAlignment=1, texParameters=[(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR),
(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)])
GL.glBindTexture(GL.GL_TEXTURE_2D, textureDesc.id)
psychopy.tools.gltools.
createTexImage2DMultisample
(width, height, target=37120, samples=1, internalFormat=32856, texParameters=())¶Create a 2D multisampled texture.
Parameters: |
|
---|---|
Returns: | A TexImage2DMultisample descriptor. |
Return type: |
|
psychopy.tools.gltools.
deleteTexture
(texture)¶Free the resources associated with a texture. This invalidates the texture’s ID.
Returns: | |
---|---|
Return type: | obj:`None’ |
psychopy.tools.gltools.
createVBO
(data, size=3, dtype=5126, target=34962)¶Create a single-storage array buffer, often referred to as Vertex Buffer Object (VBO).
Parameters: |
|
---|---|
Returns: | A descriptor with vertex buffer information. |
Return type: | VertexBufferObject |
Notes
Creating vertex buffers is a computationally expensive operation. Be sure to load all resources before entering your experiment’s main loop.
Examples
# vertices of a triangle verts = [ 1.0, 1.0, 0.0, # v0
0.0, -1.0, 0.0, # v1-1.0, 1.0, 0.0] # v2
# load vertices to graphics device, return a descriptor vboDesc = createVBO(verts, 3)
# draw GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vboDesc.id) GL.glVertexPointer(vboDesc.vertexSize, vboDesc.dtype, 0, None) GL.glEnableClientState(vboDesc.bufferType) GL.glDrawArrays(GL.GL_TRIANGLES, 0, vboDesc.indices) GL.glFlush()
psychopy.tools.gltools.
createVAO
(vertexBuffers, indexBuffer=None)¶Create a Vertex Array Object (VAO) with specified Vertex Buffer Objects. VAOs store buffer binding states, reducing CPU overhead when drawing objects with vertex data stored in VBOs.
Parameters: |
|
---|---|
Returns: | A descriptor with vertex array information. |
Return type: | VertexArrayObject |
Examples
# create a VAO vaoDesc = createVAO(vboVerts, vboTexCoords, vboNormals)
# draw the VAO, renders the mesh drawVAO(vaoDesc, GL.GL_TRIANGLES)
psychopy.tools.gltools.
drawVAO
(vao, mode=4, flush=False)¶Draw a vertex array using glDrawArrays. This method does not require shaders.
Parameters: | |
---|---|
Returns: | |
Return type: |
Examples
# create a VAO vaoDesc = createVAO(vboVerts, vboTexCoords, vboNormals)
# draw the VAO, renders the mesh drawVAO(vaoDesc, GL.GL_TRIANGLES)
psychopy.tools.gltools.
deleteVBO
(vbo)¶Delete a Vertex Buffer Object (VBO).
Returns: | |
---|---|
Return type: | obj:`None’ |
psychopy.tools.gltools.
deleteVAO
(vao)¶Delete a Vertex Array Object (VAO). This does not delete array buffers bound to the VAO.
Returns: | |
---|---|
Return type: | obj:`None’ |
psychopy.tools.gltools.
createMaterial
(params=(), textures=(), face=1032)¶Create a new material.
Parameters: | params (list of tuple , optional) – List of material modes and values. Each mode is assigned a value as
(mode, color). Modes can be GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR,
GL_EMISSION, GL_SHININESS or GL_AMBIENT_AND_DIFFUSE. Colors must be
a tuple of 4 floats which specify reflectance values for each RGBA
component. The value of GL_SHININESS should be a single float. If no
values are specified, an empty material will be created. |
---|
list
of tuple
, optional: List of texture units and TexImage2D descriptors. These will be writtenParameters: | face (int , optional) – Faces to apply material to. Values can be GL_FRONT_AND_BACK, GL_FRONT
and GL_BACK. The default is GL_FRONT_AND_BACK. |
---|---|
Returns: | A descriptor with material properties. |
Return type: | Material |
Examples
# The values for the material below can be found at # http://devernay.free.fr/cours/opengl/materials.html
# create a gold material gold = createMaterial([
(GL.GL_AMBIENT, (0.24725, 0.19950, 0.07450, 1.0)), (GL.GL_DIFFUSE, (0.75164, 0.60648, 0.22648, 1.0)), (GL.GL_SPECULAR, (0.628281, 0.555802, 0.366065, 1.0)), (GL.GL_SHININESS, 0.4 * 128.0)])
# use the material when drawing useMaterial(gold) drawVAO( … ) # all meshes will be gold useMaterial(None) # turn off material when done
# create a red plastic material, but define reflectance and shine later red_plastic = createMaterial()
# you need to convert values to ctypes! red_plastic.values[GL_AMBIENT] = (GLfloat * 4)(0.0, 0.0, 0.0, 1.0) red_plastic.values[GL_DIFFUSE] = (GLfloat * 4)(0.5, 0.0, 0.0, 1.0) red_plastic.values[GL_SPECULAR] = (GLfloat * 4)(0.7, 0.6, 0.6, 1.0) red_plastic.values[GL_SHININESS] = 0.25 * 128.0
# set and draw useMaterial(red_plastic) drawVertexbuffers( … ) # all meshes will be red plastic useMaterial(None)
psychopy.tools.gltools.
useMaterial
(material, useTextures=True)¶Use a material for proceeding vertex draws.
Parameters: |
|
---|---|
Returns: | |
Return type: |
Notes
Examples
# use the material when drawing useMaterial(metalMaterials.gold) drawVAO( … ) # all meshes drawn will be gold useMaterial(None) # turn off material when done
psychopy.tools.gltools.
createLight
(params=())¶Create a point light source.
psychopy.tools.gltools.
useLights
(lights, setupOnly=False)¶Use specified lights in successive rendering operations. All lights will be transformed using the present modelview matrix.
Parameters: |
|
---|---|
Returns: | |
Return type: |
psychopy.tools.gltools.
setAmbientLight
(color)¶Set the global ambient lighting for the scene when lighting is enabled. This is equivalent to GL.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, color) and does not contribute to the GL_MAX_LIGHTS limit.
Parameters: | color (tuple ) – Ambient lighting RGBA intensity for the whole scene. |
---|---|
Returns: | |
Return type: | None |
Notes
If unset, the default value is (0.2, 0.2, 0.2, 1.0) when GL_LIGHTING is enabled.
psychopy.tools.gltools.
loadObjFile
(objFile)¶Load a Wavefront OBJ file (*.obj).
Parameters: | objFile (str ) – Path to the *.OBJ file to load. |
---|---|
Returns: | |
Return type: | WavefrontObjModel |
Notes
Examples
# load a model from file objModel = loadObjFile(‘/path/to/file.obj’)
# load the material (*.mtl) file, textures are also loaded materials = loadMtl(‘/path/to/’ + objModel.mtlFile)
# apply settings GL.glEnable(GL.GL_CULL_FACE) GL.glEnable(GL.GL_DEPTH_TEST) GL.glDepthFunc(GL.GL_LEQUAL) GL.glDepthMask(GL.GL_TRUE) GL.glShadeModel(GL.GL_SMOOTH) GL.glCullFace(GL.GL_BACK) GL.glDisable(GL.GL_BLEND)
# lights useLights(light0)
# draw the model for group, vao in obj.drawGroups.items():
useMaterial(materials[group]) drawVAO(vao)
# disable materials and lights useMaterial(None) useLights(None)
psychopy.tools.gltools.
loadMtlFile
(mtlFilePath, texParameters=None)¶Load a material library (*.mtl).
psychopy.tools.gltools.
getIntegerv
(parName)¶Get a single integer parameter value, return it as a Python integer.
Parameters: | pName (:obj:`int’) – OpenGL property enum to query (e.g. GL_MAJOR_VERSION). |
---|---|
Returns: | |
Return type: | int |
psychopy.tools.gltools.
getFloatv
(parName)¶Get a single float parameter value, return it as a Python float.
Parameters: | pName (:obj:`float’) – OpenGL property enum to query. |
---|---|
Returns: | |
Return type: | int |
psychopy.tools.gltools.
getString
(parName)¶Get a single string parameter value, return it as a Python UTF-8 string.
Parameters: | pName (:obj:`int’) – OpenGL property enum to query (e.g. GL_VENDOR). |
---|---|
Returns: | |
Return type: | str |
psychopy.tools.gltools.
getOpenGLInfo
()¶Get general information about the OpenGL implementation on this machine. This should provide a consistent means of doing so regardless of the OpenGL interface we are using.
Returns are dictionary with the following fields:
vendor, renderer, version, majorVersion, minorVersion, doubleBuffer, maxTextureSize, stereo, maxSamples, extensions
Supported extensions are returned as a list in the ‘extensions’ field. You can check if a platform supports an extension by checking the membership of the extension name in that list.
Returns: | |
---|---|
Return type: | OpenGLInfo |
Working with Framebuffer Objects (FBOs):
Creating an empty framebuffer with no attachments:
fbo = createFBO() # invalid until attachments are added
Create a render target with multiple color texture attachments:
colorTex = createTexImage2D(1024,1024) # empty texture
depthRb = createRenderbuffer(800,600,internalFormat=GL.GL_DEPTH24_STENCIL8)
GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo.id)
attach(GL.GL_COLOR_ATTACHMENT0, colorTex)
attach(GL.GL_DEPTH_ATTACHMENT, depthRb)
attach(GL.GL_STENCIL_ATTACHMENT, depthRb)
# or attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb)
GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)
Attach FBO images using a context. This automatically returns to the previous FBO binding state when complete. This is useful if you don’t know the current binding state:
with useFBO(fbo):
attach(GL.GL_COLOR_ATTACHMENT0, colorTex)
attach(GL.GL_DEPTH_ATTACHMENT, depthRb)
attach(GL.GL_STENCIL_ATTACHMENT, depthRb)
How to set userData some custom function might access:
fbo.userData['flags'] = ['left_eye', 'clear_before_use']
Binding an FBO for drawing/reading:
GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb.id)
Depth-only framebuffers are valid, sometimes need for generating shadows:
depthTex = createTexImage2D(800, 600,
internalFormat=GL.GL_DEPTH_COMPONENT24,
pixelFormat=GL.GL_DEPTH_COMPONENT)
fbo = createFBO([(GL.GL_DEPTH_ATTACHMENT, depthTex)])
Deleting a framebuffer when done with it. This invalidates the framebuffer’s ID and makes it available for use:
deleteFBO(fbo)