Source code for ccpn.ui.gui.lib.OpenGL.CcpnOpenGLArrays

"""
GL routines used to draw vertex buffer objects (VBOs)
"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (http://www.ccpn.ac.uk) 2014 - 2021"
__credits__ = ("Ed Brooksbank, Luca Mureddu, Timothy J Ragan & Geerten W Vuister")
__licence__ = ("CCPN licence. See http://www.ccpn.ac.uk/v3-software/downloads/license")
__reference__ = ("Skinner, S.P., Fogh, R.H., Boucher, W., Ragan, T.J., Mureddu, L.G., & Vuister, G.W.",
                 "CcpNmr AnalysisAssign: a flexible platform for integrated NMR analysis",
                 "J.Biomol.Nmr (2016), 66, 111-124, http://doi.org/10.1007/s10858-016-0060-y")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: Ed Brooksbank $"
__dateModified__ = "$dateModified: 2021-03-09 19:13:27 +0000 (Tue, March 09, 2021) $"
__version__ = "$Revision: 3.0.3 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: Ed Brooksbank $"
__date__ = "$Date: 2018-12-20 13:28:13 +0000 (Thu, December 20, 2018) $"
#=========================================================================================
# Start of code
#=========================================================================================

import sys
from PyQt5 import QtWidgets
import numpy as np

from ccpn.ui.gui.lib.OpenGL import GL, GLU, GLUT, VBO


GLRENDERMODE_IGNORE = 0
GLRENDERMODE_DRAW = 1
GLRENDERMODE_RESCALE = 2
GLRENDERMODE_REBUILD = 3

GLREFRESHMODE_NEVER = 0
GLREFRESHMODE_ALWAYS = 1
GLREFRESHMODE_REBUILD = 2

VERTEX_PTR = 0
COLOR_PTR = 1
INDEX_PTR = 2
ATTRIB_PTR = 3
TEXT_PTR = 4


[docs]class GLVertexArray(): def __init__(self, numLists=1, renderMode=GLRENDERMODE_IGNORE, refreshMode=GLREFRESHMODE_NEVER, blendMode=False, drawMode=GL.GL_LINES, fillMode=None, dimension=3, GLContext=None, clearArrays=True): """Initialise the vertexArray properties :param numLists: deprecated, left over from original glLists, will remove soon :param renderMode: rendering type, flag used to determine when to rebuild, refresh or redraw the buffers :param refreshMode: currently not used :param blendMode: flag to specify whether solid or transparent :param drawMode: drawing mode as lines, polygons or filled :param fillMode: solid or wireframe :param dimension: number of axes required, currently 2 or 3d :param GLContext: pointer to the GL context :param clearArrays: flag to clear all arrays on initialise """ self.initialise(numLists=numLists, renderMode=renderMode, refreshMode=refreshMode, blendMode=blendMode, drawMode=drawMode, fillMode=fillMode, dimension=dimension, GLContext=GLContext, clearArrays=clearArrays)
[docs] def initialise(self, numLists=1, renderMode=GLRENDERMODE_IGNORE, refreshMode=GLREFRESHMODE_NEVER, blendMode=False, drawMode=GL.GL_LINES, fillMode=None, dimension=3, GLContext=None, clearArrays=True): """Initialise the vertexArray object. """ self._parent = GLContext self.renderMode = renderMode self.refreshMode = refreshMode if clearArrays: self.clearArrays() self.color = None self.posColours = None self.negColours = None self.numLists = numLists self.blendMode = blendMode self.drawMode = drawMode self.fillMode = fillMode self.dimension = int(dimension) self._GLContext = GLContext # VAO doesn't work on MacOS self.VAO = None self.VBOs = None
def __del__(self): """Delete vertex buffer objects on deletion """ if self.VBOs is not None: GL.glDeleteBuffers(len(self.VBOs), self.VBOs)
[docs] def clearArrays(self): """Clear and reset all arrays """ # set everything to 32 bit for openGL VBOs, indices are uint32s, everything else is float32 self.indices = np.array([], dtype=np.uint32) self.vertices = np.array([], dtype=np.float32) self.colors = np.array([], dtype=np.float32) self.texcoords = np.array([], dtype=np.float32) self.attribs = np.array([], dtype=np.float32) self.offsets = np.array([], dtype=np.float32) self.pids = np.array([], dtype=np.object_) self.numVertices = 0
[docs] def clearVertices(self): """Clear the vertex array only. """ self.vertices = np.array([], dtype=np.float32) self.numVertices = 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # indexed VBOs (vertex buffer objects) # Index array - Indices/Vertices/Colour #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[docs] def drawIndexArray(self): """Draw the vertex buffers in indexed array mode. Arrays are copied from main memory each time. Indexed with vertices and colour. """ # getLogger().info('>>> drawIndexArray') if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glColorPointer(4, GL.GL_FLOAT, 0, self.colors) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, self.indices) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def defineIndexVBO(self): """Define the buffers on the graphics card. Indexed mode with vertices and colour. If undefined, create new VBOs otherwise overwrite existing. Includes: vertices: (x, y) * vertices colors: (R, G, B, a) * vertices indices: array of indexes into vertex list _ attribs: array of float for defining aliasPosition """ # getLogger().info('>>> defineIndexVBO') # print("OpenGL: " + str(GL.glGetString(GL.GL_VERSION))) # print('glGenVertexArrays Available %s' % bool(GL.glGenVertexArrays)) # if not hasattr(self, 'VAOs'): # self.VAOs = GL.glGenVertexArrays(1) # GL.glBindVertexArray(self.VAOs) # define VAOs - doesn't work MacOS # create the VBOs if they don't exist - reusing will just rewrite the buffers if self.VBOs is None: self.VBOs = GL.glGenBuffers(5) self._defineIndexVBO()
def _defineIndexVBO(self): """Push Indices/Colours/Vertices to graphics card """ sizeVertices = self.vertices.size * self.vertices.itemsize sizeColors = self.colors.size * self.colors.itemsize sizeIndices = self.indices.size * self.indices.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeVertices, self.vertices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeColors, self.colors, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, sizeIndices, self.indices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
[docs] def updateIndexVBO(self): """Update the buffers on the graphics card. Indexed mode with vertices and colour. """ # getLogger().info('>>> updateIndexVBO') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update indexVBO: %s' % self) self._defineIndexVBO()
[docs] def updateIndexVBOIndices(self): """Update the buffers on the graphics card. Only the index array. """ # getLogger().info('>>> updateIndexVBOIndices') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update indexArray: %s' % self) sizeIndices = self.indices.size * self.indices.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, sizeIndices, self.indices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0)
[docs] def drawIndexVBO(self): """Draw the vertex buffers in indexed array mode. Arrays are drawn from buffers already bound to graphics card memory. Indexed mode with vertices and colour. """ # getLogger().info('>>> drawIndexVBO') if not self.indices.size: return if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot draw IndexVBO: %s' % self) if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glColorPointer(4, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def drawIndexArrayNoColor(self): """Draw the vertex buffers in indexed array mode. Arrays are copied from main memory each time. Indexed mode using only vertices, no colour. """ # getLogger().info('>>>drawIndexArrayNoColor') if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, self.indices) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # indexed VBOs (vertex buffer objects) # Index array - Indices/Vertices/Colour/attribs #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[docs] def defineAliasedIndexVBO(self): """Define the buffers on the graphics card. Indexed mode with vertices and colour. If undefined, create new VBOs otherwise overwrite existing. Includes: vertices: (x, y) * vertices colors: (R, G, B, a) * vertices indices: array of indexes into vertex list _ attribs: array of float for defining aliasPosition """ # getLogger().info('>>> defineIndexVBO') # print("OpenGL: " + str(GL.glGetString(GL.GL_VERSION))) # print('glGenVertexArrays Available %s' % bool(GL.glGenVertexArrays)) # if not hasattr(self, 'VAOs'): # self.VAOs = GL.glGenVertexArrays(1) # GL.glBindVertexArray(self.VAOs) # define VAOs - doesn't work MacOS # create the VBOs if they don't exist - reusing will just rewrite the buffers if self.VBOs is None: self.VBOs = GL.glGenBuffers(5) self._defineAliasedIndexVBO()
def _defineAliasedIndexVBO(self): """Push Indices/Colours/Vertices/attribs to graphics card """ sizeVertices = self.vertices.size * self.vertices.itemsize sizeColors = self.colors.size * self.colors.itemsize sizeIndices = self.indices.size * self.indices.itemsize sizeAttribs = self.attribs.size * self.attribs.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeVertices, self.vertices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeColors, self.colors, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, sizeIndices, self.indices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[ATTRIB_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeAttribs, self.attribs, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
[docs] def updateAliasedIndexVBO(self): """Update the buffers on the graphics card. Indexed mode with vertices and colour. """ # getLogger().info('>>> updateIndexVBO') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update indexVBO: %s' % self) self._defineAliasedIndexVBO()
[docs] def updateAliasedIndexVBOIndices(self): """Update the buffers on the graphics card. Only the index array. """ # getLogger().info('>>> updateIndexVBOIndices') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update indexArray: %s' % self) sizeIndices = self.indices.size * self.indices.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, sizeIndices, self.indices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0)
[docs] def drawAliasedIndexVBO(self): """Draw the vertex buffers in indexed array mode. Arrays are drawn from buffers already bound to graphics card memory. Indexed mode with vertices and colour. """ # getLogger().info('>>> drawIndexVBO') if not self.indices.size: return if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot draw IndexVBO: %s' % self) if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glEnableVertexAttribArray(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glColorPointer(4, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[ATTRIB_PTR]) GL.glVertexAttribPointer(1, 1, GL.GL_FLOAT, GL.GL_FALSE, 0, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) GL.glDisableVertexAttribArray(1) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def drawAliasedIndexArrayNoColor(self): """Draw the vertex buffers in indexed array mode. Arrays are copied from main memory each time. Indexed mode using only vertices, no colour. """ # getLogger().info('>>>drawIndexArrayNoColor') if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, self.indices) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Vertex/Colour array #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[docs] def drawVertexColor(self): """Draw the vertex buffers in direct array mode. Arrays are copied from main memory each time. Only vertices and colour required. """ # getLogger().info('>>> drawVertexColor') if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glColorPointer(4, GL.GL_FLOAT, 0, self.colors) GL.glDrawArrays(self.drawMode, 0, self.numVertices) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def defineVertexColorVBO(self): """Define the buffers on the graphics card. Not indexed mode with vertices and colour. If undefined, create new VBOs otherwise overwrite existing. Includes: vertices: (x, y) * vertices colors: (R, G, B, a) * vertices """ # getLogger().info('>>> defineVertexColorVBO') # print("OpenGL: " + str(GL.glGetString(GL.GL_VERSION))) # print('glGenVertexArrays Available %s' % bool(GL.glGenVertexArrays)) # if not hasattr(self, 'VAOs'): # self.VAOs = GL.glGenVertexArrays(1) # GL.glBindVertexArray(self.VAOs) # define VAOs - doesn't work MacOS # create the VBOs if they don't exist - reusing will just rewrite the buffers if self.VBOs is None: self.VBOs = GL.glGenBuffers(2) self._defineVertexColorVBO()
def _defineVertexColorVBO(self): """Push Colours/Vertices to graphics card """ # getLogger().info('>>> _defineVertexColorVBO') sizeVertices = self.vertices.size * self.vertices.itemsize sizeColors = self.colors.size * self.colors.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeVertices, self.vertices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeColors, self.colors, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
[docs] def updateVertexColorVBO(self): """Update the buffers on the graphics card. Direct mode with vertices and colour. """ # getLogger().info('>>> updateVertexColorVBO') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update vertexColorArray: %s' % self) self._defineVertexColorVBO()
[docs] def drawVertexColorVBO(self): """Draw the vertex buffers in direct array mode. Arrays are drawn from buffers already bound to graphics card memory. Only vertices and colour required. """ # getLogger().info('>>> drawVertexColorVBO') if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot draw VertexColorVBO: %s' % self) if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glColorPointer(4, GL.GL_FLOAT, 0, None) GL.glDrawArrays(self.drawMode, 0, self.numVertices) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def drawVertexNoColor(self): """Draw the vertex buffers in direct array mode. Arrays are copied from main memory each time. Only vertices are required. """ # getLogger().info('>>> drawVertexNoColor') if self.blendMode: GL.glEnable(GL.GL_BLEND) if self.fillMode is not None: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, self.fillMode) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glDrawArrays(self.drawMode, 0, self.numVertices) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) if self.blendMode: GL.glDisable(GL.GL_BLEND)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # indexed VBOs (vertex buffer objects) # Index text array - Indices/Vertices/Colour/Texture Co-ordinates/Attributes #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[docs] def drawTextArray(self): """Draw the texture buffers in indexed array mode. Arrays are copied from main memory each time. Facilitates drawing of fonts. """ # getLogger().info('>>> drawTextArray') if self.blendMode: GL.glEnable(GL.GL_BLEND) GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, self.vertices) GL.glColorPointer(4, GL.GL_FLOAT, 0, self.colors) GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, self.texcoords) # this is for passing extra attributes in GL.glEnableVertexAttribArray(1) GL.glVertexAttribPointer(1, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, self.attribs) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, self.indices) GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) GL.glDisableVertexAttribArray(1) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs] def defineTextArrayVBO(self): """Define the buffers on the graphics card. Indexed mode with vertices/colours/texture co-ordinates/attribs. If undefined, create new VBOs otherwise overwrite existing. Includes: vertices: (x, y) * vertices colors: (R, G, B, a) * vertices indices: array of indexes into vertex list texcoords (u, v) * vertices attribs (a, b) * vertices """ # create the VBOs if they don't exist - reusing will just rewrite the buffers if self.VBOs is None: self.VBOs = GL.glGenBuffers(5) self._defineTextArrayVBO()
def _defineTextArrayVBO(self): """Push vertices/colours/texture co-ordinates/attribs/indices to graphics card """ # getLogger().info('>>> _defineTextArrayVBO') sizeVertices = self.vertices.size * self.vertices.itemsize sizeColors = self.colors.size * self.colors.itemsize sizeText = self.texcoords.size * self.texcoords.itemsize sizeAttribs = self.attribs.size * self.attribs.itemsize sizeIndices = self.indices.size * self.indices.itemsize # bind to the buffers GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeVertices, self.vertices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeColors, self.colors, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[TEXT_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeText, self.texcoords, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[ATTRIB_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeAttribs, self.attribs, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, sizeIndices, self.indices, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
[docs] def updateTextArrayVBO(self): """Update the buffers on the graphics card. Indexed mode with vertices, colour, texture and attributes. """ # getLogger().info('>>> updateTextArrayVBO') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update textArrayVBO: %s' % self) self._defineTextArrayVBO()
[docs] def updateTextArrayVBOAttribs(self): """Update the buffers on the graphics card. Only update the attributes used for moving text. """ # getLogger().info('>>> updateTextArrayVBOAttribs') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update textArrayVBOAttribs: %s' % self) sizeAttribs = self.attribs.size * self.attribs.itemsize GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[ATTRIB_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeAttribs, self.attribs, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
[docs] def updateTextArrayVBOColour(self): """Update the buffers on the graphics card. Only update the colour, used for highlighting text. """ # getLogger().info('>>> updateTextArrayVBOColour') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot update textArrayVBOColour: %s' % self) sizeColors = self.colors.size * self.colors.itemsize GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glBufferData(GL.GL_ARRAY_BUFFER, sizeColors, self.colors, GL.GL_DYNAMIC_DRAW) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
# def enableTextClientState(self): # _attribArrayIndex = 1 # GL.glEnableClientState(GL.GL_VERTEX_ARRAY) # GL.glEnableClientState(GL.GL_COLOR_ARRAY) # GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY) # GL.glEnableVertexAttribArray(_attribArrayIndex) # # def disableTextClientState(self): # _attribArrayIndex = 1 # GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY) # GL.glDisableClientState(GL.GL_VERTEX_ARRAY) # GL.glDisableClientState(GL.GL_COLOR_ARRAY) # GL.glDisableVertexAttribArray(_attribArrayIndex)
[docs] def drawTextArrayVBO(self, enableClientState=False, disableClientState=False): """Draw the texture buffers in indexed array mode. Arrays are drawn from buffers already bound to graphics card memory. Indexed mode with vertices, colour, texture and attributes. """ # getLogger().info('>>> drawTextArrayVBO') # check the VBOs, if they don't exist raise error if self.VBOs is None: raise RuntimeError('OpenGL Error: cannot drawTextArrayVBO: %s' % self) if self.blendMode: GL.glEnable(GL.GL_BLEND) _attribArrayIndex = 1 if enableClientState: GL.glEnableClientState(GL.GL_VERTEX_ARRAY) GL.glEnableClientState(GL.GL_COLOR_ARRAY) GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY) GL.glEnableVertexAttribArray(_attribArrayIndex) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[VERTEX_PTR]) GL.glVertexPointer(self.dimension, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[COLOR_PTR]) GL.glColorPointer(4, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[TEXT_PTR]) GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, None) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBOs[ATTRIB_PTR]) GL.glVertexAttribPointer(_attribArrayIndex, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.VBOs[INDEX_PTR]) GL.glDrawElements(self.drawMode, len(self.indices), GL.GL_UNSIGNED_INT, None) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) if disableClientState: GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY) GL.glDisableClientState(GL.GL_VERTEX_ARRAY) GL.glDisableClientState(GL.GL_COLOR_ARRAY) GL.glDisableVertexAttribArray(_attribArrayIndex) if self.blendMode: GL.glDisable(GL.GL_BLEND)
[docs]class GLSymbolArray(GLVertexArray): """ Array class to handle symbols. """ def __init__(self, GLContext=None, spectrumView=None, objListView=None): super(GLSymbolArray, self).__init__(renderMode=GLRENDERMODE_REBUILD, blendMode=False, drawMode=GL.GL_LINES, dimension=2, GLContext=GLContext) self.spectrumView = spectrumView self.objListView = objListView
[docs]class GLLabelArray(GLVertexArray): """ Array class to handle labels. """ def __init__(self, GLContext=None, spectrumView=None, objListView=None): super(GLLabelArray, self).__init__(renderMode=GLRENDERMODE_REBUILD, blendMode=False, drawMode=GL.GL_LINES, dimension=2, GLContext=GLContext) self.spectrumView = spectrumView self.objListView = objListView self.stringList = []