Merge "Added api to check actor's depth in the hierarchy" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-geometry.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <dali/internal/render/renderers/render-geometry.h>
18
19 #include <dali/internal/common/buffer-index.h>
20 #include <dali/internal/update/common/scene-graph-property-buffer.h>
21 #include <dali/internal/update/rendering/scene-graph-geometry.h>
22 #include <dali/internal/render/data-providers/render-data-provider.h>
23 #include <dali/internal/render/gl-resources/context.h>
24 #include <dali/internal/render/gl-resources/gpu-buffer.h>
25 #include <dali/internal/render/shaders/program.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace SceneGraph
32 {
33
34 RenderGeometry::RenderGeometry()
35 : mDataNeedsUploading( true ),
36   mShaderChanged( true )
37 {
38 }
39
40 RenderGeometry::~RenderGeometry()
41 {
42 }
43
44 void RenderGeometry::GlContextCreated( Context& context )
45 {
46   mDataNeedsUploading = true;
47 }
48
49 void RenderGeometry::GlContextDestroyed()
50 {
51 }
52
53 void RenderGeometry::UploadAndDraw(
54   Context& context,
55   Program& program,
56   BufferIndex bufferIndex,
57   const RenderDataProvider* dataProviders )
58 {
59   UploadVertexData( context, program, bufferIndex, dataProviders );
60
61   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
62   {
63     mVertexBuffers[i]->BindBuffer( context, program );
64     mVertexBuffers[i]->EnableVertexAttributes( context, bufferIndex, program );
65   }
66
67   if( mIndexBuffer )
68   {
69     mIndexBuffer->BindBuffer( context, program );
70   }
71
72   Draw( context, bufferIndex, dataProviders );
73
74   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
75   {
76     mVertexBuffers[i]->DisableVertexAttributes( context, bufferIndex, program );
77   }
78 }
79
80 void RenderGeometry::GeometryUpdated()
81 {
82   mDataNeedsUploading = true;
83 }
84
85 void RenderGeometry::UploadVertexData(
86   Context& context,
87   Program& program,
88   BufferIndex bufferIndex,
89   const RenderDataProvider* dataProviders )
90 {
91   if( mDataNeedsUploading )
92   {
93     SetUpPropertyBuffers( context, bufferIndex, dataProviders );
94
95     for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
96     {
97       mVertexBuffers[i]->Upload( context, bufferIndex );
98       mVertexBuffers[i]->UpdateAttributeLocations( context, bufferIndex, program );
99     }
100     if( mIndexBuffer )
101     {
102       mIndexBuffer->Upload( context, bufferIndex );
103     }
104
105     mDataNeedsUploading = false;
106   }
107 }
108
109 void RenderGeometry::SetUpPropertyBuffers(
110   Context& context,
111   BufferIndex bufferIndex,
112   const RenderDataProvider* dataProvider )
113 {
114   // Vertex buffer
115   RenderDataProvider::VertexBuffers vertexBuffers = dataProvider->GetVertexBuffers();
116
117   DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" );
118
119   mVertexBuffers.Clear();
120   for( unsigned int i=0; i<vertexBuffers.Count(); ++i)
121   {
122     const PropertyBufferDataProvider* vertexBuffer = vertexBuffers[i];
123
124     RenderPropertyBuffer* propertyBuffer = new RenderPropertyBuffer(
125       *vertexBuffer,
126       GpuBuffer::ARRAY_BUFFER,
127       GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes
128
129     mVertexBuffers.PushBack( propertyBuffer );
130   }
131
132   // Index buffer
133   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
134   if( indexBuffer )
135   {
136     mIndexBuffer = new RenderPropertyBuffer(
137       *indexBuffer,
138       GpuBuffer::ELEMENT_ARRAY_BUFFER,
139       GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes
140   }
141 }
142
143 void RenderGeometry::BindBuffers( Context& context, BufferIndex bufferIndex, Program& program )
144 {
145   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
146   {
147     mVertexBuffers[i]->BindBuffer( context, program );
148   }
149
150   if( mIndexBuffer )
151   {
152     mIndexBuffer->BindBuffer( context, program );
153   }
154 }
155
156 void RenderGeometry::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
157 {
158   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
159   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
160   for( ; it != end; ++it )
161   {
162     (*it)->EnableVertexAttributes( context, bufferIndex, program );
163   }
164 }
165
166 void RenderGeometry::DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
167 {
168   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
169   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
170   for( ; it != end; ++it )
171   {
172     (*it)->DisableVertexAttributes( context, bufferIndex, program );
173   }
174 }
175
176 void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const RenderDataProvider* dataProvider )
177 {
178   const GeometryDataProvider& geometry = dataProvider->GetGeometry();
179   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
180
181   GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex );
182
183   unsigned int numIndices = 0;
184   if( indexBuffer )
185   {
186     numIndices = indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex);
187   }
188
189   switch(type)
190   {
191     case Dali::Geometry::TRIANGLES:
192     {
193       if( numIndices )
194       {
195         context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
196       }
197       else
198       {
199         const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
200         unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
201         context.DrawArrays( GL_TRIANGLES, 0, numVertices );
202       }
203       break;
204     }
205     case Dali::Geometry::LINES:
206     {
207       if( numIndices )
208       {
209         context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0);
210       }
211       else
212       {
213         const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
214         unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
215         context.DrawArrays( GL_LINES, 0, numVertices );
216       }
217       break;
218     }
219     case Dali::Geometry::POINTS:
220     {
221       const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
222       unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
223       context.DrawArrays(GL_POINTS, 0, numVertices );
224       break;
225     }
226     default:
227     {
228       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
229       break;
230     }
231   }
232 }
233
234 } // namespace SceneGraph
235 } // namespace Internal
236 } // namespace Dali