zMol
A viewer for molecular data using OpenGL and ambient occlusion
molecule_renderer.hpp
1 /****************************************************************************
2 
3 Copyright (c) 2012 Carlos Rafael Giani ( email: dv xxx AT pseudoterminal xxx DOT xxx org , remove the xxx )
4 
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17 
18  2. Altered source versions must be plainly marked as such, and must not be
19  misrepresented as being the original software.
20 
21  3. This notice may not be removed or altered from any source
22  distribution.
23 
24 ****************************************************************************/
25 
26 
27 
28 #ifndef ZMOL_MOLECULE_RENDERER_HPP
29 #define ZMOL_MOLECULE_RENDERER_HPP
30 
31 #include <memory>
32 #include <functional>
33 #include "opengl3.hpp"
34 #include "glsl.hpp"
35 #include "buffer_object.hpp"
36 #include "vertex_array_object.hpp"
37 #include "molecule_data.hpp"
38 #include "noncopyable.hpp"
39 #include "texture.hpp"
40 #include "cml/cml.h"
41 
42 
43 namespace zmol
44 {
45 
46 
60  private noncopyable
61 {
62 public:
63  // Struct containing the GLSL program as well as GLSL uniform locations into that program.
64  struct program_data
65  {
66  program m_program;
67  GLint
68  m_model_view_uniform,
69  m_projection_uniform,
70  m_scale_factor_uniform,
71  m_texlen_uniform,
72  m_border_and_flatness_uniform,
73  m_lighting_params_uniform
74  ;
75 
76  // Constructor just sets the uniform locations to -1 (= "not initialized").
77  program_data();
78  };
79 
80 
86  explicit molecule_shaders(std::function < void(std::string const &p_errormsg) > const &p_errormsg_callback);
87 
88 
89  // The GLSL shaders and programs.
90  program_data
91  m_sphere_draw_to_screen,
92  m_sphere_draw_to_shadowmap,
93  m_sphere_draw_to_ao_atlas,
94  m_cylinder_draw_to_screen,
95  m_cylinder_draw_to_shadowmap,
96  m_cylinder_draw_to_ao_atlas
97  ;
98 };
99 
100 
114  private noncopyable
115 {
116 public:
123  {
127  };
128 
133  {
136  };
137 
138 
142  typedef cml::matrix44f_c matrix;
143 
144 
170  explicit molecule_renderer(
171  molecule_shaders &p_molecule_shaders,
172  molecule_data const &p_data,
173  unsigned int const p_initial_left_viewport_offset, unsigned int const p_initial_top_viewport_offset,
174  unsigned int const p_initial_viewport_width, unsigned int const p_initial_viewport_height,
175  unsigned int const p_initial_atlas_size,
176  float const p_initial_radius_scale = 1.0f,
177  rendering_modes const p_initial_rendering_mode = rendering_mode_space_filling,
178  atom_color_modes const p_initial_atom_color_mode = atom_color_mode_per_element
179  );
205  explicit molecule_renderer(
206  molecule_shaders &p_molecule_shaders,
207  molecule_data &&p_data,
208  unsigned int const p_initial_left_viewport_offset, unsigned int const p_initial_top_viewport_offset,
209  unsigned int const p_initial_viewport_width, unsigned int const p_initial_viewport_height,
210  unsigned int const p_initial_atlas_size,
211  float const p_initial_radius_scale = 1.0f,
212  rendering_modes const p_initial_rendering_mode = rendering_mode_space_filling,
213  atom_color_modes const p_initial_atom_color_mode = atom_color_mode_per_element
214  );
215 
224  void set_rendering_mode(rendering_modes const p_new_rendering_mode);
225 
234  void set_atom_color_mode(atom_color_modes const p_new_atom_color_mode);
235 
247  void set_viewport(unsigned int const p_new_left_viewport_offset, unsigned int const p_new_top_viewport_offset, unsigned int const p_new_viewport_width, unsigned int const p_new_viewport_height);
248 
254  void set_radius_scale(float const p_new_radius_scale);
255 
261  void set_border_width(float const p_new_border_width);
262 
268  void set_border_variance(float const p_new_border_variance);
269 
275  void set_ao_strength(float const p_new_ao_strength);
276 
282  void set_direct_lighting_strength(float const p_new_direct_lighting_strength);
283 
289  void set_shininess(float const p_new_shininess);
290 
296  void set_glossiness(float const p_new_glossiness);
297 
303  void set_flatness(float const p_new_flatness);
304 
310  void set_atlas_size(unsigned int const p_new_atlas_size);
311 
321  void render(cml::quaternionf const &p_rotation);
322 
328  matrix const & get_projection() const { return m_projection; }
329 
330 
331 protected:
332  typedef std::unique_ptr < texture > texture_uptr;
333 
334 
335  // Rendering always happens in two passes: first the spheres, then the cylinders.
336  enum passes
337  {
338  pass_spheres,
339  pass_cylinders
340  };
341 
342 
343  // Common initializer for all the constructors.
344  void init_renderer();
345 
346  // Internal rendering function for a specific pass using a given GLSL program.
347  void render_internal(molecule_shaders::program_data &p_program_data, matrix const &p_rotation, matrix const &p_projection, passes const p_pass);
348 
349  // Calculates ambient occlusion; expects the impostor geometry to exist already, so calc_quads() must be called prior to this.
350  void calc_ao();
351 
352  // Calculates impostor quads. This always needs to be called before the ambient occlusion term is calculated (= before calc_ao() is called).
353  void calc_quads();
354 
355  // Initializes the atlas texture instance, that is, the value of m_ao_atlas.
356  void init_atlas_texture();
357 
358 
359  molecule_shaders &m_shaders;
360  matrix m_projection;
361  vertex_array_object m_vao;
362  buffer_object m_vertices, m_indices;
363  molecule_data m_data;
364  std::size_t m_num_atoms, m_num_bonds;
365  float m_scale_factor; // Factor to scale atom and cylinder radii and atom positions; depends on the overall size of the molecule
366  float m_radius_scale; // User-defined scale by which the sphere and cylinder radii are scaled
367  float m_border_width, m_border_variance;
368  float m_ao_strength, m_direct_lighting_strength, m_shininess, m_glossiness, m_flatness;
369  cml::vector3f m_base_translation;
370  unsigned int m_left_viewport_offset, m_top_viewport_offset, m_viewport_width, m_viewport_height;
371  unsigned int m_atlas_size;
372  rendering_modes m_rendering_mode;
373  atom_color_modes m_atom_color_mode;
374 
375  texture_uptr m_ao_atlas;
376  std::size_t m_ao_patch_sidelength;
377 };
378 
379 
380 }
381 
382 
383 #endif
384