Exemple #1
0
    def attach_texture(self, target, attachment, texture):
        """Attach a Texture to the Framebuffer

        :Parameters:
            `target` : int
                Specifies the framebuffer target. target must be
                gl.GL_DRAW_FRAMEBUFFER, gl.GL_READ_FRAMEBUFFER, or
                gl.GL_FRAMEBUFFER. gl.GL_FRAMEBUFFER is equivalent to
                gl.GL_DRAW_FRAMEBUFFER.
            `attachment` : int
                Specifies the attachment point of the framebuffer. attachment
                must be gl.GL_COLOR_ATTACHMENTi, gl.GL_DEPTH_ATTACHMENT,
                gl.GL_STENCIL_ATTACHMENT or gl.GL_DEPTH_STENCIL_ATTACHMENT.
            `texture` : pyglet.image.Texture
                Specifies the texture object to attach to the framebuffer
                attachment point named by attachment.
        """
        self.bind()
        gl.glFramebufferTexture2D(target, attachment, texture.target,
                                  texture.id, texture.level)
        # gl.glFramebufferTexture2D(target, attachment, texture.target,
        # texture.id, texture.level)
        self._attachment_types |= attachment
        self._width = max(texture.width, self._width)
        self._height = max(texture.height, self._height)
        self.unbind()
Exemple #2
0
    def __init__(self, width, height, wwidth, wheight):
        self.width = width
        self.height = height
        self.windowwidth = wwidth
        self.windowheight = wheight
        self.framebuffer = gl.GLuint(0)
        self.rendered_texture = Texture()

        gl.glGenFramebuffers(1, ctypes.byref(self.framebuffer))

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebuffer)

        # Set up the texture as the target for color output
        with self.rendered_texture:
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, self.width,
                            self.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, 0)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_NEAREST)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_NEAREST)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D,
                                      self.rendered_texture.name, 0)

        if gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:
            raise ValueError('Framebuffer not set up completely')

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def build_buffer():
    buffer = gl.GLuint(0)
    gl.glGenFramebuffers(1, ctypes.byref(buffer))
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, buffer)

    texture = gl.GLuint(0)
    gl.glGenTextures(1, ctypes.byref(texture))
    gl.glEnable(gl.GL_TEXTURE_2D)
    gl.glBindTexture(gl.GL_TEXTURE_2D, texture)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, BUF_WIDTH, BUF_HEIGHT, 0,
                    gl.GL_RGBA, gl.GL_FLOAT, None)
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                       gl.GL_NEAREST)
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                       gl.GL_NEAREST)

    gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                              gl.GL_TEXTURE_2D, texture, 0)

    if (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) !=
            gl.GL_FRAMEBUFFER_COMPLETE):
        raise RuntimeError('Framebuffer incomplete !')

    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
    gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
    gl.glDisable(gl.GL_TEXTURE_2D)

    return buffer, texture
Exemple #4
0
    def _link(self):
        for attachment, tex in zip(COLOR_ATTACHMENTS, self.textures):
            gl.glBindTexture(gl.GL_TEXTURE_2D, tex)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S,
                               gl.GL_REPEAT)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T,
                               gl.GL_REPEAT)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_NEAREST)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_NEAREST)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, self.width,
                            self.height, 0, gl.GL_RGBA, gl.GL_FLOAT, None)

            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, attachment,
                                      gl.GL_TEXTURE_2D, tex, 0)

        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self.depthbuf)
        gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT16,
                                 self.width, self.height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT,
                                     gl.GL_RENDERBUFFER, self.depthbuf)

        assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE, \
            "Framebuffer is not complete!"
    def __init__(self,
                 width,
                 height,
                 window,
                 num_color_attachments=1,
                 mapping_mode=None,
                 provide_depth=False,
                 provide_stencil=False):
        """"Create an arbitrary layer framebuffer, I'll add stencil and depthbuffers if I ever package this for resuse, in pyweek, those args are pretty much placeholders"""
        if mapping_mode is None:
            mapping_mode = gl.GL_NEAREST
        assert not provide_stencil, 'stencil buffer not implemented'
        assert not provide_depth, 'depth buffer not implemented'
        self.window = window
        self.width = width
        self.height = height
        self.bufferId = gl.GLuint(0)
        self.textureIds = []
        self.buffer_args = []

        #create the vram objects?
        gl.glGenFramebuffers(1, rf(self.bufferId))
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.bufferId)

        for bufferIndex in range(num_color_attachments):
            newTex = gl.GLuint(0)
            gl.glGenTextures(1, rf(newTex))
            self.textureIds.append(newTex)
            gl.glBindTexture(gl.GL_TEXTURE_2D, newTex)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, width, height, 0,
                            gl.GL_RGB, gl.GL_UNSIGNED_INT, 0)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               mapping_mode)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               mapping_mode)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0 + bufferIndex,
                                      gl.GL_TEXTURE_2D, newTex, 0)
            self.buffer_args.append(gl.GL_COLOR_ATTACHMENT0 + bufferIndex)
        #assign one of the vram objects to the framebuffer cache?

        if provide_depth:
            self.buffer_args.append(gl.GL_DEPTH_ATTACHMENT)
        if provide_stencil:
            self.buffer_args.append(gl.GL_STENCIL_ATTACHMENT)

        self.buffers_provided = (gl.GLenum *
                                 len(self.buffer_args))(*self.buffer_args)

        gl.glDrawBuffers(len(self.buffer_args), self.buffers_provided)
        self.textures = [
            Texture(self.width, self.height, gl.GL_TEXTURE_2D, texId.value)
            for texId in self.textureIds
        ]

        assert gl.glCheckFramebufferStatus(
            gl.GL_FRAMEBUFFER
        ) == gl.GL_FRAMEBUFFER_COMPLETE, "I don't know why this happened, but at least I can find out"
Exemple #6
0
    def bind_texture(self, texture):
        with texture:
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D, texture.id, 0)

            if (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) !=
                    gl.GL_FRAMEBUFFER_COMPLETE):
                raise RuntimeError('Framebuffer incomplete !')
Exemple #7
0
        def createFramebuffer(width, height):
            """Function for setting up additional buffer"""
            # create a new framebuffer
            fboId = GL.GLuint()
            GL.glGenFramebuffers(1, ctypes.byref(fboId))
            GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fboId)

            # create a texture to render to, required for warping
            texId = GL.GLuint()
            GL.glGenTextures(1, ctypes.byref(texId))
            GL.glBindTexture(GL.GL_TEXTURE_2D, texId)
            GL.glTexParameteri(GL.GL_TEXTURE_2D,
                               GL.GL_TEXTURE_MAG_FILTER,
                               GL.GL_LINEAR)
            GL.glTexParameteri(GL.GL_TEXTURE_2D,
                               GL.GL_TEXTURE_MIN_FILTER,
                               GL.GL_LINEAR)
            GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA32F_ARB,
                            int(width), int(height), 0,
                            GL.GL_RGBA, GL.GL_FLOAT, None)
            GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
                                      GL.GL_COLOR_ATTACHMENT0,
                                      GL.GL_TEXTURE_2D,
                                      texId,
                                      0)

            # create a render buffer
            rbId = GL.GLuint()
            GL.glGenRenderbuffers(1, ctypes.byref(rbId))
            GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, rbId)
            GL.glRenderbufferStorage(
                GL.GL_RENDERBUFFER,
                GL.GL_DEPTH24_STENCIL8,
                int(width),
                int(height))
            GL.glFramebufferRenderbuffer(
                GL.GL_FRAMEBUFFER,
                GL.GL_DEPTH_ATTACHMENT,
                GL.GL_RENDERBUFFER,
                rbId)
            GL.glFramebufferRenderbuffer(
                GL.GL_FRAMEBUFFER,
                GL.GL_STENCIL_ATTACHMENT,
                GL.GL_RENDERBUFFER,
                rbId)
            GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, 0)

            # clear the buffer
            GL.glClear(GL.GL_COLOR_BUFFER_BIT)
            GL.glClear(GL.GL_STENCIL_BUFFER_BIT)
            GL.glClear(GL.GL_DEPTH_BUFFER_BIT)

            GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)

            return fboId, texId, rbId
Exemple #8
0
    def __init__(self, width, height):
        self.fbo = gl.GLuint(0)

        gl.glGenFramebuffers(1, ctypes.byref(self.fbo))
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo)
        
        self.texture = pyglet.image.Texture.create(width, height)
        gl.glBindTexture(self.texture.target, 0)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.texture.id, 0)
        
        draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
        gl.glDrawBuffers(1, draw_buffers)

        assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
Exemple #9
0
def setup_framebuffer():
    gl.glGenFramebuffers(1, ctypes.byref(framebuffer))
    gl.glGenTextures(1, ctypes.byref(rendered_texture))

    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer)

    # Set up the texture as the target for color output
    gl.glBindTexture(gl.GL_TEXTURE_2D, rendered_texture)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, FB_WIDTH, FB_HEIGHT, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, 0)
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
    gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, rendered_texture, 0)

    draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
    gl.glDrawBuffers(1, draw_buffers)

    assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
Exemple #10
0
    def __init__(self, width, height):
        self.fbo = gl.GLuint(0)

        gl.glGenFramebuffers(1, ctypes.byref(self.fbo))
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo)

        self.texture = pyglet.image.Texture.create(width, height)
        gl.glBindTexture(self.texture.target, 0)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_2D, self.texture.id, 0)

        draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
        gl.glDrawBuffers(1, draw_buffers)

        assert gl.glCheckFramebufferStatus(
            gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
Exemple #11
0
    def _setup(self):
        self.name = gl.GLuint()

        gl.glCreateFramebuffers(1, byref(self.name))
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.name)

        self.cubemap_texture = gl.GLuint()

        gl.glGenTextures(gl.GL_TEXTURE_CUBE_MAP, byref(self.name))
        gl.glBindTexture(gl.GL_TEXTURE_CUBE_MAP, self.cubemap_texture)

        w, h = self.size

        # initialize the texture (IMPORTANT!!!)
        for i in range(6):
            gl.glTexImage2D(gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
                            gl.GL_DEPTH_COMPONENT, w, h, 0,
                            gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT, 0)

        gl.glFramebufferTexture2D(gl.GL_DRAW_FRAMEBUFFER,
                                  gl.GL_DEPTH_ATTACHMENT,
                                  gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
                                  self.cubemap_texture, 0)

        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_BASE_LEVEL, 0)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_MAX_LEVEL, 0)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_MAG_FILTER,
                           gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_MIN_FILTER,
                           gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_WRAP_S,
                           gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_WRAP_T,
                           gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_TEXTURE_WRAP_R,
                           gl.GL_CLAMP_TO_EDGE)
        gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP, gl.GL_DEPTH_TEXTURE_MODE,
                           gl.GL_LUMINANCE)
        gl.glBindTexture(gl.GL_TEXTURE_CUBE_MAP, 0)

        status = gl.glCheckFramebufferStatus(gl.GL_DRAW_FRAMEBUFFER)
        assert status == gl.GL_FRAMEBUFFER_COMPLETE, f"Could not setup framebuffer! {status}"
Exemple #12
0
def attach(attachPoint, imageBuffer):
    """Attach an image to a specified attachment point on the presently bound
    FBO.

    Parameters
    ----------
    attachPoint :obj:`int`
        Attachment point for 'imageBuffer' (e.g. GL.GL_COLOR_ATTACHMENT0).
    imageBuffer : :obj:`TexImage2D` or :obj:`Renderbuffer`
        Framebuffer-attachable buffer descriptor.

    Returns
    -------
    None

    Examples
    --------
    # with descriptors colorTex and depthRb
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo)
    attach(GL.GL_COLOR_ATTACHMENT0, colorTex)
    attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb)
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, lastBoundFbo)

    # same as above, but using a context manager
    with useFBO(fbo):
        attach(GL.GL_COLOR_ATTACHMENT0, colorTex)
        attach(GL.GL_DEPTH_STENCIL_ATTACHMENT, depthRb)

    """
    # We should also support binding GL names specified as integers. Right now
    # you need as descriptor which contains the target and name for the buffer.
    #
    if isinstance(imageBuffer, (TexImage2D, TexImage2DMultisample)):
        GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, attachPoint,
                                  imageBuffer.target, imageBuffer.id, 0)
    elif isinstance(imageBuffer, Renderbuffer):
        GL.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, attachPoint,
                                     imageBuffer.target, imageBuffer.id)
Exemple #13
0
    def resize(self, width, height):
        ''' resizes the framebuffer to the given dimensions '''
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo)
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.rendered_texture)
        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, width, height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, 0)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.rendered_texture, 0)

        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self.depthrenderbuffer)
        gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, width, height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, self.depthrenderbuffer)

        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self.pickingbuffer)
        gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_R16UI, width, height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT1, gl.GL_RENDERBUFFER, self.pickingbuffer)

        draw_buffers = (gl.GLenum * 2)(gl.GL_COLOR_ATTACHMENT0, gl.GL_COLOR_ATTACHMENT1)
        gl.glDrawBuffers(2, draw_buffers)

        if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:
            logging.error('setting up fbo failed')

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
Exemple #14
0
def createFBO(width, height, colorFormat=GL.GL_RGBA8):
    """Generate a new Framebuffer object (FBO) for use as a render target.

    Parameters
    ----------
    width : :obj:`int`
        Buffer width in pixels.
    height : :obj:`int`
        Buffer height in pixels.
    colorFormat : :obj:`int`
        Format for color renderbuffer data (e.g. GL_RGBA8).

    Returns
    -------
    :obj:`list` of :obj:`int`
        List of OpenGL ids (FBO, Color Texture, Depth/Stencil RB).

    Examples
    --------
    # create a FBO
    frameBuffer, frameTexture, stencilTexture = createFBO(
        800, 600, GL.GL_RGBA32F_ARB)
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, frameBuffer)  # bind it

    """
    # Create a texture render target for color data, same _setupFramebuffer()
    #
    # We should avoid creating a texture here in the future since we might want
    # to bind an existing texture from elsewhere and reuse the same FBO.
    #
    colorTextureId = GL.GLuint()
    GL.glGenTextures(1, ctypes.byref(colorTextureId))
    GL.glBindTexture(GL.GL_TEXTURE_2D, colorTextureId)
    GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
                       GL.GL_LINEAR)
    GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
                       GL.GL_LINEAR)
    GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, colorFormat, int(width), int(height),
                    0, GL.GL_RGBA, GL.GL_FLOAT, None)
    GL.glBindTexture(GL.GL_TEXTURE_2D, 0)

    fboId = GL.GLuint()
    GL.glGenFramebuffers(1, ctypes.byref(fboId))

    # attach texture to the frame buffer
    GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0,
                              GL.GL_TEXTURE_2D, colorTextureId, 0)

    # create depth and stencil render buffers
    depthRbId = GL.GLuint()
    GL.glGenRenderbuffers(1, ctypes.byref(depthRbId))
    GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, depthRbId)
    GL.glRenderbufferStorage(GL.GL_RENDERBUFFER, GL.GL_DEPTH24_STENCIL8,
                             int(width), int(height))
    GL.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT,
                                 GL.GL_RENDERBUFFER, depthRbId)
    GL.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT,
                                 GL.GL_RENDERBUFFER, depthRbId)
    GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, 0)

    # clear VRAM garbage
    GL.glClear(GL.GL_STENCIL_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT
               | GL.GL_STENCIL_BUFFER_BIT)

    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)

    # check completeness
    if not checkFramebufferComplete(fboId):
        # delete the framebuffer and all the resources associated with it
        GL.glDeleteTextures(1, colorTextureId)
        GL.glDeleteRenderbuffers(1, depthRbId)
        GL.glDeleteFramebuffers(1, fboId)
        raise RuntimeError('Failed to create a framebuffer. Exiting.')

    return fboId, colorTextureId, depthRbId
Exemple #15
0
def create_frame_buffers(width, height, num_samples):
    """Create the frame buffer objects"""
    from pyglet import gl

    # Create a frame buffer (rendering target)
    multi_fbo = gl.GLuint(0)
    gl.glGenFramebuffers(1, byref(multi_fbo))
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, multi_fbo)

    # The try block here is because some OpenGL drivers
    # (Intel GPU drivers on macbooks in particular) do not
    # support multisampling on frame buffer objects
    try:
        if not gl.gl_info.have_version(major=3, minor=2):
            raise Exception('OpenGL version 3.2+ required for \
                            GL_TEXTURE_2D_MULTISAMPLE')

        # Create a multisampled texture to render into
        fbTex = gl.GLuint(0)
        gl.glGenTextures(1, byref(fbTex))
        gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex)
        gl.glTexImage2DMultisample(gl.GL_TEXTURE_2D_MULTISAMPLE, num_samples,
                                   gl.GL_RGBA32F, width, height, True)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex, 0)

        # Attach a multisampled depth buffer to the FBO
        depth_rb = gl.GLuint(0)
        gl.glGenRenderbuffers(1, byref(depth_rb))
        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb)
        gl.glRenderbufferStorageMultisample(gl.GL_RENDERBUFFER, num_samples,
                                            gl.GL_DEPTH_COMPONENT, width,
                                            height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT,
                                     gl.GL_RENDERBUFFER, depth_rb)

    except:
        logger.debug('Falling back to non-multisampled frame buffer')

        # Create a plain texture texture to render into
        fbTex = gl.GLuint(0)
        gl.glGenTextures(1, byref(fbTex))
        gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex)
        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0,
                        gl.GL_RGBA, gl.GL_FLOAT, None)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_2D, fbTex, 0)

        # Attach depth buffer to FBO
        depth_rb = gl.GLuint(0)
        gl.glGenRenderbuffers(1, byref(depth_rb))
        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb)
        gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT,
                                 width, height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT,
                                     gl.GL_RENDERBUFFER, depth_rb)

    # Sanity check
    import pyglet
    if pyglet.options['debug_gl']:
        res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER)
        assert res == gl.GL_FRAMEBUFFER_COMPLETE

    # Create the frame buffer used to resolve the final render
    final_fbo = gl.GLuint(0)
    gl.glGenFramebuffers(1, byref(final_fbo))
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, final_fbo)

    # Create the texture used to resolve the final render
    fbTex = gl.GLuint(0)
    gl.glGenTextures(1, byref(fbTex))
    gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0,
                    gl.GL_RGBA, gl.GL_FLOAT, None)
    gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                              gl.GL_TEXTURE_2D, fbTex, 0)
    import pyglet
    if pyglet.options['debug_gl']:
        res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER)
        assert res == gl.GL_FRAMEBUFFER_COMPLETE

    # Enable depth testing
    gl.glEnable(gl.GL_DEPTH_TEST)

    # Unbind the frame buffer
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)

    return multi_fbo, final_fbo
Exemple #16
0
        def setupFBOandTextures(self):
            self.framebufferA0 = gl.GLuint(0)
            self.framebufferA1 = gl.GLuint(0)
            self.framebufferB0 = gl.GLuint(0)
            self.framebufferB1 = gl.GLuint(0)

            self.A0_tex = gl.GLuint(0)
            self.A1_tex = gl.GLuint(0)
            self.B0_tex = gl.GLuint(0)
            self.B1_tex = gl.GLuint(0)

            self.draw_buffersA0 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
            self.draw_buffersA1 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
            self.draw_buffersB0 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
            self.draw_buffersB1 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)

            gl.glGenFramebuffers(1, ctypes.byref(self.framebufferA0))
            gl.glGenFramebuffers(1, ctypes.byref(self.framebufferA1))
            gl.glGenFramebuffers(1, ctypes.byref(self.framebufferB0))
            gl.glGenFramebuffers(1, ctypes.byref(self.framebufferB1))

            gl.glGenTextures(1, ctypes.byref(self.A0_tex))
            gl.glGenTextures(1, ctypes.byref(self.A1_tex))
            gl.glGenTextures(1, ctypes.byref(self.B0_tex))
            gl.glGenTextures(1, ctypes.byref(self.B1_tex))

            #A
            gl.glActiveTexture(gl.GL_TEXTURE0)
            gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferA0)
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.A0_tex)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx,
                            self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Ap)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_LINEAR)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_LINEAR)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D, self.A0_tex, 0)
            gl.glDrawBuffers(1, self.draw_buffersA0)

            assert gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE

            gl.glActiveTexture(gl.GL_TEXTURE1)
            gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferA1)
            # Set up the texture as the target for color output
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.A1_tex)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx,
                            self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Ap)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_LINEAR)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_LINEAR)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D, self.A1_tex, 0)

            gl.glDrawBuffers(1, self.draw_buffersA1)

            assert gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE

            #B

            gl.glActiveTexture(gl.GL_TEXTURE2)
            gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferB0)
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.B0_tex)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx,
                            self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Bp)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_LINEAR)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_LINEAR)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D, self.B0_tex, 0)
            gl.glDrawBuffers(1, self.draw_buffersB0)

            assert gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE

            gl.glActiveTexture(gl.GL_TEXTURE3)
            gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferB1)
            # Set up the texture as the target for color output
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.B1_tex)
            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx,
                            self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Bp)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER,
                               gl.GL_LINEAR)
            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
                               gl.GL_LINEAR)
            gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                      gl.GL_COLOR_ATTACHMENT0,
                                      gl.GL_TEXTURE_2D, self.B1_tex, 0)

            gl.glDrawBuffers(1, self.draw_buffersB1)

            assert gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
Exemple #17
0
    def __init__(self,
                 ctx: "Context",
                 *,
                 color_attachments=None,
                 depth_attachment=None):
        """
        :param Context ctx: The context this framebuffer belongs to
        :param List[arcade.gl.Texture] color_attachments: List of color attachments.
        :param arcade.gl.Texture depth_attachment: A depth attachment (optional)
        """
        if not color_attachments:
            raise ValueError(
                "Framebuffer must at least have one color attachment")

        self._ctx = ctx
        self._color_attachments = (color_attachments if isinstance(
            color_attachments, list) else [color_attachments])
        self._depth_attachment = depth_attachment
        self._glo = fbo_id = gl.GLuint()  # The OpenGL alias/name
        self._samples = 0  # Leaving this at 0 for future sample support
        self._depth_mask = True  # Determines if the depth buffer should be affected
        self._prev_fbo = None

        # Create the framebuffer object
        gl.glGenFramebuffers(1, self._glo)
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._glo)

        # Ensure all attachments have the same size.
        # OpenGL do actually support different sizes,
        # but let's keep this simple with high compatibility.
        expected_size = (self._color_attachments[0] if self._color_attachments
                         else self._depth_attachment).size
        for layer in [*self._color_attachments, self._depth_attachment]:
            if layer and layer.size != expected_size:
                raise ValueError(
                    "All framebuffer attachments should have the same size")

        self._width, self._height = expected_size
        self._viewport = 0, 0, self._width, self._height

        # Attach textures to it
        for i, tex in enumerate(self._color_attachments):
            # TODO: Possibly support attaching a specific mipmap level
            #       but we can read from specific mip levels from shaders.
            gl.glFramebufferTexture2D(
                gl.GL_FRAMEBUFFER,
                gl.GL_COLOR_ATTACHMENT0 + i,
                gl.GL_TEXTURE_2D,
                tex.glo,
                0,  # Level 0
            )

        if self.depth_attachment:
            gl.glFramebufferTexture2D(
                gl.GL_FRAMEBUFFER,
                gl.GL_DEPTH_ATTACHMENT,
                self.depth_attachment._target,
                self.depth_attachment.glo,
                0,
            )

        # Ensure the framebuffer is sane!
        self._check_completeness()

        # Set up draw buffers. This is simply a prepared list of attachments enums
        # we use in the use() method to activate the different color attachment layers
        layers = [
            gl.GL_COLOR_ATTACHMENT0 + i
            for i, _ in enumerate(self._color_attachments)
        ]
        # pyglet wants this as a ctypes thingy, so let's prepare it
        self._draw_buffers = (gl.GLuint * len(layers))(*layers)

        # Restore the original bound framebuffer to avoid confusion
        self.ctx.active_framebuffer.use(force=True)

        self.ctx.stats.incr("framebuffer")
        weakref.finalize(self, Framebuffer.release, ctx, fbo_id)
Exemple #18
0
def create_frame_buffers(width: int, height: int,
                         num_samples: int) -> Tuple[int, int]:
    """Create the frame buffer objects"""

    # Create a frame buffer (rendering target)
    multi_fbo = gl.GLuint(0)
    gl.glGenFramebuffers(1, byref(multi_fbo))
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, multi_fbo)

    # The try block here is because some OpenGL drivers
    # (Intel GPU drivers on macbooks in particular) do not
    # support multisampling on frame buffer objects
    # noinspection PyBroadException
    try:
        # Create a multisampled texture to render into
        fbTex = gl.GLuint(0)
        gl.glGenTextures(1, byref(fbTex))
        gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex)
        gl.glTexImage2DMultisample(gl.GL_TEXTURE_2D_MULTISAMPLE, num_samples,
                                   gl.GL_RGBA32F, width, height, True)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex, 0)

        # Attach a multisampled depth buffer to the FBO
        depth_rb = gl.GLuint(0)
        gl.glGenRenderbuffers(1, byref(depth_rb))
        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb)
        gl.glRenderbufferStorageMultisample(gl.GL_RENDERBUFFER, num_samples,
                                            gl.GL_DEPTH_COMPONENT, width,
                                            height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT,
                                     gl.GL_RENDERBUFFER, depth_rb)

    except BaseException as e:
        # logger.warning(e=traceback.format_exc())
        logger.debug("Falling back to non-multisampled frame buffer")

        # Create a plain texture texture to render into
        fbTex = gl.GLuint(0)
        gl.glGenTextures(1, byref(fbTex))
        gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex)
        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0,
                        gl.GL_RGBA, gl.GL_FLOAT, None)
        gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_2D, fbTex, 0)

        # Attach depth buffer to FBO
        depth_rb = gl.GLuint(0)
        gl.glGenRenderbuffers(1, byref(depth_rb))
        gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb)
        gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT,
                                 width, height)
        gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT,
                                     gl.GL_RENDERBUFFER, depth_rb)

    # Sanity check

    if pyglet.options["debug_gl"]:
        res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER)
        assert res == gl.GL_FRAMEBUFFER_COMPLETE

    # Create the frame buffer used to resolve the final render
    final_fbo = gl.GLuint(0)
    gl.glGenFramebuffers(1, byref(final_fbo))
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, final_fbo)

    # Create the texture used to resolve the final render
    fbTex = gl.GLuint(0)
    gl.glGenTextures(1, byref(fbTex))
    gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0,
                    gl.GL_RGBA, gl.GL_FLOAT, None)
    gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                              gl.GL_TEXTURE_2D, fbTex, 0)

    if pyglet.options["debug_gl"]:
        res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER)
        assert res == gl.GL_FRAMEBUFFER_COMPLETE

    # Enable depth testing
    gl.glEnable(gl.GL_DEPTH_TEST)

    # Unbind the frame buffer
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)

    return multi_fbo, final_fbo