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

View File

@ -38,7 +38,7 @@
using namespace KiGfx; 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_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL ),
m_failed( false ) 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 VBO_VERTEX* VBO_CONTAINER::GetAllVertices() const
{ {
return m_vertices; return m_vertices;

View File

@ -337,21 +337,22 @@ private:
wxEvtHandler* mouseListener; wxEvtHandler* mouseListener;
wxEvtHandler* paintListener; 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_CONTAINER precomputedContainer; ///< Container for storing display lists
VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices
GLuint displayListCircle; ///< Circle display list
GLuint displayListSemiCircle; ///< Semi circle display list
// Vertex buffer objects related fields // Vertex buffer objects related fields
typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap; typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap;
GroupsMap groups; ///< Stores informations about VBO objects (groups) GroupsMap groups; ///< Stores informations about VBO objects (groups)
unsigned int groupCounter; ///< Counter used for generating keys for groups unsigned int groupCounter; ///< Counter used for generating keys for groups
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping) VBO_ITEM* currentItem; ///< Currently used VBO_ITEM (for grouping)
VBO_CONTAINER vboContainer; ///< Container for storing VBO_ITEMs VBO_CONTAINER* currentContainer; ///< Currently used VBO_CONTAINER (for storing VBO_ITEMs)
GLuint vboVertices; ///< Currently used vertices VBO handle VBO_CONTAINER cachedVbo; ///< Container for storing VBO_ITEMs
GLuint vboIndices; ///< Currently used indices VBO handle GLuint cachedVerts; ///< Currently used vertices VBO handle
GLuint cachedInds; ///< Currently used indices VBO handle
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt 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 glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices 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. /// Compute the points of an unit circle & semicircle and store them in VBO.
void computeCircleVbo(); 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 // Event handling
/** /**
* @brief This is the window creation event handler. * @brief This is the window creation event handler.
@ -527,26 +524,6 @@ private:
*/ */
unsigned int getGroupNumber(); 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. * @brief Adds vertex to the current item or draws it in immediate mode.
* @param aX is X coordinate. * @param aX is X coordinate.
@ -555,22 +532,13 @@ private:
*/ */
inline void vertex3( double aX, double aY, double aZ ) inline void vertex3( double aX, double aY, double aZ )
{ {
if( isGrouping ) // New vertex coordinates for VBO
{ const VBO_VERTEX vertex = { aX, aY, aZ };
// New vertex coordinates for VBO currentItem->PushVertex( &vertex );
const VBO_VERTEX vertex = { aX, aY, aZ };
currentGroup->PushVertex( &vertex );
}
else
{
glVertex3d( aX, aY, aZ );
}
} }
/** /**
* @brief Function that replaces glTranslate and behaves according to isGrouping variable. * @brief Function that replaces glTranslate. It modifies transformation matrix.
* In case isGrouping==false, it is simply glTranslate, in other case it
* modifies transformation matrix.
* *
* @param aX is translation in X axis direction. * @param aX is translation in X axis direction.
* @param aY is translation in Y axis direction. * @param aY is translation in Y axis direction.
@ -578,20 +546,11 @@ private:
*/ */
inline void translate3( double aX, double aY, double aZ ) inline void translate3( double aX, double aY, double aZ )
{ {
if( isGrouping ) transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
{
transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
}
else
{
glTranslated( aX, aY, aZ );
}
} }
/** /**
* @brief Function that replaces glColor and behaves according to isGrouping variable. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM.
* In case isGrouping==false, it is simply glColor, in other case it
* modifies color used by current VBO_ITEM.
* *
* @param aR is red component. * @param aR is red component.
* @param aG is green component. * @param aG is green component.
@ -600,33 +559,17 @@ private:
*/ */
inline void color4( double aRed, double aGreen, double aBlue, double aAlpha ) inline void color4( double aRed, double aGreen, double aBlue, double aAlpha )
{ {
if( isGrouping ) currentContainer->UseColor( aRed, aGreen, aBlue, aAlpha );
{
vboContainer.UseColor( aRed, aGreen, aBlue, aAlpha );
}
else
{
glColor4d( aRed, aGreen, aBlue, aAlpha );
}
} }
/** /**
* @brief Function that replaces glColor and behaves according to isGrouping variable. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM.
* 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. * @param aColor is the new color.
*/ */
inline void color4( const COLOR4D& aColor ) inline void color4( const COLOR4D& aColor )
{ {
if( isGrouping ) currentContainer->UseColor( aColor );
{
vboContainer.UseColor( aColor );
}
else
{
glColor4d( aColor.r, aColor.g, aColor.b, aColor.a);
}
} }
/** /**
@ -639,11 +582,10 @@ private:
inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f, inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f,
GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f ) GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f )
{ {
if( isUseShader && isGrouping ) if( isUseShader )
{ {
const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 }; const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 };
currentContainer->UseShader( shader );
vboContainer.UseShader( shader );
} }
} }
}; };

View File

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

View File

@ -126,7 +126,7 @@ public:
///< Informs the container that there will be no more vertices for the current VBO_ITEM ///< Informs the container that there will be no more vertices for the current VBO_ITEM
void Finish(); 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 VertByteSize = sizeof(VBO_VERTEX);
static const unsigned int VertStride = VertByteSize / sizeof(GLfloat); static const unsigned int VertStride = VertByteSize / sizeof(GLfloat);