Vertices are stored in GPU memory (OpenGL GAL).

This commit is contained in:
Maciej Suminski 2016-05-02 16:12:16 +02:00
parent 01912aaabd
commit 702be4903f
14 changed files with 267 additions and 216 deletions

View File

@ -152,7 +152,11 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_painter->GetSettings() );
m_viewControls->UpdateScrollbars();
m_gal->BeginUpdate();
m_view->UpdateItems();
m_gal->EndUpdate();
m_gal->BeginDrawing();
m_gal->ClearScreen( settings->GetBackgroundColor() );

View File

@ -33,6 +33,8 @@
#include <gal/opengl/vertex_manager.h>
#include <gal/opengl/vertex_item.h>
#include <gal/opengl/shader.h>
#include <gal/opengl/utils.h>
#include <confirm.h>
#include <list>
#include <cassert>
@ -45,7 +47,8 @@
using namespace KIGFX;
CACHED_CONTAINER::CACHED_CONTAINER( unsigned int aSize ) :
VERTEX_CONTAINER( aSize ), m_item( NULL )
VERTEX_CONTAINER( aSize ), m_item( NULL ), m_isMapped( false ),
m_isInitialized( false ), m_glBufferHandle( -1 )
{
// In the beginning there is only free space
m_freeChunks.insert( CHUNK( aSize, 0 ) );
@ -57,6 +60,18 @@ CACHED_CONTAINER::CACHED_CONTAINER( unsigned int aSize ) :
}
CACHED_CONTAINER::~CACHED_CONTAINER()
{
if( m_isMapped )
Unmap();
if( m_isInitialized )
{
glDeleteBuffers( 1, &m_glBufferHandle );
}
}
void CACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
{
assert( aItem != NULL );
@ -103,6 +118,7 @@ void CACHED_CONTAINER::FinishItem()
VERTEX* CACHED_CONTAINER::Allocate( unsigned int aSize )
{
assert( m_item != NULL );
assert( m_isMapped );
if( m_failed )
return NULL;
@ -181,7 +197,7 @@ void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
// a large amount of memory when there is no use for it
if( m_freeSpace > ( 0.75 * m_currentSize ) && m_currentSize > m_initialSize )
{
resizeContainer( 0.5 * m_currentSize );
defragmentResize( 0.5 * m_currentSize );
}
#endif
}
@ -189,6 +205,10 @@ void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
void CACHED_CONTAINER::Clear()
{
Map();
glInvalidateBufferData( GL_ARRAY_BUFFER );
Unmap();
m_freeSpace = m_currentSize;
m_failed = false;
@ -207,9 +227,51 @@ void CACHED_CONTAINER::Clear()
}
void CACHED_CONTAINER::Map()
{
assert( !IsMapped() );
if( !m_isInitialized )
init();
glBindBuffer( GL_ARRAY_BUFFER, m_glBufferHandle );
m_vertices = static_cast<VERTEX*>( glMapBuffer( GL_ARRAY_BUFFER, GL_READ_WRITE ) );
checkGlError( "mapping vertices buffer" );
m_isMapped = true;
}
void CACHED_CONTAINER::Unmap()
{
assert( IsMapped() );
glUnmapBuffer( GL_ARRAY_BUFFER );
checkGlError( "unmapping vertices buffer" );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
m_vertices = NULL;
checkGlError( "unbinding vertices buffer" );
m_isMapped = false;
}
void CACHED_CONTAINER::init()
{
glGenBuffers( 1, &m_glBufferHandle );
glBindBuffer( GL_COPY_WRITE_BUFFER, m_glBufferHandle );
glBufferData( GL_COPY_WRITE_BUFFER, m_currentSize * VertexSize, NULL, GL_DYNAMIC_DRAW );
glBindBuffer( GL_COPY_WRITE_BUFFER, 0 );
checkGlError( "allocating video memory for cached container" );
m_isInitialized = true;
}
unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
{
assert( aSize > 0 );
assert( m_isMapped );
#if CACHED_CONTAINER_TEST > 2
wxLogDebug( wxT( "Resize 0x%08lx from %d to %d" ), (long) m_item, m_itemSize, aSize );
@ -224,12 +286,12 @@ unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
if( aSize < m_freeSpace + m_currentSize )
{
// Yes: exponential growing
result = resizeContainer( m_currentSize * 2 );
result = defragmentResize( m_currentSize * 2 );
}
else
{
// No: grow to the nearest greater power of 2
result = resizeContainer( pow( 2, ceil( log2( m_currentSize * 2 + aSize ) ) ) );
result = defragmentResize( pow( 2, ceil( log2( m_currentSize * 2 + aSize ) ) ) );
}
if( !result )
@ -243,7 +305,7 @@ unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
{
// In the case when there is enough space to store the vertices,
// but the free space is not continous we should defragment the container
if( !defragment() )
if( !defragmentResize( m_currentSize ) )
return UINT_MAX;
// Update the current offset
@ -288,72 +350,12 @@ unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
m_freeSpace -= aSize;
// mergeFreeChunks(); // veery slow and buggy
m_item->setOffset( newChunkOffset );
return newChunkOffset;
}
bool CACHED_CONTAINER::defragment( VERTEX* aTarget )
{
#if CACHED_CONTAINER_TEST > 0
wxLogDebug( wxT( "Defragmenting" ) );
prof_counter totalTime;
prof_start( &totalTime );
#endif
if( aTarget == NULL )
{
// No target was specified, so we have to reallocate our own space
int size = m_currentSize * sizeof( VERTEX );
aTarget = static_cast<VERTEX*>( malloc( size ) );
if( aTarget == NULL )
{
DisplayError( NULL, wxString::Format(
wxT( "CACHED_CONTAINER::defragment: Run out of memory (malloc %d bytes)" ),
size ) );
return false;
}
}
int newOffset = 0;
ITEMS::iterator it, it_end;
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
{
VERTEX_ITEM* item = *it;
int itemOffset = item->GetOffset();
int itemSize = item->GetSize();
// Move an item to the new container
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VertexSize );
// Update new offset
item->setOffset( newOffset );
// Move to the next free space
newOffset += itemSize;
}
free( m_vertices );
m_vertices = aTarget;
// Now there is only one big chunk of free memory
m_freeChunks.clear();
wxASSERT( m_freeSpace > 0 );
m_freeChunks.insert( CHUNK( m_freeSpace, m_currentSize - m_freeSpace ) );
#if CACHED_CONTAINER_TEST > 0
prof_end( &totalTime );
wxLogDebug( wxT( "Defragmented the container storing %d vertices / %.1f ms" ),
m_currentSize - m_freeSpace, totalTime.msecs() );
#endif
return true;
}
void CACHED_CONTAINER::mergeFreeChunks()
{
if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged
@ -415,65 +417,72 @@ void CACHED_CONTAINER::mergeFreeChunks()
}
bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
bool CACHED_CONTAINER::defragmentResize( unsigned int aNewSize )
{
#if CACHED_CONTAINER_TEST > 0
wxLogDebug( wxT( "Resizing container from %d to %d" ), m_currentSize, aNewSize );
#endif
VERTEX* newContainer;
// No shrinking if we cannot fit all the data
if( aNewSize < m_currentSize && usedSpace() > aNewSize )
return false;
if( aNewSize < m_currentSize )
#if CACHED_CONTAINER_TEST > 0
wxLogDebug( wxT( "Defragmenting" ) );
prof_counter totalTime;
prof_start( &totalTime );
#endif
GLuint newBuffer;
Unmap();
glGenBuffers( 1, &newBuffer );
glBindBuffer( GL_COPY_WRITE_BUFFER, newBuffer );
glBufferData( GL_COPY_WRITE_BUFFER, aNewSize * VertexSize, NULL, GL_DYNAMIC_DRAW );
glBindBuffer( GL_COPY_READ_BUFFER, m_glBufferHandle );
checkGlError( "resizing vertex buffer" );
int newOffset = 0;
ITEMS::iterator it, it_end;
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
{
// Shrinking container
// Sanity check, no shrinking if we cannot fit all the data
if( usedSpace() > aNewSize )
return false;
VERTEX_ITEM* item = *it;
int itemOffset = item->GetOffset();
int itemSize = item->GetSize();
int size = aNewSize * sizeof( VERTEX );
newContainer = static_cast<VERTEX*>( malloc( size ) );
// Move an item to the new container
glCopyBufferSubData( GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
itemOffset * VertexSize, newOffset * VertexSize, itemSize * VertexSize );
if( newContainer == NULL )
{
DisplayError( NULL, wxString::Format(
wxT( "CACHED_CONTAINER::resizeContainer:\n"
"Run out of memory (malloc %d bytes)" ),
size ) );
return false;
}
// Update new offset
item->setOffset( newOffset );
// Defragment directly to the new, smaller container
defragment( newContainer );
// We have to correct freeChunks after defragmentation
m_freeChunks.clear();
wxASSERT( aNewSize - usedSpace() > 0 );
m_freeChunks.insert( CHUNK( aNewSize - usedSpace(), usedSpace() ) );
}
else
{
// Enlarging container
int size = aNewSize * sizeof( VERTEX );
newContainer = static_cast<VERTEX*>( realloc( m_vertices, size ) );
if( newContainer == NULL )
{
DisplayError( NULL, wxString::Format(
wxT( "CACHED_CONTAINER::resizeContainer:\n"
"Run out of memory (realloc from %d to %d bytes)" ),
m_currentSize * sizeof( VERTEX ), size ) );
return false;
}
// Add an entry for the new memory chunk at the end of the container
m_freeChunks.insert( CHUNK( aNewSize - m_currentSize, m_currentSize ) );
// Move to the next free space
newOffset += itemSize;
}
m_vertices = newContainer;
glBindBuffer( GL_COPY_WRITE_BUFFER, 0 );
glBindBuffer( GL_COPY_READ_BUFFER, 0 );
glDeleteBuffers( 1, &m_glBufferHandle );
m_glBufferHandle = newBuffer;
checkGlError( "switching buffers during defragmentation" );
Map();
m_freeSpace += ( aNewSize - m_currentSize );
#if CACHED_CONTAINER_TEST > 0
prof_end( &totalTime );
wxLogDebug( wxT( "Defragmented the container storing %d vertices / %.1f ms" ),
m_currentSize - m_freeSpace, totalTime.msecs() );
#endif
m_freeSpace += ( aNewSize - m_currentSize );
m_currentSize = aNewSize;
// Now there is only one big chunk of free memory
m_freeChunks.clear();
m_freeChunks.insert( CHUNK( m_freeSpace, m_currentSize - m_freeSpace ) );
return true;
}

View File

@ -69,7 +69,6 @@ GPU_MANAGER::~GPU_MANAGER()
void GPU_MANAGER::SetShader( SHADER& aShader )
{
m_shader = &aShader;
m_shaderAttrib = m_shader->GetAttribute( "attrShaderParams" );
if( m_shaderAttrib == -1 )
@ -82,7 +81,7 @@ void GPU_MANAGER::SetShader( SHADER& aShader )
// Cached manager
GPU_CACHED_MANAGER::GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
GPU_MANAGER( aContainer ), m_buffersInitialized( false ), m_indicesPtr( NULL ),
m_verticesBuffer( 0 ), m_indicesBuffer( 0 ), m_indicesSize( 0 ), m_indicesCapacity( 0 )
m_indicesBuffer( 0 ), m_indicesSize( 0 ), m_indicesCapacity( 0 )
{
// Allocate the biggest possible buffer for indices
resizeIndices( aContainer->GetSize() );
@ -94,33 +93,24 @@ GPU_CACHED_MANAGER::~GPU_CACHED_MANAGER()
if( m_buffersInitialized )
{
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glDeleteBuffers( 1, &m_verticesBuffer );
glDeleteBuffers( 1, &m_indicesBuffer );
}
}
void GPU_CACHED_MANAGER::Initialize()
{
wxASSERT( !m_buffersInitialized );
if( !m_buffersInitialized )
{
glGenBuffers( 1, &m_indicesBuffer );
checkGlError( "generating vertices buffer" );
glGenBuffers( 1, &m_verticesBuffer );
checkGlError( "generating vertices buffer" );
m_buffersInitialized = true;
}
}
void GPU_CACHED_MANAGER::BeginDrawing()
{
wxASSERT( !m_isDrawing );
if( !m_buffersInitialized )
{
glGenBuffers( 1, &m_indicesBuffer );
checkGlError( "generating vertices buffer" );
m_buffersInitialized = true;
}
if( m_container->IsDirty() )
uploadToGpu();
resizeIndices( m_container->GetSize() );
// Number of vertices to be drawn in the EndDrawing()
m_indicesSize = 0;
@ -160,6 +150,11 @@ void GPU_CACHED_MANAGER::EndDrawing()
wxASSERT( m_isDrawing );
CACHED_CONTAINER* cached = static_cast<CACHED_CONTAINER*>( m_container );
if( cached->IsMapped() )
cached->Unmap();
if( m_indicesSize == 0 )
{
m_isDrawing = false;
@ -171,7 +166,7 @@ void GPU_CACHED_MANAGER::EndDrawing()
glEnableClientState( GL_COLOR_ARRAY );
// Bind vertices data buffers
glBindBuffer( GL_ARRAY_BUFFER, m_verticesBuffer );
glBindBuffer( GL_ARRAY_BUFFER, cached->GetBufferHandle() );
glVertexPointer( CoordStride, GL_FLOAT, VertexSize, 0 );
glColorPointer( ColorStride, GL_UNSIGNED_BYTE, VertexSize, (GLvoid*) ColorOffset );
@ -185,7 +180,7 @@ void GPU_CACHED_MANAGER::EndDrawing()
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indicesSize * sizeof(int),
(GLvoid*) m_indices.get(), GL_STATIC_DRAW );
(GLvoid*) m_indices.get(), GL_DYNAMIC_DRAW );
glDrawElements( GL_TRIANGLES, m_indicesSize, GL_UNSIGNED_INT, 0 );
@ -216,38 +211,6 @@ void GPU_CACHED_MANAGER::EndDrawing()
}
void GPU_CACHED_MANAGER::uploadToGpu()
{
#ifdef __WXDEBUG__
prof_counter totalTime;
prof_start( &totalTime );
#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 );
checkGlError( "binding vertices buffer" );
glBufferData( GL_ARRAY_BUFFER, bufferSize * VertexSize, vertices, GL_STATIC_DRAW );
checkGlError( "transferring vertices" );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
checkGlError( "unbinding vertices buffer" );
// Allocate the biggest possible buffer for indices
resizeIndices( bufferSize );
#ifdef __WXDEBUG__
prof_end( &totalTime );
wxLogTrace( "GAL_PROFILE",
wxT( "Uploading %d vertices to GPU / %.1f ms" ), bufferSize, totalTime.msecs() );
#endif /* __WXDEBUG__ */
}
void GPU_CACHED_MANAGER::resizeIndices( unsigned int aNewSize )
{
if( aNewSize > m_indicesCapacity )
@ -265,12 +228,6 @@ GPU_NONCACHED_MANAGER::GPU_NONCACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
}
void GPU_NONCACHED_MANAGER::Initialize()
{
// Nothing has to be intialized
}
void GPU_NONCACHED_MANAGER::BeginDrawing()
{
// Nothing has to be prepared

View File

@ -29,6 +29,7 @@
*/
#include <gal/opengl/noncached_container.h>
#include <cstring>
#include <cstdlib>
using namespace KIGFX;
@ -36,11 +37,14 @@ using namespace KIGFX;
NONCACHED_CONTAINER::NONCACHED_CONTAINER( unsigned int aSize ) :
VERTEX_CONTAINER( aSize ), m_freePtr( 0 )
{
m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
}
NONCACHED_CONTAINER::~NONCACHED_CONTAINER()
{
free( m_vertices );
}

View File

@ -299,6 +299,18 @@ void OPENGL_GAL::EndDrawing()
}
void OPENGL_GAL::BeginUpdate()
{
cachedManager.Map();
}
void OPENGL_GAL::EndUpdate()
{
cachedManager.Unmap();
}
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{
const VECTOR2D startEndVector = aEndPoint - aStartPoint;

View File

@ -31,8 +31,6 @@
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/shader.h>
#include <cstdlib>
#include <cstring>
using namespace KIGFX;
@ -47,14 +45,11 @@ VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached )
VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ),
m_failed( false ), m_dirty( true )
m_vertices( NULL ), m_failed( false ), m_dirty( true )
{
m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
}
VERTEX_CONTAINER::~VERTEX_CONTAINER()
{
free( m_vertices );
}

View File

@ -49,6 +49,18 @@ VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) :
}
void VERTEX_MANAGER::Map()
{
m_container->Map();
}
void VERTEX_MANAGER::Unmap()
{
m_container->Unmap();
}
bool VERTEX_MANAGER::Reserve( unsigned int aSize )
{
assert( m_reservedSpace == 0 && m_reserved == NULL );

View File

@ -422,9 +422,11 @@ void VIEW::UpdateLayerColor( int aLayer )
r.SetMaximum();
m_gal->BeginUpdate();
updateItemsColor visitor( aLayer, m_painter, m_gal );
m_layers[aLayer].items->Query( r, visitor );
MarkTargetDirty( m_layers[aLayer].target );
m_gal->EndUpdate();
}
@ -433,6 +435,7 @@ void VIEW::UpdateAllLayersColor()
BOX2I r;
r.SetMaximum();
m_gal->BeginUpdate();
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{
@ -446,6 +449,7 @@ void VIEW::UpdateAllLayersColor()
l->items->Query( r, visitor );
}
m_gal->EndUpdate();
MarkDirty();
}
@ -482,8 +486,11 @@ void VIEW::ChangeLayerDepth( int aLayer, int aDepth )
r.SetMaximum();
m_gal->BeginUpdate();
changeItemsDepth visitor( aLayer, aDepth, m_gal );
m_layers[aLayer].items->Query( r, visitor );
m_gal->EndUpdate();
MarkTargetDirty( m_layers[aLayer].target );
}
@ -1009,6 +1016,8 @@ void VIEW::RecacheAllItems( bool aImmediately )
prof_start( &totalRealTime );
#endif /* __WXDEBUG__ */
m_gal->BeginUpdate();
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{
VIEW_LAYER* l = &( ( *i ).second );
@ -1023,6 +1032,8 @@ void VIEW::RecacheAllItems( bool aImmediately )
}
}
m_gal->EndUpdate();
#ifdef __WXDEBUG__
prof_end( &totalRealTime );
wxLogTrace( "GAL_PROFILE", wxT( "RecacheAllItems::immediately: %u %.1f ms" ),

View File

@ -79,6 +79,12 @@ public:
/// @brief End the drawing, needs to be called for every new frame.
virtual void EndDrawing() {};
/// @brief Enables item update mode.
virtual void BeginUpdate() {}
/// @brief Disables item update mode.
virtual void EndUpdate() {}
/**
* @brief Draw a line.
*

View File

@ -48,6 +48,7 @@ class CACHED_CONTAINER : public VERTEX_CONTAINER
{
public:
CACHED_CONTAINER( unsigned int aSize = defaultInitSize );
~CACHED_CONTAINER();
///> @copydoc VERTEX_CONTAINER::SetItem()
virtual void SetItem( VERTEX_ITEM* aItem );
@ -64,6 +65,30 @@ public:
///> @copydoc VERTEX_CONTAINER::Clear()
virtual void Clear();
/**
* Function GetBufferHandle()
* returns handle to the vertex buffer. It might be negative if the buffer is not initialized.
*/
inline unsigned int GetBufferHandle() const
{
return m_glBufferHandle;
}
/**
* Function IsMapped()
* returns true if vertex buffer is currently mapped.
*/
inline bool IsMapped() const
{
return m_isMapped;
}
///> @copydoc VERTEX_CONTAINER::Map()
void Map();
///> @copydoc VERTEX_CONTAINER::Unmap()
void Unmap();
protected:
///> Maps size of free memory chunks to their offsets
typedef std::pair<unsigned int, unsigned int> CHUNK;
@ -86,6 +111,17 @@ protected:
unsigned int m_chunkOffset;
unsigned int m_itemSize;
bool m_isMapped;
bool m_isInitialized;
unsigned int m_glBufferHandle;
/**
* Function init()
* performs the GL vertex buffer initialization. It can be invoked only when an OpenGL context
* is bound.
*/
void init();
/**
* Function reallocate()
* resizes the chunk that stores the current item to the given size.
@ -96,32 +132,21 @@ protected:
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.
* Function defragmentResize()
* removes empty spaces between chunks and optionally resizes the container.
* After the operation there is continous space for storing vertices at the end 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)
* @param aNewSize is the new size of container, expressed in number of vertices
* @return false in case of failure (e.g. memory shortage)
*/
virtual bool defragment( VERTEX* aTarget = NULL );
bool defragmentResize( unsigned int aNewSize );
/**
* 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 );
void mergeFreeChunks();
/**
* Function getPowerOf2()

View File

@ -47,12 +47,6 @@ public:
virtual ~GPU_MANAGER();
/**
* @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.
@ -109,9 +103,6 @@ public:
GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer );
~GPU_CACHED_MANAGER();
///> @copydoc GPU_MANAGER::Initialize()
virtual void Initialize();
///> @copydoc GPU_MANAGER::BeginDrawing()
virtual void BeginDrawing();
@ -124,14 +115,13 @@ public:
///> @copydoc GPU_MANAGER::EndDrawing()
virtual void EndDrawing();
protected:
/**
* Function uploadToGpu
* Rebuilds vertex buffer object using stored VERTEX_ITEMs and sends it to the graphics card
* memory.
*/
virtual void uploadToGpu();
///> Maps vertex buffer stored in GPU memory.
void Map();
///> Unmaps vertex buffer.
void Unmap();
protected:
///> Resizes the indices buffer to aNewSize if necessary
void resizeIndices( unsigned int aNewSize );
@ -144,9 +134,6 @@ protected:
///> Pointer to the first free cell in the indices buffer
GLuint* m_indicesPtr;
///> Handle to vertices buffer
GLuint m_verticesBuffer;
///> Handle to indices buffer
GLuint m_indicesBuffer;
@ -163,9 +150,6 @@ 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();

View File

@ -34,6 +34,7 @@
#include <gal/opengl/shader.h>
#include <gal/opengl/vertex_manager.h>
#include <gal/opengl/vertex_item.h>
#include <gal/opengl/cached_container.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/opengl_compositor.h>
@ -95,6 +96,12 @@ public:
/// @copydoc GAL::EndDrawing()
virtual void EndDrawing();
/// @copydoc GAL::BeginUpdate()
virtual void BeginUpdate();
/// @copydoc GAL::EndUpdate()
virtual void EndUpdate();
/// @copydoc GAL::DrawLine()
virtual void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );

View File

@ -48,6 +48,19 @@ public:
virtual ~VERTEX_CONTAINER();
/**
* Function Map()
* prepares the container for vertices updates.
*/
virtual void Map() {}
/**
* Function Unmap()
* finishes the vertices updates stage.
*/
virtual void Unmap()
{}
/**
* Function SetItem()
* sets the item in order to modify or finishes its current modifications.

View File

@ -58,6 +58,18 @@ public:
*/
VERTEX_MANAGER( bool aCached );
/**
* Function Map()
* maps vertex buffer.
*/
void Map();
/**
* Function Unmap()
* unmaps vertex buffer.
*/
void Unmap();
/**
* Function Reserve()
* allocates space for vertices, so it will be used with subsequent Vertex() calls.