Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Enable ETC2 compressed textures and add tool to generate them from ra…
Browse files Browse the repository at this point in the history
…w assets (#892)
  • Loading branch information
MortimerGoro authored and bluemarvin committed Dec 14, 2018
1 parent 91d4710 commit a24d68f
Show file tree
Hide file tree
Showing 61 changed files with 154 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ oculussig_*
third_party

user.properties*

# Node modules
node_modules
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ geckoViewLocalArm=/path/to/your/build/geckoview-nightly-armeabi-v7a-64.0.2018092
geckoViewLocalX86=/path/to/your/build/geckoview-nightly-x86-64.0.20180924100359.aar
```

## Compress assets

ETC2 compression is used to improve performance and memory usage. Raw assets are placed in the `uncompressed_assets` folder. You can generate the compressed textures using the compressor utility in `tools/compressor`. You need to set up [etc2comp](https://github.com/google/etc2comp) and make it available on your PATH before running the script. Run this command to generate the compressed assets:

```bash
npm install
gulp compress
```

## Development troubleshooting

### `Device supports , but APK only supports armeabi-v7a[...]`
Expand Down
4 changes: 2 additions & 2 deletions app/src/googlevr/assets/vr_controller_daydream.mtl
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd vr_controller_daydream_tex.png
map_Ka vr_controller_daydream_tex.png
map_Kd vr_controller_daydream_tex.ktx
map_Ka vr_controller_daydream_tex.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/negx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/negy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/negz.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/posx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/posy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/cave/posz.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/negx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/negy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/negz.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/posx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/posy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/meadow/posz.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/negx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/negy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/negz.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/posx.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/posy.ktx
Binary file not shown.
Binary file added app/src/main/assets/cubemap/space/posz.ktx
Binary file not shown.
Binary file added app/src/main/assets/spinners_v3.ktx
Binary file not shown.
2 changes: 1 addition & 1 deletion app/src/main/assets/spinners_v3.mtl
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd spinners_v3.jpg
map_Kd spinners_v3.ktx
Binary file removed app/src/main/assets/webvr_spinner.png
Binary file not shown.
18 changes: 11 additions & 7 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,16 @@ BrowserWorld::InitializeJava(JNIEnv* aEnv, jobject& aActivity, jobject& aAssetMa
m.loadingAnimation->LoadModels(m.loader);
m.rootController->AddNode(m.controllers->GetRoot());
std::string skyboxPath = VRBrowser::GetActiveEnvironment();
std::string extension;
if (VRBrowser::isOverrideEnvPathEnabled()) {
std::string storagePath = VRBrowser::GetStorageAbsolutePath(INJECT_SKYBOX_PATH);
if (std::ifstream(storagePath)) {
skyboxPath = storagePath;
extension = ".jpg";
}
}
#if !defined(SNAPDRAGONVR)
CreateSkyBox(skyboxPath.c_str());
CreateSkyBox(skyboxPath.c_str(), extension);
// Don't load the env model, we are going for skyboxes in v1.0
// CreateFloor();
#endif
Expand Down Expand Up @@ -650,7 +652,7 @@ BrowserWorld::UpdateEnvironment() {
ASSERT_ON_RENDER_THREAD();
std::string env = VRBrowser::GetActiveEnvironment();
VRB_LOG("Setting environment: %s", env.c_str());
CreateSkyBox(env.c_str());
CreateSkyBox(env.c_str(), "");
}

void
Expand Down Expand Up @@ -1071,21 +1073,23 @@ BrowserWorld::DrawSplashAnimation() {
}

void
BrowserWorld::CreateSkyBox(const std::string& basePath) {
BrowserWorld::CreateSkyBox(const std::string& aBasePath, const std::string& aExtension) {
ASSERT_ON_RENDER_THREAD();
const bool empty = basePath == "cubemap/void";
const bool empty = aBasePath == "cubemap/void";
const std::string extension = aExtension.empty() ? ".ktx" : aExtension;
if (m.skybox && empty) {
m.skybox->SetVisible(false);
return;
} else if (m.skybox) {
m.skybox->SetVisible(true);
m.skybox->Load(m.loader, basePath);
m.skybox->Load(m.loader, aBasePath, extension);
return;
} else if (!empty) {
VRLayerCubePtr layer = m.device->CreateLayerCube(1024, 1024);
GLenum glFormat = extension == ".ktx" ? GL_COMPRESSED_RGB8_ETC2 : GL_RGB8;
VRLayerCubePtr layer = m.device->CreateLayerCube(1024, 1024, glFormat);
m.skybox = Skybox::Create(m.create, layer);
m.rootOpaqueParent->AddNode(m.skybox->GetRoot());
m.skybox->Load(m.loader, basePath);
m.skybox->Load(m.loader, aBasePath, extension);
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/BrowserWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class BrowserWorld {
void DrawImmersive();
void DrawLoadingAnimation();
void DrawSplashAnimation();
void CreateSkyBox(const std::string& basePath);
void CreateSkyBox(const std::string& aBasePath, const std::string& aExtension);
void CreateFloor();
float DistanceToPlane(const vrb::NodePtr& aNode, const vrb::Vector& aPosition, const vrb::Vector& aDirection) const;
private:
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/DeviceDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class DeviceDelegate {
virtual VRLayerQuadPtr CreateLayerQuad(int32_t aWidth,
int32_t aHeight,
VRLayerQuad::SurfaceType aSurfaceType) { return nullptr; }
virtual VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight) { return nullptr; }
virtual VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) { return nullptr; }
virtual VRLayerEquirectPtr CreateLayerEquirect(const VRLayerQuadPtr &aSource) { return nullptr; }
virtual void DeleteLayer(const VRLayerPtr& aLayer) {};
protected:
Expand Down
13 changes: 8 additions & 5 deletions app/src/main/cpp/Skybox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ using namespace vrb;

namespace crow {

static TextureCubeMapPtr LoadTextureCube(vrb::CreationContextPtr& aContext, const std::string& aBasePath, GLuint targetTexture = 0) {
static TextureCubeMapPtr LoadTextureCube(vrb::CreationContextPtr& aContext, const std::string& aBasePath,
const std::string& aExtension, GLuint targetTexture = 0) {
TextureCubeMapPtr cubemap = vrb::TextureCubeMap::Create(aContext, targetTexture);
cubemap->SetTextureParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
cubemap->SetTextureParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
cubemap->SetTextureParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
cubemap->SetTextureParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
cubemap->SetTextureParameter(GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

auto path = [&](const std::string &name) { return aBasePath + "/" + name + ".jpg"; };
auto path = [&](const std::string &name) { return aBasePath + "/" + name + aExtension; };
vrb::TextureCubeMap::Load(aContext, cubemap, path("posx"), path("negx"), path("posy"),
path("negy"), path("posz"), path("negz"));
return cubemap;
Expand All @@ -48,6 +49,7 @@ struct Skybox::State {
vrb::GeometryPtr geometry;
vrb::ModelLoaderAndroidPtr loader;
std::string basePath;
std::string extension;
TextureCubeMapPtr texture;
State():
layerTextureHandle(0)
Expand Down Expand Up @@ -116,7 +118,7 @@ struct Skybox::State {
}


texture = LoadTextureCube(aContext, basePath);
texture = LoadTextureCube(aContext, basePath, extension);
vrb::RenderStatePtr state = geometry->GetRenderState();
state->SetTexture(texture);
state->SetMaterial(Color(1.0f, 1.0f, 1.0f), Color(1.0f, 1.0f, 1.0f), Color(0.0f, 0.0f, 0.0f),
Expand All @@ -135,19 +137,20 @@ struct Skybox::State {
return;
}
vrb::CreationContextPtr create = context.lock();
texture = LoadTextureCube(create, basePath, layerTextureHandle);
texture = LoadTextureCube(create, basePath, extension, layerTextureHandle);
texture->Bind();
layer->SetLoaded(true);
}
};

void
Skybox::Load(const vrb::ModelLoaderAndroidPtr& aLoader, const std::string& aBasePath) {
Skybox::Load(const vrb::ModelLoaderAndroidPtr& aLoader, const std::string& aBasePath, const std::string& aExtension) {
if (m.basePath == aBasePath) {
return;
}
m.loader = aLoader;
m.basePath = aBasePath;
m.extension = aExtension;
if (m.layer) {
m.LoadLayer();
} else {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/Skybox.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ typedef std::shared_ptr<VRLayerCube> VRLayerCubePtr;
class Skybox {
public:
static SkyboxPtr Create(vrb::CreationContextPtr aContext, const VRLayerCubePtr& aLayer = nullptr);
void Load(const vrb::ModelLoaderAndroidPtr& aLoader, const std::string &basePath);
void Load(const vrb::ModelLoaderAndroidPtr& aLoader, const std::string& aBasePath, const std::string& aExtension);
void SetVisible(bool aVisible);
void SetTransform(const vrb::Matrix& aTransform);
void SetTintColor(const vrb::Color& aTintColor);
Expand Down
4 changes: 2 additions & 2 deletions app/src/oculusvr/assets/vr_controller_oculusgo.mtl
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd vr_controller_oculusgo_tex.png
map_Ka vr_controller_oculusgo_tex.png
map_Kd vr_controller_oculusgo_tex.ktx
map_Ka vr_controller_oculusgo_tex.ktx
Binary file not shown.
11 changes: 7 additions & 4 deletions app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,10 @@ typedef std::shared_ptr<OculusLayerCube> OculusLayerCubePtr;

class OculusLayerCube: public OculusLayer<VRLayerCubePtr, ovrLayerCube2> {
public:
static OculusLayerCubePtr Create(const VRLayerCubePtr& aLayer) {
static OculusLayerCubePtr Create(const VRLayerCubePtr& aLayer, GLint aInternalFormat) {
auto result = std::make_shared<OculusLayerCube>();
result->layer = aLayer;
result->glFormat = aInternalFormat;
return result;
}

Expand All @@ -341,7 +342,7 @@ class OculusLayerCube: public OculusLayer<VRLayerCubePtr, ovrLayerCube2> {
ovrLayer.Offset.x = 0.0f;
ovrLayer.Offset.y = 0.0f;
ovrLayer.Offset.z = 0.0f;
swapChain = vrapi_CreateTextureSwapChain(VRAPI_TEXTURE_TYPE_CUBE, VRAPI_TEXTURE_FORMAT_8888, layer->GetWidth(), layer->GetHeight(), 1, false);
swapChain = vrapi_CreateTextureSwapChain3(VRAPI_TEXTURE_TYPE_CUBE, glFormat, layer->GetWidth(), layer->GetHeight(), 1, 1);
layer->SetTextureHandle(vrapi_GetTextureSwapChainHandle(swapChain, 0));
OculusLayer::Init();
}
Expand Down Expand Up @@ -375,6 +376,8 @@ class OculusLayerCube: public OculusLayer<VRLayerCubePtr, ovrLayerCube2> {
const ovrLayerHeader2 * Header() const override {
return &ovrLayer.Header;
}
protected:
GLint glFormat;
};


Expand Down Expand Up @@ -1059,15 +1062,15 @@ DeviceDelegateOculusVR::CreateLayerQuad(int32_t aWidth, int32_t aHeight,
}

VRLayerCubePtr
DeviceDelegateOculusVR::CreateLayerCube(int32_t aWidth, int32_t aHeight) {
DeviceDelegateOculusVR::CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) {
if (!m.layersEnabled) {
return nullptr;
}
if (m.cubeLayer) {
m.cubeLayer->Destroy();
}
VRLayerCubePtr layer = VRLayerCube::Create(aWidth, aHeight);
m.cubeLayer = OculusLayerCube::Create(layer);
m.cubeLayer = OculusLayerCube::Create(layer, aInternalFormat);
if (m.ovr) {
m.cubeLayer->Init();
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/oculusvr/cpp/DeviceDelegateOculusVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class DeviceDelegateOculusVR : public DeviceDelegate {
void EndFrame(const bool aDiscard) override;
VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerQuad::SurfaceType aSurfaceType) override;
VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight) override;
VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) override;
VRLayerEquirectPtr CreateLayerEquirect(const VRLayerQuadPtr &aSource) override;
void DeleteLayer(const VRLayerPtr& aLayer) override;
// Custom methods for NativeActivity render loop based devices.
Expand Down
4 changes: 2 additions & 2 deletions app/src/wavevr/assets/vr_controller_focus.mtl
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd vr_controller_focus_tex.png
map_Ka vr_controller_focus_tex.png
map_Kd vr_controller_focus_tex.ktx
map_Ka vr_controller_focus_tex.ktx
Binary file not shown.
80 changes: 80 additions & 0 deletions tools/compressor/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const fs = require('fs');
const path = require('path');
const gulp = require('gulp');
const sharp = require('sharp');
const tmp = require('tmp');
const execSync = require('child_process').execSync;
const readdirp = require('readdirp');

const assetsPath = '../../app/src/uncompressed_assets';
const assetFilter = ['*.jpg', '*.jpeg', '*.png'];

function compressAsset(source, target, rgba, done) {
if (fs.existsSync(target)) {
console.log("Already compressed: " + target);
done();
return;
}

const extension = path.extname(source);
if (extension !== ".png") {
// Etc2Tool requires png format
const tempImage = tmp.tmpNameSync() + ".png";
sharp(source)
.toFile(tempImage)
.then(data => {
compressAsset(tempImage, target, false, done);
})
.catch(err => {
console.log("PNG conversion failed for " + source + ": " + err);
done(err);
});
return;
}

try {
console.log("About to compress: " + target);
var format = rgba ? "RGBA8" : "RGB8";
var out = execSync(`EtcTool ${source} -output ${target} -format ${format} -effort 100 -v`).toString();
console.log(out);
done();
} catch (err) {
console.error(err.message);
done(err);
}
}

gulp.task('compress', function(done) {
let pending = 0;
let finished = false;
const settings = {
root: assetsPath,
fileFilter: assetFilter
};
readdirp(settings)
.on('data', function (entry) {
pending++;
const name = entry.fullPath;
const extension = path.extname(name);
let target = name.slice(0, -extension.length) + ".ktx";
target = target.replace("uncompressed_assets/", "");
compressAsset(name, target, true, function() {
pending--;
if (finished && !pending) {
done();
}
});
})
.on('warn', function(warn){
console.log("Warn: ", warn);
})
.on('error', function(err){
console.log("Error: ", err);
})
.on('end', function(){
finished = true;
if (!pending) {
done();
}
});
});
24 changes: 24 additions & 0 deletions tools/compressor/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "fxr-compressor",
"version": "1.0.0",
"description": "FxR asset compressor",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"fxr",
"asset",
"compressor"
],
"author": "Mozilla",
"license": "Apache-2.0",
"devDependencies": {
"gulp": "^4.0.0"
},
"dependencies": {
"readdirp": "^2.2.1",
"sharp": "^0.21.1",
"tmp": "0.0.33"
}
}

0 comments on commit a24d68f

Please sign in to comment.