Merge "Removed DepthIndex methods from public-api" into devel/new_mesh
[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, 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   BufferIndex bufferIndex,
88   const RenderDataProvider* dataProviders )
89 {
90   if( mDataNeedsUploading )
91   {
92     SetUpPropertyBuffers( context, bufferIndex, dataProviders );
93
94     for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
95     {
96       mVertexBuffers[i]->Upload( context, bufferIndex );
97     }
98     if( mIndexBuffer )
99     {
100       mIndexBuffer->Upload( context, bufferIndex );
101     }
102
103     mDataNeedsUploading = false;
104   }
105 }
106
107 void RenderGeometry::SetUpPropertyBuffers(
108   Context& context,
109   BufferIndex bufferIndex,
110   const RenderDataProvider* dataProvider )
111 {
112   // Vertex buffer
113   RenderDataProvider::VertexBuffers vertexBuffers = dataProvider->GetVertexBuffers();
114
115   DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" );
116
117   for( unsigned int i=0; i<vertexBuffers.Count(); ++i)
118   {
119     const PropertyBufferDataProvider* vertexBuffer = vertexBuffers[i];
120
121     RenderPropertyBuffer* propertyBuffer = new RenderPropertyBuffer(
122       *vertexBuffer,
123       GpuBuffer::ARRAY_BUFFER,
124       GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes
125
126     mVertexBuffers.PushBack( propertyBuffer );
127   }
128
129   // Index buffer
130   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
131   if( indexBuffer )
132   {
133     mIndexBuffer = new RenderPropertyBuffer(
134       *indexBuffer,
135       GpuBuffer::ELEMENT_ARRAY_BUFFER,
136       GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes
137   }
138 }
139
140 void RenderGeometry::BindBuffers( Context& context, BufferIndex bufferIndex, Program& program )
141 {
142   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
143   {
144     mVertexBuffers[i]->BindBuffer( context, program );
145   }
146
147   if( mIndexBuffer )
148   {
149     mIndexBuffer->BindBuffer( context, program );
150   }
151 }
152
153 void RenderGeometry::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
154 {
155   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
156   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
157   for( ; it != end; ++it )
158   {
159     (*it)->EnableVertexAttributes( context, bufferIndex, program );
160   }
161 }
162
163 void RenderGeometry::DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
164 {
165   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
166   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
167   for( ; it != end; ++it )
168   {
169     (*it)->DisableVertexAttributes( context, bufferIndex, program );
170   }
171 }
172
173 void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const RenderDataProvider* dataProvider )
174 {
175   const GeometryDataProvider& geometry = dataProvider->GetGeometry();
176   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
177
178   GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex );
179
180   unsigned int numIndices = 0;
181   if( indexBuffer )
182   {
183     numIndices = indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex);
184   }
185
186   switch(type)
187   {
188     case Dali::Geometry::TRIANGLES:
189     {
190       if( numIndices )
191       {
192         context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
193       }
194       else
195       {
196         const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
197         unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
198         context.DrawArrays( GL_TRIANGLES, 0, numVertices );
199       }
200       break;
201     }
202     case Dali::Geometry::LINES:
203     {
204       if( numIndices )
205       {
206         context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0);
207       }
208       else
209       {
210         const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
211         unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
212         context.DrawArrays( GL_LINES, 0, numVertices );
213       }
214       break;
215     }
216     case Dali::Geometry::POINTS:
217     {
218       const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
219       unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
220       context.DrawArrays(GL_POINTS, 0, numVertices );
221       break;
222     }
223     default:
224     {
225       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
226       break;
227     }
228   }
229 }
230
231 } // namespace SceneGraph
232 } // namespace Internal
233 } // namespace Dali