Пример #1
0
    def mirror_framebuffer(self,
                           src,
                           src_x=0,
                           src_y=0,
                           src_w=0,
                           src_h=0,
                           dst_x=0,
                           dst_y=0,
                           dst_w=0,
                           dst_h=0,
                           target=GL_COLOR_BUFFER_BIT,
                           filter_type=GL_LINEAR):
        glBindFramebuffer(GL_READ_FRAMEBUFFER, src.buffer)
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, self.buffer)

        if GL_COLOR_BUFFER_BIT == target:
            glDrawBuffers(1, (GL_COLOR_ATTACHMENT0, ))
            glReadBuffer(GL_COLOR_ATTACHMENT0)
        elif GL_DEPTH_BUFFER_BIT == target and src.depth_texture is not None:
            attachment = OpenGLContext.get_depth_attachment(
                src.depth_texture.internal_format)
            glDrawBuffers(1, (attachment, ))
            glReadBuffer(attachment)

        glBlitFramebuffer(src_w or src.viewport_width, src_y, src_x, src_h
                          or src.viewport_height, dst_x, dst_y, dst_w
                          or self.viewport_width, dst_h
                          or self.viewport_height, target, filter_type)
Пример #2
0
    def get_image_data(self, level=0):
        if self.target not in (GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY,
                               GL_TEXTURE_3D):
            return None

        level = min(level, self.get_mipmap_count())
        dtype = get_numpy_dtype(self.data_type)

        try:
            glBindTexture(self.target, self.buffer)
            data = OpenGLContext.glGetTexImage(self.target, level,
                                               self.texture_format,
                                               self.data_type)
            # convert to numpy array
            if type(data) is bytes:
                data = np.fromstring(data, dtype=dtype)
            else:
                data = np.array(data, dtype=dtype)
            glBindTexture(self.target, 0)
            return data
        except:
            logger.error(traceback.format_exc())
            logger.error('%s failed to get image data.' % self.name)
            logger.info('Try to glReadPixels.')

        glBindTexture(self.target, self.buffer)
        fb = glGenFramebuffers(1)
        glBindFramebuffer(GL_FRAMEBUFFER, fb)

        data = []
        for layer in range(self.depth):
            if GL_TEXTURE_2D == self.target:
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                       GL_TEXTURE_2D, self.buffer, level)
            elif GL_TEXTURE_3D == self.target:
                glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                       GL_TEXTURE_3D, self.buffer, level,
                                       layer)
            elif GL_TEXTURE_2D_ARRAY == self.target:
                glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                          self.buffer, level, layer)
            glReadBuffer(GL_COLOR_ATTACHMENT0)
            width, height = self.get_mipmap_size(level)
            pixels = glReadPixels(0, 0, width, height, self.texture_format,
                                  self.data_type)
            # convert to numpy array
            if type(pixels) is bytes:
                pixels = np.fromstring(pixels, dtype=dtype)
            data.append(pixels)
        data = np.array(data, dtype=dtype)
        glBindTexture(self.target, 0)
        glBindFramebuffer(GL_FRAMEBUFFER, 0)
        glDeleteFramebuffers(1, [
            fb,
        ])
        return data
Пример #3
0
    def generate_framebuffer(self, target_face=GL_TEXTURE_CUBE_MAP_POSITIVE_X, target_layer=0, target_level=0):
        if self.buffer is None:
            self.buffer = glGenFramebuffers(1)

        glBindFramebuffer(GL_FRAMEBUFFER, self.buffer)

        self.target_face = target_face
        self.target_layer = target_layer
        self.target_level = target_level

        # bind color textures
        layer_offset = 0
        last_texture = None
        for i, color_texture in enumerate(self.color_textures):
            if last_texture != color_texture:
                layer_offset = 0
                last_texture = color_texture
            else:
                layer_offset += 1

            if color_texture is not None:
                self.attachment_framebuffer(GL_COLOR_ATTACHMENT0 + i, color_texture.target, color_texture.buffer, layer_offset)

        if self.attach_count > 0:
            glDrawBuffers(self.attach_count, self.attachments)
        else:
            glDrawBuffer(GL_NONE)
            glReadBuffer(GL_NONE)

        # bind depth texture
        if self.depth_texture is not None:
            attachment = OpenGLContext.get_depth_attachment(self.depth_texture.internal_format)
            self.attachment_framebuffer(attachment, self.depth_texture.target, self.depth_texture.buffer)
        else:
            glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0)

        gl_error = glCheckFramebufferStatus(GL_FRAMEBUFFER)
        if gl_error != GL_FRAMEBUFFER_COMPLETE:
            error_message = "glCheckFramebufferStatus error %s." % self.get_error(gl_error)
            logger.error(error_message)
            raise BaseException(error_message)
Пример #4
0
    def build_command(self):
        self.commands.clear()
        self.add_command(glBindFramebuffer, GL_FRAMEBUFFER, self.buffer)

        # bind color textures
        layer_offset = 0
        last_texture = None
        for i, color_texture in enumerate(self.color_textures):
            if last_texture != color_texture:
                layer_offset = 0
                last_texture = color_texture
            else:
                layer_offset += 1

            attachment = GL_COLOR_ATTACHMENT0 + i

            if color_texture is not None:
                self.add_command(self.func_bind_framebuffer, attachment,
                                 color_texture.target, color_texture.buffer,
                                 layer_offset)

        if self.attach_count > 0:
            self.add_command(glDrawBuffers, self.attach_count,
                             self.attachments)
        else:
            self.add_command(glDrawBuffer, GL_NONE)
            self.add_command(glReadBuffer, GL_NONE)

        # bind depth texture
        if self.depth_texture is not None:
            attachment = OpenGLContext.get_depth_attachment(
                self.depth_texture.internal_format)
            self.add_command(self.func_bind_framebuffer, attachment,
                             self.depth_texture.target,
                             self.depth_texture.buffer)
        else:
            self.add_command(glFramebufferTexture, GL_FRAMEBUFFER,
                             GL_DEPTH_STENCIL_ATTACHMENT, 0, 0)
Пример #5
0
 def use_program(self):
     OpenGLContext.use_program(self.program)
Пример #6
0
 def delete(self):
     OpenGLContext.use_program(0)
     glDeleteProgram(self.program)
     logger.info("Deleted %s material." % self.name)