remove custom shader header generation build-step in favor of c++11 raw string literals
rework shader loading code to handle an arbitrary amount of to-be-concatenated strings
This commit is contained in:
parent
047f52e7cb
commit
77f9cd0cb0
|
@ -19,24 +19,6 @@ if( NOT APPLE ) # windows and linux use openssl under curl
|
||||||
find_package( OpenSSL REQUIRED )
|
find_package( OpenSSL REQUIRED )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Generate header files containing shader programs
|
|
||||||
# Order of input files is significant
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT gal/opengl/shader_src.h
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-DinputFiles="${PROJECT_SOURCE_DIR}/common/gal/opengl/shader.vert\\;${PROJECT_SOURCE_DIR}/common/gal/opengl/shader.frag"
|
|
||||||
-DoutputFile="shader_src.h"
|
|
||||||
-P ${CMAKE_MODULE_PATH}/Shaders.cmake
|
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/common/gal/opengl
|
|
||||||
COMMENT "Generating headers containing GLSL source code"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(
|
|
||||||
shader_headers ALL
|
|
||||||
DEPENDS gal/opengl/shader_src.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set( GAL_SRCS
|
set( GAL_SRCS
|
||||||
# Common part
|
# Common part
|
||||||
basic_gal.cpp
|
basic_gal.cpp
|
||||||
|
@ -56,6 +38,7 @@ set( GAL_SRCS
|
||||||
# OpenGL GAL
|
# OpenGL GAL
|
||||||
gal/opengl/opengl_gal.cpp
|
gal/opengl/opengl_gal.cpp
|
||||||
gal/opengl/gl_resources.cpp
|
gal/opengl/gl_resources.cpp
|
||||||
|
gal/opengl/gl_builtin_shaders.cpp
|
||||||
gal/opengl/shader.cpp
|
gal/opengl/shader.cpp
|
||||||
gal/opengl/vertex_item.cpp
|
gal/opengl/vertex_item.cpp
|
||||||
gal/opengl/vertex_container.cpp
|
gal/opengl/vertex_container.cpp
|
||||||
|
|
|
@ -0,0 +1,229 @@
|
||||||
|
#include "gl_builtin_shaders.h"
|
||||||
|
|
||||||
|
namespace KIGFX {
|
||||||
|
namespace BUILTIN_SHADERS {
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* KiCad shaders
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char kicad_vertex_shader[] = R"SHADER_SOURCE(
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2016 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@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
|
||||||
|
|
||||||
|
// Shader types
|
||||||
|
const float SHADER_LINE = 1.0;
|
||||||
|
const float SHADER_FILLED_CIRCLE = 2.0;
|
||||||
|
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||||
|
const float SHADER_FONT = 4.0;
|
||||||
|
|
||||||
|
// Minimum line width
|
||||||
|
const float MIN_WIDTH = 1.0;
|
||||||
|
|
||||||
|
attribute vec4 attrShaderParams;
|
||||||
|
varying vec4 shaderParams;
|
||||||
|
varying vec2 circleCoords;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Pass attributes to the fragment shader
|
||||||
|
shaderParams = attrShaderParams;
|
||||||
|
|
||||||
|
if( shaderParams[0] == SHADER_LINE )
|
||||||
|
{
|
||||||
|
float lineWidth = shaderParams[3];
|
||||||
|
float worldScale = abs( gl_ModelViewMatrix[0][0] );
|
||||||
|
|
||||||
|
// Make lines appear to be at least 1 pixel wide
|
||||||
|
if( worldScale * lineWidth < MIN_WIDTH )
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix *
|
||||||
|
( gl_Vertex + vec4( shaderParams.yz * MIN_WIDTH / ( worldScale * lineWidth ), 0.0, 0.0 ) );
|
||||||
|
else
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix *
|
||||||
|
( gl_Vertex + vec4( shaderParams.yz, 0.0, 0.0 ) );
|
||||||
|
}
|
||||||
|
else if( ( shaderParams[0] == SHADER_STROKED_CIRCLE ) ||
|
||||||
|
( shaderParams[0] == SHADER_FILLED_CIRCLE ) )
|
||||||
|
{
|
||||||
|
// Compute relative circle coordinates basing on indices
|
||||||
|
// Circle
|
||||||
|
if( shaderParams[1] == 1.0 )
|
||||||
|
circleCoords = vec2( -sqrt( 3.0 ), -1.0 );
|
||||||
|
else if( shaderParams[1] == 2.0 )
|
||||||
|
circleCoords = vec2( sqrt( 3.0 ), -1.0 );
|
||||||
|
else if( shaderParams[1] == 3.0 )
|
||||||
|
circleCoords = vec2( 0.0, 2.0 );
|
||||||
|
|
||||||
|
// Semicircle
|
||||||
|
else if( shaderParams[1] == 4.0 )
|
||||||
|
circleCoords = vec2( -3.0 / sqrt( 3.0 ), 0.0 );
|
||||||
|
else if( shaderParams[1] == 5.0 )
|
||||||
|
circleCoords = vec2( 3.0 / sqrt( 3.0 ), 0.0 );
|
||||||
|
else if( shaderParams[1] == 6.0 )
|
||||||
|
circleCoords = vec2( 0.0, 2.0 );
|
||||||
|
|
||||||
|
// Make the line appear to be at least 1 pixel wide
|
||||||
|
float lineWidth = shaderParams[3];
|
||||||
|
float worldScale = abs( gl_ModelViewMatrix[0][0] );
|
||||||
|
|
||||||
|
if( worldScale * lineWidth < MIN_WIDTH )
|
||||||
|
shaderParams[3] = shaderParams[3] / ( worldScale * lineWidth );
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Pass through the coordinates like in the fixed pipeline
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
)SHADER_SOURCE";
|
||||||
|
|
||||||
|
const char kicad_fragment_shader[] = R"SHADER_SOURCE(
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2016 CERN
|
||||||
|
* Copyright (C) 2016 Kicad Developers, see authors.txt for contributors.
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// Multi-channel signed distance field
|
||||||
|
#define USE_MSDF
|
||||||
|
|
||||||
|
// Shader types
|
||||||
|
const float SHADER_LINE = 1.0;
|
||||||
|
const float SHADER_FILLED_CIRCLE = 2.0;
|
||||||
|
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||||
|
const float SHADER_FONT = 4.0;
|
||||||
|
|
||||||
|
varying vec4 shaderParams;
|
||||||
|
varying vec2 circleCoords;
|
||||||
|
uniform sampler2D fontTexture;
|
||||||
|
|
||||||
|
// Needed to reconstruct the mipmap level / texel derivative
|
||||||
|
uniform int fontTextureWidth;
|
||||||
|
|
||||||
|
void filledCircle( vec2 aCoord )
|
||||||
|
{
|
||||||
|
if( dot( aCoord, aCoord ) < 1.0 )
|
||||||
|
gl_FragColor = gl_Color;
|
||||||
|
else
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void strokedCircle( vec2 aCoord, float aRadius, float aWidth )
|
||||||
|
{
|
||||||
|
float outerRadius = aRadius + ( aWidth / 2 );
|
||||||
|
float innerRadius = aRadius - ( aWidth / 2 );
|
||||||
|
float relWidth = innerRadius / outerRadius;
|
||||||
|
|
||||||
|
if( ( dot( aCoord, aCoord ) < 1.0 ) &&
|
||||||
|
( dot( aCoord, aCoord ) > relWidth * relWidth ) )
|
||||||
|
gl_FragColor = gl_Color;
|
||||||
|
else
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_MSDF
|
||||||
|
float median( vec3 v )
|
||||||
|
{
|
||||||
|
return max( min( v.r, v.g ), min( max( v.r, v.g ), v.b ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if( shaderParams[0] == SHADER_FILLED_CIRCLE )
|
||||||
|
{
|
||||||
|
filledCircle( circleCoords );
|
||||||
|
}
|
||||||
|
else if( shaderParams[0] == SHADER_STROKED_CIRCLE )
|
||||||
|
{
|
||||||
|
strokedCircle( circleCoords, shaderParams[2], shaderParams[3] );
|
||||||
|
}
|
||||||
|
else if( shaderParams[0] == SHADER_FONT )
|
||||||
|
{
|
||||||
|
vec2 tex = shaderParams.yz;
|
||||||
|
|
||||||
|
// Unless we're streching chars it is okay to consider
|
||||||
|
// one derivative for filtering
|
||||||
|
float derivative = length( dFdx( tex ) ) * fontTextureWidth / 4;
|
||||||
|
|
||||||
|
#ifdef USE_MSDF
|
||||||
|
float dist = median( texture2D( fontTexture, tex ).rgb );
|
||||||
|
#else
|
||||||
|
float dist = texture2D( fontTexture, tex ).r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// use the derivative for zoom-adaptive filtering
|
||||||
|
float alpha = smoothstep( 0.5 - derivative, 0.5 + derivative, dist );
|
||||||
|
|
||||||
|
gl_FragColor = vec4( gl_Color.rgb, alpha );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Simple pass-through
|
||||||
|
gl_FragColor = gl_Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)SHADER_SOURCE";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef GAL_GL_BUILTIN_SHADERS_H__
|
||||||
|
#define GAL_GL_BUILTIN_SHADERS_H__
|
||||||
|
|
||||||
|
namespace KIGFX {
|
||||||
|
|
||||||
|
namespace BUILTIN_SHADERS {
|
||||||
|
|
||||||
|
extern const char kicad_vertex_shader[];
|
||||||
|
extern const char kicad_fragment_shader[];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,6 +49,7 @@ using namespace KIGFX;
|
||||||
// The current font is "Ubuntu Mono" available under Ubuntu Font Licence 1.0
|
// The current font is "Ubuntu Mono" available under Ubuntu Font Licence 1.0
|
||||||
// (see ubuntu-font-licence-1.0.txt for details)
|
// (see ubuntu-font-licence-1.0.txt for details)
|
||||||
#include "gl_resources.h"
|
#include "gl_resources.h"
|
||||||
|
#include "gl_builtin_shaders.h"
|
||||||
using namespace KIGFX::BUILTIN_FONT;
|
using namespace KIGFX::BUILTIN_FONT;
|
||||||
|
|
||||||
static void InitTesselatorCallbacks( GLUtesselator* aTesselator );
|
static void InitTesselatorCallbacks( GLUtesselator* aTesselator );
|
||||||
|
@ -1558,10 +1559,10 @@ void OPENGL_GAL::OPENGL_TEST::Render( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||||
error( "Vertex buffer objects are not supported!" );
|
error( "Vertex buffer objects are not supported!" );
|
||||||
|
|
||||||
// Prepare shaders
|
// Prepare shaders
|
||||||
else if( !m_gal->shader->IsLinked() && !m_gal->shader->LoadBuiltinShader( 0, SHADER_TYPE_VERTEX ) )
|
else if( !m_gal->shader->IsLinked() && !m_gal->shader->LoadShaderFromStrings( SHADER_TYPE_VERTEX, BUILTIN_SHADERS::kicad_vertex_shader ) )
|
||||||
error( "Cannot compile vertex shader!" );
|
error( "Cannot compile vertex shader!" );
|
||||||
|
|
||||||
else if( !m_gal->shader->IsLinked() && !m_gal->shader->LoadBuiltinShader( 1, SHADER_TYPE_FRAGMENT ) )
|
else if( !m_gal->shader->IsLinked() && !m_gal->shader->LoadShaderFromStrings(SHADER_TYPE_FRAGMENT, BUILTIN_SHADERS::kicad_fragment_shader ) )
|
||||||
error( "Cannot compile fragment shader!" );
|
error( "Cannot compile fragment shader!" );
|
||||||
|
|
||||||
else if( !m_gal->shader->IsLinked() && !m_gal->shader->Link() )
|
else if( !m_gal->shader->IsLinked() && !m_gal->shader->Link() )
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <gal/opengl/shader.h>
|
#include <gal/opengl/shader.h>
|
||||||
#include "shader_src.h"
|
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
@ -76,22 +75,12 @@ SHADER::~SHADER()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHADER::LoadShaderFromFile( SHADER_TYPE aShaderType, const std::string& aShaderSourceName )
|
||||||
bool SHADER::LoadBuiltinShader( unsigned int aShaderNumber, SHADER_TYPE aShaderType )
|
|
||||||
{
|
|
||||||
if( aShaderNumber >= shaders_number )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return addSource( std::string( shaders_src[aShaderNumber] ), aShaderType );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SHADER::LoadShaderFromFile( const std::string& aShaderSourceName, SHADER_TYPE aShaderType )
|
|
||||||
{
|
{
|
||||||
// Load shader sources
|
// Load shader sources
|
||||||
const std::string shaderSource = readSource( aShaderSourceName );
|
const std::string shaderSource = ReadSource( aShaderSourceName );
|
||||||
|
|
||||||
return addSource( shaderSource, aShaderType );
|
return LoadShaderFromStrings( aShaderType, shaderSource );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,7 +198,7 @@ void SHADER::shaderInfo( GLuint aShader )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string SHADER::readSource( std::string aShaderSourceName )
|
std::string SHADER::ReadSource( std::string aShaderSourceName )
|
||||||
{
|
{
|
||||||
// Open the shader source for reading
|
// Open the shader source for reading
|
||||||
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
|
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
|
||||||
|
@ -231,7 +220,8 @@ std::string SHADER::readSource( std::string aShaderSourceName )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderType )
|
bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char* const * aArray,
|
||||||
|
size_t aSize )
|
||||||
{
|
{
|
||||||
assert( !isShaderLinked );
|
assert( !isShaderLinked );
|
||||||
|
|
||||||
|
@ -249,18 +239,10 @@ bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderTyp
|
||||||
// Get the program info
|
// Get the program info
|
||||||
programInfo( programNumber );
|
programInfo( programNumber );
|
||||||
|
|
||||||
// Copy to char array
|
// Attach the sources
|
||||||
char* source = new char[aShaderSource.size() + 1];
|
glShaderSource( shaderNumber, aSize, aArray, NULL );
|
||||||
strncpy( source, aShaderSource.c_str(), aShaderSource.size() + 1 );
|
|
||||||
const char** source_ = (const char**) ( &source );
|
|
||||||
|
|
||||||
// Attach the source
|
|
||||||
glShaderSource( shaderNumber, 1, source_, NULL );
|
|
||||||
programInfo( programNumber );
|
programInfo( programNumber );
|
||||||
|
|
||||||
// Delete the allocated char array
|
|
||||||
delete[] source;
|
|
||||||
|
|
||||||
// Compile and attach shader to the program
|
// Compile and attach shader to the program
|
||||||
glCompileShader( shaderNumber );
|
glCompileShader( shaderNumber );
|
||||||
GLint status;
|
GLint status;
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013-2016 CERN
|
|
||||||
* Copyright (C) 2016 Kicad Developers, see authors.txt for contributors.
|
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
// Multi-channel signed distance field
|
|
||||||
#define USE_MSDF
|
|
||||||
|
|
||||||
// Shader types
|
|
||||||
const float SHADER_LINE = 1.0;
|
|
||||||
const float SHADER_FILLED_CIRCLE = 2.0;
|
|
||||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
|
||||||
const float SHADER_FONT = 4.0;
|
|
||||||
|
|
||||||
varying vec4 shaderParams;
|
|
||||||
varying vec2 circleCoords;
|
|
||||||
uniform sampler2D fontTexture;
|
|
||||||
|
|
||||||
// Needed to reconstruct the mipmap level / texel derivative
|
|
||||||
uniform int fontTextureWidth;
|
|
||||||
|
|
||||||
void filledCircle( vec2 aCoord )
|
|
||||||
{
|
|
||||||
if( dot( aCoord, aCoord ) < 1.0 )
|
|
||||||
gl_FragColor = gl_Color;
|
|
||||||
else
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void strokedCircle( vec2 aCoord, float aRadius, float aWidth )
|
|
||||||
{
|
|
||||||
float outerRadius = aRadius + ( aWidth / 2 );
|
|
||||||
float innerRadius = aRadius - ( aWidth / 2 );
|
|
||||||
float relWidth = innerRadius / outerRadius;
|
|
||||||
|
|
||||||
if( ( dot( aCoord, aCoord ) < 1.0 ) &&
|
|
||||||
( dot( aCoord, aCoord ) > relWidth * relWidth ) )
|
|
||||||
gl_FragColor = gl_Color;
|
|
||||||
else
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_MSDF
|
|
||||||
float median( vec3 v )
|
|
||||||
{
|
|
||||||
return max( min( v.r, v.g ), min( max( v.r, v.g ), v.b ) );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if( shaderParams[0] == SHADER_FILLED_CIRCLE )
|
|
||||||
{
|
|
||||||
filledCircle( circleCoords );
|
|
||||||
}
|
|
||||||
else if( shaderParams[0] == SHADER_STROKED_CIRCLE )
|
|
||||||
{
|
|
||||||
strokedCircle( circleCoords, shaderParams[2], shaderParams[3] );
|
|
||||||
}
|
|
||||||
else if( shaderParams[0] == SHADER_FONT )
|
|
||||||
{
|
|
||||||
vec2 tex = shaderParams.yz;
|
|
||||||
|
|
||||||
// Unless we're streching chars it is okay to consider
|
|
||||||
// one derivative for filtering
|
|
||||||
float derivative = length( dFdx( tex ) ) * fontTextureWidth / 4;
|
|
||||||
|
|
||||||
#ifdef USE_MSDF
|
|
||||||
float dist = median( texture2D( fontTexture, tex ).rgb );
|
|
||||||
#else
|
|
||||||
float dist = texture2D( fontTexture, tex ).r;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// use the derivative for zoom-adaptive filtering
|
|
||||||
float alpha = smoothstep( 0.5 - derivative, 0.5 + derivative, dist );
|
|
||||||
|
|
||||||
gl_FragColor = vec4( gl_Color.rgb, alpha );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Simple pass-through
|
|
||||||
gl_FragColor = gl_Color;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013-2016 CERN
|
|
||||||
* @author Maciej Suminski <maciej.suminski@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
|
|
||||||
|
|
||||||
// Shader types
|
|
||||||
const float SHADER_LINE = 1.0;
|
|
||||||
const float SHADER_FILLED_CIRCLE = 2.0;
|
|
||||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
|
||||||
const float SHADER_FONT = 4.0;
|
|
||||||
|
|
||||||
// Minimum line width
|
|
||||||
const float MIN_WIDTH = 1.0;
|
|
||||||
|
|
||||||
attribute vec4 attrShaderParams;
|
|
||||||
varying vec4 shaderParams;
|
|
||||||
varying vec2 circleCoords;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// Pass attributes to the fragment shader
|
|
||||||
shaderParams = attrShaderParams;
|
|
||||||
|
|
||||||
if( shaderParams[0] == SHADER_LINE )
|
|
||||||
{
|
|
||||||
float lineWidth = shaderParams[3];
|
|
||||||
float worldScale = abs( gl_ModelViewMatrix[0][0] );
|
|
||||||
|
|
||||||
// Make lines appear to be at least 1 pixel wide
|
|
||||||
if( worldScale * lineWidth < MIN_WIDTH )
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix *
|
|
||||||
( gl_Vertex + vec4( shaderParams.yz * MIN_WIDTH / ( worldScale * lineWidth ), 0.0, 0.0 ) );
|
|
||||||
else
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix *
|
|
||||||
( gl_Vertex + vec4( shaderParams.yz, 0.0, 0.0 ) );
|
|
||||||
}
|
|
||||||
else if( ( shaderParams[0] == SHADER_STROKED_CIRCLE ) ||
|
|
||||||
( shaderParams[0] == SHADER_FILLED_CIRCLE ) )
|
|
||||||
{
|
|
||||||
// Compute relative circle coordinates basing on indices
|
|
||||||
// Circle
|
|
||||||
if( shaderParams[1] == 1.0 )
|
|
||||||
circleCoords = vec2( -sqrt( 3.0 ), -1.0 );
|
|
||||||
else if( shaderParams[1] == 2.0 )
|
|
||||||
circleCoords = vec2( sqrt( 3.0 ), -1.0 );
|
|
||||||
else if( shaderParams[1] == 3.0 )
|
|
||||||
circleCoords = vec2( 0.0, 2.0 );
|
|
||||||
|
|
||||||
// Semicircle
|
|
||||||
else if( shaderParams[1] == 4.0 )
|
|
||||||
circleCoords = vec2( -3.0 / sqrt( 3.0 ), 0.0 );
|
|
||||||
else if( shaderParams[1] == 5.0 )
|
|
||||||
circleCoords = vec2( 3.0 / sqrt( 3.0 ), 0.0 );
|
|
||||||
else if( shaderParams[1] == 6.0 )
|
|
||||||
circleCoords = vec2( 0.0, 2.0 );
|
|
||||||
|
|
||||||
// Make the line appear to be at least 1 pixel wide
|
|
||||||
float lineWidth = shaderParams[3];
|
|
||||||
float worldScale = abs( gl_ModelViewMatrix[0][0] );
|
|
||||||
|
|
||||||
if( worldScale * lineWidth < MIN_WIDTH )
|
|
||||||
shaderParams[3] = shaderParams[3] / ( worldScale * lineWidth );
|
|
||||||
|
|
||||||
gl_Position = ftransform();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Pass through the coordinates like in the fixed pipeline
|
|
||||||
gl_Position = ftransform();
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FrontColor = gl_Color;
|
|
||||||
}
|
|
|
@ -46,6 +46,21 @@ enum SHADER_TYPE
|
||||||
SHADER_TYPE_GEOMETRY = GL_GEOMETRY_SHADER ///< Geometry shader
|
SHADER_TYPE_GEOMETRY = GL_GEOMETRY_SHADER ///< Geometry shader
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace DETAIL {
|
||||||
|
|
||||||
|
inline const char* translateStringArg( const std::string& str )
|
||||||
|
{
|
||||||
|
return str.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* translateStringArg( const char* str )
|
||||||
|
{
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class SHADER provides the access to the OpenGL shaders.
|
* @brief Class SHADER provides the access to the OpenGL shaders.
|
||||||
*
|
*
|
||||||
|
@ -71,13 +86,19 @@ public:
|
||||||
virtual ~SHADER();
|
virtual ~SHADER();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads one of the built-in shaders and compiles it.
|
* @brief Add a shader and compile the shader sources.
|
||||||
*
|
*
|
||||||
* @param aShaderNumber is the shader number (indexing from 0).
|
* @param aArgs is the list of strings (std::string or convertible to const char*) which
|
||||||
|
are concatenated and compiled as a single shader source code.
|
||||||
* @param aShaderType is the type of the shader.
|
* @param aShaderType is the type of the shader.
|
||||||
* @return True in case of success, false otherwise.
|
* @return True in case of success, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool LoadBuiltinShader( unsigned int aShaderNumber, SHADER_TYPE aShaderType );
|
template< typename... Args >
|
||||||
|
bool LoadShaderFromStrings( SHADER_TYPE aShaderType, Args&&... aArgs )
|
||||||
|
{
|
||||||
|
const char* arr[] = { DETAIL::translateStringArg( aArgs )... };
|
||||||
|
return loadShaderFromStringArray( aShaderType, arr, sizeof...(Args) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads one of the built-in shaders and compiles it.
|
* @brief Loads one of the built-in shaders and compiles it.
|
||||||
|
@ -86,7 +107,7 @@ public:
|
||||||
* @param aShaderType is the type of the shader.
|
* @param aShaderType is the type of the shader.
|
||||||
* @return True in case of success, false otherwise.
|
* @return True in case of success, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool LoadShaderFromFile( const std::string& aShaderSourceName, SHADER_TYPE aShaderType );
|
bool LoadShaderFromFile( SHADER_TYPE aShaderType, const std::string& aShaderSourceName );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Link the shaders.
|
* @brief Link the shaders.
|
||||||
|
@ -170,8 +191,22 @@ public:
|
||||||
*/
|
*/
|
||||||
int GetAttribute( std::string aAttributeName ) const;
|
int GetAttribute( std::string aAttributeName ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the shader source file
|
||||||
|
*
|
||||||
|
* @param aShaderSourceName is the shader source file name.
|
||||||
|
* @return the source as string
|
||||||
|
*/
|
||||||
|
static std::string ReadSource( std::string aShaderSourceName );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compile vertex of fragment shader source code into the program.
|
||||||
|
*/
|
||||||
|
bool loadShaderFromStringArray( SHADER_TYPE aShaderType, const char * const * aArray,
|
||||||
|
size_t aSize );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the shader program information.
|
* @brief Get the shader program information.
|
||||||
*
|
*
|
||||||
|
@ -186,23 +221,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void shaderInfo( GLuint aShader );
|
void shaderInfo( GLuint aShader );
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read the shader source file
|
|
||||||
*
|
|
||||||
* @param aShaderSourceName is the shader source file name.
|
|
||||||
* @return the source as string
|
|
||||||
*/
|
|
||||||
std::string readSource( std::string aShaderSourceName );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add a shader and compile the shader sources.
|
|
||||||
*
|
|
||||||
* @param aShaderSource is the shader source content.
|
|
||||||
* @param aShaderType is the type of the shader.
|
|
||||||
* @return True in case of success, false otherwise.
|
|
||||||
*/
|
|
||||||
bool addSource( const std::string& aShaderSource, SHADER_TYPE aShaderType );
|
|
||||||
|
|
||||||
std::deque<GLuint> shaderNumbers; ///< Shader number list
|
std::deque<GLuint> shaderNumbers; ///< Shader number list
|
||||||
GLuint programNumber; ///< Shader program number
|
GLuint programNumber; ///< Shader program number
|
||||||
bool isProgramCreated; ///< Flag for program creation
|
bool isProgramCreated; ///< Flag for program creation
|
||||||
|
|
Loading…
Reference in New Issue