Code refactoring.
This commit is contained in:
parent
790a1f8563
commit
190ed58568
|
@ -69,6 +69,7 @@ unsigned int CAIRO_COMPOSITOR::GetBuffer()
|
|||
{
|
||||
// Pixel storage
|
||||
BitmapPtr bitmap( new unsigned int[m_bufferSize] );
|
||||
|
||||
memset( bitmap.get(), 0x00, m_bufferSize * sizeof(int) );
|
||||
|
||||
// Create the Cairo surface
|
||||
|
@ -105,6 +106,7 @@ void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
|||
m_current = aBufferHandle - 1;
|
||||
*m_currentContext = m_buffers[m_current].context;
|
||||
}
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
else
|
||||
wxLogDebug( wxT( "Tried to use a not existing buffer" ) );
|
||||
|
@ -141,6 +143,7 @@ void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
|||
// Restore the transformation matrix
|
||||
cairo_set_matrix( m_mainContext, &m_matrix );
|
||||
}
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
else
|
||||
wxLogDebug( wxT( "Tried to use a not existing buffer" ) );
|
||||
|
|
|
@ -87,117 +87,7 @@ CAIRO_GAL::~CAIRO_GAL()
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
screenSize = VECTOR2D( aWidth, aHeight );
|
||||
|
||||
// Recreate the bitmaps
|
||||
deleteBitmaps();
|
||||
allocateBitmaps();
|
||||
|
||||
SetSize( wxSize( aWidth, aHeight ) );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
// Post the mouse event to the event listener registered in constructor, if any
|
||||
if( mouseListener )
|
||||
wxPostEvent( mouseListener, aEvent );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::initSurface()
|
||||
{
|
||||
wxASSERT( !isInitialized );
|
||||
|
||||
// Create the Cairo surface
|
||||
surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT,
|
||||
screenSize.x, screenSize.y, stride );
|
||||
context = cairo_create( surface );
|
||||
#ifdef __WXDEBUG__
|
||||
cairo_status_t status = cairo_status( context );
|
||||
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
|
||||
#endif /* __WXDEBUG__ */
|
||||
currentContext = context;
|
||||
|
||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
|
||||
|
||||
// Clear the screen
|
||||
ClearScreen();
|
||||
|
||||
// Compute the world <-> screen transformations
|
||||
ComputeWorldScreenMatrix();
|
||||
|
||||
cairo_matrix_init( &cairoWorldScreenMatrix, worldScreenMatrix.m_data[0][0],
|
||||
worldScreenMatrix.m_data[1][0], worldScreenMatrix.m_data[0][1],
|
||||
worldScreenMatrix.m_data[1][1], worldScreenMatrix.m_data[0][2],
|
||||
worldScreenMatrix.m_data[1][2] );
|
||||
|
||||
cairo_set_matrix( context, &cairoWorldScreenMatrix );
|
||||
|
||||
isSetAttributes = false;
|
||||
|
||||
// Start drawing with a new path
|
||||
cairo_new_path( context );
|
||||
isElementAdded = true;
|
||||
|
||||
cairo_set_line_join( context, CAIRO_LINE_JOIN_ROUND );
|
||||
cairo_set_line_cap( context, CAIRO_LINE_CAP_ROUND );
|
||||
|
||||
lineWidth = 0;
|
||||
|
||||
isDeleteSavedPixels = true;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::deinitSurface()
|
||||
{
|
||||
if( !isInitialized )
|
||||
return;
|
||||
|
||||
// Destroy Cairo objects
|
||||
cairo_destroy( context );
|
||||
cairo_surface_destroy( surface );
|
||||
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::setCompositor()
|
||||
{
|
||||
// Recreate the compositor with the new Cairo context
|
||||
compositor.reset( new CAIRO_COMPOSITOR( ¤tContext ) );
|
||||
compositor->Resize( screenSize.x, screenSize.y );
|
||||
|
||||
// Prepare buffers
|
||||
mainBuffer = compositor->GetBuffer();
|
||||
overlayBuffer = compositor->GetBuffer();
|
||||
}
|
||||
|
||||
|
||||
unsigned int CAIRO_GAL::getNewGroupNumber()
|
||||
{
|
||||
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
|
||||
wxT( "There are no free slots to store a group" ) );
|
||||
|
||||
while( groups.find( groupCounter ) != groups.end() )
|
||||
{
|
||||
groupCounter++;
|
||||
}
|
||||
|
||||
return groupCounter++;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::BeginDrawing() throw( int )
|
||||
void CAIRO_GAL::BeginDrawing()
|
||||
{
|
||||
initSurface();
|
||||
setCompositor();
|
||||
|
@ -245,65 +135,6 @@ void CAIRO_GAL::EndDrawing()
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SaveScreen()
|
||||
{
|
||||
// Copy the current bitmap to the backup buffer
|
||||
int offset = 0;
|
||||
|
||||
for( int j = 0; j < screenSize.y; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBufferBackup[offset + i] = bitmapBuffer[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::RestoreScreen()
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
for( int j = 0; j < screenSize.y; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBuffer[offset + i] = bitmapBufferBackup[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetTarget( RenderTarget aTarget )
|
||||
{
|
||||
// If the compositor is not set, that means that there is a recaching process going on
|
||||
// and we do not need the compositor now
|
||||
if( !compositor )
|
||||
return;
|
||||
|
||||
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
||||
cairo_pop_group_to_source( currentContext );
|
||||
cairo_paint_with_alpha( currentContext, fillColor.a );
|
||||
|
||||
switch( aTarget )
|
||||
{
|
||||
default:
|
||||
case TARGET_CACHED:
|
||||
case TARGET_NONCACHED:
|
||||
compositor->SetBuffer( mainBuffer );
|
||||
break;
|
||||
|
||||
case TARGET_OVERLAY:
|
||||
compositor->SetBuffer( overlayBuffer );
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_push_group( currentContext );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
||||
|
@ -373,36 +204,6 @@ void CAIRO_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aS
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
// Iterate over the point list and draw the segments
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
cairo_move_to( currentContext, it->x, it->y );
|
||||
for( ++it; it != aPointList.end(); ++it )
|
||||
{
|
||||
cairo_line_to( currentContext, it->x, it->y );
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
// Iterate over the point list and draw the polygon
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
cairo_move_to( currentContext, it->x, it->y );
|
||||
for( ++it; it != aPointList.end(); ++it )
|
||||
{
|
||||
cairo_line_to( currentContext, it->x, it->y );
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
// Calculate the diagonal points
|
||||
|
@ -420,6 +221,38 @@ void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
// Iterate over the point list and draw the segments
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
cairo_move_to( currentContext, it->x, it->y );
|
||||
|
||||
for( ++it; it != aPointList.end(); ++it )
|
||||
{
|
||||
cairo_line_to( currentContext, it->x, it->y );
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
// Iterate over the point list and draw the polygon
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
cairo_move_to( currentContext, it->x, it->y );
|
||||
|
||||
for( ++it; it != aPointList.end(); ++it )
|
||||
{
|
||||
cairo_line_to( currentContext, it->x, it->y );
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
|
||||
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
|
@ -432,9 +265,41 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetBackgroundColor( const COLOR4D& aColor )
|
||||
void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
backgroundColor = aColor;
|
||||
screenSize = VECTOR2D( aWidth, aHeight );
|
||||
|
||||
// Recreate the bitmaps
|
||||
deleteBitmaps();
|
||||
allocateBitmaps();
|
||||
|
||||
SetSize( wxSize( aWidth, aHeight ) );
|
||||
}
|
||||
|
||||
|
||||
bool CAIRO_GAL::Show( bool aShow )
|
||||
{
|
||||
bool s = wxWindow::Show( aShow );
|
||||
|
||||
if( aShow )
|
||||
wxWindow::Raise();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Flush()
|
||||
{
|
||||
storePath();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ClearScreen()
|
||||
{
|
||||
cairo_set_source_rgb( currentContext,
|
||||
backgroundColor.r, backgroundColor.g, backgroundColor.b );
|
||||
cairo_rectangle( currentContext, 0.0, 0.0, screenSize.x, screenSize.y );
|
||||
cairo_fill( currentContext );
|
||||
}
|
||||
|
||||
|
||||
|
@ -528,15 +393,6 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth )
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ClearScreen()
|
||||
{
|
||||
cairo_set_source_rgb( currentContext,
|
||||
backgroundColor.r, backgroundColor.g, backgroundColor.b );
|
||||
cairo_rectangle( currentContext, 0.0, 0.0, screenSize.x, screenSize.y );
|
||||
cairo_fill( currentContext );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetLayerDepth( double aLayerDepth )
|
||||
{
|
||||
super::SetLayerDepth( aLayerDepth );
|
||||
|
@ -686,35 +542,6 @@ void CAIRO_GAL::EndGroup()
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ClearCache()
|
||||
{
|
||||
for( int i = groups.size() - 1; i >= 0; --i )
|
||||
{
|
||||
DeleteGroup( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
storePath();
|
||||
|
||||
// Delete the Cairo paths
|
||||
std::deque<GroupElement>::iterator it, end;
|
||||
|
||||
for( it = groups[aGroupNumber].begin(), end = groups[aGroupNumber].end(); it != end; ++it )
|
||||
{
|
||||
if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH )
|
||||
{
|
||||
cairo_path_destroy( it->cairoPath );
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the group
|
||||
groups.erase( aGroupNumber );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawGroup( int aGroupNumber )
|
||||
{
|
||||
// This method implements a small Virtual Machine - all stored commands
|
||||
|
@ -828,103 +655,91 @@ void CAIRO_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Flush()
|
||||
void CAIRO_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
storePath();
|
||||
}
|
||||
|
||||
// Delete the Cairo paths
|
||||
std::deque<GroupElement>::iterator it, end;
|
||||
|
||||
void CAIRO_GAL::ComputeWorldScreenMatrix()
|
||||
for( it = groups[aGroupNumber].begin(), end = groups[aGroupNumber].end(); it != end; ++it )
|
||||
{
|
||||
ComputeWorldScale();
|
||||
|
||||
worldScreenMatrix.SetIdentity();
|
||||
|
||||
MATRIX3x3D translation;
|
||||
translation.SetIdentity();
|
||||
translation.SetTranslation( 0.5 * screenSize );
|
||||
|
||||
MATRIX3x3D scale;
|
||||
scale.SetIdentity();
|
||||
scale.SetScale( VECTOR2D( worldScale, worldScale ) );
|
||||
|
||||
MATRIX3x3D lookat;
|
||||
lookat.SetIdentity();
|
||||
lookat.SetTranslation( -lookAtPoint );
|
||||
|
||||
worldScreenMatrix = translation * scale * lookat * worldScreenMatrix;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::storePath()
|
||||
if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH )
|
||||
{
|
||||
if( isElementAdded )
|
||||
{
|
||||
isElementAdded = false;
|
||||
|
||||
if( !isGrouping )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
cairo_set_source_rgb( currentContext, fillColor.r, fillColor.g, fillColor.b );
|
||||
cairo_fill_preserve( currentContext );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
cairo_set_source_rgb( currentContext, strokeColor.r, strokeColor.g, strokeColor.b );
|
||||
cairo_stroke_preserve( currentContext );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the actual path, append it to the global path list
|
||||
// then check, if the path needs to be stroked/filled and
|
||||
// add this command to the group list;
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||
groupElement.command = CMD_STROKE_PATH;
|
||||
currentGroup->push_back( groupElement );
|
||||
}
|
||||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||
groupElement.command = CMD_FILL_PATH;
|
||||
currentGroup->push_back( groupElement );
|
||||
cairo_path_destroy( it->cairoPath );
|
||||
}
|
||||
}
|
||||
|
||||
cairo_new_path( currentContext );
|
||||
// Delete the group
|
||||
groups.erase( aGroupNumber );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ClearCache()
|
||||
{
|
||||
for( int i = groups.size() - 1; i >= 0; --i )
|
||||
{
|
||||
DeleteGroup( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------
|
||||
// Cursor handling
|
||||
// ---------------
|
||||
|
||||
|
||||
void CAIRO_GAL::initCursor( int aCursorSize )
|
||||
void CAIRO_GAL::SaveScreen()
|
||||
{
|
||||
cursorPixels = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorPixelsSaved = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorSize = aCursorSize;
|
||||
// Copy the current bitmap to the backup buffer
|
||||
int offset = 0;
|
||||
|
||||
wxMemoryDC cursorShape( *cursorPixels );
|
||||
for( int j = 0; j < screenSize.y; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBufferBackup[offset + i] = bitmapBuffer[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursorShape.SetBackground( *wxTRANSPARENT_BRUSH );
|
||||
wxColour color( cursorColor.r * cursorColor.a * 255, cursorColor.g * cursorColor.a * 255,
|
||||
cursorColor.b * cursorColor.a * 255, 255 );
|
||||
wxPen pen = wxPen( color );
|
||||
cursorShape.SetPen( pen );
|
||||
cursorShape.Clear();
|
||||
|
||||
cursorShape.DrawLine( 0, aCursorSize / 2, aCursorSize, aCursorSize / 2 );
|
||||
cursorShape.DrawLine( aCursorSize / 2, 0, aCursorSize / 2, aCursorSize );
|
||||
void CAIRO_GAL::RestoreScreen()
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
for( int j = 0; j < screenSize.y; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBuffer[offset + i] = bitmapBufferBackup[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetTarget( RenderTarget aTarget )
|
||||
{
|
||||
// If the compositor is not set, that means that there is a recaching process going on
|
||||
// and we do not need the compositor now
|
||||
if( !compositor )
|
||||
return;
|
||||
|
||||
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
||||
cairo_pop_group_to_source( currentContext );
|
||||
cairo_paint_with_alpha( currentContext, fillColor.a );
|
||||
|
||||
switch( aTarget )
|
||||
{
|
||||
default:
|
||||
case TARGET_CACHED:
|
||||
case TARGET_NONCACHED:
|
||||
compositor->SetBuffer( mainBuffer );
|
||||
break;
|
||||
|
||||
case TARGET_OVERLAY:
|
||||
compositor->SetBuffer( overlayBuffer );
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_push_group( currentContext );
|
||||
}
|
||||
|
||||
|
||||
|
@ -975,7 +790,7 @@ void CAIRO_GAL::DrawCursor( VECTOR2D aCursorPosition )
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
void CAIRO_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||
|
@ -984,6 +799,88 @@ void CAIRO_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::storePath()
|
||||
{
|
||||
if( isElementAdded )
|
||||
{
|
||||
isElementAdded = false;
|
||||
|
||||
if( !isGrouping )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
cairo_set_source_rgb( currentContext, fillColor.r, fillColor.g, fillColor.b );
|
||||
cairo_fill_preserve( currentContext );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
cairo_set_source_rgb( currentContext, strokeColor.r, strokeColor.g,
|
||||
strokeColor.b );
|
||||
cairo_stroke_preserve( currentContext );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the actual path, append it to the global path list
|
||||
// then check, if the path needs to be stroked/filled and
|
||||
// add this command to the group list;
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||
groupElement.command = CMD_STROKE_PATH;
|
||||
currentGroup->push_back( groupElement );
|
||||
}
|
||||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||
groupElement.command = CMD_FILL_PATH;
|
||||
currentGroup->push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
cairo_new_path( currentContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
// Post the mouse event to the event listener registered in constructor, if any
|
||||
if( mouseListener )
|
||||
wxPostEvent( mouseListener, aEvent );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::initCursor( int aCursorSize )
|
||||
{
|
||||
cursorPixels = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorPixelsSaved = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorSize = aCursorSize;
|
||||
|
||||
wxMemoryDC cursorShape( *cursorPixels );
|
||||
|
||||
cursorShape.SetBackground( *wxTRANSPARENT_BRUSH );
|
||||
wxColour color( cursorColor.r * cursorColor.a * 255, cursorColor.g * cursorColor.a * 255,
|
||||
cursorColor.b * cursorColor.a * 255, 255 );
|
||||
wxPen pen = wxPen( color );
|
||||
cursorShape.SetPen( pen );
|
||||
cursorShape.Clear();
|
||||
|
||||
cursorShape.DrawLine( 0, aCursorSize / 2, aCursorSize, aCursorSize / 2 );
|
||||
cursorShape.DrawLine( aCursorSize / 2, 0, aCursorSize / 2, aCursorSize );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::allocateBitmaps()
|
||||
{
|
||||
// Create buffer, use the system independent Cairo context backend
|
||||
|
@ -1004,12 +901,83 @@ void CAIRO_GAL::deleteBitmaps()
|
|||
}
|
||||
|
||||
|
||||
bool CAIRO_GAL::Show( bool aShow )
|
||||
void CAIRO_GAL::initSurface()
|
||||
{
|
||||
bool s = wxWindow::Show( aShow );
|
||||
wxASSERT( !isInitialized );
|
||||
|
||||
if( aShow )
|
||||
wxWindow::Raise();
|
||||
// Create the Cairo surface
|
||||
surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT,
|
||||
screenSize.x, screenSize.y, stride );
|
||||
context = cairo_create( surface );
|
||||
#ifdef __WXDEBUG__
|
||||
cairo_status_t status = cairo_status( context );
|
||||
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
|
||||
#endif /* __WXDEBUG__ */
|
||||
currentContext = context;
|
||||
|
||||
return s;
|
||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
|
||||
|
||||
// Clear the screen
|
||||
ClearScreen();
|
||||
|
||||
// Compute the world <-> screen transformations
|
||||
ComputeWorldScreenMatrix();
|
||||
|
||||
cairo_matrix_init( &cairoWorldScreenMatrix, worldScreenMatrix.m_data[0][0],
|
||||
worldScreenMatrix.m_data[1][0], worldScreenMatrix.m_data[0][1],
|
||||
worldScreenMatrix.m_data[1][1], worldScreenMatrix.m_data[0][2],
|
||||
worldScreenMatrix.m_data[1][2] );
|
||||
|
||||
cairo_set_matrix( context, &cairoWorldScreenMatrix );
|
||||
|
||||
// Start drawing with a new path
|
||||
cairo_new_path( context );
|
||||
isElementAdded = true;
|
||||
|
||||
cairo_set_line_join( context, CAIRO_LINE_JOIN_ROUND );
|
||||
cairo_set_line_cap( context, CAIRO_LINE_CAP_ROUND );
|
||||
|
||||
lineWidth = 0;
|
||||
|
||||
isDeleteSavedPixels = true;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::deinitSurface()
|
||||
{
|
||||
if( !isInitialized )
|
||||
return;
|
||||
|
||||
// Destroy Cairo objects
|
||||
cairo_destroy( context );
|
||||
cairo_surface_destroy( surface );
|
||||
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::setCompositor()
|
||||
{
|
||||
// Recreate the compositor with the new Cairo context
|
||||
compositor.reset( new CAIRO_COMPOSITOR( ¤tContext ) );
|
||||
compositor->Resize( screenSize.x, screenSize.y );
|
||||
|
||||
// Prepare buffers
|
||||
mainBuffer = compositor->GetBuffer();
|
||||
overlayBuffer = compositor->GetBuffer();
|
||||
}
|
||||
|
||||
|
||||
unsigned int CAIRO_GAL::getNewGroupNumber()
|
||||
{
|
||||
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
|
||||
wxT( "There are no free slots to store a group" ) );
|
||||
|
||||
while( groups.find( groupCounter ) != groups.end() )
|
||||
{
|
||||
groupCounter++;
|
||||
}
|
||||
|
||||
return groupCounter++;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,33 @@ GAL::~GAL()
|
|||
}
|
||||
|
||||
|
||||
void GAL::ComputeWorldScreenMatrix()
|
||||
{
|
||||
ComputeWorldScale();
|
||||
|
||||
worldScreenMatrix.SetIdentity();
|
||||
|
||||
MATRIX3x3D translation;
|
||||
translation.SetIdentity();
|
||||
translation.SetTranslation( 0.5 * screenSize );
|
||||
|
||||
MATRIX3x3D scale;
|
||||
scale.SetIdentity();
|
||||
scale.SetScale( VECTOR2D( worldScale, worldScale ) );
|
||||
|
||||
MATRIX3x3D flip;
|
||||
flip.SetIdentity();
|
||||
flip.SetScale( VECTOR2D( 1.0, 1.0 ) );
|
||||
|
||||
MATRIX3x3D lookat;
|
||||
lookat.SetIdentity();
|
||||
lookat.SetTranslation( -lookAtPoint );
|
||||
|
||||
worldScreenMatrix = translation * flip * scale * lookat * worldScreenMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GAL::DrawGrid()
|
||||
{
|
||||
if( !gridVisibility )
|
||||
|
@ -136,7 +163,7 @@ void GAL::DrawGrid()
|
|||
if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold )
|
||||
|| gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
DrawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y ),
|
||||
drawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y ),
|
||||
VECTOR2D( gridEndX * gridSize.x, j * gridSize.y ) );
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +182,7 @@ void GAL::DrawGrid()
|
|||
if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold )
|
||||
|| gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
DrawGridLine( VECTOR2D( i * gridSize.x, gridStartY * gridSize.y ),
|
||||
drawGridLine( VECTOR2D( i * gridSize.x, gridStartY * gridSize.y ),
|
||||
VECTOR2D( i * gridSize.x, gridEndY * gridSize.y ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,9 +229,11 @@ void OPENGL_COMPOSITOR::clean()
|
|||
{
|
||||
glDeleteTextures( 1, &it->textureTarget );
|
||||
}
|
||||
|
||||
m_buffers.clear();
|
||||
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
GLuint OPENGL_COMPOSITOR::m_currentFbo = 0;
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#endif /* __WXDEBUG__ */
|
||||
|
||||
#include <limits>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#ifndef CALLBACK
|
||||
#define CALLBACK
|
||||
|
@ -94,9 +93,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
|||
tesselator = gluNewTess();
|
||||
InitTesselatorCallbacks( tesselator );
|
||||
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
|
||||
|
||||
// Compute the unit circle vertices and store them in a buffer for faster drawing
|
||||
computeCircle();
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,109 +107,6 @@ OPENGL_GAL::~OPENGL_GAL()
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
screenSize = VECTOR2D( aWidth, aHeight );
|
||||
|
||||
// Resize framebuffers
|
||||
compositor.Resize( aWidth, aHeight );
|
||||
isFramebufferInitialized = false;
|
||||
|
||||
wxGLCanvas::SetSize( aWidth, aHeight );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
// Post the mouse event to the event listener registered in constructor, if any
|
||||
if( mouseListener )
|
||||
wxPostEvent( mouseListener, aEvent );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SaveScreen()
|
||||
{
|
||||
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::RestoreScreen()
|
||||
{
|
||||
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetTarget( RenderTarget aTarget )
|
||||
{
|
||||
switch( aTarget )
|
||||
{
|
||||
default:
|
||||
case TARGET_CACHED:
|
||||
currentManager = &cachedManager;
|
||||
break;
|
||||
|
||||
case TARGET_NONCACHED:
|
||||
currentManager = &nonCachedManager;
|
||||
break;
|
||||
|
||||
case TARGET_OVERLAY:
|
||||
currentManager = &overlayManager;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::initGlew()
|
||||
{
|
||||
// Initialize GLEW library
|
||||
GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( (char*) glewGetErrorString( err ) ) );
|
||||
exit( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug( wxString( wxT( "Status: Using GLEW " ) ) +
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
// Check the OpenGL version (minimum 2.1 is required)
|
||||
if( GLEW_VERSION_2_1 )
|
||||
{
|
||||
wxLogInfo( wxT( "OpenGL Version 2.1 supported." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError( wxT( "OpenGL Version 2.1 is not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// Framebuffers have to be supported
|
||||
if( !GLEW_ARB_framebuffer_object )
|
||||
{
|
||||
wxLogError( wxT( "Framebuffer objects are not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// Vertex buffer have to be supported
|
||||
if( !GLEW_ARB_vertex_buffer_object )
|
||||
{
|
||||
wxLogError( wxT( "Vertex buffer objects are not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
isGlewInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::BeginDrawing()
|
||||
{
|
||||
SetCurrent( *glContext );
|
||||
|
@ -232,7 +125,8 @@ void OPENGL_GAL::BeginDrawing()
|
|||
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 );
|
||||
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y,
|
||||
-depthRange.x, -depthRange.y );
|
||||
|
||||
// Prepare rendering target buffers
|
||||
compositor.Initialize();
|
||||
|
@ -333,37 +227,16 @@ void OPENGL_GAL::EndDrawing()
|
|||
}
|
||||
|
||||
|
||||
inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
double scale = 0.5 * lineWidth / lineLength;
|
||||
const VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
if( lineLength <= 0.0 )
|
||||
return;
|
||||
drawLineQuad( aStartPoint, aEndPoint );
|
||||
|
||||
// The perpendicular vector also needs transformations
|
||||
glm::vec4 vector = currentManager->GetTransformation() *
|
||||
glm::vec4( -startEndVector.y * scale, startEndVector.x * scale, 0.0, 0.0 );
|
||||
|
||||
// Line width is maintained by the vertex shader
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v2
|
||||
// Line caps
|
||||
drawFilledSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
drawFilledSemiCircle( aEndPoint, lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,93 +287,6 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
|
|||
}
|
||||
|
||||
|
||||
unsigned int OPENGL_GAL::getNewGroupNumber()
|
||||
{
|
||||
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
|
||||
wxT( "There are no free slots to store a group" ) );
|
||||
|
||||
while( groups.find( groupCounter ) != groups.end() )
|
||||
{
|
||||
groupCounter++;
|
||||
}
|
||||
|
||||
return groupCounter++;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
const VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( aStartPoint, aEndPoint );
|
||||
|
||||
// Line caps
|
||||
drawFilledSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
drawFilledSemiCircle( aEndPoint, lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
// Start from the second point
|
||||
for( it++; it != aPointList.end(); it++ )
|
||||
{
|
||||
const VECTOR2D startEndVector = ( *it - *( it - 1 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( *( it - 1 ), *it );
|
||||
|
||||
// There is no need to draw line caps on both ends of polyline's segments
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
}
|
||||
|
||||
// ..and now - draw the ending cap
|
||||
const VECTOR2D startEndVector = ( *( it - 1 ) - *( it - 2 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
// Compute the diagonal points of the rectangle
|
||||
VECTOR2D diagonalPointA( aEndPoint.x, aStartPoint.y );
|
||||
VECTOR2D diagonalPointB( aStartPoint.x, aEndPoint.y );
|
||||
|
||||
// Stroke the outline
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
std::deque<VECTOR2D> pointList;
|
||||
pointList.push_back( aStartPoint );
|
||||
pointList.push_back( diagonalPointA );
|
||||
pointList.push_back( aEndPoint );
|
||||
pointList.push_back( diagonalPointB );
|
||||
pointList.push_back( aStartPoint );
|
||||
DrawPolyline( pointList );
|
||||
}
|
||||
|
||||
// Fill the rectangle
|
||||
if( isFillEnabled )
|
||||
{
|
||||
currentManager->Shader( SHADER_NONE );
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth );
|
||||
currentManager->Vertex( diagonalPointA.x, diagonalPointA.y, layerDepth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth );
|
||||
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth );
|
||||
currentManager->Vertex( diagonalPointB.x, diagonalPointB.y, layerDepth );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
|
@ -508,13 +294,13 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
|
||||
Parameters given to setShader are indices of the triangle's vertices
|
||||
(if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
Shader uses this coordinates to determine if fragments are inside the circle or not.
|
||||
v2
|
||||
/\
|
||||
//\\
|
||||
v0 /_\/_\ v1
|
||||
* Parameters given to setShader are indices of the triangle's vertices
|
||||
* (if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
* Shader uses this coordinates to determine if fragments are inside the circle or not.
|
||||
* v2
|
||||
* /\
|
||||
* //\\
|
||||
* v0 /_\/_\ v1
|
||||
*/
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 1.0 );
|
||||
currentManager->Vertex( aCenterPoint.x - aRadius * sqrt( 3.0f ), // v0
|
||||
|
@ -534,14 +320,14 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
|
||||
Parameters given to setShader are indices of the triangle's vertices
|
||||
(if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
and the line width. Shader uses this coordinates to determine if fragments are
|
||||
inside the circle or not.
|
||||
v2
|
||||
/\
|
||||
//\\
|
||||
v0 /_\/_\ v1
|
||||
* Parameters given to setShader are indices of the triangle's vertices
|
||||
* (if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
* and the line width. Shader uses this coordinates to determine if fragments are
|
||||
* inside the circle or not.
|
||||
* v2
|
||||
* /\
|
||||
* //\\
|
||||
* v0 /_\/_\ v1
|
||||
*/
|
||||
double outerRadius = aRadius + ( lineWidth / 2 );
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 1.0, aRadius, lineWidth );
|
||||
|
@ -559,84 +345,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
drawFilledSemiCircle( aCenterPoint, aRadius, aAngle );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
drawStrokedSemiCircle( aCenterPoint, aRadius, aAngle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aAngle )
|
||||
{
|
||||
Save();
|
||||
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
|
||||
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
/* Draw a triangle that contains the semicircle, then shade it to leave only
|
||||
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
|
||||
(if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
Shader uses this coordinates to determine if fragments are inside the semicircle or not.
|
||||
v2
|
||||
/\
|
||||
/__\
|
||||
v0 //__\\ v1
|
||||
*/
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 4.0f );
|
||||
currentManager->Vertex( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 5.0f );
|
||||
currentManager->Vertex( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 6.0f );
|
||||
currentManager->Vertex( 0.0f, aRadius * 2.0f, layerDepth ); // v2
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aAngle )
|
||||
{
|
||||
double outerRadius = aRadius + ( lineWidth / 2 );
|
||||
|
||||
Save();
|
||||
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
|
||||
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
/* Draw a triangle that contains the semicircle, then shade it to leave only
|
||||
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
|
||||
(if you want to understand more, check the vertex shader source [shader.vert]), the
|
||||
radius and the line width. Shader uses this coordinates to determine if fragments are
|
||||
inside the semicircle or not.
|
||||
v2
|
||||
/\
|
||||
/__\
|
||||
v0 //__\\ v1
|
||||
*/
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 4.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( -outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 5.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 6.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( 0.0f, outerRadius * 2.0f, layerDepth ); // v2
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
|
||||
// FIXME Optimize
|
||||
void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||
double aEndAngle )
|
||||
{
|
||||
|
@ -700,33 +408,64 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
}
|
||||
|
||||
|
||||
struct OGLPOINT
|
||||
void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
OGLPOINT() :
|
||||
x( 0.0 ), y( 0.0 ), z( 0.0 )
|
||||
{}
|
||||
// Compute the diagonal points of the rectangle
|
||||
VECTOR2D diagonalPointA( aEndPoint.x, aStartPoint.y );
|
||||
VECTOR2D diagonalPointB( aStartPoint.x, aEndPoint.y );
|
||||
|
||||
OGLPOINT( const char* fastest )
|
||||
// Stroke the outline
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
// do nothing for fastest speed, and keep inline
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
std::deque<VECTOR2D> pointList;
|
||||
pointList.push_back( aStartPoint );
|
||||
pointList.push_back( diagonalPointA );
|
||||
pointList.push_back( aEndPoint );
|
||||
pointList.push_back( diagonalPointB );
|
||||
pointList.push_back( aStartPoint );
|
||||
DrawPolyline( pointList );
|
||||
}
|
||||
|
||||
OGLPOINT( const VECTOR2D& aPoint ) :
|
||||
x( aPoint.x ), y( aPoint.y ), z( 0.0 )
|
||||
{}
|
||||
|
||||
OGLPOINT& operator=( const VECTOR2D& aPoint )
|
||||
// Fill the rectangle
|
||||
if( isFillEnabled )
|
||||
{
|
||||
x = aPoint.x;
|
||||
y = aPoint.y;
|
||||
z = 0.0;
|
||||
return *this;
|
||||
currentManager->Shader( SHADER_NONE );
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth );
|
||||
currentManager->Vertex( diagonalPointA.x, diagonalPointA.y, layerDepth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth );
|
||||
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth );
|
||||
currentManager->Vertex( diagonalPointB.x, diagonalPointB.y, layerDepth );
|
||||
}
|
||||
}
|
||||
|
||||
GLdouble x;
|
||||
GLdouble y;
|
||||
GLdouble z;
|
||||
};
|
||||
|
||||
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
// Start from the second point
|
||||
for( it++; it != aPointList.end(); it++ )
|
||||
{
|
||||
const VECTOR2D startEndVector = ( *it - *( it - 1 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( *( it - 1 ), *it );
|
||||
|
||||
// There is no need to draw line caps on both ends of polyline's segments
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
}
|
||||
|
||||
// ..and now - draw the ending cap
|
||||
const VECTOR2D startEndVector = ( *( it - 1 ) - *( it - 2 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
||||
|
@ -808,34 +547,32 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetStrokeColor( const COLOR4D& aColor )
|
||||
void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
isSetAttributes = true;
|
||||
strokeColor = aColor;
|
||||
screenSize = VECTOR2D( aWidth, aHeight );
|
||||
|
||||
// This is the default drawing color
|
||||
currentManager->Color( aColor.r, aColor.g, aColor.b, aColor.a );
|
||||
// Resize framebuffers
|
||||
compositor.Resize( aWidth, aHeight );
|
||||
isFramebufferInitialized = false;
|
||||
|
||||
wxGLCanvas::SetSize( aWidth, aHeight );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetFillColor( const COLOR4D& aColor )
|
||||
bool OPENGL_GAL::Show( bool aShow )
|
||||
{
|
||||
isSetAttributes = true;
|
||||
fillColor = aColor;
|
||||
bool s = wxGLCanvas::Show( aShow );
|
||||
|
||||
if( aShow )
|
||||
wxGLCanvas::Raise();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetBackgroundColor( const COLOR4D& aColor )
|
||||
void OPENGL_GAL::Flush()
|
||||
{
|
||||
isSetAttributes = true;
|
||||
backgroundColor = aColor;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetLineWidth( double aLineWidth )
|
||||
{
|
||||
isSetAttributes = true;
|
||||
lineWidth = aLineWidth;
|
||||
glFlush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -847,6 +584,15 @@ void OPENGL_GAL::ClearScreen()
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::SetStrokeColor( const COLOR4D& aColor )
|
||||
{
|
||||
strokeColor = aColor;
|
||||
|
||||
// This is the default drawing color
|
||||
currentManager->Color( aColor.r, aColor.g, aColor.b, aColor.a );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::Transform( MATRIX3x3D aTransformation )
|
||||
{
|
||||
GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
|
||||
|
@ -883,12 +629,6 @@ void OPENGL_GAL::Scale( const VECTOR2D& aScale )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::Flush()
|
||||
{
|
||||
glFlush();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::Save()
|
||||
{
|
||||
currentManager->PushMatrix();
|
||||
|
@ -919,19 +659,6 @@ void OPENGL_GAL::EndGroup()
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::ClearCache()
|
||||
{
|
||||
groups.clear();
|
||||
cachedManager.Clear();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
groups.erase( aGroupNumber );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawGroup( int aGroupNumber )
|
||||
{
|
||||
cachedManager.DrawItem( *groups[aGroupNumber] );
|
||||
|
@ -950,123 +677,48 @@ void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::computeCircle()
|
||||
void OPENGL_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
VERTEX* vertex = circleContainer.Allocate( CIRCLE_POINTS );
|
||||
|
||||
// Compute the circle points for a given number of segments
|
||||
for( int i = 0; i < CIRCLE_POINTS; ++i )
|
||||
{
|
||||
vertex->x = 0.0f;
|
||||
vertex->y = 0.0f;
|
||||
vertex->z = 0.0f;
|
||||
vertex++;
|
||||
|
||||
vertex->x = cos( 2.0 * M_PI / CIRCLE_POINTS * i );
|
||||
vertex->y = sin( 2.0 * M_PI / CIRCLE_POINTS * i );
|
||||
vertex->z = 0.0f;
|
||||
vertex++;
|
||||
|
||||
vertex->x = cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) );
|
||||
vertex->y = sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) );
|
||||
vertex->z = 0.0f;
|
||||
vertex++;
|
||||
}
|
||||
groups.erase( aGroupNumber );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::ComputeWorldScreenMatrix()
|
||||
void OPENGL_GAL::ClearCache()
|
||||
{
|
||||
ComputeWorldScale();
|
||||
|
||||
worldScreenMatrix.SetIdentity();
|
||||
|
||||
MATRIX3x3D translation;
|
||||
translation.SetIdentity();
|
||||
translation.SetTranslation( 0.5 * screenSize );
|
||||
|
||||
MATRIX3x3D scale;
|
||||
scale.SetIdentity();
|
||||
scale.SetScale( VECTOR2D( worldScale, worldScale ) );
|
||||
|
||||
MATRIX3x3D flip;
|
||||
flip.SetIdentity();
|
||||
flip.SetScale( VECTOR2D( 1.0, 1.0 ) );
|
||||
|
||||
MATRIX3x3D lookat;
|
||||
lookat.SetIdentity();
|
||||
lookat.SetTranslation( -lookAtPoint );
|
||||
|
||||
worldScreenMatrix = translation * flip * scale * lookat * worldScreenMatrix;
|
||||
groups.clear();
|
||||
cachedManager.Clear();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Callback functions for the tesselator
|
||||
// -------------------------------------
|
||||
|
||||
// Compare Redbook Chapter 11
|
||||
|
||||
|
||||
void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
|
||||
void OPENGL_GAL::SaveScreen()
|
||||
{
|
||||
GLdouble* vertex = static_cast<GLdouble*>( aVertexPtr );
|
||||
OPENGL_GAL::TessParams* param = static_cast<OPENGL_GAL::TessParams*>( aData );
|
||||
VERTEX_MANAGER* vboManager = param->vboManager;
|
||||
|
||||
if( vboManager )
|
||||
vboManager->Vertex( vertex[0], vertex[1], vertex[2] );
|
||||
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK CombineCallback( GLdouble coords[3],
|
||||
GLdouble* vertex_data[4],
|
||||
GLfloat weight[4], GLdouble** dataOut, void* aData )
|
||||
void OPENGL_GAL::RestoreScreen()
|
||||
{
|
||||
GLdouble* vertex = new GLdouble[3];
|
||||
OPENGL_GAL::TessParams* param = static_cast<OPENGL_GAL::TessParams*>( aData );
|
||||
|
||||
// Save the pointer so we can delete it later
|
||||
param->intersectPoints.push_back( vertex );
|
||||
|
||||
memcpy( vertex, coords, 3 * sizeof(GLdouble) );
|
||||
|
||||
*dataOut = vertex;
|
||||
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK EdgeCallback(void)
|
||||
void OPENGL_GAL::SetTarget( RenderTarget aTarget )
|
||||
{
|
||||
// This callback is needed to force GLU tesselator to use triangles only
|
||||
switch( aTarget )
|
||||
{
|
||||
default:
|
||||
case TARGET_CACHED:
|
||||
currentManager = &cachedManager;
|
||||
break;
|
||||
|
||||
case TARGET_NONCACHED:
|
||||
currentManager = &nonCachedManager;
|
||||
break;
|
||||
|
||||
case TARGET_OVERLAY:
|
||||
currentManager = &overlayManager;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK ErrorCallback( GLenum aErrorCode )
|
||||
{
|
||||
const GLubyte* estring;
|
||||
|
||||
estring = gluErrorString( aErrorCode );
|
||||
wxLogError( wxT( "Tessellation Error: %s" ), (char*) estring );
|
||||
}
|
||||
|
||||
|
||||
void InitTesselatorCallbacks( GLUtesselator* aTesselator )
|
||||
{
|
||||
gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_EDGE_FLAG, ( void (CALLBACK*)() )EdgeCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_ERROR_DATA, ( void (CALLBACK*)() )ErrorCallback );
|
||||
}
|
||||
|
||||
|
||||
// ---------------
|
||||
// Cursor handling
|
||||
// ---------------
|
||||
|
||||
|
||||
void OPENGL_GAL::initCursor( int aCursorSize )
|
||||
{
|
||||
cursorSize = aCursorSize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1140,7 +792,7 @@ void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
compositor.SetBuffer( mainBuffer );
|
||||
|
||||
|
@ -1165,12 +817,247 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
|||
}
|
||||
|
||||
|
||||
bool OPENGL_GAL::Show( bool aShow )
|
||||
inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
bool s = wxGLCanvas::Show( aShow );
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
double scale = 0.5 * lineWidth / lineLength;
|
||||
|
||||
if( aShow )
|
||||
wxGLCanvas::Raise();
|
||||
if( lineLength <= 0.0 )
|
||||
return;
|
||||
|
||||
return s;
|
||||
// The perpendicular vector also needs transformations
|
||||
glm::vec4 vector = currentManager->GetTransformation() *
|
||||
glm::vec4( -startEndVector.y * scale, startEndVector.x * scale, 0.0, 0.0 );
|
||||
|
||||
// Line width is maintained by the vertex shader
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
currentManager->Vertex( aEndPoint.x, aEndPoint.y, layerDepth ); // v2
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
drawFilledSemiCircle( aCenterPoint, aRadius, aAngle );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
drawStrokedSemiCircle( aCenterPoint, aRadius, aAngle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aAngle )
|
||||
{
|
||||
Save();
|
||||
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
|
||||
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
/* Draw a triangle that contains the semicircle, then shade it to leave only
|
||||
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
|
||||
* (if you want to understand more, check the vertex shader source [shader.vert]).
|
||||
* Shader uses this coordinates to determine if fragments are inside the semicircle or not.
|
||||
* v2
|
||||
* /\
|
||||
* /__\
|
||||
* v0 //__\\ v1
|
||||
*/
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 4.0f );
|
||||
currentManager->Vertex( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 5.0f );
|
||||
currentManager->Vertex( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_FILLED_CIRCLE, 6.0f );
|
||||
currentManager->Vertex( 0.0f, aRadius * 2.0f, layerDepth ); // v2
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aAngle )
|
||||
{
|
||||
double outerRadius = aRadius + ( lineWidth / 2 );
|
||||
|
||||
Save();
|
||||
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
|
||||
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
/* Draw a triangle that contains the semicircle, then shade it to leave only
|
||||
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
|
||||
* (if you want to understand more, check the vertex shader source [shader.vert]), the
|
||||
* radius and the line width. Shader uses this coordinates to determine if fragments are
|
||||
* inside the semicircle or not.
|
||||
* v2
|
||||
* /\
|
||||
* /__\
|
||||
* v0 //__\\ v1
|
||||
*/
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 4.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( -outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
|
||||
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 5.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
|
||||
|
||||
currentManager->Shader( SHADER_STROKED_CIRCLE, 6.0f, aRadius, lineWidth );
|
||||
currentManager->Vertex( 0.0f, outerRadius * 2.0f, layerDepth ); // v2
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
// Post the mouse event to the event listener registered in constructor, if any
|
||||
if( mouseListener )
|
||||
wxPostEvent( mouseListener, aEvent );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::initGlew()
|
||||
{
|
||||
// Initialize GLEW library
|
||||
GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( (char*) glewGetErrorString( err ) ) );
|
||||
exit( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug( wxString( wxT( "Status: Using GLEW " ) ) +
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
// Check the OpenGL version (minimum 2.1 is required)
|
||||
if( GLEW_VERSION_2_1 )
|
||||
{
|
||||
wxLogInfo( wxT( "OpenGL Version 2.1 supported." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError( wxT( "OpenGL Version 2.1 is not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// Framebuffers have to be supported
|
||||
if( !GLEW_ARB_framebuffer_object )
|
||||
{
|
||||
wxLogError( wxT( "Framebuffer objects are not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// Vertex buffer have to be supported
|
||||
if( !GLEW_ARB_vertex_buffer_object )
|
||||
{
|
||||
wxLogError( wxT( "Vertex buffer objects are not supported!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
isGlewInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::initCursor( int aCursorSize )
|
||||
{
|
||||
cursorSize = aCursorSize;
|
||||
}
|
||||
|
||||
|
||||
unsigned int OPENGL_GAL::getNewGroupNumber()
|
||||
{
|
||||
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
|
||||
wxT( "There are no free slots to store a group" ) );
|
||||
|
||||
while( groups.find( groupCounter ) != groups.end() )
|
||||
{
|
||||
groupCounter++;
|
||||
}
|
||||
|
||||
return groupCounter++;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Callback functions for the tesselator
|
||||
// -------------------------------------
|
||||
|
||||
// Compare Redbook Chapter 11
|
||||
void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
|
||||
{
|
||||
GLdouble* vertex = static_cast<GLdouble*>( aVertexPtr );
|
||||
OPENGL_GAL::TessParams* param = static_cast<OPENGL_GAL::TessParams*>( aData );
|
||||
VERTEX_MANAGER* vboManager = param->vboManager;
|
||||
|
||||
if( vboManager )
|
||||
vboManager->Vertex( vertex[0], vertex[1], vertex[2] );
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK CombineCallback( GLdouble coords[3],
|
||||
GLdouble* vertex_data[4],
|
||||
GLfloat weight[4], GLdouble** dataOut, void* aData )
|
||||
{
|
||||
GLdouble* vertex = new GLdouble[3];
|
||||
OPENGL_GAL::TessParams* param = static_cast<OPENGL_GAL::TessParams*>( aData );
|
||||
|
||||
// Save the pointer so we can delete it later
|
||||
param->intersectPoints.push_back( vertex );
|
||||
|
||||
memcpy( vertex, coords, 3 * sizeof(GLdouble) );
|
||||
|
||||
*dataOut = vertex;
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK EdgeCallback()
|
||||
{
|
||||
// This callback is needed to force GLU tesselator to use triangles only
|
||||
}
|
||||
|
||||
|
||||
void CALLBACK ErrorCallback( GLenum aErrorCode )
|
||||
{
|
||||
const GLubyte* estring;
|
||||
|
||||
estring = gluErrorString( aErrorCode );
|
||||
wxLogError( wxT( "Tessellation Error: %s" ), (char*) estring );
|
||||
}
|
||||
|
||||
|
||||
void InitTesselatorCallbacks( GLUtesselator* aTesselator )
|
||||
{
|
||||
gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_EDGE_FLAG, ( void (CALLBACK*)() )EdgeCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_ERROR_DATA, ( void (CALLBACK*)() )ErrorCallback );
|
||||
}
|
||||
|
|
|
@ -97,7 +97,8 @@ bool SHADER::Link()
|
|||
programInfo( programNumber );
|
||||
|
||||
// Check the Link state
|
||||
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &isShaderLinked );
|
||||
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB,
|
||||
(GLint*) &isShaderLinked );
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
if( !isShaderLinked )
|
||||
|
@ -253,6 +254,7 @@ bool SHADER::addSource( const std::string& aShaderSource, ShaderType aShaderType
|
|||
glCompileShader( shaderNumber );
|
||||
GLint status;
|
||||
glGetShaderiv( shaderNumber, GL_COMPILE_STATUS, &status );
|
||||
|
||||
if( status != GL_TRUE )
|
||||
{
|
||||
wxLogError( wxT( "Shader compilation error" ) );
|
||||
|
@ -275,4 +277,3 @@ bool SHADER::addSource( const std::string& aShaderSource, ShaderType aShaderType
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ void VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) const
|
|||
{
|
||||
// Obtain the pointer to the vertex in the currently used container
|
||||
VERTEX* newVertex = m_container->Allocate( 1 );
|
||||
|
||||
if( newVertex == NULL )
|
||||
{
|
||||
wxLogError( wxT( "Vertex allocation error" ) );
|
||||
|
@ -66,6 +67,7 @@ void VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize ) co
|
|||
{
|
||||
// Obtain pointer to the vertex in currently used container
|
||||
VERTEX* newVertex = m_container->Allocate( aSize );
|
||||
|
||||
if( newVertex == NULL )
|
||||
{
|
||||
wxLogError( wxT( "Vertex allocation error" ) );
|
||||
|
@ -158,6 +160,7 @@ void VERTEX_MANAGER::BeginDrawing() const
|
|||
void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
|
||||
{
|
||||
int size = aItem.GetSize();
|
||||
|
||||
if( size > 0 )
|
||||
{
|
||||
int offset = aItem.GetOffset();
|
||||
|
|
|
@ -85,7 +85,6 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
|
|||
else
|
||||
scrollSpeed = scrollVec.y;
|
||||
|
||||
VECTOR2D t = m_view->GetScreenPixelSize();
|
||||
VECTOR2D delta( event.ControlDown() ? -scrollSpeed : 0.0,
|
||||
event.ShiftDown() ? -scrollSpeed : 0.0 );
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
namespace KiGfx
|
||||
{
|
||||
|
||||
class CAIRO_COMPOSITOR : public COMPOSITOR
|
||||
{
|
||||
public:
|
||||
|
@ -102,7 +101,6 @@ protected:
|
|||
return m_buffers.size();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* COMPOSITOR_H_ */
|
||||
|
|
|
@ -45,9 +45,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define EXCEPTION_ZERO_CLIENT_RECTANGLE 0
|
||||
#define EXCEPTION_ZERO_CONTEXT 1
|
||||
|
||||
/**
|
||||
* @brief Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
|
||||
*
|
||||
|
@ -92,7 +89,7 @@ public:
|
|||
// ---------------
|
||||
|
||||
/// @copydoc GAL::BeginDrawing()
|
||||
virtual void BeginDrawing() throw (int);
|
||||
virtual void BeginDrawing();
|
||||
|
||||
/// @copydoc GAL::EndDrawing()
|
||||
virtual void EndDrawing();
|
||||
|
@ -103,19 +100,19 @@ public:
|
|||
/// @copydoc GAL::DrawSegment()
|
||||
virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCircle()
|
||||
virtual void DrawCircle( const VECTOR2D& aCenterPoint, double aRadius );
|
||||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
virtual void
|
||||
DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle, double aEndAngle );
|
||||
virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle );
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
|
@ -149,24 +146,15 @@ public:
|
|||
/// @copydoc GAL::SetIsStroke()
|
||||
virtual void SetIsStroke( bool aIsStrokeEnabled );
|
||||
|
||||
/// @copydoc GAL::SetFillColor()
|
||||
virtual void SetFillColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::SetStrokeColor()
|
||||
virtual void SetStrokeColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::GetStrokeColor()
|
||||
COLOR4D GetStrokeColor();
|
||||
|
||||
/// @copydoc GAL::SetBackgroundColor()
|
||||
virtual void SetBackgroundColor( const COLOR4D& aColor );
|
||||
/// @copydoc GAL::SetFillColor()
|
||||
virtual void SetFillColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::SetLineWidth()
|
||||
virtual void SetLineWidth( double aLineWidth );
|
||||
|
||||
/// @copydoc GAL::GetLineWidth()
|
||||
double GetLineWidth();
|
||||
|
||||
/// @copydoc GAL::SetLayerDepth()
|
||||
virtual void SetLayerDepth( double aLayerDepth );
|
||||
|
||||
|
@ -221,33 +209,6 @@ public:
|
|||
// Handling the world <-> screen transformation
|
||||
// --------------------------------------------------------
|
||||
|
||||
/// @copydoc GAL::ComputeWorldScreenMatrix()
|
||||
virtual void ComputeWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::GetWorldScreenMatrix()
|
||||
MATRIX3x3D GetWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::SetWorldScreenMatrix()
|
||||
void SetWorldScreenMatrix( MATRIX3x3D aMatrix );
|
||||
|
||||
/// @copydoc GAL::SetWorldUnitLength()
|
||||
void SetWorldUnitLength( double aWorldUnitLength );
|
||||
|
||||
/// @copydoc GAL::SetScreenDPI()
|
||||
void SetScreenDPI( double aScreenDPI );
|
||||
|
||||
/// @copydoc GAL::SetLookAtPoint()
|
||||
void SetLookAtPoint( const VECTOR2D& aPoint );
|
||||
|
||||
/// @copydoc GAL::GetLookAtPoint()
|
||||
VECTOR2D GetLookAtPoint();
|
||||
|
||||
/// @copydoc GAL::SetZoomFactor()
|
||||
void SetZoomFactor( double aZoomFactor );
|
||||
|
||||
/// @copydoc GAL::GetZoomFactor()
|
||||
double GetZoomFactor();
|
||||
|
||||
/// @copydoc GAL::SaveScreen()
|
||||
virtual void SaveScreen();
|
||||
|
||||
|
@ -264,9 +225,6 @@ public:
|
|||
/// @copydoc GAL::ComputeCursorToWorld()
|
||||
virtual VECTOR2D ComputeCursorToWorld( const VECTOR2D& aCursorPosition );
|
||||
|
||||
/// @copydoc GAL::SetIsCursorEnabled()
|
||||
void SetIsCursorEnabled( bool aIsCursorEnabled );
|
||||
|
||||
/// @copydoc GAL::DrawCursor()
|
||||
virtual void DrawCursor( VECTOR2D aCursorPosition );
|
||||
|
||||
|
@ -295,7 +253,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
private:
|
||||
/// Super class definition
|
||||
|
@ -325,8 +283,7 @@ private:
|
|||
static const int MAX_CAIRO_ARGUMENTS = 6;
|
||||
|
||||
/// Definitions for the command recorder
|
||||
enum GraphicsCommand
|
||||
{
|
||||
enum GraphicsCommand {
|
||||
CMD_SET_FILL, ///< Enable/disable filling
|
||||
CMD_SET_STROKE, ///< Enable/disable stroking
|
||||
CMD_SET_FILLCOLOR, ///< Set the fill color
|
||||
|
@ -392,18 +349,18 @@ private:
|
|||
/// @copydoc GAL::initCursor()
|
||||
virtual void initCursor( int aCursorSize );
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void allocateBitmaps();
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void deleteBitmaps();
|
||||
|
||||
/// Prepare Cairo surfaces for drawing
|
||||
void initSurface();
|
||||
|
||||
/// Destroy Cairo surfaces when are not needed anymore
|
||||
void deinitSurface();
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void allocateBitmaps();
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void deleteBitmaps();
|
||||
|
||||
/// Prepare the compositor
|
||||
void setCompositor();
|
||||
|
||||
|
|
|
@ -231,7 +231,10 @@ public:
|
|||
*
|
||||
* @param aColor is the color for background filling.
|
||||
*/
|
||||
virtual void SetBackgroundColor( const COLOR4D& aColor ) = 0;
|
||||
inline virtual void SetBackgroundColor( const COLOR4D& aColor )
|
||||
{
|
||||
backgroundColor = aColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the line width.
|
||||
|
@ -417,7 +420,7 @@ public:
|
|||
// --------------------------------------------------------
|
||||
|
||||
/// @brief Compute the world <-> screen transformation matrix
|
||||
virtual void ComputeWorldScreenMatrix() = 0;
|
||||
virtual void ComputeWorldScreenMatrix();
|
||||
|
||||
/**
|
||||
* @brief Get the world <-> screen transformation matrix.
|
||||
|
@ -745,7 +748,6 @@ protected:
|
|||
|
||||
bool isFillEnabled; ///< Is filling of graphic objects enabled ?
|
||||
bool isStrokeEnabled; ///< Are the outlines stroked ?
|
||||
bool isSetAttributes; ///< True, if the attributes have been set
|
||||
|
||||
COLOR4D backgroundColor; ///< The background color
|
||||
COLOR4D fillColor; ///< The fill color
|
||||
|
@ -784,7 +786,7 @@ protected:
|
|||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) = 0;
|
||||
virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Initialize the cursor.
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
namespace KiGfx
|
||||
{
|
||||
|
||||
class OPENGL_COMPOSITOR : public COMPOSITOR
|
||||
{
|
||||
public:
|
||||
|
@ -94,7 +93,6 @@ protected:
|
|||
return m_buffers.size();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* COMPOSITOR_H_ */
|
||||
|
|
|
@ -104,19 +104,19 @@ public:
|
|||
/// @copydoc GAL::DrawSegment()
|
||||
virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCircle()
|
||||
virtual void DrawCircle( const VECTOR2D& aCenterPoint, double aRadius );
|
||||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
virtual void
|
||||
DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle, double aEndAngle );
|
||||
virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle );
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
|
@ -144,42 +144,9 @@ public:
|
|||
// Attribute setting
|
||||
// -----------------
|
||||
|
||||
/// @copydoc GAL::SetIsFill()
|
||||
virtual void SetIsFill( bool aIsFillEnabled )
|
||||
{
|
||||
isFillEnabled = aIsFillEnabled;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetIsStroke()
|
||||
virtual void SetIsStroke( bool aIsStrokeEnabled )
|
||||
{
|
||||
isStrokeEnabled = aIsStrokeEnabled;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetFillColor()
|
||||
virtual void SetFillColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::SetStrokeColor()
|
||||
virtual void SetStrokeColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::GetStrokeColor()
|
||||
COLOR4D GetStrokeColor();
|
||||
|
||||
/// @copydoc GAL::SetBackgroundColor()
|
||||
virtual void SetBackgroundColor( const COLOR4D& aColor );
|
||||
|
||||
/// @copydoc GAL::SetLineWidth()
|
||||
virtual void SetLineWidth( double aLineWidth );
|
||||
|
||||
/// @copydoc GAL::GetLineWidth()
|
||||
double GetLineWidth();
|
||||
|
||||
/// @copydoc GAL::SetLayerDepth()
|
||||
virtual void SetLayerDepth( double aLayerDepth )
|
||||
{
|
||||
super::SetLayerDepth( aLayerDepth );
|
||||
}
|
||||
|
||||
// --------------
|
||||
// Transformation
|
||||
// --------------
|
||||
|
@ -231,33 +198,6 @@ public:
|
|||
// Handling the world <-> screen transformation
|
||||
// --------------------------------------------------------
|
||||
|
||||
/// @copydoc GAL::ComputeWorldScreenMatrix()
|
||||
virtual void ComputeWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::GetWorldScreenMatrix()
|
||||
MATRIX3x3D GetWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::SetWorldScreenMatrix()
|
||||
void SetWorldScreenMatrix( MATRIX3x3D aMatrix );
|
||||
|
||||
/// @copydoc GAL::SetWorldUnitLength()
|
||||
void SetWorldUnitLength( double aWorldUnitLength );
|
||||
|
||||
/// @copydoc GAL::SetScreenDPI()
|
||||
void SetScreenDPI( double aScreenDPI );
|
||||
|
||||
/// @copydoc GAL::SetLookAtPoint()
|
||||
void SetLookAtPoint( const VECTOR2D& aPoint );
|
||||
|
||||
/// @copydoc GAL::GetLookAtPoint()
|
||||
VECTOR2D GetLookAtPoint();
|
||||
|
||||
/// @copydoc GAL::SetZoomFactor()
|
||||
void SetZoomFactor( double aZoomFactor );
|
||||
|
||||
/// @copydoc GAL::GetZoomFactor()
|
||||
double GetZoomFactor();
|
||||
|
||||
/// @copydoc GAL::SaveScreen()
|
||||
virtual void SaveScreen();
|
||||
|
||||
|
@ -274,9 +214,6 @@ public:
|
|||
/// @copydoc GAL::ComputeCursorToWorld()
|
||||
virtual VECTOR2D ComputeCursorToWorld( const VECTOR2D& aCursorPosition );
|
||||
|
||||
/// @copydoc GAL::SetIsCursorEnabled()
|
||||
void SetIsCursorEnabled( bool aIsCursorEnabled );
|
||||
|
||||
/// @copydoc GAL::DrawCursor()
|
||||
virtual void DrawCursor( VECTOR2D aCursorPosition );
|
||||
|
||||
|
@ -312,7 +249,7 @@ public:
|
|||
} TessParams;
|
||||
|
||||
protected:
|
||||
virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
private:
|
||||
/// Super class definition
|
||||
|
@ -327,9 +264,6 @@ private:
|
|||
wxEvtHandler* mouseListener;
|
||||
wxEvtHandler* paintListener;
|
||||
|
||||
// Precomputed vertices for faster circle & semicircle drawing
|
||||
NONCACHED_CONTAINER circleContainer; ///< Container for storing circle vertices
|
||||
|
||||
// Vertex buffer objects related fields
|
||||
typedef std::map< unsigned int, boost::shared_ptr<VERTEX_ITEM> > GroupsMap;
|
||||
GroupsMap groups; ///< Stores informations about VBO objects (groups)
|
||||
|
@ -344,10 +278,6 @@ private:
|
|||
unsigned int mainBuffer; ///< Main rendering target
|
||||
unsigned int overlayBuffer; ///< Auxiliary rendering target (for menus etc.)
|
||||
|
||||
// Polygon tesselation
|
||||
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
||||
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
|
||||
|
||||
// Shader
|
||||
SHADER shader; ///< There is only one shader used for different objects
|
||||
|
||||
|
@ -363,13 +293,54 @@ private:
|
|||
bool isShaderInitialized; ///< Was the shader initialized?
|
||||
bool isGrouping; ///< Was a group started?
|
||||
|
||||
// Polygon tesselation
|
||||
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
||||
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
|
||||
|
||||
// Structure used for tesselation of polygons
|
||||
struct OGLPOINT
|
||||
{
|
||||
OGLPOINT() :
|
||||
x( 0.0 ), y( 0.0 ), z( 0.0 )
|
||||
{}
|
||||
|
||||
OGLPOINT( const char* fastest )
|
||||
{
|
||||
// do nothing for fastest speed, and keep inline
|
||||
}
|
||||
|
||||
OGLPOINT( const VECTOR2D& aPoint ) :
|
||||
x( aPoint.x ), y( aPoint.y ), z( 0.0 )
|
||||
{}
|
||||
|
||||
OGLPOINT& operator=( const VECTOR2D& aPoint )
|
||||
{
|
||||
x = aPoint.x;
|
||||
y = aPoint.y;
|
||||
z = 0.0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLdouble x;
|
||||
GLdouble y;
|
||||
GLdouble z;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Draw a quad for the line.
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
/**
|
||||
* @brief Draw a semicircle. Depending on settings (isStrokeEnabled & isFilledEnabled) it runs
|
||||
* the proper function (drawStrokedSemiCircle or drawFilledSemiCircle).
|
||||
*
|
||||
* @param aCenterPoint is the center point.
|
||||
* @param aRadius is the radius of the semi-circle.
|
||||
* @param aAngle is the angle of the semi-circle.
|
||||
* @param aRadius is the radius of the semicircle.
|
||||
* @param aAngle is the angle of the semicircle.
|
||||
*
|
||||
*/
|
||||
void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
|
||||
|
@ -378,8 +349,8 @@ private:
|
|||
* @brief Draw a filled semicircle.
|
||||
*
|
||||
* @param aCenterPoint is the center point.
|
||||
* @param aRadius is the radius of the semi-circle.
|
||||
* @param aAngle is the angle of the semi-circle.
|
||||
* @param aRadius is the radius of the semicircle.
|
||||
* @param aAngle is the angle of the semicircle.
|
||||
*
|
||||
*/
|
||||
void drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
|
||||
|
@ -388,23 +359,13 @@ private:
|
|||
* @brief Draw a stroked semicircle.
|
||||
*
|
||||
* @param aCenterPoint is the center point.
|
||||
* @param aRadius is the radius of the semi-circle.
|
||||
* @param aAngle is the angle of the semi-circle.
|
||||
* @param aRadius is the radius of the semicircle.
|
||||
* @param aAngle is the angle of the semicircle.
|
||||
*
|
||||
*/
|
||||
void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
|
||||
|
||||
/// Compute the points of the unit circle and store them in VBO.
|
||||
void computeCircle();
|
||||
|
||||
// Event handling
|
||||
/**
|
||||
* @brief This is the window creation event handler.
|
||||
*
|
||||
* @param aEvent is the window creation event.
|
||||
*/
|
||||
void onCreate( wxWindowCreateEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief This is the OnPaint event handler.
|
||||
*
|
||||
|
@ -419,20 +380,12 @@ private:
|
|||
*/
|
||||
void skipMouseEvent( wxMouseEvent& aEvent );
|
||||
|
||||
/// Initialize GLEW.
|
||||
/// Initialize GLEW
|
||||
void initGlew();
|
||||
|
||||
/// @copydoc GAL::initCursor()
|
||||
virtual void initCursor( int aCursorSize );
|
||||
|
||||
/**
|
||||
* @brief Draw a quad for the line.
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
/**
|
||||
* @brief Returns a valid key that can be used as a new group number.
|
||||
*
|
||||
|
|
|
@ -35,8 +35,7 @@
|
|||
namespace KiGfx
|
||||
{
|
||||
// Possible types of shaders
|
||||
enum SHADER_TYPE
|
||||
{
|
||||
enum SHADER_TYPE {
|
||||
SHADER_NONE = 0,
|
||||
SHADER_LINE,
|
||||
SHADER_FILLED_CIRCLE,
|
||||
|
|
Loading…
Reference in New Issue