MRPT  2.0.1
Shader.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 #include <mrpt/opengl/Shader.h>
13 #include <mrpt/opengl/opengl_api.h>
14 #include <iostream>
15 
16 using namespace std;
17 using namespace mrpt;
18 using namespace mrpt::opengl;
19 
20 // ============ Shader ============
21 Shader::~Shader() { clear(); }
22 Shader& Shader::operator=(Shader&& o)
23 {
24  m_shader = o.m_shader;
25  o.m_shader = 0;
26  return *this;
27 }
28 Shader::Shader(Shader&& o)
29 {
30  m_shader = o.m_shader;
31  o.m_shader = 0;
32 }
33 
35 {
36  if (!m_shader) return; // Nothing to do
37 #if MRPT_HAS_OPENGL_GLUT
38  glDeleteShader(m_shader);
39  m_shader = 0;
40 #endif
41 }
42 
43 bool Shader::compile(
44  unsigned int type, const std::string& shaderCode,
45  mrpt::optional_ref<std::string> outErrorMessages)
46 {
47 #if MRPT_HAS_OPENGL_GLUT
48  clear();
49 
50  m_shader = glCreateShader(static_cast<GLenum>(type));
51 
52  const GLchar* source = shaderCode.c_str();
53  const GLint length = shaderCode.size();
54 
55  glShaderSource(m_shader, 1, &source, &length);
56  glCompileShader(m_shader);
57 
58  GLint shader_ok;
59  glGetShaderiv(m_shader, GL_COMPILE_STATUS, &shader_ok);
60  if (!shader_ok)
61  {
62  GLint log_length;
63  std::string log;
64  glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &log_length);
65  log.resize(log_length);
66  glGetShaderInfoLog(m_shader, log_length, NULL, &log[0]);
67 
68  if (outErrorMessages)
69  outErrorMessages.value().get() = std::move(log);
70  else
71  std::cerr << "[Shader::compile] Compile error: " << log << "\n";
72 
73  glDeleteShader(m_shader);
74  m_shader = 0;
75  return false; // error
76  }
77 
78  return true; // ok
79 #else
80  THROW_EXCEPTION("MRPT built without OpenGL support.");
81 #endif
82 }
83 
84 // ========= Program =============
85 Program::~Program() { clear(); }
86 
88 {
89  if (!m_program) return;
90 
91 #if MRPT_HAS_OPENGL_GLUT
92  // 1) Detach shaders from program.
93  for (const Shader& s : m_shaders) glDetachShader(m_program, s.handle());
94 
95  // 2) Delete program.
96  glDeleteProgram(m_program);
97 
98  // 3) Delete shaders.
99  m_shaders.clear();
100 
101  // 4) Delete all variables:
102  m_uniforms.clear();
103  m_attribs.clear();
104 #endif
105 
106  m_program = 0;
107 }
108 
109 bool Program::linkProgram(
110  std::vector<Shader>& shaders,
111  mrpt::optional_ref<std::string> outErrorMessages)
112 {
113 #if MRPT_HAS_OPENGL_GLUT
114  clear();
115 
116  m_program = glCreateProgram();
117  ASSERT_(m_program != 0);
118 
119  // Take ownership of shaders:
120  m_shaders = std::move(shaders);
121 
122  for (const auto& shader : m_shaders)
123  glAttachShader(m_program, shader.handle());
124 
125  glLinkProgram(m_program);
126  CHECK_OPENGL_ERROR();
127 
128  GLint program_ok;
129  glGetProgramiv(m_program, GL_LINK_STATUS, &program_ok);
130  if (!program_ok)
131  {
132  GLint log_length;
133  std::string log;
134  glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &log_length);
135  log.resize(log_length);
136  glGetProgramInfoLog(m_program, log_length, NULL, &log[0]);
137 
138  if (outErrorMessages)
139  outErrorMessages.value().get() = std::move(log);
140  else
141  std::cerr << "[Program::linkProgram] Link error: " << log << "\n";
142  clear();
143  return false; // error
144  }
145 
146  return true;
147 #else
148  THROW_EXCEPTION("MRPT built without OpenGL support.");
149 #endif
150 }
151 
152 void Program::declareUniform(const std::string& name)
153 {
154 #if MRPT_HAS_OPENGL_GLUT
155  ASSERT_(!empty());
156 
157  if (m_uniforms.count(name) != 0)
159  "declareUniform: Name `%s` already registered", name.c_str());
160 
161  const auto ret = glGetUniformLocation(
162  m_program, static_cast<const GLchar*>(name.c_str()));
163  if (ret < 0)
165  "declareUniform: glGetUniformLocation() returned error for `%s`",
166  name.c_str());
167  m_uniforms[name] = ret;
168 #else
169  THROW_EXCEPTION("MRPT built without OpenGL support.");
170 #endif
171 }
172 void Program::declareAttribute(const std::string& name)
173 {
174 #if MRPT_HAS_OPENGL_GLUT
175  ASSERT_(!empty());
176 
177  if (m_attribs.count(name) != 0)
179  "declareAttribute: Name `%s` already registered", name.c_str());
180 
181  const auto ret = glGetAttribLocation(
182  m_program, static_cast<const GLchar*>(name.c_str()));
183  if (ret < 0)
185  "declareAttribute: glGetAttribLocation() returned error for `%s`",
186  name.c_str());
187  m_attribs[name] = ret;
188 
189 #else
190  THROW_EXCEPTION("MRPT built without OpenGL support.");
191 #endif
192 }
193 
194 void Program::dumpProgramDescription(std::ostream& o) const
195 {
196 #if MRPT_HAS_OPENGL_GLUT
197  ASSERT_(!empty());
198 
199  GLint count;
200 
201  GLint size; // size of the variable
202  GLenum type; // type of the variable (float, vec3 or mat4, etc)
203 
204  const GLsizei bufSize = 32; // maximum name length
205  GLchar name[bufSize]; // variable name in GLSL
206  GLsizei length; // name length
207 
208  // Attributes
209  glGetProgramiv(m_program, GL_ACTIVE_ATTRIBUTES, &count);
210  o << mrpt::format("Active Attributes: %d\n", count);
211 
212  for (GLint i = 0; i < count; i++)
213  {
214  glGetActiveAttrib(
215  m_program, (GLuint)i, bufSize, &length, &size, &type, name);
216 
217  o << mrpt::format("Attribute #%d Type: %u Name: %s\n", i, type, name);
218  }
219 
220  // Uniforms
221  glGetProgramiv(m_program, GL_ACTIVE_UNIFORMS, &count);
222  printf("Active Uniforms: %d\n", count);
223 
224  for (GLint i = 0; i < count; i++)
225  {
226  glGetActiveUniform(
227  m_program, (GLuint)i, bufSize, &length, &size, &type, name);
228 
229  o << mrpt::format("Uniform #%d Type: %u Name: %s\n", i, type, name);
230  }
231 #endif
232 }
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
size_t size(const MATRIXLIKE &m, const int dim)
STL namespace.
std::optional< std::reference_wrapper< T > > optional_ref
Shorter name for std::optional<std::reference_wrapper<T>>
Definition: optional_ref.h:20
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
A resource handling helper for OpenGL "Shader" compiled code fragment.
Definition: Shader.h:37
unsigned int m_shader
Definition: Shader.h:66
bool empty() const
Definition: ts_hash_map.h:191
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:69
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:183



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020