Note that there are some explanatory texts on larger screens.

plurals
  1. POOpaque OpenGL textures have transparent border
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload