Introducing shaders.
Shader's parameters are stored in VBO_ITEM. Changed VBO_ITEM data structure. Added UseShader() function for selecting shader for a given VBO_ITEM. Added one main vertex & fragment shader program to be used for with all kinds of items (type of shader is selected using attributes that are stored in VBO). Currently available shaders are: at-least-1px-width line, filled circle and stroked circle. Removed unnecessary param (aDepthOffset) from a few functions (OPENGL_GAL::drawSemiCircle(), OPENGL_GAL::drawLineCap()). Removed function OPENGL_GAL::DrawRoundedSegment(). Changed some asserts to debug info or error log.
This commit is contained in:
parent
ad5d10a8ba
commit
28511cf4fe
|
@ -58,9 +58,9 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
|||
wxStandardPaths paths;
|
||||
wxFileName executableFile( paths.GetExecutablePath() );
|
||||
m_galShaderPath = std::string( ( executableFile.GetPath() +
|
||||
wxT( "/../../common/gal/opengl/shader/" ) ).mb_str() );
|
||||
wxT( "/../../common/gal/opengl/" ) ).mb_str() );
|
||||
|
||||
SwitchBackend( aGalType, false );
|
||||
SwitchBackend( aGalType, true );
|
||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||
|
||||
// Initial display settings
|
||||
|
|
|
@ -26,8 +26,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <gal/opengl/opengl_gal.h>
|
||||
#include <gal/opengl/shader.h>
|
||||
#include <gal/definitions.h>
|
||||
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
|
||||
|
||||
|
@ -71,22 +72,20 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
|||
isUseShader = isUseShaders;
|
||||
isShaderInitialized = false;
|
||||
isGrouping = false;
|
||||
shaderPath = "../../common/gal/opengl/shader/";
|
||||
shaderPath = "../../common/gal/opengl";
|
||||
wxSize parentSize = aParent->GetSize();
|
||||
|
||||
isVboInitialized = false;
|
||||
vboNeedsUpdate = false;
|
||||
curVboItem = NULL;
|
||||
vboSize = 0;
|
||||
transform = glm::mat4( 1.0f );
|
||||
transform = glm::mat4( 1.0f ); // Identity matrix
|
||||
|
||||
SetSize( parentSize );
|
||||
|
||||
screenSize.x = parentSize.x;
|
||||
screenSize.y = parentSize.y;
|
||||
|
||||
currentShader = -1;
|
||||
|
||||
// Set grid defaults
|
||||
SetGridColor( COLOR4D( 0.3, 0.3, 0.3, 0.3 ) );
|
||||
SetCoarseGrid( 10 );
|
||||
|
@ -108,10 +107,13 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
|||
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
|
||||
#endif
|
||||
|
||||
if( !isUseShader )
|
||||
{
|
||||
// Compute the unit circles, used for speed up of the circle drawing
|
||||
computeUnitCircle();
|
||||
computeUnitSemiCircle();
|
||||
// computeUnitArcs(); // TODO it is not used anywhere
|
||||
//computeUnitArcs(); // TODO remove? it is not used anywhere
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,18 +348,18 @@ void OPENGL_GAL::BeginDrawing()
|
|||
// Compile the shaders
|
||||
if( !isShaderInitialized && isUseShader )
|
||||
{
|
||||
std::string shaderNames[SHADER_NUMBER] = { std::string( "round" ) };
|
||||
|
||||
for( int i = 0; i < 1; i++ )
|
||||
shader.ConfigureGeometryShader( 3, GL_TRIANGLES, GL_TRIANGLES );
|
||||
shader.AddSource( shaderPath + std::string( "/shader.vert" ), SHADER_TYPE_VERTEX );
|
||||
shader.AddSource( shaderPath + std::string( "/shader.frag" ), SHADER_TYPE_FRAGMENT );
|
||||
if( !shader.Link() )
|
||||
{
|
||||
shaderList.push_back( SHADER() );
|
||||
wxLogFatalError( wxT( "Cannot link the shaders!" ) );
|
||||
}
|
||||
|
||||
shaderList[i].AddSource( shaderPath + std::string( "/" ) + shaderNames[i] +
|
||||
std::string( ".frag" ), SHADER_TYPE_FRAGMENT );
|
||||
shaderList[i].AddSource( shaderPath + std::string( "/" ) + shaderNames[i] +
|
||||
std::string( ".vert" ), SHADER_TYPE_VERTEX );
|
||||
|
||||
shaderList[i].Link();
|
||||
shaderAttrib = shader.GetAttribute( "attrShaderParams" );
|
||||
if( shaderAttrib == -1 )
|
||||
{
|
||||
wxLogFatalError( wxT( "Could not get the shader attribute location" ) );
|
||||
}
|
||||
|
||||
isShaderInitialized = true;
|
||||
|
@ -420,7 +422,8 @@ void OPENGL_GAL::BeginDrawing()
|
|||
|
||||
void OPENGL_GAL::blitMainTexture( bool aIsClearFrameBuffer )
|
||||
{
|
||||
selectShader( -1 );
|
||||
shader.Deactivate();
|
||||
|
||||
// Don't use blending for the final blitting
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
|
@ -474,25 +477,41 @@ void OPENGL_GAL::EndDrawing()
|
|||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
|
||||
// Bind vertices data buffer and point to the data
|
||||
// Bind vertices data buffers
|
||||
glBindBuffer( GL_ARRAY_BUFFER, curVboVertId );
|
||||
glVertexPointer( 3, GL_FLOAT, VBO_ITEM::VertSize, 0 );
|
||||
glColorPointer( 4, GL_FLOAT, VBO_ITEM::VertSize, (GLvoid*) VBO_ITEM::ColorByteOffset );
|
||||
glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, 0 );
|
||||
glColorPointer( VBO_ITEM::ColorStride, GL_FLOAT, VBO_ITEM::VertByteSize,
|
||||
(GLvoid*) VBO_ITEM::ColorByteOffset );
|
||||
|
||||
// Shader parameters
|
||||
if( isUseShader )
|
||||
{
|
||||
shader.Use();
|
||||
glEnableVertexAttribArray( shaderAttrib );
|
||||
glVertexAttribPointer( shaderAttrib, VBO_ITEM::ShaderStride, GL_FLOAT, GL_FALSE,
|
||||
VBO_ITEM::VertByteSize, (GLvoid*) VBO_ITEM::ShaderByteOffset );
|
||||
}
|
||||
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId );
|
||||
GLuint* indicesPtr = static_cast<GLuint*>( glMapBuffer( GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY ) );
|
||||
|
||||
wxASSERT_MSG( indicesPtr != NULL, "OPENGL_GAL::EndDrawing: Could not map GPU memory" );
|
||||
if( indicesPtr == NULL )
|
||||
{
|
||||
wxLogError( wxT( "Could not map GPU memory" ) );
|
||||
}
|
||||
|
||||
// Copy indices of items that should be drawn to GPU memory
|
||||
std::list<VBO_ITEM*>::const_iterator it, end;
|
||||
for( it = itemsToDraw.begin(), end = itemsToDraw.end(); it != end; ++it )
|
||||
{
|
||||
memcpy( indicesPtr, (*it)->GetIndices(), (*it)->GetSize() * VBO_ITEM::IndSize );
|
||||
memcpy( indicesPtr, (*it)->GetIndices(), (*it)->GetSize() * VBO_ITEM::IndByteSize );
|
||||
indicesPtr += (*it)->GetSize() * VBO_ITEM::IndStride;
|
||||
}
|
||||
|
||||
bool result = glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER );
|
||||
wxASSERT_MSG( result == TRUE, "OPENGL_GAL::EndDrawing: Unmapping indices buffer failed" );
|
||||
if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) )
|
||||
{
|
||||
wxLogError( wxT( "Unmapping indices buffer failed" ) );
|
||||
}
|
||||
|
||||
glDrawElements( GL_TRIANGLES, itemsToDrawSize, GL_UNSIGNED_INT, (GLvoid*) 0 );
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
||||
|
@ -501,6 +520,11 @@ void OPENGL_GAL::EndDrawing()
|
|||
// Deactivate vertex array
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
if( isUseShader )
|
||||
{
|
||||
glDisableVertexAttribArray( shaderAttrib );
|
||||
shader.Deactivate();
|
||||
}
|
||||
|
||||
// Draw the remaining contents, blit the main texture to the screen, swap the buffers
|
||||
glFlush();
|
||||
|
@ -538,18 +562,18 @@ void OPENGL_GAL::rebuildVbo()
|
|||
{
|
||||
int size = (*vboItem)->GetSize();
|
||||
|
||||
memcpy( verticesBufferPtr, (*vboItem)->GetVertices(), size * VBO_ITEM::VertSize );
|
||||
memcpy( verticesBufferPtr, (*vboItem)->GetVertices(), size * VBO_ITEM::VertByteSize );
|
||||
verticesBufferPtr += size * VBO_ITEM::VertStride;
|
||||
}
|
||||
|
||||
// Upload vertices coordinates and indices to GPU memory
|
||||
// Upload vertices coordinates, shader types and indices to GPU memory
|
||||
glBindBuffer( GL_ARRAY_BUFFER, curVboVertId );
|
||||
glBufferData( GL_ARRAY_BUFFER, vboSize * VBO_ITEM::VertSize, verticesBuffer, GL_DYNAMIC_DRAW );
|
||||
glBufferData( GL_ARRAY_BUFFER, vboSize * VBO_ITEM::VertByteSize, verticesBuffer, GL_DYNAMIC_DRAW );
|
||||
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
|
||||
// Allocate the biggest possible buffer for indices
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, curVboIndId );
|
||||
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndSize, NULL, GL_STREAM_DRAW );
|
||||
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboSize * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW );
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
||||
|
||||
delete[] verticesBuffer;
|
||||
|
@ -558,105 +582,81 @@ void OPENGL_GAL::rebuildVbo()
|
|||
#ifdef __WXDEBUG__
|
||||
prof_end( &totalTime );
|
||||
|
||||
wxLogDebug( wxT( "Rebuilding VBO::items %d / %.1f ms" ),
|
||||
wxLogDebug( wxT( "Rebuilding VBO::%d vertices / %.1f ms" ),
|
||||
vboSize, (double) totalTime.value / 1000.0 );
|
||||
#endif /* __WXDEBUG__ */
|
||||
}
|
||||
|
||||
|
||||
inline void OPENGL_GAL::selectShader( int aIndex )
|
||||
{
|
||||
if( currentShader != aIndex )
|
||||
{
|
||||
if( currentShader >= 0 )
|
||||
shaderList[currentShader].Deactivate();
|
||||
|
||||
if( aIndex >= 0 )
|
||||
shaderList[aIndex].Use();
|
||||
|
||||
currentShader = aIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawRoundedSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
||||
double aWidth, bool aStroke, bool aGlBegin )
|
||||
{
|
||||
VECTOR2D l = ( aEndPoint - aStartPoint );
|
||||
double lnorm = l.EuclideanNorm();
|
||||
double aspect;
|
||||
|
||||
if( l.x == 0 && l.y == 0 )
|
||||
{
|
||||
l = VECTOR2D( aWidth / 2.0, 0.0 );
|
||||
aspect = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = l.Resize( aWidth / 2.0 );
|
||||
aspect = lnorm / (lnorm + aWidth);
|
||||
}
|
||||
|
||||
VECTOR2D p = l.Perpendicular();
|
||||
VECTOR2D corners[4] = { aStartPoint - l - p, aEndPoint + l - p,
|
||||
aEndPoint + l + p, aStartPoint - l + p };
|
||||
|
||||
if( aStroke )
|
||||
{
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
}
|
||||
else
|
||||
{
|
||||
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
}
|
||||
|
||||
selectShader( 0 );
|
||||
|
||||
if( aGlBegin )
|
||||
glBegin( GL_QUADS ); // shader
|
||||
|
||||
glNormal3d( aspect, 0, 0 );
|
||||
glTexCoord2f( 0.0, 0.0 );
|
||||
glVertex3d( corners[0].x, corners[0].y, layerDepth );
|
||||
glNormal3d( aspect, 0, 0 );
|
||||
glTexCoord2f( 1.0, 0.0 );
|
||||
glVertex3d( corners[1].x, corners[1].y, layerDepth );
|
||||
glNormal3d( aspect, 0, 0 );
|
||||
glTexCoord2f( 1.0, 1.0 );
|
||||
glVertex3d( corners[2].x, corners[2].y, layerDepth );
|
||||
glNormal3d( aspect, 0, 0 );
|
||||
glTexCoord2f( 0.0, 1.0 );
|
||||
glVertex3d( corners[3].x, corners[3].y, layerDepth );
|
||||
|
||||
if( aGlBegin )
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
double scale = 0.5 * lineWidth / lineLength;
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
if( lineLength > 0.0 )
|
||||
{
|
||||
wxLogDebug( wxT( "Tried to draw line with length <= 0" ) );
|
||||
}
|
||||
#endif /* __WXDEBUG__ */
|
||||
|
||||
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
|
||||
// XXX Should be improved later.
|
||||
double scale = 0.5 * lineWidth / lineLength;
|
||||
double scale1pix = 0.5001 / worldScale / lineLength;
|
||||
if( lineWidth * worldScale < 1.0002 && !isGrouping )
|
||||
{
|
||||
scale = scale1pix;
|
||||
scale = 0.5001 / worldScale / lineLength;
|
||||
}
|
||||
|
||||
VECTOR2D perpendicularVector( -startEndVector.y * scale, startEndVector.x * scale );
|
||||
|
||||
begin( GL_TRIANGLES );
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
glm::vec4 vector( perpendicularVector.x, perpendicularVector.y, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
// Line width is maintained by the vertex shader
|
||||
setShader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
setShader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); // v1
|
||||
|
||||
setShader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
setShader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); // v0
|
||||
|
||||
setShader( SHADER_LINE, -vector.x, -vector.y, lineWidth );
|
||||
vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); // v3
|
||||
|
||||
setShader( SHADER_LINE, vector.x, vector.y, lineWidth );
|
||||
vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); // v2
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute the edge points of the line
|
||||
VECTOR2D v0 = aStartPoint + perpendicularVector;
|
||||
VECTOR2D v1 = aStartPoint - perpendicularVector;
|
||||
VECTOR2D v2 = aEndPoint + perpendicularVector;
|
||||
VECTOR2D v3 = aEndPoint - perpendicularVector;
|
||||
|
||||
begin( GL_TRIANGLES );
|
||||
vertex3( v0.x, v0.y, layerDepth );
|
||||
vertex3( v1.x, v1.y, layerDepth );
|
||||
vertex3( v3.x, v3.y, layerDepth );
|
||||
|
@ -664,6 +664,8 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2
|
|||
vertex3( v0.x, v0.y, layerDepth );
|
||||
vertex3( v3.x, v3.y, layerDepth );
|
||||
vertex3( v2.x, v2.y, layerDepth );
|
||||
}
|
||||
|
||||
end();
|
||||
}
|
||||
|
||||
|
@ -676,15 +678,17 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
|
|||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
// Filled tracks
|
||||
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
SetLineWidth( aWidth );
|
||||
drawSemiCircle( aStartPoint, aWidth / 2, lineAngle + M_PI / 2, layerDepth );
|
||||
drawSemiCircle( aEndPoint, aWidth / 2, lineAngle - M_PI / 2, layerDepth );
|
||||
drawSemiCircle( aStartPoint, aWidth / 2, lineAngle + M_PI / 2 );
|
||||
drawSemiCircle( aEndPoint, aWidth / 2, lineAngle - M_PI / 2 );
|
||||
drawLineQuad( aStartPoint, aEndPoint );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Outlined tracks
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
@ -700,16 +704,15 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
|
|||
drawLineQuad( VECTOR2D( 0.0, -aWidth / 2.0 ),
|
||||
VECTOR2D( lineLength, -aWidth / 2.0 ) );
|
||||
|
||||
DrawArc( VECTOR2D( 0.0, 0.0 ), aWidth / 2.0, M_PI / 2.0, 3.0 * M_PI / 2.0 );
|
||||
DrawArc( VECTOR2D( lineLength, 0.0 ), aWidth / 2.0, M_PI / 2.0, -M_PI / 2.0 );
|
||||
drawSemiCircle( VECTOR2D( 0.0, 0.0 ), aWidth / 2, M_PI / 2 );
|
||||
drawSemiCircle( VECTOR2D( lineLength, 0.0 ), aWidth / 2, -M_PI / 2 );
|
||||
|
||||
Restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
||||
double aDepthOffset )
|
||||
inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
// double lineLength = startEndVector.EuclideanNorm();
|
||||
|
@ -723,7 +726,7 @@ inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D
|
|||
|
||||
case LINE_CAP_ROUND:
|
||||
// Add a semicircle at the line end
|
||||
drawSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2, aDepthOffset );
|
||||
drawSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
break;
|
||||
|
||||
case LINE_CAP_SQUARED:
|
||||
|
@ -754,6 +757,7 @@ void OPENGL_GAL::vertex3( double aX, double aY, double aZ )
|
|||
{
|
||||
if( isGrouping )
|
||||
{
|
||||
// New vertex coordinates for VBO
|
||||
const GLfloat vertex[] = { aX, aY, aZ };
|
||||
curVboItem->PushVertex( vertex );
|
||||
}
|
||||
|
@ -805,31 +809,46 @@ void OPENGL_GAL::color4( const COLOR4D& aColor )
|
|||
|
||||
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
if( isUseShader )
|
||||
if( isFillEnabled )
|
||||
{
|
||||
drawRoundedSegment( aStartPoint, aEndPoint, lineWidth, true, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
if( lineLength > 0.0 )
|
||||
{
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
drawLineCap( aStartPoint, aEndPoint, layerDepth );
|
||||
drawLineCap( aEndPoint, aStartPoint, layerDepth );
|
||||
drawLineCap( aStartPoint, aEndPoint );
|
||||
drawLineCap( aEndPoint, aStartPoint );
|
||||
drawLineQuad( aStartPoint, aEndPoint );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
// TODO outline mode
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
drawLineCap( aStartPoint, aEndPoint );
|
||||
drawLineCap( aEndPoint, aStartPoint );
|
||||
drawLineQuad( aStartPoint, aEndPoint );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
LineCap savedLineCap = lineCap;
|
||||
|
||||
bool isFirstPoint = true;
|
||||
|
||||
if( isUseShader )
|
||||
{
|
||||
// This method reduces amount of triangles used for drawing
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
// Start from the second point
|
||||
for( it++; it != aPointList.end(); it++ )
|
||||
{
|
||||
DrawLine( *( it - 1 ), *it );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LineCap savedLineCap = lineCap;
|
||||
bool isFirstLine = true;
|
||||
VECTOR2D startEndVector;
|
||||
VECTOR2D lastStartEndVector;
|
||||
|
@ -854,7 +873,7 @@ void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
|||
|
||||
if( isFirstLine )
|
||||
{
|
||||
drawLineCap( lastPoint, actualPoint, layerDepth );
|
||||
drawLineCap( lastPoint, actualPoint );
|
||||
isFirstLine = false;
|
||||
}
|
||||
else
|
||||
|
@ -1029,7 +1048,7 @@ void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
|||
|
||||
if( it == aPointList.end() - 1 )
|
||||
{
|
||||
drawLineCap( actualPoint, lastPoint, layerDepth );
|
||||
drawLineCap( actualPoint, lastPoint );
|
||||
}
|
||||
|
||||
drawLineQuad( lastPoint, *it );
|
||||
|
@ -1050,47 +1069,11 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
|
|||
VECTOR2D diagonalPointA( aEndPoint.x, aStartPoint.y );
|
||||
VECTOR2D diagonalPointB( aStartPoint.x, aEndPoint.y );
|
||||
|
||||
if( isUseShader )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
selectShader( 0 );
|
||||
glColor4d( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
glBegin( GL_QUADS ); // shader
|
||||
glNormal3d( 1.0, 0, 0 );
|
||||
glTexCoord2f( 0.0, 0.0 );
|
||||
glVertex3d( aStartPoint.x, aStartPoint.y, layerDepth );
|
||||
glNormal3d( 1.0, 0, 0 );
|
||||
glTexCoord2f( 1.0, 0.0 );
|
||||
glVertex3d( diagonalPointA.x, diagonalPointA.y, layerDepth );
|
||||
glNormal3d( 1.0, 0, 0 );
|
||||
glTexCoord2f( 1.0, 1.0 );
|
||||
glVertex3d( aEndPoint.x, aEndPoint.y, layerDepth );
|
||||
glNormal3d( 1.0, 0, 0 );
|
||||
glTexCoord2f( 0.0, 1.0 );
|
||||
glVertex3d( diagonalPointB.x, diagonalPointB.y, layerDepth );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
glBegin( GL_QUADS ); // shader
|
||||
drawRoundedSegment( aStartPoint, diagonalPointA, lineWidth, true, false );
|
||||
drawRoundedSegment( aEndPoint, diagonalPointA, lineWidth, true, false );
|
||||
drawRoundedSegment( aStartPoint, diagonalPointB, lineWidth, true, false );
|
||||
drawRoundedSegment( aEndPoint, diagonalPointB, lineWidth, true, false );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
selectShader( -1 );
|
||||
|
||||
// Stroke the outline
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
std::deque<VECTOR2D> pointList;
|
||||
pointList.push_back( aStartPoint );
|
||||
pointList.push_back( diagonalPointA );
|
||||
|
@ -1103,6 +1086,7 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
|
|||
// Fill the rectangle
|
||||
if( isFillEnabled )
|
||||
{
|
||||
setShader( SHADER_NONE );
|
||||
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
begin( GL_TRIANGLES );
|
||||
|
@ -1115,23 +1099,74 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
|
|||
vertex3( diagonalPointB.x, diagonalPointB.y, layerDepth );
|
||||
end();
|
||||
}
|
||||
|
||||
// Restore the stroke color
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
{
|
||||
// We need a minimum radius, else simply don't draw the circle
|
||||
if( aRadius <= 0.0 )
|
||||
#ifdef __WXDEBUG__
|
||||
if( aRadius > 0.0 )
|
||||
{
|
||||
return;
|
||||
wxLogDebug( wxT( "Tried to draw circle with radius <= 0" ) );
|
||||
}
|
||||
#endif /* __WXDEBUG__ */
|
||||
|
||||
if( isUseShader )
|
||||
{
|
||||
drawRoundedSegment( aCenterPoint, aCenterPoint, aRadius * 2.0, false, true );
|
||||
if( isFillEnabled )
|
||||
{
|
||||
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
|
||||
Parameters given to setShader are relative coordinates of the triangle's vertices.
|
||||
Shader uses this coordinates to determine if fragments are inside the circle or not.
|
||||
v2
|
||||
/\
|
||||
//\\
|
||||
v0 /_\/_\ v1
|
||||
*/
|
||||
setShader( SHADER_FILLED_CIRCLE, -sqrt( 3.0f ), -1.0f );
|
||||
vertex3( aCenterPoint.x - aRadius * sqrt( 3.0f ), // v0
|
||||
aCenterPoint.y - aRadius, layerDepth );
|
||||
|
||||
setShader( SHADER_FILLED_CIRCLE, sqrt( 3.0f ), -1.0f );
|
||||
vertex3( aCenterPoint.x + aRadius * sqrt( 3.0f ), // v1
|
||||
aCenterPoint.y - aRadius, layerDepth );
|
||||
|
||||
setShader( SHADER_FILLED_CIRCLE, 0.0f, 2.0f );
|
||||
vertex3( aCenterPoint.x, aCenterPoint.y + aRadius * 2.0f, layerDepth ); // v2
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
|
||||
Parameters given to setShader are relative coordinates of the triangle's vertices
|
||||
and the line width. Shader uses this coordinates to determine if fragments are inside
|
||||
the circle or not. Width parameter has to be passed as a relative value.
|
||||
v2
|
||||
/\
|
||||
//\\
|
||||
v0 /_\/_\ v1
|
||||
*/
|
||||
float outerRadius = aRadius + ( lineWidth / 2.0f );
|
||||
float innerRadius = aRadius - ( lineWidth / 2.0f );
|
||||
float relWidth = innerRadius / outerRadius;
|
||||
|
||||
setShader( SHADER_STROKED_CIRCLE, -sqrt( 3.0f ), -1.0f, relWidth );
|
||||
vertex3( aCenterPoint.x - outerRadius * sqrt( 3.0f ), // v0
|
||||
aCenterPoint.y - outerRadius, layerDepth );
|
||||
|
||||
setShader( SHADER_STROKED_CIRCLE, sqrt( 3.0f ), -1.0f, relWidth );
|
||||
vertex3( aCenterPoint.x + outerRadius * sqrt( 3.0f ), // v1
|
||||
aCenterPoint.y - outerRadius, layerDepth );
|
||||
|
||||
setShader( SHADER_STROKED_CIRCLE, 0.0f, 2.0f, relWidth );
|
||||
vertex3( aCenterPoint.x, // v2
|
||||
aCenterPoint.y + outerRadius * 2.0f, layerDepth );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1142,12 +1177,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
outerScale += 1.0;
|
||||
innerScale += 1.0;
|
||||
|
||||
if( isUseShader )
|
||||
{
|
||||
// TODO is it ever reached?
|
||||
innerScale *= 1.0 / cos( M_PI / CIRCLE_POINTS );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
if( innerScale < outerScale )
|
||||
|
@ -1209,11 +1238,39 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle,
|
||||
double aDepthOffset )
|
||||
void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
|
||||
{
|
||||
if( isUseShader )
|
||||
{
|
||||
Save();
|
||||
translate3( aCenterPoint.x, aCenterPoint.y, aDepthOffset );
|
||||
Translate( aCenterPoint );
|
||||
Rotate( aAngle );
|
||||
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
/* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle.
|
||||
Parameters given to setShader are relative coordinates of the triangle's vertices.
|
||||
Shader uses this coordinates to determine if fragments are inside the semicircle or not.
|
||||
v2
|
||||
/\
|
||||
/__\
|
||||
v0 //__\\ v1
|
||||
*/
|
||||
setShader( SHADER_FILLED_CIRCLE, -3.0f / sqrt( 3.0f ), 0.0f, lineWidth );
|
||||
vertex3( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
|
||||
|
||||
setShader( SHADER_FILLED_CIRCLE, 3.0f / sqrt( 3.0f ), 0.0f, lineWidth );
|
||||
vertex3( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
|
||||
|
||||
setShader( SHADER_FILLED_CIRCLE, 0.0f, 2.0f, lineWidth );
|
||||
vertex3( 0.0f, aRadius * 2.0f, layerDepth ); // v2
|
||||
|
||||
Restore();
|
||||
}
|
||||
else
|
||||
{
|
||||
Save();
|
||||
translate3( aCenterPoint.x, aCenterPoint.y, layerDepth );
|
||||
Scale( VECTOR2D( aRadius, aRadius ) );
|
||||
Rotate( aAngle );
|
||||
|
||||
|
@ -1227,6 +1284,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
|
|||
}
|
||||
|
||||
Restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1239,12 +1297,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
return;
|
||||
}
|
||||
|
||||
double outerScale = lineWidth / aRadius / 2;
|
||||
double innerScale = -outerScale;
|
||||
|
||||
outerScale += 1.0;
|
||||
innerScale += 1.0;
|
||||
|
||||
// Swap the angles, if start angle is greater than end angle
|
||||
SWAP( aStartAngle, >, aEndAngle );
|
||||
|
||||
|
@ -1254,46 +1306,37 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
VECTOR2D middlePoint = 0.5 * startEndPoint;
|
||||
|
||||
Save();
|
||||
translate3( aCenterPoint.x, aCenterPoint.y, layerDepth );
|
||||
Scale( VECTOR2D( aRadius, aRadius ) );
|
||||
translate3( aCenterPoint.x, aCenterPoint.y, 0.0 );
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
if( isUseShader )
|
||||
{
|
||||
int n_points_s = (int) ( aRadius * worldScale );
|
||||
int n_points_a = (int) ( ( aEndAngle - aStartAngle ) /
|
||||
(double) ( 2.0 * M_PI / CIRCLE_POINTS ) );
|
||||
double alphaIncrement = 2.0 * M_PI / CIRCLE_POINTS;
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
if( n_points_s < 4 )
|
||||
n_points_s = 4;
|
||||
|
||||
int n_points = std::min( n_points_s, n_points_a );
|
||||
|
||||
if( n_points > CIRCLE_POINTS )
|
||||
n_points = CIRCLE_POINTS;
|
||||
|
||||
double alphaIncrement = ( aEndAngle - aStartAngle ) / n_points;
|
||||
|
||||
double cosI = cos( alphaIncrement );
|
||||
double sinI = sin( alphaIncrement );
|
||||
|
||||
VECTOR2D p( cos( aStartAngle ), sin( aStartAngle ) );
|
||||
|
||||
glBegin( GL_QUADS ); // shader
|
||||
|
||||
for( int i = 0; i < n_points; i++ )
|
||||
VECTOR2D p( cos( aStartAngle ) * aRadius, sin( aStartAngle ) * aRadius );
|
||||
for( double alpha = aStartAngle; alpha < aEndAngle; alpha += alphaIncrement )
|
||||
{
|
||||
VECTOR2D p_next( p.x * cosI - p.y * sinI, p.x * sinI + p.y * cosI );
|
||||
if( alpha > aEndAngle )
|
||||
alpha = aEndAngle;
|
||||
|
||||
VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
|
||||
DrawLine( p, p_next );
|
||||
|
||||
drawRoundedSegment( p, p_next, lineWidth / aRadius, true, false );
|
||||
p = p_next;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
Scale( VECTOR2D( aRadius, aRadius ) );
|
||||
|
||||
double outerScale = lineWidth / aRadius / 2;
|
||||
double innerScale = -outerScale;
|
||||
|
||||
outerScale += 1.0;
|
||||
innerScale += 1.0;
|
||||
|
||||
double alphaIncrement = 2 * M_PI / CIRCLE_POINTS;
|
||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
|
@ -1312,21 +1355,21 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
double v2[] = { cos( alpha ) * innerScale, sin( alpha ) * innerScale };
|
||||
double v3[] = { cos( alpha ) * outerScale, sin( alpha ) * outerScale };
|
||||
|
||||
vertex3( v0[0], v0[1], 0.0 );
|
||||
vertex3( v1[0], v1[1], 0.0 );
|
||||
vertex3( v2[0], v2[1], 0.0 );
|
||||
vertex3( v0[0], v0[1], layerDepth );
|
||||
vertex3( v1[0], v1[1], layerDepth );
|
||||
vertex3( v2[0], v2[1], layerDepth );
|
||||
|
||||
vertex3( v1[0], v1[1], 0.0 );
|
||||
vertex3( v3[0], v3[1], 0.0 );
|
||||
vertex3( v2[0], v2[1], 0.0 );
|
||||
vertex3( v1[0], v1[1], layerDepth );
|
||||
vertex3( v3[0], v3[1], layerDepth );
|
||||
vertex3( v2[0], v2[1], layerDepth );
|
||||
}
|
||||
|
||||
end();
|
||||
|
||||
if( lineCap == LINE_CAP_ROUND )
|
||||
{
|
||||
drawSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI, 0 );
|
||||
drawSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle, 0 );
|
||||
drawSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI );
|
||||
drawSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1341,15 +1384,15 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
|
||||
for( alpha = aStartAngle; ( alpha + alphaIncrement ) < aEndAngle; )
|
||||
{
|
||||
vertex3( middlePoint.x, middlePoint.y, 0.0 );
|
||||
vertex3( cos( alpha ), sin( alpha ), 0.0 );
|
||||
vertex3( middlePoint.x, middlePoint.y, layerDepth );
|
||||
vertex3( cos( alpha ), sin( alpha ), layerDepth );
|
||||
alpha += alphaIncrement;
|
||||
vertex3( cos( alpha ), sin( alpha ), 0.0 );
|
||||
vertex3( cos( alpha ), sin( alpha ), layerDepth );
|
||||
}
|
||||
|
||||
vertex3( middlePoint.x, middlePoint.y, 0.0 );
|
||||
vertex3( cos( alpha ), sin( alpha ), 0.0 );
|
||||
vertex3( endPoint.x, endPoint.y, 0.0 );
|
||||
vertex3( middlePoint.x, middlePoint.y, layerDepth );
|
||||
vertex3( cos( alpha ), sin( alpha ), layerDepth );
|
||||
vertex3( endPoint.x, endPoint.y, layerDepth );
|
||||
end();
|
||||
}
|
||||
|
||||
|
@ -1391,6 +1434,8 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
|||
// Any non convex polygon needs to be tesselated
|
||||
// for this purpose the GLU standard functions are used
|
||||
|
||||
setShader( SHADER_NONE );
|
||||
|
||||
GLUtesselator* tesselator = gluNewTess();
|
||||
|
||||
typedef std::vector<OGLPOINT> OGLPOINTS;
|
||||
|
@ -1624,18 +1669,27 @@ int OPENGL_GAL::BeginGroup()
|
|||
|
||||
void OPENGL_GAL::EndGroup()
|
||||
{
|
||||
wxASSERT_MSG( curVboItem->GetSize() != 0,
|
||||
"OPENGL_GAL::EndGroup: Tried to add group that contains nothing" );
|
||||
#ifdef __WXDEBUG__
|
||||
if( curVboItem->GetSize() != 0 )
|
||||
{
|
||||
wxLogDebug( wxT( "Tried to add group that contains nothing" ) );
|
||||
}
|
||||
#endif /* __WXDEBUG__ */
|
||||
|
||||
vboSize += curVboItem->GetSize();
|
||||
curVboItem = NULL;
|
||||
isGrouping = false;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
wxASSERT_MSG( aGroupNumber < vboItems.size(),
|
||||
"OPENGL_GAL::DeleteGroup: Tried to delete not existing group" );
|
||||
#ifdef __WXDEBUG__
|
||||
if( (unsigned) aGroupNumber < vboItems.size() )
|
||||
{
|
||||
wxLogDebug( wxT( "Tried to delete not existing group" ) );
|
||||
}
|
||||
#endif /* __WXDEBUG__ */
|
||||
|
||||
std::deque<VBO_ITEM*>::iterator it = vboItems.begin();
|
||||
std::advance( it, aGroupNumber );
|
||||
|
@ -1962,7 +2016,7 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
|||
VECTOR2D point4 = aEndPoint - perpendicularVector;
|
||||
|
||||
if( isUseShader )
|
||||
selectShader( -1 );
|
||||
shader.Deactivate();
|
||||
|
||||
// Set color
|
||||
glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a );
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
|
@ -24,18 +25,48 @@
|
|||
*/
|
||||
|
||||
#version 120
|
||||
//#pragma debug(on)
|
||||
|
||||
varying float aspect;
|
||||
// Shader types
|
||||
const float SHADER_LINE = 1.0;
|
||||
const float SHADER_FILLED_CIRCLE = 2.0;
|
||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||
|
||||
void main()
|
||||
varying in vec4 shaderParams;
|
||||
|
||||
void filledCircle( vec2 aCoord )
|
||||
{
|
||||
vec2 v = abs( gl_TexCoord[0].xy - vec2( 0.5, 0.5 ) ) * 2.0 - vec2( aspect, 0.0 );
|
||||
vec2 d = vec2( v.x / ( 1.0 - aspect ), v.y );
|
||||
|
||||
if( v.x <= 0.0 || (dot( d, d ) < 1.0 ) )
|
||||
if( dot( aCoord, aCoord ) < 1.0 )
|
||||
gl_FragColor = gl_Color;
|
||||
else
|
||||
discard;
|
||||
|
||||
// gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
void strokedCircle( vec2 aCoord, float aWidth )
|
||||
{
|
||||
if( ( dot( aCoord, aCoord ) < 1.0 ) &&
|
||||
( dot( aCoord, aCoord ) > aWidth * aWidth ) )
|
||||
gl_FragColor = gl_Color;
|
||||
else
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
if( shaderParams[0] == SHADER_FILLED_CIRCLE )
|
||||
{
|
||||
filledCircle( vec2( shaderParams[1], shaderParams[2] ) );
|
||||
}
|
||||
else if( shaderParams[0] == SHADER_STROKED_CIRCLE )
|
||||
{
|
||||
strokedCircle( vec2( shaderParams[1], shaderParams[2] ), shaderParams[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple pass-through
|
||||
gl_FragColor = gl_Color;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
|
@ -24,12 +24,42 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
// Shader types
|
||||
const float SHADER_LINE = 1.0;
|
||||
const float SHADER_FILLED_CIRCLE = 2.0;
|
||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||
|
||||
attribute vec4 attrShaderParams;
|
||||
varying out vec4 shaderParams;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Simple pass-through
|
||||
gl_Position = gl_Vertex;
|
||||
// Pass attributes to the fragment shader
|
||||
shaderParams = attrShaderParams;
|
||||
|
||||
if( shaderParams[0] == SHADER_LINE )
|
||||
{
|
||||
float lineWidth = shaderParams[3];
|
||||
float worldScale = gl_ModelViewMatrix[0][0];
|
||||
float scale;
|
||||
|
||||
// Make lines appear to be at least 1 pixel width
|
||||
if( worldScale * lineWidth < 1.0 )
|
||||
scale = 1.0 / ( worldScale * lineWidth );
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
( gl_Vertex + vec4( shaderParams.yz * scale, 0.0, 0.0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pass through the coordinates like in the fixed pipeline
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
// Input variables
|
||||
flat varying vec4 center_;
|
||||
flat varying vec2 radius_;
|
||||
flat varying vec4 colorA_;
|
||||
flat varying vec4 colorB_;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Compute the distance from the circle edge
|
||||
float distA = distance( center_, gl_FragCoord ) - radius_.y;
|
||||
float distB = radius_.x - distance( center_, gl_FragCoord );
|
||||
|
||||
// Limit the range to [ 0 .. 1 ]
|
||||
if( distA < 0 ) distA = 0;
|
||||
if( distA > 1 ) distA = 1;
|
||||
if( distB < 0 ) distB = 0;
|
||||
if( distB > 1 ) distB = 1;
|
||||
|
||||
// Points with a larger distance from the edge are set deeper
|
||||
gl_FragDepth = gl_FragCoord.z + distA * 0.001 + distB * 0.001;
|
||||
|
||||
// Compute the color
|
||||
vec4 color;
|
||||
color.r = colorA_.r;
|
||||
color.g = colorA_.g;
|
||||
color.b = colorA_.b;
|
||||
color.a = colorA_.a * ( 1 - distA ) * ( 1 - distB );
|
||||
|
||||
// Now output the edge fragment color
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Geometry shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
#extension GL_EXT_geometry_shader4: enable
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
uniform float viewPortX2;
|
||||
uniform float viewPortY2;
|
||||
|
||||
flat varying vec4 center_;
|
||||
flat varying vec2 radius_;
|
||||
flat varying vec4 colorA_;
|
||||
|
||||
const float PI = 3.141592654;
|
||||
const float EPSILON = 0.01;
|
||||
const float smallestValue = 1.175494351e-38;
|
||||
const int SEGMENTS = 16;
|
||||
|
||||
const float PIXEL_EXTEND = 1.5;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 center = gl_PositionIn[0];
|
||||
vec4 radius = gl_PositionIn[1];
|
||||
|
||||
center_ = gl_ModelViewProjectionMatrix * center;
|
||||
|
||||
// Compute the outer and inner radius in screen coordinates
|
||||
// This could be further optimized
|
||||
radius_.x = ( gl_ModelViewProjectionMatrix * vec4(radius.x, 0, 0, 1) ).x;
|
||||
radius_.x = abs( radius_.x - (gl_ModelViewProjectionMatrix * vec4(0, 0, 0, 1) ).x ) * viewPortX2;
|
||||
radius_.y = ( gl_ModelViewProjectionMatrix * vec4(radius.y, 0, 0, 1) ).x;
|
||||
radius_.y = abs( radius_.y - (gl_ModelViewProjectionMatrix * vec4(0, 0, 0, 1) ).x ) * viewPortX2;
|
||||
|
||||
// Compute the center point in screen coordinates
|
||||
center_.x = center_.x * viewPortX2 + viewPortX2;
|
||||
center_.y = center_.y * viewPortY2 + viewPortY2;
|
||||
|
||||
// Compute the extend value, first make sure that the outline is inside the triangles and second add
|
||||
// a margin for one pixel for smooth edges
|
||||
float extendInner = 1.0;
|
||||
float extendOuter = 0;
|
||||
if( radius_.y > smallestValue )
|
||||
{
|
||||
extendOuter += PIXEL_EXTEND / radius_.y;
|
||||
}
|
||||
extendOuter += 1.0 / cos( PI / SEGMENTS );
|
||||
|
||||
colorA_ = gl_FrontColorIn[0];
|
||||
|
||||
// Create a quad strip for the outer circle edge
|
||||
for( float alpha = 0, inc = 2 * PI / SEGMENTS, limit = 2 * PI + EPSILON;
|
||||
alpha < limit; alpha += inc )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendInner * radius.y * cos( alpha ),
|
||||
center.y + extendInner * radius.y * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendOuter * radius.y * cos( alpha ),
|
||||
center.y + extendOuter * radius.y * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
|
||||
if( radius.x > 0 )
|
||||
{
|
||||
extendInner = cos( PI / SEGMENTS ) - PIXEL_EXTEND / radius_.x;
|
||||
if( extendInner < 0.0 )
|
||||
{
|
||||
extendInner = 0;
|
||||
}
|
||||
extendOuter = 1.0 / cos( PI / SEGMENTS);
|
||||
|
||||
// Create a quad strip for the inner circle edge
|
||||
for( float alpha = 0, inc = 2 * PI / SEGMENTS, limit = 2 * PI + EPSILON;
|
||||
alpha < limit; alpha += inc )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendOuter * radius.x * cos( alpha ),
|
||||
center.y + extendOuter * radius.x * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendInner * radius.x * cos( alpha ),
|
||||
center.y + extendInner * radius.x * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
// Simple pass-through
|
||||
gl_Position = gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
varying float dist;
|
||||
|
||||
void main()
|
||||
{
|
||||
float d = dist;
|
||||
gl_FragDepth = gl_FragCoord.z + d * 0.001;
|
||||
gl_FragColor = vec4( gl_Color.rgb, gl_Color.a * ( 1 - d ) );
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Geometry shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
#extension GL_EXT_geometry_shader4: enable
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
uniform float viewPortX2;
|
||||
uniform float viewPortY2;
|
||||
varying float dist;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Compute the transformed start and end points
|
||||
vec2 startPoint = gl_PositionIn[0].xy;
|
||||
vec2 endPoint = gl_PositionIn[1].xy;
|
||||
float lineWidth = gl_PositionIn[1].z;
|
||||
|
||||
// Compute vector start -> end
|
||||
vec2 startEndVector = endPoint.xy - startPoint.xy;
|
||||
float lineLength = distance( startPoint, endPoint );
|
||||
float scale = 0.0;
|
||||
|
||||
if( lineLength > 0.0 )
|
||||
{
|
||||
scale = 0.5 * lineWidth / lineLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 0.0;
|
||||
}
|
||||
|
||||
// Compute the edge points of the line
|
||||
vec2 perpendicularVector = scale * vec2( -startEndVector.y, startEndVector.x );
|
||||
vec2 point1 = startPoint + perpendicularVector;
|
||||
vec2 point2 = startPoint - perpendicularVector;
|
||||
vec2 point3 = endPoint + perpendicularVector;
|
||||
vec2 point4 = endPoint - perpendicularVector;
|
||||
|
||||
vec4 point1T = gl_ModelViewProjectionMatrix * vec4( point1, gl_PositionIn[0].zw );
|
||||
vec4 point2T = gl_ModelViewProjectionMatrix * vec4( point2, gl_PositionIn[0].zw );
|
||||
vec4 point3T = gl_ModelViewProjectionMatrix * vec4( point3, gl_PositionIn[0].zw );
|
||||
vec4 point4T = gl_ModelViewProjectionMatrix * vec4( point4, gl_PositionIn[0].zw );
|
||||
|
||||
// Construct the quad for the middle
|
||||
gl_FrontColor = gl_FrontColorIn[0];
|
||||
dist = 0;
|
||||
gl_Position = point1T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point2T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point3T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point4T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
// Compute the perpendicular vector with 1 pixel width
|
||||
vec2 v = point1T.xy - point3T.xy;
|
||||
vec4 onePix = 0.5 * vec4( -v.y, v.x, 0, 0 );
|
||||
onePix *= 1.0 / sqrt( dot( onePix, onePix ) );
|
||||
onePix.x *= 1.0 / viewPortX2;
|
||||
onePix.y *= 1.0 / viewPortY2;
|
||||
|
||||
gl_FrontColor = gl_FrontColorIn[0];
|
||||
|
||||
dist = 1;
|
||||
gl_Position = point1T + onePix;
|
||||
EmitVertex();
|
||||
dist = 1;
|
||||
gl_Position = point3T + onePix;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point1T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point3T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
dist = 1;
|
||||
gl_Position = point2T - onePix;
|
||||
EmitVertex();
|
||||
dist = 1;
|
||||
gl_Position = point4T - onePix;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point2T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point4T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
varying float aspect;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
aspect = gl_Normal.x;
|
||||
}
|
|
@ -40,6 +40,9 @@ VBO_ITEM::VBO_ITEM() :
|
|||
m_isDirty( true ),
|
||||
m_transform( NULL )
|
||||
{
|
||||
// By default no shader is used
|
||||
m_shader[0] = 0;
|
||||
|
||||
// Prepare a block for storing vertices & indices
|
||||
useNewBlock();
|
||||
}
|
||||
|
@ -50,7 +53,7 @@ VBO_ITEM::~VBO_ITEM()
|
|||
if( m_isDirty )
|
||||
{
|
||||
// Data is still stored in blocks
|
||||
std::list<GLfloat*>::const_iterator v_it, v_end;
|
||||
std::list<VBO_VERTEX*>::const_iterator v_it, v_end;
|
||||
for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it )
|
||||
delete[] *v_it;
|
||||
|
||||
|
@ -76,23 +79,26 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex )
|
|||
{
|
||||
// Apply transformations
|
||||
// X, Y, Z coordinates
|
||||
glm::vec4 origVertex( aVertex[0], aVertex[1], aVertex[2], 1.0f );
|
||||
glm::vec4 transVertex = *m_transform * origVertex;
|
||||
glm::vec4 vertex( aVertex[0], aVertex[1], aVertex[2], 1.0f );
|
||||
vertex = *m_transform * vertex;
|
||||
|
||||
// Replace only coordinates, leave color as it is
|
||||
memcpy( m_vertPtr, &transVertex[0], CoordSize );
|
||||
memcpy( &m_vertPtr->struc.coord, &vertex[0], CoordByteSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the new vertex
|
||||
memcpy( m_vertPtr, aVertex, CoordSize );
|
||||
memcpy( &m_vertPtr->struc.coord, aVertex, CoordByteSize );
|
||||
}
|
||||
|
||||
// Apply currently used color
|
||||
memcpy( m_vertPtr + ColorOffset, m_color, ColorSize );
|
||||
memcpy( &m_vertPtr->struc.color, m_color, ColorByteSize );
|
||||
|
||||
// Apply currently used shader
|
||||
memcpy( &m_vertPtr->struc.shader, m_shader, ShaderByteSize );
|
||||
|
||||
// Move to the next free space
|
||||
m_vertPtr += VertStride;
|
||||
m_vertPtr++;
|
||||
|
||||
// Add the new index
|
||||
*m_indPtr = m_offset + m_size;
|
||||
|
@ -177,10 +183,10 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
|
|||
|
||||
for( int i = 0; i < m_size; ++i )
|
||||
{
|
||||
memcpy( vertexPtr, newColor, ColorSize );
|
||||
memcpy( vertexPtr, newColor, ColorByteSize );
|
||||
|
||||
// Move on to the next vertex
|
||||
vertexPtr += VertStride;
|
||||
vertexPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +200,12 @@ void VBO_ITEM::UseColor( const COLOR4D& aColor )
|
|||
}
|
||||
|
||||
|
||||
void VBO_ITEM::UseShader( const GLfloat* aShader )
|
||||
{
|
||||
memcpy( m_shader, aShader, ShaderByteSize );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// TODO
|
||||
void SetVbo( int aVboId )
|
||||
|
@ -209,7 +221,7 @@ int GetVbo() const
|
|||
|
||||
void VBO_ITEM::useNewBlock()
|
||||
{
|
||||
GLfloat* newVertBlock = new GLfloat[BLOCK_SIZE * VertStride];
|
||||
VBO_VERTEX* newVertBlock = new VBO_VERTEX[BLOCK_SIZE];
|
||||
GLuint* newIndBlock = new GLuint[BLOCK_SIZE];
|
||||
|
||||
m_vertPtr = newVertBlock;
|
||||
|
@ -233,16 +245,16 @@ void VBO_ITEM::prepareFinal()
|
|||
GLfloat* vertPtr = m_vertices;
|
||||
|
||||
// Copy blocks of vertices one after another to m_vertices
|
||||
std::list<GLfloat*>::const_iterator v_it;
|
||||
std::list<VBO_VERTEX*>::const_iterator v_it;
|
||||
for( v_it = m_vertBlocks.begin(); *v_it != m_vertBlocks.back(); ++v_it )
|
||||
{
|
||||
memcpy( vertPtr, *v_it, BLOCK_SIZE * VertSize );
|
||||
memcpy( vertPtr, *v_it, BLOCK_SIZE * VertByteSize );
|
||||
delete[] *v_it;
|
||||
vertPtr += ( BLOCK_SIZE * VertStride );
|
||||
}
|
||||
|
||||
// In the last block we need to copy only used vertices
|
||||
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertSize );
|
||||
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertByteSize );
|
||||
|
||||
if( m_indices )
|
||||
delete m_indices;
|
||||
|
@ -256,13 +268,13 @@ void VBO_ITEM::prepareFinal()
|
|||
std::list<GLuint*>::const_iterator i_it;
|
||||
for( i_it = m_indBlocks.begin(); *i_it != m_indBlocks.back(); ++i_it )
|
||||
{
|
||||
memcpy( indPtr, *i_it, BLOCK_SIZE * IndSize );
|
||||
memcpy( indPtr, *i_it, BLOCK_SIZE * IndByteSize );
|
||||
delete[] *i_it;
|
||||
indPtr += ( BLOCK_SIZE * IndStride );
|
||||
}
|
||||
|
||||
// In the last block we need to copy only used indices
|
||||
memcpy( indPtr, *i_it, ( BLOCK_SIZE - m_spaceLeft ) * IndSize );
|
||||
memcpy( indPtr, *i_it, ( BLOCK_SIZE - m_spaceLeft ) * IndByteSize );
|
||||
|
||||
m_isDirty = false;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
// OpenGL mathematics library
|
||||
#define GLM_FORCE_RADIANS
|
||||
#include <gal/opengl/vbo_item.h>
|
||||
#include <gal/opengl/shader.h>
|
||||
|
||||
// wxWidgets imports
|
||||
#include <wx/wx.h>
|
||||
|
@ -323,7 +324,6 @@ private:
|
|||
|
||||
static const int CIRCLE_POINTS = 64; ///< The number of points for circle approximation
|
||||
static const int CURVE_POINTS = 32; ///< The number of points for curve approximation
|
||||
static const int SHADER_NUMBER = 2; ///< Number of the used shaders
|
||||
static const double MITER_LIMIT = 1.5; ///< Limit for mitered edges ( * lineWidth )
|
||||
|
||||
/// This factor is used to for correct merging of antialiased edges,
|
||||
|
@ -365,7 +365,18 @@ private:
|
|||
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
||||
|
||||
// Shader
|
||||
std::deque<SHADER> shaderList; ///< List of the shaders
|
||||
// Possible types of shaders
|
||||
typedef enum
|
||||
{
|
||||
SHADER_NONE = 0,
|
||||
SHADER_LINE,
|
||||
SHADER_FILLED_CIRCLE,
|
||||
SHADER_STROKED_CIRCLE,
|
||||
} SHADER_TYPE;
|
||||
|
||||
SHADER shader; ///< There is only one shader used for different objects
|
||||
int shaderAttrib; ///< Location of shader attributes (for glVertexAttribPointer)
|
||||
std::string shaderPath; ///< Location of shader files
|
||||
|
||||
// Cursor
|
||||
int cursorSize; ///< Size of the cursor in pixels
|
||||
|
@ -391,8 +402,6 @@ private:
|
|||
bool isShaderEnabled; ///< Are the shaders enabled?
|
||||
bool isUseShader; ///< Should the shaders be used?
|
||||
bool isGrouping; ///< Was a group started?
|
||||
int currentShader; ///< ID of the shader currently in use
|
||||
std::string shaderPath;
|
||||
|
||||
/**
|
||||
* @brief Draw a semi circle (used for line caps).
|
||||
|
@ -400,11 +409,9 @@ private:
|
|||
* @param aCenterPoint is the center point.
|
||||
* @param aRadius is the radius of the semi-circle.
|
||||
* @param aAngle is the angle of the semi-circle.
|
||||
* @param ADepthOffset is the relative depth of the semi-circle.
|
||||
*
|
||||
*/
|
||||
void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle,
|
||||
double aDepthOffset );
|
||||
void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
|
||||
|
||||
/// Compute the points of a unit circle.
|
||||
void computeUnitCircle();
|
||||
|
@ -506,8 +513,7 @@ private:
|
|||
* @param aEndPoint is the end point of the line.
|
||||
* @param aDepthOffset is the relative depth of the line cap.
|
||||
*/
|
||||
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
||||
double aDepthOffset );
|
||||
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||
|
||||
///< OpenGL replacement functions (that are working both in immediate and VBO modes)
|
||||
/**
|
||||
|
@ -561,13 +567,23 @@ private:
|
|||
*/
|
||||
inline void color4( const COLOR4D& aColor );
|
||||
|
||||
inline void selectShader( int aIndex );
|
||||
|
||||
/// @copydoc GAL::DrawRoundedSegment()
|
||||
void drawRoundedSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth,
|
||||
bool aStroke = false, bool aGlBegin = false );
|
||||
|
||||
/**
|
||||
* @brief Function that sets shader and its parameters for the currently used VBO_ITEM.
|
||||
* It should be used before adding any vertices that have to be shaded.
|
||||
* @param aShader is the type of shader used for vertices.
|
||||
* @param aParam[1..3] are shader's parameters. Their meaning depends on the type of used shader.
|
||||
* For more information you may check shaders' source code.
|
||||
*/
|
||||
inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f,
|
||||
GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f )
|
||||
{
|
||||
if( isUseShader && isGrouping )
|
||||
{
|
||||
const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 };
|
||||
|
||||
curVboItem->UseShader( shader );
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
|
|
|
@ -34,10 +34,31 @@
|
|||
#include <gal/opengl/glm/glm.hpp>
|
||||
#include <gal/color4d.h>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
typedef struct VBO_VERTEX_DATA
|
||||
{
|
||||
GLfloat x, y, z; // Coordinates
|
||||
GLfloat r, g, b, a; // Color
|
||||
GLfloat shader[4]; // Shader type & params
|
||||
} VBO_VERTEX_DATA;
|
||||
|
||||
typedef struct VBO_VERTEX_STRUCT
|
||||
{
|
||||
GLfloat coord[3]; // Coordinates
|
||||
GLfloat color[4]; // Color
|
||||
GLfloat shader[4]; // Shader type & params
|
||||
} VBO_VERTEX_STRUCT;
|
||||
|
||||
typedef union VBO_VERTEX
|
||||
{
|
||||
VBO_VERTEX_DATA data;
|
||||
VBO_VERTEX_STRUCT struc;
|
||||
} VBO_VERTEX;
|
||||
|
||||
class VBO_ITEM
|
||||
{
|
||||
|
@ -50,6 +71,7 @@ public:
|
|||
* Adds a single vertex to the VBO_ITEM. Vertex contains information about coordinates and
|
||||
* colors and has to follow the specified format {X,Y,Z,R,G,B,A}.
|
||||
* @param aVertex is a vertex to be added.
|
||||
* @param aShader is an attribute for shader.
|
||||
*/
|
||||
void PushVertex( const GLfloat* aVertex );
|
||||
|
||||
|
@ -60,6 +82,7 @@ public:
|
|||
* coordinates and colors and has to follow the specified format {X,Y,Z,R,G,B,A}.
|
||||
* @param aVertices are vertices to be added.
|
||||
* @param aSize is an amount of vertices to be added.
|
||||
* @param aShader is an attribute for shader.
|
||||
*/
|
||||
void PushVertices( const GLfloat* aVertices, GLuint aSize );
|
||||
|
||||
|
@ -121,26 +144,38 @@ public:
|
|||
*/
|
||||
void UseColor( const COLOR4D& aColor );
|
||||
|
||||
/**
|
||||
* Function UseShader()
|
||||
* Sets shader and its parameters used for all added vertices.
|
||||
* @param aShader is the array that contains shader number followed by its parameters.
|
||||
*/
|
||||
void UseShader( const GLfloat* aShader );
|
||||
|
||||
///< Functions for getting VBO ids.
|
||||
//void SetVbo( int aVboId );
|
||||
//int GetVbo() const;
|
||||
|
||||
///< Data organization information for vertices {X,Y,Z,R,G,B,A}.
|
||||
// Each vertex consists of 7 floats, but it is padded to 8
|
||||
static const int VertStride = 8;
|
||||
static const int VertSize = VertStride * sizeof(GLfloat);
|
||||
///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX).
|
||||
static const int VertByteSize = sizeof(VBO_VERTEX);
|
||||
static const int VertStride = VertByteSize / sizeof(GLfloat);
|
||||
|
||||
static const int CoordStride = 3;
|
||||
static const int CoordSize = CoordStride * sizeof(GLfloat);
|
||||
static const int CoordStride = sizeof(VBO_VERTEX_STRUCT().coord) / sizeof(GLfloat);
|
||||
static const int CoordByteSize = sizeof(VBO_VERTEX_STRUCT().coord);
|
||||
|
||||
// Offset of color data from the beginning of each vertex data
|
||||
static const int ColorOffset = 3;
|
||||
static const int ColorByteOffset = ColorOffset * sizeof(GLfloat);
|
||||
static const int ColorStride = 4;
|
||||
static const int ColorSize = ColorStride * sizeof(GLfloat);
|
||||
static const int ColorByteOffset = offsetof( VBO_VERTEX_STRUCT, color );
|
||||
static const int ColorOffset = ColorByteOffset / sizeof(GLfloat);
|
||||
static const int ColorStride = sizeof(VBO_VERTEX_STRUCT().color) / sizeof(GLfloat);
|
||||
static const int ColorByteSize = sizeof(VBO_VERTEX_STRUCT().color);
|
||||
|
||||
// Shader attributes
|
||||
static const int ShaderByteOffset = offsetof( VBO_VERTEX_STRUCT, shader );
|
||||
static const int ShaderOffset = ShaderByteOffset / sizeof(GLfloat);
|
||||
static const int ShaderStride = sizeof(VBO_VERTEX_STRUCT().shader) / sizeof(GLfloat);
|
||||
static const int ShaderByteSize = sizeof(VBO_VERTEX_STRUCT().shader);
|
||||
|
||||
static const int IndStride = 1;
|
||||
static const int IndSize = IndStride * sizeof(GLuint);
|
||||
static const int IndByteSize = IndStride * sizeof(GLuint);
|
||||
|
||||
private:
|
||||
///< VBO ids in which the item is stored.
|
||||
|
@ -153,16 +188,16 @@ private:
|
|||
///< Indices of vertices
|
||||
GLuint* m_indices;
|
||||
|
||||
///< Lists of blocks
|
||||
std::list<GLfloat*> m_vertBlocks;
|
||||
///< Lists of data blocks storing vertices
|
||||
std::list<VBO_VERTEX*> m_vertBlocks;
|
||||
std::list<GLuint*> m_indBlocks;
|
||||
///< Pointers to current blocks that can be used for storing data
|
||||
GLfloat* m_vertPtr;
|
||||
///< Pointers to current blocks that should be used for storing data
|
||||
VBO_VERTEX* m_vertPtr;
|
||||
GLuint* m_indPtr;
|
||||
///< How many vertices can be stored in the current buffer
|
||||
int m_spaceLeft;
|
||||
///< Number of vertices & indices stored in a single block
|
||||
static const int BLOCK_SIZE = 8;
|
||||
static const int BLOCK_SIZE = 256;
|
||||
///< Creates a new block for storing vertices data
|
||||
void useNewBlock();
|
||||
///< Prepares a continuous block of data that can be copied to graphics card buffer.
|
||||
|
@ -172,12 +207,11 @@ private:
|
|||
int m_offset;
|
||||
int m_size;
|
||||
|
||||
///< Shader data used for rendering.
|
||||
int m_shader;
|
||||
int m_shaderAttrib;
|
||||
|
||||
///< Color used for new vertices pushed.
|
||||
GLfloat m_color[4];
|
||||
GLfloat m_color[ColorStride];
|
||||
|
||||
///< Shader and its parameters used for new vertices pushed
|
||||
GLfloat m_shader[ShaderStride];
|
||||
|
||||
///< Flag telling if the item should be recached in VBO or not.
|
||||
bool m_isDirty;
|
||||
|
|
|
@ -582,12 +582,12 @@ void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
|
|||
break;
|
||||
|
||||
case ID_MENU_CANVAS_CAIRO:
|
||||
m_galCanvas->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO, false );
|
||||
m_galCanvas->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );
|
||||
UseGalCanvas( true );
|
||||
break;
|
||||
|
||||
case ID_MENU_CANVAS_OPENGL:
|
||||
m_galCanvas->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL, false );
|
||||
m_galCanvas->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL, true );
|
||||
UseGalCanvas( true );
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue