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

First GLTensor draw was failing, because i was calling

GLSLShader.loadAtts before setting the vertex attribute divisor. Other
associated changes to initial refresh - it now occurs after all
eigenvector/value textures are ready.
parent ba1ea0b7
No related branches found
No related tags found
No related merge requests found
...@@ -60,6 +60,10 @@ import glvector_funcs ...@@ -60,6 +60,10 @@ import glvector_funcs
def init(self): def init(self):
"""Creates textures for the tensor eigenvalue and eigenvector images, """Creates textures for the tensor eigenvalue and eigenvector images,
and calls :func:`compileShaders` and :func:`updateShaderState`. and calls :func:`compileShaders` and :func:`updateShaderState`.
:returns: A list of ``Thread`` instances, one for each of the
:class:`.ImageTexture` instances that are created. See
the ``init`` parameter to :meth:`.GLVector.__init__`.
""" """
image = self.image image = self.image
...@@ -74,8 +78,9 @@ def init(self): ...@@ -74,8 +78,9 @@ def init(self):
def vPrefilter(d): def vPrefilter(d):
return d.transpose((3, 0, 1, 2)) return d.transpose((3, 0, 1, 2))
names = ['v1', 'v2', 'v3', 'l1', 'l2', 'l3'] names = ['v1', 'v2', 'v3', 'l1', 'l2', 'l3']
imgs = [ v1, v2, v3, l1, l2, l3] imgs = [ v1, v2, v3, l1, l2, l3]
texThreads = []
for name, img in zip(names, imgs): for name, img in zip(names, imgs):
texName = '{}_{}_{}'.format(type(self).__name__, name, id(img)) texName = '{}_{}_{}'.format(type(self).__name__, name, id(img))
...@@ -96,6 +101,8 @@ def init(self): ...@@ -96,6 +101,8 @@ def init(self):
normalise=True, normalise=True,
prefilter=prefilter) prefilter=prefilter)
texThreads.append(tex.refreshThread())
setattr(self, '{}Texture'.format(name), tex) setattr(self, '{}Texture'.format(name), tex)
self.shader = None self.shader = None
...@@ -103,6 +110,8 @@ def init(self): ...@@ -103,6 +110,8 @@ def init(self):
compileShaders(self) compileShaders(self)
updateShaderState(self) updateShaderState(self)
return texThreads
def destroy(self): def destroy(self):
"""Deletes the :class:`.GLSLShader`, and all textures. """ """Deletes the :class:`.GLSLShader`, and all textures. """
...@@ -262,10 +271,10 @@ def draw(self, zpos, xform=None): ...@@ -262,10 +271,10 @@ def draw(self, zpos, xform=None):
# Set divisor to 1, so we use one set of # Set divisor to 1, so we use one set of
# voxel coordinates for every sphere drawn # voxel coordinates for every sphere drawn
shader.loadAtts()
shader.setAtt('voxel', voxels, divisor=1) shader.setAtt('voxel', voxels, divisor=1)
shader.set( 'voxToDisplayMat', xform) shader.set( 'voxToDisplayMat', xform)
shader.loadAtts()
arbdi.glDrawElementsInstancedARB( arbdi.glDrawElementsInstancedARB(
gl.GL_QUADS, self.nVertices, gl.GL_UNSIGNED_INT, None, nVoxels) gl.GL_QUADS, self.nVertices, gl.GL_UNSIGNED_INT, None, nVoxels)
......
...@@ -131,8 +131,11 @@ class GLVector(globject.GLImageObject): ...@@ -131,8 +131,11 @@ class GLVector(globject.GLImageObject):
:arg init: An optional function to be called when all of the :arg init: An optional function to be called when all of the
:class:`.ImageTexture` instances associated with :class:`.ImageTexture` instances associated with
this ``GLVector`` have been initialised. this ``GLVector`` have been initialised. If this
function does any initialisation on one or more
separate threads, it should return references to
those threads so that this method is able to
determine when initialisation is complete.
""" """
if vectorImage is None: vectorImage = image if vectorImage is None: vectorImage = image
...@@ -177,9 +180,8 @@ class GLVector(globject.GLImageObject): ...@@ -177,9 +180,8 @@ class GLVector(globject.GLImageObject):
self.refreshColourTextures() self.refreshColourTextures()
def texRefresh(): def texRefresh():
if init is not None: if init is not None: async.wait(init(), self.notify)
init() else: self.notify()
self.notify()
async.wait([self.refreshImageTexture(), async.wait([self.refreshImageTexture(),
self.refreshAuxTexture('modulate'), self.refreshAuxTexture('modulate'),
......
...@@ -34,6 +34,7 @@ the task (via :func:`idle`). ...@@ -34,6 +34,7 @@ the task (via :func:`idle`).
import Queue import Queue
import logging import logging
import threading import threading
import collections
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -173,13 +174,17 @@ def wait(threads, task, *args, **kwargs): ...@@ -173,13 +174,17 @@ def wait(threads, task, *args, **kwargs):
If a ``wx.App`` is not running, this function ``join``s the threads If a ``wx.App`` is not running, this function ``join``s the threads
directly instead of creating a new ``Thread`` to do so. directly instead of creating a new ``Thread`` to do so.
:arg threads: A sequence of ``Thread`` instances to join. Elements in the :arg threads: A ``Thread``, or a sequence of ``Thread`` instances to
sequence may be ``None``. join. Elements in the sequence may be ``None``.
:arg task: The task to run. :arg task: The task to run.
All other arguments are passed to the ``task`` function. All other arguments are passed to the ``task`` function.
""" """
if not isinstance(threads, collections.Sequence):
threads = [threads]
haveWX = _haveWX() haveWX = _haveWX()
def joinAll(): def joinAll():
......
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