title: OpenGL spritesheet shader
body: <p>I'm staring to understand that a vertex Shader handles transformations of my texture. While the fragment Shader handles individual pixels. But this vector math is confusing. </p>
  
  <p>What I'm trying to do is render a sprite from a sprite sheet. I can render a whole image just fine, but now i'm actually trying to write my own shader.</p>
  
  <p>I think its more efficient to have the graphics card do the heavy lifting, that being said;</p>
  
  <p>Currently I draw whole images like so:</p>
  
  <p>In my init step,</p>
  
  <pre><code>void TextureRenderer::initRenderData()
  {
      // Configure VAO/VBO
      game_uint VBO;
      game_float vertices[] = {
          // Pos      // Tex
          0.0f, 1.0f, 0.0f, 1.0f,
          1.0f, 0.0f, 1.0f, 0.0f,
          0.0f, 0.0f, 0.0f, 0.0f,
  
          0.0f, 1.0f, 0.0f, 1.0f,
          1.0f, 1.0f, 1.0f, 1.0f,
          1.0f, 0.0f, 1.0f, 0.0f
      };
  
      glGenVertexArrays(1, &amp;this-&gt;quadVAO);
      glGenBuffers(1, &amp;VBO);
  
      glBindBuffer(GL_ARRAY_BUFFER, VBO);
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  
      glBindVertexArray(this-&gt;quadVAO);
      glEnableVertexAttribArray(0);
      glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(game_float), (GLvoid*)0);
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p>Then when its time to draw any texture:</p>
  
  <pre><code>void TextureRenderer::DrawTexture(Texture2D &amp;texture, vec2 position, vec2 size, game_float rotate, vec3 color)
  {
      // Prepare transformations
      this-&gt;shader-&gt;Use();
      glm::mat4 model;
      model = glm::translate(model, vec3(position, 0.0f));  // First translate (transformations are: scale happens first, then rotation and then finall translation happens; reversed order)
  
      model = glm::translate(model, vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); // Move origin of rotation to center of quad
      model = glm::rotate(model, rotate, vec3(0.0f, 0.0f, 1.0f)); // Then rotate
      model = glm::translate(model, vec3(-0.5f * size.x, -0.5f * size.y, 0.0f)); // Move origin back
  
      model = glm::scale(model, vec3(size, 1.0f)); // Last scale
  
      this-&gt;shader-&gt;SetMatrix4("model", model);
  
      // Render textured quad
      this-&gt;shader-&gt;SetVector3f("spriteColor", color);
  
      glActiveTexture(GL_TEXTURE0);
      texture.Bind();
  
      glBindVertexArray(this-&gt;quadVAO);
      glDrawArrays(GL_TRIANGLES, 0, 6);
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p>TextureShader.vs:</p>
  
  <pre><code>#version 330 core
  layout (location = 0) in vec4 vertex; // &lt;vec2 position, vec2 texCoords&gt;
  
  out vec2 TexCoords;
  
  uniform mat4 model;
  uniform mat4 projection;
  
  void main()
  {
      TexCoords = vertex.zw;
      gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
  }
  </code></pre>
  
  <p>Fragment Shader:</p>
  
  <pre><code>#version 330 core
  in vec2 TexCoords; //Position
  out vec4 color;
  
  uniform sampler2D image;
  uniform vec3 spriteColor;
  
  void main()
  {    
      color = vec4(spriteColor, 1.0) * texture(image, TexCoords);
  }  
  </code></pre>
  
  <p>Now that work all fine and dandy (assuming proper opengl setup ext.)</p>
  
  <p>But id like to apply this to a Sprite sheet shader, and have the GPU handle the math to draw it.</p>
  
  <pre><code>void SpriteRenderer::drawSprite(Texture2D &amp;texture, vec2 position,game_float spriteHeight,game_float spriteWidth,int frameIndex)
  {
      shader-&gt;Use();//Load a diffrent Shader here.
      shader-&gt;SetInteger("frameindex", frameIndex);
      shader-&gt;SetVector2f("position", position);
      shader-&gt;SetFloat("spriteHeight", spriteHeight);
      shader-&gt;SetFloat("spriteWidth", spriteWidth);
      shader-&gt;SetMatrix4("model", model);
      shader-&gt;SetVector3f("spriteColor", color);
  
      glActiveTexture(GL_TEXTURE0); //Set texture to nothin
      texture.Bind(); //Bind my texture.
  
      glBindVertexArray(this-&gt;quadVAO); //Bind the fullscreen quad
      glDrawArrays(GL_TRIANGLES, 0, 6); //Draw
      glBindVertexArray(0); //Unbind the quad.
  }
  </code></pre>
  
  <p>I assume:
  Inside the vertex Shader, I manipulate the VAO quad to the position it is on the canvas then set the color of the pixles in the fragment shader to that spesific region.</p>
  
  <p>How would that be done?</p>
  
  <p>Or would it be better off for me to pre-calculate a VAO Array for each Sprite in a sprite class? Then each draw call would be:</p>
  
  <pre><code>void SpriteRenderer::drawSprite(Texture2D &amp;texture, vec2 position,Sprite s)
  </code></pre>
  
  <p>Where the sprite has these vertices stored.</p>
  
  <p>Iv seen: 
  <a href="https://stackoverflow.com/questions/14426412/techniques-for-drawing-spritesheets-in-opengl-with-shaders">Techniques for drawing spritesheets in OpenGL with shaders</a></p>
  
  <p>Somewhat similar, but id like to have the GPU handle the math all together.</p>