Radium Engine  1.5.0
Renderer.hpp
1 #pragma once
2 
3 #include <Engine/RaEngine.hpp>
4 
5 #include <array>
6 #include <chrono>
7 #include <memory>
8 #include <mutex>
9 #include <vector>
10 
11 #include <Core/Types.hpp>
12 #include <Core/Utils/Color.hpp>
13 #include <Core/Utils/Timer.hpp>
14 #include <Engine/Data/DisplayableObject.hpp>
15 
16 namespace globjects {
17 class Framebuffer;
18 }
19 
20 namespace Ra {
21 namespace Engine {
22 
23 namespace Data {
24 class Texture;
25 struct ViewingParameters;
26 class ShaderProgram;
27 class ShaderProgramManager;
28 class TextureManager;
29 } // namespace Data
30 
31 namespace Scene {
32 class Light;
33 class LightManager;
34 } // namespace Scene
35 
36 namespace Rendering {
37 class RenderObject;
38 class RenderObjectManager;
39 
44 class RA_ENGINE_API Renderer
45 {
46  protected:
47  using RenderObjectPtr = std::shared_ptr<RenderObject>;
48 
49  public:
53  struct TimerData {
54  Core::Utils::TimePoint renderStart;
55  Core::Utils::TimePoint updateEnd;
56  Core::Utils::TimePoint feedRenderQueuesEnd;
57  Core::Utils::TimePoint mainRenderEnd;
58  Core::Utils::TimePoint postProcessEnd;
59  Core::Utils::TimePoint renderEnd;
60  };
61 
65  enum PickingMode {
66  RO = 0,
68  EDGE,
73  NONE,
74  };
75 
80  enum PickingPurpose { SELECTION = 0, MANIPULATION };
81 
85  struct PickingQuery {
86  Core::Vector2 m_screenCoords;
87  PickingPurpose m_purpose;
88  PickingMode m_mode;
89  };
90 
109  {
110  public:
112  inline const std::vector<std::tuple<int, int, int>>& getIndices() const;
113 
115  inline void addIndex( const std::tuple<int, int, int>& idx );
116 
118  inline void reserve( size_t s );
119 
121  inline void removeDuplicatedIndices() const;
122 
124  inline void clear();
125 
126  inline void setRoIdx( Core::Utils::Index idx );
127  inline Core::Utils::Index getRoIdx() const;
128  inline void setMode( PickingMode mode );
129  inline PickingMode getMode() const;
130  //
131 
134  inline Scalar getDepth() const;
135  inline void setDepth( Scalar depth );
136 
137  private:
141  Core::Utils::Index m_roIdx { Core::Utils::Index::Invalid() };
142 
147  mutable std::vector<std::tuple<int, int, int>> m_indices;
148  Scalar m_depth;
149  };
150 
151  public:
157  Renderer();
158 
159  virtual ~Renderer();
160 
161  // -=-=-=-=-=-=-=-=- FINAL -=-=-=-=-=-=-=-=- //
162 
166  inline const TimerData& getTimerData() const;
167 
171  inline Data::Texture* getDisplayTexture() const;
172 
173  // Lock the renderer (for MT access)
177  inline void lockRendering();
178 
182  inline void unlockRendering();
183 
187  inline void toggleWireframe();
188 
193  inline void enableWireframe( bool enabled );
194 
198  inline void toggleDrawDebug();
199 
204  inline void enableDebugDraw( bool enabled );
205 
210  inline void enablePostProcess( bool enabled );
211 
232  void render( const Data::ViewingParameters& renderData );
233 
237  void initialize( uint width, uint height );
238 
248  void resize( uint width, uint height );
249 
254  inline void addPickingRequest( const PickingQuery& query );
255 
262  inline const std::vector<PickingResult>& getPickingResults() const;
263 
270  inline const std::vector<PickingQuery>& getPickingQueries() const;
271 
272  inline void setMousePosition( const Core::Vector2& pos );
273 
274  inline void setBrushRadius( Scalar brushRadius );
275 
277  bool hasLight() const;
278 
280  inline void setBackgroundColor( const Core::Utils::Color& color );
281 
282  inline const Core::Utils::Color& getBackgroundColor() const;
283 
284  // -=-=-=-=-=-=-=-=- VIRTUAL -=-=-=-=-=-=-=-=- //
290  virtual void addLight( const Scene::Light* light );
291 
295  virtual void reloadShaders();
296 
297  // TODO: For now the drawn texture takes the whole viewport,
298  // maybe it could be great if we had a way to switch between
299  // the current "fullscreen" debug mode, and some kind of
300  // "windowed" mode (that would show the debugged texture in
301  // its own viewport, without hiding the final texture.)
308  virtual void displayTexture( const std::string& texName );
309 
314  virtual std::vector<std::string> getAvailableTextures() const;
315 
320  virtual std::string getRendererName() const = 0;
321 
327  virtual bool buildRenderTechnique( RenderObject* ro ) const = 0;
328 
334  int buildAllRenderTechniques() const;
335 
342  virtual std::unique_ptr<uchar[]> grabFrame( size_t& w, size_t& h ) const;
343 
351  PickingResult doPickingNow( const PickingQuery& query,
352  const Data::ViewingParameters& renderData );
353 
354  protected:
359  virtual void initializeInternal() = 0;
360 
364  virtual void resizeInternal() = 0;
365 
370  virtual void updateStepInternal( const Data::ViewingParameters& renderData ) = 0;
371 
378  virtual void renderInternal( const Data::ViewingParameters& renderData ) = 0;
379 
388  virtual void postProcessInternal( const Data::ViewingParameters& renderData ) = 0;
389 
393  virtual void
394  debugInternal( const Data::ViewingParameters& renderData ) = 0; // is viewingParameters useful ?
395 
399  virtual void uiInternal( const Data::ViewingParameters& renderData ) = 0; // idem ?
400 
401  private:
402  // 0.
403  void saveExternalFBOInternal();
404  void restoreExternalFBOInternal();
405 
406  // 1.
407  void feedRenderQueuesInternal( const Data::ViewingParameters& renderData );
408 
409  // 2.0
410  void updateRenderObjectsInternal( const Data::ViewingParameters& renderData );
411 
412  // 3.
413  void splitRenderQueuesForPicking( const Data::ViewingParameters& renderData );
414  void splitRQ( const std::vector<RenderObjectPtr>& renderQueue,
415  std::array<std::vector<RenderObjectPtr>, 4>& renderQueuePicking );
416  void renderForPicking( const Data::ViewingParameters& renderData,
417  const std::array<const Data::ShaderProgram*, 4>& pickingShaders,
418  const std::array<std::vector<RenderObjectPtr>, 4>& renderQueuePicking );
419 
420  void doPicking( const Data::ViewingParameters& renderData );
421 
422  // 6.
423  void drawScreenInternal();
424 
425  // 7.
426  void notifyRenderObjectsRenderingInternal();
427 
428  protected:
429  uint m_width { 0 };
430  uint m_height { 0 };
431 
436  Data::ShaderProgramManager* m_shaderProgramManager { nullptr };
437 
442  RenderObjectManager* m_renderObjectManager { nullptr };
443 
444  // It would make more sense if we are able to show the
445  // debugged texture in its own viewport.
451  Data::Texture* m_displayedTexture { nullptr };
452 
455  std::vector<Ra::Engine::Scene::LightManager*> m_lightmanagers;
456 
457  bool m_renderQueuesUpToDate { false };
458 
459  std::vector<RenderObjectPtr> m_fancyRenderObjects;
460  std::vector<RenderObjectPtr> m_debugRenderObjects;
461  std::vector<RenderObjectPtr> m_xrayRenderObjects;
462  std::vector<RenderObjectPtr> m_uiRenderObjects;
463 
464  // Simple quad mesh, used to render the final image
465  std::unique_ptr<Data::Displayable> m_quadMesh;
466 
467  bool m_drawDebug { true }; // Should we render debug stuff ?
468  bool m_wireframe { false }; // Are we rendering in "real" wireframe mode
469  bool m_postProcessEnabled { true }; // Should we do post processing ?
470 
471  // derived class could use the already created textures
473  std::unique_ptr<Data::Texture> m_depthTexture;
475  std::unique_ptr<Data::Texture> m_fancyTexture;
477  std::map<std::string, Data::Texture*> m_secondaryTextures;
478 
479  private:
480  // Renderer timings data
481  TimerData m_timerData;
482 
483  std::mutex m_renderMutex;
484 
485  // PICKING STUFF
486  Ra::Core::Vector2 m_mousePosition;
487  float m_brushRadius { 0 };
488  std::unique_ptr<globjects::Framebuffer> m_pickingFbo;
489  std::unique_ptr<Data::Texture> m_pickingTexture;
490 
491  static const int NoPickingRenderMode = Data::Displayable::PickingRenderMode::NO_PICKING;
492  std::array<std::vector<RenderObjectPtr>, NoPickingRenderMode> m_fancyRenderObjectsPicking;
493  std::array<std::vector<RenderObjectPtr>, NoPickingRenderMode> m_debugRenderObjectsPicking;
494  std::array<std::vector<RenderObjectPtr>, NoPickingRenderMode> m_xrayRenderObjectsPicking;
495  std::array<std::vector<RenderObjectPtr>, NoPickingRenderMode> m_uiRenderObjectsPicking;
496  std::array<const Data::ShaderProgram*, NoPickingRenderMode> m_pickingShaders;
497 
498  std::vector<PickingQuery> m_pickingQueries;
499  std::vector<PickingQuery> m_lastFramePickingQueries;
500  std::vector<PickingResult> m_pickingResults;
501 
502  Core::Utils::Color m_backgroundColor { Core::Utils::Color::Grey( 0.0392_ra, 0_ra ) };
503  void preparePicking( const Data::ViewingParameters& renderData );
504 
505  bool m_initialized { false };
506 };
507 
508 inline const std::vector<std::tuple<int, int, int>>& Renderer::PickingResult::getIndices() const {
509  return m_indices;
510 }
511 
512 inline void Renderer::PickingResult::addIndex( const std::tuple<int, int, int>& idx ) {
513  m_indices.push_back( idx );
514 }
515 
516 inline void Renderer::PickingResult::reserve( size_t s ) {
517  m_indices.reserve( s );
518 }
519 
521  std::sort( m_indices.begin(), m_indices.end() );
522  m_indices.erase( std::unique( m_indices.begin(), m_indices.end() ), m_indices.end() );
523 }
524 
527  m_roIdx = Core::Utils::Index::Invalid();
528  m_indices.clear();
529 }
530 
531 inline void Renderer::PickingResult::setRoIdx( Core::Utils::Index idx ) {
532  m_roIdx = idx;
533 }
534 
535 inline Core::Utils::Index Renderer::PickingResult::getRoIdx() const {
536  return m_roIdx;
537 }
538 
539 inline void Renderer::PickingResult::setMode( Renderer::PickingMode mode ) {
540  m_mode = mode;
541 }
542 
543 inline Renderer::PickingMode Renderer::PickingResult::getMode() const {
544  return m_mode;
545 }
546 
547 inline Scalar Renderer::PickingResult::getDepth() const {
548  return m_depth;
549 }
550 
551 inline void Renderer::PickingResult::setDepth( Scalar depth ) {
552  m_depth = depth;
553 }
554 
556  return m_timerData;
557 }
558 
560  return m_displayedTexture;
561 }
562 
563 inline void Renderer::lockRendering() {
564  m_renderMutex.lock();
565 }
566 
568  m_renderMutex.unlock();
569 }
570 
572  m_wireframe = !m_wireframe;
573 }
574 
575 inline void Renderer::enableWireframe( bool enabled ) {
576  m_wireframe = enabled;
577 }
578 
580  m_drawDebug = !m_drawDebug;
581 }
582 
583 inline void Renderer::enableDebugDraw( bool enabled ) {
584  m_drawDebug = enabled;
585 }
586 
587 inline void Renderer::enablePostProcess( bool enabled ) {
588  m_postProcessEnabled = enabled;
589 }
590 
591 inline void Renderer::addPickingRequest( const PickingQuery& query ) {
592  m_pickingQueries.push_back( query );
593 }
594 
595 inline const std::vector<Renderer::PickingResult>& Renderer::getPickingResults() const {
596  return m_pickingResults;
597 }
598 
599 inline const std::vector<Renderer::PickingQuery>& Renderer::getPickingQueries() const {
600  return m_lastFramePickingQueries;
601 }
602 
603 inline void Renderer::setMousePosition( const Core::Vector2& pos ) {
604  m_mousePosition[0] = pos[0];
605  m_mousePosition[1] = m_height - pos[1];
606 }
607 
608 inline void Renderer::setBrushRadius( Scalar brushRadius ) {
609  m_brushRadius = brushRadius;
610 }
611 
613  m_backgroundColor = color;
614 }
615 
616 inline const Core::Utils::Color& Renderer::getBackgroundColor() const {
617  return m_backgroundColor;
618 }
619 
620 } // namespace Rendering
621 } // namespace Engine
622 } // namespace Ra
void addIndex(const std::tuple< int, int, int > &idx)
Add new ids to the result.
Definition: Renderer.hpp:512
void clear()
Reset query to default.
Definition: Renderer.hpp:525
void reserve(size_t s)
Reserve size of ids container.
Definition: Renderer.hpp:516
const std::vector< std::tuple< int, int, int > > & getIndices() const
Read access to the collected ids.
Definition: Renderer.hpp:508
void removeDuplicatedIndices() const
Remove duplicates in m_indices.
Definition: Renderer.hpp:520
const TimerData & getTimerData() const
Definition: Renderer.hpp:555
void addPickingRequest(const PickingQuery &query)
Definition: Renderer.hpp:591
virtual std::string getRendererName() const =0
Get the name of the renderer, e.g to be displayed in the UI.
virtual void debugInternal(const Data::ViewingParameters &renderData)=0
Add the debug layer with useful informations.
void enableDebugDraw(bool enabled)
Definition: Renderer.hpp:583
void enablePostProcess(bool enabled)
Definition: Renderer.hpp:587
std::vector< Ra::Engine::Scene::LightManager * > m_lightmanagers
Definition: Renderer.hpp:455
virtual void postProcessInternal(const Data::ViewingParameters &renderData)=0
Do all post processing stuff. If you override this method, be careful to fill.
Data::Texture * getDisplayTexture() const
Definition: Renderer.hpp:559
virtual bool buildRenderTechnique(RenderObject *ro) const =0
std::unique_ptr< Data::Texture > m_fancyTexture
Final color texture : might be attached to the main framebuffer.
Definition: Renderer.hpp:475
void setBackgroundColor(const Core::Utils::Color &color)
Update the background color (does not trigger a redraw)
Definition: Renderer.hpp:612
Data::Texture * m_displayedTexture
The texture that will be displayed on screen. If no call to.
Definition: Renderer.hpp:451
@ C_VERTEX
Picks all vertices of a mesh within a screen space circle.
Definition: Renderer.hpp:70
@ C_TRIANGLE
Picks all triangles of a mesh within a screen space circle.
Definition: Renderer.hpp:72
@ C_EDGE
Picks all edges of a mesh within a screen space circle.
Definition: Renderer.hpp:71
@ TRIANGLE
Pick a triangle of a mesh.
Definition: Renderer.hpp:69
@ EDGE
Pick an edge of a mesh.
Definition: Renderer.hpp:68
@ VERTEX
Pick a vertex of a mesh.
Definition: Renderer.hpp:67
virtual void initializeInternal()=0
initializeInternal Initialize the renderer dependant resources.
const std::vector< PickingResult > & getPickingResults() const
Definition: Renderer.hpp:595
virtual void uiInternal(const Data::ViewingParameters &renderData)=0
Draw the UI data.
std::map< std::string, Data::Texture * > m_secondaryTextures
Textures exposed in the texture section box to be displayed.
Definition: Renderer.hpp:477
std::unique_ptr< Data::Texture > m_depthTexture
Depth texture : might be attached to the main framebuffer.
Definition: Renderer.hpp:473
virtual void updateStepInternal(const Data::ViewingParameters &renderData)=0
const std::vector< PickingQuery > & getPickingQueries() const
Definition: Renderer.hpp:599
void enableWireframe(bool enabled)
Definition: Renderer.hpp:575
virtual void renderInternal(const Data::ViewingParameters &renderData)=0
All the scene rendering magics basically happens here.
Definition: Cage.cpp:3
the set of viewing parameters extracted from the camera and given to the renderer