Commit 28511cf4 authored by Maciej Suminski's avatar Maciej Suminski

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.
parent ad5d10a8
...@@ -58,9 +58,9 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin ...@@ -58,9 +58,9 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
wxStandardPaths paths; wxStandardPaths paths;
wxFileName executableFile( paths.GetExecutablePath() ); wxFileName executableFile( paths.GetExecutablePath() );
m_galShaderPath = std::string( ( executableFile.GetPath() + 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 ); SetBackgroundStyle( wxBG_STYLE_CUSTOM );
// Initial display settings // Initial display settings
......
This diff is collapsed.
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * 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 * Fragment shader
* *
...@@ -24,18 +25,48 @@ ...@@ -24,18 +25,48 @@
*/ */
#version 120 #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 ); if( dot( aCoord, aCoord ) < 1.0 )
vec2 d = vec2( v.x / ( 1.0 - aspect ), v.y ); gl_FragColor = gl_Color;
else
discard;
}
if( v.x <= 0.0 || (dot( d, d ) < 1.0 ) )
void strokedCircle( vec2 aCoord, float aWidth )
{
if( ( dot( aCoord, aCoord ) < 1.0 ) &&
( dot( aCoord, aCoord ) > aWidth * aWidth ) )
gl_FragColor = gl_Color; gl_FragColor = gl_Color;
else else
discard; discard;
}
// gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); 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;
}
} }
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * 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) 2013 CERN
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* Vertex shader * Vertex shader
* *
...@@ -24,12 +24,42 @@ ...@@ -24,12 +24,42 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
// This shader requires GLSL 1.2
#version 120 #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() void main()
{ {
// Simple pass-through // Pass attributes to the fragment shader
gl_Position = gl_Vertex; 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; gl_FrontColor = gl_Color;
} }
/*
* 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;
}
/*
* 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();
}
}
/*
* 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;
}
/*
* 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 ) );
}
/*
* 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();
}
/*
* 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() : ...@@ -40,6 +40,9 @@ VBO_ITEM::VBO_ITEM() :
m_isDirty( true ), m_isDirty( true ),
m_transform( NULL ) m_transform( NULL )
{ {
// By default no shader is used
m_shader[0] = 0;
// Prepare a block for storing vertices & indices // Prepare a block for storing vertices & indices
useNewBlock(); useNewBlock();
} }
...@@ -50,7 +53,7 @@ VBO_ITEM::~VBO_ITEM() ...@@ -50,7 +53,7 @@ VBO_ITEM::~VBO_ITEM()
if( m_isDirty ) if( m_isDirty )
{ {
// Data is still stored in blocks // 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 ) for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it )
delete[] *v_it; delete[] *v_it;
...@@ -75,24 +78,27 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex ) ...@@ -75,24 +78,27 @@ void VBO_ITEM::PushVertex( const GLfloat* aVertex )
if( m_transform != NULL ) if( m_transform != NULL )
{ {
// Apply transformations // Apply transformations
// X, Y, Z coordinates // X, Y, Z coordinates
glm::vec4 origVertex( aVertex[0], aVertex[1], aVertex[2], 1.0f ); glm::vec4 vertex( aVertex[0], aVertex[1], aVertex[2], 1.0f );
glm::vec4 transVertex = *m_transform * origVertex; vertex = *m_transform * vertex;
// Replace only coordinates, leave color as it is // Replace only coordinates, leave color as it is
memcpy( m_vertPtr, &transVertex[0], CoordSize ); memcpy( &m_vertPtr->struc.coord, &vertex[0], CoordByteSize );
} }
else else
{ {
// Add the new vertex // Add the new vertex
memcpy( m_vertPtr, aVertex, CoordSize ); memcpy( &m_vertPtr->struc.coord, aVertex, CoordByteSize );
} }
// Apply currently used color // 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 // Move to the next free space
m_vertPtr += VertStride; m_vertPtr++;
// Add the new index // Add the new index
*m_indPtr = m_offset + m_size; *m_indPtr = m_offset + m_size;
...@@ -177,10 +183,10 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) ...@@ -177,10 +183,10 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
for( int i = 0; i < m_size; ++i ) for( int i = 0; i < m_size; ++i )
{ {
memcpy( vertexPtr, newColor, ColorSize ); memcpy( vertexPtr, newColor, ColorByteSize );
// Move on to the next vertex // Move on to the next vertex
vertexPtr += VertStride; vertexPtr++;
} }
} }
...@@ -194,6 +200,12 @@ void VBO_ITEM::UseColor( const COLOR4D& aColor ) ...@@ -194,6 +200,12 @@ void VBO_ITEM::UseColor( const COLOR4D& aColor )
} }
void VBO_ITEM::UseShader( const GLfloat* aShader )
{
memcpy( m_shader, aShader, ShaderByteSize );
}
/* /*
// TODO // TODO
void SetVbo( int aVboId ) void SetVbo( int aVboId )
...@@ -209,8 +221,8 @@ int GetVbo() const ...@@ -209,8 +221,8 @@ int GetVbo() const
void VBO_ITEM::useNewBlock() 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]; GLuint* newIndBlock = new GLuint[BLOCK_SIZE];
m_vertPtr = newVertBlock; m_vertPtr = newVertBlock;
m_indPtr = newIndBlock; m_indPtr = newIndBlock;
...@@ -233,16 +245,16 @@ void VBO_ITEM::prepareFinal() ...@@ -233,16 +245,16 @@ void VBO_ITEM::prepareFinal()
GLfloat* vertPtr = m_vertices; GLfloat* vertPtr = m_vertices;
// Copy blocks of vertices one after another to 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 ) 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; delete[] *v_it;
vertPtr += ( BLOCK_SIZE * VertStride ); vertPtr += ( BLOCK_SIZE * VertStride );
} }
// In the last block we need to copy only used vertices // In the last block we need to copy only used vertices
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertSize ); memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertByteSize );
if( m_indices ) if( m_indices )
delete m_indices; delete m_indices;
...@@ -256,13 +268,13 @@ void VBO_ITEM::prepareFinal() ...@@ -256,13 +268,13 @@ void VBO_ITEM::prepareFinal()
std::list<GLuint*>::const_iterator i_it; std::list<GLuint*>::const_iterator i_it;
for( i_it = m_indBlocks.begin(); *i_it != m_indBlocks.back(); ++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; delete[] *i_it;
indPtr += ( BLOCK_SIZE * IndStride ); indPtr += ( BLOCK_SIZE * IndStride );
} }
// In the last block we need to copy only used indices // 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; m_isDirty = false;
} }
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
// OpenGL mathematics library // OpenGL mathematics library
#define GLM_FORCE_RADIANS #define GLM_FORCE_RADIANS
#include <gal/opengl/vbo_item.h> #include <gal/opengl/vbo_item.h>
#include <gal/opengl/shader.h>
// wxWidgets imports // wxWidgets imports
#include <wx/wx.h> #include <wx/wx.h>
...@@ -323,7 +324,6 @@ private: ...@@ -323,7 +324,6 @@ private:
static const int CIRCLE_POINTS = 64; ///< The number of points for circle approximation 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 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 ) static const double MITER_LIMIT = 1.5; ///< Limit for mitered edges ( * lineWidth )
/// This factor is used to for correct merging of antialiased edges, /// This factor is used to for correct merging of antialiased edges,
...@@ -365,7 +365,18 @@ private: ...@@ -365,7 +365,18 @@ private:
GLUtesselator* tesselator; ///< Pointer to the tesselator GLUtesselator* tesselator; ///< Pointer to the tesselator
// Shader // 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 // Cursor
int cursorSize; ///< Size of the cursor in pixels int cursorSize; ///< Size of the cursor in pixels
...@@ -391,8 +402,6 @@ private: ...@@ -391,8 +402,6 @@ private:
bool isShaderEnabled; ///< Are the shaders enabled? bool isShaderEnabled; ///< Are the shaders enabled?
bool isUseShader; ///< Should the shaders be used? bool isUseShader; ///< Should the shaders be used?
bool isGrouping; ///< Was a group started? 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). * @brief Draw a semi circle (used for line caps).
...@@ -400,11 +409,9 @@ private: ...@@ -400,11 +409,9 @@ private:
* @param aCenterPoint is the center point. * @param aCenterPoint is the center point.
* @param aRadius is the radius of the semi-circle. * @param aRadius is the radius of the semi-circle.
* @param aAngle is the angle 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, void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
double aDepthOffset );
/// Compute the points of a unit circle. /// Compute the points of a unit circle.
void computeUnitCircle(); void computeUnitCircle();
...@@ -506,8 +513,7 @@ private: ...@@ -506,8 +513,7 @@ private:
* @param aEndPoint is the end point of the line. * @param aEndPoint is the end point of the line.
* @param aDepthOffset is the relative depth of the line cap. * @param aDepthOffset is the relative depth of the line cap.
*/ */
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
double aDepthOffset );
///< OpenGL replacement functions (that are working both in immediate and VBO modes) ///< OpenGL replacement functions (that are working both in immediate and VBO modes)
/** /**
...@@ -561,13 +567,23 @@ private: ...@@ -561,13 +567,23 @@ private:
*/ */
inline void color4( const COLOR4D& aColor ); inline void color4( const COLOR4D& aColor );
inline void selectShader( int aIndex ); /**
* @brief Function that sets shader and its parameters for the currently used VBO_ITEM.
/// @copydoc GAL::DrawRoundedSegment() * It should be used before adding any vertices that have to be shaded.
void drawRoundedSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth, * @param aShader is the type of shader used for vertices.
bool aStroke = false, bool aGlBegin = false ); * @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 } // namespace KiGfx
......
...@@ -34,10 +34,31 @@ ...@@ -34,10 +34,31 @@
#include <gal/opengl/glm/glm.hpp> #include <gal/opengl/glm/glm.hpp>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <cstddef>
#include <list> #include <list>
namespace KiGfx 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 class VBO_ITEM
{ {
...@@ -50,6 +71,7 @@ public: ...@@ -50,6 +71,7 @@ public:
* Adds a single vertex to the VBO_ITEM. Vertex contains information about coordinates and * 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}. * colors and has to follow the specified format {X,Y,Z,R,G,B,A}.
* @param aVertex is a vertex to be added. * @param aVertex is a vertex to be added.
* @param aShader is an attribute for shader.
*/ */
void PushVertex( const GLfloat* aVertex ); void PushVertex( const GLfloat* aVertex );
...@@ -60,6 +82,7 @@ public: ...@@ -60,6 +82,7 @@ public:
* coordinates and colors and has to follow the specified format {X,Y,Z,R,G,B,A}. * 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 aVertices are vertices to be added.
* @param aSize is an amount of 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 ); void PushVertices( const GLfloat* aVertices, GLuint aSize );
...@@ -121,26 +144,38 @@ public: ...@@ -121,26 +144,38 @@ public:
*/ */
void UseColor( const COLOR4D& aColor ); 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. ///< Functions for getting VBO ids.
//void SetVbo( int aVboId ); //void SetVbo( int aVboId );
//int GetVbo() const; //int GetVbo() const;
///< Data organization information for vertices {X,Y,Z,R,G,B,A}. ///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX).
// Each vertex consists of 7 floats, but it is padded to 8 static const int VertByteSize = sizeof(VBO_VERTEX);
static const int VertStride = 8; static const int VertStride = VertByteSize / sizeof(GLfloat);
static const int VertSize = VertStride * sizeof(GLfloat);
static const int CoordStride = 3; static const int CoordStride = sizeof(VBO_VERTEX_STRUCT().coord) / sizeof(GLfloat);
static const int CoordSize = CoordStride * sizeof(GLfloat); static const int CoordByteSize = sizeof(VBO_VERTEX_STRUCT().coord);
// Offset of color data from the beginning of each vertex data // Offset of color data from the beginning of each vertex data
static const int ColorOffset = 3; static const int ColorByteOffset = offsetof( VBO_VERTEX_STRUCT, color );
static const int ColorByteOffset = ColorOffset * sizeof(GLfloat); static const int ColorOffset = ColorByteOffset / sizeof(GLfloat);
static const int ColorStride = 4; static const int ColorStride = sizeof(VBO_VERTEX_STRUCT().color) / sizeof(GLfloat);
static const int ColorSize = ColorStride * 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 IndStride = 1;
static const int IndSize = IndStride * sizeof(GLuint); static const int IndByteSize = IndStride * sizeof(GLuint);
private: private:
///< VBO ids in which the item is stored. ///< VBO ids in which the item is stored.
...@@ -153,31 +188,30 @@ private: ...@@ -153,31 +188,30 @@ private:
///< Indices of vertices ///< Indices of vertices
GLuint* m_indices; GLuint* m_indices;
///< Lists of blocks ///< Lists of data blocks storing vertices
std::list<GLfloat*> m_vertBlocks; std::list<VBO_VERTEX*> m_vertBlocks;
std::list<GLuint*> m_indBlocks; std::list<GLuint*> m_indBlocks;
///< Pointers to current blocks that can be used for storing data ///< Pointers to current blocks that should be used for storing data
GLfloat* m_vertPtr; VBO_VERTEX* m_vertPtr;
GLuint* m_indPtr; GLuint* m_indPtr;
///< How many vertices can be stored in the current buffer ///< How many vertices can be stored in the current buffer
int m_spaceLeft; int m_spaceLeft;
///< Number of vertices & indices stored in a single block ///< Number of vertices & 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 ///< Creates a new block for storing vertices data
void useNewBlock(); void useNewBlock();
///< Prepares a continuous block of data that can be copied to graphics card buffer. ///< Prepares a continuous block of data that can be copied to graphics card buffer.
void prepareFinal(); void prepareFinal();
///< Offset and size of data in VBO. ///< Offset and size of data in VBO.
int m_offset; int m_offset;
int m_size; int m_size;
///< Shader data used for rendering.
int m_shader;
int m_shaderAttrib;
///< Color used for new vertices pushed. ///< 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. ///< Flag telling if the item should be recached in VBO or not.
bool m_isDirty; bool m_isDirty;
......
...@@ -582,12 +582,12 @@ void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent ) ...@@ -582,12 +582,12 @@ void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
break; break;
case ID_MENU_CANVAS_CAIRO: 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 ); UseGalCanvas( true );
break; break;
case ID_MENU_CANVAS_OPENGL: 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 ); UseGalCanvas( true );
break; break;
} }
......
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