Beispiel #1
0
def deleteRenderbuffer(renderBuffer):
    """Free the resources associated with a renderbuffer. This invalidates the
    renderbuffer's ID.

    Returns
    -------
    :obj:`None'

    """
    GL.glDeleteRenderbuffers(1, renderBuffer.id)
Beispiel #2
0
 def __del__(self):
     try:
         gl.glDeleteRenderbuffers(1, self._id)
         # Python interpreter is shutting down:
     except ImportError:
         pass
Beispiel #3
0
 def delete(self):
     gl.glDeleteRenderbuffers(1, self._id)
Beispiel #4
0
def createMultisampleFBO(width, height, samples, colorFormat=GL.GL_RGBA8):
    """Create a multisample framebuffer for rendering. Objects drawn to the
    framebuffer will be anti-aliased if 'GL_MULTISAMPLE' is active. A combined
    depth and stencil buffer is created with 'GL_DEPTH24_STENCIL8' format.

    Multisampling is computationally intensive for your graphics hardware and
    consumes substantial amounts of VRAM. Furthermore, samples must be
    'resolved' prior to display by copying (using blitFramebuffer, see Examples)
    to a non-multisample buffer.

    Parameters
    ----------
    width : :obj:`int`
        Buffer width in pixels.
    height : :obj:`int`
        Buffer height in pixels.
    samples : :obj:`int`
        Number of samples for multi-sampling, should be >1 and power-of-two.
        Work with one sample, but will raise a warning.
    colorFormat : :obj:`int`
        Format for color renderbuffer data (e.g. GL_RGBA8).

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

    Examples
    --------
    # create a multisample FBO with 8 samples
    msaaFbo, colorRb, depthRb = createMultisampleFBO(800, 600, 8)
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, msaaFbo)  # bind it

    # resolve samples into another framebuffer texture
    GL.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, msaaFbo)
    GL.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, fbo)
    gltools.blitFramebuffer((0, 0, 800, 600))

    """
    # determine if the 'samples' value is valid
    max_samples = getIntegerv(GL.GL_MAX_SAMPLES)
    if isinstance(samples, int):
        if (samples & (samples - 1)) != 0:
            raise ValueError(
                'Invalid number of samples, must be power-of-two.')
        elif samples < 0 or samples > max_samples:
            raise ValueError(
                'Invalid number of samples, must be <{}.'.format(max_samples))
        elif samples == 1:
            # warn that you are creating a single sample texture, use a regular
            # FBO instead.
            logging.warning('Creating a multisample FBO with one sample!')
    elif isinstance(samples, str):
        if samples == 'max':
            samples = max_samples

    # create the FBO, bind it for attachments
    fboId = GL.GLuint()
    GL.glGenFramebuffers(1, ctypes.byref(fboId))
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fboId)

    # Color render buffer only instead of a texture. I can't think of a use case
    # to pass around a multisampled texture (yet).
    colorRbId = GL.GLuint()
    GL.glGenRenderbuffers(1, ctypes.byref(colorRbId))
    GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, colorRbId)
    GL.glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples,
                                        colorFormat, int(width), int(height))
    GL.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0,
                                 GL.GL_RENDERBUFFER, colorRbId)
    GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, 0)

    # setup the render buffer for depth and stencil
    depthRbId = GL.GLuint()
    GL.glGenRenderbuffers(1, ctypes.byref(depthRbId))
    GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, depthRbId)
    GL.glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples,
                                        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.glDeleteRenderbuffers(1, colorRbId)
        GL.glDeleteRenderbuffers(1, depthRbId)
        GL.glDeleteFramebuffers(1, fboId)
        raise RuntimeError(
            'Failed to create a multisample framebuffer. Exiting.')

    return fboId, colorRbId, depthRbId
Beispiel #5
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