diff --git a/panda/src/tinydisplay/tinyXGraphicsWindow.cxx b/panda/src/tinydisplay/tinyXGraphicsWindow.cxx index eb11385679..41bfdca120 100644 --- a/panda/src/tinydisplay/tinyXGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinyXGraphicsWindow.cxx @@ -234,14 +234,12 @@ begin_flip() { _reduced_frame_buffer->xsize, _reduced_frame_buffer->ysize); } - if (_bytes_per_pixel == 4 && _pitch == _full_frame_buffer->linesize) { - // If we match the expected bpp, we don't need an intervening copy - // operation. Just point the XImage directly at the framebuffer - // data. - _ximage->data = (char *)_full_frame_buffer->pbuf; - } else { - ZB_copyFrameBuffer(_full_frame_buffer, _ximage->data, _pitch); - } + // We can't just point the XPutImage directly at our own framebuffer + // data, even if the bytes_per_pixel matches, because some X + // displays will respect the alpha channel and make the window + // transparent there. We don't want transparent windows where the + // alpha data happens to less than 1.0. + ZB_copyFrameBufferNoAlpha(_full_frame_buffer, _ximage->data, _pitch); XPutImage(_display, _xwindow, _gc, _ximage, 0, 0, 0, 0, _full_frame_buffer->xsize, _full_frame_buffer->ysize); @@ -1830,19 +1828,14 @@ create_reduced_frame_buffer() { void TinyXGraphicsWindow:: create_ximage() { if (_ximage != NULL) { - if (_bytes_per_pixel != 4) { - PANDA_FREE_ARRAY(_ximage->data); - } + PANDA_FREE_ARRAY(_ximage->data); _ximage->data = NULL; XDestroyImage(_ximage); _ximage = NULL; } int image_size = _full_frame_buffer->ysize * _pitch; - char *data = NULL; - if (_bytes_per_pixel != 4) { - data = (char *)PANDA_MALLOC_ARRAY(image_size); - } + char *data = (char *)PANDA_MALLOC_ARRAY(image_size); _ximage = XCreateImage(_display, _visual, _depth, ZPixmap, 0, data, _full_frame_buffer->xsize, _full_frame_buffer->ysize, diff --git a/panda/src/tinydisplay/zbuffer.cxx b/panda/src/tinydisplay/zbuffer.cxx index 49ee2771dd..e9dc83423e 100644 --- a/panda/src/tinydisplay/zbuffer.cxx +++ b/panda/src/tinydisplay/zbuffer.cxx @@ -148,6 +148,30 @@ static void ZB_copyBuffer(const ZBuffer * zb, } } +static void +ZB_copyBufferNoAlpha(const ZBuffer * zb, void *buf, int linesize) { + const PIXEL *q = zb->pbuf; + PIXEL *p = (PIXEL *)buf; + int xsize = zb->xsize; + for (int y = 0; y < zb->ysize; ++y) { + const PIXEL *q1 = q; + PIXEL *p1 = p; + PIXEL *p2 = p1 + xsize; + while (p1 < p2) { + // Make sure the alpha bits are set to 0xff. +#ifdef WORDS_BIGENDIAN + *p1 = *q1 | 0x000000ff; +#else + *p1 = *q1 | 0xff000000; +#endif + ++p1; + ++q1; + } + p = (PIXEL *) ((char *) p + linesize); + q = (const PIXEL *) ((const char *) q + zb->linesize); + } +} + #define RGB32_TO_RGB16(v) \ (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3)) @@ -228,6 +252,30 @@ void ZB_copyFrameBuffer(const ZBuffer * zb, void *buf, } } +void ZB_copyFrameBufferNoAlpha(const ZBuffer * zb, void *buf, + int linesize) +{ + switch (zb->mode) { +#ifdef TGL_FEATURE_16_BITS + case ZB_MODE_5R6G5B: + ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); + break; +#endif +#ifdef TGL_FEATURE_24_BITS + case ZB_MODE_RGB24: + ZB_copyFrameBufferRGB24(zb, buf, linesize); + break; +#endif +#ifdef TGL_FEATURE_32_BITS + case ZB_MODE_RGBA: + ZB_copyBufferNoAlpha(zb, buf, linesize); + break; +#endif + default: + assert(0); + } +} + // Copy from (source_xmin,source_ymin)+(source_xsize,source_ysize) to // (dest_xmin,dest_ymin)+(dest_xsize,dest_ysize). void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, int dest_xsize, int dest_ysize, diff --git a/panda/src/tinydisplay/zbuffer.h b/panda/src/tinydisplay/zbuffer.h index 2dfc5bd31f..78e65d73f5 100644 --- a/panda/src/tinydisplay/zbuffer.h +++ b/panda/src/tinydisplay/zbuffer.h @@ -230,6 +230,7 @@ int texcoord_mirror_once(int coord, int max_coord); /* linesize is in BYTES */ void ZB_copyFrameBuffer(const ZBuffer *zb,void *buf,int linesize); +void ZB_copyFrameBufferNoAlpha(const ZBuffer *zb,void *buf,int linesize); void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, int dest_xsize, int dest_ysize, const ZBuffer *source, int source_xmin, int source_ymin,