Vis 2 Demo  1.0
Technical illustration type real-time rendering of geometry
 All Classes Namespaces Files Functions Variables Typedefs Macros
Shader.cpp
Go to the documentation of this file.
1 #include "Shader.h"
2 #include <iostream>
3 #include <fstream>
4 
5 using namespace vis2;
6 
7 Shader::Shader(const std::string& _vertexShader,
8  const std::string& _fragmentShader)
9  : program_handle(0), vertex_shader_handle(0), fragment_shader_handle(0), shader_in_use(false)
10 {
11  // initialize a program handle
12  this->program_handle = glCreateProgram();
13  if (this->program_handle == 0)
14  {
15  std::cout << "Could not create shader program!" << std::endl;
16  system("PAUSE");
17  exit(-1);
18  }
19 
20  // load vertex and fragment shader
21  loadShader(_vertexShader,GL_VERTEX_SHADER,this->vertex_shader_handle);
22  loadShader(_fragmentShader,GL_FRAGMENT_SHADER,this->fragment_shader_handle);
23 
24  // link the shaders to a complete program
25  link();
26 
27 }
28 
30 {
31  glDeleteProgram(this->program_handle);
32  glDeleteShader(this->vertex_shader_handle);
33  glDeleteShader(this->fragment_shader_handle);
34 }
35 
37 {
38  glUseProgram(this->program_handle);
39  shader_in_use = true;
40 }
41 
43 {
44  glUseProgram(0);
45  shader_in_use = false;
46 }
47 
48 void Shader::loadShader(const std::string& _path_to_shader,
49  GLenum _shaderType,
50  GLuint& _shaderHandle)
51 {
52  std::ifstream shader_file(_path_to_shader);
53  if (shader_file.good())
54  {
55  // read the entire file content (shortes version of this preocedure)
56  std::string str_code = std::string( std::istreambuf_iterator<char>(shader_file),
57  std::istreambuf_iterator<char>());
58  shader_file.close();
59 
60  // initialize the shader handle
61  _shaderHandle = glCreateShader(_shaderType);
62  if (_shaderHandle == 0)
63  {
64  std::cout << "Failed to create shader handle!" << std::endl;
65  system("PAUSE");
66  exit(-1);
67  }
68 
69  // transfer shader code to the GK
70  const char* code_Ptr = str_code.c_str();
71  glShaderSource(_shaderHandle,1,&code_Ptr,NULL);
72  glCompileShader(_shaderHandle);
73 
74  // check for compile errors
75  GLint success;
76  glGetShaderiv(_shaderHandle,GL_COMPILE_STATUS,&success);
77  if (success == GL_FALSE || !glIsShader(_shaderHandle))
78  {
79  // read the compiler log and print on stdout
80  GLint log_size;
81  glGetShaderiv(_shaderHandle,GL_INFO_LOG_LENGTH,&log_size);
82  GLchar* log_content_Ptr = new char[log_size];
83 
84  glGetShaderInfoLog(_shaderHandle,log_size,NULL,log_content_Ptr);
85  std::cout << "Failed to compile shader:\n" << log_content_Ptr << std::endl;
86  system("PAUSE");
87  delete [] log_content_Ptr;
88  exit(-1);
89 
90  }
91 
92  }
93  else
94  {
95  std::cout << "Failed to open shader source code file \"" << _path_to_shader << "\" !" << std::endl;
96  system("PAUSE");
97  exit(-1);
98  }
99 
100 }
101 
102 
104 {
105  // attach the shader to the program
106  glAttachShader(this->program_handle,this->vertex_shader_handle);
107  glAttachShader(this->program_handle,this->fragment_shader_handle);
108 
109  // bind output (frag data location)
110  glBindFragDataLocation(this->program_handle,0,"fragColor");
111 
112  // link
113  glLinkProgram(this->program_handle);
114 
115  // check for errors
116  GLint success;
117  glGetProgramiv(this->program_handle,GL_LINK_STATUS,&success);
118 
119  if (!success) // anything other than ZERO
120  {
121  // read the compiler log and print on stdout
122  GLint log_size;
123  glGetProgramiv(this->program_handle,GL_INFO_LOG_LENGTH,&log_size);
124 
125  GLchar* log_content_Ptr = new char[log_size];
126  glGetProgramInfoLog(this->program_handle,log_size,NULL,log_content_Ptr);
127 
128  std::cout << "Failed to link shader program:\n" << log_content_Ptr << std::endl;
129  system("PAUSE");
130  delete [] log_content_Ptr;
131  exit(-1);
132  }
133 
134 }