Skip to content
Snippets Groups Projects
Commit ea86c585 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Fixed canvas refresh issue on certain OpenGL implementations. Added GL

stuff to fsl.utils.platform
parent 1a5cff85
No related branches found
No related tags found
No related merge requests found
...@@ -187,9 +187,14 @@ package also contains the following: ...@@ -187,9 +187,14 @@ package also contains the following:
~fsl.fsleyes.gl.shaders ~fsl.fsleyes.gl.shaders
""" """
import logging
import logging
import platform
import os import os
import fsl.utils.async as async
import fsl.utils.platform as fslplatform
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -251,6 +256,9 @@ def bootstrap(glVersion=None): ...@@ -251,6 +256,9 @@ def bootstrap(glVersion=None):
``GL_VERSION`` A string containing the target OpenGL version, in ``GL_VERSION`` A string containing the target OpenGL version, in
the format ``major.minor``, e.g. ``2.1``. the format ``major.minor``, e.g. ``2.1``.
``GL_RENDERER`` A string containing the name of the OpenGL renderer.
``glvolume_funcs`` The version-specific module containing functions for ``glvolume_funcs`` The version-specific module containing functions for
rendering :class:`.GLVolume` instances. rendering :class:`.GLVolume` instances.
...@@ -269,6 +277,11 @@ def bootstrap(glVersion=None): ...@@ -269,6 +277,11 @@ def bootstrap(glVersion=None):
``gltensor_funcs`` The version-specific module containing functions for ``gltensor_funcs`` The version-specific module containing functions for
rendering :class:`.GLTensor` instances. rendering :class:`.GLTensor` instances.
====================== ==================================================== ====================== ====================================================
This function also sets the :attr:`.Platform.glVersion` and
:attr:`.Platform.glRenderer` properties of the
:attr:`fsl.utils.platform.platform` instance.
:arg glVersion: A tuple containing the desired (major, minor) OpenGL API :arg glVersion: A tuple containing the desired (major, minor) OpenGL API
...@@ -308,7 +321,6 @@ def bootstrap(glVersion=None): ...@@ -308,7 +321,6 @@ def bootstrap(glVersion=None):
# fall back to the gl14 implementation # fall back to the gl14 implementation
if glpkg == gl21: if glpkg == gl21:
# List any GL21 extensions here # List any GL21 extensions here
exts = ['GL_EXT_framebuffer_object', exts = ['GL_EXT_framebuffer_object',
'GL_ARB_instanced_arrays', 'GL_ARB_instanced_arrays',
...@@ -380,6 +392,7 @@ def bootstrap(glVersion=None): ...@@ -380,6 +392,7 @@ def bootstrap(glVersion=None):
except ValueError: pass except ValueError: pass
thismod.GL_VERSION = verstr thismod.GL_VERSION = verstr
thismod.GL_RENDERER = renderer
thismod.glvolume_funcs = glpkg.glvolume_funcs thismod.glvolume_funcs = glpkg.glvolume_funcs
thismod.glrgbvector_funcs = glpkg.glrgbvector_funcs thismod.glrgbvector_funcs = glpkg.glrgbvector_funcs
thismod.gllinevector_funcs = glpkg.gllinevector_funcs thismod.gllinevector_funcs = glpkg.gllinevector_funcs
...@@ -387,6 +400,9 @@ def bootstrap(glVersion=None): ...@@ -387,6 +400,9 @@ def bootstrap(glVersion=None):
thismod.gllabel_funcs = glpkg.gllabel_funcs thismod.gllabel_funcs = glpkg.gllabel_funcs
thismod.gltensor_funcs = glpkg.gltensor_funcs thismod.gltensor_funcs = glpkg.gltensor_funcs
thismod._bootstrapped = True thismod._bootstrapped = True
fslplatform.glVersion = thismod.GL_VERSION
fslplatform.glRenderer = thismod.GL_RENDERER
def getWXGLContext(parent=None): def getWXGLContext(parent=None):
...@@ -612,6 +628,25 @@ class WXGLCanvasTarget(object): ...@@ -612,6 +628,25 @@ class WXGLCanvasTarget(object):
self._glReady = False self._glReady = False
self.Bind(wx.EVT_PAINT, self._mainDraw) self.Bind(wx.EVT_PAINT, self._mainDraw)
# Using the Apple software renderer under OSX,
# we need to call refresh on the idle loop,
# otherwise refresh of multiple canvases (i.e.
# the OrthoPanel). gets all screwed up. Don't
# know why.
if platform.system() == 'Darwin' and \
'software' in fslplatform.glRenderer.lower():
def refresh(*a):
async.idle(self.Refresh)
# On other platforms/renderers,
# we can call Refresh directly
else:
def refresh(*a):
self.Refresh()
self._refresh = refresh
def _initGL(self): def _initGL(self):
...@@ -622,8 +657,12 @@ class WXGLCanvasTarget(object): ...@@ -622,8 +657,12 @@ class WXGLCanvasTarget(object):
def _draw(self, *a): def _draw(self, *a):
"""This method should implement the OpenGL drawing logic. Must be """This method should implement the OpenGL drawing logic - it must be
implemented by subclasses. implemented by subclasses.
.. note:: When runing with an on-screen display, this method should
never be called directly - call the :meth:`_refresh` method
instead.
""" """
raise NotImplementedError() raise NotImplementedError()
...@@ -670,9 +709,10 @@ class WXGLCanvasTarget(object): ...@@ -670,9 +709,10 @@ class WXGLCanvasTarget(object):
def _refresh(self, *a): def _refresh(self, *a):
"""Triggers a redraw via the :meth:`_draw` method.""" """Triggers a redraw via the :meth:`_draw` method.
self.Refresh()
.. note:: This method is dynamically assigned in :meth:`__init__`.
"""
def _postDraw(self): def _postDraw(self):
"""Called after the scene has been rendered. Swaps the front/back """Called after the scene has been rendered. Swaps the front/back
......
...@@ -208,13 +208,13 @@ class SliceCanvas(props.HasProperties): ...@@ -208,13 +208,13 @@ class SliceCanvas(props.HasProperties):
# when any of the properties of this # when any of the properties of this
# canvas change, we need to redraw # canvas change, we need to redraw
self.addListener('zax', self.name, self._zAxisChanged) self.addListener('zax', self.name, self._zAxisChanged)
self.addListener('pos', self.name, self._draw) self.addListener('pos', self.name, self._refresh)
self.addListener('displayBounds', self.name, self._draw) self.addListener('displayBounds', self.name, self._refresh)
self.addListener('bgColour', self.name, self._draw) self.addListener('bgColour', self.name, self._refresh)
self.addListener('cursorColour', self.name, self._draw) self.addListener('cursorColour', self.name, self._refresh)
self.addListener('showCursor', self.name, self._draw) self.addListener('showCursor', self.name, self._refresh)
self.addListener('invertX', self.name, self._draw) self.addListener('invertX', self.name, self._refresh)
self.addListener('invertY', self.name, self._draw) self.addListener('invertY', self.name, self._refresh)
self.addListener('zoom', self.name, self._zoomChanged) self.addListener('zoom', self.name, self._zoomChanged)
self.addListener('renderMode', self.name, self._renderModeChange) self.addListener('renderMode', self.name, self._renderModeChange)
self.addListener('resolutionLimit', self.addListener('resolutionLimit',
......
...@@ -60,12 +60,20 @@ class Platform(notifier.Notifier): ...@@ -60,12 +60,20 @@ class Platform(notifier.Notifier):
"""The ``Platform`` class contains a handful of properties which contain """The ``Platform`` class contains a handful of properties which contain
information about the platform we are running on. information about the platform we are running on.
.. note:: The values of the :attr:`glVersion` and :attr:`glRenderer`
properties are not automatically set - they will only contain
a value if one is assigned to them. The
:func:`fsl.fsleyes.gl.bootstrap` function does this when it is
first called.
.. autosummary:: .. autosummary::
fsldir fsldir
haveGui haveGui
wxBuild wxBuild
wxFlavour wxFlavour
glVersion
glRenderer
""" """
...@@ -77,6 +85,8 @@ class Platform(notifier.Notifier): ...@@ -77,6 +85,8 @@ class Platform(notifier.Notifier):
self.__haveGui = False self.__haveGui = False
self.__wxFlavour = None self.__wxFlavour = None
self.__wxPlatform = None self.__wxPlatform = None
self.__glVersion = None
self.__glRenderer = None
try: try:
import wx import wx
...@@ -151,6 +161,34 @@ class Platform(notifier.Notifier): ...@@ -151,6 +161,34 @@ class Platform(notifier.Notifier):
self.__fsldir = value self.__fsldir = value
self.notify() self.notify()
@property
def glVersion(self):
"""Returns the available OpenGL version, or ``None`` if it has not
been set.
"""
return self.__glVersion
@glVersion.setter
def glVersion(self, value):
"""Set the available OpenGL version. """
self.__glVersion = value
@property
def glRenderer(self):
"""Returns the available OpenGL renderer, or ``None`` if it has not
been set.
"""
return self.__glRenderer
@glRenderer.setter
def glRenderer(self, value):
"""Set the available OpenGL renderer. """
self.__glRenderer = value
platform = Platform() platform = Platform()
"""An instance of the :class:`Platform` class. Feel free to create your own """An instance of the :class:`Platform` class. Feel free to create your own
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment