Пример #1
0
void Framebuffer2D::destroyBuffers(unsigned char bufferBit)
{
    if( bufferBit & FBO_AUX0_BIT &&
        glIsTexture(bufferHandle[FBO_AUX0]))
            glDeleteTextures(1, &bufferHandle[FBO_AUX0]);

    if( bufferBit & FBO_AUX1_BIT &&
        glIsTexture(bufferHandle[FBO_AUX1]))
            glDeleteTextures(1, &bufferHandle[FBO_AUX1]);

    if( bufferBit & FBO_AUX2_BIT &&
        glIsTexture(bufferHandle[FBO_AUX2]))
            glDeleteTextures(1, &bufferHandle[FBO_AUX2]);

    if( bufferBit & FBO_AUX3_BIT &&
        glIsTexture(bufferHandle[FBO_AUX3]))
            glDeleteTextures(1, &bufferHandle[FBO_AUX3]);

    if(bufferBit & FBO_DEPTH_BIT &&
        glIsTexture(bufferHandle[FBO_DEPTH]))
            glDeleteTextures(1, &bufferHandle[FBO_DEPTH]);

    if(bufferBit & RBO_DEPTH_BIT && glIsRenderbuffer(renderBufferDepthHandle))
    {
        glDeleteRenderbuffers(1, &renderBufferDepthHandle);
    }
}
Пример #2
0
TextureResource::~TextureResource(){
	
	if(glIsTexture(ids[0])) glDeleteTextures(numTextures, ids);
	if (glIsFramebuffer(frameBuffer)) glDeleteFramebuffers(1, &frameBuffer);
	if (glIsRenderbuffer(renderBuffer)) glDeleteRenderbuffers(1, &renderBuffer);
	if (ids) delete[] ids;
}
Пример #3
0
 template<> template<> const GlObject<GlObject_Type::RenderBuffer>*    GlObject<GlObject_Type::Resource>::ResourceCast() const
 {
     if (glIsRenderbuffer(RawGLHandle(this))) {
         return (GlObject<GlObject_Type::RenderBuffer>*)(this);
     } else {
         return (GlObject<GlObject_Type::RenderBuffer>*)RawGLHandle_Invalid;
     }
 }
Пример #4
0
GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
{
    if (!renderbuffer)
        return GL_FALSE;
    
    makeContextCurrent();
    return glIsRenderbuffer(renderbuffer);
}
Пример #5
0
RenderTargetTexture::~RenderTargetTexture() {
	if (m_fbo && glIsFramebuffer(m_fbo)) {
		glDeleteFramebuffers(1, &m_fbo);
	}

	if (m_depthBuffer && glIsRenderbuffer(m_depthBuffer)) {
		glDeleteRenderbuffers(1, &m_depthBuffer);
	}
}
Пример #6
0
RenderTargetDepthStencil::~RenderTargetDepthStencil()
{
    if(glIsRenderbuffer(_depthStencilBuffer))
    {
        glDeleteRenderbuffers(1, &_depthStencilBuffer);
        _depthStencilBuffer = 0;
    }
#if CC_ENABLE_CACHE_TEXTURE_DATA
    Director::getInstance()->getEventDispatcher()->removeEventListener(_reBuildDepthStencilListener);
#endif
}
Пример #7
0
RenderTargetRenderBuffer::~RenderTargetRenderBuffer()
{
    if(glIsRenderbuffer(_colorBuffer))
    {
        glDeleteRenderbuffers(1, &_colorBuffer);
        _colorBuffer = 0;
    }
#if CC_ENABLE_CACHE_TEXTURE_DATA
    Director::getInstance()->getEventDispatcher()->removeEventListener(_reBuildRenderBufferListener);
#endif
}
Пример #8
0
void GLFramebuffer::setWidthAndHeight(unsigned int width, unsigned int height)
{
    mWidth = std::max(width, 1u);
    mHeight = std::max(height, 1u);

    if (not mFinished)
    {
        return;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);

    if (mDepthTexture != NULL)
    {
        GLTexture *glDepthTex = (GLTexture *)mDepthTexture;

        glBindTexture(GL_TEXTURE_2D, glDepthTex->mTexture);

        glDepthTex->allocData2D(mWidth, mHeight, mDepthFormat, Texture::Depth32F_Format, NULL);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, glDepthTex->mTexture, 0);
    }

    if (glIsRenderbuffer(mDepthRBO) and mDepthTexture == NULL)
    {
        glBindRenderbuffer(GL_RENDERBUFFER, mDepthRBO);

        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight);

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRBO);
    }

    unsigned int i=0;
    GLenum drawBuffers[mColorTextures.size()];

    for (std::vector<ColorTexture>::iterator it = mColorTextures.begin();
         it != mColorTextures.end(); ++it)
    {
        GLTexture *glTexture = (GLTexture *)it->texture;

        glBindTexture(GL_TEXTURE_2D, glTexture->mTexture);

        glTexture->allocData2D(mWidth*it->scale.x, mHeight*it->scale.y, it->format, Texture::RGBU8_Format, NULL);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_2D, glTexture->mTexture, 0);
        drawBuffers[i] = GL_COLOR_ATTACHMENT0+i;

        ++i;
    }

    glDrawBuffers(mColorTextures.size(), drawBuffers);
}
Пример #9
0
void rtt::delete_buffer(rtt::fbo* buffer) {
    for(size_t i = 0; i < buffer->attachment_count; i++) {
        if(buffer->tex[i] == 0) continue;
        glDeleteTextures(1, &buffer->tex[i]);
    }
    for(size_t i = 0; i < buffer->attachment_count; i++) {
        if(buffer->resolve_buffer[i] <= A2E_DEFAULT_FRAMEBUFFER) break;
        glDeleteFramebuffers(1, &buffer->resolve_buffer[i]);
    }

    // depending on how these were created, they can either be renderbuffers or textures
    if(buffer->color_buffer > A2E_DEFAULT_RENDERBUFFER && glIsRenderbuffer(buffer->color_buffer)) {
        glDeleteRenderbuffers(1, &buffer->color_buffer);
        buffer->color_buffer = 0;
    }
    if(buffer->depth_buffer > A2E_DEFAULT_RENDERBUFFER && glIsRenderbuffer(buffer->depth_buffer)) {
        glDeleteRenderbuffers(1, &buffer->depth_buffer);
        buffer->depth_buffer = 0;
    }
    if(buffer->color_buffer > 0 && glIsTexture(buffer->color_buffer)) {
        glDeleteTextures(1, &buffer->color_buffer);
        buffer->color_buffer = 0;
    }
    if(buffer->depth_buffer > 0 && glIsTexture(buffer->depth_buffer)) {
        glDeleteTextures(1, &buffer->depth_buffer);
        buffer->depth_buffer = 0;
    }

    //
    glDeleteFramebuffers(1, &buffer->fbo_id);
    const auto iter = find(begin(buffers), end(buffers), buffer);
    if(iter != end(buffers)) {
        buffers.erase(iter);
        delete buffer;
    }
}
Пример #10
0
void GL3LightingManager::freeResources() {
    if (glIsFramebuffer(_renderFrameBuffer)) {
        glDeleteFramebuffers(1, &_renderFrameBuffer);
        _renderFrameBuffer = 0;
    }

    if (glIsTexture(_gBufferTextures[0])) {
        glDeleteTextures(NUM_GBUFFERS, _gBufferTextures);
        memset(_gBufferTextures, 0, sizeof(_gBufferTextures));
    }

    if (glIsRenderbuffer(_depthRenderBuffer)) {
        glDeleteRenderbuffers(1, &_depthRenderBuffer);
        _depthRenderBuffer = 0;
    }
}
Пример #11
0
GLFramebuffer::~GLFramebuffer()
{
    if (glIsRenderbuffer(mDepthRBO))
    {
        glDeleteRenderbuffers(1, &mDepthRBO);
    }

    DELETE(Texture, mDepthTexture);

    for (std::vector<ColorTexture>::iterator it = mColorTextures.begin();
         it != mColorTextures.end(); ++it)
    {
        DELETE(Texture, it->texture);
    }

    glDeleteFramebuffers(1, &mFramebuffer);
}
Пример #12
0
///////////////////////////////////////////////////////////////////////////////
// return renderbuffer parameters as string using glGetRenderbufferParameteriv
///////////////////////////////////////////////////////////////////////////////
    std::string getRenderbufferParameters(GLuint id) {
        if (glIsRenderbuffer(id) == GL_FALSE)
            return "Not Renderbuffer object";

        int width, height, format;
        std::string formatName;
        glBindRenderbuffer(GL_RENDERBUFFER, id);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);    // get renderbuffer width
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);  // get renderbuffer height
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &format); // get renderbuffer internal format
        glBindRenderbuffer(GL_RENDERBUFFER, 0);

        formatName = convertInternalFormatToString(format);

        std::stringstream ss;
        ss << width << "x" << height << ", " << formatName << "(" << format << ")";
        return ss.str();
    }
Пример #13
0
 template<> void Destroy<GlObject_Type::Resource>(RawGLHandle object)
 {
         //
         //      We don't know the type of this resource.
         //      fall back to the simpliest possible polymorphism...
         //
         //      Just check the type and 
         //
     if (glIsTexture(object)) {
         glDeleteTextures(1, &object);
     } else if (glIsBuffer(object)) {
         glDeleteBuffers(1, &object);
     } else if (glIsFramebuffer(object)) {
         glDeleteFramebuffers(1, &object);
     } else if (glIsRenderbuffer(object)) {
         glDeleteRenderbuffers(1, &object);
     }
 }
Пример #14
0
 gl::boolean_t is_renderbuffer(gl::uint_t renderbuffer) {
   return glIsRenderbuffer(renderbuffer);
 }
Пример #15
0
FBO::~FBO()
{
  if (this->id_depth != 0 && glIsRenderbuffer(this->id_depth)) glDeleteRenderbuffers(1, &this->id_depth);
  if (glIsFramebuffer(this->id) == GL_TRUE) glDeleteFramebuffers(1, &this->id);
}
Пример #16
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(1, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;

        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else if (attachment == QGLFramebufferObject::Depth
               || attachment == QGLFramebufferObject::CombinedDepthStencil)
    {
        glGenRenderbuffers(1, &depth_stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
#define GL_DEPTH_COMPONENT16 0x81A5
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        GLint i = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_stencil_buffer);
        fbo_attachment = QGLFramebufferObject::Depth;
        valid = checkFramebufferStatus();
        if (!valid)
            glDeleteRenderbuffers(1, &depth_stencil_buffer);
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}
Пример #17
0
enum piglit_result
piglit_display(void)
{
	bool pass = true;
	GLchar label[11];
	GLsizei length;
	GLuint ids[10];
	GLint param;

	/* Throw some invalid inputs at glCreateRenderbuffers */

	/* n is negative */
	glCreateRenderbuffers(-1, ids);
	SUBTEST(GL_INVALID_VALUE, pass, "n < 0");

	/* Throw some valid inputs at glCreateRenderbuffers. */

	/* n is zero */
	glCreateRenderbuffers(0, NULL);
	SUBTEST(GL_NO_ERROR, pass, "n == 0");

	/* n is more than 1 */
	glCreateRenderbuffers(10, ids);
	SUBTEST(GL_NO_ERROR, pass, "n > 1");

	/* test the default state of dsa-created render buffer objects */
	SUBTESTCONDITION(glIsRenderbuffer(ids[2]), pass, "IsRenderbuffer()");

	glBindRenderbuffer(GL_RENDERBUFFER, ids[2]);
	piglit_check_gl_error(GL_NO_ERROR);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_WIDTH, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default width(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_HEIGHT, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default height(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_INTERNAL_FORMAT, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == GL_RGBA, pass,
			 "default internal format == RGBA");

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_RED_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default red size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_GREEN_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default green size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_BLUE_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default blue size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_ALPHA_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default alpha size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_DEPTH_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default depth size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_STENCIL_SIZE, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default stencil size(%d) == 0", param);

	glGetRenderbufferParameteriv(GL_RENDERBUFFER,
				     GL_RENDERBUFFER_SAMPLES, &param);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(param == 0, pass,
			 "default no. of samples(%d) == 0", param);

	glGetObjectLabel(GL_RENDERBUFFER, ids[2], 11, &length, label);
	piglit_check_gl_error(GL_NO_ERROR);
	SUBTESTCONDITION(length == 0, pass,
			 "default label size(%d) == 0", length);

	/* clean up */
	glDeleteRenderbuffers(10, ids);

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Пример #18
0
uintptr_t processFn(struct fnargs* args, char* parg) {
	uintptr_t ret = 0;
	switch (args->fn) {
	case glfnUNDEFINED:
		abort(); // bad glfn
		break;
	case glfnActiveTexture:
		glActiveTexture((GLenum)args->a0);
		break;
	case glfnAttachShader:
		glAttachShader((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnBindAttribLocation:
		glBindAttribLocation((GLint)args->a0, (GLint)args->a1, (GLchar*)args->a2);
		break;
	case glfnBindBuffer:
		glBindBuffer((GLenum)args->a0, (GLuint)args->a1);
		break;
	case glfnBindFramebuffer:
		glBindFramebuffer((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBindRenderbuffer:
		glBindRenderbuffer((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBindTexture:
		glBindTexture((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnBlendColor:
		glBlendColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnBlendEquation:
		glBlendEquation((GLenum)args->a0);
		break;
	case glfnBlendEquationSeparate:
		glBlendEquationSeparate((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnBlendFunc:
		glBlendFunc((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnBlendFuncSeparate:
		glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
		break;
	case glfnBufferData:
		glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2);
		break;
	case glfnBufferSubData:
		glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)parg);
		break;
	case glfnCheckFramebufferStatus:
		ret = glCheckFramebufferStatus((GLenum)args->a0);
		break;
	case glfnClear:
		glClear((GLenum)args->a0);
		break;
	case glfnClearColor:
		glClearColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnClearDepthf:
		glClearDepthf(*(GLfloat*)&args->a0);
		break;
	case glfnClearStencil:
		glClearStencil((GLint)args->a0);
		break;
	case glfnColorMask:
		glColorMask((GLboolean)args->a0, (GLboolean)args->a1, (GLboolean)args->a2, (GLboolean)args->a3);
		break;
	case glfnCompileShader:
		glCompileShader((GLint)args->a0);
		break;
	case glfnCompressedTexImage2D:
		glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)parg);
		break;
	case glfnCompressedTexSubImage2D:
		glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)parg);
		break;
	case glfnCopyTexImage2D:
		glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7);
		break;
	case glfnCopyTexSubImage2D:
		glCopyTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7);
		break;
	case glfnCreateProgram:
		ret = glCreateProgram();
		break;
	case glfnCreateShader:
		ret = glCreateShader((GLenum)args->a0);
		break;
	case glfnCullFace:
		glCullFace((GLenum)args->a0);
		break;
	case glfnDeleteBuffer:
		glDeleteBuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteFramebuffer:
		glDeleteFramebuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteProgram:
		glDeleteProgram((GLint)args->a0);
		break;
	case glfnDeleteRenderbuffer:
		glDeleteRenderbuffers(1, (const GLuint*)(&args->a0));
		break;
	case glfnDeleteShader:
		glDeleteShader((GLint)args->a0);
		break;
	case glfnDeleteTexture:
		glDeleteTextures(1, (const GLuint*)(&args->a0));
		break;
	case glfnDepthFunc:
		glDepthFunc((GLenum)args->a0);
		break;
	case glfnDepthMask:
		glDepthMask((GLboolean)args->a0);
		break;
	case glfnDepthRangef:
		glDepthRangef(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnDetachShader:
		glDetachShader((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnDisable:
		glDisable((GLenum)args->a0);
		break;
	case glfnDisableVertexAttribArray:
		glDisableVertexAttribArray((GLint)args->a0);
		break;
	case glfnDrawArrays:
		glDrawArrays((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2);
		break;
	case glfnDrawElements:
		glDrawElements((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (void*)args->a3);
		break;
	case glfnEnable:
		glEnable((GLenum)args->a0);
		break;
	case glfnEnableVertexAttribArray:
		glEnableVertexAttribArray((GLint)args->a0);
		break;
	case glfnFinish:
		glFinish();
		break;
	case glfnFlush:
		glFlush();
		break;
	case glfnFramebufferRenderbuffer:
		glFramebufferRenderbuffer((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3);
		break;
	case glfnFramebufferTexture2D:
		glFramebufferTexture2D((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4);
		break;
	case glfnFrontFace:
		glFrontFace((GLenum)args->a0);
		break;
	case glfnGenBuffer:
		glGenBuffers(1, (GLuint*)&ret);
		break;
	case glfnGenFramebuffer:
		glGenFramebuffers(1, (GLuint*)&ret);
		break;
	case glfnGenRenderbuffer:
		glGenRenderbuffers(1, (GLuint*)&ret);
		break;
	case glfnGenTexture:
		glGenTextures(1, (GLuint*)&ret);
		break;
	case glfnGenerateMipmap:
		glGenerateMipmap((GLenum)args->a0);
		break;
	case glfnGetActiveAttrib:
		glGetActiveAttrib(
			(GLuint)args->a0,
			(GLuint)args->a1,
			(GLsizei)args->a2,
			NULL,
			(GLint*)&ret,
			(GLenum*)args->a3,
			(GLchar*)parg);
		break;
	case glfnGetActiveUniform:
		glGetActiveUniform(
			(GLuint)args->a0,
			(GLuint)args->a1,
			(GLsizei)args->a2,
			NULL,
			(GLint*)&ret,
			(GLenum*)args->a3,
			(GLchar*)parg);
		break;
	case glfnGetAttachedShaders:
		glGetAttachedShaders((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)&ret, (GLuint*)parg);
		break;
	case glfnGetAttribLocation:
		ret = glGetAttribLocation((GLint)args->a0, (GLchar*)args->a1);
		break;
	case glfnGetBooleanv:
		glGetBooleanv((GLenum)args->a0, (GLboolean*)parg);
		break;
	case glfnGetBufferParameteri:
		glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetFloatv:
		glGetFloatv((GLenum)args->a0, (GLfloat*)parg);
		break;
	case glfnGetIntegerv:
		glGetIntegerv((GLenum)args->a0, (GLint*)parg);
		break;
	case glfnGetError:
		ret = glGetError();
		break;
	case glfnGetFramebufferAttachmentParameteriv:
		glGetFramebufferAttachmentParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint*)&ret);
		break;
	case glfnGetProgramiv:
		glGetProgramiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetProgramInfoLog:
		glGetProgramInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetRenderbufferParameteriv:
		glGetRenderbufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetShaderiv:
		glGetShaderiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret);
		break;
	case glfnGetShaderInfoLog:
		glGetShaderInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetShaderPrecisionFormat:
		glGetShaderPrecisionFormat((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg, &((GLint*)parg)[2]);
		break;
	case glfnGetShaderSource:
		glGetShaderSource((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg);
		break;
	case glfnGetString:
		ret = (uintptr_t)glGetString((GLenum)args->a0);
		break;
	case glfnGetTexParameterfv:
		glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnGetTexParameteriv:
		glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnGetUniformfv:
		glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)parg);
		break;
	case glfnGetUniformiv:
		glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)parg);
		break;
	case glfnGetUniformLocation:
		ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1);
		break;
	case glfnGetVertexAttribfv:
		glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnGetVertexAttribiv:
		glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnHint:
		glHint((GLenum)args->a0, (GLenum)args->a1);
		break;
	case glfnIsBuffer:
		ret = glIsBuffer((GLint)args->a0);
		break;
	case glfnIsEnabled:
		ret = glIsEnabled((GLenum)args->a0);
		break;
	case glfnIsFramebuffer:
		ret = glIsFramebuffer((GLint)args->a0);
		break;
	case glfnIsProgram:
		ret = glIsProgram((GLint)args->a0);
		break;
	case glfnIsRenderbuffer:
		ret = glIsRenderbuffer((GLint)args->a0);
		break;
	case glfnIsShader:
		ret = glIsShader((GLint)args->a0);
		break;
	case glfnIsTexture:
		ret = glIsTexture((GLint)args->a0);
		break;
	case glfnLineWidth:
		glLineWidth(*(GLfloat*)&args->a0);
		break;
	case glfnLinkProgram:
		glLinkProgram((GLint)args->a0);
		break;
	case glfnPixelStorei:
		glPixelStorei((GLenum)args->a0, (GLint)args->a1);
		break;
	case glfnPolygonOffset:
		glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnReadPixels:
		glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)parg);
		break;
	case glfnReleaseShaderCompiler:
		glReleaseShaderCompiler();
		break;
	case glfnRenderbufferStorage:
		glRenderbufferStorage((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnSampleCoverage:
		glSampleCoverage(*(GLfloat*)&args->a0, (GLboolean)args->a1);
		break;
	case glfnScissor:
		glScissor((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnShaderSource:
#if defined(os_ios) || defined(os_osx)
		glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar *const *)args->a2, NULL);
#else
		glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar **)args->a2, NULL);
#endif
		break;
	case glfnStencilFunc:
		glStencilFunc((GLenum)args->a0, (GLint)args->a1, (GLuint)args->a2);
		break;
	case glfnStencilFuncSeparate:
		glStencilFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLuint)args->a3);
		break;
	case glfnStencilMask:
		glStencilMask((GLuint)args->a0);
		break;
	case glfnStencilMaskSeparate:
		glStencilMaskSeparate((GLenum)args->a0, (GLuint)args->a1);
		break;
	case glfnStencilOp:
		glStencilOp((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2);
		break;
	case glfnStencilOpSeparate:
		glStencilOpSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3);
		break;
	case glfnTexImage2D:
		glTexImage2D(
			(GLenum)args->a0,
			(GLint)args->a1,
			(GLint)args->a2,
			(GLsizei)args->a3,
			(GLsizei)args->a4,
			0, // border
			(GLenum)args->a5,
			(GLenum)args->a6,
			(const GLvoid*)parg);
		break;
	case glfnTexSubImage2D:
		glTexSubImage2D(
			(GLenum)args->a0,
			(GLint)args->a1,
			(GLint)args->a2,
			(GLint)args->a3,
			(GLsizei)args->a4,
			(GLsizei)args->a5,
			(GLenum)args->a6,
			(GLenum)args->a7,
			(const GLvoid*)parg);
		break;
	case glfnTexParameterf:
		glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnTexParameterfv:
		glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg);
		break;
	case glfnTexParameteri:
		glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2);
		break;
	case glfnTexParameteriv:
		glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg);
		break;
	case glfnUniform1f:
		glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnUniform1fv:
		glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform1i:
		glUniform1i((GLint)args->a0, (GLint)args->a1);
		break;
	case glfnUniform1iv:
		glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform2f:
		glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnUniform2fv:
		glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform2i:
		glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2);
		break;
	case glfnUniform2iv:
		glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform3f:
		glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnUniform3fv:
		glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform3i:
		glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	case glfnUniform3iv:
		glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform4f:
		glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
		break;
	case glfnUniform4fv:
		glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniform4i:
		glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4);
		break;
	case glfnUniform4iv:
		glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg);
		break;
	case glfnUniformMatrix2fv:
		glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUniformMatrix3fv:
		glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUniformMatrix4fv:
		glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg);
		break;
	case glfnUseProgram:
		glUseProgram((GLint)args->a0);
		break;
	case glfnValidateProgram:
		glValidateProgram((GLint)args->a0);
		break;
	case glfnVertexAttrib1f:
		glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1);
		break;
	case glfnVertexAttrib1fv:
		glVertexAttrib1fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib2f:
		glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2);
		break;
	case glfnVertexAttrib2fv:
		glVertexAttrib2fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib3f:
		glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3);
		break;
	case glfnVertexAttrib3fv:
		glVertexAttrib3fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttrib4f:
		glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4);
		break;
	case glfnVertexAttrib4fv:
		glVertexAttrib4fv((GLint)args->a0, (GLfloat*)parg);
		break;
	case glfnVertexAttribPointer:
		glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5);
		break;
	case glfnViewport:
		glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3);
		break;
	}
	return ret;
}
Пример #19
0
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format, GLint samples)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    fbo_guard.setContext(ctx);

    bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
    if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
        return;

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    fbo_guard.setId(fbo);

    glDevice.setFBO(q, attachment);

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        glGenTextures(1, &texture);
        glBindTexture(target, texture);
        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#ifndef QT_OPENGL_ES
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#else
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
        glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);

        samples = qBound(0, int(samples), int(maxSamples));

        glGenRenderbuffers(1, &color_buffer);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer);
        if (glRenderbufferStorageMultisampleEXT && samples > 0) {
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format,
                size.width(), size.height());
        }

        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                     GL_RENDERBUFFER_EXT, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
    }

    // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
    // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
    // might not be supported while separate buffers are, according to QTBUG-12861.

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
        else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT,
                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());

        stencil_buffer = depth_buffer;
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, stencil_buffer);

        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            stencil_buffer = depth_buffer = 0;
        }
    }

    if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
        || (attachment == QGLFramebufferObject::Depth)))
    {
        glGenRenderbuffers(1, &depth_buffer);
        Q_ASSERT(!glIsRenderbuffer(depth_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer);
        Q_ASSERT(glIsRenderbuffer(depth_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
            } else {
                glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                    GL_DEPTH_COMPONENT16, size.width(), size.height());
            }
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, 
                                        size.width(), size.height());
            } else {
                glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, 
                                        size.width(), size.height());
            }
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                     GL_RENDERBUFFER_EXT, depth_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &depth_buffer);
            depth_buffer = 0;
        }
    }

    if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
        glGenRenderbuffers(1, &stencil_buffer);
        Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer);
        Q_ASSERT(glIsRenderbuffer(stencil_buffer));
        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
#ifdef QT_OPENGL_ES
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX8_EXT, size.width(), size.height());
#else
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
                GL_STENCIL_INDEX, size.width(), size.height());
#endif
        } else {
#ifdef QT_OPENGL_ES
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT,
                                  size.width(), size.height());
#else
            glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
                                  size.width(), size.height());
#endif
        }
        glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                  GL_RENDERBUFFER_EXT, stencil_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            glDeleteRenderbuffers(1, &stencil_buffer);
            stencil_buffer = 0;
        }
    }

    // The FBO might have become valid after removing the depth or stencil buffer.
    valid = checkFramebufferStatus();

    if (depth_buffer && stencil_buffer) {
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
    } else if (depth_buffer) {
        fbo_attachment = QGLFramebufferObject::Depth;
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
    if (!valid) {
        if (color_buffer)
            glDeleteRenderbuffers(1, &color_buffer);
        else
            glDeleteTextures(1, &texture);
        if (depth_buffer)
            glDeleteRenderbuffers(1, &depth_buffer);
        if (stencil_buffer && depth_buffer != stencil_buffer)
            glDeleteRenderbuffers(1, &stencil_buffer);
        glDeleteFramebuffers(1, &fbo);
        fbo_guard.setId(0);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
}