通过 XRender 在 Linux 上实现图形特效
一 环境准备与能力检测
sudo apt-get install libxrender-devsudo yum install libXrender-develsudo dnf install libXrender-develxdpyinfo | grep "X Render",若输出包含 X Render 表示支持。也可在程序中用 XRenderQueryExtension(display, &event_base, &error_base) 检测扩展是否可用。二 最小可用示例 合成两张 ARGB32 位图
XRenderComposite 进行合成(如 PictOpOver 表示“源覆盖到目标之上”)。gcc -o xrender_demo main.c -lX11 -lXrender#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
#include <stdio.h>
int main(void) {
Display *dpy = XOpenDisplay(NULL);
if (!dpy) { fprintf(stderr, "无法打开显示\n"); return 1; }
int scr = DefaultScreen(dpy);
Window root = RootWindow(dpy, scr);
// 检查扩展
int evb, errb;
if (!XRenderQueryExtension(dpy, &evb, &errb)) {
fprintf(stderr, "XRender 扩展不可用\n");
XCloseDisplay(dpy);
return 1;
}
// 创建两个 200x200 的 ARGB32 Pixmap 并填充颜色
Pixmap pm1 = XCreatePixmap(dpy, root, 200, 200, 32);
Pixmap pm2 = XCreatePixmap(dpy, root, 200, 200, 32);
GC gc = XCreateGC(dpy, pm1, 0, NULL);
XSetForeground(dpy, gc, 0xFF0000FF); // 蓝
XFillRectangle(dpy, pm1, gc, 0, 0, 200, 200);
XSetForeground(dpy, gc, 0x80FF0000); // 半透明红
XFillRectangle(dpy, pm2, gc, 50, 50, 100, 100);
XFreeGC(dpy, gc);
// 将 Pixmap 包装为 Picture(ARGB32)
XRenderPictureAttributes attrs = {0};
Picture pic1 = XRenderCreatePictureFromPixmap(dpy, pm1, PictStandardARGB32, CPSubwindowMode, &attrs);
Picture pic2 = XRenderCreatePictureFromPixmap(dpy, pm2, PictStandardARGB32, CPSubwindowMode, &attrs);
// 合成:pic2 OVER pic1 → 目标为根窗口(直接显示)
XRenderComposite(dpy, PictOpOver, pic2, None, XRenderCreatePictureFromDrawable(dpy, root, 0, &attrs),
0, 0, 0, 0, 50, 50, 100, 100);
// 资源清理
XRenderFreePicture(dpy, pic1);
XRenderFreePicture(dpy, pic2);
XFreePixmap(dpy, pm1);
XFreePixmap(dpy, pm2);
XCloseDisplay(dpy);
return 0;
}
PictOpOver 是最常用的合成操作;其他如 PictOpSrc、PictOpAdd 等可按需选择。三 常见特效与实现要点
XftDrawString8/16 绘制文字,启用 XftAntialias(true) 获得平滑边缘(属于 Xft,常与 XRender 管线配合使用)。XRenderComposite 合成。XRenderCreateLinearGradient/XRenderCreateRadialGradient 生成 Picture(类型为 PictTypeDirect,包含颜色停止点),再作为源进行合成,可实现线性/径向渐变。XRenderComposite 不直接提供几何变换;常见做法是预先用 cairo(软件渲染到 ARGB32)或 OpenGL 生成变换后的位图,再用 XRender 合成到窗口。四 进阶与生态