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),
38 mGeometryType(Dali::Geometry::TRIANGLES),
39 mRequiresDepthTest(false)
42 // Observe our own PropertyOwner's uniform map
43 AddUniformMapObserver( *this );
48 mConnectionObservers.Destroy( *this );
51 void Geometry::AddVertexBuffer( PropertyBuffer* vertexBuffer )
53 mVertexBuffers.PushBack( vertexBuffer );
54 CalculateExtents( vertexBuffer );
55 vertexBuffer->AddUniformMapObserver(*this);
56 mConnectionObservers.ConnectionsChanged(*this);
60 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, vertexBuffer, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
64 void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
66 DALI_ASSERT_DEBUG( NULL != vertexBuffer );
68 // Find the object and destroy it
69 Vector<PropertyBuffer*>::Iterator match = std::find(
70 mVertexBuffers.Begin(),
74 DALI_ASSERT_DEBUG( mVertexBuffers.End() != match );
75 if( mVertexBuffers.End() != match )
77 vertexBuffer->RemoveUniformMapObserver(*this);
78 mVertexBuffers.Erase( match );
79 mConnectionObservers.ConnectionsChanged(*this);
83 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, vertexBuffer );
88 void Geometry::SetIndexBuffer( PropertyBuffer* indexBuffer )
90 if( mIndexBuffer != indexBuffer )
92 mIndexBuffer = indexBuffer;
93 indexBuffer->AddUniformMapObserver(*this);
94 mConnectionObservers.ConnectionsChanged(*this);
98 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, indexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
103 void Geometry::ClearIndexBuffer()
107 mIndexBuffer->RemoveUniformMapObserver(*this);
109 if( mRenderGeometry )
111 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, mIndexBuffer );
115 mConnectionObservers.ConnectionsChanged(*this);
118 void Geometry::SetGeometryType( BufferIndex bufferIndex, Geometry::GeometryType geometryType )
120 mGeometryType.Set( bufferIndex, geometryType);
123 Vector<PropertyBuffer*>& Geometry::GetVertexBuffers()
125 return mVertexBuffers;
128 PropertyBuffer* Geometry::GetIndexBuffer()
133 Geometry::GeometryType Geometry::GetGeometryType( BufferIndex bufferIndex) const
135 int geometryType = mGeometryType[ bufferIndex ];
136 return static_cast< GeometryDataProvider::GeometryType > ( geometryType );
139 bool Geometry::GetRequiresDepthTesting( BufferIndex bufferIndex ) const
141 return mRequiresDepthTest.GetBoolean( bufferIndex );
144 void Geometry::ResetDefaultProperties( BufferIndex updateBufferIndex )
146 // Reset the animated properties
147 mCenter.ResetToBaseValue( updateBufferIndex );
149 // Age the double buffered properties
150 mGeometryType.CopyPrevious(updateBufferIndex);
151 mRequiresDepthTest.CopyPrevious(updateBufferIndex);
154 void Geometry::CalculateExtents( PropertyBuffer* vertexBuffer )
156 unsigned int elementIndex = 0;
157 unsigned int elementCount = vertexBuffer->GetElementCount( 0 );
158 unsigned int elementCount1 = vertexBuffer->GetElementCount( 1 );
160 // Select the double buffered element list that is the largest...
161 if ( elementCount < elementCount1 )
163 elementCount = elementCount1;
167 unsigned int attributeCount = vertexBuffer->GetAttributeCount( elementIndex );
168 unsigned int elementSize = vertexBuffer->GetElementSize( elementIndex );
170 std::string posName( "aPos" );
178 // Find the position attribute index
179 for ( unsigned int i = 0; i < attributeCount; ++i )
181 found = vertexBuffer->GetAttributeName( 0, i ).find( posName );
182 if ( found != std::string::npos )
184 unsigned int offset = vertexBuffer->GetAttributeOffset( elementIndex, i );
185 const PropertyBufferDataProvider::BufferType& data = vertexBuffer->GetData( elementIndex );
187 // Check attribute type to determine correct position type
188 Property::Type positionType = vertexBuffer->GetAttributeType( elementIndex, i );
191 switch ( positionType )
193 case Property::VECTOR2:
195 for ( unsigned int j = 0; j < elementCount; ++j )
197 const Vector2* position = reinterpret_cast< const Vector2* >( &data[ offset ] );
198 offset += elementSize;
200 if ( position->x < left )
204 if ( position->x > right )
208 if ( position->y < top )
212 if ( position->y > bottom )
214 bottom = position->y;
218 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, 0.0f );
219 center = Vector3( halfExtents.x + left , halfExtents.y + top, 0.0f );
222 case Property::VECTOR3:
226 for ( unsigned int j = 0; j < elementCount; ++j )
228 const Vector3* position = reinterpret_cast< const Vector3* >( &data[ offset ] );
229 offset += elementSize;
231 if ( position->x < left )
235 if ( position->x > right )
239 if ( position->y < top )
243 if ( position->y > bottom )
245 bottom = position->y;
247 if ( position->z > far )
251 if ( position->z < near )
256 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, ( far - near ) * 0.5f );
257 center = Vector3( halfExtents.x + left , halfExtents.y + top, halfExtents.z + near );
265 mCenter.Bake( 0, center );
266 mCenter.Bake( 1, center );
271 void Geometry::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
275 void Geometry::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
279 void Geometry::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
281 mConnectionObservers.Add(observer);
284 void Geometry::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
286 mConnectionObservers.Remove(observer);
289 void Geometry::UniformMappingsChanged( const UniformMap& mappings )
291 // Our uniform map, or that of one of the watched children has changed.
292 // Inform connected observers.
293 mConnectionObservers.ConnectedUniformMapChanged();
296 RenderGeometry* Geometry::GetRenderGeometry(SceneController* sceneController)
300 //Create RenderGeometry
301 mSceneController = sceneController;
302 mRenderGeometry = new RenderGeometry( *this );
304 size_t vertexBufferCount( mVertexBuffers.Size() );
305 for( size_t i(0); i<vertexBufferCount; ++i )
307 mRenderGeometry->AddPropertyBuffer( mVertexBuffers[i], GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
312 mRenderGeometry->AddPropertyBuffer( mIndexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
315 //Transfer ownership to RenderManager
316 sceneController->GetRenderMessageDispatcher().AddGeometry( *mRenderGeometry );
320 return mRenderGeometry;
323 void Geometry::OnRendererDisconnect()
326 if( mRendererRefCount == 0 )
328 //Delete the corresponding RenderGeometry via message to RenderManager
329 mSceneController->GetRenderMessageDispatcher().RemoveGeometry( *mRenderGeometry );
332 mSceneController = 0;
337 } // namespace SceneGraph
338 } // namespace Internal