Commit 6359e2a9a75350ffbed54c75f6d4480abfe13ec1

Authored by David Steele
1 parent bda3e2de

Added a mesh sorting and blending example

Displays 6 actors with different materials, alternating
opaque and transparent actors.
Actor 5 has the same material as Actor 1.

Clicking an actor will change it's depth index ( > value means drawn later )
Clicking outside the actors will change the Z values of all the actors

Change-Id: I37640dcbc98774e86948f6c26d7e6718ebb00a6b
Signed-off-by: David Steele <david.steele@partner.samsung.com>
examples/mesh-sorting/mesh-sorting-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2015 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 +// EXTERNAL INCLUDES
  19 +
  20 +// INTERNAL INCLUDES
  21 +#include "shared/view.h"
  22 +
  23 +#include <dali-toolkit/dali-toolkit.h>
  24 +#include <stdio.h>
  25 +#include <sstream>
  26 +#include <cstring>
  27 +
  28 +using namespace Dali;
  29 +
  30 +namespace
  31 +{
  32 +
  33 +const char* MATERIAL_SAMPLES[] =
  34 +{
  35 + DALI_IMAGE_DIR "people-medium-1.jpg",
  36 + DALI_IMAGE_DIR "people-medium-4.jpg",
  37 + DALI_IMAGE_DIR "people-medium-11.jpg",
  38 + DALI_IMAGE_DIR "people-small-16.jpg",
  39 + DALI_IMAGE_DIR "people-medium-15.jpg",
  40 + DALI_IMAGE_DIR "people-medium-6.jpg",
  41 +};
  42 +const unsigned int NUMBER_OF_SAMPLES(sizeof(MATERIAL_SAMPLES)/sizeof(const char*));
  43 +
  44 +
  45 +#define MAKE_SHADER(A)#A
  46 +
  47 +const char* VERTEX_SHADER = MAKE_SHADER(
  48 +uniform highp float uHue;
  49 +attribute mediump vec2 aPosition;
  50 +attribute highp vec2 aTexCoord;
  51 +varying mediump vec2 vTexCoord;
  52 +uniform mediump mat4 uMvpMatrix;
  53 +uniform mediump vec3 uSize;
  54 +varying mediump vec3 vGlobColor;
  55 +
  56 +vec3 hsv2rgb(vec3 c)
  57 +{
  58 + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
  59 + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
  60 + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
  61 +}
  62 +
  63 +void main()
  64 +{
  65 + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
  66 + vertexPosition.xyz *= uSize;
  67 + vertexPosition = uMvpMatrix * vertexPosition;
  68 + vGlobColor = hsv2rgb( vec3( clamp(uHue, 0.0, 1.0), 1.0, 1.0 ) );
  69 +
  70 + vTexCoord = aTexCoord;
  71 + gl_Position = vertexPosition;
  72 +}
  73 +);
  74 +
  75 +const char* FRAGMENT_SHADER = MAKE_SHADER(
  76 +varying mediump vec2 vTexCoord;
  77 +varying mediump vec3 vGlobColor;
  78 +uniform lowp vec4 uColor;
  79 +uniform sampler2D sTexture;
  80 +
  81 +void main()
  82 +{
  83 + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4(vGlobColor, 1.0) ;
  84 +}
  85 +);
  86 +
  87 +Geometry CreateGeometry()
  88 +{
  89 + // Create vertices
  90 + const float halfQuadSize = .5f;
  91 + struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; };
  92 + TexturedQuadVertex texturedQuadVertexData[4] = {
  93 + { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) },
  94 + { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) },
  95 + { Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f) },
  96 + { Vector2( halfQuadSize, halfQuadSize), Vector2(1.f, 1.f) } };
  97 +
  98 + Property::Map texturedQuadVertexFormat;
  99 + texturedQuadVertexFormat["aPosition"] = Property::VECTOR2;
  100 + texturedQuadVertexFormat["aTexCoord"] = Property::VECTOR2;
  101 + PropertyBuffer texturedQuadVertices = PropertyBuffer::New( PropertyBuffer::STATIC, texturedQuadVertexFormat, 4 );
  102 + texturedQuadVertices.SetData(texturedQuadVertexData);
  103 +
  104 + // Create indices
  105 + unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 };
  106 + Property::Map indexFormat;
  107 + indexFormat["indices"] = Property::UNSIGNED_INTEGER;
  108 + PropertyBuffer indices = PropertyBuffer::New( PropertyBuffer::STATIC, indexFormat, 6 );
  109 + indices.SetData(indexData);
  110 +
  111 + // Create the geometry object
  112 + Geometry texturedQuadGeometry = Geometry::New();
  113 + texturedQuadGeometry.AddVertexBuffer( texturedQuadVertices );
  114 + texturedQuadGeometry.SetIndexBuffer( indices );
  115 +
  116 + return texturedQuadGeometry;
  117 +}
  118 +
  119 +} // anonymous namespace
  120 +
  121 +// This example shows how to use a simple mesh
  122 +//
  123 +class ExampleController : public ConnectionTracker
  124 +{
  125 +public:
  126 +
  127 + /**
  128 + * The example controller constructor.
  129 + * @param[in] application The application instance
  130 + */
  131 + ExampleController( Application& application )
  132 + : mApplication( application ),
  133 + mZMode(0)
  134 + {
  135 + // Connect to the Application's Init signal
  136 + mApplication.InitSignal().Connect( this, &ExampleController::Create );
  137 + memset(mDepthIndices, 0, sizeof(mDepthIndices));
  138 + }
  139 +
  140 + /**
  141 + * The example controller destructor
  142 + */
  143 + ~ExampleController()
  144 + {
  145 + // Nothing to do here;
  146 + }
  147 +
  148 + /**
  149 + * Invoked upon creation of application
  150 + * @param[in] application The application instance
  151 + */
  152 + void Create( Application& application )
  153 + {
  154 + Stage stage = Stage::GetCurrent();
  155 + stage.KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
  156 +
  157 + mStageSize = stage.GetSize();
  158 +
  159 + // The Init signal is received once (only) during the Application lifetime
  160 +
  161 + // Hide the indicator bar
  162 + application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
  163 +
  164 + mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
  165 + mGeometry = CreateGeometry();
  166 +
  167 + Material firstMat;
  168 +
  169 + for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
  170 + {
  171 + Image image = ResourceImage::New( MATERIAL_SAMPLES[i] );
  172 + Sampler sampler = Sampler::New(image, "sTexture");
  173 + Material material = Material::New( mShader );
  174 + material.AddSampler( sampler );
  175 + if( i==0 ) { firstMat = material; }
  176 +
  177 + Renderer renderer = Renderer::New( mGeometry, material );
  178 + Actor meshActor = Actor::New();
  179 + mActors[i] = meshActor;
  180 + meshActor.AddRenderer( renderer );
  181 + meshActor.SetSize(175, 175);
  182 + meshActor.RegisterProperty("index", (int)i);
  183 +
  184 + renderer.SetDepthIndex(0);
  185 + // Test with actor alpha
  186 + meshActor.SetParentOrigin( ParentOrigin::CENTER );
  187 + meshActor.SetAnchorPoint( AnchorPoint::CENTER );
  188 + meshActor.SetPosition( 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), i*10 );
  189 +
  190 + meshActor.SetOpacity( i%2?0.7f:1.0f );
  191 +
  192 + Property::Index index=meshActor.RegisterProperty("hue", i/(float)NUMBER_OF_SAMPLES);
  193 + meshActor.AddUniformMapping( index, "uHue" );
  194 +
  195 + meshActor.TouchedSignal().Connect(this, &ExampleController::OnTouched);
  196 + std::ostringstream oss;
  197 + oss << "Mesh Actor " << i;
  198 + meshActor.SetName(oss.str());
  199 + stage.Add( meshActor );
  200 + }
  201 +
  202 + mActors[NUMBER_OF_SAMPLES-2].GetRendererAt(0).SetMaterial( firstMat );
  203 +
  204 + stage.GetRootLayer().TouchedSignal().Connect(this, &ExampleController::OnStageTouched);
  205 + }
  206 +
  207 + void PrintDepths()
  208 + {
  209 + switch( mZMode )
  210 + {
  211 + case 0:
  212 + {
  213 + printf("Children Z ordered back to front\n");
  214 + break;
  215 + }
  216 + case 1:
  217 + {
  218 + printf("All children set to same Z=0\n");
  219 + break;
  220 + }
  221 + case 2:
  222 + {
  223 + printf("Children Z ordered front to back\n");
  224 + break;
  225 + }
  226 + }
  227 +
  228 + for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
  229 + {
  230 + printf("DepthIndex[%d]=%d\n", i, mDepthIndices[i]);
  231 + }
  232 + printf("\n");
  233 + }
  234 +
  235 + bool OnTouched( Actor actor, const TouchEvent& event )
  236 + {
  237 + if( event.GetPoint(0).state == TouchPoint::Finished )
  238 + {
  239 + int index = actor.GetProperty<int>(actor.GetPropertyIndex("index"));
  240 +
  241 + int newDepthIndex = (mDepthIndices[index] + 10) % 30;
  242 + mDepthIndices[index] = newDepthIndex;
  243 +
  244 + Renderer renderer = actor.GetRendererAt(0);
  245 + renderer.SetDepthIndex(newDepthIndex);
  246 +
  247 + PrintDepths();
  248 + }
  249 + return true;
  250 + }
  251 +
  252 + bool OnStageTouched( Actor rootLayer, const TouchEvent& event )
  253 + {
  254 + if( event.GetPoint(0).state == TouchPoint::Finished )
  255 + {
  256 + switch( mZMode )
  257 + {
  258 + case 0:
  259 + {
  260 + mZMode = 1;
  261 + for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
  262 + {
  263 + Actor child = rootLayer.GetChildAt(i);
  264 + child.SetZ( 0.0f );
  265 + }
  266 + PrintDepths();
  267 + break;
  268 + }
  269 + case 1:
  270 + {
  271 + mZMode = 2;
  272 + for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
  273 + {
  274 + Actor child = rootLayer.GetChildAt(i);
  275 + child.SetZ( 100-i*10 );
  276 + }
  277 + PrintDepths();
  278 + break;
  279 + }
  280 + case 2:
  281 + {
  282 + mZMode = 0;
  283 + for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
  284 + {
  285 + Actor child = rootLayer.GetChildAt(i);
  286 + child.SetZ( i*10 );
  287 + }
  288 + PrintDepths();
  289 + break;
  290 + }
  291 + }
  292 + }
  293 + return true;
  294 + }
  295 +
  296 + /**
  297 + * Invoked whenever the quit button is clicked
  298 + * @param[in] button the quit button
  299 + */
  300 + bool OnQuitButtonClicked( Toolkit::Button button )
  301 + {
  302 + // quit the application
  303 + mApplication.Quit();
  304 + return true;
  305 + }
  306 +
  307 + void OnKeyEvent(const KeyEvent& event)
  308 + {
  309 + if(event.state == KeyEvent::Down)
  310 + {
  311 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  312 + {
  313 + mApplication.Quit();
  314 + }
  315 + }
  316 + }
  317 +
  318 +private:
  319 +
  320 + Application& mApplication; ///< Application instance
  321 + Vector3 mStageSize; ///< The size of the stage
  322 +
  323 + Shader mShader;
  324 + Geometry mGeometry;
  325 +
  326 + int mDepthIndices[NUMBER_OF_SAMPLES];
  327 + Actor mActors[NUMBER_OF_SAMPLES];
  328 + int mZMode;
  329 +};
  330 +
  331 +void RunTest( Application& application )
  332 +{
  333 + ExampleController test( application );
  334 +
  335 + application.MainLoop();
  336 +}
  337 +
  338 +// Entry point for Linux & SLP applications
  339 +//
  340 +int main( int argc, char **argv )
  341 +{
  342 + Application application = Application::New( &argc, &argv );
  343 +
  344 + RunTest( application );
  345 +
  346 + return 0;
  347 +}
... ...