/* * Copyright (C) 2018 The Android Open Source Project * * 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 "common/arguments.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // for printing usage/help #include "generated/resources/resources.h" #include "generated/resources/monkey.h" using namespace filament; using namespace filamesh; using namespace filament::math; using Backend = Engine::Backend; struct App { Config config; utils::Entity light; Material* material; MaterialInstance* materialInstance; MeshReader::Mesh mesh; mat4f transform; }; static const char* IBL_FOLDER = "assets/ibl/lightroom_14b"; static void printUsage(char* name) { std::string exec_name(utils::Path(name).getName()); std::string usage( "EXEC renders a simple PBR example\n" "Usage:\n" " EXEC [options]\n" "Options:\n" " --help, -h\n" " Prints this message\n\n" "API_USAGE" ); const std::string from("EXEC"); for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) { usage.replace(pos, from.length(), exec_name); } const std::string apiUsage("API_USAGE"); for (size_t pos = usage.find(apiUsage); pos != std::string::npos; pos = usage.find(apiUsage, pos)) { usage.replace(pos, apiUsage.length(), samples::getBackendAPIArgumentsUsage()); } std::cout << usage; } static int handleCommandLineArguments(int argc, char* argv[], App* app) { static constexpr const char* OPTSTR = "ha:"; static const struct option OPTIONS[] = { { "help", no_argument, nullptr, 'h' }, { "api", required_argument, nullptr, 'a' }, { nullptr, 0, nullptr, 0 } }; int opt; int option_index = 0; while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) { std::string arg(optarg ? optarg : ""); switch (opt) { default: case 'h': printUsage(argv[0]); exit(0); case 'a': app->config.backend = samples::parseArgumentsForBackend(arg); break; } } return optind; } int main(int argc, char** argv) { App app; app.config.title = "hellopbr"; app.config.iblDirectory = FilamentApp::getRootAssetsPath() + IBL_FOLDER; handleCommandLineArguments(argc, argv, &app); auto setup = [config=app.config, &app](Engine* engine, View* view, Scene* scene) { auto& tcm = engine->getTransformManager(); auto& rcm = engine->getRenderableManager(); auto& em = utils::EntityManager::get(); // Instantiate material. app.material = Material::Builder() .package(RESOURCES_AIDEFAULTMAT_DATA, RESOURCES_AIDEFAULTMAT_SIZE).build(*engine); auto mi = app.materialInstance = app.material->createInstance(); mi->setParameter("baseColor", RgbType::LINEAR, float3{0.8}); mi->setParameter("metallic", 1.0f); mi->setParameter("roughness", 0.4f); mi->setParameter("reflectance", 0.5f); // Add geometry into the scene. app.mesh = MeshReader::loadMeshFromBuffer(engine, MONKEY_SUZANNE_DATA, nullptr, nullptr, mi); auto ti = tcm.getInstance(app.mesh.renderable); app.transform = mat4f{ mat3f(1), float3(0, 0, -4) } * tcm.getWorldTransform(ti); rcm.setCastShadows(rcm.getInstance(app.mesh.renderable), false); scene->addEntity(app.mesh.renderable); // Add light sources into the scene. app.light = em.create(); LightManager::Builder(LightManager::Type::SUN) .color(Color::toLinear(sRGBColor(0.98f, 0.92f, 0.89f))) .intensity(110000) .direction({ 0.7, -1, -0.8 }) .sunAngularRadius(1.9f) .castShadows(false) .build(*engine, app.light); scene->addEntity(app.light); }; auto cleanup = [&app](Engine* engine, View*, Scene*) { engine->destroy(app.light); engine->destroy(app.mesh.renderable); engine->destroy(app.materialInstance); engine->destroy(app.material); }; FilamentApp::get().animate([&app](Engine* engine, View* view, double now) { auto& tcm = engine->getTransformManager(); auto ti = tcm.getInstance(app.mesh.renderable); tcm.setTransform(ti, app.transform * mat4f::rotation(now, float3{ 0, 1, 0 })); }); FilamentApp::get().run(app.config, setup, cleanup); return 0; }