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>
31 RenderGeometry::RenderGeometry( GeometryType type, bool requiresDepthTest )
33 mGeometryType( type ),
34 mRequiresDepthTest(requiresDepthTest ),
35 mHasBeenUpdated(false),
36 mAttributesChanged(true)
40 RenderGeometry::~RenderGeometry()
44 void RenderGeometry::GlContextCreated( Context& context )
48 void RenderGeometry::GlContextDestroyed()
52 void RenderGeometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer, bool isIndexBuffer )
56 mIndexBuffer = propertyBuffer;
60 mVertexBuffers.PushBack( propertyBuffer );
61 mAttributesChanged = true;
65 void RenderGeometry::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
67 if( propertyBuffer == mIndexBuffer )
73 size_t bufferCount = mVertexBuffers.Size();
74 for( size_t i(0); i<bufferCount; ++i )
76 if( propertyBuffer == mVertexBuffers[i] )
78 //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
79 mVertexBuffers.Remove( mVertexBuffers.Begin()+i);
80 mAttributesChanged = true;
87 void RenderGeometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
89 attributeLocation.Clear();
91 for( size_t i(0); i< mVertexBuffers.Size(); ++i )
93 unsigned int attributeCount = mVertexBuffers[i]->GetAttributeCount();
94 for( unsigned int j = 0; j < attributeCount; ++j )
96 const std::string& attributeName = mVertexBuffers[i]->GetAttributeName( j );
97 unsigned int index = program.RegisterCustomAttribute( attributeName );
98 GLint location = program.GetCustomAttributeLocation( index );
102 DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() );
105 attributeLocation.PushBack( location );
110 void RenderGeometry::OnRenderFinished()
112 mHasBeenUpdated = false;
113 mAttributesChanged = false;
116 void RenderGeometry::UploadAndDraw(
118 BufferIndex bufferIndex,
119 Vector<GLint>& attributeLocation,
120 size_t elementBufferOffset,
121 size_t elementBufferCount )
123 if( !mHasBeenUpdated )
128 if(!mIndexBuffer->Update( context, true ) )
130 //Index buffer is not ready ( Size, data or format has not been specified yet )
135 for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
137 if( !mVertexBuffers[i]->Update( context, false ) )
139 //Vertex buffer is not ready ( Size, data or format has not been specified yet )
144 mHasBeenUpdated = true;
147 //Bind buffers to attribute locations
148 unsigned int base = 0;
149 for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
151 mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER );
152 base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base );
157 mIndexBuffer->BindBuffer( GpuBuffer::ELEMENT_ARRAY_BUFFER );
161 unsigned int numIndices(0u);
162 intptr_t firstIndexOffset(0u);
165 numIndices = mIndexBuffer->GetDataSize() / mIndexBuffer->GetElementSize();
166 if ( elementBufferCount )
168 numIndices = elementBufferCount > numIndices ? numIndices : elementBufferCount;
170 firstIndexOffset = elementBufferOffset * sizeof(GLushort);
174 switch(mGeometryType)
176 case Dali::Geometry::TRIANGLES:
180 context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
184 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
185 context.DrawArrays( GL_TRIANGLES, 0, numVertices );
189 case Dali::Geometry::LINES:
193 context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
197 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
198 context.DrawArrays( GL_LINES, 0, numVertices );
202 case Dali::Geometry::POINTS:
204 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
205 context.DrawArrays(GL_POINTS, 0, numVertices );
208 case Dali::Geometry::TRIANGLE_STRIP:
212 context.DrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
216 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
217 context.DrawArrays(GL_TRIANGLE_STRIP, 0, numVertices );
221 case Dali::Geometry::TRIANGLE_FAN:
225 context.DrawElements(GL_TRIANGLE_FAN, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
229 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
230 context.DrawArrays(GL_TRIANGLE_FAN, 0, numVertices );
234 case Dali::Geometry::LINE_LOOP:
238 context.DrawElements(GL_LINE_LOOP, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
242 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
243 context.DrawArrays(GL_LINE_LOOP, 0, numVertices );
247 case Dali::Geometry::LINE_STRIP:
251 context.DrawElements(GL_LINE_STRIP, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset) );
255 unsigned int numVertices = mVertexBuffers[0]->GetElementCount();
256 context.DrawArrays(GL_LINE_STRIP, 0, numVertices );
262 DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
268 for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
270 if( attributeLocation[i] != -1 )
272 context.DisableVertexAttributeArray( attributeLocation[i] );
277 } // namespace SceneGraph
278 } // namespace Internal