Radium Engine  1.5.20
Loading...
Searching...
No Matches
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
22namespace Ra {
23namespace Engine {
24namespace Rendering {
25
27 Scene::Component* comp,
28 const RenderObjectType& type,
29 int lifetime ) :
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
38RenderObject::~RenderObject() {
39 if ( m_mesh ) {
40 m_mesh->getAbstractGeometry().getAabbObservable().detach( m_aabbObserverIndex );
41 }
42}
43
45 Scene::Component* comp,
46 const RenderObjectType& type,
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
68const RenderObjectType& RenderObject::getType() const {
69 return m_type;
70}
71
72void RenderObject::setType( const RenderObjectType& t ) {
73 m_type = t;
74}
75
77 return m_name;
78}
79
80void RenderObject::setVisible( bool visible ) {
81 m_visible = visible;
82}
83
84void RenderObject::toggleVisible() {
85 m_visible = !m_visible;
86}
87
88bool RenderObject::isVisible() const {
89 return m_visible;
90}
91
92void RenderObject::setPickable( bool pickable ) {
93 m_pickable = pickable;
94}
95
96void RenderObject::togglePickable() {
97 m_pickable = !m_pickable;
98}
99
100bool RenderObject::isPickable() const {
101 return m_pickable;
102}
103
104void RenderObject::setXRay( bool xray ) {
105 m_xray = xray;
106}
107
108void RenderObject::toggleXRay() {
109 m_xray = !m_xray;
110}
111
112bool RenderObject::isXRay() const {
113 return m_xray;
114}
115
116void RenderObject::setTransparent( bool transparent ) {
117 m_transparent = transparent;
118}
119
120void RenderObject::toggleTransparent() {
121 m_transparent = !m_transparent;
122}
123
124bool 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
143bool RenderObject::isDirty() const {
144 return m_dirty;
145}
146
147const Scene::Component* RenderObject::getComponent() const {
148 return m_component;
149}
150
151Scene::Component* RenderObject::getComponent() {
152 return m_component;
153}
154
155void RenderObject::setRenderTechnique( std::shared_ptr<RenderTechnique> technique ) {
156 CORE_ASSERT( technique, "Passing a nullptr as render technique" );
157 m_renderTechnique = technique;
158}
159
160std::shared_ptr<const RenderTechnique> RenderObject::getRenderTechnique() const {
161 return m_renderTechnique;
162}
163
164std::shared_ptr<RenderTechnique> RenderObject::getRenderTechnique() {
165 return m_renderTechnique;
166}
167
168void RenderObject::setMaterial( std::shared_ptr<Data::Material> material ) {
169 m_material = material;
170}
171
172std::shared_ptr<const Data::Material> RenderObject::getMaterial() const {
173 return m_material;
174}
175
176std::shared_ptr<Data::Material> RenderObject::getMaterial() {
177 return m_material;
178}
179
180void 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
194std::shared_ptr<const Data::Displayable> RenderObject::getMesh() const {
195 return m_mesh;
196}
197
198const std::shared_ptr<Data::Displayable>& RenderObject::getMesh() {
199 return m_mesh;
200}
201
202Core::Transform RenderObject::getTransform() const {
203 return m_component->getEntity()->getTransform() * m_localTransform;
204}
205
206Core::Matrix4 RenderObject::getTransformAsMatrix() const {
207 return getTransform().matrix();
208}
209
210Core::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
232void RenderObject::setLocalTransform( const Core::Transform& transform ) {
233 m_localTransform = transform;
234 invalidateAabb();
235}
236
237void RenderObject::setLocalTransform( const Core::Matrix4& transform ) {
238 m_localTransform = Core::Transform( transform );
239 invalidateAabb();
240}
241
242const Core::Transform& RenderObject::getLocalTransform() const {
243 return m_localTransform;
244}
245
246const 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
307void RenderObject::invalidateAabb() {
308 m_isAabbValid = false;
309 m_component->invalidateAabb();
310}
311
312} // namespace Rendering
313} // namespace Engine
314} // namespace Ra
Management of shader parameters with automatic binding of a named parameter to the corresponding glsl...
void bind(const Data::ShaderProgram *shader) const
Bind the parameter uniform on the shader program.
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
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
std::shared_ptr< T > make_shared(Args &&... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
the set of viewing parameters extracted from the camera and given to the renderer
T transform(T... args)