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 // @todo Inform renderers of deletion of buffers?
50 // could remove self from own uniform map observer, but it's about to be destroyed.
53 void Geometry::AddVertexBuffer( PropertyBuffer* vertexBuffer )
55 mVertexBuffers.PushBack( vertexBuffer );
56 CalculateExtents( vertexBuffer );
57 vertexBuffer->AddUniformMapObserver(*this);
58 mConnectionObservers.ConnectionsChanged(*this);
62 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, vertexBuffer, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
66 void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
68 DALI_ASSERT_DEBUG( NULL != vertexBuffer );
70 // Find the object and destroy it
71 Vector<PropertyBuffer*>::Iterator match = std::find(
72 mVertexBuffers.Begin(),
76 DALI_ASSERT_DEBUG( mVertexBuffers.End() != match );
77 if( mVertexBuffers.End() != match )
79 vertexBuffer->RemoveUniformMapObserver(*this);
80 mVertexBuffers.Erase( match );
81 mConnectionObservers.ConnectionsChanged(*this);
85 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, vertexBuffer );
90 void Geometry::SetIndexBuffer( PropertyBuffer* indexBuffer )
92 if( mIndexBuffer != indexBuffer )
94 mIndexBuffer = indexBuffer;
95 indexBuffer->AddUniformMapObserver(*this);
96 mConnectionObservers.ConnectionsChanged(*this);
100 mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, indexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
105 void Geometry::ClearIndexBuffer()
109 mIndexBuffer->RemoveUniformMapObserver(*this);
111 if( mRenderGeometry )
113 mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, mIndexBuffer );
117 mConnectionObservers.ConnectionsChanged(*this);
120 void Geometry::SetGeometryType( BufferIndex bufferIndex, Geometry::GeometryType geometryType )
122 mGeometryType.Set( bufferIndex, geometryType);
125 Vector<PropertyBuffer*>& Geometry::GetVertexBuffers()
127 return mVertexBuffers;
130 PropertyBuffer* Geometry::GetIndexBuffer()
135 Geometry::GeometryType Geometry::GetGeometryType( BufferIndex bufferIndex) const
137 int geometryType = mGeometryType[ bufferIndex ];
138 return static_cast< GeometryDataProvider::GeometryType > ( geometryType );
141 bool Geometry::GetRequiresDepthTesting( BufferIndex bufferIndex ) const
143 return mRequiresDepthTest.GetBoolean( bufferIndex );
146 void Geometry::ResetDefaultProperties( BufferIndex updateBufferIndex )
148 // Reset the animated properties
149 mCenter.ResetToBaseValue( updateBufferIndex );
151 // Age the double buffered properties
152 mGeometryType.CopyPrevious(updateBufferIndex);
153 mRequiresDepthTest.CopyPrevious(updateBufferIndex);
156 void Geometry::CalculateExtents( PropertyBuffer* vertexBuffer )
158 unsigned int elementIndex = 0;
159 unsigned int elementCount = vertexBuffer->GetElementCount( 0 );
160 unsigned int elementCount1 = vertexBuffer->GetElementCount( 1 );
162 // Select the double buffered element list that is the largest...
163 if ( elementCount < elementCount1 )
165 elementCount = elementCount1;
169 unsigned int attributeCount = vertexBuffer->GetAttributeCount( elementIndex );
170 unsigned int elementSize = vertexBuffer->GetElementSize( elementIndex );
172 std::string posName( "aPos" );
180 // Find the position attribute index
181 for ( unsigned int i = 0; i < attributeCount; ++i )
183 found = vertexBuffer->GetAttributeName( 0, i ).find( posName );
184 if ( found != std::string::npos )
186 unsigned int offset = vertexBuffer->GetAttributeOffset( elementIndex, i );
187 const PropertyBufferDataProvider::BufferType& data = vertexBuffer->GetData( elementIndex );
189 // Check attribute type to determine correct position type
190 Property::Type positionType = vertexBuffer->GetAttributeType( elementIndex, i );
193 switch ( positionType )
195 case Property::VECTOR2:
197 for ( unsigned int j = 0; j < elementCount; ++j )
199 const Vector2* position = reinterpret_cast< const Vector2* >( &data[ offset ] );
200 offset += elementSize;
202 if ( position->x < left )
206 if ( position->x > right )
210 if ( position->y < top )
214 if ( position->y > bottom )
216 bottom = position->y;
220 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, 0.0f );
221 center = Vector3( halfExtents.x + left , halfExtents.y + top, 0.0f );
224 case Property::VECTOR3:
228 for ( unsigned int j = 0; j < elementCount; ++j )
230 const Vector3* position = reinterpret_cast< const Vector3* >( &data[ offset ] );
231 offset += elementSize;
233 if ( position->x < left )
237 if ( position->x > right )
241 if ( position->y < top )
245 if ( position->y > bottom )
247 bottom = position->y;
249 if ( position->z > far )
253 if ( position->z < near )
258 halfExtents = Vector3( ( right - left ) * 0.5f, ( bottom - top ) * 0.5f, ( far - near ) * 0.5f );
259 center = Vector3( halfExtents.x + left , halfExtents.y + top, halfExtents.z + near );
267 mCenter.Bake( 0, center );
268 mCenter.Bake( 1, center );
273 void Geometry::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
277 void Geometry::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
281 void Geometry::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
283 mConnectionObservers.Add(observer);
286 void Geometry::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
288 mConnectionObservers.Remove(observer);
291 void Geometry::UniformMappingsChanged( const UniformMap& mappings )
293 // Our uniform map, or that of one of the watched children has changed.
294 // Inform connected observers.
295 mConnectionObservers.ConnectedUniformMapChanged();
298 RenderGeometry* Geometry::GetRenderGeometry(SceneController* sceneController)
302 //Create RenderGeometry
303 mSceneController = sceneController;
304 mRenderGeometry = new RenderGeometry( *this );
306 size_t vertexBufferCount( mVertexBuffers.Size() );
307 for( size_t i(0); i<vertexBufferCount; ++i )
309 mRenderGeometry->AddPropertyBuffer( mVertexBuffers[i], GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
314 mRenderGeometry->AddPropertyBuffer( mIndexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
317 //Transfer ownership to RenderManager
318 sceneController->GetRenderMessageDispatcher().AddGeometry( *mRenderGeometry );
322 return mRenderGeometry;
325 void Geometry::OnRendererDisconnect()
328 if( mRendererRefCount == 0 )
330 //Delete the corresponding RenderGeometry via message to RenderManager
331 mSceneController->GetRenderMessageDispatcher().RemoveGeometry( *mRenderGeometry );
334 mSceneController = 0;
339 } // namespace SceneGraph
340 } // namespace Internal