bool OpenGLComponent::renderAndSwapBuffers()
{
    const ScopedLock sl (contextLock);

   #if JUCE_LINUX
    updateContext();
   #endif

    if (context != nullptr)
    {
        if (! makeCurrentContextActive())
            return false;

        if (needToUpdateViewport)
        {
            needToUpdateViewport = false;
            juce_glViewport (getWidth(), getHeight());
        }

        renderOpenGL();
        swapBuffers();
    }

    return true;
}
void OpenGLWindow::render()
{
    m_painter->beginNativePainting();
    glEnable(GL_MULTISAMPLE);

    renderOpenGL();

    glDisable(GL_MULTISAMPLE);
    m_painter->endNativePainting();

    m_painter->setPen(Qt::red);
    m_painter->setFont(QFont("Monospace", 11));
    m_painter->drawText(QRect(20,60,this->width(),100), Qt::AlignLeft, "FPS: " + QString::number(m_fps));

    m_painter->end();
}
bool OpenGLComponent::performRender()
{
    const ScopedLock sl (contextLock);

   #if JUCE_LINUX
    updateContext();
   #endif

    if (context != nullptr)
    {
        if (! makeCurrentRenderingTarget())
            return false;

        if (needToUpdateViewport)
        {
            needToUpdateViewport = false;
            glViewport (0, 0, getWidth(), getHeight());
        }

        renderOpenGL();

        if (needToRepaint && (flags & allowSubComponents) != 0)
        {
            needToRepaint = false;

            contextLock.exit(); // (MM must be locked before the context lock)
            MessageManagerLock mmLock (renderThread);
            contextLock.enter();

            if (! mmLock.lockWasGained())
                return false;

            // you mustn't set your own cached image object for an OpenGLComponent!
            jassert (dynamic_cast<OpenGLCachedComponentImage*> (getCachedComponentImage()) == cachedImage);

            const Rectangle<int> bounds (getLocalBounds());
            OpenGLFrameBuffer& frameBuffer = cachedImage->getFrameBuffer (bounds.getWidth(), bounds.getHeight());

            {
                RectangleList invalid (bounds);
                invalid.subtract (cachedImage->validArea);
                cachedImage->validArea = bounds;

                if (! invalid.isEmpty())
                {
                    jassert (getCurrentContext() != nullptr);

                    {
                        OpenGLGraphicsContext g (*getCurrentContext(), frameBuffer);
                        g.clipToRectangleList (invalid);

                        g.setFill (Colours::transparentBlack);
                        g.fillRect (bounds, true);
                        g.setFill (Colours::black);

                        paintSelf (g);
                    }

                    makeCurrentRenderingTarget();
                }
            }

            glEnable (GL_TEXTURE_2D);
            context->extensions.glActiveTexture (GL_TEXTURE0);
            glBindTexture (GL_TEXTURE_2D, frameBuffer.getTextureID());

            context->copyTexture (bounds, Rectangle<int> (bounds.getWidth(),
                                                          bounds.getHeight()));
            glBindTexture (GL_TEXTURE_2D, 0);
        }

        swapBuffers();
    }

    return true;
}