SuperimposeMesh
All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
Shader.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2019 Istituto Italiano di Tecnologia (IIT)
3  *
4  * This software may be modified and distributed under the terms of the
5  * BSD 3-Clause license. See the accompanying LICENSE file for details.
6  */
7 
9 
10 #include <cmrc/cmrc.hpp>
11 CMRC_DECLARE(shader);
12 
13 #include <fstream>
14 #include <sstream>
15 #include <iostream>
16 
17 
18 Shader::Shader(const std::string& vertex_shader_path, const std::string& fragment_shader_path)
19 {
20  std::string sourcecode_vertex_shader;
21  std::string sourcecode_fragmentshader;
22 
23  /* Retrieve the vertex/fragment source code from path. */
24  try
25  {
26  auto cmrc_fs = cmrc::shader::get_filesystem();
27 
28  if (cmrc_fs.exists(vertex_shader_path) && cmrc_fs.is_file(vertex_shader_path) &&
29  cmrc_fs.exists(fragment_shader_path) && cmrc_fs.is_file(fragment_shader_path))
30  {
31  auto vertex_shader_cmrc_file = cmrc_fs.open(vertex_shader_path);
32  sourcecode_vertex_shader.assign(vertex_shader_cmrc_file.cbegin(), vertex_shader_cmrc_file.cend());
33 
34 
35  auto fragment_shader_cmrc_file = cmrc_fs.open(fragment_shader_path);
36  sourcecode_fragmentshader.assign(fragment_shader_cmrc_file.cbegin(), fragment_shader_cmrc_file.cend());
37  }
38  else
39  {
40  std::ifstream file_vertex_shader;
41  file_vertex_shader.exceptions(std::ifstream::badbit);
42 
43  file_vertex_shader.open(vertex_shader_path);
44 
45  std::stringstream vertex_shader_stream;
46  vertex_shader_stream << file_vertex_shader.rdbuf();
47 
48  file_vertex_shader.close();
49 
50 
51  std::ifstream file_fragment_shader;
52  file_fragment_shader.exceptions(std::ifstream::badbit);
53 
54  file_fragment_shader.open(fragment_shader_path);
55 
56  std::stringstream fragment_shader_stream;
57  fragment_shader_stream << file_fragment_shader.rdbuf();
58 
59  file_fragment_shader.close();
60 
61 
62  sourcecode_vertex_shader = vertex_shader_stream.str();
63  sourcecode_fragmentshader = fragment_shader_stream.str();
64  }
65  }
66  catch (const std::ifstream::failure& e)
67  {
68  throw std::runtime_error("ERROR::SHADER::CTOR\nERROR:\n\tCould not read shader source code.\n" + std::string(e.what()));
69  }
70 
71 
72  /* Compile shaders. */
73  const GLchar* ptr_sourcecode_vertex_shader = sourcecode_vertex_shader.c_str();
74  const GLchar* ptr_sourcecode_fragment_shader = sourcecode_fragmentshader.c_str();
75 
76  GLuint vertex;
77  GLuint fragment;
78  GLint success;
79  GLchar info_log[512];
80 
81  /* Vertex Shader. */
82  vertex = glCreateShader(GL_VERTEX_SHADER);
83  glShaderSource(vertex, 1, &ptr_sourcecode_vertex_shader, NULL);
84  glCompileShader(vertex);
85 
86  /* Print compile errors if any. */
87  glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
88  if (!success)
89  {
90  glGetShaderInfoLog(vertex, 512, NULL, info_log);
91  throw std::runtime_error("ERROR::SHADER::CTOR\nERROR:\n\tVertex shader program compilation error.\nLOG:\n\t" + std::string(info_log));
92  };
93 
94 
95  /* Fragment Shader. */
96  fragment = glCreateShader(GL_FRAGMENT_SHADER);
97  glShaderSource(fragment, 1, &ptr_sourcecode_fragment_shader, NULL);
98  glCompileShader(fragment);
99 
100  /* Print compile errors if any. */
101  glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
102  if (!success)
103  {
104  glGetShaderInfoLog(vertex, 512, NULL, info_log);
105  throw std::runtime_error("ERROR::SHADER::CTOR\nERROR:\n\tFragment shader program compilation error.\nLOG:\n\t" + std::string(info_log));
106  };
107 
108 
109  /* Shader Program. */
110  shader_program_id_ = glCreateProgram();
111  glAttachShader(shader_program_id_, vertex);
112  glAttachShader(shader_program_id_, fragment);
113  glLinkProgram(shader_program_id_);
114 
115  /* Print linking errors if any. */
116  glGetProgramiv(shader_program_id_, GL_LINK_STATUS, &success);
117  if (!success)
118  {
119  glGetProgramInfoLog(shader_program_id_, 512, NULL, info_log);
120  throw std::runtime_error("ERROR::SHADER::CTOR\nERROR:\n\tShader program link fail.\nLOG:\n\t" + std::string(info_log));
121  }
122 
123  /* Delete the shaders as they're linked into our program now and no longer necessery. */
124  glDeleteShader(vertex);
125  glDeleteShader(fragment);
126 }
127 
128 
130 {
131  glUseProgram(shader_program_id_);
132 }
133 
134 
136 {
137  glUseProgram(0);
138 }
void install()
Activate the shader program.
Definition: Shader.cpp:129
Shader(const std::string &vertex_shader_path, const std::string &fragment_shader_path)
Create a shader program with given vertex and fragment shader paths.
Definition: Shader.cpp:18
GLuint shader_program_id_
The program ID.
Definition: Shader.h:45
CMRC_DECLARE(shader)
void uninstall()
Deactivate the shader program.
Definition: Shader.cpp:135