Molecule Viewer
 All Classes Functions Variables Enumerations Pages
Shader.cpp
1 #include <fstream>
2 
3 #include "Shader.hpp"
4 
5 //**************************************************//
6 // Initialize the shader
7 //**************************************************//
8 Shader::Shader(const string &path) : _success(false) {
9 
10  // Load the shader files
11  string vertex_shader_source;
12  if (FileExists(path+".vert")) {
13  vertex_shader_source = ReadFile(path+".vert");
14  } else {
15  cerr << "Vertex shader file "
16  << path <<".vert does not exist." << endl;
17  return;
18  }
19 
20  string fragment_shader_source;
21  if (FileExists(path+".frag")) {
22  fragment_shader_source = ReadFile(path+".frag");
23  } else {
24  cerr << "Fragment shader file " << path <<".frag does not exist." << endl;
25  return;
26  }
27 
28  string geometry_shader_source;
29  if (FileExists(path+".geom")) {
30  geometry_shader_source = ReadFile(path+".geom");
31  } else {
32  cerr << "Geometry shader file " << path <<".geom does not exist." << endl;
33  }
34 
35 
36  // Compile the shaders
37 
38  _vertex_shader = compile(GL_VERTEX_SHADER, vertex_shader_source);
39  if (_vertex_shader == 0)
40  return;
41  GetErrors();
42 
43  _fragment_shader = compile(GL_FRAGMENT_SHADER, fragment_shader_source);
44  if (_fragment_shader == 0)
45  return;
46  GetErrors();
47 
48  _geometry_shader = compile(GL_GEOMETRY_SHADER, geometry_shader_source);
49  if (_geometry_shader == 0)
50  return;
51  GetErrors();
52 
53  // Link the shaders into a program
54 
55  link();
56  if (_program == 0)
57  return;
58  GenerateAddresses();
59  _success = true;
60  GetErrors();
61 }
62 
63 //**************************************************//
64 // Free resources
65 //**************************************************//
67  glDeleteProgram(_program);
68  glDeleteShader(_vertex_shader);
69  glDeleteShader(_fragment_shader);
70  glDeleteShader(_geometry_shader);
71 }
72 
73 //**************************************************//
74 // Generate shader addresses
75 //**************************************************//
76 void Shader::GenerateAddresses(void) {
77 
78  _shaderAddresses[Shader::Position] = 0;
79  _shaderAddresses[Shader::Radius] = 1;
80  _shaderAddresses[Shader::Color] = 2;
81  _shaderAddresses[Shader::UVQuad] = 3;
82 
83  _shaderAddresses[Shader::ProjectionMatrix] = get_uniform_location("projectionMatrix");
84  _shaderAddresses[Shader::LightPosition] = get_uniform_location("lightPosition");
85  _shaderAddresses[Shader::OcclusionDirections] = get_uniform_location("numberOfDirections");
86  _shaderAddresses[Shader::OcclusionTexture] = get_uniform_location("textureMap");
87  _shaderAddresses[Shader::ModelViewMatrix] = get_uniform_location("modelViewMatrix");
88  _shaderAddresses[Shader::ShadowMVMatrix] = get_uniform_location("shadowMVMatrix");
89  _shaderAddresses[Shader::ShadowPMatrix] = get_uniform_location("shadowPMatrix");
90  _shaderAddresses[Shader::ContourData] = get_uniform_location("contourData");
91  _shaderAddresses[Shader::ShadowActive] = get_uniform_location("shadowActive");
92  _shaderAddresses[Shader::OcclusionActive] = get_uniform_location("occlusionActive");
93  _shaderAddresses[Shader::AmbientIntensity] = get_uniform_location("ambientIntensity");
94  _shaderAddresses[Shader::DirectIntensity] = get_uniform_location("directIntensity");
95  _shaderAddresses[Shader::Glossiness] = get_uniform_location("glossiness");
96  _shaderAddresses[Shader::ShadowTex] = get_uniform_location("shadowMap");
97  _shaderAddresses[Shader::FarPlane] = get_uniform_location("farPlane");
98 
99 
100 }
101 
102 //**************************************************//
103 // Returns the shader address
104 //**************************************************//
105 GLuint Shader::GetAddress(int address) {
106  return _shaderAddresses[address];
107 }
108 
109 GLuint Shader::compile (GLenum type, const string &source)
110 {
111  // Create shader object
112 
113  GLuint shader = glCreateShader(type);
114 
115  if (shader == 0) {
116  cerr << "Could not create shader object." << endl;
117  return 0;
118  }
119 
120  // Define shader source and compile
121 
122  const char* src = source.data();
123  int len = source.size();
124 
125  glShaderSource(shader, 1, &src, &len);
126 
127  glCompileShader(shader);
128 
129  // Check for errors
130 
131  int status;
132 
133  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
134 
135  if (status != GL_TRUE) {
136  qDebug() << "Shader compilation failed." << endl;
137  shader_log(shader);
138  }
139 
140 
141  GetErrors();
142 
143  return shader;
144 }
145 
146 void Shader::link(void)
147 {
148  // Create program handle
149  _program = glCreateProgram();
150 
151  // Attach shaders and link
152 
153  glAttachShader(_program, _vertex_shader);
154  glAttachShader(_program, _fragment_shader);
155 
156  glAttachShader(_program, _geometry_shader);
157 
158  glLinkProgram(_program);
159 
160  // Check for problems
161 
162  int status;
163 
164  glGetProgramiv(_program, GL_LINK_STATUS, &status);
165 
166  if (status != GL_TRUE) {
167  qDebug() << "Shader linking failed." << endl;
168  program_log(_program);
169 
170  glDeleteProgram(_program);
171  _program = 0;
172  }
173 
174  GetErrors();
175 }
176 
177 #define LOG_BUFFER_SIZE 8096
178 
179 void Shader::program_log(GLuint program)
180 {
181  char logBuffer[LOG_BUFFER_SIZE];
182  GLsizei length;
183 
184  logBuffer[0] = '\0';
185  glGetProgramInfoLog(program, LOG_BUFFER_SIZE, &length,logBuffer);
186 
187  if (length > 0) {
188  qDebug() << logBuffer << endl;
189  }
190 };
191 
192 void Shader::shader_log(GLuint shader)
193 {
194  char logBuffer[LOG_BUFFER_SIZE];
195  GLsizei length;
196 
197  logBuffer[0] = '\0';
198  glGetShaderInfoLog(shader, LOG_BUFFER_SIZE, &length,logBuffer);
199 
200  if (length > 0) {
201  qDebug() << logBuffer << endl;
202  }
203 };