9494d9f9b0cf9473adb3b4db11bb827e3dcd74a6
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / wireframe / wireframe-visual.cpp
1 /*
2  * Copyright (c) 2022 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
18 // CLASS HEADER
19 #include "wireframe-visual.h"
20
21 // INTERNAL INCLUDES
22 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
23 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
24 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
25 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
26 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
27 #include <dali-toolkit/public-api/visuals/visual-properties.h>
28
29 namespace Dali
30 {
31 namespace Toolkit
32 {
33 namespace Internal
34 {
35 namespace
36 {
37 const int         CUSTOM_PROPERTY_COUNT(5);
38 const char* const POSITION_ATTRIBUTE_NAME("aPosition");
39 const char* const INDEX_NAME("indices");
40 } // namespace
41
42 WireframeVisualPtr WireframeVisual::New(VisualFactoryCache& factoryCache, const Property::Map& properties)
43 {
44   Visual::BasePtr emtptyVisual;
45
46   return New(factoryCache, emtptyVisual, properties);
47 }
48
49 WireframeVisualPtr WireframeVisual::New(VisualFactoryCache& factoryCache, Visual::BasePtr actualVisual)
50 {
51   WireframeVisualPtr wireframeVisual(new WireframeVisual(factoryCache, actualVisual));
52   wireframeVisual->Initialize();
53   return wireframeVisual;
54 }
55
56 WireframeVisualPtr WireframeVisual::New(VisualFactoryCache& factoryCache, Visual::BasePtr actualVisual, const Property::Map& properties)
57 {
58   WireframeVisualPtr wireframeVisual(new WireframeVisual(factoryCache, actualVisual));
59
60   // Instead of calling SetProperties, looking for the only valid property 'transform'
61   Property::Value* transformValue = properties.Find(Toolkit::Visual::Property::TRANSFORM, TRANSFORM);
62   Property::Map    transformMap;
63   if(transformValue && transformValue->Get(transformMap))
64   {
65     wireframeVisual->SetTransformAndSize(transformMap, Vector2::ZERO);
66   }
67   wireframeVisual->Initialize();
68   return wireframeVisual;
69 }
70
71 WireframeVisual::WireframeVisual(VisualFactoryCache& factoryCache, Visual::BasePtr actualVisual)
72 : Visual::Base(factoryCache, Visual::FittingMode::FILL, actualVisual ? actualVisual->GetType() : Toolkit::Visual::WIREFRAME),
73   mActualVisual(actualVisual)
74 {
75 }
76
77 WireframeVisual::~WireframeVisual()
78 {
79 }
80
81 float WireframeVisual::GetHeightForWidth(float width)
82 {
83   if(mActualVisual)
84   {
85     return mActualVisual->GetHeightForWidth(width);
86   }
87   else
88   {
89     return Visual::Base::GetHeightForWidth(width);
90   }
91 }
92
93 void WireframeVisual::GetNaturalSize(Vector2& naturalSize)
94 {
95   if(mActualVisual)
96   {
97     mActualVisual->GetNaturalSize(naturalSize);
98   }
99   else
100   {
101     Visual::Base::GetNaturalSize(naturalSize);
102   }
103 }
104
105 void WireframeVisual::DoCreatePropertyMap(Property::Map& map) const
106 {
107   if(mActualVisual)
108   {
109     mActualVisual->CreatePropertyMap(map);
110   }
111   else
112   {
113     map.Clear();
114     map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::WIREFRAME);
115   }
116 }
117
118 void WireframeVisual::DoCreateInstancePropertyMap(Property::Map& map) const
119 {
120   // Do nothing
121 }
122
123 void WireframeVisual::DoSetProperties(const Property::Map& propertyMap)
124 {
125   Property::Value* mixValue = propertyMap.Find(Toolkit::Visual::Property::MIX_COLOR, MIX_COLOR);
126   if(mixValue)
127   {
128     Vector4 mixColor;
129     mixValue->Get(mixColor);
130     SetMixColor(mixColor);
131   }
132 }
133
134 void WireframeVisual::DoSetOnScene(Actor& actor)
135 {
136   actor.AddRenderer(mImpl->mRenderer);
137
138   // Wireframe generated and ready to display
139   ResourceReady(Toolkit::Visual::ResourceStatus::READY);
140 }
141
142 void WireframeVisual::OnInitialize()
143 {
144   Shader shader = mFactoryCache.GetShader(VisualFactoryCache::WIREFRAME_SHADER);
145   if(!shader)
146   {
147     shader = Shader::New(SHADER_WIREFRAME_VISUAL_SHADER_VERT, SHADER_WIREFRAME_VISUAL_SHADER_FRAG);
148     mFactoryCache.SaveShader(VisualFactoryCache::WIREFRAME_SHADER, shader);
149   }
150
151   Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::WIREFRAME_GEOMETRY);
152   if(!geometry)
153   {
154     geometry = CreateQuadWireframeGeometry();
155     mFactoryCache.SaveGeometry(VisualFactoryCache::WIREFRAME_GEOMETRY, geometry);
156   }
157
158   //Create the renderer
159   mImpl->mRenderer = Renderer::New(geometry, shader);
160   mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
161
162   //Register transform properties
163   mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
164 }
165
166 Geometry WireframeVisual::CreateQuadWireframeGeometry()
167 {
168   const float halfWidth  = 0.5f;
169   const float halfHeight = 0.5f;
170   struct QuadVertex
171   {
172     Vector2 position;
173   };
174   QuadVertex quadVertexData[4] =
175     {
176       {Vector2(-halfWidth, -halfHeight)},
177       {Vector2(halfWidth, -halfHeight)},
178       {Vector2(halfWidth, halfHeight)},
179       {Vector2(-halfWidth, halfHeight)}};
180
181   Property::Map quadVertexFormat;
182   quadVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
183   VertexBuffer quadVertices                 = VertexBuffer::New(quadVertexFormat);
184   quadVertices.SetData(quadVertexData, 4);
185
186   // Create indices
187   unsigned short indexData[10] = {0, 1, 1, 2, 2, 3, 3, 0};
188
189   // Create the geometry object
190   Geometry geometry = Geometry::New();
191   geometry.AddVertexBuffer(quadVertices);
192   geometry.SetIndexBuffer(indexData, sizeof(indexData) / sizeof(indexData[0]));
193   geometry.SetType(Geometry::LINES);
194
195   return geometry;
196 }
197
198 void WireframeVisual::OnSetTransform()
199 {
200   if(mImpl->mRenderer)
201   {
202     //Register transform properties
203     mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
204   }
205 }
206
207 Visual::Base& WireframeVisual::GetVisualObject()
208 {
209   if(mActualVisual)
210   {
211     return *mActualVisual.Get();
212   }
213
214   return *this;
215 }
216
217 } // namespace Internal
218
219 } // namespace Toolkit
220
221 } // namespace Dali