Search code examples
cgraphicsx11xlib

How to Render a Scaled Pixel Buffer with Xlib/XRender


On startup I allocate: u32 *pixel_buffer = calloc(width * height, 4);

I wish to render this scaled to the current width and height of the window. My attempts:

  1. Using XCreateImage/XPutImage renders correctly when the starting window dimensions match the dimensions of the pixel buffer. On window resize however, the contents of the buffer aren't scaled and the extra space is filled in with black (the value of the background pixel I set for the window)
  2. Use XPutImage to a Pixmap. Then each loop iteration, use XRenderCreatePicture on this Pixmap and on the Window and XRenderComposite them. This just produces a black screen.

Any suggestions?


Solution

  • XPutImage(display, pixmap, default_gc, x_image, 
            0, 0, 0, 0, pixel_buffer_width, pixel_buffer_height);
    
    Picture src_pict = XRenderCreatePicture(display, pixmap, pic_format, 0, &pic_attributes);
    Picture dst_pict = XRenderCreatePicture(display, window, pic_format, 0, &pic_attributes);
    
    double x_scale = pixel_buffer_width / window_width;
    double y_scale = pixel_buffer_height / window_height;
    XTransform transform_matrix = {{
      {XDoubleToFixed(x_scale), XDoubleToFixed(0), XDoubleToFixed(0)},
      {XDoubleToFixed(0), XDoubleToFixed(y_scale), XDoubleToFixed(0)},
      {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1.0)}  
    }};
    XRenderSetPictureTransform(display, src_pict, &transform_matrix);
    
    XRenderComposite(display, PictOpSrc, src_pict, 0, dst_pict, 
                    0, 0, 0, 0, 0, 0,
                    window_width, window_height);