title: Uniform buffer object (UBO) does not work correctly using OpenGL/GLSL
body: <p>I'm currently developing a small 3D engine. Until here I used to use method like glUniformXXX to send my uniform variables (one by one) to the shader program. So I was obliged to send them for each frame (it's not very optimized). So I decided to use Uniform Buffer Object to send all these uniform variables once at the initialization of the program. So, the material data will be loaded once in a buffer the same manner using VBO, IBO or PBO by state changes. Of course if I want for some reason to modify the data in cache I always could use methods like glMapBuffer and glUnmapBuffer to update the data.</p>
  
  <p>For my example I loaded a simple ADS shader program (Ambient, Diffuse and Specular lighting). Now for a sake of simplicity the Shininess component (used to compute the specular light) is placed into a uniform block in the fragment shader as follow (all remaining uniform variables we need to compute ADS shading are used as simple uniform variables):</p>
  
  <pre><code>[...]
  
  layout (std140) uniform MaterialBlock
  {
      float Shininess;
  };
  
  [...]
  
  vec3 Specular = LightInfos[idx].Ls * MaterialInfos.Ks * pow(max(dot(reflectDir, viewDir), 0.0f), Shininess);
  
  [...]
  </code></pre>
  
  <p>Now I'm going to present you the client code to load our UBO:</p>
  
  <pre><code>void video::SpecularEffect::SetupMaterials(std::string const &amp;name)
  {
      GLuint blockIndex = 0, bindingPoint = 0, bufferIndex = 0;
      float shininess = 96.0f;
      {
          blockIndex = glGetUniformBlockIndex(this-&gt;m_Handle, "MaterialBlock");
  
          glUniformBlockBinding(this-&gt;m_Handle, blockIndex, bindingPoint);
          {
              glGenBuffers(1, &amp;bufferIndex);
              glBindBuffer(GL_UNIFORM_BUFFER, bufferIndex);
              {
                  glBufferData(GL_UNIFORM_BUFFER, sizeof(float), &amp;shininess, GL_DYNAMIC_DRAW);
              }
              glBindBuffer(GL_UNIFORM_BUFFER, 0);
          }
          glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, bufferIndex);
    [...]
  }
  </code></pre>
  
  <p>As you can see the code above describes the following schematic:</p>
  
  <pre><code>[*.frag]               BlockIndex     BindingPoint        *pBuffer
  
  uniform MaterialBlock     [0] ----------&gt; [1] &lt;----------- [96.0f] //The shininess value = 96.0f
  {
      float Shininess;
  };
  </code></pre>
  
  <p>Now here's the render function:</p>
  
  <pre><code>void video::RenderBatch::Render(void)
  {
      type::EffectPtr pShaderEffect = EffectManager::GetSingleton()
          .FindEffectByName(this-&gt;m_pMaterial-&gt;GetAssocEffectName());
  
      pShaderEffect-&gt;Bind();
      {
          ///VERTEX ATTRIBUTES LOCATIONS.
          {
              pShaderEffect-&gt;BindAttribLocation(scene::VERTEX_POSITION, "VertexPosition");
              pShaderEffect-&gt;BindAttribLocation(scene::VERTEX_TEXTURE, "VertexTexture");
              pShaderEffect-&gt;BindAttribLocation(scene::VERTEX_NORMAL, "VertexNormal");
          }
          //SEND MATRIX UNIFORMS.
          {
              glm::mat3 normalMatrix = glm::mat3(glm::vec3(this-&gt;m_ModelViewMatrix[0]),
                  glm::vec3(this-&gt;m_ModelViewMatrix[1]), glm::vec3(this-&gt;m_ModelViewMatrix[2]));
  
              pShaderEffect-&gt;SetUniform("ModelViewProjMatrix", this-&gt;m_ModelViewProjMatrix);
              pShaderEffect-&gt;SetUniform("ModelViewMatrix", this-&gt;m_ModelViewMatrix);
              pShaderEffect-&gt;SetUniform("NormalMatrix", normalMatrix);
          }
          this-&gt;SendLightUniforms(pShaderEffect);
  
          pShaderEffect-&gt;SetupMaterials(this-&gt;m_pMaterial-&gt;GetName());
          {
              this-&gt;m_pVertexArray-&gt;Lock(); //VAO binding
              {
                  this-&gt;m_pIndexBuffer-&gt;Lock(); //IBO binding
                  {
                      //Draw call here
                  }
                  this-&gt;m_pIndexBuffer-&gt;Unlock();
              }
              this-&gt;m_pVertexArray-&gt;Unlock();
          }
      }
      pShaderEffect-&gt;Release();
  }
  </code></pre>
  
  <p>As you can see I call the method 'SetupMaterials' directly in the loop. But this is not correct because I do a reallocation of the buffer each frame and moreover a UBO is useless used like this. The goal is to load the material data in cache once. However the rendering is correct (so the uniform block seems to be correctly initialized and the shader program have the access to the buffer):</p>
  
  <p><img src="https://i.stack.imgur.com/n9jED.jpg" alt="enter image description here"> </p>
  
  <p>But now if I just load and fill the buffer once at the initialization, so before the main loop, I have the following display:</p>
  
  <p><img src="https://i.stack.imgur.com/ZcOVK.jpg" alt="enter image description here"></p>
  
  <p>However, I have none OpenGL error (using 'glGetError').</p>
  
  <p>Plus I tried to bind the UBO using 'glBindBuffer(GL_UNIFORM_BUFFER, bufferIndex)' in the render method above, but I still have the same display!</p>
  
  <p>So, why the display is correct if I call the loading method directly in the main loop ? And why it does not work if I call it once at the initialization ?  How could I fix my problem ?</p>
  
  <p>Thanks a lot in advance for your help!</p>