2 * Copyright (c) 2021 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.
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali/dali.h>
24 #include "generated/native-image-source-texture-frag.h"
25 #include "generated/native-image-source-texture-vert.h"
26 #include "shared/utility.h"
29 using namespace Toolkit;
33 const float BUTTON_HEIGHT = 100.0f;
34 const float BUTTON_COUNT = 5.0f;
36 const std::string JPG_FILENAME = DEMO_IMAGE_DIR "gallery-medium-4.jpg";
37 const std::string CAPTURE_FILENAME = DEMO_DATA_PUBLIC_RW_DIR "native-image-capture.png";
40 * @brief Creates a shader used to render a native image
41 * @param[in] nativeImage The native image
42 * @return A shader to render the native image
44 Shader CreateShader(NativeImageInterface& nativeImage)
46 std::string fragmentShader;
48 //Get custom fragment shader prefix
49 fragmentShader = SHADER_NATIVE_IMAGE_SOURCE_TEXTURE_FRAG.data();
50 nativeImage.ApplyNativeFragmentShader(fragmentShader);
52 return Shader::New(SHADER_NATIVE_IMAGE_SOURCE_TEXTURE_VERT, fragmentShader);
57 // This example shows how to create and use a NativeImageSource as the target of the render task.
59 class NativeImageSourceController : public ConnectionTracker
62 NativeImageSourceController(Application& application)
63 : mApplication(application),
66 // Connect to the Application's Init signal
67 mApplication.InitSignal().Connect(this, &NativeImageSourceController::Create);
70 ~NativeImageSourceController()
72 // Nothing to do here;
75 // The Init signal is received once (only) during the Application lifetime
76 void Create(Application& application)
78 // Get a handle to the window
79 Window window = application.GetWindow();
80 window.SetBackgroundColor(Color::WHITE);
82 window.KeyEventSignal().Connect(this, &NativeImageSourceController::OnKeyEvent);
89 void CreateButtonArea()
91 Window window = mApplication.GetWindow();
92 Vector2 windowSize = window.GetSize();
94 mButtonArea = Layer::New();
95 mButtonArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, BUTTON_HEIGHT));
96 mButtonArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
97 mButtonArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
98 window.Add(mButtonArea);
100 mButtonShow = PushButton::New();
101 mButtonShow.SetProperty(Button::Property::TOGGLABLE, true);
102 mButtonShow.SetProperty(Toolkit::Button::Property::LABEL, "SHOW");
103 mButtonShow.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
104 mButtonShow.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
105 mButtonShow.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
106 mButtonShow.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
107 mButtonArea.Add(mButtonShow);
109 mButtonRefreshAlways = PushButton::New();
110 mButtonRefreshAlways.SetProperty(Button::Property::TOGGLABLE, true);
111 mButtonRefreshAlways.SetProperty(Toolkit::Button::Property::LABEL, "ALWAYS");
112 mButtonRefreshAlways.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
113 mButtonRefreshAlways.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
114 mButtonRefreshAlways.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
115 mButtonRefreshAlways.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 1.0f, 0.0f));
116 mButtonRefreshAlways.StateChangedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
117 mButtonArea.Add(mButtonRefreshAlways);
119 mButtonRefreshOnce = PushButton::New();
120 mButtonRefreshOnce.SetProperty(Toolkit::Button::Property::LABEL, "ONCE");
121 mButtonRefreshOnce.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
122 mButtonRefreshOnce.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
123 mButtonRefreshOnce.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
124 mButtonRefreshOnce.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 2.0f, 0.0f));
125 mButtonRefreshOnce.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
126 mButtonArea.Add(mButtonRefreshOnce);
128 mButtonCapture = PushButton::New();
129 mButtonCapture.SetProperty(Toolkit::Button::Property::LABEL, "CAPTURE");
130 mButtonCapture.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
131 mButtonCapture.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
132 mButtonCapture.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
133 mButtonCapture.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 3.0f, 0.0f));
134 mButtonCapture.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
135 mButtonArea.Add(mButtonCapture);
137 mButtonReset = PushButton::New();
138 mButtonReset.SetProperty(Toolkit::Button::Property::LABEL, "RESET");
139 mButtonReset.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
140 mButtonReset.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
141 mButtonReset.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
142 mButtonReset.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 4.0f, 0.0f));
143 mButtonReset.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
144 mButtonArea.Add(mButtonReset);
147 void CreateContentAreas()
149 Window window = mApplication.GetWindow();
150 Vector2 windowSize = window.GetSize();
152 float contentHeight((windowSize.y - BUTTON_HEIGHT) / 2.0f);
154 mTopContentArea = Actor::New();
155 mTopContentArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, contentHeight));
156 mTopContentArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
157 mTopContentArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
158 mTopContentArea.SetProperty(Actor::Property::POSITION_Y, BUTTON_HEIGHT);
159 window.Add(mTopContentArea);
161 mBottomContentArea = Actor::New();
162 mBottomContentArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, contentHeight));
163 mBottomContentArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
164 mBottomContentArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
165 window.Add(mBottomContentArea);
167 mSourceActor = ImageView::New(JPG_FILENAME);
168 mSourceActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
169 mSourceActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
170 mTopContentArea.Add(mSourceActor);
172 Animation animation = Animation::New(2.f);
173 Degree relativeRotationDegrees(90.0f);
174 Radian relativeRotationRadians(relativeRotationDegrees);
175 animation.AnimateTo(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(0.f, 0.5f));
176 animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(0.5f, 0.5f));
177 animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(1.f, 0.5f));
178 animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(1.5f, 0.5f));
179 animation.SetLooping(true);
182 TextLabel textLabel1 = TextLabel::New("Image");
183 textLabel1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
184 textLabel1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
185 mTopContentArea.Add(textLabel1);
187 // Wait until button press before creating mOffscreenRenderTask
189 TextLabel textLabel2 = TextLabel::New("Native Image");
190 textLabel2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
191 textLabel2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
192 mBottomContentArea.Add(textLabel2);
195 void SetupNativeImage()
197 if(!mOffscreenRenderTask)
199 Window window = mApplication.GetWindow();
200 Vector2 windowSize = window.GetSize();
202 float contentHeight((windowSize.y - BUTTON_HEIGHT) / 2.0f);
203 Vector2 imageSize(windowSize.x, contentHeight);
205 mNativeImageSourcePtr = NativeImageSource::New(imageSize.width, imageSize.height, NativeImageSource::COLOR_DEPTH_DEFAULT);
206 mNativeTexture = Texture::New(*mNativeImageSourcePtr);
208 mFrameBuffer = FrameBuffer::New(mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), FrameBuffer::Attachment::NONE);
209 mFrameBuffer.AttachColorTexture(mNativeTexture);
211 mCameraActor = CameraActor::New(imageSize);
212 mCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
213 mCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
214 mTopContentArea.Add(mCameraActor);
216 RenderTaskList taskList = window.GetRenderTaskList();
217 mOffscreenRenderTask = taskList.CreateTask();
218 mOffscreenRenderTask.SetSourceActor(mSourceActor);
219 mOffscreenRenderTask.SetClearColor(Color::WHITE);
220 mOffscreenRenderTask.SetClearEnabled(true);
221 mOffscreenRenderTask.SetCameraActor(mCameraActor);
222 mOffscreenRenderTask.GetCameraActor().SetInvertYAxis(true);
223 mOffscreenRenderTask.SetFrameBuffer(mFrameBuffer);
228 mOffscreenRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
232 mOffscreenRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
236 void SetupDisplayActor(bool show)
242 // Make sure we have something to display
245 mDisplayActor = Actor::New();
246 mDisplayActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
247 mDisplayActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
249 Geometry geometry = DemoHelper::CreateTexturedQuad();
251 Shader shader = CreateShader(*mNativeImageSourcePtr);
253 Renderer renderer = Renderer::New(geometry, shader);
255 TextureSet textureSet = TextureSet::New();
256 textureSet.SetTexture(0u, mNativeTexture);
257 renderer.SetTextures(textureSet);
259 mDisplayActor.AddRenderer(renderer);
260 mDisplayActor.SetProperty(Actor::Property::SIZE, Vector2(mNativeTexture.GetWidth(), mNativeTexture.GetHeight()));
262 mBottomContentArea.Add(mDisplayActor);
267 UnparentAndReset(mDisplayActor);
273 mRefreshAlways = false;
276 mOffscreenRenderTask.FinishedSignal().Connect(this, &NativeImageSourceController::DoCapture);
279 void DoCapture(RenderTask& task)
281 task.FinishedSignal().Disconnect(this, &NativeImageSourceController::DoCapture);
283 mNativeImageSourcePtr->EncodeToFile(CAPTURE_FILENAME);
288 SetupDisplayActor(false);
290 Window window = mApplication.GetWindow();
291 RenderTaskList taskList = window.GetRenderTaskList();
292 taskList.RemoveTask(mOffscreenRenderTask);
293 mOffscreenRenderTask.Reset();
294 mCameraActor.Reset();
296 mFrameBuffer.Reset();
297 mNativeTexture.Reset();
298 mNativeImageSourcePtr.Reset();
301 bool OnButtonSelected(Toolkit::Button button)
303 Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast(button);
305 if(pushButton == mButtonShow)
307 bool isSelected = mButtonShow.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
309 SetupDisplayActor(isSelected);
311 else if(pushButton == mButtonRefreshAlways)
313 bool isSelected = mButtonRefreshAlways.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
315 mRefreshAlways = isSelected;
318 else if(pushButton == mButtonRefreshOnce)
320 bool isSelected = mButtonRefreshAlways.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
324 mButtonRefreshAlways.SetProperty(Button::Property::SELECTED, false);
327 mRefreshAlways = false;
330 else if(pushButton == mButtonCapture)
334 else if(pushButton == mButtonReset)
342 void OnKeyEvent(const KeyEvent& event)
344 if(event.GetState() == KeyEvent::DOWN)
346 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
354 Application& mApplication;
357 Actor mTopContentArea;
358 Actor mBottomContentArea;
360 PushButton mButtonShow;
361 PushButton mButtonRefreshAlways;
362 PushButton mButtonRefreshOnce;
363 PushButton mButtonCapture;
364 PushButton mButtonReset;
368 NativeImageSourcePtr mNativeImageSourcePtr;
369 Texture mNativeTexture;
370 FrameBuffer mFrameBuffer;
372 RenderTask mOffscreenRenderTask;
373 CameraActor mCameraActor;
380 int DALI_EXPORT_API main(int argc, char** argv)
382 Application application = Application::New(&argc, &argv);
383 NativeImageSourceController test(application);
384 application.MainLoop();