gpt4 book ai didi

c++ - 如何避免cairo绘图xlib表面闪烁?

转载 作者:行者123 更新时间:2023-12-01 15:02:27 26 4
gpt4 key购买 nike

我正在使用 C++ 中的 cairo xlib 进行一些编程,我的代码在下面列出。

我遇到了一些闪烁的问题,但是通过修改我的代码,现在通常看起来效果不错。
但是,当窗口以小尺寸(在我的笔记本电脑上约为600x450)调整大小时,仍然是闪烁的
我该如何解决?

#include <cairo.h>
#include <cairo-xlib.h>
#include <string>
#include <cstdio>

using namespace std;

int main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;

surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
cr = cairo_create (surface);
/* Examples are in 1.0 x
* 1.0 coordinate space */
cairo_scale (cr, 800, 600);

cairo_set_source_rgb (cr, 1.0, 0, 0);
cairo_rectangle (cr, 0, 0, 1.0, 1.0);
cairo_fill(cr);
cairo_destroy(cr);

Display *display = XOpenDisplay(NULL);
int default_scr = DefaultScreen(display);
Visual *visual = DefaultVisual(display, default_scr);
Window root_win = RootWindow(display, default_scr);
Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
BlackPixel(display, default_scr), WhitePixel(display, default_scr));
cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, 800, 600);

XSelectInput(display, drawable, ExposureMask | StructureNotifyMask);
XMapWindow(display, drawable);
XFlush(display);
XSync(display, default_scr);
Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, drawable, &wmDeleteMessage, 1);

int height;
int width;
XEvent event;
bool running = true;
while (running)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
cairo_t *x11_cr = cairo_create(x11_sf);
cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
cairo_set_source_surface(x11_cr, surface, 0, 0);
cairo_paint(x11_cr);
cairo_destroy (x11_cr);
}
break;
case ClientMessage:
if (event.xclient.data.l[0] == wmDeleteMessage)
{
running = false;
}
break;
case ConfigureNotify:
width = event.xconfigure.width;
height = event.xconfigure.height;
cairo_xlib_surface_set_size(x11_sf, width, height);
break;
}
}

cairo_surface_destroy (surface);

return 0;
}

我使用 cairo_xlib_surface绘制一个具有整个红色背景色的窗口。我试图捕获 XExpose事件并重绘它。但是有时重绘结果变得奇怪。
#include <cairo.h>
#include <cairo-xlib.h>
#include <string>
#include <cstdio>

using namespace std;

int main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;

surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
cr = cairo_create (surface);
/* Examples are in 1.0 x 1.0 coordinate space */
cairo_scale (cr, 800, 600);

/* Drawing code goes here */
cairo_set_source_rgb (cr, 1.0, 0, 0);
cairo_rectangle (cr, 0, 0, 1.0, 1.0);
cairo_fill(cr);

Display *display = XOpenDisplay(NULL);
int default_scr = DefaultScreen(display);
Visual *visual = DefaultVisual(display, default_scr);
Window root_win = RootWindow(display, default_scr);
Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
BlackPixel(display, default_scr), WhitePixel(display, default_scr));

XSelectInput(display, drawable, ExposureMask);
XMapWindow(display, drawable);
XFlush(display);
XSync(display, default_scr);


int height;
int width;
XEvent event;
while (1)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
width = event.xexpose.width;
height = event.xexpose.height;
cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, width, height);
cairo_t *x11_cr = cairo_create(x11_sf);
cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
cairo_set_source_surface(x11_cr, surface, 0, 0);
cairo_paint(x11_cr);
cairo_destroy (x11_cr);
cairo_surface_destroy (x11_sf);
}
break;
}
}


/* Write output and clean up */
cairo_destroy (cr);
cairo_surface_destroy (surface);

return 0;
}

调整窗口大小时,有时会得到如下结果:
The result window

似乎尚未完成绘制红色背景的操作。

有人可以告诉我为什么会这样以及如何避免吗?

如果有人想在 下进行编译,则可以使用Linux :g++ \pkg-config --cflags --libs x11 cairo\ src.cpp

谢谢!

最佳答案

该问题是由于您在白色背景上用填充红色区域来制作红色背景而造成的,这不是最有效的方法。

您应该使用定义为红色而不是白色的背景色来创建窗口!

因此,要做到这一点,请在XCreateSimpleWindow()背景参数(最后一个)中,将0xFF0000放入它,它是24位色彩空间中红色的十六进制值,但是如果使用其他格式,则可能需要更改它颜色空间。该行如下所示:

XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
BlackPixel(display, default_scr), WhitePixel(display, default_scr));

关于c++ - 如何避免cairo绘图xlib表面闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382772/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com