title: Opaque OpenGL textures have transparent border
body: <p>My problem concerns rendering text with OpenGL -- the text is rendered into a texture, and then drawn onto a quad. The trouble is that the pixels on the edge of the texture are drawn partially transparent. The interior of the texture is fine.</p>
  
  <p>I'm calculating the texture coordinates to hit the center of my texels, using NEAREST (non-)interpolation, setting the texture wrapping to CLAMP_TO_EDGE, and setting the projection matrix to place my vertices at the center of the viewport pixels. Still seeing the issue.</p>
  
  <p>I'm working on VTK with their texture utilities. These are the GL calls that are used to load the texture, as determined by stepping through with a debugger:</p>
  
  <pre><code>glGenTextures(1, &amp;id);
  glBindTexture(GL_TEXTURE_2D, id);
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  // Create and bind pixel buffer object here (not shown, lots of indirection in VTK)...
  glTexImage2D( GL_TEXTURE_2D, 0 , GL_RGBA, xsize, ysize, 0, format, GL_UNSIGNED_BYTE, 0);
  // Unbind PBO -- also omitted
  glBindTexture(GL_TEXTURE_2D, id);
  glAlphaFunc (GL_GREATER, static_cast&lt;GLclampf&gt;(0));
  glEnable (GL_ALPHA_TEST);
  // I've also tried doing this here for premultiplied alpha, but it made no difference:
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  glMatrixMode(GL_TEXTURE);
  glLoadIdentity();
  </code></pre>
  
  <p>The rendering code:</p>
  
  <pre><code>  float p[2] = ...; // point to render text at
  
    int imgDims[2] = ...; // Actual dimensions of image
    float width = ...; // Width of texture in image
    float height = ...; // Height of texture in image
  
    // Prepare the quad
    float xmin = p[0];
    float xmax = xmin + width - 1;
    float ymin = p[1];
    float ymax = ymin + height - 1;
    float quad[] = { xmin, ymin,
                     xmax, ymin,
                     xmax, ymax,
                     xmin, ymax };
  
    // Calculate the texture coordinates.
    float smin = 1.0f / (2.0f * (imgDims[0]));
    float smax = (2.0 * width - 1.0f) / (2.0f * imgDims[0]);
    float tmin = 1.0f / (2.0f * imgDims[1]);
    float tmax = (2.0f * height - 1.0f) / (2.0f * imgDims[1]);
  
    float texCoord[] = { smin, tmin,
                         smax, tmin,
                         smax, tmax,
                         smin, tmax };
  
    // Set projection matrix to map object coords to pixel centers
    // (modelview is identity)
    GLint vp[4];
    glGetIntegerv(GL_VIEWPORT, vp);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    float offset = 0.5;
    glOrtho(offset, vp[2] + offset,
            offset, vp[3] + offset,
            -1, 1);
  
    // Disable polygon smoothing. Why not, I've tried everything else?
    glDisable(GL_POLYGON_SMOOTH);
  
    // Draw the quad
    glColor4ub(255, 255, 255, 255);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, points);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
    glDrawArrays(GL_QUADS, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
  
    // Restore projection matrix
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
  </code></pre>
  
  <p>For debugging purposes, I've overwritten the outermost texels with red, and the next inner layer of texels with green (otherwise it's hard to see what's going on in the mostly-white text image).</p>
  
  <p>I've inspected the texture in-memory using gDEBugger, and it looks as expected -- bright red and green borders around the texture area (the extra empty space is padding to make its size a power of two). For reference:</p>
  
  <p><img src="https://i.stack.imgur.com/tKpyq.png" alt="Good pixels!"></p>
  
  <p>Here's what the final rendered image looks like (magnified 20x -- the black pixels are remnants of the text that was rendered under the debugging borders). Pale red border, but still a bold green inner border:</p>
  
  <p><img src="https://i.stack.imgur.com/iJT7i.png" alt="Bad pixels!"></p>
  
  <p>So it is just the outer edge of pixels that is affected. I'm not sure if it's color-blending or alpha-blending that's screwing things up, I'm at a loss. I've noticed that the corner pixels are twice as pale as the edge pixels, perhaps that's significant... Maybe someone here can spot the error?</p>