Remove Geometry scene object
[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 #include <dali/internal/common/buffer-index.h>
19 #include <dali/internal/render/gl-resources/context.h>
20 #include <dali/internal/render/gl-resources/gpu-buffer.h>
21 #include <dali/internal/render/renderers/render-property-buffer.h>
22 #include <dali/internal/render/shaders/program.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace Render
29 {
30
31 Geometry::Geometry()
32 : mIndices(),
33   mIndexBuffer(NULL),
34   mGeometryType( Dali::Geometry::TRIANGLES ),
35   mIndicesChanged(false),
36   mRequiresDepthTest(false ),
37   mHasBeenUpdated(false),
38   mAttributesChanged(true)
39 {
40 }
41
42 Geometry::~Geometry()
43 {
44 }
45
46 void Geometry::GlContextCreated( Context& context )
47 {
48 }
49
50 void Geometry::GlContextDestroyed()
51 {
52 }
53
54 void Geometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
55 {
56   mVertexBuffers.PushBack( propertyBuffer );
57   mAttributesChanged = true;
58 }
59
60 void Geometry::SetIndexBuffer( Dali::Vector<unsigned short>& indices )
61 {
62   mIndices.Swap( indices );
63   mIndicesChanged = true;
64 }
65
66 void Geometry::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
67 {
68   size_t bufferCount = mVertexBuffers.Size();
69   for( size_t i(0); i<bufferCount; ++i )
70   {
71     if( propertyBuffer == mVertexBuffers[i] )
72     {
73       //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
74       mVertexBuffers.Remove( mVertexBuffers.Begin()+i);
75       mAttributesChanged = true;
76       break;
77     }
78   }
79 }
80
81 void Geometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
82 {
83   attributeLocation.Clear();
84
85   for( size_t i(0); i< mVertexBuffers.Size(); ++i )
86   {
87     unsigned int attributeCount = mVertexBuffers[i]->GetAttributeCount();
88     for( unsigned int j = 0; j < attributeCount; ++j )
89     {
90       const std::string& attributeName = mVertexBuffers[i]->GetAttributeName( j );
91       unsigned int index = program.RegisterCustomAttribute( attributeName );
92       GLint location = program.GetCustomAttributeLocation( index );
93
94       if( -1 == location )
95       {
96         DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() );
97       }
98
99       attributeLocation.PushBack( location );
100     }
101   }
102 }
103
104 void Geometry::OnRenderFinished()
105 {
106   mHasBeenUpdated = false;
107   mAttributesChanged = false;
108 }
109
110 void Geometry::UploadAndDraw(
111     Context& context,
112     BufferIndex bufferIndex,
113     Vector<GLint>& attributeLocation,
114     size_t elementBufferOffset,
115     size_t elementBufferCount )
116 {
117   if( !mHasBeenUpdated )
118   {
119     // Update buffers
120     if( mIndicesChanged )
121     {
122       if( mIndices.Empty() )
123       {
124         mIndexBuffer = NULL;
125       }
126       else
127       {
128         if ( mIndexBuffer == NULL )
129         {
130           mIndexBuffer = new GpuBuffer( context );
131         }
132
133         std::size_t bufferSize =  sizeof( unsigned short ) * mIndices.Size();
134         mIndexBuffer->UpdateDataBuffer( bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER );
135       }
136
137       mIndicesChanged = false;
138     }
139
140     for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
141     {
142       if( !mVertexBuffers[i]->Update( context ) )
143       {
144         //Vertex buffer is not ready ( Size, data or format has not been specified yet )
145         return;
146       }
147     }
148
149     mHasBeenUpdated = true;
150   }
151
152   //Bind buffers to attribute locations
153   unsigned int base = 0u;
154   size_t vertexBufferCount(mVertexBuffers.Count());
155   for( unsigned int i = 0; i < vertexBufferCount; ++i )
156   {
157     mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER );
158     base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base );
159   }
160
161   GLenum geometryGLType(0);
162   unsigned int numIndices(0u);
163   intptr_t firstIndexOffset(0u);
164   if( mIndexBuffer )
165   {
166     numIndices = mIndices.Size();
167
168     if( elementBufferOffset )
169     {
170       elementBufferOffset = elementBufferOffset >= numIndices ? numIndices- 1 : elementBufferOffset;
171       firstIndexOffset = elementBufferOffset * sizeof(GLushort);
172     }
173     if ( elementBufferCount )
174     {
175       numIndices = std::min( elementBufferCount, numIndices - elementBufferOffset );
176     }
177   }
178
179   switch(mGeometryType)
180   {
181     case Dali::Geometry::TRIANGLES:
182     {
183       geometryGLType = GL_TRIANGLES;
184       break;
185     }
186     case Dali::Geometry::LINES:
187     {
188       geometryGLType = GL_LINES;
189       break;
190     }
191     case Dali::Geometry::POINTS:
192     {
193       geometryGLType = GL_POINTS;
194       break;
195     }
196     case Dali::Geometry::TRIANGLE_STRIP:
197     {
198       geometryGLType = GL_TRIANGLE_STRIP;
199       break;
200     }
201     case Dali::Geometry::TRIANGLE_FAN:
202     {
203       geometryGLType = GL_TRIANGLE_FAN;
204       break;
205     }
206     case Dali::Geometry::LINE_LOOP:
207     {
208       geometryGLType = GL_LINE_LOOP;
209       break;
210     }
211     case Dali::Geometry::LINE_STRIP:
212     {
213       geometryGLType = GL_LINE_STRIP;
214       break;
215     }
216     default:
217     {
218       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
219       break;
220     }
221   }
222
223   //Draw call
224   if( mIndexBuffer && geometryGLType != GL_POINTS )
225   {
226     //Indexed draw call
227     mIndexBuffer->Bind( GpuBuffer::ELEMENT_ARRAY_BUFFER );
228     context.DrawElements(geometryGLType, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset));
229   }
230   else
231   {
232     //Unindex draw call
233     unsigned int numVertices(0u);
234     if( vertexBufferCount > 0 )
235     {
236       numVertices = mVertexBuffers[0]->GetElementCount();
237     }
238
239     context.DrawArrays( geometryGLType, 0, numVertices );
240   }
241
242   //Disable attributes
243   for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
244   {
245     if( attributeLocation[i] != -1 )
246     {
247       context.DisableVertexAttributeArray( attributeLocation[i] );
248     }
249   }
250 }
251
252 } // namespace SceneGraph
253 } // namespace Internal
254 } // namespace Dali