Weird problem while loading multiple textures in a for loop

Hi! I’ve been playing with WebGL for some time and I get stuck in a weird issue. I got a JSON file defining the position and src-image-for-texture for multiple elements. I load the positions in a ‘elementPositions’ array and the src-images in a ‘elementImageSrcs’ array. Then I have a ‘elementTextures’ array where I create all textures.

The problem comes when I try to initTextures() using the following line:

for (var i=0; i < numElements; i++) { elementTextures[i] = loadTexture(elementImageSrcs[i]); }

It just doesn’t work; it seems loadTexture() doesn’t like elementImageSrcs[i].

But if I use:


  elementImageSrcs[0] = "im/crate01.gif";
  elementImageSrcs[1] = "im/crate02.gif";
  elementImageSrcs[2] = "im/crate03.gif";

  elementTextures[0] = loadTexture(elementImageSrcs[0]);
  elementTextures[1] = loadTexture(elementImageSrcs[1]);
  elementTextures[2] = loadTexture(elementImageSrcs[2]);

It works perfectly.

I’ve spend nearly two days trying to realize what could be the problem but I didn’t find the answer (maybe the JSON loading? maybe my limited knowledge of JavaScript?). Anyone knows what I’m doing wrong?

You can check the code here.

Hey! I’ve been investigating further on this issue and I find the problem but it’s really weird… (at least for my understanding).

The problem is that when initTextures() is launched, ‘elementImageSrcs’ array is not filled yet.

How is that possible if I’m loading the JSON file previous to initTextures() ??? any idea ?

Do you load JSON asynchronously or synchronously?

Hi wglb, thanks for your answer.

Actually, I’m not sure which method I’m using… I use:

function initElements() {
  var request = new XMLHttpRequest();
  request.open("GET", "elements.json");
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      var jsonData = JSON.parse(request.responseText);
      for (var i=0; i < numElements; i++) {
        elementPositions[i] = jsonData.elements[i].position;
        elementImageSrcs[i] = jsonData.elements[i].imagesrc;
      }
    }
  }
  request.send();
}

And the initElements() is called in the main entry point, just before the initTextures().

I image this method is synchronously… how would it be asynchronously?

No, this is asynchronously, it means your JSON loading is in 99% done later, after initTextures(). More details here: https://developer.mozilla.org/en/XMLHttpRequest

This is equivalent in synchronous way:


function initElements() {
  var request = new XMLHttpRequest();
  request.open("GET", "elements.json", false); // false means not asynchronously
  request.send(null);
  if (req.status == 200) {
    var jsonData = JSON.parse(request.responseText);
    for (var i=0; i < numElements; i++) {
        elementPositions[i] = jsonData.elements[i].position;
        elementImageSrcs[i] = jsonData.elements[i].imagesrc;
      }
  }
}

Hi wglb! Many thanks for your answer! I tested it and now it works. Thanks! :smiley: