X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=examples%2Freflection-demo%2Freflection-example.cpp;h=9de2407e6481ecda86991f3461a33bcaeb0e0ae0;hb=1b19fd140ff139b5854a1a62447faf31b175d8f6;hp=c0eb8803aa079a690b49d5076fb6332ef467c0ed;hpb=7c0e29c4b068dd1f2a4dc3d1da21ab680cd405ce;p=platform%2Fcore%2Fuifw%2Fdali-demo.git diff --git a/examples/reflection-demo/reflection-example.cpp b/examples/reflection-demo/reflection-example.cpp index c0eb880..9de2407 100644 --- a/examples/reflection-demo/reflection-example.cpp +++ b/examples/reflection-demo/reflection-example.cpp @@ -24,7 +24,10 @@ #include "gltf-scene.h" using namespace Dali; -using Dali::Toolkit::TextLabel; + +namespace +{ +// clang-format off const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec3 aPosition;\n @@ -158,460 +161,458 @@ const char* TEX_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( (texture2D(sTexture1, uv))) * intensity;\n }\n ); +// clang-format on struct Model { - Shader shader; - Geometry geometry; + Shader shader; + Geometry geometry; }; +using ModelPtr = std::unique_ptr; -// This example shows how to create and display mirrored reflection using CameraActor -// -class ReflectionExample : public ConnectionTracker +using ActorContainer = std::vector; +using CameraContainer = std::vector; +using ModelContainer = std::vector; +using TextureSetContainer = std::vector; + +const Vector3 DEFAULT_LIGHT_DIRECTION(0.5, 0.5, -1); + +template +bool LoadFile(const std::string& filename, std::vector& bytes) { -public: + Dali::FileStream fileStream(filename, Dali::FileStream::READ | Dali::FileStream::BINARY); + FILE* fin = fileStream.GetFile(); - ReflectionExample( Application& application ) - : mApplication( application ) + if(fin) { - // Connect to the Application's Init signal - mApplication.InitSignal().Connect( this, &ReflectionExample::Create ); + if(fseek(fin, 0, SEEK_END)) + { + return false; + } + bytes.resize(uint32_t(ftell(fin))); + std::fill(bytes.begin(), bytes.end(), 0); + if(fseek(fin, 0, SEEK_SET)) + { + return false; + } + size_t result = fread(bytes.data(), 1, bytes.size(), fin); + return (result != 0); } - ~ReflectionExample() = default; + return false; +} -private: +Shader CreateShader(const std::string& vsh, const std::string& fsh) +{ + std::vector vshShaderSource; + std::vector fshShaderSource; - // The Init signal is received once (only) during the Application lifetime - void Create( Application& application ) + // VSH + if(vsh[0] == '/') { - // Get a handle to the stage - Stage stage = Stage::GetCurrent(); - uint32_t stageWidth = uint32_t(stage.GetSize().x); - uint32_t stageHeight = uint32_t(stage.GetSize().y); - - stage.GetRenderTaskList().GetTask(0).SetClearEnabled(false); - mLayer3D = Layer::New(); - mLayer3D.SetSize( stageWidth, stageHeight ); - stage.Add(mLayer3D); - - mLayer3D.SetAnchorPoint( AnchorPoint::CENTER ); - mLayer3D.SetParentOrigin( ParentOrigin::CENTER ); - mLayer3D.SetBehavior( Layer::LAYER_3D ); - mLayer3D.SetDepthTestDisabled( false ); - - - auto gltf = glTF(DEMO_GAME_DIR "/reflection"); - - // Define direction of light - mLightDir = Vector3( 0.5, 0.5, -1 ); - - /** - * Instantiate texture sets - */ - CreateTextureSetsFromGLTF( &gltf, DEMO_GAME_DIR ); - - /** - * Create models - */ - CreateModelsFromGLTF( &gltf ); - - /** - * Create scene nodes - */ - CreateSceneFromGLTF( stage, &gltf ); - - auto planeActor = mLayer3D.FindChildByName( "Plane" ); - auto solarActor = mLayer3D.FindChildByName( "solar_root" ); - auto backgroundActor = mLayer3D.FindChildByName( "background" ); - ReplaceShader( backgroundActor, VERTEX_SHADER, FRAGMENT_SIMPLE_SHADER ); - mCenterActor = mLayer3D.FindChildByName( "center" ); - mCenterHorizActor = mLayer3D.FindChildByName( "center2" ); - - // Prepare Sun - auto sun = mLayer3D.FindChildByName( "sun" ); - ReplaceShader( sun, VERTEX_SHADER, PLASMA_FRAGMENT_SHADER ); - mSunTimeUniformIndex = sun.RegisterProperty( "uTime", 0.0f ); - mSunKFactorUniformIndex = sun.RegisterProperty( "uKFactor", 0.0f ); - - mTickTimer = Timer::New( 16 ); - mTickTimer.TickSignal().Connect( this, &ReflectionExample::TickTimerSignal); - - // Milkyway - auto milkyway = mLayer3D.FindChildByName( "milkyway" ); - ReplaceShader( milkyway, VERTEX_SHADER, FRAGMENT_SHADER ); - - auto renderTaskSourceActor = mLayer3D.FindChildByName( "RenderTaskSource" ); - - /** - * Access camera (it's a child of "Camera" node) - */ - auto camera = mLayer3D.FindChildByName( "Camera_Orientation" ); - auto cameraRef = mLayer3D.FindChildByName( "CameraReflection_Orientation" ); + std::string vshPath(DEMO_GAME_DIR); + vshPath += '/'; + vshPath += vsh; + LoadFile(vshPath, vshShaderSource); + } + else + { + vshShaderSource.insert(vshShaderSource.end(), vsh.begin(), vsh.end()); + } - auto cameraActor = CameraActor::DownCast( camera ); - mCamera3D = cameraActor; + // FSH + if(fsh[0] == '/') + { + std::string fshPath(DEMO_GAME_DIR); + fshPath += '/'; + fshPath += fsh; + LoadFile(fshPath, fshShaderSource); + } + else + { + fshShaderSource.insert(fshShaderSource.end(), fsh.begin(), fsh.end()); + } - auto cameraRefActor = CameraActor::DownCast( cameraRef ); - cameraRefActor.SetProperty( DevelCameraActor::Property::REFLECTION_PLANE, Vector4(0.0f, -1.0f, 0.0f, 0.0f)); - mReflectionCamera3D = cameraRefActor; + vshShaderSource.emplace_back(0); + fshShaderSource.emplace_back(0); + return Shader::New(std::string(vshShaderSource.data()), std::string(fshShaderSource.data())); +} - auto task3D = stage.GetRenderTaskList().CreateTask(); - task3D.SetSourceActor( mLayer3D ); - task3D.SetViewport( Rect(0, 0, stageWidth, stageHeight ) ); - task3D.SetCameraActor( cameraActor ); - task3D.SetClearColor( Color::BLACK ); - task3D.SetClearEnabled( true ); - task3D.SetExclusive( false ); - task3D.SetCameraActor( cameraActor ); +ModelPtr CreateModel( + glTF& gltf, + const glTF_Mesh* mesh, + const std::string& vertexShaderSource, + const std::string& fragmentShaderSource) +{ + /* + * Obtain interleaved buffer for first mesh with position and normal attributes + */ + auto positionBuffer = gltf.GetMeshAttributeBuffer(*mesh, + {glTFAttributeType::POSITION, + glTFAttributeType::NORMAL, + glTFAttributeType::TEXCOORD_0}); - /** - * Change shader to textured - */ - Shader texShader = CreateShader( VERTEX_SHADER, TEX_FRAGMENT_SHADER ); - planeActor.RegisterProperty( "uScreenSize", Vector2(stageWidth, stageHeight) ); - auto renderer = planeActor.GetRendererAt(0); - auto textureSet = renderer.GetTextures(); - renderer.SetShader( texShader ); - - Texture fbTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, stageWidth, stageHeight ); - textureSet.SetTexture( 1u, fbTexture ); - - auto fb = FrameBuffer::New(stageWidth, stageHeight, - FrameBuffer::Attachment::DEPTH ); - - fb.AttachColorTexture( fbTexture ); - - auto renderTask = stage.GetRenderTaskList().CreateTask(); - renderTask.SetFrameBuffer( fb ); - renderTask.SetSourceActor( renderTaskSourceActor ); - renderTask.SetViewport( Rect(0, 0, stageWidth, stageHeight ) ); - renderTask.SetCameraActor( cameraRefActor ); - renderTask.SetClearColor( Color::BLACK ); - renderTask.SetClearEnabled( true ); - renderTask.SetExclusive( false ); - - mAnimation = Animation::New(30.0f ); - mAnimation.AnimateBy(Property(solarActor, Actor::Property::ORIENTATION ), - Quaternion( Degree(359), Vector3(0.0, 1.0, 0.0))); - mAnimation.AnimateBy(Property(milkyway, Actor::Property::ORIENTATION ), - Quaternion( Degree(-359), Vector3(0.0, 1.0, 0.0))); - mAnimation.SetLooping(true ); - mAnimation.Play(); + auto attributeCount = gltf.GetMeshAttributeCount(mesh); + /** + * Create matching property buffer + */ + auto vertexBuffer = VertexBuffer::New(Property::Map() + .Add("aPosition", Property::VECTOR3) + .Add("aNormal", Property::VECTOR3) + .Add("aTexCoord", Property::VECTOR2)); + + // set vertex data + vertexBuffer.SetData(positionBuffer.data(), attributeCount); + + auto geometry = Geometry::New(); + geometry.AddVertexBuffer(vertexBuffer); + auto indexBuffer = gltf.GetMeshIndexBuffer(mesh); + geometry.SetIndexBuffer(indexBuffer.data(), indexBuffer.size()); + geometry.SetType(Geometry::Type::TRIANGLES); + ModelPtr retval(new Model()); + retval->shader = CreateShader(vertexShaderSource, fragmentShaderSource); + retval->geometry = geometry; + return retval; +} - Actor panScreen = Actor::New(); - auto stageSize = stage.GetSize(); - panScreen.SetSize( stageSize.width, stageSize.height ); - panScreen.SetAnchorPoint( AnchorPoint::CENTER ); - panScreen.SetParentOrigin( ParentOrigin::CENTER ); - auto camera2d = stage.GetRenderTaskList().GetTask(0).GetCameraActor(); - panScreen.SetPosition( 0, 0, camera2d.GetNearClippingPlane() ); - camera2d.Add(panScreen); - camera2d.RotateBy( Degree(180.0f), Vector3( 0.0, 1.0, 0.0 ) ); - mPanGestureDetector = PanGestureDetector::New(); - mPanGestureDetector.Attach( panScreen ); - mPanGestureDetector.DetectedSignal().Connect( this, &ReflectionExample::OnPan ); +void ReplaceShader(Actor& actor, const std::string& vsh, const std::string& fsh) +{ + auto renderer = actor.GetRendererAt(0); + auto shader = CreateShader(vsh, fsh); + renderer.SetShader(shader); +} - // Respond to key events - stage.KeyEventSignal().Connect( this, &ReflectionExample::OnKeyEvent ); +void CreateTextureSetsFromGLTF(glTF* gltf, const std::string& basePath, TextureSetContainer& textureSets) +{ + const auto& materials = gltf->GetMaterials(); + const auto& textures = gltf->GetTextures(); - mTickTimer.Start(); - } + std::map textureCache{}; - void CreateSceneFromGLTF( Stage stage, glTF* gltf ) + for(const auto& material : materials) { - const auto& nodes = gltf->GetNodes(); - - // for each node create nodes and children - // resolve parents later - std::vector actors; - actors.reserve( nodes.size() ); - for( const auto& node : nodes ) + TextureSet textureSet; + if(material.pbrMetallicRoughness.enabled) { - auto actor = node.cameraId != 0xffffffff ? CameraActor::New( stage.GetSize() ) : Actor::New(); - - actor.SetSize( 1, 1, 1 ); - actor.SetName( node.name ); - actor.SetAnchorPoint( AnchorPoint::CENTER ); - actor.SetParentOrigin( ParentOrigin::CENTER ); - actor.SetPosition( node.translation[0], node.translation[1], node.translation[2] ); - actor.SetScale( node.scale[0], node.scale[1], node.scale[2] ); - actor.SetOrientation( Quaternion(node.rotationQuaternion[3], - node.rotationQuaternion[0], - node.rotationQuaternion[1], - node.rotationQuaternion[2])); - - actors.emplace_back( actor ); - - // Initially add each actor to the very first one - if(actors.size() > 1) + textureSet = TextureSet::New(); + std::string filename(basePath); + filename += '/'; + filename += textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; + Dali::PixelData pixelData = Dali::Toolkit::SyncImageLoader::Load(filename); + + auto cacheKey = textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; + auto iter = textureCache.find(cacheKey); + Texture texture; + if(iter == textureCache.end()) { - actors[0].Add(actor); + texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight()); + texture.Upload(pixelData); + texture.GenerateMipmaps(); + textureCache[cacheKey] = texture; } - - // If mesh, create and add renderer - if(node.meshId != 0xffffffff) + else { - const auto& model = mModels[node.meshId].get(); - auto renderer = Renderer::New( model->geometry, model->shader ); + texture = iter->second; + } + textureSet.SetTexture(0, texture); + Dali::Sampler sampler = Dali::Sampler::New(); + sampler.SetWrapMode(Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT); + sampler.SetFilterMode(Dali::FilterMode::LINEAR_MIPMAP_LINEAR, Dali::FilterMode::LINEAR); + textureSet.SetSampler(0, sampler); + } + textureSets.emplace_back(textureSet); + } +} - // if textured, add texture set - auto materialId = gltf->GetMeshes()[node.meshId]->material; - if( materialId != 0xffffffff ) - { - if( gltf->GetMaterials()[materialId].pbrMetallicRoughness.enabled ) - { - renderer.SetTextures( mTextureSets[materialId] ); - } - } +/** + * Creates models from glTF + */ +void CreateModelsFromGLTF(glTF* gltf, ModelContainer& models) +{ + const auto& meshes = gltf->GetMeshes(); + for(const auto& mesh : meshes) + { + // change shader to use texture if material indicates that + if(mesh->material != 0xffffffff && gltf->GetMaterials()[mesh->material].pbrMetallicRoughness.enabled) + { + models.emplace_back(CreateModel(*gltf, mesh, VERTEX_SHADER, TEXTURED_FRAGMENT_SHADER)); + } + else + { + models.emplace_back(CreateModel(*gltf, mesh, VERTEX_SHADER, FRAGMENT_SHADER)); + } + } +} - actor.AddRenderer( renderer ); - } +Actor CreateSceneFromGLTF( + Window window, + glTF* gltf, + ModelContainer& models, + ActorContainer& actors, + CameraContainer& cameras, + TextureSetContainer& textureSets) +{ + const auto& nodes = gltf->GetNodes(); - // Reset and attach main camera - if( node.cameraId != 0xffffffff ) - { - mCameraPos = Vector3(node.translation[0], node.translation[1], node.translation[2]); - auto quatY = Quaternion( Degree(180.0f), Vector3( 0.0, 1.0, 0.0) ); - auto cameraActor = CameraActor::DownCast( actor ); - cameraActor.SetOrientation( Quaternion(node.rotationQuaternion[3], - node.rotationQuaternion[0], - node.rotationQuaternion[1], - node.rotationQuaternion[2] ) - * quatY - ); - cameraActor.SetProjectionMode( Camera::PERSPECTIVE_PROJECTION ); - - const auto camera = gltf->GetCameras()[node.cameraId]; - cameraActor.SetNearClippingPlane( camera->znear ); - cameraActor.SetFarClippingPlane( camera->zfar ); - cameraActor.SetFieldOfView( camera->yfov ); - - cameraActor.SetProperty( CameraActor::Property::INVERT_Y_AXIS, true); - cameraActor.SetAnchorPoint( AnchorPoint::CENTER ); - cameraActor.SetParentOrigin( ParentOrigin::CENTER ); - - mCameras.emplace_back( cameraActor ); - } + Vector3 cameraPosition; + + // for each node create nodes and children + // resolve parents later + actors.reserve(nodes.size()); + for(const auto& node : nodes) + { + auto actor = node.cameraId != 0xffffffff ? CameraActor::New(window.GetSize()) : Actor::New(); + + actor.SetProperty(Actor::Property::SIZE, Vector3(1, 1, 1)); + actor.SetProperty(Dali::Actor::Property::NAME, node.name); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::POSITION, Vector3(node.translation[0], node.translation[1], node.translation[2])); + actor.SetProperty(Actor::Property::SCALE, Vector3(node.scale[0], node.scale[1], node.scale[2])); + actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(node.rotationQuaternion[3], node.rotationQuaternion[0], node.rotationQuaternion[1], node.rotationQuaternion[2])); + + actors.emplace_back(actor); + + // Initially add each actor to the very first one + if(actors.size() > 1) + { + actors[0].Add(actor); } - // Resolve hierarchy dependencies - auto i = 0u; - for( const auto& node : nodes ) + // If mesh, create and add renderer + if(node.meshId != 0xffffffff) { - if(!node.children.empty()) + const auto& model = models[node.meshId].get(); + auto renderer = Renderer::New(model->geometry, model->shader); + + // if textured, add texture set + auto materialId = gltf->GetMeshes()[node.meshId]->material; + if(materialId != 0xffffffff) { - for(const auto& childId : node.children) + if(gltf->GetMaterials()[materialId].pbrMetallicRoughness.enabled) { - actors[i].Add( actors[childId+1] ); + renderer.SetTextures(textureSets[materialId]); } } - ++i; - } - mActors = std::move(actors); - - // Add root actor to the stage - mLayer3D.Add( mActors[0] ); + actor.AddRenderer(renderer); + } - for( auto& actor : mActors ) + // Reset and attach main camera + if(node.cameraId != 0xffffffff) { - actor.RegisterProperty( "lightDir", mLightDir ); - actor.RegisterProperty( "eyePos", mCameraPos ); + cameraPosition = Vector3(node.translation[0], node.translation[1], node.translation[2]); + auto quatY = Quaternion(Degree(180.0f), Vector3(0.0, 1.0, 0.0)); + auto cameraActor = CameraActor::DownCast(actor); + cameraActor.SetProperty(Actor::Property::ORIENTATION, Quaternion(node.rotationQuaternion[3], node.rotationQuaternion[0], node.rotationQuaternion[1], node.rotationQuaternion[2]) * quatY); + cameraActor.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION); + + const auto camera = gltf->GetCameras()[node.cameraId]; + cameraActor.SetNearClippingPlane(camera->znear); + cameraActor.SetFarClippingPlane(camera->zfar); + cameraActor.SetFieldOfView(camera->yfov); + + cameraActor.SetProperty(CameraActor::Property::INVERT_Y_AXIS, true); + cameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + cameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + + cameras.emplace_back(cameraActor); } - } - /** - * Creates models from glTF - */ - void CreateModelsFromGLTF( glTF* gltf ) + // Resolve hierarchy dependencies + auto i = 0u; + for(const auto& node : nodes) { - const auto& meshes = gltf->GetMeshes(); - for( const auto& mesh : meshes ) + if(!node.children.empty()) { - // change shader to use texture if material indicates that - if(mesh->material != 0xffffffff && gltf->GetMaterials()[mesh->material].pbrMetallicRoughness.enabled) + for(const auto& childId : node.children) { - mModels.emplace_back( CreateModel( *gltf, mesh, VERTEX_SHADER, TEXTURED_FRAGMENT_SHADER ) ); - } - else - { - mModels.emplace_back( CreateModel( *gltf, mesh, VERTEX_SHADER, FRAGMENT_SHADER ) ); + actors[i].Add(actors[childId + 1]); } } + ++i; } - void CreateTextureSetsFromGLTF( glTF* gltf, const std::string& basePath ) + for(auto& actor : actors) { - const auto& materials = gltf->GetMaterials(); - const auto& textures = gltf->GetTextures(); + actor.RegisterProperty("lightDir", DEFAULT_LIGHT_DIRECTION); + actor.RegisterProperty("eyePos", cameraPosition); + } - std::map textureCache{}; + return actors[0]; +} - for(const auto& material : materials ) - { - TextureSet textureSet; - if(material.pbrMetallicRoughness.enabled) - { - textureSet = TextureSet::New(); - std::string filename( basePath ); - filename += '/'; - filename += textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; - Dali::PixelData pixelData = Dali::Toolkit::SyncImageLoader::Load( filename ); - - auto cacheKey = textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; - auto iter = textureCache.find(cacheKey); - Texture texture; - if(iter == textureCache.end()) - { - texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), - pixelData.GetHeight()); - texture.Upload(pixelData); - texture.GenerateMipmaps(); - textureCache[cacheKey] = texture; - } - else - { - texture = iter->second; - } - textureSet.SetTexture( 0, texture ); - Dali::Sampler sampler = Dali::Sampler::New(); - sampler.SetWrapMode( Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT ); - sampler.SetFilterMode( Dali::FilterMode::LINEAR_MIPMAP_LINEAR, Dali::FilterMode::LINEAR ); - textureSet.SetSampler( 0, sampler ); - } - mTextureSets.emplace_back( textureSet ); - } +} // unnamed namespace + +// This example shows how to create and display mirrored reflection using CameraActor +// +class ReflectionExample : public ConnectionTracker +{ +public: + ReflectionExample(Application& application) + : mApplication(application) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect(this, &ReflectionExample::Create); } - template - bool LoadFile( const std::string& filename, std::vector& bytes ) + ~ReflectionExample() = default; + +private: + // The Init signal is received once (only) during the Application lifetime + void Create(Application& application) { - Dali::FileStream fileStream( filename, Dali::FileStream::READ | Dali::FileStream::BINARY ); - FILE* fin = fileStream.GetFile(); + // Get a handle to the window + Window window = application.GetWindow(); + uint32_t windowWidth = uint32_t(window.GetSize().GetWidth()); + uint32_t windowHeight = uint32_t(window.GetSize().GetHeight()); - if( fin ) - { - if( fseek( fin, 0, SEEK_END ) ) - { - return false; - } - bytes.resize( uint32_t(ftell( fin )) ); - std::fill( bytes.begin(), bytes.end(), 0 ); - if( fseek( fin, 0, SEEK_SET ) ) - { - return false; - } - size_t result = fread( bytes.data(), 1, bytes.size(), fin ); - return ( result != 0 ); - } + window.GetRenderTaskList().GetTask(0).SetClearEnabled(false); + mLayer3D = Layer::New(); + mLayer3D.SetProperty(Actor::Property::SIZE, Vector2(windowWidth, windowHeight)); + window.Add(mLayer3D); - return false; - } + mLayer3D.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + mLayer3D.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mLayer3D.SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D); + mLayer3D.SetProperty(Layer::Property::DEPTH_TEST, true); - Shader CreateShader( const std::string& vsh, const std::string& fsh ) - { - std::vector vshShaderSource; - std::vector fshShaderSource; + auto gltf = glTF(DEMO_GAME_DIR "/reflection"); - // VSH - if(vsh[0] == '/') - { - std::string vshPath( DEMO_GAME_DIR ); - vshPath += '/'; - vshPath += vsh; - LoadFile( vshPath, vshShaderSource ); - } - else - { - vshShaderSource.insert(vshShaderSource.end(), vsh.begin(), vsh.end()); - } + // Define direction of light - // FSH - if(fsh[0] == '/') - { - std::string fshPath( DEMO_GAME_DIR ); - fshPath += '/'; - fshPath += fsh; - LoadFile( fshPath, fshShaderSource ); - } - else - { - fshShaderSource.insert(fshShaderSource.end(), fsh.begin(), fsh.end()); - } + /** + * Instantiate texture sets + */ + CreateTextureSetsFromGLTF(&gltf, DEMO_GAME_DIR, mTextureSets); - vshShaderSource.emplace_back(0); - fshShaderSource.emplace_back(0); - return Shader::New( std::string(vshShaderSource.data()), std::string(fshShaderSource.data()) ); - } + /** + * Create models + */ + CreateModelsFromGLTF(&gltf, mModels); - std::unique_ptr CreateModel( glTF& gltf, - const glTF_Mesh* mesh, - const std::string& vertexShaderSource, - const std::string& fragmentShaderSource ) - { - /* - * Obtain interleaved buffer for first mesh with position and normal attributes + /** + * Create scene nodes & add to 3D Layer */ - auto positionBuffer = gltf.GetMeshAttributeBuffer( *mesh, - { - glTFAttributeType::POSITION, - glTFAttributeType::NORMAL, - glTFAttributeType::TEXCOORD_0 - } ); - - auto attributeCount = gltf.GetMeshAttributeCount( mesh ); + mLayer3D.Add(CreateSceneFromGLTF(window, &gltf, mModels, mActors, mCameras, mTextureSets)); + + auto planeActor = mLayer3D.FindChildByName("Plane"); + auto solarActor = mLayer3D.FindChildByName("solar_root"); + auto backgroundActor = mLayer3D.FindChildByName("background"); + ReplaceShader(backgroundActor, VERTEX_SHADER, FRAGMENT_SIMPLE_SHADER); + mCenterActor = mLayer3D.FindChildByName("center"); + mCenterHorizActor = mLayer3D.FindChildByName("center2"); + + // Prepare Sun + auto sun = mLayer3D.FindChildByName("sun"); + ReplaceShader(sun, VERTEX_SHADER, PLASMA_FRAGMENT_SHADER); + mSunTimeUniformIndex = sun.RegisterProperty("uTime", 0.0f); + mSunKFactorUniformIndex = sun.RegisterProperty("uKFactor", 0.0f); + + mTickTimer = Timer::New(16); + mTickTimer.TickSignal().Connect(this, &ReflectionExample::TickTimerSignal); + + // Milkyway + auto milkyway = mLayer3D.FindChildByName("milkyway"); + ReplaceShader(milkyway, VERTEX_SHADER, FRAGMENT_SHADER); + + auto renderTaskSourceActor = mLayer3D.FindChildByName("RenderTaskSource"); + /** - * Create matching property buffer + * Access camera (it's a child of "Camera" node) */ - auto vertexBuffer = PropertyBuffer::New( Property::Map() - .Add("aPosition", Property::VECTOR3 ) - .Add("aNormal", Property::VECTOR3) - .Add("aTexCoord", Property::VECTOR2) - ); - - // set vertex data - vertexBuffer.SetData( positionBuffer.data(), attributeCount ); - - auto geometry = Geometry::New(); - geometry.AddVertexBuffer( vertexBuffer ); - auto indexBuffer = gltf.GetMeshIndexBuffer( mesh ); - geometry.SetIndexBuffer( indexBuffer.data(), indexBuffer.size() ); - geometry.SetType( Geometry::Type::TRIANGLES ); - std::unique_ptr retval( new Model() ); - retval->shader = CreateShader( vertexShaderSource, fragmentShaderSource ); - retval->geometry = geometry; - return retval; - } + auto camera = mLayer3D.FindChildByName("Camera_Orientation"); + auto cameraRef = mLayer3D.FindChildByName("CameraReflection_Orientation"); - void ReplaceShader( Actor& actor, const std::string& vsh, const std::string& fsh ) - { - auto renderer = actor.GetRendererAt(0); - auto shader = CreateShader(vsh, fsh); - renderer.SetShader( shader ); + auto cameraActor = CameraActor::DownCast(camera); + mCamera3D = cameraActor; + + auto cameraRefActor = CameraActor::DownCast(cameraRef); + cameraRefActor.SetProperty(DevelCameraActor::Property::REFLECTION_PLANE, Vector4(0.0f, -1.0f, 0.0f, 0.0f)); + mReflectionCamera3D = cameraRefActor; + + auto task3D = window.GetRenderTaskList().CreateTask(); + task3D.SetSourceActor(mLayer3D); + task3D.SetViewport(Rect(0, 0, windowWidth, windowHeight)); + task3D.SetCameraActor(cameraActor); + task3D.SetClearColor(Color::BLACK); + task3D.SetClearEnabled(true); + task3D.SetExclusive(false); + task3D.SetCameraActor(cameraActor); + + /** + * Change shader to textured + */ + Shader texShader = CreateShader(VERTEX_SHADER, TEX_FRAGMENT_SHADER); + planeActor.RegisterProperty("uScreenSize", Vector2(windowWidth, windowHeight)); + auto renderer = planeActor.GetRendererAt(0); + auto textureSet = renderer.GetTextures(); + renderer.SetShader(texShader); + + Texture fbTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, windowWidth, windowHeight); + textureSet.SetTexture(1u, fbTexture); + + auto fb = FrameBuffer::New(windowWidth, windowHeight, FrameBuffer::Attachment::DEPTH); + + fb.AttachColorTexture(fbTexture); + + auto renderTask = window.GetRenderTaskList().CreateTask(); + renderTask.SetFrameBuffer(fb); + renderTask.SetSourceActor(renderTaskSourceActor); + renderTask.SetViewport(Rect(0, 0, windowWidth, windowHeight)); + renderTask.SetCameraActor(cameraRefActor); + renderTask.SetClearColor(Color::BLACK); + renderTask.SetClearEnabled(true); + renderTask.SetExclusive(false); + + mAnimation = Animation::New(30.0f); + mAnimation.AnimateBy(Property(solarActor, Actor::Property::ORIENTATION), + Quaternion(Degree(359), Vector3(0.0, 1.0, 0.0))); + mAnimation.AnimateBy(Property(milkyway, Actor::Property::ORIENTATION), + Quaternion(Degree(-359), Vector3(0.0, 1.0, 0.0))); + mAnimation.SetLooping(true); + mAnimation.Play(); + + Actor panScreen = Actor::New(); + Vector2 windowSize = window.GetSize(); + panScreen.SetProperty(Actor::Property::SIZE, windowSize); + panScreen.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + panScreen.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + auto camera2d = window.GetRenderTaskList().GetTask(0).GetCameraActor(); + panScreen.SetProperty(Actor::Property::POSITION, Vector3(0, 0, camera2d.GetNearClippingPlane())); + camera2d.Add(panScreen); + camera2d.RotateBy(Degree(180.0f), Vector3(0.0, 1.0, 0.0)); + mPanGestureDetector = PanGestureDetector::New(); + mPanGestureDetector.Attach(panScreen); + mPanGestureDetector.DetectedSignal().Connect(this, &ReflectionExample::OnPan); + + // Respond to key events + window.KeyEventSignal().Connect(this, &ReflectionExample::OnKeyEvent); + + mTickTimer.Start(); } - void OnPan( Actor actor, const PanGesture& panGesture ) + void OnPan(Actor actor, const PanGesture& panGesture) { - auto displacement = panGesture.screenDisplacement; - mCenterActor.RotateBy( Degree( displacement.y *0.1f ), Vector3( 0.0, 0.0, 1.0) ); - mCenterActor.RotateBy( Degree( displacement.x *0.1f ), Vector3( 0.0, 1.0, 0.0) ); + const auto& displacement = panGesture.GetScreenDisplacement(); + mCenterActor.RotateBy(Degree(displacement.y * 0.1f), Vector3(0.0, 0.0, 1.0)); + mCenterActor.RotateBy(Degree(displacement.x * 0.1f), Vector3(0.0, 1.0, 0.0)); Quaternion q; - mCenterActor.GetProperty( Actor::Property::ORIENTATION ).Get(q); + mCenterActor.GetProperty(Actor::Property::ORIENTATION).Get(q); Matrix m = Matrix::IDENTITY; - m.SetTransformComponents( Vector3::ONE, q, Vector3::ZERO ); + m.SetTransformComponents(Vector3::ONE, q, Vector3::ZERO); auto yAxis = m.GetYAxis() * -1.0f; yAxis.Normalize(); - mReflectionCamera3D.SetProperty( DevelCameraActor::Property::REFLECTION_PLANE, Vector4(yAxis.x, yAxis.y, yAxis.z, 0.0f)); + mReflectionCamera3D.SetProperty(DevelCameraActor::Property::REFLECTION_PLANE, Vector4(yAxis.x, yAxis.y, yAxis.z, 0.0f)); } - void OnKeyEvent( const KeyEvent& event ) + void OnKeyEvent(const KeyEvent& event) { - if( event.state == KeyEvent::Down ) + if(event.GetState() == KeyEvent::DOWN) { - if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK)) { mApplication.Quit(); } @@ -620,55 +621,53 @@ private: bool TickTimerSignal() { - auto root = mLayer3D; + auto root = mLayer3D; static float rotationAngle = 0.0f; const auto ROTATION_ANGLE_STEP = 0.05f; - const auto FRAME_DELTA_TIME = 0.016f; - const auto PLASMA_K_FACTOR = 12.0f; // 'granularity' of plasma effect + const auto FRAME_DELTA_TIME = 0.016f; + const auto PLASMA_K_FACTOR = 12.0f; // 'granularity' of plasma effect rotationAngle += ROTATION_ANGLE_STEP; mMockTime += FRAME_DELTA_TIME; mKFactor = PLASMA_K_FACTOR; - auto sun = root.FindChildByName( "sun" ); - sun.SetProperty( mSunTimeUniformIndex, mMockTime ); - sun.SetProperty( mSunKFactorUniformIndex, mKFactor ); - sun.SetOrientation( Quaternion( Radian(Degree(rotationAngle)), Vector3(0.0, 1.0, 0.0))); + auto sun = root.FindChildByName("sun"); + sun.SetProperty(mSunTimeUniformIndex, mMockTime); + sun.SetProperty(mSunKFactorUniformIndex, mKFactor); + sun.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(rotationAngle)), Vector3(0.0, 1.0, 0.0))); return true; } private: - Application& mApplication; - - Layer mLayer3D; - - std::vector mActors; - std::vector mCameras; - std::vector> mModels; - std::vector mTextureSets; - - Animation mAnimation; - float mMockTime = 0.0f; - float mKFactor = 0.0f; - Property::Index mSunTimeUniformIndex; - Property::Index mSunKFactorUniformIndex; - PanGestureDetector mPanGestureDetector; - - Vector3 mCameraPos; - Vector3 mLightDir; - Timer mTickTimer; - - CameraActor mCamera3D; - CameraActor mReflectionCamera3D; - Actor mCenterActor; - Actor mCenterHorizActor; + Application& mApplication; + + Layer mLayer3D{}; + + ActorContainer mActors{}; + CameraContainer mCameras{}; + ModelContainer mModels{}; + TextureSetContainer mTextureSets{}; + + Animation mAnimation{}; + float mMockTime{0.0f}; + float mKFactor{0.0f}; + Property::Index mSunTimeUniformIndex{}; + Property::Index mSunKFactorUniformIndex{}; + PanGestureDetector mPanGestureDetector{}; + + Timer mTickTimer{}; + + CameraActor mCamera3D{}; + CameraActor mReflectionCamera3D{}; + Actor mCenterActor{}; + Actor mCenterHorizActor{}; }; -int DALI_EXPORT_API main( int argc, char **argv ) +int DALI_EXPORT_API main(int argc, char** argv) { - Application application = Application::New( &argc, &argv ); - ReflectionExample test( application ); + Application application = Application::New(&argc, &argv); + ReflectionExample test(application); application.MainLoop(); return 0; }