bool OpenGLES2Texture::updateImageBuffer()
{
    /* Update dimension and format */
    const bool ReCreateTexture = (GLDimension_ != GLBasePipeline::getGlTexDimension(Type_));
    
    updateFormatAndDimension();
    
    if (ReCreateTexture)
        createHWTexture();
    
    /* Clear the image data */
    glBindTexture(GLDimension_, getTexID());
    
    /* Update format and texture image */
    updateTextureAttributes();
    updateTextureImage();
    
    /* Update render target (create/delete) */
    deleteFramebuffer();
    
    if (isRenderTarget_)
    {
        createFramebuffer(
            getTexID(), ImageBuffer_->getSize(), GLDimension_, ImageBuffer_->getFormat(),
            Type_, CubeMapFace_, ArrayLayer_,
            DepthBufferSource_ ? static_cast<OpenGLES2Texture*>(DepthBufferSource_)->DepthBufferID_ : 0
        );
    }
    
    return true;
}
void OpenGLTexture::updateRenderTarget()
{
    deleteFramebuffer();
    
    if (isRenderTarget_)
    {
        const GLuint DepthBufferSourceID = (DepthBufferSource_ ? static_cast<OpenGLTexture*>(DepthBufferSource_)->DepthBufferID_ : 0);
        
        /* Create GL frame buffer object */
        #ifdef SP_COMPILE_WITH_OPENGL
        if (MultiSamples_ > 0 && GlbRenderSys->RenderQuery_[RenderSystem::RENDERQUERY_MULTISAMPLE_RENDERTARGET])
        {
            createFramebufferMultisample(
                getTexID(), ImageBuffer_->getSize(), GLDimension_, GLInternalFormat_,
                MultiSamples_, MRTList_, ImageBuffer_->getFormat(),
                Type_, CubeMapFace_, ArrayLayer_, DepthBufferSourceID
            );
        }
        else
        #endif
        {
            createFramebuffer(
                getTexID(), ImageBuffer_->getSize(), GLDimension_, ImageBuffer_->getFormat(),
                Type_, CubeMapFace_, ArrayLayer_, DepthBufferSourceID
            );
        }
    }
    
    /* Refresh MRT view list for all referenced textures */
    refreshRefMRT();
}
Context::~Context()
{
    mState.reset();

    while (!mFramebufferMap.empty())
    {
        // Delete the framebuffer in reverse order to destroy the framebuffer zero last.
        deleteFramebuffer(mFramebufferMap.rbegin()->first);
    }

    while (!mFenceNVMap.empty())
    {
        deleteFenceNV(mFenceNVMap.begin()->first);
    }

    while (!mQueryMap.empty())
    {
        deleteQuery(mQueryMap.begin()->first);
    }

    while (!mVertexArrayMap.empty())
    {
        deleteVertexArray(mVertexArrayMap.begin()->first);
    }

    mTransformFeedbackZero.set(NULL);
    while (!mTransformFeedbackMap.empty())
    {
        deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
    }

    for (auto &zeroTexture : mZeroTextures)
    {
        zeroTexture.second.set(NULL);
    }
    mZeroTextures.clear();

    if (mResourceManager)
    {
        mResourceManager->release();
    }

    SafeDelete(mCompiler);
}
OpenGLES2Texture::~OpenGLES2Texture()
{
    deleteFramebuffer();
}