def __refreshTexture(self, tex, idx):
        """Refreshes the given :class:`.RenderTexture`.

        :arg tex: The ``RenderTexture`` to refresh.
        :arg idx: Index of the ``RenderTexture``.
        """

        globj = self.__globj
        zpos  = self.__indexToZpos(idx)
        xax   = self.__xax
        yax   = self.__yax
        axes  = (self.__xax, self.__yax, self.__zax)

        if not globj.ready():
            return

        lo, hi = globj.getDisplayBounds()
        res    = globj.getDataResolution(xax, yax)

        if res is not None:
            width  = res[xax]
            height = res[yax]
        else:
            width  = self.__defaultWidth
            height = self.__defaultHeight

        if width  > self.__maxWidth:  width  = self.__maxWidth
        if height > self.__maxHeight: height = self.__maxHeight

        log.debug('Refreshing render texture for slice {} (zpos {}, '
                  'zax {}): {} x {}'.format(idx, zpos, self.__zax,
                                            width, height))

        tex.setSize(width, height)

        oldSize       = gl.glGetIntegerv(gl.GL_VIEWPORT)
        oldProjMat    = gl.glGetFloatv(  gl.GL_PROJECTION_MATRIX)
        oldMVMat      = gl.glGetFloatv(  gl.GL_MODELVIEW_MATRIX)

        tex.bindAsRenderTarget()
        glroutines.show2D(xax, yax, width, height, lo, hi)
        glroutines.clear((0, 0, 0, 0))

        with glroutines.disabled(gl.GL_BLEND):
            globj.preDraw()
            globj.draw2D(zpos, axes)
            globj.postDraw()

        tex.unbindAsRenderTarget()

        gl.glViewport(*oldSize)
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadMatrixf(oldProjMat)
        gl.glMatrixMode(gl.GL_MODELVIEW)
        gl.glLoadMatrixf(oldMVMat)

        self.__textureDirty[idx] = False
Example #2
0
    def _draw(self):
        """Draws the scene to the canvas. """

        if not self._setGLContext():
            return

        opts = self.opts
        glroutines.clear(opts.bgColour)

        if not self.__setViewport():
            return

        overlays, globjs = self.getGLObjects()

        if len(overlays) == 0:
            return

        # If occlusion is on, we offset the
        # depth of each overlay so that, where
        # a depth collision occurs, overlays
        # which are higher in the list will get
        # drawn above (closer to the screen)
        # than lower ones.
        depthOffset = transform.scaleOffsetXform(1, [0, 0, 0.1])
        depthOffset = np.array(depthOffset, dtype=np.float32, copy=False)
        xform = np.array(self.__viewMat, dtype=np.float32, copy=False)

        for ovl, globj in zip(overlays, globjs):

            display = self.__displayCtx.getDisplay(ovl)

            if not globj.ready():
                continue
            if not display.enabled:
                continue

            if opts.occlusion:
                xform = transform.concat(depthOffset, xform)
            elif isinstance(ovl, fslimage.Image):
                gl.glClear(gl.GL_DEPTH_BUFFER_BIT)

            log.debug('Drawing {} [{}]'.format(ovl, globj))

            globj.preDraw(xform=xform)
            globj.draw3D(xform=xform)
            globj.postDraw(xform=xform)

        if opts.showCursor:
            with glroutines.enabled((gl.GL_DEPTH_TEST)):
                self.__drawCursor()

        if opts.showLegend:
            self.__drawLegend()
Example #3
0
    def _draw(self, *a):
        """Draws the current scene to the canvas. """

        if self.destroyed:
            return

        width, height = self.GetSize()
        if width == 0 or height == 0:
            return

        if not self._setGLContext():
            return

        opts = self.opts
        axes = (opts.xax, opts.yax, opts.zax)

        overlays, globjs = self._getGLObjects()

        # See comment in SliceCanvas._draw
        # regarding this test
        if any([not g.ready() for g in globjs]):
            return

        if opts.renderMode == 'offscreen':

            log.debug('Rendering to off-screen texture')

            rt = self._offscreenRenderTexture

            lo = [None] * 3
            hi = [None] * 3

            lo[opts.xax], hi[opts.xax] = opts.displayBounds.x
            lo[opts.yax], hi[opts.yax] = opts.displayBounds.y
            lo[opts.zax], hi[opts.zax] = opts.zrange

            rt.bindAsRenderTarget()
            rt.setRenderViewport(opts.xax, opts.yax, lo, hi)
            glroutines.clear((0, 0, 0, 0))

        else:
            self._setViewport(invertX=False, invertY=False)
            glroutines.clear(opts.bgColour)

        startSlice = opts.ncols * opts.topRow
        endSlice = startSlice + opts.nrows * opts.ncols

        if endSlice > self._nslices:
            endSlice = self._nslices

        # Draw all the slices for all the overlays.
        for overlay, globj in zip(overlays, globjs):

            display = self.displayCtx.getDisplay(overlay)
            globj = self._glObjects.get(overlay, None)

            if not display.enabled:
                continue

            log.debug('Drawing {} slices ({} - {}) for '
                      'overlay {} directly to canvas'.format(
                          endSlice - startSlice, startSlice, endSlice,
                          overlay))

            zposes = self._sliceLocs[overlay][startSlice:endSlice]
            xforms = self._transforms[overlay][startSlice:endSlice]
            xforms = self.__prepareSliceTransforms(globj, xforms)

            if opts.renderMode == 'prerender':
                rt, name = self._prerenderTextures.get(overlay, (None, None))

                if rt is None:
                    continue

                log.debug('Drawing {} slices ({} - {}) for overlay {} '
                          'from pre-rendered texture'.format(
                              endSlice - startSlice, startSlice, endSlice,
                              overlay))

                for zpos, xform in zip(zposes, xforms):
                    rt.draw(zpos, xform)
            else:

                globj.preDraw()
                globj.drawAll(axes, zposes, xforms)
                globj.postDraw()

        if opts.renderMode == 'offscreen':
            rt.unbindAsRenderTarget()
            rt.restoreViewport()
            self._setViewport(invertX=False, invertY=False)
            glroutines.clear(opts.bgColour)
            rt.drawOnBounds(0, opts.displayBounds.xlo, opts.displayBounds.xhi,
                            opts.displayBounds.ylo, opts.displayBounds.yHi,
                            opts.xax, opts.yax)

        if len(self.overlayList) > 0:
            if opts.showCursor: self._drawCursor()
            if opts.showGridLines: self._drawGridLines()
            if opts.highlightSlice: self._drawSliceHighlight()

        self.getAnnotations().draw(opts.pos[opts.zax])
Example #4
0
    def _draw(self):
        """Draws the scene to the canvas. """

        if self.destroyed:
            return

        if not self._setGLContext():
            return

        opts = self.opts
        glroutines.clear(opts.bgColour)

        if not self.__setViewport():
            return

        overlays, globjs = self.getGLObjects()

        if len(overlays) == 0:
            return

        # If occlusion is on, we offset the
        # depth of each overlay so that, where
        # a depth collision occurs, overlays
        # which are higher in the list will get
        # drawn above (closer to the screen)
        # than lower ones.
        depthOffset = affine.scaleOffsetXform(1, [0, 0, 0.1])
        depthOffset = np.array(depthOffset, dtype=np.float32, copy=False)
        xform = np.array(self.__viewMat, dtype=np.float32, copy=False)

        for ovl, globj in zip(overlays, globjs):

            display = self.__displayCtx.getDisplay(ovl)

            if not globj.ready():
                continue
            if not display.enabled:
                continue

            if opts.occlusion:
                xform = affine.concat(depthOffset, xform)
            elif isinstance(ovl, fslimage.Image):
                gl.glClear(gl.GL_DEPTH_BUFFER_BIT)

            log.debug('Drawing {} [{}]'.format(ovl, globj))

            globj.preDraw(xform=xform)
            globj.draw3D(xform=xform)
            globj.postDraw(xform=xform)

        if opts.showCursor:
            with glroutines.enabled((gl.GL_DEPTH_TEST)):
                self.__drawCursor()

        if opts.showLegend:
            self.__drawLegend()

        if opts.showLight:
            self.__drawLight()

        # Testing click-to-near/far clipping plane transformation
        if hasattr(self, 'points'):
            colours = [(1, 0, 0, 1), (0, 0, 1, 1)]
            gl.glPointSize(5)

            gl.glBegin(gl.GL_LINES)
            for i, p in enumerate(self.points):
                gl.glColor4f(*colours[i % 2])
                p = affine.transform(p, self.viewMatrix)
                gl.glVertex3f(*p)
            gl.glEnd()