2012-10-19 03:18:20 +00:00
|
|
|
from OpenGL.GL import *
|
|
|
|
from .. GLGraphicsItem import GLGraphicsItem
|
2013-12-23 14:46:54 +00:00
|
|
|
from ...Qt import QtGui
|
2012-10-19 03:18:20 +00:00
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
__all__ = ['GLImageItem']
|
|
|
|
|
|
|
|
class GLImageItem(GLGraphicsItem):
|
|
|
|
"""
|
|
|
|
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
|
|
|
|
|
|
|
Displays image data as a textured quad.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2013-04-07 13:16:21 +00:00
|
|
|
def __init__(self, data, smooth=False, glOptions='translucent'):
|
2012-10-19 03:18:20 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
============== =======================================================================================
|
|
|
|
**Arguments:**
|
|
|
|
data Volume data to be rendered. *Must* be 3D numpy array (x, y, RGBA) with dtype=ubyte.
|
|
|
|
(See functions.makeRGBA)
|
|
|
|
smooth (bool) If True, the volume slices are rendered with linear interpolation
|
|
|
|
============== =======================================================================================
|
|
|
|
"""
|
|
|
|
|
|
|
|
self.smooth = smooth
|
2014-07-06 15:44:26 +00:00
|
|
|
self._needUpdate = False
|
2012-10-19 03:18:20 +00:00
|
|
|
GLGraphicsItem.__init__(self)
|
2014-07-06 15:44:26 +00:00
|
|
|
self.setData(data)
|
2013-04-07 13:16:21 +00:00
|
|
|
self.setGLOptions(glOptions)
|
2012-10-19 03:18:20 +00:00
|
|
|
|
|
|
|
def initializeGL(self):
|
|
|
|
glEnable(GL_TEXTURE_2D)
|
|
|
|
self.texture = glGenTextures(1)
|
2014-07-06 15:44:26 +00:00
|
|
|
|
|
|
|
def setData(self, data):
|
|
|
|
self.data = data
|
|
|
|
self._needUpdate = True
|
|
|
|
self.update()
|
|
|
|
|
|
|
|
def _updateTexture(self):
|
2012-10-19 03:18:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, self.texture)
|
|
|
|
if self.smooth:
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
|
|
|
else:
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
|
|
|
|
#glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER)
|
|
|
|
shape = self.data.shape
|
|
|
|
|
|
|
|
## Test texture dimensions first
|
|
|
|
glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
|
|
|
|
if glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) == 0:
|
|
|
|
raise Exception("OpenGL failed to create 2D texture (%dx%d); too large for this hardware." % shape[:2])
|
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, self.data.transpose((1,0,2)))
|
|
|
|
glDisable(GL_TEXTURE_2D)
|
|
|
|
|
|
|
|
#self.lists = {}
|
|
|
|
#for ax in [0,1,2]:
|
|
|
|
#for d in [-1, 1]:
|
|
|
|
#l = glGenLists(1)
|
|
|
|
#self.lists[(ax,d)] = l
|
|
|
|
#glNewList(l, GL_COMPILE)
|
|
|
|
#self.drawVolume(ax, d)
|
|
|
|
#glEndList()
|
|
|
|
|
|
|
|
|
|
|
|
def paint(self):
|
2014-07-06 15:44:26 +00:00
|
|
|
if self._needUpdate:
|
|
|
|
self._updateTexture()
|
2012-10-19 03:18:20 +00:00
|
|
|
glEnable(GL_TEXTURE_2D)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, self.texture)
|
|
|
|
|
2013-04-07 13:16:21 +00:00
|
|
|
self.setupGLState()
|
|
|
|
|
|
|
|
#glEnable(GL_DEPTH_TEST)
|
|
|
|
##glDisable(GL_CULL_FACE)
|
|
|
|
#glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
|
|
#glEnable( GL_BLEND )
|
|
|
|
#glEnable( GL_ALPHA_TEST )
|
2012-10-19 03:18:20 +00:00
|
|
|
glColor4f(1,1,1,1)
|
|
|
|
|
|
|
|
glBegin(GL_QUADS)
|
|
|
|
glTexCoord2f(0,0)
|
|
|
|
glVertex3f(0,0,0)
|
|
|
|
glTexCoord2f(1,0)
|
|
|
|
glVertex3f(self.data.shape[0], 0, 0)
|
|
|
|
glTexCoord2f(1,1)
|
|
|
|
glVertex3f(self.data.shape[0], self.data.shape[1], 0)
|
|
|
|
glTexCoord2f(0,1)
|
|
|
|
glVertex3f(0, self.data.shape[1], 0)
|
|
|
|
glEnd()
|
|
|
|
glDisable(GL_TEXTURE_3D)
|
|
|
|
|