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.com/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.com/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.org/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...
I 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 completed loading task");
resolve(x); // it went ok!
}
var loader = new THREE.TextureLoader();
loader.load("https://codefisher.org/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 );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With