Commit 5242fff9 authored by Maciej Suminski's avatar Maciej Suminski

Code refactorization. VBO_CONTAINER is split to [NON]CACHED_MANAGER,...

Code refactorization. VBO_CONTAINER is split to [NON]CACHED_MANAGER, GPU_MANAGER and VERTEX_MANAGER.
parent 4d7db717
......@@ -36,8 +36,12 @@ set(GAL_SRCS
gal/color4d.cpp
gal/opengl/opengl_gal.cpp
gal/opengl/shader.cpp
gal/opengl/vbo_item.cpp
gal/opengl/vbo_container.cpp
gal/opengl/vertex_item.cpp
gal/opengl/vertex_container.cpp
gal/opengl/cached_container.cpp
gal/opengl/noncached_container.cpp
gal/opengl/vertex_manager.cpp
gal/opengl/gpu_manager.cpp
gal/cairo/cairo_gal.cpp
view/wx_view_controls.cpp
)
......
......@@ -132,7 +132,7 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
#endif /* __WXDEBUG__ */
m_gal->BeginDrawing();
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0, 0, 0, 1.0 ) );
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
m_gal->ClearScreen();
m_gal->DrawGrid();
......
......@@ -37,7 +37,7 @@ using namespace KiGfx;
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
wxEvtHandler* aPaintListener, const wxString& aName ) :
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
{
// Default values
fillColor = COLOR4D( 0, 0, 0, 1 );
......@@ -141,7 +141,7 @@ void CAIRO_GAL::initSurface()
cairoSurface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer,
CAIRO_FORMAT_RGB24, clientRectangle.width,
clientRectangle.height, stride );
cairoImage = cairo_create ( cairoSurface );
cairoImage = cairo_create( cairoSurface );
#ifdef __WXDEBUG__
cairo_status_t status = cairo_status( cairoImage );
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
......@@ -194,10 +194,10 @@ void CAIRO_GAL::deinitSurface()
}
unsigned int CAIRO_GAL::getGroupNumber()
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" ) );
wxT( "There are no free slots to store a group" ) );
while( groups.find( groupCounter ) != groups.end() )
{
......@@ -230,6 +230,7 @@ void CAIRO_GAL::EndDrawing()
// Now translate the raw image data from the format stored
// by cairo into a format understood by wxImage.
unsigned char* wxOutputPtr = wxOutput;
for( size_t count = 0; count < bufferSize; count++ )
{
unsigned int value = bitmapBuffer[count];
......@@ -287,7 +288,8 @@ void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint
}
void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth )
void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
double aWidth )
{
if( isFillEnabled )
{
......@@ -317,7 +319,6 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
cairo_line_to( cairoImage, lineLength, -aWidth / 2.0 );
cairo_restore( cairoImage );
}
isElementAdded = true;
......@@ -351,7 +352,8 @@ void CAIRO_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
bool isFirstPoint = true;
// Iterate over the point list and draw the segments
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it )
std::deque<VECTOR2D>::const_iterator it;
for( it = aPointList.begin(); it != aPointList.end(); ++it )
{
if( isFirstPoint )
{
......@@ -373,7 +375,8 @@ void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
bool isFirstPoint = true;
// Iterate over the point list and draw the polygon
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it )
std::deque<VECTOR2D>::const_iterator it;
for( it = aPointList.begin(); it != aPointList.end(); ++it )
{
if( isFirstPoint )
{
......@@ -644,10 +647,10 @@ int CAIRO_GAL::BeginGroup()
storePath();
Group group;
int groupNumber = getGroupNumber();
int groupNumber = getNewGroupNumber();
groups.insert( std::make_pair( groupNumber, group ) );
currentGroup = &groups[groupNumber];
isGrouping = true;
isGrouping = true;
return groupNumber;
}
......@@ -677,6 +680,7 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber )
// 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 )
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file gpu_manager.cpp
* @brief Class to handle uploading vertices and indices to GPU in drawing purposes.
*/
#include <gal/opengl/gpu_manager.h>
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/shader.h>
#include <typeinfo>
#include <wx/log.h>
#ifdef __WXDEBUG__
#include <profile.h>
#endif
using namespace KiGfx;
GPU_MANAGER* GPU_MANAGER::MakeManager( VERTEX_CONTAINER* aContainer )
{
if( typeid( *aContainer ) == typeid( CACHED_CONTAINER ) )
return new GPU_CACHED_MANAGER( aContainer );
else if( typeid( *aContainer ) == typeid( NONCACHED_CONTAINER ) )
return new GPU_NONCACHED_MANAGER( aContainer );
wxASSERT_MSG( false, "Not handled container type" );
return NULL;
}
GPU_MANAGER::GPU_MANAGER( VERTEX_CONTAINER* aContainer ) :
m_container( aContainer ), m_shader( NULL )
{
}
GPU_MANAGER::~GPU_MANAGER()
{
}
void GPU_MANAGER::SetShader( SHADER& aShader )
{
m_shader = &aShader;
m_shaderAttrib = m_shader->GetAttribute( "attrShaderParams" );
if( m_shaderAttrib == -1 )
{
wxLogFatalError( wxT( "Could not get the shader attribute location" ) );
}
}
// Cached manager
GPU_CACHED_MANAGER::GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
GPU_MANAGER( aContainer ), m_buffersInitialized( false ), m_indicesPtr( NULL ),
m_indicesSize( 0 )
{
}
GPU_CACHED_MANAGER::~GPU_CACHED_MANAGER()
{
if( m_buffersInitialized )
{
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glDeleteBuffers( 1, &m_verticesBuffer );
}
}
void GPU_CACHED_MANAGER::Initialize()
{
wxASSERT( !m_buffersInitialized );
if( !m_buffersInitialized )
{
glGenBuffers( 1, &m_verticesBuffer );
m_buffersInitialized = true;
}
}
void GPU_CACHED_MANAGER::BeginDrawing()
{
wxASSERT( !m_isDrawing );
if( m_container->isDirty() )
uploadToGpu();
// Number of vertices to be drawn in the EndDrawing()
m_indicesSize = 0;
// Set the indices pointer to the beginning of the indices-to-draw buffer
m_indicesPtr = m_indices.get();
m_isDrawing = true;
}
void GPU_CACHED_MANAGER::DrawIndices( unsigned int aOffset, unsigned int aSize )
{
wxASSERT( m_isDrawing );
// Copy indices of items that should be drawn to GPU memory
for( unsigned int i = aOffset; i < aOffset + aSize; *m_indicesPtr++ = i++ );
m_indicesSize += aSize;
}
void GPU_CACHED_MANAGER::DrawAll()
{
wxASSERT( m_isDrawing );
m_indicesSize = m_container->GetSize();
for( unsigned int i = 0; i < m_indicesSize; *m_indicesPtr++ = i++ );
}
void GPU_CACHED_MANAGER::EndDrawing()
{
wxASSERT( m_isDrawing );
// Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
// Bind vertices data buffers
glBindBuffer( GL_ARRAY_BUFFER, m_verticesBuffer );
glVertexPointer( CoordStride, GL_FLOAT, VertexSize, 0 );
glColorPointer( ColorStride, GL_UNSIGNED_BYTE, VertexSize, (GLvoid*) ColorOffset );
if( m_shader != NULL ) // Use shader if applicable
{
m_shader->Use();
glEnableVertexAttribArray( m_shaderAttrib );
glVertexAttribPointer( m_shaderAttrib, ShaderStride, GL_FLOAT, GL_FALSE,
VertexSize, (GLvoid*) ShaderOffset );
}
glDrawElements( GL_TRIANGLES, m_indicesSize, GL_UNSIGNED_INT, (GLvoid*) m_indices.get() );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
// Deactivate vertex array
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
if( m_shader != NULL )
{
glDisableVertexAttribArray( m_shaderAttrib );
m_shader->Deactivate();
}
m_isDrawing = false;
}
void GPU_CACHED_MANAGER::uploadToGpu()
{
#ifdef __WXDEBUG__
prof_counter totalTime;
prof_start( &totalTime, false );
#endif /* __WXDEBUG__ */
if( !m_buffersInitialized )
Initialize();
int bufferSize = m_container->GetSize();
GLfloat* vertices = (GLfloat*) m_container->GetAllVertices();
// Upload vertices coordinates and shader types to GPU memory
glBindBuffer( GL_ARRAY_BUFFER, m_verticesBuffer );
glBufferData( GL_ARRAY_BUFFER, bufferSize * VertexSize, vertices, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
// Allocate the biggest possible buffer for indices
m_indices.reset( new GLuint[bufferSize] );
if( glGetError() != GL_NO_ERROR )
{
wxLogError( wxT( "Error during data upload to the GPU memory" ) );
}
#ifdef __WXDEBUG__
prof_end( &totalTime );
wxLogDebug( wxT( "Uploading %d vertices to GPU / %.1f ms" ),
bufferSize, (double) totalTime.value / 1000.0 );
#endif /* __WXDEBUG__ */
}
// Noncached manager
GPU_NONCACHED_MANAGER::GPU_NONCACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
GPU_MANAGER( aContainer )
{
}
void GPU_NONCACHED_MANAGER::Initialize()
{
// Nothing has to be intialized
}
void GPU_NONCACHED_MANAGER::BeginDrawing()
{
// Nothing has to be prepared
}
void GPU_NONCACHED_MANAGER::DrawIndices( unsigned int aOffset, unsigned int aSize )
{
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
}
void GPU_NONCACHED_MANAGER::DrawAll()
{
// This is the default use case, nothing has to be done
// The real rendering takes place in the EndDrawing() function
}
void GPU_NONCACHED_MANAGER::EndDrawing()
{
VERTEX* vertices = m_container->GetAllVertices();
GLfloat* coordinates = (GLfloat*) ( vertices );
GLubyte* colors = (GLubyte*) ( vertices ) + ColorOffset;
GLfloat* shaders = (GLfloat*) ( vertices ) + ShaderOffset / sizeof(GLfloat);
// Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( CoordStride, GL_FLOAT, VertexSize, coordinates );
glColorPointer( ColorStride, GL_UNSIGNED_BYTE, VertexSize, colors );
if( m_shader != NULL ) // Use shader if applicable
{
m_shader->Use();
glEnableVertexAttribArray( m_shaderAttrib );
glVertexAttribPointer( m_shaderAttrib, ShaderStride, GL_FLOAT, GL_FALSE,
VertexSize, shaders );
}
glDrawArrays( GL_TRIANGLES, 0, m_container->GetSize() );
// Deactivate vertex array
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
if( m_shader != NULL )
{
glDisableVertexAttribArray( m_shaderAttrib );
m_shader->Deactivate();
}
}
......@@ -23,94 +23,72 @@
*/
/**
* @file vbo_item.cpp
* @brief Class to handle an item held in a Vertex Buffer Object.
* @file noncached_container.cpp
* @brief Class to store instances of VERTEX without caching. It allows a fast one-frame drawing
* and then clearing the buffer and starting from scratch.
*/
#include <gal/opengl/vbo_container.h>
#include <gal/opengl/vbo_item.h>
#include <cstring>
#include <gal/opengl/noncached_container.h>
#include <cstdlib>
using namespace KiGfx;
VBO_ITEM::VBO_ITEM( VBO_CONTAINER* aContainer ) :
m_offset( 0 ),
m_size( 0 ),
m_container( aContainer ),
m_isDirty( true )
NONCACHED_CONTAINER::NONCACHED_CONTAINER( unsigned int aSize ) :
VERTEX_CONTAINER( aSize ), m_freePtr( 0 )
{
// The item's size is not known yet, so we just start an item in the container
aContainer->StartItem( this );
}
VBO_ITEM::~VBO_ITEM()
NONCACHED_CONTAINER::~NONCACHED_CONTAINER()
{
m_container->Free( this );
}
void VBO_ITEM::PushVertex( const VBO_VERTEX* aVertex )
void NONCACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
{
m_container->Add( aVertex );
m_isDirty = true;
// Nothing has to be done, as the noncached container
// does not care about VERTEX_ITEMs ownership
}
void VBO_ITEM::PushVertices( const VBO_VERTEX* aVertices, GLuint aSize )
VERTEX* NONCACHED_CONTAINER::Allocate( unsigned int aSize )
{
for( unsigned int i = 0; i < aSize; ++i )
if( m_freeSpace < aSize )
{
PushVertex( &aVertices[i] );
// Double the space
VERTEX* newVertices = static_cast<VERTEX*>( realloc( m_vertices,
m_currentSize * 2 *
sizeof(VERTEX) ) );
if( newVertices != NULL )
{
m_vertices = newVertices;
m_freeSpace += m_currentSize;
m_currentSize *= 2;
}
else
{
return NULL;
}
}
}
VBO_VERTEX* VBO_ITEM::GetVertices()
{
if( m_isDirty )
Finish();
return m_container->GetVertices( m_offset );
}
void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
{
VBO_VERTEX* vertexPtr = GetVertices();
VERTEX* freeVertex = &m_vertices[m_freePtr];
for( unsigned int i = 0; i < m_size; ++i )
{
vertexPtr->r = aColor.r * 255;
vertexPtr->g = aColor.g * 255;
vertexPtr->b = aColor.b * 255;
vertexPtr->a = aColor.a * 255;
// Move to the next free chunk
m_freePtr += aSize;
m_freeSpace -= aSize;
// Move on to the next vertex
vertexPtr++;
}
return freeVertex;
}
void VBO_ITEM::ChangeDepth( int aDepth )
void NONCACHED_CONTAINER::Erase()
{
VBO_VERTEX* vertexPtr = GetVertices();
for( unsigned int i = 0; i < m_size; ++i )
{
vertexPtr->z = aDepth;
// Move on to the next vertex
vertexPtr++;
}
}
void VBO_ITEM::Finish()
void NONCACHED_CONTAINER::Clear()
{
// The unknown-sized item has just ended, so we need to inform the container about it
m_container->EndItem();
m_isDirty = false;
m_freePtr = 0;
m_freeSpace = m_currentSize;
}
This diff is collapsed.
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vertex_container.cpp
* @brief Class to store vertices and handle transfers between system memory and GPU memory.
*/
#include <gal/opengl/vertex_container.h>
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/shader.h>
#include <wx/log.h>
using namespace KiGfx;
VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached )
{
if( aCached )
return new CACHED_CONTAINER;
else
return new NONCACHED_CONTAINER;
}
VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ), m_failed( false )
{
m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
}
VERTEX_CONTAINER::~VERTEX_CONTAINER()
{
free( m_vertices );
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vertex_item.cpp
* @brief Class to handle an item held in a container.
*/
#include <gal/opengl/vertex_item.h>
#include <gal/opengl/vertex_manager.h>
#include <cstring>
using namespace KiGfx;
VERTEX_ITEM::VERTEX_ITEM( const VERTEX_MANAGER& aManager ) :
m_manager( aManager ), m_offset( 0 ), m_size( 0 )
{
// As the item is created, we are going to modify it, so call to SetItem() is needed
m_manager.SetItem( *this );
}
VERTEX_ITEM::~VERTEX_ITEM()
{
m_manager.FreeItem( *this );
}
VERTEX* VERTEX_ITEM::GetVertices() const
{
return m_manager.GetVertices( *this );
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vertex_manager.cpp
* @brief Class to control vertex container and GPU with possibility of emulating old-style OpenGL
* 1.0 state machine using modern OpenGL methods.
*/
#include <gal/opengl/vertex_manager.h>
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/gpu_manager.h>
#include <gal/opengl/vertex_item.h>
using namespace KiGfx;
VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) :
m_noTransform( true ), m_transform( 1.0f )
{
m_container.reset( VERTEX_CONTAINER::MakeContainer( aCached ) );
m_gpu.reset( GPU_MANAGER::MakeManager( m_container.get() ) );
// There is no shader used by default
for( unsigned int i = 0; i < ShaderStride; ++i )
m_shader[i] = 0.0f;
}
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" ) );
return;
}
putVertex( *newVertex, aX, aY, aZ );
}
void VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize ) const
{
// Obtain pointer to the vertex in currently used container
VERTEX* newVertex = m_container->Allocate( aSize );
if( newVertex == NULL )
{
wxLogError( wxT( "Vertex allocation error" ) );
return;
}
// Put vertices in already allocated memory chunk
for( unsigned int i = 0; i < aSize; ++i )
{
putVertex( newVertex[i], aVertices[i].x, aVertices[i].y, aVertices[i].z );
}
}
void VERTEX_MANAGER::SetItem( VERTEX_ITEM& aItem ) const
{
m_container->SetItem( &aItem );
}
void VERTEX_MANAGER::FreeItem( VERTEX_ITEM& aItem ) const
{
m_container->SetItem( &aItem );
m_container->Erase();
}
void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
{
unsigned int size = aItem.GetSize();
unsigned int offset = aItem.GetOffset();
VERTEX* vertex = m_container->GetVertices( offset );
for( unsigned int i = 0; i < size; ++i )
{
vertex->r = aColor.r;
vertex->g = aColor.g;
vertex->b = aColor.b;
vertex->a = aColor.a;
vertex++;
}
}
void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
{
unsigned int size = aItem.GetSize();
unsigned int offset = aItem.GetOffset();
VERTEX* vertex = m_container->GetVertices( offset );
for( unsigned int i = 0; i < size; ++i )
{
vertex->z = aDepth;
vertex++;
}
}
VERTEX* VERTEX_MANAGER::GetVertices( const VERTEX_ITEM& aItem ) const
{
if( aItem.GetSize() == 0 )
return NULL; // The item is not stored in the container
return m_container->GetVertices( aItem.GetOffset() );
}
void VERTEX_MANAGER::SetShader( SHADER& aShader ) const
{
m_gpu->SetShader( aShader );
}
void VERTEX_MANAGER::Clear() const
{
m_container->Clear();
}
void VERTEX_MANAGER::BeginDrawing() const
{
m_gpu->BeginDrawing();
}
void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
{
int size = aItem.GetSize();
if( size > 0 )
{
int offset = aItem.GetOffset();
m_gpu->DrawIndices( offset, size );
}
}
void VERTEX_MANAGER::EndDrawing() const
{
m_gpu->EndDrawing();
}
void VERTEX_MANAGER::putVertex( VERTEX& aTarget, GLfloat aX, GLfloat aY, GLfloat aZ ) const
{
// Modify the vertex according to the currently used transformations
if( m_noTransform )
{
// Simply copy coordinates, when the transform matrix is the identity matrix
aTarget.x = aX;
aTarget.y = aY;
aTarget.z = aZ;
}
else
{
// Apply transformations
glm::vec4 transVertex( aX, aY, aZ, 1.0f );
transVertex = m_transform * transVertex;
aTarget.x = transVertex.x;
aTarget.y = transVertex.y;
aTarget.z = transVertex.z;
}
// Apply currently used color
aTarget.r = m_color[0];
aTarget.g = m_color[1];
aTarget.b = m_color[2];
aTarget.a = m_color[3];
// Apply currently used shader
for( unsigned int j = 0; j < ShaderStride; ++j )
{
aTarget.shader[j] = m_shader[j];
}
}
......@@ -401,11 +401,11 @@ private:
void deinitSurface();
/**
* @brief Returns a valid key that can be used as a group number.
* @brief Returns a valid key that can be used as a new group number.
*
* @return An unique group number that is not used by any other group.
*/
unsigned int getGroupNumber();
unsigned int getNewGroupNumber();
};
} // namespace KiGfx
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file cached_container.h
* @brief Class to store instances of VERTEX with caching. It allows storing VERTEX objects and
* associates them with VERTEX_ITEMs. This leads to a possibility of caching vertices data in the
* GPU memory and a fast reuse of that data.
*/
#ifndef CACHED_CONTAINER_H_
#define CACHED_CONTAINER_H_
#include <gal/opengl/vertex_container.h>
#include <map>
#include <set>
#ifdef __WXDEBUG__
// Debug messages verbosity level
// #define CACHED_CONTAINER_TEST 2
#endif
namespace KiGfx
{
class VERTEX_ITEM;
class SHADER;
class CACHED_CONTAINER : public VERTEX_CONTAINER
{
public:
CACHED_CONTAINER( unsigned int aSize = defaultInitSize );
///< @copydoc VERTEX_CONTAINER::SetItem()
virtual void SetItem( VERTEX_ITEM* aItem );
///< @copydoc VERTEX_CONTAINER::Allocate()
virtual VERTEX* Allocate( unsigned int aSize );
///< @copydoc VERTEX_CONTAINER::Erase()
virtual void Erase();
///< @copydoc VERTEX_CONTAINER::Clear()
virtual void Clear();
/**
* Function GetVertices()
* returns the vertices stored by the specific item.
*
* @param aItem is the item.
*/
virtual VERTEX* GetVertices( const VERTEX_ITEM* aItem ) const;
protected:
///< Maps size of free memory chunks to their offsets
typedef std::pair<unsigned int, unsigned int> Chunk;
typedef std::multimap<unsigned int, unsigned int> FreeChunkMap;
/// List of all the stored items
typedef std::set<VERTEX_ITEM*> Items;
///< Stores size & offset of free chunks.
FreeChunkMap m_freeChunks;
///< Stored VERTEX_ITEMs
Items m_items;
///< Currently modified item
VERTEX_ITEM* m_item;
///< Properties of currently modified chunk & item
unsigned int m_chunkSize;
unsigned int m_chunkOffset;
unsigned int m_itemSize;
/**
* Function reallocate()
* resizes the chunk that stores the current item to the given size.
*
* @param aSize is the number of vertices to be stored.
* @return offset of the new chunk.
*/
virtual unsigned int reallocate( unsigned int aSize );
/**
* Function defragment()
* removes empty spaces between chunks, so after that there is a long continous space
* for storing vertices at the and of the container.
*
* @param aTarget is the already allocated destination for defragmented data. It has to be
* at least of the same size as the current container. If left NULL, it will be allocated
* inside the defragment() function.
* @return false in case of failure (eg. memory shortage)
*/
virtual bool defragment( VERTEX* aTarget = NULL );
/**
* Function mergeFreeChunks()
* looks for consecutive free memory chunks and merges them, decreasing fragmentation of
* memory.
*/
virtual void mergeFreeChunks();
/**
* Function resizeContainer()
*
* prepares a bigger container of a given size.
* @param aNewSize is the new size of container, expressed in vertices
* @return false in case of failure (eg. memory shortage)
*/
virtual bool resizeContainer( unsigned int aNewSize );
/**
* Function freeItem()
* frees the space occupied by the item and returns it to the free space pool.
*
* @param aItem is the item to be freed.
*/
virtual void freeItem( VERTEX_ITEM* aItem );
/**
* Function getPowerOf2()
* returns the nearest power of 2, bigger than aNumber.
*
* @param aNumber is the number for which we look for a bigger power of 2.
*/
unsigned int getPowerOf2( unsigned int aNumber ) const;
private:
/**
* Function getChunkSize()
* returns size of the given chunk.
*
* @param aChunk is the chunk.
*/
inline int getChunkSize( const Chunk& aChunk ) const
{
return aChunk.first;
}
/**
* Function getChunkOffset()
* returns offset of the chunk.
*
* @param aChunk is the chunk.
*/
inline unsigned int getChunkOffset( const Chunk& aChunk ) const
{
return aChunk.second;
}
/// Debug & test functions
#ifdef CACHED_CONTAINER_TEST
void showFreeChunks();
void showReservedChunks();
void test();
#else
inline void showFreeChunks() {}
inline void showReservedChunks() {}
inline void test() {}
#endif /* CACHED_CONTAINER_TEST */
};
} // namespace KiGfx
#endif /* CACHED_CONTAINER_H_ */
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file gpu_manager.h
* @brief Class to handle uploading vertices and indices to GPU in drawing purposes.
*/
#ifndef GPU_MANAGER_H_
#define GPU_MANAGER_H_
#include <gal/opengl/vertex_common.h>
#include <boost/scoped_array.hpp>
namespace KiGfx
{
class SHADER;
class VERTEX_CONTAINER;
class CACHED_CONTAINER;
class NONCACHED_CONTAINER;
class GPU_MANAGER
{
public:
static GPU_MANAGER* MakeManager( VERTEX_CONTAINER* aContainer );
virtual ~GPU_MANAGER();
// TODO docs
/**
* @brief Initializes everything needed to use vertex buffer objects (should be called when
* there is an OpenGL context available).
*/
virtual void Initialize() = 0;
/**
* Function BeginDrawing()
* Prepares the stored data to be drawn.
*/
virtual void BeginDrawing() = 0;
/**
* Function DrawIndices()
* Makes the GPU draw given range of vertices.
* @param aOffset is the beginning of the range.
* @param aSize is the number of vertices to be drawn.
*/
virtual void DrawIndices( unsigned int aOffset, unsigned int aSize ) = 0;
/**
* Function DrawIndices()
* Makes the GPU draw all the vertices stored in the container.
*/
virtual void DrawAll() = 0;
/**
* Function EndDrawing()
* Clears the container after drawing routines.
*/
virtual void EndDrawing() = 0;
/**
* Function SetShader()
* Allows using shaders with the stored data.
* @param aShader is the object that allows using shaders.
*/
virtual void SetShader( SHADER& aShader );
protected:
GPU_MANAGER( VERTEX_CONTAINER* aContainer );
///< Drawing status flag.
bool m_isDrawing;
///< Container that stores vertices data.
VERTEX_CONTAINER* m_container;
///< Shader handling
SHADER* m_shader;
int m_shaderAttrib; ///< Location of shader attributes (for glVertexAttribPointer)
};
class GPU_CACHED_MANAGER : public GPU_MANAGER
{
public:
GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer );
~GPU_CACHED_MANAGER();
///< @copydoc GPU_MANAGER::Initialize()
virtual void Initialize();
///< @copydoc GPU_MANAGER::BeginDrawing()
virtual void BeginDrawing();
///< @copydoc GPU_MANAGER::DrawIndices()
virtual void DrawIndices( unsigned int aOffset, unsigned int aSize );
///< @copydoc GPU_MANAGER::DrawAll()
virtual void DrawAll();
///< @copydoc GPU_MANAGER::EndDrawing()
virtual void EndDrawing();
/**
* Function uploadToGpu
* Rebuilds vertex buffer object using stored VERTEX_ITEMs and sends it to the graphics card
* memory.
*/
virtual void uploadToGpu();
protected:
bool m_buffersInitialized;
boost::scoped_array<GLuint> m_indices;
GLuint* m_indicesPtr;
GLuint m_verticesBuffer;
unsigned int m_indicesSize;
};
class GPU_NONCACHED_MANAGER : public GPU_MANAGER
{
public:
GPU_NONCACHED_MANAGER( VERTEX_CONTAINER* aContainer );
///< @copydoc GPU_MANAGER::Initialize()
virtual void Initialize();
///< @copydoc GPU_MANAGER::BeginDrawing()
virtual void BeginDrawing();
///< @copydoc GPU_MANAGER::DrawIndices()
virtual void DrawIndices( unsigned int aOffset, unsigned int aSize );
///< @copydoc GPU_MANAGER::DrawAll()
virtual void DrawAll();
///< @copydoc GPU_MANAGER::EndDrawing()
virtual void EndDrawing();
};
} // namespace KiGfx
#endif /* GPU_MANAGER_H_ */
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file noncached_container.h
* @brief Class to store instances of VERTEX without caching. It allows a fast one-frame drawing
* and then clearing the buffer and starting from scratch.
*/
#ifndef NONCACHED_CONTAINER_H_
#define NONCACHED_CONTAINER_H_
#include <gal/opengl/vertex_container.h>
namespace KiGfx
{
class VERTEX_ITEM;
class SHADER;
class NONCACHED_CONTAINER : public VERTEX_CONTAINER
{
public:
NONCACHED_CONTAINER( unsigned int aSize = defaultInitSize );
virtual ~NONCACHED_CONTAINER();
///< @copydoc VERTEX_CONTAINER::SetItem()
virtual void SetItem( VERTEX_ITEM* aItem );
///< @copydoc VERTEX_CONTAINER::Allocate()
virtual VERTEX* Allocate( unsigned int aSize );
///< @copydoc VERTEX_CONTAINER::Erase()
virtual void Erase();
///< @copydoc VERTEX_CONTAINER::Clear()
virtual void Clear();
///< @copydoc VERTEX_CONTAINER::GetSize()
virtual inline unsigned int GetSize() const
{
// As the m_freePtr points to the first free space, we can safely assume
// that this is the number of vertices stored inside
return m_freePtr;
}
protected:
///< Index of the free first space where a vertex can be stored
unsigned int m_freePtr;
};
} // namespace KiGfx
#endif /* NONCACHED_CONTAINER_H_ */
......@@ -31,25 +31,21 @@
// GAL imports
#include <gal/graphics_abstraction_layer.h>
#include <GL/glew.h>
// OpenGL mathematics library
#define GLM_FORCE_RADIANS
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
#include <gal/opengl/vbo_container.h>
#include <gal/opengl/shader.h>
#include <gal/opengl/vertex_manager.h>
#include <gal/opengl/vertex_item.h>
#include <gal/opengl/noncached_container.h>
// wxWidgets imports
#include <wx/wx.h>
#include <wx/glcanvas.h>
// STL imports
#include <cmath>
#include <iterator>
#include <vector>
#include <algorithm>
#include <boost/unordered_map.hpp>
#include <memory>
#include <map>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <stdlib.h>
#include <iostream>
......@@ -312,7 +308,7 @@ public:
///< Parameters passed to the GLU tesselator
typedef struct
{
VBO_ITEM* vboItem; ///< VBO_ITEM for storing new vertices
VERTEX_MANAGER* vboManager; ///< VERTEX_ITEM for storing new vertices
std::vector<GLdouble*>& intersectPoints; ///< Intersect points, that have to be freed
} TessParams;
......@@ -325,11 +321,6 @@ 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
static const double MITER_LIMIT = 1.5; ///< Limit for mitered edges ( * lineWidth )
/// This factor is used to for correct merging of antialiased edges,
/// a very small value is required
static const double DEPTH_ADJUST_FACTOR = ( 1.0 / (1 << 23) );
wxClientDC* clientDC; ///< Drawing context
wxGLContext* glContext; ///< OpenGL context of wxWidgets
......@@ -338,43 +329,22 @@ private:
wxEvtHandler* paintListener;
// VBO buffered vertices for faster circle & semicircle drawing
VBO_CONTAINER precomputedContainer; ///< Container for storing display lists
VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices
NONCACHED_CONTAINER circleContainer; ///< Container for storing circle vertices
// Vertex buffer objects related fields
typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap;
typedef std::map< unsigned int, boost::shared_ptr<VERTEX_ITEM> > GroupsMap;
GroupsMap groups; ///< Stores informations about VBO objects (groups)
unsigned int groupCounter; ///< Counter used for generating keys for groups
VBO_ITEM* currentItem; ///< Currently used VBO_ITEM (for grouping)
VBO_CONTAINER* currentContainer; ///< Currently used VBO_CONTAINER (for storing VBO_ITEMs)
VBO_CONTAINER cachedVbo; ///< Container for storing VBO_ITEMs
GLuint cachedVerts; ///< Currently used vertices VBO handle
GLuint cachedInds; ///< Currently used indices VBO handle
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt
VBO_CONTAINER nonCachedVbo; ///< Container for storing non-cached VBO_ITEMs
VBO_ITEM* nonCachedItem; ///< Item that is gathering non-cached vertices
glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices
int indicesSize; ///< Number of indices to be drawn
GLuint* indicesPtr; ///< Pointer to mapped GPU memory
VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
VERTEX_MANAGER cachedManager; ///< Container for storing cached VERTEX_ITEMs
VERTEX_MANAGER nonCachedManager; ///< Container for storing non-cached VERTEX_ITEMs
// Polygon tesselation
GLUtesselator* tesselator; ///< Pointer to the tesselator
GLUtesselator* tesselator; ///< Pointer to the tesselator
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
// Shader
// Possible types of shaders
typedef enum
{
SHADER_NONE = 0,
SHADER_LINE,
SHADER_FILLED_CIRCLE,
SHADER_STROKED_CIRCLE,
} SHADER_TYPE;
SHADER shader; ///< There is only one shader used for different objects
int shaderAttrib; ///< Location of shader attributes (for glVertexAttribPointer)
// Cursor
int cursorSize; ///< Size of the cursor in pixels
......@@ -394,7 +364,6 @@ private:
// Internal flags
bool isGlewInitialized; ///< Is GLEW initialized?
bool isFrameBufferInitialized; ///< Are the frame buffers initialized?
bool isVboInitialized;
bool isShaderInitialized; ///< Was the shader initialized?
bool isUseShader; ///< Should the shaders be used?
bool isGrouping; ///< Was a group started?
......@@ -430,8 +399,8 @@ private:
*/
void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
/// Compute the points of an unit circle & semicircle and store them in VBO.
void computeCircleVbo();
/// Compute the points of the unit circle and store them in VBO.
void computeCircle();
// Event handling
/**
......@@ -493,22 +462,6 @@ private:
*/
void deleteFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture );
/**
* @brief Initializes everything needed to use vertex buffer objects.
*/
void initVertexBufferObjects();
/**
* @brief Deinitializes everything when vertex buffer objects are not used anymore.
*/
void deleteVertexBufferObjects();
/**
* @brief Rebuilds vertex buffer object using stored VBO_ITEMS and sends it to
* the graphics card memory.
*/
void rebuildVbo();
/**
* @brief Draw a quad for the line.
*
......@@ -518,76 +471,11 @@ private:
inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/**
* @brief Returns a valid key that can be used as a group number.
* @brief Returns a valid key that can be used as a new group number.
*
* @return An unique group number that is not used by any other group.
*/
unsigned int getGroupNumber();
/**
* @brief Adds vertex to the current item or draws it in immediate mode.
* @param aX is X coordinate.
* @param aY is Y coordinate.
* @param aZ is Z coordinate.
*/
inline void vertex3( double aX, double aY, double aZ )
{
// New vertex coordinates for VBO
const VBO_VERTEX vertex = { aX, aY, aZ };
currentItem->PushVertex( &vertex );
}
/**
* @brief Function that replaces glTranslate. It modifies transformation matrix.
*
* @param aX is translation in X axis direction.
* @param aY is translation in Y axis direction.
* @param aZ is translation in Z axis direction.
*/
inline void translate3( double aX, double aY, double aZ )
{
transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
}
/**
* @brief Function that replaces glColor. It modifies color used by current VBO_ITEM.
*
* @param aR is red component.
* @param aG is green component.
* @param aB is blue component.
* @param aA is alpha component.
*/
inline void color4( double aRed, double aGreen, double aBlue, double aAlpha )
{
currentContainer->UseColor( aRed, aGreen, aBlue, aAlpha );
}
/**
* @brief Function that replaces glColor. It modifies color used by current VBO_ITEM.
*
* @param aColor is the new color.
*/
inline void color4( const COLOR4D& aColor )
{
currentContainer->UseColor( aColor );
}
/**
* @brief Function that sets shader and its parameters for the currently used VBO_ITEM.
* It should be used before adding any vertices that have to be shaded.
* @param aShader is the type of shader used for vertices.
* @param aParam[1..3] are shader's parameters. Their meaning depends on the type of used shader.
* For more information you may check shaders' source code.
*/
inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f,
GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f )
{
if( isUseShader )
{
const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 };
currentContainer->UseShader( shader );
}
}
unsigned int getNewGroupNumber();
};
} // namespace KiGfx
......
This diff is collapsed.
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vertex_common.h
* @brief Common defines and consts used in vertex related classes.
*/
#ifndef VERTEX_COMMON_H_
#define VERTEX_COMMON_H_
#include <GL/glew.h>
namespace KiGfx
{
// Possible types of shaders
enum SHADER_TYPE
{
SHADER_NONE = 0,
SHADER_LINE,
SHADER_FILLED_CIRCLE,
SHADER_STROKED_CIRCLE,
};
typedef struct VERTEX
{
GLfloat x, y, z; // Coordinates
GLubyte r, g, b, a; // Color
GLfloat shader[4]; // Shader type & params
} VERTEX;
///< Data structure for vertices {X,Y,Z,R,G,B,A,shader&param} (@see VERTEX).
const unsigned int VertexSize = sizeof(VERTEX);
const unsigned int VertexStride = VertexSize / sizeof(GLfloat);
const unsigned int CoordSize = sizeof(VERTEX().x) + sizeof(VERTEX().y) + sizeof(VERTEX().z);
const unsigned int CoordStride = CoordSize / sizeof(GLfloat);
// Offset of color data from the beginning of each vertex data
const unsigned int ColorOffset = offsetof(VERTEX, r);
const unsigned int ColorSize = sizeof(VERTEX().r) + sizeof(VERTEX().g) +
sizeof(VERTEX().b) + sizeof(VERTEX().a);
const unsigned int ColorStride = ColorSize / sizeof(GLubyte);
// Shader attributes
const unsigned int ShaderOffset = offsetof(VERTEX, shader);
const unsigned int ShaderSize = sizeof(VERTEX().shader);
const unsigned int ShaderStride = ShaderSize / sizeof(GLfloat);
const unsigned int IndexSize = sizeof(GLuint);
} // namespace KiGfx
#endif /* VERTEX_COMMON_H_ */
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vertex_container.h
* @brief Class to store vertices and handle transfers between system memory and GPU memory.
*/
#ifndef VERTEX_CONTAINER_H_
#define VERTEX_CONTAINER_H_
#include <gal/opengl/vertex_common.h>
namespace KiGfx
{
class VERTEX;
class VERTEX_ITEM;
class SHADER;
class VERTEX_CONTAINER
{
public:
/**
* Function MakeContainer()
* Returns a pointer to a new container of an appropriate type.
*/
static VERTEX_CONTAINER* MakeContainer( bool aCached );
virtual ~VERTEX_CONTAINER();
/**
* Function SetItem()
* sets the item in order to modify or finishes its current modifications.
* @param aItem is the item or NULL in case of finishing the item.
*/
virtual void SetItem( VERTEX_ITEM* aItem ) = 0;
/**
* Function Allocate()
* returns allocated space (possibly resizing the reserved memory chunk or allocating a new
* chunk if it was not stored before) for the given number of vertices associated with the
* current item (set by SetItem()). The newly allocated space is added at the end of the chunk
* used by the current item and may serve to store new vertices.
* @param aSize is the number of vertices to be allocated.
* @return Pointer to the allocated space or NULL in case of failure.
*/
virtual VERTEX* Allocate( unsigned int aSize ) = 0;
/**
* Function Erase()
* erases all vertices associated with the current item (set by SetItem()).
*/
virtual void Erase() = 0;
/**
* Function Clear()
* removes all the data stored in the container and restores its original state.
*/
virtual void Clear() = 0;
/**
* Function GetAllVertices()
* returns all the vertices stored in the container. It is especially useful for transferring
* data to the GPU memory.
*/
inline virtual VERTEX* GetAllVertices() const
{
return m_vertices;
}
/**
* Function GetVertices()
* returns vertices stored at the specific offset.
* @aOffset is the offset.
*/
virtual inline VERTEX* GetVertices( unsigned int aOffset ) const
{
return &m_vertices[aOffset];
}
/**
* Function GetSize()
* returns amount of vertices currently stored in the container.
*/
virtual inline unsigned int GetSize() const
{
return m_currentSize;
}
/**
* Function IsDirty()
* returns information about container cache state. Clears the flag after calling the function.
* @return true in case the vertices have to be reuploaded.
*/
inline bool isDirty()
{
bool state = m_dirty;
m_dirty = false;
return state;
}
protected:
VERTEX_CONTAINER( unsigned int aSize = defaultInitSize );
///< How many vertices we can store in the container
unsigned int m_freeSpace;
///< How big is the current container, expressed in vertices
unsigned int m_currentSize;
///< Store the initial size, so it can be resized to this on Clear()
unsigned int m_initialSize;
///< Actual storage memory (should be handled using malloc/realloc/free to speed up resizing)
VERTEX* m_vertices;
///< State flags
bool m_failed;
bool m_dirty;
/**
* Function reservedSpace()
* returns size of the reserved memory space.
* @return Size of the reserved memory space (expressed as a number of vertices).
*/
unsigned int reservedSpace()
{
return m_currentSize - m_freeSpace;
}
///< Default initial size of a container (expressed in vertices)
static const unsigned int defaultInitSize = 1048576;
};
} // namespace KiGfx
#endif /* VERTEX_CONTAINER_H_ */
......@@ -23,68 +23,34 @@
*/
/**
* @file vbo_item.h
* @brief Class to handle an item held in a Vertex Buffer Object.
* @file vertex_item.h
* @brief Class to handle an item held in a container.
*/
#ifndef VBO_ITEM_H_
#define VBO_ITEM_H_
#ifndef VERTEX_ITEM_H_
#define VERTEX_ITEM_H_
#include <GL/gl.h>
#include <gal/opengl/vertex_common.h>
#include <gal/color4d.h>
#include <cstddef>
namespace KiGfx
{
typedef struct VBO_VERTEX
{
GLfloat x, y, z; // Coordinates
GLubyte r, g, b, a; // Color
GLfloat shader[4]; // Shader type & params
} VBO_VERTEX;
class VBO_CONTAINER;
class VERTEX_MANAGER;
class VBO_ITEM
class VERTEX_ITEM
{
friend class VBO_CONTAINER;
public:
VBO_ITEM( VBO_CONTAINER* aContainer );
~VBO_ITEM();
/**
* Function PushVertex()
* Adds a single vertex to the VBO_ITEM. Vertex contains information about coordinates and
* colors and has to follow the specified format {X,Y,Z,R,G,B,A}.
* @param aVertex is a vertex to be added.
* @param aShader is an attribute for shader.
*/
void PushVertex( const VBO_VERTEX* aVertex );
/**
* Function PushVertices()
* Adds multiple vertices to the VBO_ITEM. This function is recommended over multiple calls to
* PushVertex, as it does less memory reallocations. Vertices contain information about
* coordinates and colors and has to follow the specified format {X,Y,Z,R,G,B,A}.
* @param aVertices are vertices to be added.
* @param aSize is an amount of vertices to be added.
* @param aShader is an attribute for shader.
*/
void PushVertices( const VBO_VERTEX* aVertices, GLuint aSize );
/**
* Function GetVertices()
* Returns a pointer to the array containing all vertices.
* @return Pointer to vertices packed in format {X, Y, Z, R, G, B, A}.
*/
VBO_VERTEX* GetVertices();
friend class CACHED_CONTAINER;
friend class VERTEX_MANAGER;
VERTEX_ITEM( const VERTEX_MANAGER& aManager );
virtual ~VERTEX_ITEM();
/**
* Function GetSize()
* Returns information about number of vertices stored.
* @param Amount of vertices.
* @param Number of vertices.
*/
inline unsigned int GetSize() const
{
......@@ -93,7 +59,7 @@ public:
/**
* Function GetOffset()
* Returns data offset in the VBO.
* Returns data offset in the container.
* @return Data offset expressed as a number of vertices.
*/
inline unsigned int GetOffset() const
......@@ -102,76 +68,36 @@ public:
}
/**
* Function ChangeColor()
* Colors all vertices to the specified color.
* @param aColor is the new color for vertices.
*/
void ChangeColor( const COLOR4D& aColor );
/**
* Function ChangeDepth()
* Moves all vertices to the specified depth.
* @param aDepth is the new depth for vertices.
* Function GetVertices()
* Returns pointer to the data used by the VERTEX_ITEM.
*/
void ChangeDepth( int aDepth );
///< Informs the container that there will be no more vertices for the current VBO_ITEM
void Finish();
VERTEX* GetVertices() const;
///< Data structure for vertices {X,Y,Z,R,G,B,A,shader&param} (@see VBO_VERTEX).
static const unsigned int VertByteSize = sizeof(VBO_VERTEX);
static const unsigned int VertStride = VertByteSize / sizeof(GLfloat);
static const unsigned int CoordByteSize = sizeof(VBO_VERTEX().x) + sizeof(VBO_VERTEX().y) +
sizeof(VBO_VERTEX().z);
static const unsigned int CoordStride = CoordByteSize / sizeof(GLfloat);
// Offset of color data from the beginning of each vertex data
static const unsigned int ColorByteOffset = offsetof(VBO_VERTEX, r);
static const unsigned int ColorOffset = ColorByteOffset / sizeof(GLubyte);
static const unsigned int ColorByteSize = sizeof(VBO_VERTEX().r) + sizeof(VBO_VERTEX().g) +
sizeof(VBO_VERTEX().b) + sizeof(VBO_VERTEX().a);
static const unsigned int ColorStride = ColorByteSize / sizeof(GLubyte);
// Shader attributes
static const unsigned int ShaderByteOffset = offsetof(VBO_VERTEX, shader);
static const unsigned int ShaderOffset = ShaderByteOffset / sizeof(GLfloat);
static const unsigned int ShaderByteSize = sizeof(VBO_VERTEX().shader);
static const unsigned int ShaderStride = ShaderByteSize / sizeof(GLfloat);
static const unsigned int IndByteSize = sizeof(GLuint);
protected:
///< Offset and size of data stored in the VBO_CONTAINER.
unsigned int m_offset;
unsigned int m_size;
///< Storage for vertices.
VBO_CONTAINER* m_container;
///< Flag telling if the item should be recached in VBO or not.
bool m_isDirty;
private:
const VERTEX_MANAGER& m_manager;
unsigned int m_offset;
unsigned int m_size;
/**
* Function setSize()
* Sets data size in the VBO.
* @param aSize is the size expressed as a number of vertices.
* Function SetOffset()
* Sets data offset in the container.
* @param aOffset is the offset expressed as a number of vertices.
*/
void setSize( unsigned int aSize )
inline void setOffset( unsigned int aOffset )
{
m_size = aSize;
m_offset = aOffset;
}
/**
* Function setOffset()
* Sets data offset in the VBO.
* @param aOffset is the offset expressed as a number of vertices.
* Function SetSize()
* Sets data size in the container.
* @param aSize is the size expressed as a number of vertices.
*/
inline void setOffset( unsigned int aOffset )
inline void setSize( unsigned int aSize )
{
m_offset = aOffset;
m_size = aSize;
}
};
} // namespace KiGfx
#endif /* VBO_ITEM_H_ */
#endif /* VERTEX_ITEM_H_ */
This diff is collapsed.
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