title: Drawing a rectangle between two points in OpenGL using scale + rotation matrix
body: <p>I have a rectangle mesh that I share in a flyweight type object that other classes use to draw themselves. The drawing code looks like:</p>
  
  <pre><code>void Draw(const glm::ivec2 position, const glm::ivec2 size)
  {
      /* do some binding ...*/
  
      glm::vec2 s(m_screenDimensions.x,m_screenDimensions.y);
      glm::vec2 p(position.x,position.y);
      glm::vec2 d(size.x,size.y);
      glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f),glm::vec3(-1.0f+p.x/s.x*2.0f+(d.x/s.x),1.0f-p.y/s.y*2.0f-(d.y/s.y),0.0f));
      glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f),glm::vec3(d.x/s.x,d.y/s.y,1.0f));
      m_program.SetUniform(m_modelMatrixLocation,translationMatrix * scaleMatrix * glm::mat4(1.0f));
  
      /* dispatch draw calls ... */
  }
  </code></pre>
  
  <p>This easily draws a rectangle at the desired position and size. However, I'd like to now draw lines using this same rectangle flyweight. So basically:</p>
  
  <pre><code>void Draw(const glm::ivec2 position1, const glm::ivec2 position2, const unsigned int width)
  {
      /* ... */
  }
  </code></pre>
  
  <p>The problem I'm having is calculating the translation, scale and rotation matrix.</p>
  
  <p>I understand that I can calculate the rectangle points via:</p>
  
  <ol>
  <li>Getting a vector between the two positions</li>
  <li>Getting a perpendicular vector</li>
  <li>Placing each of the four around the positions moving along this perpendicular vector</li>
  </ol>
  
  <p>But I don't understand how to calculate the rotation matrix needed. Obviously, because it's being expressed as a line (two points and a width) instead of as a rect (position and size) the way I'm calculating the translation matrix and scale matrix needs to be different to.</p>
  
  <p>For example, if I calculate the translation and scale matrix as I am now (by deducing the size and position points from the provided positions and width); how do I calculate the rotation matrix?</p>
  
  <p><strong>EDIT1</strong></p>
  
  <p>I've tried as suggested but I'm not getting anything on the screen:</p>
  
  <pre><code>void RectColoured::Draw(const glm::ivec2 position1, const glm::ivec2 position2, const int width) const
  {
      m_program.Bind();
      m_program.SetUniform(m_colorUniformLocation,m_color);
      m_program.SetUniform(m_useTextureUniformLocation,false);
  
   /*   glm::vec2 s(m_screenDimensions.x,m_screenDimensions.y);
      glm::vec2 p(position1.x,position1.y);
      glm::vec2 d(position2.x-position1.x+10,position2.y-position1.y+10);
      glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f),glm::vec3(-1.0f+p.x/s.x*2.0f+(d.x/s.x),1.0f-p.y/s.y*2.0f-(d.y/s.y),0.0f));
      glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f),glm::vec3(d.x/s.x,d.y/s.y,1.0f));
      m_program.SetUniform(m_modelMatrixLocation,translationMatrix * scaleMatrix * glm::mat4(1.0f));
  */
      glm::vec2 s(m_screenDimensions.x,m_screenDimensions.y);
      glm::vec2 d = position2-position1;
      glm::vec2 n = glm::normalize(d);
      auto p1 = position1;
      float w = width;
      float m[] = {
              2*d.x/s.x,  2*n.x/s.x*w,    0,  2*(p1.x-0.5*n.x)/s.x-1.0,
              2*d.y/s.y,  2*n.y/s.y*w,    0,  2*(p1.y-0.5*n.y)/s.y-1.0,
              0,          0,              0,  0,
              0,          0,              0,  1
      };
      glm::mat4 matrix = glm::make_mat4(m);
      m_program.SetUniform(m_modelMatrixLocation,matrix);
  
      m_quad.BindAndDraw();
  }
  </code></pre>
  
  <p><strong>EDIT 2</strong>
  Not quite there:</p>
  
  <pre><code>void RectColoured::Draw(const glm::ivec2 position1, const glm::ivec2 position2, const int width) const
  {
      m_program.Bind();
      m_program.SetUniform(m_colorUniformLocation,m_color);
      m_program.SetUniform(m_useTextureUniformLocation,false);
  
      glm::vec2 s = m_screenDimensions;
      glm::vec2 d = position2-position1;
      glm::vec2 n = glm::normalize(glm::vec2(d.y,-d.x));
      auto p1 = position1;
      float w = width;
      float m[] = {
          2.0f*d.x/s.x,                       -2.0f*d.y/s.y,                      0.0f, 0.0f,
          2.0f*n.x/s.x*w,                     -2.0f*n.y/s.y*w,                    0.0f, 0.0f,
          0.0f,                               0.0f,                               0.0f, 0.0f,
          2.0f*(p1.x-0.5f*n.x*w)/s.x-1.0f,    -2.0f*(p1.y-0.5f*n.y*w)/s.y+1.0f,   0.0f, 1.0f
      };
      glm::mat4 matrix = glm::make_mat4(m);
      m_program.SetUniform(m_modelMatrixLocation,matrix);
  
      m_quad.BindAndDraw();
  }
  </code></pre>
  
  <p>Gives this result:</p>
  
  <p><a href="https://i.stack.imgur.com/QJBdf.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QJBdf.jpg" alt="enter image description here"></a></p>
  
  <p>The two rectangle "nodes" have their top left corner as the two points of the line I'm trying to draw. I can see that it looks about twice as long as it should be along the direction.</p>