Hello,

In Mesa-3.0, glReadPixels doesn't always return the correct alpha values.  The
bug is related to read_fast_rgba_pixels().  In cases where
(*ctx->Driver.ReadRGBASpan) calls read_color_span, the final returned alpha
values are all 255, even if there is a local enabled alpha buffer with other
values.  I think a fix might be to in readpix.c change line 507 and beyond from:

         for (row=0; row<readHeight; row++) {
            (*ctx->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
                                        (void *) dest);
            dest += rowLength * 4;
            srcY++;
         }

to:
         for (row=0; row<readHeight; row++) {
            (*ctx->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
                                        (void *) dest);
            if (ctx->RasterMask & ALPHABUF_BIT) {
              gl_read_alpha_span( ctx, readWidth, srcX, srcY, dest );
            }
            dest += rowLength * 4;
            srcY++;
         }

An example program that shows the problem on linux (assuming Mesa installed in
/opt) follows.  It writes one pixel with rgba of 1, 2, 3, 4; reads the pixel
back, and prints the value.  Compile with

gcc -g3 -ansi -pedantic -Wall -o temp temp.c -I/usr/X11R6/include \
-I/opt/include -L/usr/X11R6/lib -L/opt -lGL -lGLU -L/usr/X11R6/lib \
-lX11 -lXext -lXmu -lXt -lm

------------- bug.c --------
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <assert.h>

XVisualInfo* choose_depth_buffer_visual(Display* display) {
  int configuration[] = {GLX_RGBA,
                         GLX_RED_SIZE, 8,
                         GLX_GREEN_SIZE, 8,
                         GLX_BLUE_SIZE, 8,
                         GLX_ALPHA_SIZE, 8,
                         None};
  static XVisualInfo* vi = 0;

  if(!glXQueryExtension(display, 0, 0)) return 0;
  vi = glXChooseVisual(display, DefaultScreen(display), configuration);
  assert(vi);
  return vi;
}

int main() {
  Display* display;
  XVisualInfo* vi;
  GLXContext pixmap_context = 0;
  Pixmap pixmap;
  GLXPixmap glxpixmap;
  unsigned buf;
  unsigned char color[4] = {1, 2, 3, 4};

  display = XOpenDisplay(0);
  vi = choose_depth_buffer_visual(display);
  pixmap = XCreatePixmap(display, RootWindow(display, vi->screen),
                         1, 1, vi->depth);
  glxpixmap = glXCreateGLXPixmap(display, vi, pixmap);
  pixmap_context = glXCreateContext(display, vi, 0, True);
  glXMakeCurrent(display, glxpixmap, pixmap_context);
  glDrawBuffer(GL_FRONT);
  glClear(GL_COLOR_BUFFER_BIT);
  /* Either way fails. */
#if 1
  glColor4ubv(color);
  glBegin(GL_POINTS);
  glVertex3d(0.0, 0.0, 0.0);
  glEnd();
#else
   glDrawPixels(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
#endif
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glReadBuffer(GL_FRONT);
  glPixelTransferf(GL_RED_SCALE, 1.0);
  glPixelTransferf(GL_GREEN_SCALE, 1.0);
  glPixelTransferf(GL_BLUE_SCALE, 1.0);
  glPixelTransferf(GL_ALPHA_SCALE, 1.0);
  glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &buf);
  glXDestroyGLXPixmap(display, glxpixmap);
  glXDestroyContext(display, pixmap_context);
  XFreePixmap(display, pixmap);

  printf("buf: %0x.\nShould have gotten 04030201 (or maybe 01020304 on a
litte-endian machine).\n ", buf);
  return 0;

}
---------------------
Instead of getting 04030201 you will likely get ff030201.  With the "fix" I do
get 0430201.

Doug


_______________________________________________
Mesa-bug maillist  -  [EMAIL PROTECTED]
http://lists.mesa3d.org/mailman/listinfo/mesa-bug


_______________________________________________
Mesa-dev maillist  -  [EMAIL PROTECTED]
http://lists.mesa3d.org/mailman/listinfo/mesa-dev

Reply via email to