Commit 733e5a55 authored by Maciej Suminski's avatar Maciej Suminski

Faster way of caching items for OPENGL GAL.

parent c9f9c4dd
...@@ -511,6 +511,7 @@ void OPENGL_GAL::rebuildVbo() ...@@ -511,6 +511,7 @@ void OPENGL_GAL::rebuildVbo()
// Upload vertices coordinates and indices to GPU memory // Upload vertices coordinates and indices to GPU memory
glBindBuffer( GL_ARRAY_BUFFER, curVboVertId ); glBindBuffer( GL_ARRAY_BUFFER, curVboVertId );
glBufferData( GL_ARRAY_BUFFER, vboSize * VBO_ITEM::VertSize, verticesBuffer, GL_DYNAMIC_DRAW ); glBufferData( GL_ARRAY_BUFFER, vboSize * VBO_ITEM::VertSize, verticesBuffer, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndSize, glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndSize,
......
...@@ -40,11 +40,25 @@ VBO_ITEM::VBO_ITEM() : ...@@ -40,11 +40,25 @@ VBO_ITEM::VBO_ITEM() :
m_isDirty( true ), m_isDirty( true ),
m_transform( NULL ) m_transform( NULL )
{ {
// Prepare a block for storing vertices & indices
useNewBlock();
} }
VBO_ITEM::~VBO_ITEM() VBO_ITEM::~VBO_ITEM()
{ {
if( m_isDirty )
{
// Data is still stored in blocks
std::list<GLfloat*>::const_iterator v_it, v_end;
for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it )
delete[] *v_it;
std::list<GLuint*>::const_iterator i_it, i_end;
for( i_it = m_indBlocks.begin(), i_end = m_indBlocks.end(); i_it != i_end; ++i_it )
delete[] *i_it;
}
if( m_vertices ) if( m_vertices )
delete m_vertices; delete m_vertices;
...@@ -55,20 +69,11 @@ VBO_ITEM::~VBO_ITEM() ...@@ -55,20 +69,11 @@ VBO_ITEM::~VBO_ITEM()
void VBO_ITEM::PushVertex( const GLfloat* aVertex ) void VBO_ITEM::PushVertex( const GLfloat* aVertex )
{ {
GLfloat* newVertices = new GLfloat[( m_size + 1 ) * VertStride]; if( m_spaceLeft == 0 )
GLuint* newIndices = new GLuint[( m_size + 1 ) * IndStride]; useNewBlock();
// Handle a new vertex
if( m_vertices )
{
// Copy all previous vertices data
memcpy( newVertices, m_vertices, m_size * VertSize );
delete m_vertices;
}
m_vertices = newVertices;
// Add the new vertex // Add the new vertex
memcpy( &newVertices[m_size * VertStride], aVertex, VertSize ); memcpy( m_vertPtr, aVertex, VertSize );
if( m_transform != NULL ) if( m_transform != NULL )
{ {
...@@ -78,89 +83,45 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex ) ...@@ -78,89 +83,45 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex )
glm::vec4 transVertex = *m_transform * origVertex; glm::vec4 transVertex = *m_transform * origVertex;
// Replace only coordinates, leave color as it is // Replace only coordinates, leave color as it is
memcpy( &newVertices[m_size * VertStride], &transVertex[0], 3 * sizeof(GLfloat) ); memcpy( m_vertPtr, &transVertex[0], 3 * sizeof(GLfloat) );
} }
// Handle a new index // Move to the next free space
if( m_indices ) m_vertPtr += VertStride;
{
// Copy all previous vertices data
memcpy( newIndices, m_indices, m_size * IndSize );
delete m_indices;
}
m_indices = newIndices;
// Add the new vertex // Add the new index
m_indices[m_size] = m_offset + m_size; *m_indPtr = m_offset + m_size;
m_indPtr++;
m_size++; m_size++;
m_isDirty = true; m_isDirty = true;
m_spaceLeft--;
} }
void VBO_ITEM::PushVertices( const GLfloat* aVertices, GLuint aSize ) void VBO_ITEM::PushVertices( const GLfloat* aVertices, GLuint aSize )
{ {
int newSize = m_size + aSize; for( unsigned int i = 0; i < aSize; ++i )
GLfloat* newVertices = new GLfloat[newSize * VertStride];
GLuint* newIndices = new GLuint[newSize * IndStride];
// Handle new vertices
if( m_vertices )
{
// Copy all previous vertices data
memcpy( newVertices, m_vertices, ( m_size ) * VertSize );
delete m_vertices;
}
m_vertices = newVertices;
// Add new vertices
memcpy( &newVertices[m_size * VertStride], aVertices, aSize * VertSize );
if( m_transform != NULL )
{
const GLfloat* vertexPtr = aVertices;
for( unsigned int i = 0; i < aSize; ++i )
{
// Apply transformations
// X, Y, Z coordinates
glm::vec4 origVertex( vertexPtr[0], vertexPtr[1], vertexPtr[2], 1.0f );
glm::vec4 transVertex = *m_transform * origVertex;
// Replace only coordinates, leave color as it is
memcpy( &newVertices[(m_size + i) * VertStride], &transVertex[0], 3 * sizeof(GLfloat) );
// Move on to the next vertex
vertexPtr += VertStride;
}
}
// Handle new indices
if( m_indices )
{ {
// Copy all previous vertices data PushVertex( &aVertices[i * VertStride] );
memcpy( newIndices, m_indices, ( m_size ) * IndSize );
delete m_indices;
} }
m_indices = newIndices;
// Add the new vertex
for( int i = m_size; i < newSize; ++i )
m_indices[i] = m_offset + i;
m_size += aSize;
m_isDirty = true;
} }
GLfloat* VBO_ITEM::GetVertices() const GLfloat* VBO_ITEM::GetVertices()
{ {
if( m_isDirty )
prepareFinal();
return m_vertices; return m_vertices;
} }
GLuint* VBO_ITEM::GetIndices() const GLuint* VBO_ITEM::GetIndices()
{ {
if( m_isDirty )
prepareFinal();
return m_indices; return m_indices;
} }
...@@ -202,6 +163,9 @@ void VBO_ITEM::SetTransformMatrix( const glm::mat4* aMatrix ) ...@@ -202,6 +163,9 @@ void VBO_ITEM::SetTransformMatrix( const glm::mat4* aMatrix )
void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
{ {
if( m_isDirty )
prepareFinal();
// Point to color of vertices // Point to color of vertices
GLfloat* vertexPtr = m_vertices + ColorOffset; GLfloat* vertexPtr = m_vertices + ColorOffset;
const GLfloat newColor[] = { aColor.r, aColor.g, aColor.b, aColor.a }; const GLfloat newColor[] = { aColor.r, aColor.g, aColor.b, aColor.a };
...@@ -237,3 +201,64 @@ int GetVbo() const ...@@ -237,3 +201,64 @@ int GetVbo() const
{ {
} }
*/ */
void VBO_ITEM::useNewBlock()
{
GLfloat* newVertBlock = new GLfloat[BLOCK_SIZE * VertStride];
GLuint* newIndBlock = new GLuint[BLOCK_SIZE];
m_vertPtr = newVertBlock;
m_indPtr = newIndBlock;
m_vertBlocks.push_back( newVertBlock );
m_indBlocks.push_back( newIndBlock );
m_spaceLeft = BLOCK_SIZE;
}
void VBO_ITEM::prepareFinal()
{
if( m_vertices )
delete m_vertices;
// Allocate memory that would store all of vertices
m_vertices = new GLfloat[m_size * VertStride];
// Set the pointer that will move along the buffer
GLfloat* vertPtr = m_vertices;
// Copy blocks of vertices one after another to m_vertices
std::list<GLfloat*>::const_iterator v_it;
for( v_it = m_vertBlocks.begin(); *v_it != m_vertBlocks.back(); ++v_it )
{
memcpy( vertPtr, *v_it, BLOCK_SIZE * VertSize );
delete[] *v_it;
vertPtr += ( BLOCK_SIZE * VertStride );
}
// In the last block we need to copy only used vertices
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertSize );
if( m_indices )
delete m_indices;
// Allocate memory that would store all of indices
m_indices = new GLuint[m_size * IndStride];
// Set the pointer that will move along the buffer
GLuint* indPtr = m_indices;
// Copy blocks of indices one after another to m_indices
std::list<GLuint*>::const_iterator i_it;
for( i_it = m_indBlocks.begin(); *i_it != m_indBlocks.back(); ++i_it )
{
memcpy( indPtr, *i_it, BLOCK_SIZE * IndSize );
delete[] *i_it;
indPtr += ( BLOCK_SIZE * IndStride );
}
// In the last block we need to copy only used indices
memcpy( indPtr, *i_it, ( BLOCK_SIZE - m_spaceLeft ) * IndSize );
m_isDirty = false;
}
...@@ -448,7 +448,6 @@ private: ...@@ -448,7 +448,6 @@ private:
* @brief Blit the main texture to the screen. * @brief Blit the main texture to the screen.
* *
* @param aIsClearFrameBuffer if true, the frame buffer is cleared as well. * @param aIsClearFrameBuffer if true, the frame buffer is cleared as well.
*
*/ */
void blitMainTexture( bool aIsClearFrameBuffer ); void blitMainTexture( bool aIsClearFrameBuffer );
...@@ -485,7 +484,7 @@ private: ...@@ -485,7 +484,7 @@ private:
/** /**
* @brief Rebuilds vertex buffer object using stored VBO_ITEMS and sends it to * @brief Rebuilds vertex buffer object using stored VBO_ITEMS and sends it to
* the graphic card memory. * the graphics card memory.
*/ */
void rebuildVbo(); void rebuildVbo();
...@@ -529,6 +528,14 @@ private: ...@@ -529,6 +528,14 @@ private:
* @param aA is alpha component. * @param aA is alpha component.
*/ */
inline void color4( double aRed, double aGreen, double aBlue, double aAlpha ); inline void color4( double aRed, double aGreen, double aBlue, double aAlpha );
/**
* @brief Function that replaces glColor and behaves according to isGrouping variable.
* In case isGrouping==false, it is simply glColor, in other case it
* modifies color used by current VBO_ITEM.
*
* @param aColor is the new color.
*/
inline void color4( const COLOR4D& aColor ); inline void color4( const COLOR4D& aColor );
inline void selectShader( int aIndex ); inline void selectShader( int aIndex );
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
* @brief Class to handle an item held in a Vertex Buffer Object. * @brief Class to handle an item held in a Vertex Buffer Object.
*/ */
// TODO comments
#ifndef VBO_ITEM_H_ #ifndef VBO_ITEM_H_
#define VBO_ITEM_H_ #define VBO_ITEM_H_
...@@ -36,6 +34,8 @@ ...@@ -36,6 +34,8 @@
#include <gal/opengl/glm/glm.hpp> #include <gal/opengl/glm/glm.hpp>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <list>
namespace KiGfx namespace KiGfx
{ {
...@@ -68,9 +68,14 @@ public: ...@@ -68,9 +68,14 @@ public:
* Returns a pointer to the array containing all vertices. * Returns a pointer to the array containing all vertices.
* @return Pointer to vertices packed in format {X, Y, Z, R, G, B, A}. * @return Pointer to vertices packed in format {X, Y, Z, R, G, B, A}.
*/ */
GLfloat* GetVertices() const; GLfloat* GetVertices();
GLuint* GetIndices() const; /**
* Function GetIndices()
* Returns a pointer to the array containing all indices of vertices.
* @return Pointer to indices.
*/
GLuint* GetIndices();
/** /**
* Function GetSize() * Function GetSize()
...@@ -120,7 +125,7 @@ public: ...@@ -120,7 +125,7 @@ public:
//void SetVbo( int aVboId ); //void SetVbo( int aVboId );
//int GetVbo() const; //int GetVbo() const;
///< Data organization information for vertices. ///< Data organization information for vertices {X,Y,Z,R,G,B,A}.
// Each vertex consists of 7 floats // Each vertex consists of 7 floats
static const int VertStride = 7; static const int VertStride = 7;
static const int VertSize = VertStride * sizeof(GLfloat); static const int VertSize = VertStride * sizeof(GLfloat);
...@@ -128,7 +133,7 @@ public: ...@@ -128,7 +133,7 @@ public:
static const int IndStride = 1; static const int IndStride = 1;
static const int IndSize = IndStride * sizeof(GLuint); static const int IndSize = IndStride * sizeof(GLuint);
// Offset of color data from the beginning of vertex data // Offset of color data from the beginning of each vertex data
static const int ColorOffset = 3; static const int ColorOffset = 3;
static const int ColorByteOffset = ColorOffset * sizeof(GLfloat); static const int ColorByteOffset = ColorOffset * sizeof(GLfloat);
static const int ColorStride = 4; static const int ColorStride = 4;
...@@ -145,6 +150,21 @@ private: ...@@ -145,6 +150,21 @@ private:
///< Indices of vertices ///< Indices of vertices
GLuint* m_indices; GLuint* m_indices;
///< Lists of blocks
std::list<GLfloat*> m_vertBlocks;
std::list<GLuint*> m_indBlocks;
///< Pointers to current blocks that can be used for storing data
GLfloat* m_vertPtr;
GLuint* m_indPtr;
///< How many vertices can be stored in the current buffer
int m_spaceLeft;
///< Number of vertices & indices stored in a single block
static const int BLOCK_SIZE = 8;
///< Creates a new block for storing vertices data
void useNewBlock();
///< Prepares a continuous block of data that can be copied to graphics card buffer.
void prepareFinal();
///< Offset and size of data in VBO. ///< Offset and size of data in VBO.
int m_offset; int m_offset;
int m_size; int m_size;
......
...@@ -168,7 +168,7 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) ...@@ -168,7 +168,7 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
// Load zones // Load zones
for( int i = 0; i < m_Pcb->GetAreaCount(); ++i ) for( int i = 0; i < m_Pcb->GetAreaCount(); ++i )
{ {
//view->Add( (KiGfx::VIEW_ITEM*) ( m_Pcb->GetArea( i ) ) ); view->Add( (KiGfx::VIEW_ITEM*) ( m_Pcb->GetArea( i ) ) );
} }
// Load drawings // Load drawings
......
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