PropertyBuffer Attributes.
[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/geometry/scene-graph-geometry.h>
21 #include <dali/internal/update/common/scene-graph-property-buffer.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 //  BindBuffers( context, bufferIndex, program );
73 //  EnableVertexAttributes( context, bufferIndex, program );
74   Draw( context, bufferIndex, dataProviders );
75
76   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
77   {
78     mVertexBuffers[i]->DisableVertexAttributes( context, bufferIndex, program );
79   }
80   //DisableVertexAttributes( context, bufferIndex, program );
81 }
82
83 void RenderGeometry::GeometryUpdated()
84 {
85   mDataNeedsUploading = true;
86 }
87
88 void RenderGeometry::UploadVertexData(
89   Context& context,
90   BufferIndex bufferIndex,
91   const RenderDataProvider* dataProviders )
92 {
93   if( mDataNeedsUploading ) // @todo Or if any of the property buffers are dirty
94   {
95     DoUpload( context, bufferIndex, dataProviders );
96
97     mDataNeedsUploading = false;
98   }
99 }
100
101 void RenderGeometry::DoUpload(
102   Context& context,
103   BufferIndex bufferIndex,
104   const RenderDataProvider* dataProvider )
105 {
106   // Vertex buffer
107   RenderDataProvider::VertexBuffers vertexBuffers = dataProvider->GetVertexBuffers();
108
109   DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" );
110
111   for( unsigned int i=0; i<vertexBuffers.Count(); ++i)
112   {
113     const PropertyBufferDataProvider* vertexBuffer = vertexBuffers[i];
114
115     RenderPropertyBuffer* propertyBuffer = new RenderPropertyBuffer( *vertexBuffer, false );
116
117     propertyBuffer->DoUpload( context, bufferIndex );
118
119     mVertexBuffers.PushBack( propertyBuffer );
120   }
121
122   // Index buffer
123   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
124   if( indexBuffer )
125   {
126     mIndexBuffer = new RenderPropertyBuffer( *indexBuffer, true );
127
128     mIndexBuffer->DoUpload( context, bufferIndex );
129   }
130 }
131
132 void RenderGeometry::BindBuffers( Context& context, BufferIndex bufferIndex, Program& program )
133 {
134   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
135   {
136     mVertexBuffers[i]->BindBuffer( context, program );
137   }
138
139   if( mIndexBuffer )
140   {
141     mIndexBuffer->BindBuffer( context, program );
142   }
143 }
144
145 void RenderGeometry::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
146 {
147   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
148   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
149   for( ; it != end; ++it )
150   {
151     (*it)->EnableVertexAttributes( context, bufferIndex, program );
152   }
153 }
154
155 void RenderGeometry::DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program )
156 {
157   OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin();
158   OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End();
159   for( ; it != end; ++it )
160   {
161     (*it)->DisableVertexAttributes( context, bufferIndex, program );
162   }
163 }
164
165 void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const RenderDataProvider* dataProvider )
166 {
167   const GeometryDataProvider& geometry = dataProvider->GetGeometry();
168   const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer();
169
170   GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex );
171
172   unsigned int numIndices = 0;
173   if( indexBuffer )
174   {
175     numIndices = /* TODO: MESH_REWORK remove this 2, should implement unsigned short properties  */ 2 * indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex);
176   }
177
178   switch(type)
179   {
180     case Dali::Geometry::TRIANGLES:
181     {
182       context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
183       break;
184     }
185     case Dali::Geometry::LINES:
186     {
187       context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0);
188       break;
189     }
190     case Dali::Geometry::POINTS:
191     {
192       const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0];
193
194       unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex );
195       context.DrawArrays(GL_POINTS, 0, numVertices );
196       break;
197     }
198     default:
199     {
200       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
201       break;
202     }
203   }
204 }
205
206 } // namespace SceneGraph
207 } // namespace Internal
208 } // namespace Dali