Commit 8742dae4 authored by Maciej Suminski's avatar Maciej Suminski

Removed indices storing from VBO_ITEM as they are always consecutive numbers....

Removed indices storing from VBO_ITEM as they are always consecutive numbers. Removed storing pointers to VBO_ITEMs that have to be drawn - instead they are memcpied to mapped GPU memory.
Some functions of VBO_ITEM became inline.
parent 8e1fe5d7
...@@ -414,9 +414,19 @@ void OPENGL_GAL::BeginDrawing() ...@@ -414,9 +414,19 @@ void OPENGL_GAL::BeginDrawing()
if( vboNeedsUpdate ) if( vboNeedsUpdate )
rebuildVbo(); rebuildVbo();
// Clear indices buffer // Number of vertices to be drawn
itemsToDraw.clear(); indicesSize = 0;
itemsToDrawSize = 0;
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId );
// Discard old buffer, so we can use it again
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW );
// Map the GPU memory, so we can store indices that are going to be drawn
indicesPtr = static_cast<GLuint*>( glMapBuffer( GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY ) );
if( indicesPtr == NULL )
{
wxLogError( wxT( "Could not map GPU memory" ) );
}
} }
...@@ -473,6 +483,11 @@ void OPENGL_GAL::EndDrawing() ...@@ -473,6 +483,11 @@ void OPENGL_GAL::EndDrawing()
// TODO Checking if we are using right VBOs, in other case do the binding. // TODO Checking if we are using right VBOs, in other case do the binding.
// Right now there is only one VBO, so there is no problem. // Right now there is only one VBO, so there is no problem.
if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) )
{
wxLogError( wxT( "Unmapping indices buffer failed" ) );
}
// Prepare buffers // Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY ); glEnableClientState( GL_COLOR_ARRAY );
...@@ -492,28 +507,7 @@ void OPENGL_GAL::EndDrawing() ...@@ -492,28 +507,7 @@ void OPENGL_GAL::EndDrawing()
VBO_ITEM::VertByteSize, (GLvoid*) VBO_ITEM::ShaderByteOffset ); VBO_ITEM::VertByteSize, (GLvoid*) VBO_ITEM::ShaderByteOffset );
} }
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId ); glDrawElements( GL_TRIANGLES, indicesSize, GL_UNSIGNED_INT, (GLvoid*) 0 );
GLuint* indicesPtr = static_cast<GLuint*>( glMapBuffer( GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY ) );
if( indicesPtr == NULL )
{
wxLogError( wxT( "Could not map GPU memory" ) );
}
// Copy indices of items that should be drawn to GPU memory
std::list<VBO_ITEM*>::const_iterator it, end;
for( it = itemsToDraw.begin(), end = itemsToDraw.end(); it != end; ++it )
{
memcpy( indicesPtr, (*it)->GetIndices(), (*it)->GetSize() * VBO_ITEM::IndByteSize );
indicesPtr += (*it)->GetSize() * VBO_ITEM::IndStride;
}
if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) )
{
wxLogError( wxT( "Unmapping indices buffer failed" ) );
}
glDrawElements( GL_TRIANGLES, itemsToDrawSize, GL_UNSIGNED_INT, (GLvoid*) 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 );
...@@ -1704,8 +1698,13 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber ) ...@@ -1704,8 +1698,13 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
void OPENGL_GAL::DrawGroup( int aGroupNumber ) void OPENGL_GAL::DrawGroup( int aGroupNumber )
{ {
itemsToDraw.push_back( vboItems[aGroupNumber] ); int size = vboItems[aGroupNumber]->GetSize();
itemsToDrawSize += vboItems[aGroupNumber]->GetSize(); int offset = vboItems[aGroupNumber]->GetOffset();
// Copy indices of items that should be drawn to GPU memory
for( int i = offset; i < offset + size; *indicesPtr++ = i++ );
indicesSize += size;
} }
......
...@@ -34,7 +34,6 @@ using namespace KiGfx; ...@@ -34,7 +34,6 @@ using namespace KiGfx;
VBO_ITEM::VBO_ITEM() : VBO_ITEM::VBO_ITEM() :
m_vertices( NULL ), m_vertices( NULL ),
m_indices( NULL ),
m_offset( 0 ), m_offset( 0 ),
m_size( 0 ), m_size( 0 ),
m_isDirty( true ), m_isDirty( true ),
...@@ -56,17 +55,10 @@ VBO_ITEM::~VBO_ITEM() ...@@ -56,17 +55,10 @@ VBO_ITEM::~VBO_ITEM()
std::list<VBO_VERTEX*>::const_iterator v_it, v_end; std::list<VBO_VERTEX*>::const_iterator v_it, v_end;
for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it ) for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it )
delete[] *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;
if( m_indices )
delete m_indices;
} }
...@@ -100,10 +92,6 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex ) ...@@ -100,10 +92,6 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex )
// Move to the next free space // Move to the next free space
m_vertPtr++; m_vertPtr++;
// Add the new index
*m_indPtr = m_offset + m_size;
m_indPtr++;
m_size++; m_size++;
m_isDirty = true; m_isDirty = true;
m_spaceLeft--; m_spaceLeft--;
...@@ -128,50 +116,6 @@ GLfloat* VBO_ITEM::GetVertices() ...@@ -128,50 +116,6 @@ GLfloat* VBO_ITEM::GetVertices()
} }
GLuint* VBO_ITEM::GetIndices()
{
if( m_isDirty )
prepareFinal();
return m_indices;
}
int VBO_ITEM::GetSize() const
{
return m_size;
}
void VBO_ITEM::SetOffset( int aOffset )
{
if( m_offset == aOffset )
return;
int delta = aOffset - m_offset;
// Change offset for all the stored indices
for( int i = 0; i < m_size; ++i )
{
m_indices += delta;
}
m_offset = aOffset;
}
int VBO_ITEM::GetOffset() const
{
return m_offset;
}
void VBO_ITEM::SetTransformMatrix( const glm::mat4* aMatrix )
{
m_transform = aMatrix;
}
void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
{ {
if( m_isDirty ) if( m_isDirty )
...@@ -191,31 +135,12 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) ...@@ -191,31 +135,12 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
} }
void VBO_ITEM::UseColor( const COLOR4D& aColor )
{
m_color[0] = aColor.r;
m_color[1] = aColor.g;
m_color[2] = aColor.b;
m_color[3] = aColor.a;
}
void VBO_ITEM::UseShader( const GLfloat* aShader )
{
memcpy( m_shader, aShader, ShaderByteSize );
}
void VBO_ITEM::useNewBlock() void VBO_ITEM::useNewBlock()
{ {
VBO_VERTEX* newVertBlock = new VBO_VERTEX[BLOCK_SIZE]; VBO_VERTEX* newVertBlock = new VBO_VERTEX[BLOCK_SIZE];
GLuint* newIndBlock = new GLuint[BLOCK_SIZE];
m_vertPtr = newVertBlock; m_vertPtr = newVertBlock;
m_indPtr = newIndBlock;
m_vertBlocks.push_back( newVertBlock ); m_vertBlocks.push_back( newVertBlock );
m_indBlocks.push_back( newIndBlock );
m_spaceLeft = BLOCK_SIZE; m_spaceLeft = BLOCK_SIZE;
} }
...@@ -243,25 +168,5 @@ void VBO_ITEM::prepareFinal() ...@@ -243,25 +168,5 @@ void VBO_ITEM::prepareFinal()
// In the last block we need to copy only used vertices // In the last block we need to copy only used vertices
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertByteSize ); memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertByteSize );
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 * IndByteSize );
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 ) * IndByteSize );
m_isDirty = false; m_isDirty = false;
} }
...@@ -353,9 +353,8 @@ private: ...@@ -353,9 +353,8 @@ private:
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt
glm::mat4 transform; ///< Current transformation matrix glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices
std::list<VBO_ITEM*> itemsToDraw; ///< Stores items that are going to be int indicesSize; ///< Number of indices to be drawn
///< drawn in the current frame GLuint* indicesPtr; ///< Pointer to mapped GPU memory
int itemsToDrawSize; ///< Number of indices to be drawn
double curvePoints[12]; ///< Coefficients for curves double curvePoints[12]; ///< Coefficients for curves
// FIXME to be removed: // FIXME to be removed:
......
...@@ -45,8 +45,7 @@ typedef struct VBO_VERTEX ...@@ -45,8 +45,7 @@ typedef struct VBO_VERTEX
GLfloat x, y, z; // Coordinates GLfloat x, y, z; // Coordinates
GLfloat r, g, b, a; // Color GLfloat r, g, b, a; // Color
GLfloat shader[4]; // Shader type & params GLfloat shader[4]; // Shader type & params
} VBO_VERTEX_DATA; } VBO_VERTEX;
class VBO_ITEM class VBO_ITEM
{ {
...@@ -81,33 +80,36 @@ public: ...@@ -81,33 +80,36 @@ public:
*/ */
GLfloat* GetVertices(); GLfloat* GetVertices();
/**
* Function GetIndices()
* Returns a pointer to the array containing all indices of vertices.
* @return Pointer to indices.
*/
GLuint* GetIndices();
/** /**
* Function GetSize() * Function GetSize()
* Returns information about number of vertices stored. * Returns information about number of vertices stored.
* @param Amount of vertices. * @param Amount of vertices.
*/ */
int GetSize() const; inline int GetSize() const
{
return m_size;
}
/** /**
* Function SetOffset() * Function SetOffset()
* Sets data offset in the VBO. * Sets data offset in the VBO.
* @param aOffset is the offset expressed as a number of vertices. * @param aOffset is the offset expressed as a number of vertices.
*/ */
void SetOffset( int aOffset ); void SetOffset( int aOffset )
{
m_offset = aOffset;
}
/** /**
* Function GetOffset() * Function GetOffset()
* Returns data offset in the VBO. * Returns data offset in the VBO.
* @return Data offset expressed as a number of vertices. * @return Data offset expressed as a number of vertices.
*/ */
int GetOffset() const; inline int GetOffset() const
{
return m_offset;
}
/** /**
* Function SetTransformMatrix() * Function SetTransformMatrix()
...@@ -116,7 +118,10 @@ public: ...@@ -116,7 +118,10 @@ public:
* @param aMatrix is the new transform matrix or NULL if you do not want to use transformation * @param aMatrix is the new transform matrix or NULL if you do not want to use transformation
* matrix. * matrix.
*/ */
void SetTransformMatrix( const glm::mat4* aMatrix ); void SetTransformMatrix( const glm::mat4* aMatrix )
{
m_transform = aMatrix;
}
/** /**
* Function ChangeColor() * Function ChangeColor()
...@@ -130,18 +135,37 @@ public: ...@@ -130,18 +135,37 @@ public:
* Sets color used for all added vertices. * Sets color used for all added vertices.
* @param aColor is the color used for added vertices. * @param aColor is the color used for added vertices.
*/ */
void UseColor( const COLOR4D& aColor ); void UseColor( const COLOR4D& aColor )
{
m_color[0] = aColor.r;
m_color[1] = aColor.g;
m_color[2] = aColor.b;
m_color[3] = aColor.a;
}
/** /**
* Function UseShader() * Function UseShader()
* Sets shader and its parameters used for all added vertices. * Sets shader and its parameters used for all added vertices.
* @param aShader is the array that contains shader number followed by its parameters. * @param aShader is the array that contains shader number followed by its parameters.
*/ */
void UseShader( const GLfloat* aShader ); inline void UseShader( const GLfloat* aShader )
{
for( int i = 0; i < ShaderStride; ++i )
{
m_shader[i] = aShader[i];
}
}
inline void FreeVerticesData()
{
if( m_vertices && !m_isDirty )
{
delete[] m_vertices;
m_vertices = NULL;
}
}
///< Functions for getting VBO ids.
//void SetVbo( int aVboId );
//int GetVbo() const;
///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX). ///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX).
static const int VertByteSize = sizeof(VBO_VERTEX); static const int VertByteSize = sizeof(VBO_VERTEX);
...@@ -164,26 +188,22 @@ public: ...@@ -164,26 +188,22 @@ public:
static const int ShaderByteSize = sizeof(VBO_VERTEX().shader); static const int ShaderByteSize = sizeof(VBO_VERTEX().shader);
static const int ShaderStride = ShaderByteSize / sizeof(GLfloat); static const int ShaderStride = ShaderByteSize / sizeof(GLfloat);
static const int IndStride = 1; static const int IndByteSize = sizeof(GLuint);
static const int IndByteSize = IndStride * sizeof(GLuint);
private: private:
///< Contains vertices coordinates and colors. ///< Contains vertices coordinates and colors.
///< Packed by 7 floats for each vertex: {X, Y, Z, R, G, B, A} ///< Packed by 7 floats for each vertex: {X, Y, Z, R, G, B, A}
GLfloat* m_vertices; GLfloat* m_vertices;
///< Indices of vertices
GLuint* m_indices;
///< Lists of data blocks storing vertices ///< Lists of data blocks storing vertices
std::list<VBO_VERTEX*> m_vertBlocks; std::list<VBO_VERTEX*> m_vertBlocks;
std::list<GLuint*> m_indBlocks;
///< Pointers to current blocks that should be used for storing data ///< Pointers to current blocks that should be used for storing data
VBO_VERTEX* m_vertPtr; VBO_VERTEX* m_vertPtr;
GLuint* m_indPtr;
///< How many vertices can be stored in the current buffer ///< How many vertices can be stored in the current buffer
int m_spaceLeft; int m_spaceLeft;
///< Number of vertices & indices stored in a single block ///< Number of vertices stored in a single block
static const int BLOCK_SIZE = 256; static const int BLOCK_SIZE = 256;
///< Creates a new block for storing vertices data ///< Creates a new block for storing vertices data
void useNewBlock(); void useNewBlock();
......
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