Added Rendering tutorials 41/121741/2
authoradam.b <adam.b@samsung.com>
Tue, 28 Mar 2017 15:27:16 +0000 (16:27 +0100)
committeradam.b <adam.b@samsung.com>
Tue, 28 Mar 2017 16:22:47 +0000 (17:22 +0100)
- Drawing line
- Drawing triangle
- Drawing colored cube
- Drawing textured cube

Change-Id: Ibcb3826dd67b0e6a3146dc1b22dbbeab7b4a805c

16 files changed:
com.samsung.dali-demo.xml
demo/dali-demo.cpp
examples/rendering-cube/rendering-cube.cpp [new file with mode: 0644]
examples/rendering-line/rendering-line.cpp [new file with mode: 0644]
examples/rendering-textured-cube/rendering-textured-cube.cpp [new file with mode: 0644]
examples/rendering-triangle/rendering-triangle.cpp [new file with mode: 0644]
resources/po/as.po
resources/po/de.po
resources/po/en_GB.po
resources/po/en_US.po
resources/po/es.po
resources/po/ko.po
resources/po/ml.po
resources/po/ur.po
resources/po/zn_CH.po
shared/dali-demo-strings.h

index 5c0b6af..3db69ee 100644 (file)
        <ui-application appid="styling.example" exec="/usr/apps/com.samsung.dali-demo/bin/styling.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
                <label>Styling</label>
        </ui-application>
+       <ui-application appid="rendering-cube.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-cube.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
+               <label>Rendering Cube</label>
+       </ui-application>
+       <ui-application appid="rendering-line.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-line.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
+               <label>Rendering Line</label>
+       </ui-application>
+       <ui-application appid="rendering-textured-cube.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-textured-cube.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
+               <label>Rendering Textured Cube</label>
+       </ui-application>
+       <ui-application appid="rendering-triangle.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-triangle.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
+               <label>Rendering Triangle</label>
+       </ui-application>
 </manifest>
index 924d8f2..cebd1d0 100644 (file)
@@ -80,6 +80,10 @@ int DALI_EXPORT_API main(int argc, char **argv)
   demo.AddExample(Example("mesh-visual.example", DALI_DEMO_STR_TITLE_MESH_VISUAL));
   demo.AddExample(Example("primitive-shapes.example", DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES));
   demo.AddExample(Example("styling.example", DALI_DEMO_STR_TITLE_STYLING));
+  demo.AddExample(Example("rendering-line.example", DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE));
+  demo.AddExample(Example("rendering-triangle.example", DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE));
+  demo.AddExample(Example("rendering-cube.example", DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE));
+  demo.AddExample(Example("rendering-textured-cube.example", DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE));
 
   demo.SortAlphabetically( true );
 
diff --git a/examples/rendering-cube/rendering-cube.cpp b/examples/rendering-cube/rendering-cube.cpp
new file mode 100644 (file)
index 0000000..7fda202
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+/*
+ * Vertex shader
+ */
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+attribute mediump vec3 aPosition;\n // DALi shader builtin
+attribute mediump vec3 aColor;\n // DALi shader builtin
+uniform   mediump mat4 uMvpMatrix;\n // DALi shader builtin
+uniform   mediump vec3 uSize;\n // DALi shader builtin
+\n
+varying mediump vec4 vColor;\n
+\n
+void main()\n
+{\n
+  mediump vec4 vertexPosition = vec4(aPosition, 1.0);\n
+  vertexPosition.xyz *= uSize;\n
+  vColor = vec4( aColor, 1.0 );\n
+  gl_Position = uMvpMatrix * vertexPosition;\n
+}\n
+);
+
+/*
+ * Fragment shader
+ */
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+varying mediump vec4 vColor;\n
+\n
+void main()\n
+{\n
+  gl_FragColor = vColor;\n
+}\n
+);
+
+}
+
+// This example shows how to create a cube with colors on each side
+//
+class DrawCubeController : public ConnectionTracker
+{
+public:
+
+  DrawCubeController( Application& application )
+  : mApplication( application )
+  {
+    // Connect to the Application's Init signal
+    mApplication.InitSignal().Connect( this, &DrawCubeController::Create );
+  }
+
+  ~DrawCubeController()
+  {
+    // Nothing to do here;
+  }
+
+  // The Init signal is received once (only) during the Application lifetime
+  void Create( Application& application )
+  {
+    // Get a handle to the stage
+    Stage stage = Stage::GetCurrent();
+    stage.SetBackgroundColor( Color::WHITE );
+
+    // Step 1. Create shader
+    CreateCubeShader();
+
+    // Step 2. Prepare geometry
+    CreateCubeGeometry();
+
+    // Step 3. Create a renderer
+    CreateRenderer();
+
+    // Step 4. Create an Actor
+    CreateActor();
+
+    // Step 5. Play animation to rotate the cube
+    PlayAnimation();
+
+    // Respond to a click anywhere on the stage
+    stage.GetRootLayer().TouchSignal().Connect( this, &DrawCubeController::OnTouch );
+  }
+
+  bool OnTouch( Actor actor, const TouchData& touch )
+  {
+    // quit the application
+    mApplication.Quit();
+    return true;
+  }
+
+  /**
+   * This function creates a cube geometry including texture coordinates.
+   * Also it demonstrates using the indexed draw feature by setting an index array.
+   */
+  void CreateCubeGeometry()
+  {
+    struct Vertex
+    {
+      Vector3 aPosition;
+      Vector3 aColor;
+    };
+
+    const Vector3 COLOR0( 1.0f, 1.0f, 0.0f );
+    const Vector3 COLOR1( 0.0f, 1.0f, 1.0f );
+    const Vector3 COLOR2( 1.0f, 0.0f, 1.0f );
+    const Vector3 COLOR3( 0.0f, 1.0f, 0.0f );
+    const Vector3 COLOR4( 0.0f, 0.0f, 1.0f );
+    const Vector3 COLOR5( 1.0f, 0.0f, 0.0f );
+
+    Vertex vertices[] = {
+      { Vector3(  1.0f,-1.0f,-1.0f ), COLOR5 },
+      { Vector3( -1.0f, 1.0f,-1.0f ), COLOR5 },
+      { Vector3(  1.0f, 1.0f,-1.0f ), COLOR5 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR3 },
+      { Vector3(  1.0f,-1.0f, 1.0f ), COLOR3 },
+      { Vector3(  1.0f, 1.0f, 1.0f ), COLOR3 },
+      { Vector3(  1.0f, 1.0f, 1.0f ), COLOR4 },
+      { Vector3(  1.0f,-1.0f,-1.0f ), COLOR4 },
+      { Vector3(  1.0f, 1.0f,-1.0f ), COLOR4 },
+      { Vector3(  1.0f,-1.0f, 1.0f ), COLOR1 },
+      { Vector3( -1.0f,-1.0f,-1.0f ), COLOR1 },
+      { Vector3(  1.0f,-1.0f,-1.0f ), COLOR1 },
+      { Vector3( -1.0f,-1.0f,-1.0f ), COLOR0 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR0 },
+      { Vector3( -1.0f, 1.0f,-1.0f ), COLOR0 },
+      { Vector3(  1.0f, 1.0f,-1.0f ), COLOR2 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR2 },
+      { Vector3(  1.0f, 1.0f, 1.0f ), COLOR2 },
+      { Vector3(  1.0f,-1.0f,-1.0f ), COLOR5 },
+      { Vector3( -1.0f,-1.0f,-1.0f ), COLOR5 },
+      { Vector3( -1.0f, 1.0f,-1.0f ), COLOR5 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR3 },
+      { Vector3( -1.0f,-1.0f, 1.0f ), COLOR3 },
+      { Vector3(  1.0f,-1.0f, 1.0f ), COLOR3 },
+      { Vector3(  1.0f, 1.0f, 1.0f ), COLOR4 },
+      { Vector3(  1.0f,-1.0f, 1.0f ), COLOR4 },
+      { Vector3(  1.0f,-1.0f,-1.0f ), COLOR4 },
+      { Vector3(  1.0f,-1.0f, 1.0f ), COLOR1 },
+      { Vector3( -1.0f,-1.0f, 1.0f ), COLOR1 },
+      { Vector3( -1.0f,-1.0f,-1.0f ), COLOR1 },
+      { Vector3( -1.0f,-1.0f,-1.0f ), COLOR0 },
+      { Vector3( -1.0f,-1.0f, 1.0f ), COLOR0 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR0 },
+      { Vector3(  1.0f, 1.0f,-1.0f ), COLOR2 },
+      { Vector3( -1.0f, 1.0f,-1.0f ), COLOR2 },
+      { Vector3( -1.0f, 1.0f, 1.0f ), COLOR2 },
+    };
+
+    Property::Map map;
+    map[ "aPosition" ] = Property::VECTOR3;
+    map[ "aColor" ] = Property::VECTOR3;
+    PropertyBuffer vertexBuffer = PropertyBuffer::New( map );
+
+    vertexBuffer.SetData( vertices, sizeof(vertices) / sizeof(Vertex) );
+
+    // create indices
+    const unsigned short INDEX_CUBE[] = {
+      2, 1, 0,
+      5, 4, 3,
+      8, 7, 6,
+      11, 10, 9,
+      14, 13, 12,
+      17, 16, 15,
+      20, 19, 18,
+      23, 22, 21,
+      26, 25, 24,
+      29, 28, 27,
+      32, 31, 30,
+      35, 34, 33
+    };
+    mGeometry = Geometry::New();
+    mGeometry.AddVertexBuffer( vertexBuffer );
+    mGeometry.SetIndexBuffer( INDEX_CUBE,
+                              sizeof(INDEX_CUBE)/sizeof(INDEX_CUBE[0])
+        );
+    mGeometry.SetType( Geometry::TRIANGLES );
+  }
+
+  /**
+   * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
+   *
+   * Shaders are very basic and all they do is transforming vertices and interpolating
+   * input per-vertex color.
+   */
+  void CreateCubeShader()
+  {
+    mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+  }
+
+  /**
+   * Function creates renderer. It turns on depth test and depth write.
+   */
+  void CreateRenderer()
+  {
+    mRenderer = Renderer::New( mGeometry, mShader );
+
+    // Face culling is enabled to hide the backwards facing sides of the cube
+    // This is sufficient to render a single object; for more complex scenes depth-testing might be required
+    mRenderer.SetProperty( Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK );
+  }
+
+  /**
+   * Creates new actor and attaches renderer.
+   */
+  void CreateActor()
+  {
+    Stage stage = Stage::GetCurrent();
+
+    float quarterStageWidth = stage.GetSize().x * 0.25f;
+    mActor = Actor::New();
+    mActor.SetAnchorPoint( AnchorPoint::CENTER );
+    mActor.SetParentOrigin( ParentOrigin::CENTER );
+    mActor.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
+    mActor.SetSize( Vector3( quarterStageWidth, quarterStageWidth, quarterStageWidth ) );
+    mActor.AddRenderer( mRenderer );
+    stage.Add( mActor );
+  }
+
+  /**
+   * Plays animation
+   */
+  void PlayAnimation()
+  {
+    mAnimation = Animation::New( 5.0f );
+    mAnimation.SetLooping( true );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::ZAXIS ) );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::YAXIS ) );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::XAXIS ) );
+    mAnimation.Play();
+  }
+
+private:
+  Application&  mApplication;
+
+  Renderer mRenderer;
+  Shader mShader;
+  Geometry mGeometry;
+  Actor mActor;
+  Animation mAnimation;
+};
+
+void RunTest( Application& application )
+{
+  DrawCubeController test( application );
+
+  application.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+//
+int DALI_EXPORT_API main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  RunTest( application );
+
+  return 0;
+}
diff --git a/examples/rendering-line/rendering-line.cpp b/examples/rendering-line/rendering-line.cpp
new file mode 100644 (file)
index 0000000..6b1f794
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+/*
+ * Vertex shader
+ */
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+attribute mediump vec2 aPosition;\n // DALi shader builtin
+uniform   mediump mat4 uMvpMatrix;\n // DALi shader builtin
+uniform   mediump vec3 uSize;\n // DALi shader builtin
+\n
+void main()\n
+{\n
+  mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+  vertexPosition.xyz *= uSize;\n
+  gl_Position = uMvpMatrix * vertexPosition;\n
+}\n
+);
+
+/*
+ * Fragment shader
+ */
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+uniform mediump vec4 uColor;\n
+\n
+void main()\n
+{\n
+  gl_FragColor = uColor;\n
+}\n
+);
+
+}
+
+// This example shows how to draw a line in actor's color
+//
+class DrawLineController : public ConnectionTracker
+{
+public:
+
+  DrawLineController( Application& application )
+  : mApplication( application )
+  {
+    // Connect to the Application's Init signal
+    mApplication.InitSignal().Connect( this, &DrawLineController::Create );
+  }
+
+  ~DrawLineController()
+  {
+    // Nothing to do here;
+  }
+
+  // The Init signal is received once (only) during the Application lifetime
+  void Create( Application& application )
+  {
+    // Get a handle to the stage
+    Stage stage = Stage::GetCurrent();
+    stage.SetBackgroundColor( Color::WHITE );
+
+    // Step 1. Create shader
+    CreateLineShader();
+
+    // Step 2. Prepare geometry
+    CreateLineGeometry();
+
+    // Step 3. Create a renderer
+    CreateRenderer();
+
+    // Step 4. Create an Actor
+    CreateActor();
+
+    // Respond to a click anywhere on the stage
+    stage.GetRootLayer().TouchSignal().Connect( this, &DrawLineController::OnTouch );
+  }
+
+  bool OnTouch( Actor actor, const TouchData& touch )
+  {
+    // quit the application
+    mApplication.Quit();
+    return true;
+  }
+
+  /**
+   * This function creates a line geometry made of two vertices in order
+   * to draw a diagonal line.
+   */
+  void CreateLineGeometry()
+  {
+    Vector2 vertices[] = {
+      Vector2( -1.0f, -1.0f ),
+      Vector2(  1.0f,  1.0f )
+    };
+
+    Property::Map map;
+    map[ "aPosition" ] = Property::VECTOR2;
+    PropertyBuffer vertexBuffer = PropertyBuffer::New( map );
+
+    vertexBuffer.SetData( vertices, sizeof(vertices) / sizeof(Vector2) );
+
+    mGeometry = Geometry::New();
+    mGeometry.AddVertexBuffer( vertexBuffer );
+    mGeometry.SetType( Geometry::LINES );
+  }
+
+  /**
+   * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
+   *
+   * Shaders are very basic and all they do is transforming vertices and applying actor's colour.
+   */
+  void CreateLineShader()
+  {
+    mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+  }
+
+  /**
+   * Function creates renderer.
+   */
+  void CreateRenderer()
+  {
+    mRenderer = Renderer::New( mGeometry, mShader );
+  }
+
+  /**
+   * Creates new actor and attaches renderer.
+   */
+  void CreateActor()
+  {
+    Stage stage = Stage::GetCurrent();
+    Size size = stage.GetSize() * 0.25f;
+    mActor = Actor::New();
+    mActor.SetAnchorPoint( AnchorPoint::CENTER );
+    mActor.SetParentOrigin( ParentOrigin::CENTER );
+    mActor.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
+    mActor.SetColor( Color::BLACK );
+    mActor.SetSize( Vector3( size.x, size.x, size.x ) );
+    mActor.AddRenderer( mRenderer );
+    stage.Add( mActor );
+  }
+
+private:
+  Application&  mApplication;
+
+  Renderer mRenderer;
+  Shader mShader;
+  Geometry mGeometry;
+  Actor mActor;
+};
+
+void RunTest( Application& application )
+{
+  DrawLineController test( application );
+
+  application.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+//
+int DALI_EXPORT_API main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  RunTest( application );
+
+  return 0;
+}
diff --git a/examples/rendering-textured-cube/rendering-textured-cube.cpp b/examples/rendering-textured-cube/rendering-textured-cube.cpp
new file mode 100644 (file)
index 0000000..a9abe78
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+/*
+ * Vertex shader
+ */
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+attribute mediump vec3 aPosition;\n // DALi shader builtin
+attribute mediump vec2 aTexCoord;\n // DALi shader builtin
+uniform   mediump mat4 uMvpMatrix;\n // DALi shader builtin
+uniform   mediump vec3 uSize;\n // DALi shader builtin
+\n
+varying mediump vec2 vTexCoord;\n
+void main()\n
+{\n
+  mediump vec4 vertexPosition = vec4(aPosition, 1.0);\n
+  vertexPosition.xyz *= uSize;\n
+  vTexCoord = aTexCoord;\n
+  gl_Position = uMvpMatrix * vertexPosition;\n
+}\n
+);
+
+/*
+ * Fragment shader
+ */
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+uniform sampler2D uTexture;\n
+\n
+varying mediump vec2 vTexCoord;\n
+void main()\n
+{\n
+  mediump vec4 texColor = texture2D( uTexture, vTexCoord );\n
+  gl_FragColor = texColor;\n
+}\n
+);
+
+const char* TEXTURE_URL = DEMO_IMAGE_DIR "wood.png";
+
+}
+
+// This example shows how to create textured cube
+//
+class TexturedCubeController : public ConnectionTracker
+{
+public:
+
+  TexturedCubeController( Application& application )
+  : mApplication( application )
+  {
+    // Connect to the Application's Init signal
+    mApplication.InitSignal().Connect( this, &TexturedCubeController::Create );
+  }
+
+  ~TexturedCubeController()
+  {
+    // Nothing to do here;
+  }
+
+  // The Init signal is received once (only) during the Application lifetime
+  void Create( Application& application )
+  {
+    // Get a handle to the stage
+    Stage stage = Stage::GetCurrent();
+    stage.SetBackgroundColor( Color::WHITE );
+
+    // Step 1. Create shader
+    CreateCubeShader();
+
+    // Step 2. Load a texture
+    CreateTexture();
+
+    // Step 3. Prepare geometry
+    CreateCubeGeometry();
+
+    // Step 4. Create a renderer
+    CreateRenderer();
+
+    // Step 5. Create an Actor
+    CreateActor();
+
+    // Step 6. Play animation to rotate the cube
+    PlayAnimation();
+
+    // Respond to a click anywhere on the stage
+    stage.GetRootLayer().TouchSignal().Connect( this, &TexturedCubeController::OnTouch );
+  }
+
+  bool OnTouch( Actor actor, const TouchData& touch )
+  {
+    // quit the application
+    mApplication.Quit();
+    return true;
+  }
+
+  /**
+   * @brief CreateCubeGeometry
+   * This function creates a cube geometry including texture coordinates.
+   * Also it demonstrates using the indexed draw feature by setting an index array.
+   */
+  void CreateCubeGeometry()
+  {
+    struct Vertex
+    {
+      Vector3 aPosition;
+      Vector2 aTexCoord;
+    };
+
+    Vertex vertices[] = {
+      { Vector3(  1.0f,-1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f, 1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f,-1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3(  1.0f,-1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f, 1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3(  1.0f, 1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3(  1.0f,-1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f,-1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3(  1.0f,-1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f,-1.0f,-1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3( -1.0f, 1.0f,-1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3(  1.0f, 1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f, 1.0f ), Vector2( 0.0, 1.0 ) },
+      { Vector3(  1.0f,-1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f,-1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3( -1.0f, 1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f, 1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3(  1.0f,-1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3(  1.0f,-1.0f, 1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3(  1.0f,-1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f,-1.0f, 1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f, 1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3( -1.0f,-1.0f,-1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3( -1.0f,-1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f,-1.0f, 1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+      { Vector3(  1.0f, 1.0f,-1.0f ), Vector2( 1.0, 1.0 ) },
+      { Vector3( -1.0f, 1.0f,-1.0f ), Vector2( 1.0, 0.0 ) },
+      { Vector3( -1.0f, 1.0f, 1.0f ), Vector2( 0.0, 0.0 ) },
+    };
+
+    Property::Map map;
+    map[ "aPosition" ] = Property::VECTOR3;
+    map[ "aTexCoord" ] = Property::VECTOR2;
+    PropertyBuffer vertexBuffer = PropertyBuffer::New( map );
+
+    vertexBuffer.SetData( vertices, sizeof(vertices) / sizeof(Vertex) );
+
+    // create indices
+    const unsigned short INDEX_CUBE[] = {
+      2, 1, 0,
+      5, 4, 3,
+      8, 7, 6,
+      11, 10, 9,
+      14, 13, 12,
+      17, 16, 15,
+      20, 19, 18,
+      23, 22, 21,
+      26, 25, 24,
+      29, 28, 27,
+      32, 31, 30,
+      35, 34, 33
+    };
+    mGeometry = Geometry::New();
+    mGeometry.AddVertexBuffer( vertexBuffer );
+    mGeometry.SetIndexBuffer( INDEX_CUBE,
+                              sizeof(INDEX_CUBE)/sizeof(INDEX_CUBE[0]) );
+    mGeometry.SetType( Geometry::TRIANGLES );
+  }
+
+  /**
+   * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
+   *
+   * Shaders are very basic and all they do is transforming vertices and sampling
+   * a texture.
+   */
+  void CreateCubeShader()
+  {
+    mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+  }
+
+  /**
+   * This function loads a pixel data from a file. In order to load it we use SyncImageLoader utility.
+   * If loading succeeds returned PixelData object can be used to create a texture.
+   * Texture must be uploaded. In the end the texture must be set on the TextureSet object.
+   */
+  void CreateTexture()
+  {
+    // Load image from file
+    PixelData pixels = SyncImageLoader::Load( TEXTURE_URL );
+
+    Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
+    texture.Upload( pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight() );
+
+    // create TextureSet
+    mTextureSet = TextureSet::New();
+    mTextureSet.SetTexture( 0, texture );
+  }
+
+  /**
+   * Function creates renderer. It turns on depth test and depth write.
+   */
+  void CreateRenderer()
+  {
+    mRenderer = Renderer::New( mGeometry, mShader );
+    mRenderer.SetTextures( mTextureSet );
+
+    // Face culling is enabled to hide the backwards facing sides of the cube
+    // This is sufficient to render a single object; for more complex scenes depth-testing might be required
+    mRenderer.SetProperty( Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK );
+  }
+
+  /**
+   * Creates new actor and attaches renderer.
+   */
+  void CreateActor()
+  {
+    Stage stage = Stage::GetCurrent();
+
+    float quarterStageWidth = stage.GetSize().x * 0.25f;
+    mActor = Actor::New();
+    mActor.SetAnchorPoint( AnchorPoint::CENTER );
+    mActor.SetParentOrigin( ParentOrigin::CENTER );
+    mActor.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
+    mActor.SetSize( Vector3( quarterStageWidth, quarterStageWidth, quarterStageWidth ) );
+    mActor.AddRenderer( mRenderer );
+    stage.Add( mActor );
+  }
+
+  /**
+   * Plays animation
+   */
+  void PlayAnimation()
+  {
+    mAnimation = Animation::New( 5.0f );
+    mAnimation.SetLooping( true );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::ZAXIS ) );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::YAXIS ) );
+    mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::XAXIS ) );
+    mAnimation.Play();
+  }
+
+private:
+  Application&  mApplication;
+
+  Renderer mRenderer;
+  Shader mShader;
+  Geometry mGeometry;
+  TextureSet mTextureSet;
+  Actor mActor;
+  Animation mAnimation;
+};
+
+void RunTest( Application& application )
+{
+  TexturedCubeController test( application );
+
+  application.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+//
+int DALI_EXPORT_API main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  RunTest( application );
+
+  return 0;
+}
diff --git a/examples/rendering-triangle/rendering-triangle.cpp b/examples/rendering-triangle/rendering-triangle.cpp
new file mode 100644 (file)
index 0000000..7fde494
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+/*
+ * Vertex shader
+ */
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+attribute mediump vec2 aPosition;\n // DALi shader builtin
+uniform   mediump mat4 uMvpMatrix;\n // DALi shader builtin
+uniform   mediump vec3 uSize;\n // DALi shader builtin
+\n
+void main()\n
+{\n
+  mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+  vertexPosition.xyz *= uSize;\n
+  gl_Position = uMvpMatrix * vertexPosition;\n
+}\n
+);
+
+/*
+ * Fragment shader
+ */
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+uniform mediump vec4 uColor;\n
+\n
+void main()\n
+{\n
+  gl_FragColor = uColor;\n
+}\n
+);
+
+}
+
+// This example shows how to draw a triangle in actor's color
+//
+class DrawTriangleController : public ConnectionTracker
+{
+public:
+
+  DrawTriangleController( Application& application )
+  : mApplication( application )
+  {
+    // Connect to the Application's Init signal
+    mApplication.InitSignal().Connect( this, &DrawTriangleController::Create );
+  }
+
+  ~DrawTriangleController()
+  {
+    // Nothing to do here;
+  }
+
+  // The Init signal is received once (only) during the Application lifetime
+  void Create( Application& application )
+  {
+    // Get a handle to the stage
+    Stage stage = Stage::GetCurrent();
+    stage.SetBackgroundColor( Color::WHITE );
+
+    // Step 1. Create shader
+    CreateTriangleShader();
+
+    // Step 2. Prepare geometry
+    CreateTriangleGeometry();
+
+    // Step 3. Create a renderer
+    CreateRenderer();
+
+    // Step 4. Create an Actor
+    CreateActor();
+
+    // Respond to a click anywhere on the stage
+    stage.GetRootLayer().TouchSignal().Connect( this, &DrawTriangleController::OnTouch );
+  }
+
+  bool OnTouch( Actor actor, const TouchData& touch )
+  {
+    // quit the application
+    mApplication.Quit();
+    return true;
+  }
+
+  /**
+   * This function creates a triangle geometry made of three vertices in order
+   * to draw a coloured triangle.
+   */
+  void CreateTriangleGeometry()
+  {
+    Vector2 vertices[] = {
+      Vector2( -1.0f, -1.0f ),
+      Vector2(  1.0f,  1.0f ),
+      Vector2( -1.0f,  1.0f )
+    };
+
+    Property::Map map;
+    map[ "aPosition" ] = Property::VECTOR2;
+    PropertyBuffer vertexBuffer = PropertyBuffer::New( map );
+
+    vertexBuffer.SetData( vertices, sizeof(vertices) / sizeof(Vector2) );
+
+    mGeometry = Geometry::New();
+    mGeometry.AddVertexBuffer( vertexBuffer );
+    mGeometry.SetType( Geometry::TRIANGLES );
+  }
+
+  /**
+   * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
+   *
+   * Shaders are very basic and all they do is transforming vertices and applying actor's colour.
+   */
+  void CreateTriangleShader()
+  {
+    mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+  }
+
+  /**
+   * Function creates renderer.
+   */
+  void CreateRenderer()
+  {
+    mRenderer = Renderer::New( mGeometry, mShader );
+  }
+
+  /**
+   * Creates new actor and attaches renderer.
+   */
+  void CreateActor()
+  {
+    Stage stage = Stage::GetCurrent();
+    Size size = stage.GetSize() * 0.25f;
+    mActor = Actor::New();
+    mActor.SetAnchorPoint( AnchorPoint::CENTER );
+    mActor.SetParentOrigin( ParentOrigin::CENTER );
+    mActor.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
+    mActor.SetColor( Color::RED );
+    mActor.SetSize( Vector3( size.x, size.x, size.x ) );
+    mActor.AddRenderer( mRenderer );
+    stage.Add( mActor );
+  }
+
+private:
+  Application&  mApplication;
+
+  Renderer mRenderer;
+  Shader mShader;
+  Geometry mGeometry;
+  Actor mActor;
+};
+
+void RunTest( Application& application )
+{
+  DrawTriangleController test( application );
+
+  application.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+//
+int DALI_EXPORT_API main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  RunTest( application );
+
+  return 0;
+}
index 5accc36..830a926 100755 (executable)
@@ -132,3 +132,15 @@ msgstr "অকনিষ্ঠ অৰ্জুন বঁটা"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "টিল্ট অনুভূতি"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "ৰেণ্ডাৰিং  গাঁথনি"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "ৰেণ্ডাৰিং  ঘনক"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "ৰেণ্ডাৰিং  ত্ৰিকোণমিতি"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "ৰেণ্ডাৰিং  শাৰী"
index 0aea6b5..c2e0186 100755 (executable)
@@ -132,3 +132,16 @@ msgstr "Text Scrollen"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "Neigungssensor"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "Texturierter Würfel"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "Würfel zeichnen"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "Dreieck zeichnen"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "Zeichnen"
+
index a62e46a..59661b0 100755 (executable)
@@ -132,3 +132,15 @@ msgstr "Text Scrolling"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "Tilt Sensor"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "Textured cube"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "Draw cube"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "Draw triangle"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "Draw line"
index 217b42f..1fe3b20 100755 (executable)
@@ -132,3 +132,16 @@ msgstr "Text Scrolling"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "Tilt Sensor"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "Textured cube"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "Draw cube"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "Draw triangle"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "Draw line"
+
index 3611ed6..b10604f 100755 (executable)
@@ -132,3 +132,15 @@ msgstr "Texto con desplazamiento"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "Sensor de inclinacion"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "Cubo con textura"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "Dibujar cubo"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "Dibujar triángulo"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "Dibujar linea"
index e3d16c7..4ad744c 100755 (executable)
@@ -132,3 +132,15 @@ msgstr "텍스트 스크롤"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "기울기 센서"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "질감 입방체"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "큐브 그리기"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "삼각형 그리기"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "선 그리기"
index eabc095..bcd561d 100755 (executable)
@@ -131,4 +131,16 @@ msgid "DALI_DEMO_STR_TITLE_TEXT_SCROLLING"
 msgstr "ടെക്സ്റ്റ് സ്ക്രോളിംഗ്"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
-msgstr "ചെരിവ് സെൻസർ"
\ No newline at end of file
+msgstr "ചെരിവ് സെൻസർ"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "ടെക്സ്ചർ ക്യൂബ്"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "ക്യൂബ് വരയ്ക്കുക"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "ത്രികോണം വരയ്ക്കുക"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "സമനില ലൈൻ"
index a3b8d12..39a9964 100755 (executable)
@@ -132,3 +132,15 @@ msgstr "حروف کاسکرال "
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
 msgstr "ٹلٹ سینسر"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "بویک ٹوانب "
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "ارڈ بویک "
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "ارڈ ثلثم "
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "انچنیھک ریکل "
index c340d63..6bd377c 100755 (executable)
@@ -131,4 +131,16 @@ msgid "DALI_DEMO_STR_TITLE_TEXT_SCROLLING"
 msgstr "滚动文字"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
-msgstr "倾斜传感器"
\ No newline at end of file
+msgstr "倾斜传感器"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE"
+msgstr "纹理的多维数据集"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE"
+msgstr "绘制多维数据集"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE"
+msgstr "绘制三角形"
+
+msgid "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE"
+msgstr "画线"
index 0f71b32..e98793b 100644 (file)
@@ -76,6 +76,10 @@ extern "C"
 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE   dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE")
 #define DALI_DEMO_STR_TITLE_TEXT_SCROLLING              dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_SCROLLING")
 #define DALI_DEMO_STR_TITLE_TILT_SENSOR                 dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TILT_SENSOR")
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE         dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE")
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE     dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE")
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE         dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE")
+#define DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE     dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE")
 
 #else // !INTERNATIONALIZATION_ENABLED
 
@@ -123,7 +127,10 @@ extern "C"
 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE   "Text Scripts"
 #define DALI_DEMO_STR_TITLE_TEXT_SCROLLING              "Text Scrolling"
 #define DALI_DEMO_STR_TITLE_TILT_SENSOR                 "Tilt Sensor"
-
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE         "Draw Line"
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE     "Draw Triangle"
+#define DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE         "Draw Cube"
+#define DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE     "Draw Textured Cube"
 #endif
 
 #ifdef __cplusplus