I load an image to show a sprite.
But it seems that the code proceeds before the image is fully load:
dart:web_gl: RENDER WARNING: texture bound to texture unit 0 is not renderable
WebGL - wait for texture to load
But I don't know how to wait for the image to be fully loaded using Threejs. May I have some help?
The code can be tested here : .html
Here is my code:
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src=".js/master/build/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(0, 10, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var material = new THREE.LineBasicMaterial({ color: 0x0000ff });
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 10, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 0, -10));
var line = new THREE.Line(geometry, material);
scene.add(line);
var loader = new THREE.TextureLoader();
var spriteMap = loader.load(".png");
//+-----------------------------------------------------------+
//| I need here to wait for the image to be fully loaded |
//| This cheat is fool: while (spriteMap.image.width == 0); |
//+-----------------------------------------------------------+
var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } );
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(256, 256, 1);
sprite.position.set( 0, 0, 10 );
scene.add( sprite );
//camera.position.z = 2;
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
THREE JS TextureLoader is a little bit old...
I load an image to show a sprite.
But it seems that the code proceeds before the image is fully load:
dart:web_gl: RENDER WARNING: texture bound to texture unit 0 is not renderable
WebGL - wait for texture to load
But I don't know how to wait for the image to be fully loaded using Threejs. May I have some help?
The code can be tested here : http://www.planetarium2016./sprite.html
Here is my code:
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://rawgithub./mrdoob/three.js/master/build/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(0, 10, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var material = new THREE.LineBasicMaterial({ color: 0x0000ff });
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 10, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 0, -10));
var line = new THREE.Line(geometry, material);
scene.add(line);
var loader = new THREE.TextureLoader();
var spriteMap = loader.load("https://codefisher/static/images/pastel-svg/256/bullet-star.png");
//+-----------------------------------------------------------+
//| I need here to wait for the image to be fully loaded |
//| This cheat is fool: while (spriteMap.image.width == 0); |
//+-----------------------------------------------------------+
var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } );
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(256, 256, 1);
sprite.position.set( 0, 0, 10 );
scene.add( sprite );
//camera.position.z = 2;
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
THREE JS TextureLoader is a little bit old...
Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked May 2, 2017 at 8:08 Pierre-Louis DeschampsPierre-Louis Deschamps 3703 silver badges16 bronze badges 6- 1 Possible duplicate of THREE JS TextureLoader – StudioTime Commented May 2, 2017 at 8:27
- var textureLoader = new THREE.TextureLoader(); textureLoader.load(url,function(){ //to do logic here. }); see the TextureLoader Class document – Ajit kohir Commented May 2, 2017 at 8:54
- @darren-sweeney These old question and answers are obsolete – Pierre-Louis Deschamps Commented May 2, 2017 at 10:08
- @kian that's right: threejs/docs/#api/loaders/TextureLoader – Pierre-Louis Deschamps Commented May 2, 2017 at 10:09
-
@Pierre-LouisDeschamps Ah ok, my point was mainly to highlight
.load
callback, which you're now using – StudioTime Commented May 2, 2017 at 10:15
3 Answers
Reset to default 7I would solve this by using JavaScript promises. I separated your three.js code into two main functions, one for initialization and one for animation with requestAnimationFrame. It's more readable this way especially if you intend to perform an async task:
var scene;
var camera;
var renderer;
var spriteMap;
var loaderPromise = new Promise(function(resolve, reject) {
function loadDone(x) {
console.log("loader successfully pleted loading task");
resolve(x); // it went ok!
}
var loader = new THREE.TextureLoader();
loader.load("https://codefisher/static/images/pastel-svg/256/bullet-star.png", loadDone);
});
loaderPromise.
then(function(response) {
spriteMap = response; //assign loaded image data to a variable
init(); //initialize the render
requestAnimationFrame( render );
}, function(err) {
console.log(err);
});
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(0, 10, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var material = new THREE.LineBasicMaterial({ color: 0x0000ff });
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 10, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 0, -10));
var line = new THREE.Line(geometry, material);
scene.add(line);
var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } );
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(256, 256, 1);
sprite.position.set( 0, 0, 10 );
scene.add( sprite );
}
function render() {
renderer.render(scene, camera);
requestAnimationFrame( render );
}
solution here: https://threejs/docs/#api/loaders/TextureLoader
this is the code to solve my problem:
var url = "https://codefisher/static/images/pastel-svg/256/bullet-star.png";
var loader = new THREE.TextureLoader();
var spriteMaterial;
loader.load(url,
function(texture)
{
spriteMaterial = new THREE.SpriteMaterial( { map: texture, color: 0x0000ff } );
}
);
var sprite = new THREE.Sprite( spriteMaterial );
var loader = new THREE.TextureLoader();
loader.load(
'img/url/img.png',
function ( map ) {
// map var is your image
},
function ( xhr ) {
if ( xhr.lengthComputable ) {
console.log( 'percent: ' + (xhr.loaded / xhr.total * 100) );
}
},
function ( err ) {
console.log( 'An error happened' );
}
);
THREE 73