Rework to support multiple views with OpenGL GAL canvas.
This commit is contained in:
parent
60b0a4e0be
commit
0fc93666c6
|
@ -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();
|
||||
|
||||
// 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 );
|
||||
|
||||
if( !isFramebufferInitialized )
|
||||
{
|
||||
// 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 );
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue