`texture` support.
diff --git a/examples/glview/README.md b/examples/glview/README.md
index b248bcf..cff927a 100644
--- a/examples/glview/README.md
+++ b/examples/glview/README.md
@@ -18,6 +18,7 @@
 
 ## TODO
 
-* [ ] Texture
+* [x] Texture
+  * [ ] Various texture format.
 * [ ] Shader
 * [ ] Animation
diff --git a/examples/glview/glview.cc b/examples/glview/glview.cc
index 1ab9817..fd3a466 100644
--- a/examples/glview/glview.cc
+++ b/examples/glview/glview.cc
@@ -20,6 +20,16 @@
 
 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
 
+#define CheckGLErrors(desc)                                                    \
+  {                                                                            \
+    GLenum e = glGetError();                                                   \
+    if (e != GL_NO_ERROR) {                                                    \
+      printf("OpenGL error in \"%s\": %d (%d) %s:%d\n", desc, e, e, __FILE__,  \
+             __LINE__);                                                        \
+      exit(20);                                                                \
+    }                                                                          \
+  }
+
 #define CAM_Z (3.0f)
 int width = 768;
 int height = 768;
@@ -32,19 +42,21 @@
 float prev_quat[4];
 float eye[3], lookat[3], up[3];
 
-GLFWwindow* window;
+GLFWwindow *window;
 
-typedef struct
-{
-  GLuint vb;
-} GLBufferState;
+typedef struct { GLuint vb; } GLBufferState;
 
-typedef struct
-{
+typedef struct {
+  std::vector<GLuint> diffuseTex; // for each primitive in mesh
+} GLMeshState;
+
+typedef struct {
   std::map<std::string, GLint> attribs;
+  std::map<std::string, GLint> uniforms;
 } GLProgramState;
 
 std::map<std::string, GLBufferState> gBufferState;
+std::map<std::string, GLMeshState> gMeshState;
 GLProgramState gGLProgramState;
 
 void CheckErrors(std::string desc) {
@@ -79,7 +91,7 @@
   srcbuf[len] = 0;
   fclose(fp);
 
-  const GLchar* srcs[1];
+  const GLchar *srcs[1];
   srcs[0] = &srcbuf.at(0);
 
   shader = glCreateShader(shaderType);
@@ -93,7 +105,7 @@
     printf("%s\n", log);
     // assert(val == GL_TRUE && "failed to compile shader");
     printf("ERR: Failed to load or compile shader [ %s ]\n",
-        shaderSourceFilename);
+           shaderSourceFilename);
     return false;
   }
 
@@ -122,8 +134,7 @@
   return true;
 }
 
-void reshapeFunc(GLFWwindow* window, int w, int h)
-{
+void reshapeFunc(GLFWwindow *window, int w, int h) {
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
@@ -135,113 +146,187 @@
   height = h;
 }
 
-void keyboardFunc(GLFWwindow *window, int key, int scancode, int action, int mods) {
-  if(action == GLFW_PRESS || action == GLFW_REPEAT){
+void keyboardFunc(GLFWwindow *window, int key, int scancode, int action,
+                  int mods) {
+  if (action == GLFW_PRESS || action == GLFW_REPEAT) {
     // Close window
-    if(key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, GL_TRUE);
+    if (key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE)
+      glfwSetWindowShouldClose(window, GL_TRUE);
   }
 }
 
-void clickFunc(GLFWwindow* window, int button, int action, int mods){
-    double x, y;
-    glfwGetCursorPos(window,&x, &y);
+void clickFunc(GLFWwindow *window, int button, int action, int mods) {
+  double x, y;
+  glfwGetCursorPos(window, &x, &y);
 
-    if(button == GLFW_MOUSE_BUTTON_LEFT){
-        mouseLeftPressed = true;
-        if(action == GLFW_PRESS){
-          int id = -1;
-          //int id = ui.Proc(x, y);
-          if (id < 0) { // outside of UI 
-            trackball(prev_quat, 0.0, 0.0, 0.0, 0.0);
-          }
-        } else if(action == GLFW_RELEASE){
-            mouseLeftPressed = false;
-        }
+  if (button == GLFW_MOUSE_BUTTON_LEFT) {
+    mouseLeftPressed = true;
+    if (action == GLFW_PRESS) {
+      int id = -1;
+      // int id = ui.Proc(x, y);
+      if (id < 0) { // outside of UI
+        trackball(prev_quat, 0.0, 0.0, 0.0, 0.0);
+      }
+    } else if (action == GLFW_RELEASE) {
+      mouseLeftPressed = false;
+    }
   }
-  if(button == GLFW_MOUSE_BUTTON_RIGHT){
-    if(action == GLFW_PRESS){
+  if (button == GLFW_MOUSE_BUTTON_RIGHT) {
+    if (action == GLFW_PRESS) {
       mouseRightPressed = true;
-    } else if(action == GLFW_RELEASE){
+    } else if (action == GLFW_RELEASE) {
       mouseRightPressed = false;
     }
   }
-  if(button == GLFW_MOUSE_BUTTON_MIDDLE){
-    if(action == GLFW_PRESS){
+  if (button == GLFW_MOUSE_BUTTON_MIDDLE) {
+    if (action == GLFW_PRESS) {
       mouseMiddlePressed = true;
-    } else if(action == GLFW_RELEASE){
+    } else if (action == GLFW_RELEASE) {
       mouseMiddlePressed = false;
     }
   }
 }
 
-void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y){
+void motionFunc(GLFWwindow *window, double mouse_x, double mouse_y) {
   float rotScale = 1.0f;
   float transScale = 2.0f;
 
-    if(mouseLeftPressed){
-      trackball(prev_quat,
-          rotScale * (2.0f * prevMouseX - width) / (float)width,
-          rotScale * (height - 2.0f * prevMouseY) / (float)height,
-          rotScale * (2.0f * mouse_x - width) / (float)width,
-          rotScale * (height - 2.0f * mouse_y) / (float)height);
+  if (mouseLeftPressed) {
+    trackball(prev_quat, rotScale * (2.0f * prevMouseX - width) / (float)width,
+              rotScale * (height - 2.0f * prevMouseY) / (float)height,
+              rotScale * (2.0f * mouse_x - width) / (float)width,
+              rotScale * (height - 2.0f * mouse_y) / (float)height);
 
-      add_quats(prev_quat, curr_quat, curr_quat);
-    } else if (mouseMiddlePressed) {
-      eye[0] += -transScale * (mouse_x - prevMouseX) / (float)width;
-      lookat[0] += -transScale * (mouse_x - prevMouseX) / (float)width;
-      eye[1] += transScale * (mouse_y - prevMouseY) / (float)height;
-      lookat[1] += transScale * (mouse_y - prevMouseY) / (float)height;
-    } else if (mouseRightPressed) {
-      eye[2] += transScale * (mouse_y - prevMouseY) / (float)height;
-      lookat[2] += transScale * (mouse_y - prevMouseY) / (float)height;
-    }
+    add_quats(prev_quat, curr_quat, curr_quat);
+  } else if (mouseMiddlePressed) {
+    eye[0] += -transScale * (mouse_x - prevMouseX) / (float)width;
+    lookat[0] += -transScale * (mouse_x - prevMouseX) / (float)width;
+    eye[1] += transScale * (mouse_y - prevMouseY) / (float)height;
+    lookat[1] += transScale * (mouse_y - prevMouseY) / (float)height;
+  } else if (mouseRightPressed) {
+    eye[2] += transScale * (mouse_y - prevMouseY) / (float)height;
+    lookat[2] += transScale * (mouse_y - prevMouseY) / (float)height;
+  }
 
   // Update mouse point
   prevMouseX = mouse_x;
   prevMouseY = mouse_y;
 }
 
-static void SetupGLState(Scene& scene, GLuint progId)
-{
-  std::map<std::string, BufferView>::const_iterator it(scene.bufferViews.begin());
-  std::map<std::string, BufferView>::const_iterator itEnd(scene.bufferViews.end());
+static void SetupGLState(Scene &scene, GLuint progId) {
+  // Buffer
+  {
+    std::map<std::string, BufferView>::const_iterator it(
+        scene.bufferViews.begin());
+    std::map<std::string, BufferView>::const_iterator itEnd(
+        scene.bufferViews.end());
 
-  for (; it != itEnd; it++) {
-    const BufferView& bufferView = it->second;
-    if (bufferView.target == 0) {
-      continue; // Unsupported bufferView.
+    for (; it != itEnd; it++) {
+      const BufferView &bufferView = it->second;
+      if (bufferView.target == 0) {
+        continue; // Unsupported bufferView.
+      }
+
+      const Buffer &buffer = scene.buffers[bufferView.buffer];
+      GLBufferState state;
+      glGenBuffers(1, &state.vb);
+      glBindBuffer(bufferView.target, state.vb);
+      glBufferData(bufferView.target, bufferView.byteLength,
+                   &buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
+      glBindBuffer(bufferView.target, 0);
+
+      gBufferState[it->first] = state;
     }
+  }
 
-    const Buffer& buffer = scene.buffers[bufferView.buffer];
-    GLBufferState state;
-    glGenBuffers(1, &state.vb);
-    glBindBuffer(bufferView.target, state.vb);
-    glBufferData(bufferView.target, bufferView.byteLength, &buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
-    glBindBuffer(bufferView.target, 0);
-    
-    gBufferState[it->first] = state;
+  // Texture
+  {
+    std::map<std::string, Mesh>::const_iterator it(scene.meshes.begin());
+    std::map<std::string, Mesh>::const_iterator itEnd(scene.meshes.end());
+
+    for (; it != itEnd; it++) {
+      const Mesh &mesh = it->second;
+
+      gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size());
+      for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
+        const Primitive &primitive = mesh.primitives[primId];
+
+        gMeshState[mesh.name].diffuseTex[primId] = 0;
+
+        if (primitive.material.empty()) {
+          continue;
+        }
+        Material &mat = scene.materials[primitive.material];
+        printf("material.name = %s\n", mat.name.c_str());
+        if (mat.values.find("diffuse") != mat.values.end()) {
+          std::string diffuseTexName = mat.values["diffuse"].stringValue;
+          if (scene.textures.find(diffuseTexName) != scene.textures.end()) {
+            Texture &tex = scene.textures[diffuseTexName];
+            if (scene.images.find(tex.source) != scene.images.end()) {
+              Image &image = scene.images[tex.source];
+              GLuint texId;
+              glGenTextures(1, &texId);
+              glBindTexture(tex.target, texId);
+              glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+              glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+              glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+              // Ignore Texture.fomat.
+              GLenum format = GL_RGBA;
+              if (image.component == 3) {
+                format = GL_RGB;
+              }
+              glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
+                           image.height, 0, format, tex.type,
+                           &image.image.at(0));
+
+              CheckErrors("texImage2D");
+              glBindTexture(tex.target, 0);
+
+              printf("TexId = %d\n", texId);
+              gMeshState[mesh.name].diffuseTex[primId] = texId;
+            }
+          }
+        }
+      }
+    }
   }
 
   glUseProgram(progId);
   GLint vtloc = glGetAttribLocation(progId, "in_vertex");
   GLint nrmloc = glGetAttribLocation(progId, "in_normal");
+  GLint uvloc = glGetAttribLocation(progId, "in_texcoord");
+
+  GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex");
+
   gGLProgramState.attribs["POSITION"] = vtloc;
   gGLProgramState.attribs["NORMAL"] = nrmloc;
-  
+  gGLProgramState.attribs["TEXCOORD_0"] = uvloc;
+  gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc;
 };
 
-void DrawMesh(Scene& scene, const Mesh& mesh)
-{
-  for (size_t i = 0; i < mesh.primitives.size(); i++) { 
-    const Primitive& primitive = mesh.primitives[i];
+void DrawMesh(Scene &scene, const Mesh &mesh) {
 
-    if (primitive.indices.empty()) return;
+  if (gGLProgramState.uniforms["diffuseTex"] >= 0) {
+    glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0
+  }
 
-    std::map<std::string, std::string>::const_iterator it(primitive.attributes.begin());
-    std::map<std::string, std::string>::const_iterator itEnd(primitive.attributes.end());
+  for (size_t i = 0; i < mesh.primitives.size(); i++) {
+    const Primitive &primitive = mesh.primitives[i];
+
+    if (primitive.indices.empty())
+      return;
+
+    std::map<std::string, std::string>::const_iterator it(
+        primitive.attributes.begin());
+    std::map<std::string, std::string>::const_iterator itEnd(
+        primitive.attributes.end());
+
+    // Assume TEXTURE_2D target for the texture object.
+    glBindTexture(GL_TEXTURE_2D, gMeshState[mesh.name].diffuseTex[i]);
 
     for (; it != itEnd; it++) {
-      const Accessor& accessor = scene.accessors[it->second];
+      const Accessor &accessor = scene.accessors[it->second];
       glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb);
       CheckErrors("bind buffer");
       int count = 1;
@@ -254,18 +339,22 @@
       } else if (accessor.type == TINYGLTF_TYPE_VEC4) {
         count = 4;
       }
-      // it->first would be "POSITION", "NORMAL", ...
-      if ( (it->first.compare("POSITION") == 0) ||
-           (it->first.compare("NORMAL") == 0)) {
-        glVertexAttribPointer(gGLProgramState.attribs[it->first], count, accessor.componentType, GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset));
+      // it->first would be "POSITION", "NORMAL", "TEXCOORD_0", ...
+      if ((it->first.compare("POSITION") == 0) ||
+          (it->first.compare("NORMAL") == 0) ||
+          (it->first.compare("TEXCOORD_0") == 0)) {
+        glVertexAttribPointer(
+            gGLProgramState.attribs[it->first], count, accessor.componentType,
+            GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset));
         CheckErrors("vertex attrib pointer");
         glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
         CheckErrors("enable vertex attrib array");
       }
     }
 
-    const Accessor& indexAccessor = scene.accessors[primitive.indices];
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gBufferState[indexAccessor.bufferView].vb);
+    const Accessor &indexAccessor = scene.accessors[primitive.indices];
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
+                 gBufferState[indexAccessor.bufferView].vb);
     CheckErrors("bind buffer");
     int mode = -1;
     if (primitive.mode == TINYGLTF_MODE_TRIANGLES) {
@@ -281,26 +370,28 @@
     } else if (primitive.mode == TINYGLTF_MODE_LINE_LOOP) {
       mode = GL_LINE_LOOP;
     };
-    glDrawElements(mode, indexAccessor.count, indexAccessor.componentType, BUFFER_OFFSET(indexAccessor.byteOffset));
+    glDrawElements(mode, indexAccessor.count, indexAccessor.componentType,
+                   BUFFER_OFFSET(indexAccessor.byteOffset));
     CheckErrors("draw elements");
 
     {
-      std::map<std::string, std::string>::const_iterator it(primitive.attributes.begin());
-      std::map<std::string, std::string>::const_iterator itEnd(primitive.attributes.end());
+      std::map<std::string, std::string>::const_iterator it(
+          primitive.attributes.begin());
+      std::map<std::string, std::string>::const_iterator itEnd(
+          primitive.attributes.end());
 
       for (; it != itEnd; it++) {
-        if ( (it->first.compare("POSITION") == 0) ||
-             (it->first.compare("NORMAL") == 0)) {
+        if ((it->first.compare("POSITION") == 0) ||
+            (it->first.compare("NORMAL") == 0) ||
+            (it->first.compare("TEXCOORD_0") == 0)) {
           glDisableVertexAttribArray(gGLProgramState.attribs[it->first]);
         }
       }
     }
   }
-
 }
 
-void DrawScene(Scene& scene)
-{
+void DrawScene(Scene &scene) {
   std::map<std::string, Mesh>::const_iterator it(scene.meshes.begin());
   std::map<std::string, Mesh>::const_iterator itEnd(scene.meshes.end());
 
@@ -309,7 +400,6 @@
   }
 }
 
-
 static void Init() {
   trackball(curr_quat, 0, 0, 0, 0);
 
@@ -326,8 +416,7 @@
   up[2] = 0.0f;
 }
 
-int main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
   if (argc < 2) {
     std::cout << "glview input.gltf <scale>\n" << std::endl;
     return 0;
@@ -338,10 +427,10 @@
     scale = atof(argv[2]);
   }
 
-  Scene scene; 
+  Scene scene;
   TinyGLTFLoader loader;
   std::string err;
-  
+
   bool ret = loader.LoadFromFile(scene, err, argv[1]);
   if (!err.empty()) {
     printf("ERR: %s\n", err.c_str());
@@ -353,13 +442,14 @@
 
   Init();
 
-  if(!glfwInit()){
+  if (!glfwInit()) {
     std::cerr << "Failed to initialize GLFW." << std::endl;
     return -1;
   }
 
-  window = glfwCreateWindow(width, height, "Simple glTF geometry viewer", NULL, NULL);
-  if(window == NULL){
+  window = glfwCreateWindow(width, height, "Simple glTF geometry viewer", NULL,
+                            NULL);
+  if (window == NULL) {
     std::cerr << "Failed to open GLFW window. " << std::endl;
     glfwTerminate();
     return 1;
@@ -420,7 +510,7 @@
   SetupGLState(scene, progId);
   CheckErrors("SetupGLState");
 
-  while(glfwWindowShouldClose(window) == GL_FALSE) {
+  while (glfwWindowShouldClose(window) == GL_FALSE) {
     glfwPollEvents();
     glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -433,7 +523,8 @@
     // camera(define it in projection matrix)
     glMatrixMode(GL_PROJECTION);
     glPushMatrix();
-    gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0], up[1], up[2]);
+    gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0],
+              up[1], up[2]);
 
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
diff --git a/examples/glview/shader.frag b/examples/glview/shader.frag
index bd2fc49..1f30d3e 100644
--- a/examples/glview/shader.frag
+++ b/examples/glview/shader.frag
@@ -1,6 +1,11 @@
+uniform sampler2D diffuseTex;
+
 varying vec3 normal;
+varying vec2 texcoord;
 
 void main(void)
 {
-    gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
+    //gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
+    //gl_FragColor = vec4(texcoord, 0.0, 1.0);
+    gl_FragColor = texture2D(diffuseTex, texcoord);
 }
diff --git a/examples/glview/shader.vert b/examples/glview/shader.vert
index a21fa30..e21752d 100644
--- a/examples/glview/shader.vert
+++ b/examples/glview/shader.vert
@@ -1,7 +1,9 @@
 attribute vec3    in_vertex;
 attribute vec3    in_normal;
+attribute vec2    in_texcoord;
 
 varying vec3      normal;
+varying vec2      texcoord;
 
 void main(void)
 {
@@ -9,4 +11,6 @@
 	gl_Position = p;
 	vec4 nn = gl_ModelViewMatrixInverseTranspose * vec4(normalize(in_normal), 0);
 	normal = nn.xyz;
+
+	texcoord = in_texcoord;
 }
diff --git a/test.cc b/test.cc
index 8b3bfd1..7d6056d 100644
--- a/test.cc
+++ b/test.cc
@@ -6,8 +6,7 @@
 #include <cstdio>
 #include <iostream>
 
-std::string PrintMode(int mode)
-{
+std::string PrintMode(int mode) {
   if (mode == TINYGLTF_MODE_POINTS) {
     return "POINTS";
   } else if (mode == TINYGLTF_MODE_LINE) {
@@ -24,9 +23,7 @@
   return "**UNKNOWN**";
 }
 
-
-std::string PrintType(int ty)
-{
+std::string PrintType(int ty) {
   if (ty == TINYGLTF_TYPE_SCALAR) {
     return "SCALAR";
   } else if (ty == TINYGLTF_TYPE_VECTOR) {
@@ -49,8 +46,7 @@
   return "**UNKNOWN**";
 }
 
-std::string PrintComponentType(int ty)
-{
+std::string PrintComponentType(int ty) {
   if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) {
     return "BYTE";
   } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
@@ -72,8 +68,7 @@
   return "**UNKNOWN**";
 }
 
-std::string PrintFloatArray(const std::vector<double>& arr)
-{
+std::string PrintFloatArray(const std::vector<double> &arr) {
   if (arr.size() == 0) {
     return "";
   }
@@ -88,8 +83,7 @@
   return ss.str();
 }
 
-std::string PrintStringArray(const std::vector<std::string>& arr)
-{
+std::string PrintStringArray(const std::vector<std::string> &arr) {
   if (arr.size() == 0) {
     return "";
   }
@@ -104,9 +98,7 @@
   return ss.str();
 }
 
-
-std::string Indent(int indent)
-{
+std::string Indent(int indent) {
   std::string s;
   for (int i = 0; i < indent; i++) {
     s += "  ";
@@ -115,64 +107,82 @@
   return s;
 }
 
-void DumpNode(const Node& node, int indent)
-{
-  std::cout << Indent(indent) <<   "name        : " << node.name << std::endl;
-  std::cout << Indent(indent) <<   "camera      : " << node.camera << std::endl;
+void DumpNode(const Node &node, int indent) {
+  std::cout << Indent(indent) << "name        : " << node.name << std::endl;
+  std::cout << Indent(indent) << "camera      : " << node.camera << std::endl;
   if (!node.rotation.empty()) {
-    std::cout << Indent(indent) << "rotation    : " << PrintFloatArray(node.rotation) << std::endl;
+    std::cout << Indent(indent)
+              << "rotation    : " << PrintFloatArray(node.rotation)
+              << std::endl;
   }
   if (!node.scale.empty()) {
-    std::cout << Indent(indent) << "scale       : " << PrintFloatArray(node.scale) << std::endl;
+    std::cout << Indent(indent)
+              << "scale       : " << PrintFloatArray(node.scale) << std::endl;
   }
   if (!node.translation.empty()) {
-    std::cout << Indent(indent) << "translation : " << PrintFloatArray(node.translation) << std::endl;
+    std::cout << Indent(indent)
+              << "translation : " << PrintFloatArray(node.translation)
+              << std::endl;
   }
 
   if (!node.matrix.empty()) {
-    std::cout << Indent(indent) << "matrix      : " << PrintFloatArray(node.matrix) << std::endl;
+    std::cout << Indent(indent)
+              << "matrix      : " << PrintFloatArray(node.matrix) << std::endl;
   }
 
-  std::cout << Indent(indent) <<   "meshes      : " << PrintStringArray(node.meshes) << std::endl;
+  std::cout << Indent(indent)
+            << "meshes      : " << PrintStringArray(node.meshes) << std::endl;
 
-  std::cout << Indent(indent) <<   "children    : " << PrintStringArray(node.children) << std::endl;
-
+  std::cout << Indent(indent)
+            << "children    : " << PrintStringArray(node.children) << std::endl;
 }
 
-void DumpPrimitive(const Primitive& primitive, int indent)
-{
-  std::cout << Indent(indent) << "material : " << primitive.material << std::endl;
-  std::cout << Indent(indent) << "mode     : " << PrintMode(primitive.mode) << "(" << primitive.mode << ")" << std::endl;
-  std::cout << Indent(indent) << "attributes(items=" << primitive.attributes.size() << ")" << std::endl;
-  std::map<std::string, std::string>::const_iterator it(primitive.attributes.begin());
-  std::map<std::string, std::string>::const_iterator itEnd(primitive.attributes.end());
+void DumpPrimitive(const Primitive &primitive, int indent) {
+  std::cout << Indent(indent) << "material : " << primitive.material
+            << std::endl;
+  std::cout << Indent(indent) << "mode     : " << PrintMode(primitive.mode)
+            << "(" << primitive.mode << ")" << std::endl;
+  std::cout << Indent(indent)
+            << "attributes(items=" << primitive.attributes.size() << ")"
+            << std::endl;
+  std::map<std::string, std::string>::const_iterator it(
+      primitive.attributes.begin());
+  std::map<std::string, std::string>::const_iterator itEnd(
+      primitive.attributes.end());
   for (; it != itEnd; it++) {
-    std::cout << Indent(indent + 1) << it->first << ": " << it->second << std::endl;
+    std::cout << Indent(indent + 1) << it->first << ": " << it->second
+              << std::endl;
   }
-
 }
 
-void Dump(const Scene& scene)
-{
+void Dump(const Scene &scene) {
   std::cout << "=== Dump glTF ===" << std::endl;
-  std::cout << "asset.generator          : " << scene.asset.generator << std::endl;
-  std::cout << "asset.premultipliedAlpha : " << scene.asset.premultipliedAlpha << std::endl;
-  std::cout << "asset.version            : " << scene.asset.version << std::endl;
-  std::cout << "asset.profile.api        : " << scene.asset.profile_api << std::endl;
-  std::cout << "asset.profile.version    : " << scene.asset.profile_version << std::endl;
+  std::cout << "asset.generator          : " << scene.asset.generator
+            << std::endl;
+  std::cout << "asset.premultipliedAlpha : " << scene.asset.premultipliedAlpha
+            << std::endl;
+  std::cout << "asset.version            : " << scene.asset.version
+            << std::endl;
+  std::cout << "asset.profile.api        : " << scene.asset.profile_api
+            << std::endl;
+  std::cout << "asset.profile.version    : " << scene.asset.profile_version
+            << std::endl;
   std::cout << std::endl;
   std::cout << "=== Dump scene ===" << std::endl;
   std::cout << "defaultScene: " << scene.defaultScene << std::endl;
 
   {
-    std::map<std::string, std::vector<std::string> >::const_iterator it(scene.scenes.begin());
-    std::map<std::string, std::vector<std::string> >::const_iterator itEnd(scene.scenes.end());
+    std::map<std::string, std::vector<std::string> >::const_iterator it(
+        scene.scenes.begin());
+    std::map<std::string, std::vector<std::string> >::const_iterator itEnd(
+        scene.scenes.end());
     std::cout << "scenes(items=" << scene.scenes.size() << ")" << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name  : " << it->first << std::endl;
       std::cout << Indent(2) << "nodes : [ ";
       for (size_t i = 0; i < it->second.size(); i++) {
-        std::cout << it->second[i] << ((i != it->second.size()) ? ", " : "");
+        std::cout << it->second[i]
+                  << ((i != (it->second.size() - 1)) ? ", " : "");
       }
       std::cout << " ] " << std::endl;
     }
@@ -184,8 +194,10 @@
     std::cout << "meshes(item=" << scene.meshes.size() << ")" << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name     : " << it->second.name << std::endl;
-      std::cout << Indent(1) << "primitives(items=" << it->second.primitives.size() << "): " << std::endl;
-    
+      std::cout << Indent(1)
+                << "primitives(items=" << it->second.primitives.size()
+                << "): " << std::endl;
+
       for (size_t i = 0; i < it->second.primitives.size(); i++) {
         DumpPrimitive(it->second.primitives[i], 2);
       }
@@ -194,27 +206,38 @@
 
   {
     std::map<std::string, Accessor>::const_iterator it(scene.accessors.begin());
-    std::map<std::string, Accessor>::const_iterator itEnd(scene.accessors.end());
-    std::cout << "accessos(items=" << scene.accessors.size() << ")" << std::endl;
+    std::map<std::string, Accessor>::const_iterator itEnd(
+        scene.accessors.end());
+    std::cout << "accessos(items=" << scene.accessors.size() << ")"
+              << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name         : " << it->first << std::endl;
-      std::cout << Indent(2) << "bufferView   : " << it->second.bufferView << std::endl;
-      std::cout << Indent(2) << "byteOffset   : " << it->second.byteOffset << std::endl;
-      std::cout << Indent(2) << "byteStride   : " << it->second.byteStride << std::endl;
-      std::cout << Indent(2) << "componentType: " << PrintComponentType(it->second.componentType) << "(" << it->second.componentType << ")" << std::endl;
-      std::cout << Indent(2) << "count        : " << it->second.count << std::endl;
-      std::cout << Indent(2) << "type         : " << PrintType(it->second.type) << std::endl;
+      std::cout << Indent(2) << "bufferView   : " << it->second.bufferView
+                << std::endl;
+      std::cout << Indent(2) << "byteOffset   : " << it->second.byteOffset
+                << std::endl;
+      std::cout << Indent(2) << "byteStride   : " << it->second.byteStride
+                << std::endl;
+      std::cout << Indent(2) << "componentType: "
+                << PrintComponentType(it->second.componentType) << "("
+                << it->second.componentType << ")" << std::endl;
+      std::cout << Indent(2) << "count        : " << it->second.count
+                << std::endl;
+      std::cout << Indent(2) << "type         : " << PrintType(it->second.type)
+                << std::endl;
       if (!it->second.minValues.empty()) {
         std::cout << Indent(2) << "min          : [";
         for (size_t i = 0; i < it->second.minValues.size(); i++) {
-          std::cout << it->second.minValues[i] << ((i != it->second.minValues.size()-1) ? ", " : "");
+          std::cout << it->second.minValues[i]
+                    << ((i != it->second.minValues.size() - 1) ? ", " : "");
         }
         std::cout << "]" << std::endl;
       }
       if (!it->second.maxValues.empty()) {
         std::cout << Indent(2) << "max          : [";
         for (size_t i = 0; i < it->second.maxValues.size(); i++) {
-          std::cout << it->second.maxValues[i] << ((i != it->second.maxValues.size()-1) ? ", " : "");
+          std::cout << it->second.maxValues[i]
+                    << ((i != it->second.maxValues.size() - 1) ? ", " : "");
         }
         std::cout << "]" << std::endl;
       }
@@ -222,14 +245,20 @@
   }
 
   {
-    std::map<std::string, BufferView>::const_iterator it(scene.bufferViews.begin());
-    std::map<std::string, BufferView>::const_iterator itEnd(scene.bufferViews.end());
-    std::cout << "bufferViews(items=" << scene.bufferViews.size() << ")" << std::endl;
+    std::map<std::string, BufferView>::const_iterator it(
+        scene.bufferViews.begin());
+    std::map<std::string, BufferView>::const_iterator itEnd(
+        scene.bufferViews.end());
+    std::cout << "bufferViews(items=" << scene.bufferViews.size() << ")"
+              << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name         : " << it->first << std::endl;
-      std::cout << Indent(2) << "buffer       : " << it->second.buffer << std::endl;
-      std::cout << Indent(2) << "byteLength   : " << it->second.byteLength << std::endl;
-      std::cout << Indent(2) << "byteOffset   : " << it->second.byteOffset << std::endl;
+      std::cout << Indent(2) << "buffer       : " << it->second.buffer
+                << std::endl;
+      std::cout << Indent(2) << "byteLength   : " << it->second.byteLength
+                << std::endl;
+      std::cout << Indent(2) << "byteOffset   : " << it->second.byteOffset
+                << std::endl;
     }
   }
 
@@ -239,23 +268,35 @@
     std::cout << "buffers(items=" << scene.buffers.size() << ")" << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name         : " << it->first << std::endl;
-      std::cout << Indent(2) << "byteLength   : " << it->second.data.size() << std::endl;
+      std::cout << Indent(2) << "byteLength   : " << it->second.data.size()
+                << std::endl;
     }
   }
 
   {
     std::map<std::string, Material>::const_iterator it(scene.materials.begin());
-    std::map<std::string, Material>::const_iterator itEnd(scene.materials.end());
-    std::cout << "materials(items=" << scene.materials.size() << ")" << std::endl;
+    std::map<std::string, Material>::const_iterator itEnd(
+        scene.materials.end());
+    std::cout << "materials(items=" << scene.materials.size() << ")"
+              << std::endl;
     for (; it != itEnd; it++) {
       std::cout << Indent(1) << "name         : " << it->first << std::endl;
-      std::cout << Indent(1) << "technique    : " << it->second.technique << std::endl;
-      std::cout << Indent(1) << "values(items=" << it->second.values.size() << std::endl;
+      std::cout << Indent(1) << "technique    : " << it->second.technique
+                << std::endl;
+      std::cout << Indent(1) << "values(items=" << it->second.values.size()
+                << std::endl;
 
-      FloatParameterMap::const_iterator p(it->second.values.begin());
-      FloatParameterMap::const_iterator pEnd(it->second.values.end());
+      ParameterMap::const_iterator p(it->second.values.begin());
+      ParameterMap::const_iterator pEnd(it->second.values.end());
       for (; p != pEnd; p++) {
-        std::cout << Indent(3) << p->first << PrintFloatArray(p->second) << std::endl;
+        if (!p->second.numberArray.empty()) {
+          std::cout << Indent(3) << p->first
+                    << PrintFloatArray(p->second.numberArray) << std::endl;
+        }
+        if (!p->second.stringValue.empty()) {
+          std::cout << Indent(3) << p->first << " : " << p->second.stringValue
+                    << std::endl;
+        }
       }
     }
   }
@@ -270,7 +311,7 @@
       DumpNode(it->second, 2);
     }
   }
-  
+
   {
     std::map<std::string, Image>::const_iterator it(scene.images.begin());
     std::map<std::string, Image>::const_iterator itEnd(scene.images.end());
@@ -279,24 +320,46 @@
       std::cout << Indent(1) << "name         : " << it->first << std::endl;
 
       std::cout << Indent(2) << "width     : " << it->second.width << std::endl;
-      std::cout << Indent(2) << "height    : " << it->second.height << std::endl;
-      std::cout << Indent(2) << "component : " << it->second.component << std::endl;
+      std::cout << Indent(2) << "height    : " << it->second.height
+                << std::endl;
+      std::cout << Indent(2) << "component : " << it->second.component
+                << std::endl;
       std::cout << Indent(2) << "name      : " << it->second.name << std::endl;
     }
   }
+
+  {
+    std::map<std::string, Texture>::const_iterator it(scene.textures.begin());
+    std::map<std::string, Texture>::const_iterator itEnd(scene.textures.end());
+    std::cout << "textures(items=" << scene.textures.size() << ")" << std::endl;
+    for (; it != itEnd; it++) {
+      std::cout << Indent(1) << "name           : " << it->first << std::endl;
+      std::cout << Indent(1) << "format         : " << it->second.format
+                << std::endl;
+      std::cout << Indent(1) << "internalFormat : " << it->second.internalFormat
+                << std::endl;
+      std::cout << Indent(1) << "sampler        : " << it->second.sampler
+                << std::endl;
+      std::cout << Indent(1) << "source         : " << it->second.source
+                << std::endl;
+      std::cout << Indent(1) << "target         : " << it->second.target
+                << std::endl;
+      std::cout << Indent(1) << "type           : " << it->second.type
+                << std::endl;
+    }
+  }
 }
 
-int main(int argc, char** argv)
-{
+int main(int argc, char **argv) {
   if (argc < 2) {
     printf("Needs input.gltf\n");
     exit(1);
   }
 
-  Scene scene; 
+  Scene scene;
   TinyGLTFLoader loader;
   std::string err;
-  
+
   bool ret = loader.LoadFromFile(scene, err, argv[1]);
 
   if (!err.empty()) {
diff --git a/tiny_gltf_loader.h b/tiny_gltf_loader.h
index 0481db6..361d634 100644
--- a/tiny_gltf_loader.h
+++ b/tiny_gltf_loader.h
@@ -31,7 +31,8 @@
 //
 //
 // Version:
-//  - v0.9.1 Support loading glTF asset from memory 
+//  - v0.9.2 Support parsing `texture`
+//  - v0.9.1 Support loading glTF asset from memory
 //  - v0.9.0 Initial
 //
 // Tiny glTF loader is using following libraries:
@@ -80,12 +81,20 @@
 #define TINYGLTF_IMAGE_FORMAT_BMP (2)
 #define TINYGLTF_IMAGE_FORMAT_GIF (3)
 
+#define TINYGLTF_TEXTURE_FORMAT_RGBA (6408)
+#define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553)
+#define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121)
+
 #define TINYGLTF_TARGET_ARRAY_BUFFER (34962)
 #define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963)
 
-typedef std::map<std::string, std::vector<double> > FloatParameterMap;
+typedef struct {
+  std::string stringValue;
+  std::vector<double> numberArray;
+} Parameter;
 
-// LDR 8bit image
+typedef std::map<std::string, Parameter> ParameterMap;
+
 typedef struct {
   std::string name;
   int width;
@@ -95,9 +104,19 @@
 } Image;
 
 typedef struct {
+  int format;
+  int internalFormat;
+  std::string sampler; // Required
+  std::string source;  // Required
+  int target;
+  int type;
+  std::string name;
+} Texture;
+
+typedef struct {
   std::string name;
   std::string technique;
-  FloatParameterMap values;
+  ParameterMap values;
 } Material;
 
 typedef struct {
@@ -191,6 +210,7 @@
   std::map<std::string, Material> materials;
   std::map<std::string, Mesh> meshes;
   std::map<std::string, Node> nodes;
+  std::map<std::string, Texture> textures;
   std::map<std::string, Image> images;
   std::map<std::string, std::vector<std::string> > scenes; // list of nodes
 
@@ -212,9 +232,8 @@
   /// Loads glTF asset from string(memory).
   /// `length` = strlen(str);
   /// Returns false and set error string to `err` if there's an error.
-  bool LoadFromString(Scene &scene, std::string &err,
-                    const char* str, const unsigned int length, const std::string& baseDir);
-
+  bool LoadFromString(Scene &scene, std::string &err, const char *str,
+                      const unsigned int length, const std::string &baseDir);
 };
 
 } // namespace tinygltf
@@ -557,7 +576,7 @@
 
   if (data.empty()) {
     return false;
-  } 
+  }
 
   if (checkSize) {
     if (data.size() != reqBytes) {
@@ -780,6 +799,39 @@
   return true;
 }
 
+bool ParseTexture(Texture &texture, std::string &err, const picojson::object &o,
+                  const std::string &basedir) {
+
+  if (!ParseStringProperty(texture.sampler, err, o, "sampler", true)) {
+    return false;
+  }
+
+  if (!ParseStringProperty(texture.source, err, o, "source", true)) {
+    return false;
+  }
+
+  ParseStringProperty(texture.name, err, o, "name", false);
+
+  double format = TINYGLTF_TEXTURE_FORMAT_RGBA;
+  ParseNumberProperty(format, err, o, "format", false);
+
+  double internalFormat = TINYGLTF_TEXTURE_FORMAT_RGBA;
+  ParseNumberProperty(internalFormat, err, o, "internalFormat", false);
+
+  double target = TINYGLTF_TEXTURE_TARGET_TEXTURE2D;
+  ParseNumberProperty(target, err, o, "target", false);
+
+  double type = TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE;
+  ParseNumberProperty(type, err, o, "type", false);
+
+  texture.format = static_cast<int>(format);
+  texture.internalFormat = static_cast<int>(internalFormat);
+  texture.target = static_cast<int>(target);
+  texture.type = static_cast<int>(type);
+
+  return true;
+}
+
 bool ParseBuffer(Buffer &buffer, std::string &err, const picojson::object &o,
                  const std::string &basedir) {
   double byteLength;
@@ -1041,17 +1093,20 @@
 
     for (; it != itEnd; it++) {
       // Assume number values.
-      std::vector<double> values;
-      if (!ParseNumberArrayProperty(values, err, valuesObject, it->first,
-                                    false)) {
+      Parameter param;
+      if (ParseStringProperty(param.stringValue, err, valuesObject, it->first,
+                              false)) {
+        // Found string property.
+      } else if (!ParseNumberArrayProperty(param.numberArray, err, valuesObject,
+                                           it->first, false)) {
         // Fallback to numer property.
         double value;
         if (ParseNumberProperty(value, err, valuesObject, it->first, false)) {
-          values.push_back(value);
+          param.numberArray.push_back(value);
         }
       }
 
-      material.values[it->first] = values;
+      material.values[it->first] = param;
     }
   }
 
@@ -1060,7 +1115,8 @@
 }
 
 bool TinyGLTFLoader::LoadFromString(Scene &scene, std::string &err,
-                                  const char *str, unsigned int length, const std::string& baseDir) {
+                                    const char *str, unsigned int length,
+                                    const std::string &baseDir) {
   picojson::value v;
   std::string perr = picojson::parse(v, str, str + length);
 
@@ -1282,6 +1338,25 @@
     }
   }
 
+  // 9. Parse Texture
+  if (v.contains("textures") && v.get("textures").is<picojson::object>()) {
+
+    const picojson::object &root = v.get("textures").get<picojson::object>();
+
+    picojson::object::const_iterator it(root.begin());
+    picojson::object::const_iterator itEnd(root.end());
+    for (; it != itEnd; it++) {
+
+      Texture texture;
+      if (!ParseTexture(texture, err, (it->second).get<picojson::object>(),
+                        baseDir)) {
+        return false;
+      }
+
+      scene.textures[it->first] = texture;
+    }
+  }
+
   return true;
 }