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 if( active )
54 Deactivate();
55
57 {
58 if( glIsShader )
59 {
60 // Delete the shaders and the program
61 for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end();
62 ++it )
63 {
64 GLuint shader = *it;
65
66 if( glIsShader( shader ) )
67 {
68 glDetachShader( programNumber, shader );
69 glDeleteShader( shader );
70 }
71 }
72
73 glDeleteProgram( programNumber );
74 }
75 }
76}
77
78
79bool SHADER::LoadShaderFromFile( SHADER_TYPE aShaderType, const std::string& aShaderSourceName )
80{
81 // Load shader sources
82 const std::string shaderSource = ReadSource( aShaderSourceName );
83
84 return LoadShaderFromStrings( aShaderType, shaderSource );
85}
86
87
88void SHADER::ConfigureGeometryShader( GLuint maxVertices, GLuint geometryInputType,
89 GLuint geometryOutputType )
90{
91 maximumVertices = maxVertices;
92 geomInputType = geometryInputType;
93 geomOutputType = geometryOutputType;
94}
95
96
98{
99 // Shader linking
100 glLinkProgram( programNumber );
102
103 // Check the Link state
104 GLint tmp;
105 glGetProgramiv( programNumber, GL_LINK_STATUS, &tmp );
106 isShaderLinked = !!tmp;
107
108#ifdef DEBUG
109 if( !isShaderLinked )
110 {
111 int maxLength;
112 glGetProgramiv( programNumber, GL_INFO_LOG_LENGTH, &maxLength );
113 maxLength = maxLength + 1;
114 char* linkInfoLog = new char[maxLength];
115 glGetProgramInfoLog( programNumber, maxLength, &maxLength, linkInfoLog );
116 std::cerr << "Shader linking error:" << std::endl;
117 std::cerr << linkInfoLog;
118 delete[] linkInfoLog;
119 }
120#endif /* DEBUG */
121
122 return isShaderLinked;
123}
124
125
126int SHADER::AddParameter( const std::string& aParameterName )
127{
128 GLint location = glGetUniformLocation( programNumber, aParameterName.c_str() );
129
130 if( location >= 0 )
131 parameterLocation.push_back( location );
132 else
133 throw std::runtime_error( "Could not find shader uniform: " + aParameterName );
134
135 return static_cast<int>( parameterLocation.size() ) - 1;
136}
137
138
139void SHADER::SetParameter( int parameterNumber, float value ) const
140{
141 assert( (unsigned) parameterNumber < parameterLocation.size() );
142
143 glUniform1f( parameterLocation[parameterNumber], value );
144}
145
146
147void SHADER::SetParameter( int parameterNumber, int value ) const
148{
149 assert( (unsigned) parameterNumber < parameterLocation.size() );
150
151 glUniform1i( parameterLocation[parameterNumber], value );
152}
153
154
155void SHADER::SetParameter( int parameterNumber, float f0, float f1, float f2, float f3 ) const
156{
157 assert( (unsigned) parameterNumber < parameterLocation.size() );
158 float arr[4] = { f0, f1, f2, f3 };
159 glUniform4fv( parameterLocation[parameterNumber], 1, arr );
160}
161
162
163void SHADER::SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const
164{
165 assert( (unsigned) aParameterNumber < parameterLocation.size() );
166 glUniform2f( parameterLocation[aParameterNumber], static_cast<GLfloat>( aValue.x ),
167 static_cast<GLfloat>( aValue.y ) );
168}
169
170
171int SHADER::GetAttribute( const std::string& aAttributeName ) const
172{
173 return glGetAttribLocation( programNumber, aAttributeName.c_str() );
174}
175
176
177void SHADER::programInfo( GLuint aProgram )
178{
179 GLint glInfoLogLength = 0;
180 GLint writtenChars = 0;
181
182 // Get the length of the info string
183 glGetProgramiv( aProgram, GL_INFO_LOG_LENGTH, &glInfoLogLength );
184
185 // Print the information
186 if( glInfoLogLength > 2 )
187 {
188 GLchar* glInfoLog = new GLchar[glInfoLogLength];
189 glGetProgramInfoLog( aProgram, glInfoLogLength, &writtenChars, glInfoLog );
190
191 delete[] glInfoLog;
192 }
193}
194
195
196void SHADER::shaderInfo( GLuint aShader )
197{
198 GLint glInfoLogLength = 0;
199 GLint writtenChars = 0;
200
201 // Get the length of the info string
202 glGetShaderiv( aShader, GL_INFO_LOG_LENGTH, &glInfoLogLength );
203
204 // Print the information
205 if( glInfoLogLength > 2 )
206 {
207 GLchar* glInfoLog = new GLchar[glInfoLogLength];
208 glGetShaderInfoLog( aShader, glInfoLogLength, &writtenChars, glInfoLog );
209
210 delete[] glInfoLog;
211 }
212}
213
214
215std::string SHADER::ReadSource( const std::string& aShaderSourceName )
216{
217 // Open the shader source for reading
218 std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
219 std::string shaderSource;
220
221 if( !inputFile )
222 throw std::runtime_error( "Can't read the shader source: " + aShaderSourceName );
223
224 std::string shaderSourceLine;
225
226 // Read all lines from the text file
227 while( getline( inputFile, shaderSourceLine ) )
228 {
229 shaderSource += shaderSourceLine;
230 shaderSource += "\n";
231 }
232
233 return shaderSource;
234}
235
236
237bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char** aArray, size_t aSize )
238{
239 assert( !isShaderLinked );
240
241 // Create the program
242 if( !isProgramCreated )
243 {
244 programNumber = glCreateProgram();
245 isProgramCreated = true;
246 }
247
248 // Create a shader
249 GLuint shaderNumber = glCreateShader( aShaderType );
250 shaderNumbers.push_back( shaderNumber );
251
252 // Get the program info
254
255 // Attach the sources
256 glShaderSource( shaderNumber, static_cast<GLsizei>( aSize ), (const GLchar**) aArray, nullptr );
258
259 // Compile and attach shader to the program
260 glCompileShader( shaderNumber );
261 GLint status;
262 glGetShaderiv( shaderNumber, GL_COMPILE_STATUS, &status );
263
264 if( status != GL_TRUE )
265 {
266 shaderInfo( shaderNumber );
267
268 GLint maxLength = 0;
269 glGetShaderiv( shaderNumber, GL_INFO_LOG_LENGTH, &maxLength );
270
271 // The maxLength includes the NULL character
272 std::vector<GLchar> errorLog( (size_t) maxLength );
273 glGetShaderInfoLog( shaderNumber, maxLength, &maxLength, &errorLog[0] );
274
275 // Provide the infolog in whatever manor you deem best.
276 // Exit with failure.
277 glDeleteShader( shaderNumber ); // Don't leak the shader.
278
279 throw std::runtime_error( &errorLog[0] );
280 }
281
282 glAttachShader( programNumber, shaderNumber );
284
285 // Special handling for the geometry shader
286 if( aShaderType == SHADER_TYPE_GEOMETRY )
287 {
288 if( GLAD_GL_ARB_geometry_shader4 || GLAD_GL_EXT_geometry_shader4 )
289 {
290 glProgramParameteri( programNumber, GL_GEOMETRY_VERTICES_OUT_EXT, maximumVertices );
291 glProgramParameteri( programNumber, GL_GEOMETRY_INPUT_TYPE_EXT, geomInputType );
292 glProgramParameteri( programNumber, GL_GEOMETRY_OUTPUT_TYPE_EXT, geomOutputType );
293 }
294 }
295 return true;
296}
GLuint geomOutputType
Definition shader.h:227
static std::string ReadSource(const std::string &aShaderSourceName)
Read the shader source file.
Definition shader.cpp:215
bool active
Is any of shaders used?
Definition shader.h:220
bool LoadShaderFromFile(SHADER_TYPE aShaderType, const std::string &aShaderSourceName)
Load one of the built-in shaders and compiles it.
Definition shader.cpp:79
bool isProgramCreated
Flag for program creation.
Definition shader.h:218
std::deque< GLuint > shaderNumbers
Shader number list.
Definition shader.h:216
void SetParameter(int aParameterNumber, float aValue) const
Set a parameter of the shader.
Definition shader.cpp:139
GLuint geomInputType
Output type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.].
Definition shader.h:224
bool loadShaderFromStringArray(SHADER_TYPE aShaderType, const char **aArray, size_t aSize)
Compile vertex of fragment shader source code into the program.
Definition shader.cpp:237
std::deque< GLint > parameterLocation
Location of the parameter.
Definition shader.h:228
GLuint programNumber
Shader program number.
Definition shader.h:217
bool Link()
Link the shaders.
Definition shader.cpp:97
bool isShaderLinked
Is the shader linked?
Definition shader.h:219
void ConfigureGeometryShader(GLuint maxVertices, GLuint geometryInputType, GLuint geometryOutputType)
Configure the geometry shader - has to be done before linking!
Definition shader.cpp:88
bool LoadShaderFromStrings(SHADER_TYPE aShaderType, Args &&... aArgs)
Add a shader and compile the shader sources.
Definition shader.h:89
void shaderInfo(GLuint aShader)
Get the shader information.
Definition shader.cpp:196
virtual ~SHADER()
Definition shader.cpp:51
void programInfo(GLuint aProgram)
Get the shader program information.
Definition shader.cpp:177
int AddParameter(const std::string &aParameterName)
Add a parameter to the parameter queue.
Definition shader.cpp:126
GLuint maximumVertices
The maximum of vertices to be generated.
Definition shader.h:221
int GetAttribute(const std::string &aAttributeName) const
Get an attribute location.
Definition shader.cpp:171
void Deactivate()
Deactivate the shader and use the default OpenGL program.
Definition shader.h:131
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:29
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:682