title: Loading a mesh (obj+mtl) into WebGL using JSON
body: <p>I'm starting to learn WebGL and I've no experience at all with Graphics. </p>
  
  <p>I need to load a complete mesh into WebGL (Dabrovic Sponza from: <a href="http://graphics.cs.williams.edu/data/meshes.xml" rel="nofollow noreferrer">http://graphics.cs.williams.edu/data/meshes.xml</a> ). Since today the only type of model I've loaded it up was simple JSON through:</p>
  
  <pre><code>function loadModel(){
      var request=new XMLHttpRequest();
      request.open("GET", "sponza.json");
      request.onreadystatechange=function (){
          if(request.readyState==4)
              handleLoadedModel(JSON.parse(request.responseText));
      }
      request.send();   
  }
  </code></pre>
  
  <p>Now I've those files: </p>
  
  <p><img src="https://i.stack.imgur.com/TZRxu.png" alt="enter image description here"></p>
  
  <p>What I've done so far is: </p>
  
  <p>I converted the obj to JSON with this script found online</p>
  
  <pre><code>    function loadObj(url)
      {
          var req = new XMLHttpRequest();
          req.onreadystatechange = function () { processLoadObj(req) };
          req.open("GET", url, true);
          req.send(null);
      }
  
      function processLoadObj(req)
      {
          if (req.readyState == 4) {
              doLoadObj(req.responseText);
          }
      }
  
      function doLoadObj(text)
      {
          vertexArray = [ ];
          normalArray = [ ];
          textureArray = [ ];
          indexArray = [ ];
  
          var vertex = [ ];
          var normal = [ ];
          var texture = [ ];
          var facemap = { };
          var index = 0;
  
          var lines = text.split("\n");
          for (var lineIndex in lines) {
              var line = lines[lineIndex].replace(/[ \t]+/g, " ").replace(/\s\s*$/, "");
  
              // ignore comments
              if (line[0] == "#")
                  continue;
  
              var array = line.split(" ");
              if (array[0] == "v") {
                  // vertex
                  vertex.push(parseFloat(array[1]));
                  vertex.push(parseFloat(array[2]));
                  vertex.push(parseFloat(array[3]));
              }
              else if (array[0] == "vt") {
                  // normal
                  texture.push(parseFloat(array[1]));
                  texture.push(parseFloat(array[2]));
              }
              else if (array[0] == "vn") {
                  // normal
                  normal.push(parseFloat(array[1]));
                  normal.push(parseFloat(array[2]));
                  normal.push(parseFloat(array[3]));
              }
              else if (array[0] == "f") {
                  // face
                  if (array.length != 4) {
                      //obj.ctx.console.log("*** Error: face '"+line+"' not handled");
                      continue;
                  }
  
                  for (var i = 1; i &lt; 4; ++i) {
                      if (!(array[i] in facemap)) {
                          // add a new entry to the map and arrays
                          var f = array[i].split("/");
                          var vtx, nor, tex;
  
                          if (f.length == 1) {
                              vtx = parseInt(f[0]) - 1;
                              nor = vtx;
                              tex = vtx;
                          }
                          else if (f.length = 3) {
                              vtx = parseInt(f[0]) - 1;
                              tex = parseInt(f[1]) - 1;
                              nor = parseInt(f[2]) - 1;
                          }
                          else {
                              //obj.ctx.console.log("*** Error: did not understand face '"+array[i]+"'");
                              return null;
                          }
  
                          // do the vertices
                          var x = 0;
                          var y = 0;
                          var z = 0;
                          if (vtx * 3 + 2 &lt; vertex.length) {
                              x = vertex[vtx*3];
                              y = vertex[vtx*3+1];
                              z = vertex[vtx*3+2];
                          }
                          vertexArray.push(x);
                          vertexArray.push(y);
                          vertexArray.push(z);
  
                          // do the textures
                          x = 0;
                          y = 0;
                          if (tex * 2 + 1 &lt; texture.length) {
                              x = texture[tex*2];
                              y = texture[tex*2+1];
                          }
                          textureArray.push(x);
                          textureArray.push(y);
  
                          // do the normals
                          x = 0;
                          y = 0;
                          z = 1;
                          if (nor * 3 + 2 &lt; normal.length) {
                              x = normal[nor*3];
                              y = normal[nor*3+1];
                              z = normal[nor*3+2];
                          }
                          normalArray.push(x);
                          normalArray.push(y);
                          normalArray.push(z);
  
                          facemap[array[i]] = index++;
                      }
  
                      indexArray.push(facemap[array[i]]);
                  }
              }
          }
  
          result = {};
          result["vertexPositions"] = vertexArray;
          result["vertexNormals"] = normalArray;
          result["vertexTextureCoords"] = textureArray;
          result["indices"] = indexArray;;
  
  
          document.write(JSON.stringify(result));
  
      }
      &lt;/script&gt;
      &lt;/head&gt;
  
  
      &lt;body onload="loadObj('model.obj');"&gt;
      &lt;/body&gt;
  </code></pre>
  
  <p>Then put all the info into buffers (1 for text coords, 1 for vertices, 1 for normals, 1 for indices) </p>
  
  <p>And finally used a single texture for everything.</p>
  
  <p>The result is far beyond the dabrovic sponza (a random pic on google image show what I want), how can I use those jpg file and .mtl ? </p>
  
  <p>I don't even know exactly what an mtl file is and I've no experience AT ALL with those stuff, this is my first attempt, so please be patient with me! </p>
  
  <p>Also, sorry if my English is bad!</p>
  
  <p>EDIT: 
  Also, loading the mesh with a random model loader I found out that not all the vertices are correctly converted (e.g. I don't have the floor). Moreover if I use a texture for everything some parts (collonades) are rendered as fully transparent... maybe my converter is bad. There is a chance for me to write a decent converter ? Where I can find documentation to do so ? Thanks again </p>