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.
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>
34 mGeometryType( Dali::Geometry::TRIANGLES ),
35 mIndicesChanged(false),
36 mHasBeenUpdated(false),
37 mAttributesChanged(true)
45 void Geometry::GlContextCreated( Context& context )
49 void Geometry::GlContextDestroyed()
53 void Geometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer)
55 mVertexBuffers.PushBack( propertyBuffer );
56 mAttributesChanged = true;
59 void Geometry::SetIndexBuffer( Dali::Vector<unsigned short>& indices )
61 mIndices.Swap( indices );
62 mIndicesChanged = true;
65 const Dali::Vector<unsigned short>* Geometry::GetIndexBuffer() const
70 void Geometry::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
72 size_t bufferCount = mVertexBuffers.Size();
73 for( size_t i(0); i<bufferCount; ++i )
75 if( propertyBuffer == mVertexBuffers[i] )
77 //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
78 mVertexBuffers.Remove( mVertexBuffers.Begin()+i );
79 mAttributesChanged = true;
85 const Render::PropertyBuffer* Geometry::GetPropertyBuffer( size_t index ) const
87 if( index < mVertexBuffers.Size() )
89 return mVertexBuffers[ index ];
94 void Geometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
96 attributeLocation.Clear();
98 for( size_t i(0); i< mVertexBuffers.Size(); ++i )
100 unsigned int attributeCount = mVertexBuffers[i]->GetAttributeCount();
101 for( unsigned int j = 0; j < attributeCount; ++j )
103 const std::string& attributeName = mVertexBuffers[i]->GetAttributeName( j );
104 unsigned int index = program.RegisterCustomAttribute( attributeName );
105 GLint location = program.GetCustomAttributeLocation( index );
109 DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() );
112 attributeLocation.PushBack( location );
117 void Geometry::OnRenderFinished()
119 mHasBeenUpdated = false;
120 mAttributesChanged = false;
123 void Geometry::UploadAndDraw(
125 BufferIndex bufferIndex,
126 Vector<GLint>& attributeLocation,
127 size_t elementBufferOffset,
128 size_t elementBufferCount )
130 if( !mHasBeenUpdated )
133 if( mIndicesChanged )
135 if( mIndices.Empty() )
141 if ( mIndexBuffer == NULL )
143 mIndexBuffer = new GpuBuffer( context );
146 std::size_t bufferSize = sizeof( unsigned short ) * mIndices.Size();
147 mIndexBuffer->UpdateDataBuffer( bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER );
150 mIndicesChanged = false;
153 size_t count = mVertexBuffers.Count();
154 for( unsigned int i = 0; i < count; ++i )
157 if( !mVertexBuffers[i]->Update( context ) )
159 //Vertex buffer is not ready ( Size, data or format has not been specified yet )
164 mHasBeenUpdated = true;
167 //Bind buffers to attribute locations
168 unsigned int base = 0u;
169 size_t vertexBufferCount(mVertexBuffers.Count());
170 for( unsigned int i = 0; i < vertexBufferCount; ++i )
172 mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER );
173 base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base );
176 size_t numIndices(0u);
177 intptr_t firstIndexOffset(0u);
180 numIndices = mIndices.Size();
182 if( elementBufferOffset != 0u )
184 elementBufferOffset = elementBufferOffset >= numIndices ? numIndices - 1 : elementBufferOffset;
185 firstIndexOffset = elementBufferOffset * sizeof(GLushort);
186 numIndices -= elementBufferOffset;
189 if( elementBufferCount != 0u )
191 numIndices = std::min( elementBufferCount, numIndices );
195 GLenum geometryGLType(GL_NONE);
196 switch(mGeometryType)
198 case Dali::Geometry::TRIANGLES:
200 geometryGLType = GL_TRIANGLES;
203 case Dali::Geometry::LINES:
205 geometryGLType = GL_LINES;
208 case Dali::Geometry::POINTS:
210 geometryGLType = GL_POINTS;
213 case Dali::Geometry::TRIANGLE_STRIP:
215 geometryGLType = GL_TRIANGLE_STRIP;
218 case Dali::Geometry::TRIANGLE_FAN:
220 geometryGLType = GL_TRIANGLE_FAN;
223 case Dali::Geometry::LINE_LOOP:
225 geometryGLType = GL_LINE_LOOP;
228 case Dali::Geometry::LINE_STRIP:
230 geometryGLType = GL_LINE_STRIP;
236 if( mIndexBuffer && geometryGLType != GL_POINTS )
239 mIndexBuffer->Bind( GpuBuffer::ELEMENT_ARRAY_BUFFER );
240 context.DrawElements(geometryGLType, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset));
245 unsigned int numVertices(0u);
246 if( vertexBufferCount > 0 )
248 numVertices = mVertexBuffers[0]->GetElementCount();
251 context.DrawArrays( geometryGLType, 0, numVertices );
255 for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
257 if( attributeLocation[i] != -1 )
259 context.DisableVertexAttributeArray( attributeLocation[i] );
264 } // namespace SceneGraph
265 } // namespace Internal