Commit 0fc93666 authored by Maciej Suminski's avatar Maciej Suminski
Browse files

Rework to support multiple views with OpenGL GAL canvas.

parent 60b0a4e0
Loading
Loading
Loading
Loading
+31 −36
Original line number Original line Diff line number Diff line
@@ -35,7 +35,7 @@
using namespace KIGFX;
using namespace KIGFX;


OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
    m_initialized( false ), m_current( 0 )
    m_initialized( false ), m_current( 0 ), m_currentFbo( DIRECT_RENDERING )
{
{
}
}


@@ -52,9 +52,6 @@ void OPENGL_COMPOSITOR::Initialize()
    if( m_initialized )
    if( m_initialized )
        return;
        return;


    // Get the maximum number of buffers
    glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &m_maxBuffers );

    // We need framebuffer objects for drawing the screen contents
    // We need framebuffer objects for drawing the screen contents
    // Generate framebuffer and a depth buffer
    // Generate framebuffer and a depth buffer
    glGenFramebuffersEXT( 1, &m_framebuffer );
    glGenFramebuffersEXT( 1, &m_framebuffer );
@@ -68,15 +65,13 @@ void OPENGL_COMPOSITOR::Initialize()


    // Use here a size of 24 bits for the depth buffer, 8 bits for the stencil buffer
    // Use here a size of 24 bits for the depth buffer, 8 bits for the stencil buffer
    // this is required later for anti-aliasing
    // this is required later for anti-aliasing
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL, m_width, m_height );
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_width, m_height );
    glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT,
    glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT,
                                  GL_RENDERBUFFER_EXT, m_depthBuffer );
                                  GL_RENDERBUFFER_EXT, m_depthBuffer );
    glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT,
                               GL_RENDERBUFFER_EXT, m_depthBuffer );


    // Unbind the framebuffer, so by default all the rendering goes directly to the display
    // Unbind the framebuffer, so by default all the rendering goes directly to the display
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING );
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING );
    m_currentFbo = 0;
    m_currentFbo = DIRECT_RENDERING;


    m_initialized = true;
    m_initialized = true;
}
}
@@ -96,9 +91,14 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
{
{
    wxASSERT( m_initialized );
    wxASSERT( m_initialized );


    if( usedBuffers() >= m_maxBuffers )
    unsigned int maxBuffers;

    // Get the maximum number of buffers
    glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &maxBuffers );

    if( usedBuffers() >= maxBuffers )
    {
    {
        DisplayError( NULL, wxT( "Cannot create more framebuffers. OpenGL rendering "
        DisplayError( NULL, _( "Cannot create more framebuffers. OpenGL rendering "
                        "backend requires at least 3 framebuffers. You may try to update/change "
                        "backend requires at least 3 framebuffers. You may try to update/change "
                        "your graphic drivers." ) );
                        "your graphic drivers." ) );
        return 0;    // Unfortunately we have no more free buffers left
        return 0;    // Unfortunately we have no more free buffers left
@@ -114,7 +114,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()


    // Set texture parameters
    // Set texture parameters
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA,
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA,
                  GL_UNSIGNED_BYTE, NULL );
                  GL_UNSIGNED_BYTE, NULL );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
@@ -122,7 +122,8 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
    // Bind the texture to the specific attachment point, clear and rebind the screen
    // Bind the texture to the specific attachment point, clear and rebind the screen
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_framebuffer );
    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_framebuffer );
    m_currentFbo = m_framebuffer;
    m_currentFbo = m_framebuffer;
    glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint, GL_TEXTURE_2D, textureTarget, 0 );
    glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint,
                               GL_TEXTURE_2D, textureTarget, 0 );


    // Check the status, exit if the framebuffer can't be created
    // Check the status, exit if the framebuffer can't be created
    GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
    GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
@@ -132,38 +133,38 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
        switch( status )
        switch( status )
        {
        {
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
            DisplayError( NULL, wxT( "Cannot create the framebuffer." ) );
            DisplayError( NULL, _( "Cannot create the framebuffer." ) );
            break;
            break;


        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
            DisplayError( NULL, wxT( "The framebuffer attachment points are incomplete." ) );
            DisplayError( NULL, _( "The framebuffer attachment points are incomplete." ) );
            break;
            break;


        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
            DisplayError( NULL, wxT( "The framebuffer does not have at least "
            DisplayError( NULL, _( "The framebuffer does not have at least "
                                   "one image attached to it." ) );
                                   "one image attached to it." ) );
            break;
            break;


        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
            DisplayError( NULL, wxT( "The framebuffer read buffer is incomplete." ) );
            DisplayError( NULL, _( "The framebuffer read buffer is incomplete." ) );
            break;
            break;


        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
            DisplayError( NULL, wxT( "The combination of internal formats of the attached images "
            DisplayError( NULL, _( "The combination of internal formats of the attached images "
                                   "violates an implementation-dependent set of restrictions." ) );
                                   "violates an implementation-dependent set of restrictions." ) );
            break;
            break;


        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
            DisplayError( NULL, wxT( "GL_RENDERBUFFER_SAMPLES is not the same "
            DisplayError( NULL, _( "GL_RENDERBUFFER_SAMPLES is not the same "
                                   "for all attached renderbuffers" ) );
                                   "for all attached renderbuffers" ) );
            break;
            break;


        case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
        case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
            DisplayError( NULL, wxT( "Framebuffer incomplete layer targets errors." ) );
            DisplayError( NULL, _( "Framebuffer incomplete layer targets errors." ) );
            break;
            break;


        default:
        default:
            DisplayError( NULL, wxT( "Cannot create the framebuffer." ) );
            DisplayError( NULL, _( "Cannot create the framebuffer." ) );
            break;
            break;
        }
        }


@@ -192,7 +193,6 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
    // Change the rendering destination to the selected attachment point
    // Change the rendering destination to the selected attachment point
    if( aBufferHandle == DIRECT_RENDERING )
    if( aBufferHandle == DIRECT_RENDERING )
    {
    {
        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING );
        m_currentFbo = DIRECT_RENDERING;
        m_currentFbo = DIRECT_RENDERING;
    }
    }
    else if( m_currentFbo != m_framebuffer )
    else if( m_currentFbo != m_framebuffer )
@@ -221,12 +221,7 @@ void OPENGL_COMPOSITOR::ClearBuffer()
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
{
{
    wxASSERT( m_initialized );
    wxASSERT( m_initialized );

    wxASSERT( aBufferHandle != 0 && aBufferHandle <= usedBuffers() );
    if( aBufferHandle == 0 || aBufferHandle > usedBuffers() )
    {
        DisplayError( NULL, wxT( "Wrong framebuffer handle" ) );
        return;
    }


    // Switch to the main framebuffer and blit the scene
    // Switch to the main framebuffer and blit the scene
    glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
    glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
@@ -274,8 +269,8 @@ void OPENGL_COMPOSITOR::clean()
{
{
    wxASSERT( m_initialized );
    wxASSERT( m_initialized );


    glDeleteFramebuffersEXT( 1, &m_framebuffer );
    glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
    glDeleteRenderbuffersEXT( 1, &m_depthBuffer );
    m_currentFbo = DIRECT_RENDERING;


    OPENGL_BUFFERS::const_iterator it;
    OPENGL_BUFFERS::const_iterator it;


@@ -286,8 +281,8 @@ void OPENGL_COMPOSITOR::clean()


    m_buffers.clear();
    m_buffers.clear();


    glDeleteFramebuffersEXT( 1, &m_framebuffer );
    glDeleteRenderbuffersEXT( 1, &m_depthBuffer );

    m_initialized = false;
    m_initialized = false;
}
}


GLuint OPENGL_COMPOSITOR::m_currentFbo = DIRECT_RENDERING;
+15 −14
Original line number Original line Diff line number Diff line
@@ -45,6 +45,8 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator );


const int glAttributes[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0 };
const int glAttributes[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0 };


wxGLContext* OPENGL_GAL::glContext = NULL;

OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
                        wxEvtHandler* aPaintListener, const wxString& aName ) :
                        wxEvtHandler* aPaintListener, const wxString& aName ) :
    wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
    wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
@@ -54,7 +56,9 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
    overlayManager( false )
    overlayManager( false )
{
{
    // Create the OpenGL-Context
    // Create the OpenGL-Context
    if( glContext == NULL )
        glContext = new wxGLContext( this );
        glContext = new wxGLContext( this );

    parentWindow    = aParent;
    parentWindow    = aParent;
    mouseListener   = aMouseListener;
    mouseListener   = aMouseListener;
    paintListener   = aPaintListener;
    paintListener   = aPaintListener;
@@ -113,8 +117,6 @@ OPENGL_GAL::~OPENGL_GAL()


    gluDeleteTess( tesselator );
    gluDeleteTess( tesselator );
    ClearCache();
    ClearCache();

    delete glContext;
}
}




@@ -122,23 +124,22 @@ void OPENGL_GAL::BeginDrawing()
{
{
    SetCurrent( *glContext );
    SetCurrent( *glContext );


    clientDC = new wxClientDC( this );
    clientDC = new wxPaintDC( this );


    // Initialize GLEW, FBOs & VBOs
    // Initialize GLEW, FBOs & VBOs
    if( !isGlewInitialized )
    if( !isGlewInitialized )
        initGlew();
        initGlew();


    if( !isFramebufferInitialized )
    {
    // Set up the view port
    // Set up the view port
    glMatrixMode( GL_PROJECTION );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glLoadIdentity();
    glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
    glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );


    // Create the screen transformation
    // Create the screen transformation
        glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y,
    glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y );
                -depthRange.x, -depthRange.y );


    if( !isFramebufferInitialized )
    {
        // Prepare rendering target buffers
        // Prepare rendering target buffers
        compositor.Initialize();
        compositor.Initialize();
        mainBuffer = compositor.CreateBuffer();
        mainBuffer = compositor.CreateBuffer();
@@ -967,7 +968,7 @@ void OPENGL_GAL::initGlew()
        exit( 1 );
        exit( 1 );
    }
    }


    // Vertex buffer have to be supported
    // Vertex buffer has to be supported
    if( !GLEW_ARB_vertex_buffer_object )
    if( !GLEW_ARB_vertex_buffer_object )
    {
    {
        DisplayError( parentWindow, wxT( "Vertex buffer objects are not supported!" ) );
        DisplayError( parentWindow, wxT( "Vertex buffer objects are not supported!" ) );
+5 −2
Original line number Original line Diff line number Diff line
@@ -31,7 +31,8 @@
#include <gal/opengl/cached_container.h>
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/shader.h>
#include <gal/opengl/shader.h>
#include <wx/log.h>
#include <cstdlib>
#include <cstring>


using namespace KIGFX;
using namespace KIGFX;


@@ -45,9 +46,11 @@ VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached )




VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
    m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ), m_failed( false )
    m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ),
    m_failed( false ), m_dirty( true )
{
{
    m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
    m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
    memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
}
}




+7 −8
Original line number Original line Diff line number Diff line
@@ -84,14 +84,13 @@ protected:
    unsigned int    m_current;                ///< Currently used buffer handle
    unsigned int    m_current;                ///< Currently used buffer handle
    GLuint          m_framebuffer;            ///< Main FBO handle
    GLuint          m_framebuffer;            ///< Main FBO handle
    GLuint          m_depthBuffer;            ///< Depth buffer handle
    GLuint          m_depthBuffer;            ///< Depth buffer handle
    unsigned int                m_maxBuffers;             ///< Maximal amount of buffers
    typedef std::deque<OPENGL_BUFFER> OPENGL_BUFFERS;
    typedef std::deque<OPENGL_BUFFER> OPENGL_BUFFERS;


    /// Stores information about initialized buffers
    /// Stores information about initialized buffers
    OPENGL_BUFFERS  m_buffers;
    OPENGL_BUFFERS  m_buffers;


    /// Store the currently used FBO name in case there was more than one compositor used
    /// Store the currently used FBO name in case there was more than one compositor used
    static GLuint               m_currentFbo;
    GLuint          m_currentFbo;


    /**
    /**
     * Function clean()
     * Function clean()
@@ -100,7 +99,7 @@ protected:
    void clean();
    void clean();


    /// Returns number of used buffers
    /// Returns number of used buffers
    unsigned int usedBuffers()
    inline unsigned int usedBuffers()
    {
    {
        return m_buffers.size();
        return m_buffers.size();
    }
    }
+2 −12
Original line number Original line Diff line number Diff line
@@ -37,22 +37,12 @@
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/opengl_compositor.h>
#include <gal/opengl/opengl_compositor.h>


#include <wx/wx.h>
#include <wx/glcanvas.h>
#include <wx/glcanvas.h>


#include <cmath>
#include <iterator>
#include <vector>
#include <algorithm>
#include <memory>
#include <map>
#include <map>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/shared_array.hpp>
#include <boost/smart_ptr/shared_array.hpp>


#include <stdlib.h>
#include <iostream>
#include <fstream>

#ifndef CALLBACK
#ifndef CALLBACK
#define CALLBACK
#define CALLBACK
#endif
#endif
@@ -262,8 +252,8 @@ private:
    static const int    CIRCLE_POINTS   = 64;   ///< The number of points for circle approximation
    static const int    CIRCLE_POINTS   = 64;   ///< The number of points for circle approximation
    static const int    CURVE_POINTS    = 32;   ///< The number of points for curve approximation
    static const int    CURVE_POINTS    = 32;   ///< The number of points for curve approximation


    wxClientDC*             clientDC;               ///< Drawing context
    wxPaintDC*              clientDC;               ///< Drawing context
    wxGLContext*            glContext;              ///< OpenGL context of wxWidgets
    static wxGLContext*     glContext;              ///< OpenGL context of wxWidgets
    wxWindow*               parentWindow;           ///< Parent window
    wxWindow*               parentWindow;           ///< Parent window
    wxEvtHandler*           mouseListener;
    wxEvtHandler*           mouseListener;
    wxEvtHandler*           paintListener;
    wxEvtHandler*           paintListener;
Loading