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

Rework to support multiple views with OpenGL GAL canvas.

parent 60b0a4e0
...@@ -35,7 +35,7 @@ ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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 ) ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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;
...@@ -45,6 +45,8 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator ); ...@@ -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, ...@@ -54,7 +56,9 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
overlayManager( false ) overlayManager( false )
{ {
// Create the OpenGL-Context // Create the OpenGL-Context
glContext = new wxGLContext( this ); if( glContext == NULL )
glContext = new wxGLContext( this );
parentWindow = aParent; parentWindow = aParent;
mouseListener = aMouseListener; mouseListener = aMouseListener;
paintListener = aPaintListener; paintListener = aPaintListener;
...@@ -113,8 +117,6 @@ OPENGL_GAL::~OPENGL_GAL() ...@@ -113,8 +117,6 @@ OPENGL_GAL::~OPENGL_GAL()
gluDeleteTess( tesselator ); gluDeleteTess( tesselator );
ClearCache(); ClearCache();
delete glContext;
} }
...@@ -122,23 +124,22 @@ void OPENGL_GAL::BeginDrawing() ...@@ -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
{ glMatrixMode( GL_PROJECTION );
// Set up the view port glLoadIdentity();
glMatrixMode( GL_PROJECTION ); glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
glLoadIdentity();
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() ...@@ -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!" ) );
......
...@@ -31,7 +31,8 @@ ...@@ -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 ) ...@@ -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 ) );
} }
......
...@@ -1027,7 +1027,7 @@ struct VIEW::extentsVisitor { ...@@ -1027,7 +1027,7 @@ struct VIEW::extentsVisitor {
bool operator()( VIEW_ITEM* aItem ) bool operator()( VIEW_ITEM* aItem )
{ {
if(first) if( first )
extents = aItem->ViewBBox(); extents = aItem->ViewBBox();
else else
extents.Merge ( aItem->ViewBBox() ); extents.Merge ( aItem->ViewBBox() );
......
...@@ -80,18 +80,17 @@ protected: ...@@ -80,18 +80,17 @@ protected:
GLuint attachmentPoint; ///< Point to which an image from texture is attached GLuint attachmentPoint; ///< Point to which an image from texture is attached
} OPENGL_BUFFER; } OPENGL_BUFFER;
bool m_initialized; ///< Initialization status flag bool m_initialized; ///< Initialization status flag
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: ...@@ -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();
} }
......
...@@ -37,22 +37,12 @@ ...@@ -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: ...@@ -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;
......
...@@ -163,7 +163,7 @@ protected: ...@@ -163,7 +163,7 @@ protected:
* returns size of the reserved memory space. * returns size of the reserved memory space.
* @return Size of the reserved memory space (expressed as a number of vertices). * @return Size of the reserved memory space (expressed as a number of vertices).
*/ */
unsigned int reservedSpace() inline unsigned int reservedSpace()
{ {
return m_currentSize - m_freeSpace; return m_currentSize - m_freeSpace;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment