diff --git a/ios/src/SceneAsset.cpp b/ios/src/SceneAsset.cpp index 41b18813..eb2a32a4 100644 --- a/ios/src/SceneAsset.cpp +++ b/ios/src/SceneAsset.cpp @@ -1,15 +1,22 @@ -#include "SceneAsset.hpp" -#include "Log.hpp" -#include "SceneResources.hpp" +#include #include + +#include +#include +#include + #include #include #include #include #include +#include -#include +#include "StreamBufferAdapter.hpp" +#include "SceneAsset.hpp" +#include "Log.hpp" +#include "SceneResources.hpp" using namespace std::chrono; @@ -18,11 +25,13 @@ namespace polyvox { using namespace std; using namespace filament; using namespace filament::gltfio; +using namespace image; using namespace utils; +using namespace filament::math; SceneAsset::SceneAsset(FilamentAsset *asset, Engine *engine, - NameComponentManager *ncm) - : _asset(asset), _engine(engine), _ncm(ncm) { + NameComponentManager *ncm, LoadResource loadResource, FreeResource freeResource) + : _asset(asset), _engine(engine), _ncm(ncm), _loadResource(loadResource), _freeResource(freeResource) { _animator = _asset->getAnimator(); for (int i = 0; i < _animator->getAnimationCount(); i++) { _embeddedAnimationStatus.push_back( @@ -112,18 +121,59 @@ void SceneAsset::stopAnimation(int index) { _embeddedAnimationStatus[index].started = false; } -// void SceneAsset:swapTexture() { -// materialInstance = material2.createInstance() -// baseColor = loadTexture(filament.engine, context.resources, R.drawable.wall_tex_at, TextureType.COLOR) -// normal = loadTexture(filament.engine, context.resources,R.drawable.wall_tex_n,TextureType.NORMAL) -// ao = loadTexture(filament.engine, context.resources,R.drawable.wall_tex_ao,TextureType.DATA) -// roughnessMetallic = loadTexture(filament.engine, context.resources,R.drawable.wall_tex_ms,TextureType.DATA) -// val rm = filament.engine.renderableManager -// val sampler = TextureSampler() -// sampler.anisotropy = 8.0f -// material.setParameter("baseColorIndex",0) -// material.setParameter("baseColorMap",baseColor,sampler) -// } +void SceneAsset::setTexture(const char* resourcePath, int renderableIndex) { + + ResourceBuffer imageResource = _loadResource(resourcePath); + + polyvox::StreamBufferAdapter sb((char *)imageResource.data, (char *)imageResource.data + imageResource.size); + + std::istream *inputStream = new std::istream(&sb); + + LinearImage *image = new LinearImage(ImageDecoder::decode( + *inputStream, resourcePath, ImageDecoder::ColorSpace::SRGB)); + + if (!image->isValid()) { + Log("Invalid image : %s", resourcePath); + return; + } + + delete inputStream; + + _freeResource(imageResource); + + uint32_t channels = image->getChannels(); + uint32_t w = image->getWidth(); + uint32_t h = image->getHeight(); + auto texture = Texture::Builder() + .width(w) + .height(h) + .levels(0xff) + .format(channels == 3 ? Texture::InternalFormat::RGB16F + : Texture::InternalFormat::RGBA16F) + .sampler(Texture::Sampler::SAMPLER_2D) + .build(*_engine); + + Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t, + void *data) { + delete reinterpret_cast(data); + }; + + Texture::PixelBufferDescriptor buffer( + image->getPixelRef(), size_t(w * h * channels * sizeof(float)), + channels == 3 ? Texture::Format::RGB : Texture::Format::RGBA, + Texture::Type::FLOAT, freeCallback); + + texture->setImage(*_engine, 0, std::move(buffer)); + + size_t mic = _asset->getMaterialInstanceCount(); + MaterialInstance* const* inst = _asset->getMaterialInstances(); + Log("Material instance count : %d", mic); + + RenderableManager &rm = _engine->getRenderableManager(); + auto sampler = TextureSampler(); + inst[0]->setParameter("baseColorIndex",0); + inst[0]->setParameter("baseColorMap",texture,sampler); +} void SceneAsset::updateEmbeddedAnimations() { auto now = high_resolution_clock::now(); diff --git a/ios/src/SceneAsset.hpp b/ios/src/SceneAsset.hpp index a6db2391..42c6e568 100644 --- a/ios/src/SceneAsset.hpp +++ b/ios/src/SceneAsset.hpp @@ -23,12 +23,17 @@ namespace polyvox { class SceneAsset { friend class SceneAssetLoader; public: - SceneAsset(FilamentAsset* asset, Engine* engine, NameComponentManager* ncm); + SceneAsset(FilamentAsset* asset, Engine* engine, NameComponentManager* ncm, LoadResource loadResource, FreeResource freeResource); ~SceneAsset(); unique_ptr> getTargetNames(const char* meshName); unique_ptr> getAnimationNames(); + /// + /// + /// + void setTexture(const char* resourcePath, int renderableIndex); + /// /// Update the bone/morph target animations to reflect the current frame (if applicable). /// @@ -79,5 +84,8 @@ namespace polyvox { unique_ptr _morphAnimationBuffer; vector _embeddedAnimationStatus; + LoadResource _loadResource; + FreeResource _freeResource; + }; } \ No newline at end of file diff --git a/ios/src/SceneAssetLoader.cpp b/ios/src/SceneAssetLoader.cpp index 783a54f9..3bbe3fa6 100644 --- a/ios/src/SceneAssetLoader.cpp +++ b/ios/src/SceneAssetLoader.cpp @@ -72,7 +72,7 @@ SceneAsset *SceneAssetLoader::fromGltf(const char *uri, asset->releaseSourceData(); Log("Load complete for GLTF at URI %s", uri); - return new SceneAsset(asset, _engine, _ncm); + return new SceneAsset(asset, _engine, _ncm, _loadResource,_freeResource); } SceneAsset *SceneAssetLoader::fromGlb(const char *uri) { @@ -111,7 +111,7 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) { asset->releaseSourceData(); Log("Successfully loaded GLB."); - return new SceneAsset(asset, _engine, _ncm); + return new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource); } void SceneAssetLoader::remove(SceneAsset *asset) {