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 @@
using namespace KIGFX;
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 )
return;
// Get the maximum number of buffers
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &m_maxBuffers );
// We need framebuffer objects for drawing the screen contents
// Generate framebuffer and a depth buffer
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
// 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,
GL_RENDERBUFFER_EXT, m_depthBuffer );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER_EXT, m_depthBuffer );
GL_RENDERBUFFER_EXT, m_depthBuffer );
// Unbind the framebuffer, so by default all the rendering goes directly to the display
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING );
m_currentFbo = 0;
m_currentFbo = DIRECT_RENDERING;
m_initialized = true;
}
......@@ -96,9 +91,14 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
{
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 "
"your graphic drivers." ) );
return 0; // Unfortunately we have no more free buffers left
......@@ -114,7 +114,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
// Set texture parameters
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 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_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
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 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
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
......@@ -132,38 +133,38 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
switch( status )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
DisplayError( NULL, wxT( "Cannot create the framebuffer." ) );
DisplayError( NULL, _( "Cannot create the framebuffer." ) );
break;
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;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
DisplayError( NULL, wxT( "The framebuffer does not have at least "
"one image attached to it." ) );
DisplayError( NULL, _( "The framebuffer does not have at least "
"one image attached to it." ) );
break;
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;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
DisplayError( NULL, wxT( "The combination of internal formats of the attached images "
"violates an implementation-dependent set of restrictions." ) );
DisplayError( NULL, _( "The combination of internal formats of the attached images "
"violates an implementation-dependent set of restrictions." ) );
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
DisplayError( NULL, wxT( "GL_RENDERBUFFER_SAMPLES is not the same "
"for all attached renderbuffers" ) );
DisplayError( NULL, _( "GL_RENDERBUFFER_SAMPLES is not the same "
"for all attached renderbuffers" ) );
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
DisplayError( NULL, wxT( "Framebuffer incomplete layer targets errors." ) );
DisplayError( NULL, _( "Framebuffer incomplete layer targets errors." ) );
break;
default:
DisplayError( NULL, wxT( "Cannot create the framebuffer." ) );
DisplayError( NULL, _( "Cannot create the framebuffer." ) );
break;
}
......@@ -192,7 +193,6 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
// Change the rendering destination to the selected attachment point
if( aBufferHandle == DIRECT_RENDERING )
{
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING;
}
else if( m_currentFbo != m_framebuffer )
......@@ -221,12 +221,7 @@ void OPENGL_COMPOSITOR::ClearBuffer()
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
{
wxASSERT( m_initialized );
if( aBufferHandle == 0 || aBufferHandle > usedBuffers() )
{
DisplayError( NULL, wxT( "Wrong framebuffer handle" ) );
return;
}
wxASSERT( aBufferHandle != 0 && aBufferHandle <= usedBuffers() );
// Switch to the main framebuffer and blit the scene
glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
......@@ -274,8 +269,8 @@ void OPENGL_COMPOSITOR::clean()
{
wxASSERT( m_initialized );
glDeleteFramebuffersEXT( 1, &m_framebuffer );
glDeleteRenderbuffersEXT( 1, &m_depthBuffer );
glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING;
OPENGL_BUFFERS::const_iterator it;
......@@ -286,8 +281,8 @@ void OPENGL_COMPOSITOR::clean()
m_buffers.clear();
glDeleteFramebuffersEXT( 1, &m_framebuffer );
glDeleteRenderbuffersEXT( 1, &m_depthBuffer );
m_initialized = false;
}
GLuint OPENGL_COMPOSITOR::m_currentFbo = DIRECT_RENDERING;
......@@ -45,6 +45,8 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator );
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,
wxEvtHandler* aPaintListener, const wxString& aName ) :
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
......@@ -54,7 +56,9 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
overlayManager( false )
{
// Create the OpenGL-Context
glContext = new wxGLContext( this );
if( glContext == NULL )
glContext = new wxGLContext( this );
parentWindow = aParent;
mouseListener = aMouseListener;
paintListener = aPaintListener;
......@@ -113,8 +117,6 @@ OPENGL_GAL::~OPENGL_GAL()
gluDeleteTess( tesselator );
ClearCache();
delete glContext;
}
......@@ -122,23 +124,22 @@ void OPENGL_GAL::BeginDrawing()
{
SetCurrent( *glContext );
clientDC = new wxClientDC( this );
clientDC = new wxPaintDC( this );
// Initialize GLEW, FBOs & VBOs
if( !isGlewInitialized )
initGlew();
if( !isFramebufferInitialized )
{
// Set up the view port
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
// Set up the view port
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
// Create the screen transformation
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y,
-depthRange.x, -depthRange.y );
// Create the screen transformation
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y );
if( !isFramebufferInitialized )
{
// Prepare rendering target buffers
compositor.Initialize();
mainBuffer = compositor.CreateBuffer();
......@@ -967,7 +968,7 @@ void OPENGL_GAL::initGlew()
exit( 1 );
}
// Vertex buffer have to be supported
// Vertex buffer has to be supported
if( !GLEW_ARB_vertex_buffer_object )
{
DisplayError( parentWindow, wxT( "Vertex buffer objects are not supported!" ) );
......
......@@ -31,7 +31,8 @@
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/shader.h>
#include <wx/log.h>
#include <cstdlib>
#include <cstring>
using namespace KIGFX;
......@@ -45,9 +46,11 @@ VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached )
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 ) ) );
memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
}
......
......@@ -1027,7 +1027,7 @@ struct VIEW::extentsVisitor {
bool operator()( VIEW_ITEM* aItem )
{
if(first)
if( first )
extents = aItem->ViewBBox();
else
extents.Merge ( aItem->ViewBBox() );
......
......@@ -80,18 +80,17 @@ protected:
GLuint attachmentPoint; ///< Point to which an image from texture is attached
} OPENGL_BUFFER;
bool m_initialized; ///< Initialization status flag
unsigned int m_current; ///< Currently used buffer handle
GLuint m_framebuffer; ///< Main FBO handle
GLuint m_depthBuffer; ///< Depth buffer handle
unsigned int m_maxBuffers; ///< Maximal amount of buffers
bool m_initialized; ///< Initialization status flag
unsigned int m_current; ///< Currently used buffer handle
GLuint m_framebuffer; ///< Main FBO handle
GLuint m_depthBuffer; ///< Depth buffer handle
typedef std::deque<OPENGL_BUFFER> OPENGL_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
static GLuint m_currentFbo;
GLuint m_currentFbo;
/**
* Function clean()
......@@ -100,7 +99,7 @@ protected:
void clean();
/// Returns number of used buffers
unsigned int usedBuffers()
inline unsigned int usedBuffers()
{
return m_buffers.size();
}
......
......@@ -37,22 +37,12 @@
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/opengl_compositor.h>
#include <wx/wx.h>
#include <wx/glcanvas.h>
#include <cmath>
#include <iterator>
#include <vector>
#include <algorithm>
#include <memory>
#include <map>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/shared_array.hpp>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#ifndef CALLBACK
#define CALLBACK
#endif
......@@ -262,8 +252,8 @@ private:
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
wxClientDC* clientDC; ///< Drawing context
wxGLContext* glContext; ///< OpenGL context of wxWidgets
wxPaintDC* clientDC; ///< Drawing context
static wxGLContext* glContext; ///< OpenGL context of wxWidgets
wxWindow* parentWindow; ///< Parent window
wxEvtHandler* mouseListener;
wxEvtHandler* paintListener;
......
......@@ -163,7 +163,7 @@ protected:
* returns size of the reserved memory space.
* @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;
}
......
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