Example #1
0
class LogShader(object):
    '''
    Simple shader to project images in log space
    '''
    def __init__(self, shaderName="LogBuffer"):
        '''
        Constructor
        '''
        #self._incShader = 0
        self._logShader = 0
        self._shaderName = shaderName
        self._recalcMaxMin = 0  # Counter to recalculate max/min
        self._logmin = -16.5  # = ln(1e-7)
        self._invlogrng = 0.1  # arbitrary guess
        self._prepared = False  # Has the shader been initialised?
        self._preloaded = False  # Have we found the min/max value of the image?
        self._reduction = None  # Reduction shader for calculating min/max
        self._frameBuffer = None

    # Do this when the program is loaded
    def Init(self, frameBuffer):

        if not self._prepared:
            self._frameBuffer = frameBuffer
            # Set up shaders
            #self._incShader = Shader("IncrementBuffer")
            self._logShader = Shader(self._shaderName)
            size = max(self._frameBuffer.Width(), self._frameBuffer.Height())
            size = 2.0**int(np.log2(size) + 1)
            self._reduction = ReductionShader(self._frameBuffer.Texture(),
                                              size, ["ReduceMaxMin"])

            self._prepared = True

    # Do this before the objects are rendered
    def Begin(self):

        # Reduce the image
        # Get the max/min value in the texture to pass to the shader
        self._recalcMaxMin -= 1
        properScale = self._recalcMaxMin <= 0
        # HACK - turn off properscale counter; turn back on if it runs slowly
        properScale = True  # HACK - always run
        if properScale:
            reduce = self._reduction.Run()
            maxval = reduce[0, 0]
            minval = reduce[0, 1]
            if minval == maxval:
                dmin = 0.0
                dmax = 0.0
                invrng = 1.0
            else:
                dmin = float(np.log(minval))
                dmax = float(np.log(maxval))
                try:
                    invrng = 1.0 / (dmax - dmin)
                except:
                    invrng = 1.0
                self._logmin = dmin
                self._invlogrng = invrng
            self._recalcMaxMin = 10

        # Reset view
        x, y = self._frameBuffer.Pos()
        width = self._frameBuffer.Width()
        height = self._frameBuffer.Height()
        glViewport(x, y, width, height)

        self._logShader.Bind()
        self._logShader.AddFloat(self._logmin, "texmin")
        self._logShader.AddFloat(self._invlogrng, "texinvrng")

    # Do this after the objects are rendered
    def End(self):
        self._logShader.Unbind()

    def Reset(self):
        '''
        Reset the shader; make it run the pre-load operation again
        '''
        self._preloaded = False
Example #2
0
class ColourShader(object):
    '''
    Simple shader to project images in log space
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self._x, self._y = (0, 0)
        self._width, self._height = (0, 0)
        self._depth = 0  #ctypes.c_int(0)
        self._frame = 0  #ctypes.c_int(0)
        self._texture = 0  #ctypes.c_int(0)
        self._image = 0
        self._incShader = 0
        self._logShader = 0
        self._recalcMaxMin = 0  # Counter to recalculate max/min
        self._logmin = -16.11  # = ln(1e-7)
        self._invlogrng = 0.135  # Arbitrary value
        self._prepared = False
        self._reduction = None  # Reduction shader for calculating min/max

    def ViewPos(self, x, y):
        '''
        Set the view position of the outputted shader
        '''
        self._x = x
        self._y = y

    # Do this when the program is loaded
    def Init(self, display):

        if not self._prepared:
            # Set up image
            self._width, self._height = display.Window().get_size()
            # Set up empty texture to draw to
            #self._texture = glGenTextures(1)
            self._texture = ctypes.c_uint(0)
            glGenTextures(1, self._texture)
            #self._texture = pyglet.image.Texture.create(self._width, self._height, rectangle=True,internalformat=GL_RGBA32F_ARB)

            glEnable(GL_TEXTURE_2D)
            glBindTexture(GL_TEXTURE_2D, self._texture)
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
            #glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

            glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
            glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
            glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
            #glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, self._width, self._height, 0,\
            # GL_RGBA, GL_FLOAT, 0)
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, self._width, self._height, 0,\
             GL_RGBA, GL_FLOAT, 0)
            glBindTexture(GL_TEXTURE_2D, 0)

            # Set up the frame buffer object
            self._frame = ctypes.c_uint(0)
            glGenFramebuffers(1, self._frame)
            #self._frame = glGenFramebuffers(1)
            glBindFramebuffer(GL_FRAMEBUFFER, self._frame)

            # Set up the depth buffer
            #self._depth = glGenRenderbuffers(1)
            self._depth = ctypes.c_uint(0)
            glGenRenderbuffers(1, self._depth)
            glBindRenderbuffer(GL_RENDERBUFFER, self._depth)

            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
                                  self._width, self._height)
            glBindRenderbuffer(GL_RENDERBUFFER, 0)

            # Attach texture and depth buffer
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                   GL_TEXTURE_2D, self._texture,
                                   ctypes.c_int(0))
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                      GL_RENDERBUFFER, self._depth)

            # Unbind frame buffer for now
            glBindFramebuffer(GL_FRAMEBUFFER, 0)

            status = glCheckFramebufferStatus(GL_FRAMEBUFFER)

            # Create shaders
            self._incShader = Shader("IncrementBuffer")
            self._logShader = Shader("LogBuffer")
            self._reduction = ReductionShader(self._texture,
                                              max(self._width, self._height),
                                              ["ReduceMaxMin"])

            self._prepared = True

        # Pass everything through since we want to make a projected density map
        glEnable(GL_BLEND)
        glBlendFunc(GL_ONE, GL_ONE)

    # Do this before the objects are rendered
    def Begin(self, display):

        # Re-bind frame buffer
        glBindFramebuffer(GL_FRAMEBUFFER, self._frame)

        # Clear frame buffer
        glClearColor(0, 0, 0, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glDisable(GL_TEXTURE_2D)
        glDisable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_ONE, GL_ONE)
        #self._incShader.Bind()
        # At this point we draw...

    # Do this after the objects are rendered
    def End(self, display):
        # Take out the shader currently in use
        #self._incShader.Unbind()
        # Unbind frame buffer
        glBindFramebuffer(GL_FRAMEBUFFER, 0)
        # TEST REDUCTION
        reduce = self._reduction.Run()
        maxval = reduce[0, 0]
        minval = reduce[0, 1]
        # Get the max/min value in the texture to pass to the shader
        self._recalcMaxMin -= 1
        properScale = self._recalcMaxMin <= 0
        properScale = True
        if properScale:
            #data = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT)
            #red = data[:,:,0]
            #minval = np.min(red[np.nonzero(red)])
            #maxval = np.max(red)
            if minval == maxval:
                dmin = 0.0
                dmax = 0.0
                invrng = 1.0
            else:
                dmin = float(np.log(minval))
                dmax = float(np.log(maxval))
                #dmin = dmax - 10.0
                try:
                    invrng = 1.0 / (dmax - dmin)
                except:
                    invrng = 1.0
            #print "Image min, range, max:", dmin, 1.0/invrng, dmax
            #newrng = np.min([10.0,1.0/invrng]) # HACK - stops weird hard circle effect
            #dmin = dmax - newrng
            #invrng = 1.0/newrng
            dmax = 3.0
            dmin = -3.0
            self._logmin = dmin
            self._invlogrng = invrng
            self._recalcMaxMin = 10
            #print self._logmin, self._invlogrng
            #del(data)
        # HACK
        #data = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT)
        #import scipy
        #scipy.misc.imsave('outfile.jpg', data)
        # HACK END

    def DrawTexture(self):
        logshade = True
        if logshade:
            self._logShader.Bind()
            self._logShader.AddFloat(self._logmin, "texmin")
            self._logShader.AddFloat(self._invlogrng, "texinvrng")
        #shaders.glUseProgram(self._logShader.Shader())
        #minloc = glGetUniformLocation( self._logShader.Shader(), 'texmin' )
        #invrngloc = glGetUniformLocation( self._logShader.Shader(), 'texinvrng' )
        #glUniform1f( minloc,self._logmin)
        #glUniform1f( invrngloc,self._invlogrng)
        #shaders.glUseProgram(0)
        glLoadIdentity()
        glViewport(self._x, self._y, self._width, self._height)
        # Now we need to plot the texture to screen
        # Set up an orthogonal projection
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, 1, 0, 1, -10, 10)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        #glDrawPixels(self._width, self._height, GL_RGBA, GL_FLOAT, self._texture)
        # Now draw the texture with the log shader
        # Draw the texture onto a flat plane
        glColor4f(1.0, 1.0, 1.0, 1.0)
        glEnable(GL_TEXTURE_2D)
        #glDisable(GL_TEXTURE_GEN_S)
        #glDisable(GL_TEXTURE_GEN_T)
        glBindTexture(GL_TEXTURE_2D, self._texture)
        glBegin(GL_TRIANGLES)
        glTexCoord2d(0.0, 0.0)
        glVertex3f(0.0, 0.0, 0.0)
        glTexCoord2d(1.0, 0.0)
        glVertex3f(1.0, 0.0, 0.0)
        glTexCoord2d(1.0, 1.0)
        glVertex3f(1.0, 1.0, 0.0)

        glTexCoord2d(1.0, 1.0)
        glVertex3f(1.0, 1.0, 0.0)
        glTexCoord2d(0.0, 1.0)
        glVertex3f(0.0, 1.0, 0.0)
        glTexCoord2d(0.0, 0.0)
        glVertex3f(0.0, 0.0, 0.0)
        glEnd()
        if logshade:
            self._logShader.Unbind()
        glBindTexture(GL_TEXTURE_2D, 0)