Removed most of deprecated OpenGL calls. Items used to be drawn in immediate mode now are drawn using vertex arrays.

This commit is contained in:
Maciej Suminski 2013-07-05 14:01:33 +02:00
parent 408fb4f159
commit eb041ee2d3
5 changed files with 126 additions and 267 deletions

View File

@ -76,9 +76,10 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isVboInitialized = false;
vboNeedsUpdate = false;
currentGroup = NULL;
currentItem = NULL;
groupCounter = 0;
transform = glm::mat4( 1.0f ); // Identity matrix
nonCachedItem = NULL;
SetSize( parentSize );
@ -120,10 +121,7 @@ OPENGL_GAL::~OPENGL_GAL()
{
glFlush();
if( glIsList( displayListSemiCircle ) )
glDeleteLists( displayListSemiCircle, 1 );
if( glIsList( displayListCircle ) )
glDeleteLists( displayListCircle, 1 );
delete nonCachedItem;
// Delete the buffers
if( isFrameBufferInitialized )
@ -241,8 +239,8 @@ void OPENGL_GAL::initFrameBuffers()
void OPENGL_GAL::initVertexBufferObjects()
{
// Generate buffers for vertices and indices
glGenBuffers( 1, &vboVertices );
glGenBuffers( 1, &vboIndices );
glGenBuffers( 1, &cachedVerts );
glGenBuffers( 1, &cachedInds );
isVboInitialized = true;
}
@ -253,8 +251,8 @@ void OPENGL_GAL::deleteVertexBufferObjects()
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glDeleteBuffers( 1, &vboVertices );
glDeleteBuffers( 1, &vboIndices );
glDeleteBuffers( 1, &cachedVerts );
glDeleteBuffers( 1, &cachedInds );
isVboInitialized = false;
}
@ -323,7 +321,6 @@ void OPENGL_GAL::initGlew()
}
initVertexBufferObjects();
computeCircleDisplayLists();
isGlewInitialized = true;
}
@ -425,9 +422,9 @@ void OPENGL_GAL::BeginDrawing()
// Number of vertices to be drawn
indicesSize = 0;
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds );
// Discard old buffer, so we can use it again
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize,
glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize,
NULL, GL_STREAM_DRAW );
// Map the GPU memory, so we can store indices that are going to be drawn
@ -436,6 +433,14 @@ void OPENGL_GAL::BeginDrawing()
{
wxLogError( wxT( "Could not map GPU memory" ) );
}
// Prepare buffer for non-cached items
delete nonCachedItem;
nonCachedItem = new VBO_ITEM( &nonCachedVbo );
// By default we draw non-cached objects, it changes on BeginGroup()/EndGroup()
currentContainer = &nonCachedVbo;
currentItem = nonCachedItem;
}
@ -487,9 +492,6 @@ void OPENGL_GAL::blitMainTexture( bool aIsClearFrameBuffer )
void OPENGL_GAL::EndDrawing()
{
// 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.
if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) )
{
wxLogError( wxT( "Unmapping indices buffer failed" ) );
@ -500,7 +502,7 @@ void OPENGL_GAL::EndDrawing()
glEnableClientState( GL_COLOR_ARRAY );
// Bind vertices data buffers
glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
glBindBuffer( GL_ARRAY_BUFFER, cachedVerts );
glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, 0 );
glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize,
(GLvoid*) VBO_ITEM::ColorByteOffset );
@ -518,6 +520,20 @@ void OPENGL_GAL::EndDrawing()
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
// Draw non-cached items
GLfloat* vertices = (GLfloat*)( nonCachedVbo.GetAllVertices() );
GLubyte* colors = (GLubyte*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ColorOffset;
GLfloat* shaders = (GLfloat*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ShaderOffset;
glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, vertices );
glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize, colors );
if( isUseShader )
{
glVertexAttribPointer( shaderAttrib, VBO_ITEM::ShaderStride, GL_FLOAT, GL_FALSE,
VBO_ITEM::VertByteSize, shaders );
}
glDrawArrays( GL_TRIANGLES, nonCachedItem->GetOffset(), nonCachedItem->GetSize() );
// Deactivate vertex array
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
@ -543,17 +559,17 @@ void OPENGL_GAL::rebuildVbo()
prof_start( &totalTime, false );
#endif /* __WXDEBUG__ */
GLfloat* data = (GLfloat*) vboContainer.GetAllVertices();
GLfloat* data = (GLfloat*) cachedVbo.GetAllVertices();
// Upload vertices coordinates and shader types to GPU memory
glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
glBufferData( GL_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::VertByteSize,
glBindBuffer( GL_ARRAY_BUFFER, cachedVerts );
glBufferData( GL_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::VertByteSize,
data, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
// Allocate the biggest possible buffer for indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize,
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize,
NULL, GL_STREAM_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
@ -563,7 +579,7 @@ void OPENGL_GAL::rebuildVbo()
prof_end( &totalTime );
wxLogDebug( wxT( "Rebuilding VBO::%d vertices / %.1f ms" ),
vboContainer.GetSize(), (double) totalTime.value / 1000.0 );
cachedVbo.GetSize(), (double) totalTime.value / 1000.0 );
#endif /* __WXDEBUG__ */
}
@ -577,27 +593,16 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2
if( lineLength <= 0.0 )
return;
if( lineWidth * worldScale < 1.0002 && !isGrouping && !isUseShader )
{
// Limit the width of the line to a minimum of one pixel
// this looks best without anti-aliasing
scale = 0.5001 / worldScale / lineLength;
}
VECTOR2D perpendicularVector( -startEndVector.y * scale, startEndVector.x * scale );
begin( GL_TRIANGLES );
if( isUseShader && isGrouping )
if( isUseShader )
{
glm::vec4 vector( perpendicularVector.x, perpendicularVector.y, 0.0, 0.0 );
// If transform stack is not empty, then it means that
// there is a transformation matrix that has to be applied
if( !transformStack.empty() )
{
vector = transform * vector;
}
// Line width is maintained by the vertex shader
setShader( SHADER_LINE, vector.x, vector.y, lineWidth );
@ -634,8 +639,6 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2
vertex3( v3.x, v3.y, layerDepth );
vertex3( v2.x, v2.y, layerDepth );
}
end();
}
@ -760,7 +763,6 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
setShader( SHADER_NONE );
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
begin( GL_TRIANGLES );
vertex3( aStartPoint.x, aStartPoint.y, layerDepth );
vertex3( diagonalPointA.x, diagonalPointA.y, layerDepth );
vertex3( aEndPoint.x, aEndPoint.y, layerDepth );
@ -768,14 +770,13 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
vertex3( aStartPoint.x, aStartPoint.y, layerDepth );
vertex3( aEndPoint.x, aEndPoint.y, layerDepth );
vertex3( diagonalPointB.x, diagonalPointB.y, layerDepth );
end();
}
}
void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
{
if( isUseShader && isGrouping )
if( isUseShader )
{
if( isFillEnabled )
{
@ -856,8 +857,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
translate3( aCenterPoint.x, aCenterPoint.y, 0.0 );
Scale( VECTOR2D( aRadius, aRadius ) );
begin( GL_TRIANGLES );
for( int i = 0; i < 3 * CIRCLE_POINTS; ++i )
{
// verticesCircle contains precomputed circle points interleaved with vertex
@ -887,8 +886,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth );
}
end();
Restore();
}
}
@ -902,14 +899,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
translate3( aCenterPoint.x, aCenterPoint.y, layerDepth );
Scale( VECTOR2D( aRadius, aRadius ) );
if( isGrouping )
{
currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 );
}
else
{
glCallList( displayListCircle );
}
currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 );
Restore();
}
@ -934,7 +924,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
{
if( isUseShader && isGrouping )
if( isUseShader )
{
Save();
Translate( aCenterPoint );
@ -966,15 +956,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad
Scale( VECTOR2D( aRadius, aRadius ) );
Rotate( aAngle );
if( isGrouping )
{
// It is enough just to push just a half of the circle vertices to make a semicircle
currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 );
}
else
{
glCallList( displayListSemiCircle );
}
// It is enough just to push just a half of the circle vertices to make a semicircle
currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 );
Restore();
}
@ -983,7 +966,7 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad
void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
{
if( isUseShader && isGrouping )
if( isUseShader )
{
Save();
Translate( aCenterPoint );
@ -1028,8 +1011,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
VBO_VERTEX* circle = verticesCircle.GetVertices();
int next;
begin( GL_TRIANGLES );
for( int i = 0; i < ( 3 * CIRCLE_POINTS ) / 2; ++i )
{
// verticesCircle contains precomputed circle points interleaved with vertex
@ -1059,8 +1040,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, 0.0 );
}
end();
Restore();
}
}
@ -1123,8 +1102,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
double alphaIncrement = 2 * M_PI / CIRCLE_POINTS;
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
begin( GL_TRIANGLES );
for( double alpha = aStartAngle; alpha < aEndAngle; )
{
double v0[] = { cos( alpha ) * innerScale, sin( alpha ) * innerScale };
@ -1147,8 +1124,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
vertex3( v2[0], v2[1], 0.0 );
}
end();
// Draw line caps
drawFilledSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI );
drawFilledSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle );
@ -1161,8 +1136,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
double alpha;
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
begin( GL_TRIANGLES );
for( alpha = aStartAngle; ( alpha + alphaIncrement ) < aEndAngle; )
{
vertex3( middlePoint.x, middlePoint.y, 0.0 );
@ -1174,7 +1147,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
vertex3( middlePoint.x, middlePoint.y, 0.0 );
vertex3( cos( alpha ), sin( alpha ), 0.0 );
vertex3( endPoint.x, endPoint.y, 0.0 );
end();
}
Restore();
@ -1228,7 +1200,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
glShadeModel( GL_FLAT );
TessParams params = { currentGroup, tessIntersects };
TessParams params = { currentItem, tessIntersects };
gluTessBeginPolygon( tesselator, &params );
gluTessBeginContour( tesselator );
@ -1348,40 +1320,19 @@ void OPENGL_GAL::Transform( MATRIX3x3D aTransformation )
void OPENGL_GAL::Rotate( double aAngle )
{
if( isGrouping )
{
transform = glm::rotate( transform, (float) aAngle, glm::vec3( 0, 0, 1 ) );
}
else
{
glRotated( aAngle * ( 360 / ( 2 * M_PI ) ), 0, 0, 1 );
}
transform = glm::rotate( transform, (float) aAngle, glm::vec3( 0, 0, 1 ) );
}
void OPENGL_GAL::Translate( const VECTOR2D& aVector )
{
if( isGrouping )
{
transform = glm::translate( transform, glm::vec3( aVector.x, aVector.y, 0 ) );
}
else
{
glTranslated( aVector.x, aVector.y, 0 );
}
transform = glm::translate( transform, glm::vec3( aVector.x, aVector.y, 0 ) );
}
void OPENGL_GAL::Scale( const VECTOR2D& aScale )
{
if( isGrouping )
{
transform = glm::scale( transform, glm::vec3( aScale.x, aScale.y, 0 ) );
}
else
{
glScaled( aScale.x, aScale.y, 0 );
}
transform = glm::scale( transform, glm::vec3( aScale.x, aScale.y, 0 ) );
}
@ -1393,34 +1344,20 @@ void OPENGL_GAL::Flush()
void OPENGL_GAL::Save()
{
if( isGrouping )
{
transformStack.push( transform );
vboContainer.SetTransformMatrix( &transform );
}
else
{
glPushMatrix();
}
transformStack.push( transform );
currentContainer->SetTransformMatrix( &transform );
}
void OPENGL_GAL::Restore()
{
if( isGrouping )
{
transform = transformStack.top();
transformStack.pop();
transform = transformStack.top();
transformStack.pop();
if( transformStack.empty() )
{
// Disable transforming, as the selected matrix is identity
vboContainer.SetTransformMatrix( NULL );
}
}
else
if( transformStack.empty() )
{
glPopMatrix();
// Disable transforming, as the selected matrix is identity
currentContainer->SetTransformMatrix( NULL );
}
}
@ -1433,9 +1370,10 @@ int OPENGL_GAL::BeginGroup()
vboNeedsUpdate = true;
// Save the pointer for caching the current item
currentGroup = new VBO_ITEM( &vboContainer );
currentItem = new VBO_ITEM( &cachedVbo );
currentContainer = &cachedVbo;
int groupNumber = getGroupNumber();
groups.insert( std::make_pair( groupNumber, currentGroup ) );
groups.insert( std::make_pair( groupNumber, currentItem ) );
return groupNumber;
}
@ -1443,7 +1381,9 @@ int OPENGL_GAL::BeginGroup()
void OPENGL_GAL::EndGroup()
{
currentGroup->Finish();
currentItem->Finish();
currentItem = nonCachedItem;
currentContainer = &nonCachedVbo;
isGrouping = false;
}
@ -1523,42 +1463,6 @@ void OPENGL_GAL::computeCircleVbo()
}
void OPENGL_GAL::computeCircleDisplayLists()
{
// Circle display list
displayListCircle = glGenLists( 1 );
glNewList( displayListCircle, GL_COMPILE );
glBegin( GL_TRIANGLES );
for( int i = 0; i < CIRCLE_POINTS; ++i )
{
glVertex2d( 0.0, 0.0 );
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * i ),
sin( 2.0 * M_PI / CIRCLE_POINTS * i ) );
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ),
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ) );
}
glEnd();
glEndList();
// Semicircle display list
displayListSemiCircle = glGenLists( 1 );
glNewList( displayListSemiCircle, GL_COMPILE );
glBegin( GL_TRIANGLES );
for( int i = 0; i < CIRCLE_POINTS / 2; ++i )
{
glVertex2d( 0.0, 0.0 );
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * i ),
sin( 2.0 * M_PI / CIRCLE_POINTS * i ) );
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ),
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ) );
}
glEnd();
glEndList();
}
void OPENGL_GAL::ComputeWorldScreenMatrix()
{
ComputeWorldScale();
@ -1603,10 +1507,6 @@ void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
VBO_VERTEX newVertex = { vertex[0], vertex[1], vertex[2] };
vboItem->PushVertex( &newVertex );
}
else
{
glVertex3dv( vertex );
}
}
@ -1633,20 +1533,6 @@ void CALLBACK EdgeCallback(void)
}
void CALLBACK BeginCallback( GLenum aWhich, void* aData )
{
if( !aData )
glBegin( aWhich );
}
void CALLBACK EndCallback( void* aData )
{
if( !aData )
glEnd();
}
void CALLBACK ErrorCallback( GLenum aErrorCode )
{
const GLubyte* estring;
@ -1661,8 +1547,6 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator )
gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback );
gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback );
gluTessCallback( aTesselator, GLU_TESS_EDGE_FLAG, ( void (CALLBACK*)() )EdgeCallback );
gluTessCallback( aTesselator, GLU_TESS_BEGIN_DATA, ( void (CALLBACK*)() )BeginCallback );
gluTessCallback( aTesselator, GLU_TESS_END_DATA, ( void (CALLBACK*)() )EndCallback );
gluTessCallback( aTesselator, GLU_TESS_ERROR_DATA, ( void (CALLBACK*)() )ErrorCallback );
}
@ -1771,19 +1655,19 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
VECTOR2D point4 = aEndPoint - perpendicularVector;
// Set color
glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a );
color4( gridColor.r, gridColor.g, gridColor.b, gridColor.a );
setShader( SHADER_NONE );
// Draw the quad for the grid line
glBegin( GL_TRIANGLES );
double gridDepth = depthRange.y * 0.75;
glVertex3d( point1.x, point1.y, gridDepth );
glVertex3d( point2.x, point2.y, gridDepth );
glVertex3d( point4.x, point4.y, gridDepth );
vertex3( point1.x, point1.y, gridDepth );
vertex3( point2.x, point2.y, gridDepth );
vertex3( point4.x, point4.y, gridDepth );
glVertex3d( point1.x, point1.y, gridDepth );
glVertex3d( point4.x, point4.y, gridDepth );
glVertex3d( point3.x, point3.y, gridDepth );
glEnd();
vertex3( point1.x, point1.y, gridDepth );
vertex3( point4.x, point4.y, gridDepth );
vertex3( point3.x, point3.y, gridDepth );
}

View File

@ -38,7 +38,7 @@
using namespace KiGfx;
VBO_CONTAINER::VBO_CONTAINER( int aSize ) :
VBO_CONTAINER::VBO_CONTAINER( unsigned int aSize ) :
m_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL ),
m_failed( false )
{
@ -202,6 +202,30 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned
}
void VBO_CONTAINER::Clear()
{
// Change size to the default one
m_vertices = static_cast<VBO_VERTEX*>( realloc( m_vertices,
defaultInitSize * sizeof( VBO_VERTEX ) ) );
// Reset state variables
m_freeSpace = defaultInitSize;
m_currentSize = defaultInitSize;
itemStarted = false;
m_transform = NULL;
m_failed = false;
// By default no shader is used
m_shader[0] = 0;
m_freeChunks.clear();
m_reservedChunks.clear();
// In the beginning there is only free space
m_freeChunks.insert( Chunk( m_freeSpace, 0 ) );
}
VBO_VERTEX* VBO_CONTAINER::GetAllVertices() const
{
return m_vertices;

View File

@ -337,21 +337,22 @@ private:
wxEvtHandler* mouseListener;
wxEvtHandler* paintListener;
// VBO buffers & display lists (used in immediate mode)
// VBO buffered vertices for faster circle & semicircle drawing
VBO_CONTAINER precomputedContainer; ///< Container for storing display lists
VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices
GLuint displayListCircle; ///< Circle display list
GLuint displayListSemiCircle; ///< Semi circle display list
// Vertex buffer objects related fields
typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap;
GroupsMap groups; ///< Stores informations about VBO objects (groups)
unsigned int groupCounter; ///< Counter used for generating keys for groups
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping)
VBO_CONTAINER vboContainer; ///< Container for storing VBO_ITEMs
GLuint vboVertices; ///< Currently used vertices VBO handle
GLuint vboIndices; ///< Currently used indices VBO handle
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
@ -432,10 +433,6 @@ private:
/// Compute the points of an unit circle & semicircle and store them in VBO.
void computeCircleVbo();
/// Compute the points of an unit circle & semicircle and store them in display lists
/// for drawing in immediate mode.
void computeCircleDisplayLists();
// Event handling
/**
* @brief This is the window creation event handler.
@ -527,26 +524,6 @@ private:
*/
unsigned int getGroupNumber();
///< OpenGL replacement functions (that are working both in immediate and VBO modes)
/**
* @brief Starts drawing in immediate mode or does nothing if an item's caching has started.
* @param aMode specifies the primitive or primitives that will be created.
*/
inline void begin( GLenum aMode )
{
if( !isGrouping )
glBegin( aMode );
}
/**
* @brief Ends drawing in immediate mode or does nothing if an item's caching has started.
*/
inline void end()
{
if( !isGrouping )
glEnd();
}
/**
* @brief Adds vertex to the current item or draws it in immediate mode.
* @param aX is X coordinate.
@ -555,22 +532,13 @@ private:
*/
inline void vertex3( double aX, double aY, double aZ )
{
if( isGrouping )
{
// New vertex coordinates for VBO
const VBO_VERTEX vertex = { aX, aY, aZ };
currentGroup->PushVertex( &vertex );
}
else
{
glVertex3d( aX, aY, aZ );
}
// New vertex coordinates for VBO
const VBO_VERTEX vertex = { aX, aY, aZ };
currentItem->PushVertex( &vertex );
}
/**
* @brief Function that replaces glTranslate and behaves according to isGrouping variable.
* In case isGrouping==false, it is simply glTranslate, in other case it
* modifies transformation matrix.
* @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.
@ -578,20 +546,11 @@ private:
*/
inline void translate3( double aX, double aY, double aZ )
{
if( isGrouping )
{
transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
}
else
{
glTranslated( aX, aY, aZ );
}
transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
}
/**
* @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.
* @brief Function that replaces glColor. It modifies color used by current VBO_ITEM.
*
* @param aR is red component.
* @param aG is green component.
@ -600,33 +559,17 @@ private:
*/
inline void color4( double aRed, double aGreen, double aBlue, double aAlpha )
{
if( isGrouping )
{
vboContainer.UseColor( aRed, aGreen, aBlue, aAlpha );
}
else
{
glColor4d( aRed, aGreen, aBlue, aAlpha );
}
currentContainer->UseColor( aRed, aGreen, aBlue, 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.
* @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 )
{
if( isGrouping )
{
vboContainer.UseColor( aColor );
}
else
{
glColor4d( aColor.r, aColor.g, aColor.b, aColor.a);
}
currentContainer->UseColor( aColor );
}
/**
@ -639,11 +582,10 @@ private:
inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f,
GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f )
{
if( isUseShader && isGrouping )
if( isUseShader )
{
const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 };
vboContainer.UseShader( shader );
currentContainer->UseShader( shader );
}
}
};

View File

@ -46,7 +46,7 @@ typedef struct VBO_VERTEX VBO_VERTEX;
class VBO_CONTAINER
{
public:
VBO_CONTAINER( int aSize = 1048576 );
VBO_CONTAINER( unsigned int aSize = defaultInitSize );
~VBO_CONTAINER();
///< Maps size of free memory chunks to their offsets
@ -99,6 +99,12 @@ public:
}
}
/**
* Function Clear()
* Removes all the data stored in the container.
*/
void Clear();
/**
* Function GetAllVertices()
* Returns all vertices stored in the container. It is especially useful for transferring
@ -344,6 +350,9 @@ private:
return power;
}
///< Default initial size of a container (expressed in vertices)
static const unsigned int defaultInitSize = 1048576;
};
} // namespace KiGfx

View File

@ -126,7 +126,7 @@ public:
///< Informs the container that there will be no more vertices for the current VBO_ITEM
void Finish();
///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX).
///< 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);