Commit eb041ee2 authored by Maciej Suminski's avatar Maciej Suminski

Removed most of deprecated OpenGL calls. Items used to be drawn in immediate...

Removed most of deprecated OpenGL calls. Items used to be drawn in immediate mode now are drawn using vertex arrays.
parent 408fb4f1
...@@ -76,9 +76,10 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -323,7 +321,6 @@ void OPENGL_GAL::initGlew()
} }
initVertexBufferObjects(); initVertexBufferObjects();
computeCircleDisplayLists();
isGlewInitialized = true; isGlewInitialized = true;
} }
...@@ -425,9 +422,9 @@ void OPENGL_GAL::BeginDrawing() ...@@ -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() ...@@ -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 ) ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ...@@ -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 ...@@ -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 // 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 ); currentItem->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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ) ...@@ -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 ) ...@@ -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() ...@@ -1393,34 +1344,20 @@ void OPENGL_GAL::Flush()
void OPENGL_GAL::Save() void OPENGL_GAL::Save()
{ {
if( isGrouping )
{
transformStack.push( transform ); transformStack.push( transform );
vboContainer.SetTransformMatrix( &transform ); currentContainer->SetTransformMatrix( &transform );
}
else
{
glPushMatrix();
}
} }
void OPENGL_GAL::Restore() void OPENGL_GAL::Restore()
{ {
if( isGrouping )
{
transform = transformStack.top(); transform = transformStack.top();
transformStack.pop(); transformStack.pop();
if( transformStack.empty() ) if( transformStack.empty() )
{ {
// Disable transforming, as the selected matrix is identity // Disable transforming, as the selected matrix is identity
vboContainer.SetTransformMatrix( NULL ); currentContainer->SetTransformMatrix( NULL );
}
}
else
{
glPopMatrix();
} }
} }
...@@ -1433,9 +1370,10 @@ int OPENGL_GAL::BeginGroup() ...@@ -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() ...@@ -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() ...@@ -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 ) ...@@ -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) ...@@ -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 ) ...@@ -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 ...@@ -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();
} }
......
...@@ -38,7 +38,7 @@ ...@@ -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 ...@@ -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;
......
...@@ -337,21 +337,22 @@ private: ...@@ -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: ...@@ -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: ...@@ -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.
...@@ -554,44 +531,26 @@ private: ...@@ -554,44 +531,26 @@ private:
* @param aZ is Z coordinate. * @param aZ is Z coordinate.
*/ */
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 // New vertex coordinates for VBO
const VBO_VERTEX vertex = { aX, aY, aZ }; const VBO_VERTEX vertex = { aX, aY, aZ };
currentGroup->PushVertex( &vertex ); currentItem->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.
* @param aZ is translation in Z axis direction. * @param aZ is translation in Z axis direction.
*/ */
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: ...@@ -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: ...@@ -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 );
} }
} }
}; };
......
...@@ -46,7 +46,7 @@ typedef struct VBO_VERTEX VBO_VERTEX; ...@@ -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: ...@@ -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: ...@@ -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
......
...@@ -126,7 +126,7 @@ public: ...@@ -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);
......
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