KiCad PCB EDA Suite
Loading...
Searching...
No Matches
shader.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * Graphics Abstraction Layer (GAL) for OpenGL
8 *
9 * Shader class
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
25#include <iostream>
26#include <fstream>
27#include <stdexcept>
28
29#include <cstring>
30#include <cassert>
31
32#include <gal/opengl/shader.h>
33#include <vector>
34
35using namespace KIGFX;
36
38 isProgramCreated( false ),
39 isShaderLinked( false ),
40 active( false ),
41 maximumVertices( 4 ),
42 geomInputType( GL_LINES ),
43 geomOutputType( GL_LINES )
44
45{
46 // Do not have uninitialized members:
47 programNumber = 0;
48}
49
50
52{
53 active = false;
54 isProgramCreated = false;
55 shaderNumbers.clear();
56}
57
58
60{
61 if( active )
62 Deactivate();
63
65 {
66 if( glIsShader )
67 {
68 // Delete the shaders and the program
69 for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end();
70 ++it )
71 {
72 GLuint shader = *it;
73
74 if( glIsShader( shader ) )
75 {
76 glDetachShader( programNumber, shader );
77 glDeleteShader( shader );
78 }
79 }
80
81 glDeleteProgram( programNumber );
82 }
83 }
84}
85
86
87bool SHADER::LoadShaderFromFile( SHADER_TYPE aShaderType, const std::string& aShaderSourceName )
88{
89 // Load shader sources
90 const std::string shaderSource = ReadSource( aShaderSourceName );
91
92 return LoadShaderFromStrings( aShaderType, shaderSource );
93}
94
95
96void SHADER::ConfigureGeometryShader( GLuint maxVertices, GLuint geometryInputType,
97 GLuint geometryOutputType )
98{
99 maximumVertices = maxVertices;
100 geomInputType = geometryInputType;
101 geomOutputType = geometryOutputType;
102}
103
104
106{
107 // Shader linking
108 glLinkProgram( programNumber );
110
111 // Check the Link state
112 GLint tmp;
113 glGetProgramiv( programNumber, GL_LINK_STATUS, &tmp );
114 isShaderLinked = !!tmp;
115
116#ifdef DEBUG
117 if( !isShaderLinked )
118 {
119 int maxLength;
120 glGetProgramiv( programNumber, GL_INFO_LOG_LENGTH, &maxLength );
121 maxLength = maxLength + 1;
122 char* linkInfoLog = new char[maxLength];
123 glGetProgramInfoLog( programNumber, maxLength, &maxLength, linkInfoLog );
124 std::cerr << "Shader linking error:" << std::endl;
125 std::cerr << linkInfoLog;
126 delete[] linkInfoLog;
127 }
128#endif /* DEBUG */
129
130 return isShaderLinked;
131}
132
133
134int SHADER::AddParameter( const std::string& aParameterName )
135{
136 GLint location = glGetUniformLocation( programNumber, aParameterName.c_str() );
137
138 if( location >= 0 )
139 parameterLocation.push_back( location );
140 else
141 throw std::runtime_error( "Could not find shader uniform: " + aParameterName );
142
143 return static_cast<int>( parameterLocation.size() ) - 1;
144}
145
146
147void SHADER::SetParameter( int parameterNumber, float value ) const
148{
149 assert( (unsigned) parameterNumber < parameterLocation.size() );
150
151 glUniform1f( parameterLocation[parameterNumber], value );
152}
153
154
155void SHADER::SetParameter( int parameterNumber, int value ) const
156{
157 assert( (unsigned) parameterNumber < parameterLocation.size() );
158
159 glUniform1i( parameterLocation[parameterNumber], value );
160}
161
162
163void SHADER::SetParameter( int parameterNumber, float f0, float f1, float f2, float f3 ) const
164{
165 assert( (unsigned) parameterNumber < parameterLocation.size() );
166 float arr[4] = { f0, f1, f2, f3 };
167 glUniform4fv( parameterLocation[parameterNumber], 1, arr );
168}
169
170
171void SHADER::SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const
172{
173 assert( (unsigned) aParameterNumber < parameterLocation.size() );
174 glUniform2f( parameterLocation[aParameterNumber], static_cast<GLfloat>( aValue.x ),
175 static_cast<GLfloat>( aValue.y ) );
176}
177
178
179int SHADER::GetAttribute( const std::string& aAttributeName ) const
180{
181 return glGetAttribLocation( programNumber, aAttributeName.c_str() );
182}
183
184
185void SHADER::programInfo( GLuint aProgram )
186{
187 GLint glInfoLogLength = 0;
188 GLint writtenChars = 0;
189
190 // Get the length of the info string
191 glGetProgramiv( aProgram, GL_INFO_LOG_LENGTH, &glInfoLogLength );
192
193 // Print the information
194 if( glInfoLogLength > 2 )
195 {
196 GLchar* glInfoLog = new GLchar[glInfoLogLength];
197 glGetProgramInfoLog( aProgram, glInfoLogLength, &writtenChars, glInfoLog );
198
199 delete[] glInfoLog;
200 }
201}
202
203
204void SHADER::shaderInfo( GLuint aShader )
205{
206 GLint glInfoLogLength = 0;
207 GLint writtenChars = 0;
208
209 // Get the length of the info string
210 glGetShaderiv( aShader, GL_INFO_LOG_LENGTH, &glInfoLogLength );
211
212 // Print the information
213 if( glInfoLogLength > 2 )
214 {
215 GLchar* glInfoLog = new GLchar[glInfoLogLength];
216 glGetShaderInfoLog( aShader, glInfoLogLength, &writtenChars, glInfoLog );
217
218 delete[] glInfoLog;
219 }
220}
221
222
223std::string SHADER::ReadSource( const std::string& aShaderSourceName )
224{
225 // Open the shader source for reading
226 std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
227 std::string shaderSource;
228
229 if( !inputFile )
230 throw std::runtime_error( "Can't read the shader source: " + aShaderSourceName );
231
232 std::string shaderSourceLine;
233
234 // Read all lines from the text file
235 while( getline( inputFile, shaderSourceLine ) )
236 {
237 shaderSource += shaderSourceLine;
238 shaderSource += "\n";
239 }
240
241 return shaderSource;
242}
243
244
245bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char** aArray, size_t aSize )
246{
247 assert( !isShaderLinked );
248
249 // Create the program
250 if( !isProgramCreated )
251 {
252 programNumber = glCreateProgram();
253 isProgramCreated = true;
254 }
255
256 // Create a shader
257 GLuint shaderNumber = glCreateShader( aShaderType );
258 shaderNumbers.push_back( shaderNumber );
259
260 // Get the program info
262
263 // Attach the sources
264 glShaderSource( shaderNumber, static_cast<GLsizei>( aSize ), (const GLchar**) aArray, nullptr );
266
267 // Compile and attach shader to the program
268 glCompileShader( shaderNumber );
269 GLint status;
270 glGetShaderiv( shaderNumber, GL_COMPILE_STATUS, &status );
271
272 if( status != GL_TRUE )
273 {
274 shaderInfo( shaderNumber );
275
276 GLint maxLength = 0;
277 glGetShaderiv( shaderNumber, GL_INFO_LOG_LENGTH, &maxLength );
278
279 // The maxLength includes the NULL character
280 std::vector<GLchar> errorLog( (size_t) maxLength );
281 glGetShaderInfoLog( shaderNumber, maxLength, &maxLength, &errorLog[0] );
282
283 // Provide the infolog in whatever manor you deem best.
284 // Exit with failure.
285 glDeleteShader( shaderNumber ); // Don't leak the shader.
286
287 throw std::runtime_error( &errorLog[0] );
288 }
289
290 glAttachShader( programNumber, shaderNumber );
292
293 // Special handling for the geometry shader
294 if( aShaderType == SHADER_TYPE_GEOMETRY )
295 {
296 if( GLAD_GL_ARB_geometry_shader4 || GLAD_GL_EXT_geometry_shader4 )
297 {
298 glProgramParameteri( programNumber, GL_GEOMETRY_VERTICES_OUT_EXT, maximumVertices );
299 glProgramParameteri( programNumber, GL_GEOMETRY_INPUT_TYPE_EXT, geomInputType );
300 glProgramParameteri( programNumber, GL_GEOMETRY_OUTPUT_TYPE_EXT, geomOutputType );
301 }
302 }
303 return true;
304}
GLuint geomOutputType
Output type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.].
Definition shader.h:235
static std::string ReadSource(const std::string &aShaderSourceName)
Read the shader source file.
Definition shader.cpp:223
bool active
Is any of shaders used?
Definition shader.h:228
bool LoadShaderFromFile(SHADER_TYPE aShaderType, const std::string &aShaderSourceName)
Load one of the built-in shaders and compiles it.
Definition shader.cpp:87
bool isProgramCreated
Flag for program creation.
Definition shader.h:226
std::deque< GLuint > shaderNumbers
Shader number list.
Definition shader.h:224
void Abandon()
Give up ownership of the program and shader objects without deleting them.
Definition shader.cpp:51
void SetParameter(int aParameterNumber, float aValue) const
Set a parameter of the shader.
Definition shader.cpp:147
GLuint geomInputType
Input type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.].
Definition shader.h:232
bool loadShaderFromStringArray(SHADER_TYPE aShaderType, const char **aArray, size_t aSize)
Compile vertex of fragment shader source code into the program.
Definition shader.cpp:245
std::deque< GLint > parameterLocation
Location of the parameter.
Definition shader.h:236
GLuint programNumber
Shader program number.
Definition shader.h:225
bool Link()
Link the shaders.
Definition shader.cpp:105
bool isShaderLinked
Is the shader linked?
Definition shader.h:227
void ConfigureGeometryShader(GLuint maxVertices, GLuint geometryInputType, GLuint geometryOutputType)
Configure the geometry shader - has to be done before linking!
Definition shader.cpp:96
bool LoadShaderFromStrings(SHADER_TYPE aShaderType, Args &&... aArgs)
Add a shader and compile the shader sources.
Definition shader.h:97
void shaderInfo(GLuint aShader)
Get the shader information.
Definition shader.cpp:204
virtual ~SHADER()
Definition shader.cpp:59
void programInfo(GLuint aProgram)
Get the shader program information.
Definition shader.cpp:185
int AddParameter(const std::string &aParameterName)
Add a parameter to the parameter queue.
Definition shader.cpp:134
GLuint maximumVertices
The maximum of vertices to be generated.
Definition shader.h:229
int GetAttribute(const std::string &aAttributeName) const
Get an attribute location.
Definition shader.cpp:179
void Deactivate()
Deactivate the shader and use the default OpenGL program.
Definition shader.h:139
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
SHADER_TYPE
Type definition for the shader.
Definition shader.h:41
@ SHADER_TYPE_GEOMETRY
Geometry shader.
Definition shader.h:44
VECTOR2I location
VECTOR2< double > VECTOR2D
Definition vector2d.h:707