Radium Engine  1.5.0
RenderObject.cpp
1 #include <Engine/Rendering/RenderObject.hpp>
2 
3 #include <Engine/RadiumEngine.hpp>
4 
5 #include <Engine/Data/DisplayableObject.hpp>
6 #include <Engine/Data/Material.hpp>
7 #include <Engine/Data/RenderParameters.hpp>
8 #include <Engine/OpenGL.hpp>
9 #include <Engine/Rendering/RenderObjectManager.hpp>
10 #include <Engine/Scene/Component.hpp>
11 
12 // STRANGE : only needed to access to the entity and its transform for components --> refactor
13 // component to give this directly ?
14 #include <Engine/Scene/Entity.hpp>
15 
16 #include <Core/Containers/MakeShared.hpp>
17 #include <Engine/Data/BlinnPhongMaterial.hpp>
18 #include <Engine/Data/ShaderProgram.hpp>
19 #include <Engine/Data/SimpleMaterial.hpp>
20 #include <Engine/Data/ViewingParameters.hpp>
21 
22 namespace Ra {
23 namespace Engine {
24 namespace Rendering {
25 
26 RenderObject::RenderObject( const std::string& name,
27  Scene::Component* comp,
28  const RenderObjectType& type,
29  int lifetime ) :
30  IndexedObject(),
31  m_component { comp },
32  m_name { name },
33  m_type { type },
34  m_mesh { nullptr },
35  m_lifetime { lifetime },
36  m_hasLifetime { lifetime > 0 } {}
37 
38 RenderObject::~RenderObject() {
39  if ( m_mesh ) {
40  m_mesh->getAbstractGeometry().getAabbObservable().detach( m_aabbObserverIndex );
41  }
42 }
43 
45  Scene::Component* comp,
46  const RenderObjectType& type,
47  std::shared_ptr<Data::Displayable> mesh,
48  const RenderTechnique& techniqueConfig ) {
49  auto obj = new RenderObject( name, comp, type );
50  obj->setMesh( mesh );
51  obj->setVisible( true );
52  auto rt = Core::make_shared<RenderTechnique>( techniqueConfig );
53  obj->setRenderTechnique( rt );
54  return obj;
55 }
56 
58  // Do not update while we are cloning
59  std::lock_guard<std::mutex> lock( m_updateMutex );
60 
61  if ( m_renderTechnique ) { m_renderTechnique->updateGL(); }
62 
63  if ( m_mesh ) { m_mesh->updateGL(); }
64 
65  m_dirty = false;
66 }
67 
68 const RenderObjectType& RenderObject::getType() const {
69  return m_type;
70 }
71 
72 void RenderObject::setType( const RenderObjectType& t ) {
73  m_type = t;
74 }
75 
76 const std::string& RenderObject::getName() const {
77  return m_name;
78 }
79 
80 void RenderObject::setVisible( bool visible ) {
81  m_visible = visible;
82 }
83 
84 void RenderObject::toggleVisible() {
85  m_visible = !m_visible;
86 }
87 
88 bool RenderObject::isVisible() const {
89  return m_visible;
90 }
91 
92 void RenderObject::setPickable( bool pickable ) {
93  m_pickable = pickable;
94 }
95 
96 void RenderObject::togglePickable() {
97  m_pickable = !m_pickable;
98 }
99 
100 bool RenderObject::isPickable() const {
101  return m_pickable;
102 }
103 
104 void RenderObject::setXRay( bool xray ) {
105  m_xray = xray;
106 }
107 
108 void RenderObject::toggleXRay() {
109  m_xray = !m_xray;
110 }
111 
112 bool RenderObject::isXRay() const {
113  return m_xray;
114 }
115 
116 void RenderObject::setTransparent( bool transparent ) {
117  m_transparent = transparent;
118 }
119 
120 void RenderObject::toggleTransparent() {
121  m_transparent = !m_transparent;
122 }
123 
124 bool RenderObject::isTransparent() const {
125  return m_transparent;
126 }
127 
129  if ( m_material ) { m_material->setColoredByVertexAttrib( state ); }
130 }
131 
133  if ( m_material ) {
134  m_material->setColoredByVertexAttrib( !m_material->isColoredByVertexAttrib() );
135  }
136 }
137 
139  if ( m_material ) { return m_material->isColoredByVertexAttrib(); }
140  return false;
141 }
142 
143 bool RenderObject::isDirty() const {
144  return m_dirty;
145 }
146 
147 const Scene::Component* RenderObject::getComponent() const {
148  return m_component;
149 }
150 
151 Scene::Component* RenderObject::getComponent() {
152  return m_component;
153 }
154 
155 void RenderObject::setRenderTechnique( std::shared_ptr<RenderTechnique> technique ) {
156  CORE_ASSERT( technique, "Passing a nullptr as render technique" );
157  m_renderTechnique = technique;
158 }
159 
160 std::shared_ptr<const RenderTechnique> RenderObject::getRenderTechnique() const {
161  return m_renderTechnique;
162 }
163 
164 std::shared_ptr<RenderTechnique> RenderObject::getRenderTechnique() {
165  return m_renderTechnique;
166 }
167 
168 void RenderObject::setMaterial( std::shared_ptr<Data::Material> material ) {
169  m_material = material;
170 }
171 
172 std::shared_ptr<const Data::Material> RenderObject::getMaterial() const {
173  return m_material;
174 }
175 
176 std::shared_ptr<Data::Material> RenderObject::getMaterial() {
177  return m_material;
178 }
179 
180 void RenderObject::setMesh( std::shared_ptr<Data::Displayable> mesh ) {
181 
182  if ( m_mesh ) {
183  m_mesh->getAbstractGeometry().getAabbObservable().detach( m_aabbObserverIndex );
184  }
185 
186  m_mesh = mesh;
187  if ( m_mesh ) {
188  m_aabbObserverIndex = m_mesh->getAbstractGeometry().getAabbObservable().attach(
189  [this]() { this->invalidateAabb(); } );
190  invalidateAabb();
191  }
192 }
193 
194 std::shared_ptr<const Data::Displayable> RenderObject::getMesh() const {
195  return m_mesh;
196 }
197 
198 const std::shared_ptr<Data::Displayable>& RenderObject::getMesh() {
199  return m_mesh;
200 }
201 
202 Core::Transform RenderObject::getTransform() const {
203  return m_component->getEntity()->getTransform() * m_localTransform;
204 }
205 
206 Core::Matrix4 RenderObject::getTransformAsMatrix() const {
207  return getTransform().matrix();
208 }
209 
210 Core::Aabb RenderObject::computeAabb() {
211  if ( !m_isAabbValid ) {
212  auto aabb = m_mesh->getAbstractGeometry().computeAabb();
213  if ( !aabb.isEmpty() ) {
214 
215  Core::Aabb result;
216  for ( int i = 0; i < 8; ++i ) {
217  result.extend( getTransform() * aabb.corner( Core::Aabb::CornerType( i ) ) );
218  }
219 
220  m_aabb = result;
221  m_isAabbValid = true;
222  }
223  else {
224  m_aabb = aabb;
225  m_isAabbValid = true;
226  }
227  }
228 
229  return m_aabb;
230 }
231 
232 void RenderObject::setLocalTransform( const Core::Transform& transform ) {
233  m_localTransform = transform;
234  invalidateAabb();
235 }
236 
237 void RenderObject::setLocalTransform( const Core::Matrix4& transform ) {
238  m_localTransform = Core::Transform( transform );
239  invalidateAabb();
240 }
241 
242 const Core::Transform& RenderObject::getLocalTransform() const {
243  return m_localTransform;
244 }
245 
246 const Core::Matrix4& RenderObject::getLocalTransformAsMatrix() const {
247  return m_localTransform.matrix();
248 }
249 
251  if ( m_hasLifetime ) {
252  if ( --m_lifetime <= 0 ) {
253  RadiumEngine::getInstance()->getRenderObjectManager()->renderObjectExpired( m_idx );
254  }
255  }
256 }
257 
259  m_component->notifyRenderObjectExpired( m_idx );
260 }
261 
263  m_lifetime = t;
264  m_hasLifetime = true;
265 }
266 
268  const Data::ViewingParameters& viewParams,
269  const Data::ShaderProgram* shader,
270  const Data::RenderParameters& shaderParams ) {
271  if ( !m_visible || !shader ) { return; }
272  // Radium V2 : avoid this temporary
273  Core::Matrix4 modelMatrix = getTransformAsMatrix();
274  Core::Matrix4 normalMatrix = modelMatrix.inverse().transpose();
275  // bind data
276  shader->bind();
277  shader->setUniform( "transform.proj", viewParams.projMatrix );
278  shader->setUniform( "transform.view", viewParams.viewMatrix );
279  shader->setUniform( "transform.model", modelMatrix );
280  shader->setUniform( "transform.worldNormal", normalMatrix );
281  lightParams.bind( shader );
282  shaderParams.bind( shader );
283  // FIXME : find another solution for FrontFacing polygons (depends on the camera matrix)
284  // This is a hack to allow correct face culling
285  // Note that this hack implies the inclusion of OpenGL.h in this file
286  if ( viewParams.viewMatrix.determinant() < 0 ) { glFrontFace( GL_CW ); }
287  else { glFrontFace( GL_CCW ); }
288  m_mesh->render( shader );
289 }
290 
292  const Data::ViewingParameters& viewParams,
293  Core::Utils::Index passId ) {
294  if ( m_visible ) {
295  auto shader = getRenderTechnique()->getShader( passId );
296  if ( !shader ) { return; }
297 
298  auto paramsProvider = getRenderTechnique()->getParametersProvider( passId );
299  // Do not copy the provider parameters if it exists
300  if ( paramsProvider != nullptr ) {
301  render( lightParams, viewParams, shader, paramsProvider->getParameters() );
302  }
303  else { render( lightParams, viewParams, shader, {} ); }
304  }
305 }
306 
307 void RenderObject::invalidateAabb() {
308  m_isAabbValid = false;
309  m_component->invalidateAabb();
310 }
311 
312 } // namespace Rendering
313 } // namespace Engine
314 } // namespace Ra
void bind(const Data::ShaderProgram *shader) const
void setUniform(const char *name, const T &value) const
Uniform setters.
void render(const Data::RenderParameters &lightParams, const Data::ViewingParameters &viewParams, const Data::ShaderProgram *shader, const Data::RenderParameters &shaderParams)
bool isColoredByVertexAttrib() const
manage usage of VERTEX_COLOR attribute by the material
void toggleColoredByVertexAttrib()
manage usage of VERTEX_COLOR attribute by the material
void setLifetime(int t)
Set a lifetime to an existing RenderObject.
const std::string & getName() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW RenderObject(const std::string &name, Scene::Component *comp, const RenderObjectType &type, int lifetime=-1)
void hasExpired()
Notify component that the render object has expired.
void setColoredByVertexAttrib(bool state)
manage usage of VERTEX_COLOR attribute by the material
static RenderObject * createRenderObject(const std::string &name, Scene::Component *comp, const RenderObjectType &type, std::shared_ptr< Data::Displayable > mesh, const RenderTechnique &techniqueConfig=RenderTechnique::createDefaultRenderTechnique())
A component is an element that can be updated by a system. It is also linked to some other components...
Definition: Component.hpp:31
virtual Entity * getEntity() const
Return the entity the component belongs to.
Definition: Component.hpp:53
Definition: Cage.cpp:3
the set of viewing parameters extracted from the camera and given to the renderer