Skip to content
This repository has been archived by the owner on Dec 15, 2020. It is now read-only.

Commit

Permalink
Wire up custom textures, make glyph textures use that pipeline as well
Browse files Browse the repository at this point in the history
Summary:
Modifying glyph textures to use the new TextureManager registration pipeline. Also exposing the functionality to React apps, so that custom textures can be applied to Image tags (for now). Included a new test showing how spriting can be achieved (solves #97).
Next steps will be to use the TextureManager and custom textures for Meshes, and then finally edit Image to use TextureManager for networked resources (2 more diffs!)

Reviewed By: mikearmstrong001

Differential Revision: D5051405

fbshipit-source-id: c067873
  • Loading branch information
andrewimm authored and facebook-github-bot committed May 15, 2017
1 parent ba1fcbd commit 0f8675a
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 69 deletions.
4 changes: 2 additions & 2 deletions Libraries/Utilities/createGlyph.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ let nextGlyph = 1;

function createGlyph(glyph, name) {
if (typeof name !== 'string') {
name = 'glyph_' + nextGlyph;
name = nextGlyph;
nextGlyph++;
}
const uri = 'glyph://' + name;
const uri = 'texture://glyph/' + name;
GlyphTextures.registerGlyph(name, glyph);

return {uri};
Expand Down
20 changes: 20 additions & 0 deletions Libraries/Utilities/texture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule texture
*/

/**
* Opaque wrapper around custom textures, allows us to change the implementation
* at any time.
*/
function texture(name, options) {
return {uri: 'texture://' + name};
}

module.exports = texture;
3 changes: 3 additions & 0 deletions Libraries/react-vr.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ const ReactVR = {
get asset() {
return require('asset');
},
get texture() {
return require('texture');
},

// Direct access to RN properties
get Animated() {
Expand Down
71 changes: 10 additions & 61 deletions ReactVR/js/Modules/GlyphTextures.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*/

import Module from './Module';
import {Texture} from 'three';

import type {ReactNativeContext} from '../ReactNativeContext';

Expand All @@ -29,13 +28,6 @@ type Instruction =
| ['arc', number, number, number, number, number]
| ['rect', number, number, number, number];

// Map of names to the instructions on how to build them
const GLYPH_DATA_MAP = {};
// Cache of generated textures, so each name is only generated once
const TEXTURE_CACHE: {[name: string]: Texture} = {};
// Any requests waiting for data
const PENDING_LOADS = {};

function drawGlyph(
context: CanvasRenderingContext2D,
instructions: Array<any>,
Expand Down Expand Up @@ -102,59 +94,16 @@ export default class GlyphTextures extends Module {
}

registerGlyph(name: string, glyph: GlyphData) {
GLYPH_DATA_MAP[name] = glyph;
if (PENDING_LOADS[name]) {
const resolve = PENDING_LOADS[name];
delete PENDING_LOADS[name];
resolve(glyph);
}
}

_getTextureWidth(name: string) {
if (!GLYPH_DATA_MAP[name]) {
throw new Error('unknown texture glyph: ' + name);
}
return GLYPH_DATA_MAP[name].width;
}

_getTextureHeight(name: string) {
if (!GLYPH_DATA_MAP[name]) {
throw new Error('unknown texture glyph: ' + name);
}
return GLYPH_DATA_MAP[name].height;
}

_getTexture(name: string): Promise<Texture> {
if (TEXTURE_CACHE[name]) {
return Promise.resolve(TEXTURE_CACHE[name]);
const canvas = document.createElement('canvas');
canvas.width = glyph.width;
canvas.height = glyph.height;
const context = canvas.getContext('2d');
if (!context) {
throw new Error('Could not generate 2d context of canvas');
}
const glyph = GLYPH_DATA_MAP[name];

const pending = PENDING_LOADS[name];
return (pending ||
new Promise((resolve, reject) => {
if (glyph) {
resolve(glyph);
} else {
// Someone has a requested a glyph, but it hasn't registered yet
PENDING_LOADS[name] = resolve;
}
}))
.then((glyph: GlyphData) => {
const canvas = document.createElement('canvas');
canvas.width = glyph.width;
canvas.height = glyph.height;
const context = canvas.getContext('2d');
if (!context) {
throw new Error('Could not generate 2d context of canvas');
}
context.translate(0.5, 0.5);
drawGlyph(context, glyph.instructions, glyph.color);
const tex = new Texture(canvas);
tex.needsUpdate = true;
TEXTURE_CACHE[name] = tex;

return tex;
});
context.translate(0.5, 0.5);
drawGlyph(context, glyph.instructions, glyph.color);
const url = 'glyph/' + name;
this._rnctx.TextureManager.registerLocalTextureSource(url, canvas);
}
}
1 change: 1 addition & 0 deletions ReactVR/js/ReactNativeContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ export class ReactNativeContext {
this.HeadModel && this.HeadModel.frame(camera);
this.VideoModule && this.VideoModule.frame();
this.AudioModule && this.AudioModule.frame(camera);
this.TextureManager.frame();

if (rootTag) {
this._applySceneTransform(camera, rootTag);
Expand Down
19 changes: 13 additions & 6 deletions ReactVR/js/Views/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,21 @@ export default class RCTImage extends RCTBaseView {
[],
]);
// only interested in the uri for the source
if (value.uri.indexOf('glyph://') === 0) {
const name = value.uri.substr(8);
const GlyphTextures = this._rnctx.GlyphTextures;
GlyphTextures._getTexture(name)
if (value.uri.indexOf('texture://') === 0) {
this._rnctx.TextureManager
.getTextureForURL(value.uri)
.then(tex => {
this.view.setImageTexture(tex);
const width = GlyphTextures._getTextureWidth(name);
const height = GlyphTextures._getTextureHeight(name);
const image = tex.image;
let width;
let height;
if (image instanceof Image) {
width = image.naturalWidth;
height = image.naturalHeight;
} else {
width = image.width || 0;
height = image.height || 0;
}
this.UIManager._rnctx.callFunction('RCTEventEmitter', 'receiveEvent', [
this.getTag(),
'topLoad',
Expand Down
1 change: 1 addition & 0 deletions defs/three.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ declare module 'three' {

declare class Texture {
generateMipmaps: boolean,
image: Image | HTMLCanvasElement,
wrapS: number,
wrapT: number,
minFilter: number,
Expand Down

0 comments on commit 0f8675a

Please sign in to comment.