Impl(Public *i) : Base(i) { lightIntensityFactor.set(NumberValue(1.75)); observer.audienceForAvailability() += this; bank.audienceForLoad() += this; }
void assetAvailabilityChanged(String const &identifier, filesys::AssetObserver::Event event) { //qDebug() << "loading model:" << identifier << event; if(event == filesys::AssetObserver::Added) { bank.add(identifier, App::asset(identifier).absolutePath("path")); // Begin loading the model right away. bank.load(identifier); } else { bank.remove(identifier); } }
void deinit() { // GL resources must be accessed from the main thread only. bank.unloadAll(Bank::ImmediatelyInCurrentThread); atlasPool.clear(); unloadProgram(*programs[SHADER_DEFAULT]); }
void deinit() { // GL resources must be accessed from the main thread only. bank.unloadAll(Bank::ImmediatelyInCurrentThread); atlas.reset(); program.clear(); }
void assetAvailabilityChanged(String const &identifier, filesys::AssetObserver::Event event) { LOG_RES_MSG("Model asset \"%s\" is now %s") << identifier << (event == filesys::AssetObserver::Added? "available" : "unavailable"); if (event == filesys::AssetObserver::Added) { bank.add(identifier, App::asset(identifier).absolutePath("path")); // Begin loading the model right away. bank.load(identifier); } else { auto const &model = bank.model<render::Model const>(identifier); // Unload programs used by the various rendering passes. for (auto const &pass : model.passes) { DENG2_ASSERT(pass.program); unloadProgram(*static_cast<Program *>(pass.program)); } // Alternatively, the entire model may be using a single program. if (model.passes.isEmpty()) { if (model.program()) { unloadProgram(*static_cast<Program *>(model.program())); } } else { DENG2_ASSERT(!model.program()); } bank.remove(identifier); } }
/** * When model assets have been loaded, we can parse their metadata to see if there * are any animation sequences defined. If so, we'll set up a shared lookup table * that determines which sequences to start in which mobj states. * * @param path Model asset id. */ void bankLoaded(DotPath const &path) { // Models use the shared atlas. ModelDrawable &model = bank.model(path); model.audienceForAboutToGLInit() += this; auto const asset = App::asset(path); std::unique_ptr<AuxiliaryData> aux(new AuxiliaryData); // Determine the coordinate system of the model. Vector3f front(0, 0, 1); Vector3f up (0, 1, 0); if(asset.has(DEF_FRONT_VECTOR)) { front = Vector3f(asset.geta(DEF_FRONT_VECTOR)); } if(asset.has(DEF_UP_VECTOR)) { up = Vector3f(asset.geta(DEF_UP_VECTOR)); } bool mirror = ScriptedInfo::isTrue(asset, DEF_MIRROR); aux->cull = mirror? gl::Back : gl::Front; // Assimp's coordinate system uses different handedness than Doomsday, // so mirroring is needed. aux->transformation = Matrix4f::unnormalizedFrame(front, up, !mirror); aux->autoscaleToThingHeight = !ScriptedInfo::isFalse(asset, DEF_AUTOSCALE, false); // Custom texture maps. if(asset.has(DEF_MATERIAL)) { auto mats = asset.subrecord(DEF_MATERIAL).subrecords(); DENG2_FOR_EACH_CONST(Record::Subrecords, mat, mats) { handleMaterialTexture(model, mat.key(), *mat.value(), "diffuseMap", ModelDrawable::Diffuse); handleMaterialTexture(model, mat.key(), *mat.value(), "normalMap", ModelDrawable::Normals); handleMaterialTexture(model, mat.key(), *mat.value(), "heightMap", ModelDrawable::Height); handleMaterialTexture(model, mat.key(), *mat.value(), "specularMap", ModelDrawable::Specular); handleMaterialTexture(model, mat.key(), *mat.value(), "emissiveMap", ModelDrawable::Emissive); }
Instance(Public *i) : Base(i) { observer.audienceForAvailability() += this; bank.audienceForLoad() += this; }