Raspberry Pi : OpenGL

В этой статье я расскажу о графических возможностях Raspberry Pi, подводных камнях и как их исбежать.

Мной использовался дистрибутив raspbian.

Чип Broadcom BCM2835, на котором основана плата, поддерживает OpenGL ES 2.0.
Заголовочные файлы библиотек OpenGL ES и EGL находятся в папке /opt/vc/include.
Библиотеки EGL и GLESv2 расположены в папке /opt/vc/lib.

При работе с OpenGL на Raspberry Pi следует учитывать одну особенность: библиотека EGL от производителя не позволяют использовать в качестве поверхности для рисования окна X11. Для создания окна, в котором будет происходить рисование необходимо использовать библиотеку bcm_host из /opt/vc/lib и ее заголовочный файл bcm_host.h из /opt/vc/include. Создаваемое библиотекой окно выглядит как черный квадрат отображаемый поверх всех окон. Эта особенность грозит пользователю тем, что при использовании графической библиотеки Qt вы сможете использовать только полноэкранный OpenGL виджет, на котором нельзя будет разместить удобные кнопки из библиотеки Qt GUI. С другими аналогичными библиотеками GTK или FLTK аналогичных проблем не избежать. Нам пользователям остается ждать новых "правильных" библиотек от производителя или патча от энтузиастов.

Для того чтобы удобно использовать Qt и OpenGL можно использовать один из трех костылей.

1) Создать и перемещать поверхность создаваемую bcm_host поверх QWidget - это производительный вариант, но обладающий недостатками: будут коллизии при перекрытии окон, много лишних телодвижений.
2) Создать и производить рендеринг в неотображаемом EGL контексте, полученное изображение копировать с использованием метода glGetPixels и рисовать на QWidget QPixmap используя подготовленный кадр. Второй вариант непроизводителен.
3) Использовать Qt5. Код написанный на QML отрисовывается в Qt5 на OpenGL ES 2. Поэтому код написанный на QML на Raspberry Pi будет также отрисовываться в полноэкранном режиме, как и все, что мы нарисуем на opengl.

Если Вас устраивает полкоэкранный режим и разработка GUI на QML, то алгоритм действий следующий.
1. Скомпилить Qt5 для pi.
Скачать скомпиленный Qt5 для pi можно из репозитария. Cкрипт bakeqtpi.bash выкачивает исходники Qt5, образ pi, монтирует образ, собирает qmake, настроенный для кросс-компиляции, собирает qt5 под pi.

1.1. Кросс-компиляция, как новогодний подарок.
Проекты написанные на qmake можно легко кросс-компилить для pi. Для этого достаточно запустить скрипт bakeqtpi.bash и прервать после того, как он подмонтирует образ. После этого запускаем qmake, который был скомпилен этим скриптом. Он лежит в /usr/local/qt5pi/bin/qmake. Затем make.

2. Класс для рисования.
Отнаследуем PaintedItem от QQuickPaintedItem. В методе paint будем производить отрисовку на OpenGL ES2.

3. Импортируем PaintedItem в Qml

// main.cpp
QGuiApplication a(argc, argv);
qmlRegisterType("Shapes", 1, 0, "MyTriangle");
QQuickView view;
view.setSource(QUrl("../qml/test.qml"));
a.connect(view.engine(), SIGNAL(quit()), &a, SLOT(quit()) );
view.show();


// test.qml
import QtQuick 2.0
import Shapes 1.0

Rectangle{
    id: page
    width: 360
    height: 360
    .....
    MyTriangle {
        id: triangle
        anchors.fill: parent
    }
}


Пример кода можно найти в моем репозитарии.
example_of_work
Хорошие примеры программ, использующих opengles, для Raspberry Pi можно скачать с opengles-book-samples.

Leave a Reply

You must be logged in to post a comment.