У меня возникли проблемы с отображением изображения (PNG, извлеченного с помощью libpng) в окне XCB, оно всегда полностью пустое/белое. Я почти уверен, что извлечение PNG правильно, так как я могу идеально переписать его в другой файл.
Я перепробовал все, что нашел (объяснения, руководства, документация), и у меня заканчиваются идеи:
- Создание
xcb_pixmap_t
, вызывающегоxcb_create_pixmap_from_bitmap_data()
с данными, взятыми из PNG, затем вызовxcb_copy_area()
в часть EXPOSE цикла событий. - Создание
xcb_image_t*
, вызывающегоxcb_image_create_from_bitmap_data()
, а затем попытка сопоставить его с окном с помощьюxcb_image_put()
. Я даже пытался отобразить каждый пиксель с помощьюxcb_image_put_pixel()
, но безуспешно.
Пример кода:
xcb_pixmap_t pixmap = xcb_create_pixmap_from_bitmap_data(
connection, // xcb_connect(0, 0) (type: xcb_connection_t*)
window, // xcb_generate_id(connection) (type: xcb_window_t)
img.getData(), // uint8_t*
img.getWidth(), // 128
img.getHeight(), // 128
img.getBitDepth(), // 8
screen->black_pixel, // screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data (type: xcb_screen_t*)
screen->white_pixel,
nullptr);
// "img" is an instance of my own custom class, result of PNG reading
xcb_image_t* image = xcb_image_create_from_bitmap_data(
img.getData(),
img.getWidth(),
img.getHeight()); // image->data seems fine
xcb_image_put(connection,
window,
graphicsContext,
image, 0, 0, 0); // This does nothing
for (unsigned int i = 0; i < screen->height_in_pixels; ++i)
for (unsigned int j = 0; j < screen->width_in_pixels; ++j)
xcb_image_put_pixel(image, j, i, 0); // Displays nothing
[...]
// Into event loop
case XCB_EXPOSE: {
xcb_expose_event_t* exposeEvent = reinterpret_cast<xcb_expose_event_t*>(event);
xcb_copy_area(connection,
pixmap,
window,
graphicsContext,
exposeEvent->x, exposeEvent->y, // Top left x & y coordinates of the source's region to copy
exposeEvent->x, exposeEvent->y, // Top left x & y coordinates of the destination's region to copy to
exposeEvent->width,
exposeEvent->height);
xcb_flush(connection);
break;
}
Из примеров, которые я нашел, я понял, что цветовая карта не нужна, но может ли это быть так? Может ли кто-нибудь сказать мне, где я ошибся?
img.getBitDepth(), // 8
это может быть вашей проблемой. Глубина должна быть такой же, как глубина вашего окна, иначеxcb_copy_area
не удастся. У вас действительно 8-битные окна по умолчанию? В общем, вы должны быть готовы справиться с любой глубиной. - person n. 1.8e9-where's-my-share m.   schedule 28.03.2017XCB_COPY_FROM_PARENT
окну при его создании. Заменив это поле на8
, окно даже не появится. - person Razakhel   schedule 28.03.2017xcb_create_pixmap_from_bitmap_data
делает не то, что вы думаете. Это для исходных данных глубиной один бит. То же самое и сxcb_image_create_from_bitmap_data
. Это для растровых изображений с глубиной один бит. Вы хотите толькоxcb_image_create
. Это устрашающая функция. Посмотрите примеры использования в сети, прежде чем пытаться вызвать его. - person n. 1.8e9-where's-my-share m.   schedule 28.03.2017xcb_image_create
(который я уже пробовал ранее, если я правильно помню), и я продолжаю получать segfault. Я занимаюсь этим уже два дня, просто потому, что XCB не может сделать надлежащую документацию. Я думаю, что я просто сделаю окна GLX (мне все равно позже понадобится OpenGL). - person Razakhel   schedule 29.03.2017xcb_image_put
по телефонуwindow
. Это поместит изображение на экран, если окно сопоставлено, или не поместит его вообще, если окно не сопоставлено. Вы также потеряете все, что помещено в окно, когда оно частично закрыто другим окном или не отображено. Вместо этого вы, вероятно, захотите вызватьxcb_image_put
для созданного вамиpixmap
. У растрового изображения есть постоянный буфер, и вы можете копировать данные оттуда в окно всякий раз, когда окно открывается (ведь вы уже это делаете). - person Rickard Närström   schedule 06.05.2020