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()
// Upload vertices coordinates and indices to GPU memory
glBindBuffer( GL_ARRAY_BUFFER, curVboVertId );
glBufferData( GL_ARRAY_BUFFER, vboSize * VBO_ITEM::VertSize, verticesBuffer, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndSize,
......
......@@ -40,11 +40,25 @@ VBO_ITEM::VBO_ITEM() :
m_isDirty( true ),
m_transform( NULL )
{
// Prepare a block for storing vertices & indices
useNewBlock();
}
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 )
delete m_vertices;
......@@ -55,20 +69,11 @@ VBO_ITEM::~VBO_ITEM()
void VBO_ITEM::PushVertex( const GLfloat* aVertex )
{
GLfloat* newVertices = new GLfloat[( m_size + 1 ) * VertStride];
GLuint* newIndices = new GLuint[( m_size + 1 ) * IndStride];
// 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;
if( m_spaceLeft == 0 )
useNewBlock();
// Add the new vertex
memcpy( &newVertices[m_size * VertStride], aVertex, VertSize );
memcpy( m_vertPtr, aVertex, VertSize );
if( m_transform != NULL )
{
......@@ -78,89 +83,45 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex )
glm::vec4 transVertex = *m_transform * origVertex;
// 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
if( m_indices )
{
// Copy all previous vertices data
memcpy( newIndices, m_indices, m_size * IndSize );
delete m_indices;
}
m_indices = newIndices;
// Move to the next free space
m_vertPtr += VertStride;
// Add the new vertex
m_indices[m_size] = m_offset + m_size;
// Add the new index
*m_indPtr = m_offset + m_size;
m_indPtr++;
m_size++;
m_isDirty = true;
m_spaceLeft--;
}
void VBO_ITEM::PushVertices( const GLfloat* aVertices, GLuint aSize )
{
int newSize = m_size + aSize;
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;
}
PushVertex( &aVertices[i * VertStride] );
}
// Handle new indices
if( m_indices )
{
// Copy all previous vertices data
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;
}
GLuint* VBO_ITEM::GetIndices() const
GLuint* VBO_ITEM::GetIndices()
{
if( m_isDirty )
prepareFinal();
return m_indices;
}
......@@ -202,6 +163,9 @@ void VBO_ITEM::SetTransformMatrix( const glm::mat4* aMatrix )
void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
{
if( m_isDirty )
prepareFinal();
// Point to color of vertices
GLfloat* vertexPtr = m_vertices + ColorOffset;
const GLfloat newColor[] = { aColor.r, aColor.g, aColor.b, aColor.a };
......@@ -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:
* @brief Blit the main texture to the screen.
*
* @param aIsClearFrameBuffer if true, the frame buffer is cleared as well.
*
*/
void blitMainTexture( bool aIsClearFrameBuffer );
......@@ -485,7 +484,7 @@ private:
/**
* @brief Rebuilds vertex buffer object using stored VBO_ITEMS and sends it to
* the graphic card memory.
* the graphics card memory.
*/
void rebuildVbo();
......@@ -529,6 +528,14 @@ private:
* @param aA is alpha component.
*/
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 selectShader( int aIndex );
......
......@@ -27,8 +27,6 @@
* @brief Class to handle an item held in a Vertex Buffer Object.
*/
// TODO comments
#ifndef VBO_ITEM_H_
#define VBO_ITEM_H_
......@@ -36,6 +34,8 @@
#include <gal/opengl/glm/glm.hpp>
#include <gal/color4d.h>
#include <list>
namespace KiGfx
{
......@@ -68,9 +68,14 @@ public:
* Returns a pointer to the array containing all vertices.
* @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()
......@@ -120,7 +125,7 @@ public:
//void SetVbo( int aVboId );
//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
static const int VertStride = 7;
static const int VertSize = VertStride * sizeof(GLfloat);
......@@ -128,7 +133,7 @@ public:
static const int IndStride = 1;
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 ColorByteOffset = ColorOffset * sizeof(GLfloat);
static const int ColorStride = 4;
......@@ -145,6 +150,21 @@ private:
///< Indices of vertices
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.
int m_offset;
int m_size;
......
......@@ -168,7 +168,7 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
// Load zones
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
......
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