| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "garnet/examples/escher/waterfall/scenes/wobbly_ocean_scene.h" |
| |
| #include "lib/escher/geometry/tessellation.h" |
| #include "lib/escher/geometry/types.h" |
| #include "lib/escher/material/color_utils.h" |
| #include "lib/escher/material/material.h" |
| #include "lib/escher/scene/model.h" |
| #include "lib/escher/scene/stage.h" |
| #include "lib/escher/shape/modifier_wobble.h" |
| #include "lib/escher/util/stopwatch.h" |
| #include "lib/escher/vk/image.h" |
| #include "lib/escher/vk/vulkan_context.h" |
| |
| using escher::MeshAttribute; |
| using escher::MeshSpec; |
| using escher::Object; |
| using escher::ShapeModifier; |
| using escher::TexturePtr; |
| using escher::vec2; |
| using escher::vec3; |
| |
| WobblyOceanScene::WobblyOceanScene(Demo* demo) : Scene(demo) {} |
| |
| void WobblyOceanScene::Init(escher::Stage* stage) { |
| bg_ = fxl::MakeRefCounted<escher::Material>(); |
| color1_ = fxl::MakeRefCounted<escher::Material>(); |
| color2_ = fxl::MakeRefCounted<escher::Material>(); |
| color3_ = fxl::MakeRefCounted<escher::Material>(); |
| color4_ = fxl::MakeRefCounted<escher::Material>(); |
| |
| bg_->set_color(vec3(0.8f, 0.8f, 0.8f)); |
| color1_->set_color(vec3(63.f / 255.f, 138.f / 255.f, 153.f / 255.f)); |
| color2_->set_color(vec3(143.f / 255.f, 143.f / 255.f, 143.f / 255.f)); |
| color3_->set_color(escher::SrgbToLinear(vec3(0.913f, 0.384f, 0.352f))); |
| color4_->set_color(escher::SrgbToLinear(vec3(0.286f, 0.545f, 0.607f))); |
| |
| TexturePtr checkerboard = escher()->NewTexture( |
| escher()->NewCheckerboardImage(14, 4), vk::Filter::eNearest); |
| checkerboard_material_ = fxl::MakeRefCounted<escher::Material>(); |
| checkerboard_material_->SetTexture(checkerboard); |
| |
| checkerboard_material_->set_color( |
| escher::SrgbToLinear(vec3(.164f, .254f, 0.278f))); |
| |
| // Create meshes for fancy wobble effect. |
| MeshSpec spec{MeshAttribute::kPosition2D | MeshAttribute::kPositionOffset | |
| MeshAttribute::kPerimeterPos | MeshAttribute::kUV}; |
| ring_mesh1_ = escher::NewRingMesh(escher(), spec, 8, vec2(0.f, 0.f), 300.f, |
| 250.f, 18.f, -15.f); |
| ring_mesh2_ = escher::NewRingMesh(escher(), spec, 8, vec2(0.f, 0.f), 200.f, |
| 150.f, 11.f, -8.f); |
| ring_mesh3_ = escher::NewRingMesh(escher(), spec, 8, vec2(0.f, 0.f), 100.f, |
| 50.f, 5.f, -2.f); |
| |
| // Make this mesh the size of the stage |
| float screenWidth = stage->viewing_volume().width(); |
| float screenHeight = stage->viewing_volume().height(); |
| |
| // Make this mesh the size of the stage |
| wobbly_ocean_mesh_ = escher::NewRectangleMesh( |
| escher(), spec, 8, vec2(screenWidth, screenHeight * 0.5f), vec2(0.f, 0.f), |
| 18.f, 0.f); |
| } |
| |
| WobblyOceanScene::~WobblyOceanScene() {} |
| |
| escher::Model* WobblyOceanScene::Update( |
| const escher::Stopwatch& stopwatch, uint64_t frame_count, |
| escher::Stage* stage, escher::PaperRenderer2* renderer) { |
| float current_time_sec = stopwatch.GetElapsedSeconds(); |
| |
| float screenWidth = stage->viewing_volume().width(); |
| float screenHeight = stage->viewing_volume().height(); |
| float minElevation = stage->viewing_volume().bottom(); |
| float maxElevation = stage->viewing_volume().top(); |
| float elevationRange = maxElevation - minElevation; |
| |
| std::vector<Object> objects; |
| |
| vec3 ring_pos(screenWidth * 0.5, screenHeight * 0.5, 10.f); |
| Object ring1(ring_pos + vec3(0, 0, 4.f), ring_mesh1_, color4_); |
| ring1.set_shape_modifiers(ShapeModifier::kWobble); |
| Object ring2(ring_pos + vec3(75., 0, 12.f), ring_mesh2_, color1_); |
| ring2.set_shape_modifiers(ShapeModifier::kWobble); |
| Object ring3(ring_pos + vec3(-125.0, 0, 24.f), ring_mesh3_, color3_); |
| ring3.set_shape_modifiers(ShapeModifier::kWobble); |
| |
| constexpr float TWO_PI = 6.28318530718f; |
| escher::ModifierWobble wobble_data1{{{-0.3f * TWO_PI, 0.4f, 7.f * TWO_PI}, |
| {-0.15 * TWO_PI, 0.2, 14.f * TWO_PI}, |
| {0 * TWO_PI, 0, 0 * TWO_PI}}}; |
| escher::ModifierWobble wobble_data2{{{0.3f * TWO_PI, 0.5f, 10.f * TWO_PI}, |
| {0.15f * TWO_PI, 0.3f, 15.f * TWO_PI}, |
| {0.2f * TWO_PI, 0.2f, 18.f * TWO_PI}}}; |
| escher::ModifierWobble wobble_data3{{{-0.6f * TWO_PI, 1.2f, 12.f * TWO_PI}, |
| {-.3f * TWO_PI, 0.8f, 8.f * TWO_PI}, |
| {0.4 * TWO_PI, 0.5, 15.f * TWO_PI}}}; |
| ring1.set_shape_modifier_data(wobble_data1); |
| ring2.set_shape_modifier_data(wobble_data2); |
| ring3.set_shape_modifier_data(wobble_data3); |
| |
| objects.push_back(ring1); |
| objects.push_back(ring2); |
| objects.push_back(ring3); |
| |
| escher::ModifierWobble ocean_wobble_data{ |
| {{-0.1f * TWO_PI, 0.75f, 7.f * TWO_PI}, |
| {-.2f * TWO_PI, .3f, 12.f * TWO_PI}, |
| {-.5f * TWO_PI, .1f, 16.f * TWO_PI}}}; |
| |
| // Create a wobbly rectangle |
| Object ocean_rect1(vec3(0.f, screenHeight * 0.65f, 2.f), wobbly_ocean_mesh_, |
| checkerboard_material_); |
| ocean_rect1.set_shape_modifiers(ShapeModifier::kWobble); |
| ocean_rect1.set_shape_modifier_data(ocean_wobble_data); |
| objects.push_back(ocean_rect1); |
| |
| // Orbiting circle1 |
| float circle1_orbit_radius = 275.f; |
| float circle1_x_pos = sin(current_time_sec * 0.85f) * circle1_orbit_radius + |
| (screenWidth * 0.65f); |
| float circle1_y_pos = cos(current_time_sec * 0.85f) * circle1_orbit_radius + |
| (screenHeight * 0.35f); |
| float circle1_elevation = |
| (sin(current_time_sec * 0.85f + 0.5f) * 0.5f + 0.5f) * elevationRange + |
| minElevation; |
| Object circle1(Object::NewCircle( |
| vec3(circle1_x_pos, circle1_y_pos, circle1_elevation), 60.f, color2_)); |
| objects.push_back(circle1); |
| |
| // Create our background plane |
| Object bg_plane(Object::NewRect(vec2(0.f, 0.f), |
| vec2(screenWidth, screenHeight), 0.f, bg_)); |
| |
| objects.push_back(bg_plane); |
| |
| // Create the Model |
| model_ = std::unique_ptr<escher::Model>(new escher::Model(objects)); |
| model_->set_time(current_time_sec); |
| |
| return model_.get(); |
| } |