title: Opengl pixel perfect 2D drawing
body: <p>I'm working on a 2d engine. It already works quite good, but I keep getting pixel-errors.</p>
  
  <p>For example, my window is 960x540 pixels, I draw a line from (0, 0) to (959, 0). I would expect that every pixel on scan-line 0 will be set to a color, but no: the right-most pixel is not drawn. Same problem when I draw vertically to pixel 539. I really need to draw to (960, 0) or (0, 540) to have it drawn.</p>
  
  <p>As I was born in the pixel-era, I am convinced that this is not the correct result. When my screen was 320x200 pixels big, I could draw from 0 to 319 and from 0 to 199, and my screen would be full. Now I end up with a screen with a right/bottom pixel not drawn.</p>
  
  <p>This can be due to different things:
  where I expect the opengl line primitive is drawn from a pixel to a pixel inclusive, that last pixel just is actually exclusive? Is that it?
  my projection matrix is incorrect?
  I am under a false assumption that when I have a backbuffer of 960x540, that is actually has one pixel more?
  Something else?</p>
  
  <p>Can someone please help me? I have been looking into this problem for a long time now, and every time when I thought it was ok, I saw after a while that it actually wasn't.</p>
  
  <p>Here is some of my code, I tried to strip it down as much as possible. When I call my line-function, every coordinate is added with 0.375, 0.375 to make it correct on both ATI and nvidia adapters.</p>
  
  <pre><code>int width = resX();
  int height = resY();
  
  for (int i = 0; i &lt; height; i += 2)
      rm-&gt;line(0, i, width - 1, i, vec4f(1, 0, 0, 1));
  for (int i = 1; i &lt; height; i += 2)
      rm-&gt;line(0, i, width - 1, i, vec4f(0, 1, 0, 1));
  
  // when I do this, one pixel to the right remains undrawn
  
  void rendermachine::line(int x1, int y1, int x2, int y2, const vec4f &amp;color)
  {
      ... some code to decide what std::vector the coordinates should be pushed into
      // m_z is a z-coordinate, I use z-buffering to preserve correct drawing orders
      // vec2f(0, 0) is a texture-coordinate, the line is drawn without texturing
      target-&gt;push_back(vertex(vec3f((float)x1 + 0.375f, (float)y1 + 0.375f, m_z), color, vec2f(0, 0)));
      target-&gt;push_back(vertex(vec3f((float)x2 + 0.375f, (float)y2 + 0.375f, m_z), color, vec2f(0, 0)));
  }
  
  void rendermachine::update(...)
  {
      ... render target object is queried for width and height, in my test it is just the back buffer so the window client resolution is returned
      mat4f mP;
      mP.setOrthographic(0, (float)width, (float)height, 0, 0, 8000000);
  
      ... all vertices are copied to video memory
  
      ... drawing
      if (there are lines to draw)
          glDrawArrays(GL_LINES, (int)offset, (int)lines.size());
  
      ...
  }
  
  // And the (very simple) shader to draw these lines
  
  // Vertex shader
      #version 120
      attribute vec3 aVertexPosition;
      attribute vec4 aVertexColor;
      uniform mat4 mP;
      varying vec4 vColor;
      void main(void) {
          gl_Position = mP * vec4(aVertexPosition, 1.0);
          vColor = aVertexColor;
      }
  
  // Fragment shader
      #version 120
      #ifdef GL_ES
      precision highp float;
      #endif
      varying vec4 vColor;
      void main(void) {
          gl_FragColor = vColor.rgb;
      }
  </code></pre>