title: GLSL Instancing - Passing ModelMatrix
body: <p>I have done many searches on Google/Stackflow and can't find an answer to my specific issue. I tried to implement instancing using a patched sphere mesh and the following references:</p>
  
  <p><a href="http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html" rel="nofollow noreferrer">http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html</a></p>
  
  <p><a href="https://learnopengl.com/Advanced-OpenGL/Instancing" rel="nofollow noreferrer">https://learnopengl.com/Advanced-OpenGL/Instancing</a></p>
  
  <p>I have tried to debug my own code but nothing seems to be working... I am consistently getting an output that looks like the modelmatrix values are corrupt or setup incorrectly. Here is what it looks like at different camera rotations when passing in an Identity matrix for the Model:</p>
  
  <p><a href="https://i.stack.imgur.com/1BOnY.png" rel="nofollow noreferrer">Instance Model Matrix #1</a></p>
  
  <p><a href="https://i.stack.imgur.com/ua9mO.png" rel="nofollow noreferrer">Instance Model Matrix #2</a></p>
  
  <p>If I hard-code the model matrix in the vertex shader to be the Identity Matrix then it comes out just fine:</p>
  
  <p><a href="https://i.stack.imgur.com/Eurta.png" rel="nofollow noreferrer">Hard-code Model Matrix</a></p>
  
  <p>So it seems to me that the model matrix is not being passed in correctly and since I've spend days reviewing my code and trying different things. I'm hoping someone can review this and spot the problem.. THANKS!</p>
  
  <h2>InstanceObject::Init()</h2>
  
  <pre><code>for (unsigned int Level = 0; Level &lt; Levels; Level++)
  {
      FrameTicks[Level] = 0;
      VBO_SeedVector[Level] = 0;
      VBO_ModelMatrix[Level] = 0;
  
      //. Bind VAO for Object's Level of Detail
      glBindVertexArray(Meshes-&gt;GetMesh(Level)-&gt;GetVAO());
  
      //. Generate Buffers for Object's SeedVector
      glGenBuffers(1, &amp;VBO_SeedVector[Level]);
  
      //. Generate Instance Array for Object's SeedVector
      glEnableVertexAttribArray(2);
      glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4f), (void*)0);
      glVertexAttribDivisor(2, 1);
  
      //. Generate Buffers for Object's ModelMatrix
      glGenBuffers(1, &amp;VBO_ModelMatrix[Level]);
  
      //. Generate Instance Array for Object's ModelMatrix
      glEnableVertexAttribArray(3);
      glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(0 * sizeof(Vector4f)));
      glVertexAttribDivisor(3, 1);
  
      glEnableVertexAttribArray(4);
      glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(1 * sizeof(Vector4f)));
      glVertexAttribDivisor(4, 1);
  
      glEnableVertexAttribArray(5);
      glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(2 * sizeof(Vector4f)));
      glVertexAttribDivisor(5, 1);
  
      glEnableVertexAttribArray(6);
      glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(3 * sizeof(Vector4f)));
      glVertexAttribDivisor(6, 1);
  
      ObjectSeeds.push_back(std::vector&lt;Vector4f&gt;());
      ObjectModels.push_back(std::vector&lt;Matrix4f&gt;());
  }
  </code></pre>
  
  <h2>InstanceObject::Update()</h2>
  
  <pre><code>//. Load Instance Arrays into VAOs
  for (unsigned int Level = 0; Level &lt; Levels; Level++)
  {
      glBindVertexArray(Meshes-&gt;GetMesh(Level)-&gt;GetVAO());
  
      glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
      glBufferData(GL_ARRAY_BUFFER, ObjectSeeds[Level].size() * sizeof(Vector4f), &amp;ObjectSeeds[Level], GL_STATIC_DRAW);
  
      glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
      glBufferData(GL_ARRAY_BUFFER, ObjectModels[Level].size() * sizeof(Matrix4f), &amp;ObjectModels[Level], GL_STATIC_DRAW);
  }
  </code></pre>
  
  <h2>InstanceObject::Render()</h2>
  
  <pre><code>//. Empty Detailed Mesh
  if (Meshes == nullptr)
      return;
  
  //. Enable VAA for Px, Py, Pz, U
  glEnableVertexAttribArray(0);
  glVertexAttribDivisor(0, 0);
  
  //. Enable VAA for Nx, Ny, Nz, V
  glEnableVertexAttribArray(1);
  glVertexAttribDivisor(1, 0);
  
  //. Enable VAA for Seed Vector
  glEnableVertexAttribArray(2);
  glVertexAttribDivisor(2, 0);
  
  //. Enable VAA for Model Matrix
  glEnableVertexAttribArray(3);
  glVertexAttribDivisor(3, 1);
  glEnableVertexAttribArray(4);
  glVertexAttribDivisor(4, 1);
  glEnableVertexAttribArray(5);
  glVertexAttribDivisor(5, 1);
  glEnableVertexAttribArray(6);
  glVertexAttribDivisor(6, 1);
  
  //. Render Instances For Each Ring
  for (unsigned int Level = Levels - 1; Level &gt; 0; Level--)
  {
      unsigned int RingSize = ObjectModels[Level].size();
  
      //. Empty Ring
      if (RingSize == 0)
          continue;
  
      BaseMesh* Mesh = Meshes-&gt;GetMesh(Level);
  
      //. Empty Mesh
      if (Mesh == nullptr)
          continue;
  
      unsigned int VAO = Mesh-&gt;GetVAO();
  
      if (VAO == 0)
          continue;
  
      //. Render Instances
      glBindVertexArray(VAO);
      glDrawElementsInstanced(GL_TRIANGLES, Mesh-&gt;Elements.size(), GL_UNSIGNED_INT, 0, RingSize);
  }
  
  glDisableVertexAttribArray(6);
  glDisableVertexAttribArray(5);
  glDisableVertexAttribArray(4);
  glDisableVertexAttribArray(3);
  glDisableVertexAttribArray(2);
  glDisableVertexAttribArray(1);
  </code></pre>
  
  <h2>Vertex Shader</h2>
  
  <pre><code>#version 440
  
  layout (location = 0) in vec4 Position;
  layout (location = 1) in vec4 Normal;
  layout (location = 2) in vec4 Seed;
  layout (location = 3) in vec4 ModelCol0;
  layout (location = 4) in vec4 ModelCol1;
  layout (location = 5) in vec4 ModelCol2;
  layout (location = 6) in vec4 ModelCol3;
  
  //uniform mat4 Model;
  uniform mat4 View;
  uniform mat4 Projection;
  
  out vec3 mPosition;
  out vec3 vPosition;
  out vec3 vNormal;
  out vec2 vSample;
  
  void main()
  {
      mPosition = Position.xyz;
  
      mat4 vModel = mat4(1.0);
  
      vModel[0] = ModelCol0;
      vModel[1] = ModelCol1;
      vModel[2] = ModelCol2;
      vModel[3] = ModelCol3;
  
      vPosition = (vModel * vec4(mPosition.xyz, 1.0)).xyz;
      vNormal = (vModel * vec4(Normal.xyz, 0.0)).xyz;
      vSample = vec2(Position.w, Normal.w);
  
      gl_Position = Projection * View * vModel * vec4(mPosition.xyz, 1.0);
  }
  </code></pre>
  
  <hr>
  
  <h2>04/09/18 UPDATE:</h2>
  
  <p>I updated the InstanceObject::Init() to bind the VBO before the VAA calls as follows:</p>
  
  <pre><code>for (unsigned int Level = 0; Level &lt; Levels; Level++)
  {
      FrameTicks[Level] = 0;
      VBO_SeedVector[Level] = 0;
      VBO_ModelMatrix[Level] = 0;
  
      //. Bind VAO for Object's Level of Detail
      glBindVertexArray(Meshes-&gt;GetMesh(Level)-&gt;GetVAO());
  
      if (!LogErrorGL(std::cout, "glGenBuffers"))
          return false;
  
      //. Generate Buffers for Object's SeedVector
      glGenBuffers(1, &amp;VBO_SeedVector[Level]);
  
      if (!LogErrorGL(std::cout, "glGenBuffers"))
          return false;
  
      //. Enable Vertex Attribute Arrays
      glEnableVertexAttribArray(2);
  
      if (!LogErrorGL(std::cout, "glEnableVertexAttribArray"))
          return false;
  
      //. Bind Buffer to Setup Instance Array
      glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
  
      if (!LogErrorGL(std::cout, "glBindBuffer"))
          return false;
  
      //. Generate Instance Array for Object's SeedVector
      glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4f), (void*)0);
  
      if (!LogErrorGL(std::cout, "glVertexAttribPointer"))
          return false;
  
      //. Apply Attribute Divisors
      glVertexAttribDivisor(2, 1);
  
      if (!LogErrorGL(std::cout, "glVertexAttribDivisor"))
          return false;
  
      //. Unbind Buffer
      glBindBuffer(GL_ARRAY_BUFFER, 0);
  
      //.
      //.
      //.
  
      //. Generate Buffers for Object's ModelMatrix
      glGenBuffers(1, &amp;VBO_ModelMatrix[Level]);
  
      if (!LogErrorGL(std::cout, "glGenBuffers"))
          return false;
  
      //. Enable Vertex Attribute Arrays
      glEnableVertexAttribArray(3);
      glEnableVertexAttribArray(4);
      glEnableVertexAttribArray(5);
      glEnableVertexAttribArray(6);
  
      if (!LogErrorGL(std::cout, "glEnableVertexAttribArray"))
          return false;
  
      //. Bind Buffer to Setup Instance Arrays
      glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
  
      if (!LogErrorGL(std::cout, "glBindBuffer"))
          return false;
  
      //. Generate Instance Array for Object's ModelMatrix
      glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(0 * sizeof(Vector4f)));
      glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(1 * sizeof(Vector4f)));
      glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(2 * sizeof(Vector4f)));
      glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(3 * sizeof(Vector4f)));
  
      if (!LogErrorGL(std::cout, "glVertexAttribPointer"))
          return false;
  
      glVertexAttribDivisor(3, 1);
      glVertexAttribDivisor(4, 1);
      glVertexAttribDivisor(5, 1);
      glVertexAttribDivisor(6, 1);
  
      if (!LogErrorGL(std::cout, "glVertexAttribDivisor"))
          return false;
  
      //. Unbind Buffer
      glBindBuffer(GL_ARRAY_BUFFER, 0);
  
      //. Bind Default VAO ~ move to outside For Loop
      glBindVertexArray(0);
  
      if (!LogErrorGL(std::cout, "glBindVertexArray"))
          return false;
  
      ObjectSeeds.push_back(std::vector&lt;Vector4f&gt;());
      ObjectModels.push_back(std::vector&lt;Matrix4f&gt;());
  }
  </code></pre>
  
  <p>That all works without throwing any GL errors but I do get an GL_INVALID_OPERATION in the InstanceObject::Update() section when I try to bind the VAO to load the update data:</p>
  
  <pre><code>    //. Load Instance Arrays into VAOs
  for (unsigned int Level = 0; Level &lt; Levels; Level++)
  {
      glBindVertexArray(Meshes-&gt;GetMesh(Level)-&gt;GetVAO()); //. GL_INVALID OPERATION
  
      if (!LogErrorGL(std::cout, "glBindVertexArray"))
          return;
  
      //glGenBuffers(1, &amp;VBO_SeedVector[Level]);
      glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
  
      if (!LogErrorGL(std::cout, "glBindBuffer"))
          return;
  
      glBufferData(GL_ARRAY_BUFFER, ObjectSeeds[Level].size() * sizeof(Vector4f), &amp;ObjectSeeds[Level], GL_STATIC_DRAW);
  
      if (!LogErrorGL(std::cout, "glBufferData"))
          return;
  
      //glGenBuffers(1, &amp;VBO_ModelMatrix[Level]);
      glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
  
      if (!LogErrorGL(std::cout, "glBindBuffer"))
          return;
  
      glBufferData(GL_ARRAY_BUFFER, ObjectModels[Level].size() * sizeof(Matrix4f), &amp;ObjectModels[Level], GL_STATIC_DRAW);
  
      if (!LogErrorGL(std::cout, "glBufferData"))
          return;
  </code></pre>