2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "scene-graph-geometry.h"
21 #include <dali/internal/update/controllers/scene-controller.h>
22 #include <dali/internal/render/renderers/render-geometry.h>
23 #include <dali/internal/update/controllers/render-message-dispatcher.h>
33 : mIndexBuffer( NULL ),
36 mRendererRefCount(0u),
40 mGeometryType(Dali::Geometry::TRIANGLES),
41 mRequiresDepthTest(false)
44 // Observe our own PropertyOwner's uniform map
45 AddUniformMapObserver( *this );
50 // @todo Inform renderers of deletion of buffers?
52 // could remove self from own uniform map observer, but it's about to be destroyed.
55 void Geometry::AddVertexBuffer( PropertyBuffer* vertexBuffer )
57 mVertexBuffers.PushBack( vertexBuffer );
58 CalculateExtents( vertexBuffer );
59 vertexBuffer->AddUniformMapObserver(*this);
60 mConnectionObservers.ConnectionsChanged(*this);
64 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, vertexBuffer, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
68 void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
70 DALI_ASSERT_DEBUG( NULL != vertexBuffer );
72 // Find the object and destroy it
73 Vector<PropertyBuffer*>::Iterator match = std::find(
74 mVertexBuffers.Begin(),
78 DALI_ASSERT_DEBUG( mVertexBuffers.End() != match );
79 if( mVertexBuffers.End() != match )
81 vertexBuffer->RemoveUniformMapObserver(*this);
82 mVertexBuffers.Erase( match );
83 mConnectionObservers.ConnectionsChanged(*this);
87 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, vertexBuffer );
92 void Geometry::SetIndexBuffer( PropertyBuffer* indexBuffer )
94 if( mIndexBuffer != indexBuffer )
96 mIndexBuffer = indexBuffer;
97 indexBuffer->AddUniformMapObserver(*this);
98 mConnectionObservers.ConnectionsChanged(*this);
100 if( mRenderGeometry )
102 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, indexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
107 void Geometry::ClearIndexBuffer()
111 mIndexBuffer->RemoveUniformMapObserver(*this);
113 if( mRenderGeometry )
115 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, mIndexBuffer );
119 mConnectionObservers.ConnectionsChanged(*this);
122 void Geometry::SetGeometryType( BufferIndex bufferIndex, Geometry::GeometryType geometryType )
124 mGeometryType.Set( bufferIndex, geometryType);
127 Vector<PropertyBuffer*>& Geometry::GetVertexBuffers()
129 return mVertexBuffers;
132 PropertyBuffer* Geometry::GetIndexBuffer()
137 Geometry::GeometryType Geometry::GetGeometryType( BufferIndex bufferIndex) const
139 int geometryType = mGeometryType[ bufferIndex ];
140 return static_cast< GeometryDataProvider::GeometryType > ( geometryType );
143 bool Geometry::GetRequiresDepthTesting( BufferIndex bufferIndex ) const
145 return mRequiresDepthTest.GetBoolean( bufferIndex );
148 void Geometry::ResetDefaultProperties( BufferIndex updateBufferIndex )
150 // Reset the animated properties
151 mCenter.ResetToBaseValue( updateBufferIndex );
152 mHalfExtents.ResetToBaseValue( updateBufferIndex );
153 mRadius.ResetToBaseValue( updateBufferIndex );
155 // Age the double buffered properties
156 mGeometryType.CopyPrevious(updateBufferIndex);
157 mRequiresDepthTest.CopyPrevious(updateBufferIndex);
160 void Geometry::CalculateExtents( PropertyBuffer* vertexBuffer )
162 // TODO calculate extents for all vertex buffers attached to geometry
163 unsigned int elementIndex = 0;
164 unsigned int elementCount = vertexBuffer->GetElementCount( 0 );
165 unsigned int elementCount1 = vertexBuffer->GetElementCount( 1 );
167 // Select the double buffered element list that is the largest...
168 if ( elementCount < elementCount1 )
170 elementCount = elementCount1;
174 unsigned int attributeCount = vertexBuffer->GetAttributeCount( elementIndex );
175 unsigned int elementSize = vertexBuffer->GetElementSize( elementIndex );
177 std::string posName( "aPos" );
185 // Find the position attribute index
186 for ( unsigned int i = 0; i < attributeCount; ++i )
188 found = vertexBuffer->GetAttributeName( 0, i ).find( posName );
189 if ( found != std::string::npos )
191 unsigned int offset = vertexBuffer->GetAttributeOffset( elementIndex, i );
192 const PropertyBufferDataProvider::BufferType& data = vertexBuffer->GetData( elementIndex );
194 // Check attribute type to determine correct position type
195 Property::Type positionType = vertexBuffer->GetAttributeType( elementIndex, i );
198 switch ( positionType )
200 case Property::VECTOR2:
202 for ( unsigned int j = 0; j < elementCount; ++j )
204 const Vector2* position = reinterpret_cast< const Vector2* >( &data[ offset ] );
205 offset += elementSize;
207 if ( position->x < left )
211 if ( position->x > right )
215 if ( position->y < top )
219 if ( position->y > bottom )
221 bottom = position->y;
225 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, 0.0f );
226 center = Vector3( halfExtents.x + left , halfExtents.y + top, 0.0f );
229 case Property::VECTOR3:
233 for ( unsigned int j = 0; j < elementCount; ++j )
235 const Vector3* position = reinterpret_cast< const Vector3* >( &data[ offset ] );
236 offset += elementSize;
238 if ( position->x < left )
242 if ( position->x > right )
246 if ( position->y < top )
250 if ( position->y > bottom )
252 bottom = position->y;
254 if ( position->z > far )
258 if ( position->z < near )
263 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, ( far - near ) * 0.5f );
264 center = Vector3( halfExtents.x + left , halfExtents.y + top, halfExtents.z + near );
272 mCenter.Bake( 0, center );
273 mCenter.Bake( 1, center );
274 mHalfExtents.Bake( 0, halfExtents );
275 mHalfExtents.Bake( 1, halfExtents );
277 float radius = halfExtents.x;
278 if ( radius < halfExtents.y )
280 radius = halfExtents.y;
282 mRadius.SetInitial( radius );
287 void Geometry::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
291 void Geometry::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
295 void Geometry::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
297 mConnectionObservers.Add(observer);
300 void Geometry::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
302 mConnectionObservers.Remove(observer);
305 void Geometry::UniformMappingsChanged( const UniformMap& mappings )
307 // Our uniform map, or that of one of the watched children has changed.
308 // Inform connected observers.
309 mConnectionObservers.ConnectedUniformMapChanged();
312 RenderGeometry* Geometry::GetRenderGeometry(SceneController* sceneController)
316 //Create RenderGeometry
317 mSceneController = sceneController;
318 mRenderGeometry = new RenderGeometry( *this );
320 size_t vertexBufferCount( mVertexBuffers.Size() );
321 for( size_t i(0); i<vertexBufferCount; ++i )
323 mRenderGeometry->AddPropertyBuffer( mVertexBuffers[i], GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
328 mRenderGeometry->AddPropertyBuffer( mIndexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
331 //Transfer ownership to RenderManager
332 sceneController->GetRenderMessageDispatcher().AddGeometry( *mRenderGeometry );
336 return mRenderGeometry;
339 void Geometry::OnRendererDisconnect()
342 if( mRendererRefCount == 0 )
344 //Delete the corresponding RenderGeometry via message to RenderManager
345 mSceneController->GetRenderMessageDispatcher().RemoveGeometry( *mRenderGeometry );
348 mSceneController = 0;
353 } // namespace SceneGraph
354 } // namespace Internal