файл - СВД Встраиваемые Системы

Семинар «Российские информационные технологии ответственного назначения» «Композиция технологий Photon, Qt и OpenGL в QNX» Олег Большаков, СВД Встраиваемые Системы Графические технологии QNX
QNX Graphics Framework (GF) — низкоуровневая подсистема 2D и 3D графики для QNX Photon — штатная оконная подсистема QNX §  среда рабочего стола §  набор виджетов §  гибкая настройка для встраивания OpenGL — низкоуровневая библиотека 3D графики OpenGL ES — низкоуровневая библиотека 3D графики для встраиваемых систем Mesa 3D — реализация графического API OpenGL Qt — графическая библиотека §  набор виджетов §  классы общего назначения QtQuick — технология разработки специализированных высоко-­‐ динамичных графических интерфейсов Phonon — мультимедийный фреймворк Композиция
Возрастающие требования к современных системам управления и мониторинга и увеличивающаяся сложность таких систем зачастую не позволяют решить задачу разработки пользовательского интерфейса в приемлемые сроки используя только одну из графических технологий. Требуется совместное использование графических технологий — композиция. Подходы: §  Многооконность §  Многомониторность §  Многослойность §  Компоновка Многомониторность
Конфигурационный файл /etc/system/config/display.conf для двух мониторов: Многомониторность
Многослойность
// подключение к устройству и дисплею gf_dev_attach(&gdev, GF_DEVICE_INDEX(0), &gdev_info);
gf_display_attach(&display, gdev, 0, &display_info);
// подключение к слою и выделение поверхности для отображения gf_layer_attach(&layer, display, display_info.main_layer_index, 0);
gf_surface_create_layer(&surface, &layer, 1, 0,
display_info.xres, display_info.yres, display_info.format,
NULL, GF_SURFACE_CREATE_3D_ACCESSIBLE | GF_SURFACE_CREATE_2D_ACCESSIBLE);
gf_layer_set_surfaces(layer, &surface, 1);
gf_layer_enable(layer);
gf_layer_update(layer, 0);
Photon на нулевом слое, приложение EGL на первом: # egl-gears -layer=1 -xpos=700 -ypos=0 -width=700 -height=1024
Многослойность
OpenGL ES в Photon
// Подключиться к устройству и дисплею GF gf_dev_attach(&gf_dev, NULL, &gf_dev_info);
gf_display_attach(&gf_disp, gf_dev, 0, &gf_disp_info);
// Инициализировать EGL egl_disp = eglGetDisplay(gf_dev);
eglInitialize(egl_disp, NULL, NULL);
// Создать контекст Photon для 2D и 3D pd = PdCreateOffscreenContext(0, w, h, Pg_OSC_MEM_3D_WRITABLE|Pg_OSC_MEM_2D_WRITABLE);
pg = PdGetOffscreenSurface(pd);
PgGetSurfaceGFSid(pg, &sid);
// Подключиться к поверхности gf_surface_attach_by_sid(&gf_surf, gf_dev, sid);
gf_surface_get_info(gf_surf, &gf_info);
OpenGL ES в Photon
// Настроить EGL eglChooseConfig(egl_disp, … , &egl_config, … );
egl_ctx = eglCreateContext(egl_disp, egl_config, EGL_NO_CONTEXT, NULL);
egl_surf = eglCreatePixmapSurface(egl_disp, egl_config, gf_surf, … );
eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
// Создать GF контекст и установить EGL поверхность gf_context_create(&gf_ctx);
gf_context_set_surface_3d(gf_ctx, egl_surf);
QNX Mesa 3D
Приложение OpenGL QNX Mesa 3D libglut.so libGL.so GF3D | GL API libEGL.so r600-­‐gf.so io-­‐display / devg-­‐radeonhd.so Оборудование Mesa 3D в GF
// подключение к устройству и дисплею gf_dev_attach(&gdev, GF_DEVICE_INDEX(0), &gdev_info);
gf_display_attach(&display, gdev, 0, &display_info);
// подключение к слою и выделение поверхности для отображения gf_layer_attach(&layer, display, display_info.main_layer_index, 0);
gf_surface_create_layer(&surface, &layer, 1, 0,
display_info.xres, display_info.yres, display_info.format,
NULL, GF_SURFACE_CREATE_3D_ACCESSIBLE | GF_SURFACE_CREATE_2D_ACCESSIBLE);
gf_layer_set_surfaces(layer, &surface, 1);
gf_layer_enable(layer);
gf_layer_update(layer, 0);
// выделение буфера для рендеринга и контекста для вывода буфера gf_surface_create(&buffer, gdev, display_info.xres, display_info.yres,
display_info.format, NULL,
GF_SURFACE_CREATE_3D_ACCESSIBLE | GF_SURFACE_CREATE_2D_ACCESSIBLE);
gf_context_create(&context);
gf_context_set_surface(context, surface);
Mesa 3D в GF
// создание 3D контекста, активация и привязка буфера для рендеринга // gf_dev_info_t требуется Mesa 3D для выбора драйвера gf3d_create_context(gdev, &gdev_info);
gf3d_make_current(ctx, buffer);
// инициализация и настройка OpenGL «под себя» // после рисования функциями gl* // ожидание окончания отрисовки glFinish();
// вывод кадра на экран gf_draw_begin(context);
gf_draw_blit2(context, buffer, surface, 0, 0,
display_info.xres – 1, display_info.yres - 1, 0, 0);
gf_draw_flush(context);
gf_draw_end(context);
GLUT и Mesa 3D
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(480, 360);
glutInitWindowPosition(100, 100);
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("Earth");
glutReshapeFunc(reshape);
glutDisplayFunc(draw);
glutTimerFunc(TIMER_PERIOD, iterate, 0);
// инициализация объекта OpenGL glutMainLoop();
return EXIT_SUCCESS;
}
Mesa 3D в Photon
// подключение к устройству и дисплею gf_dev_attach(&gdev, GF_DEVICE_INDEX(0), &gdev_info);
gf_display_attach(&display, gdev, 0, &display_info);
// подключение к слою и выделение поверхности для отображения gf_surface_create(&gf_surface, gf_dev, width, height, disp_info.format, NULL,
GF_SURFACE_CREATE_SHAREABLE);
gf3d_make_current(ctx, gf_surface);
// создание виджета для отрисовки PtSetArg( &args[0], Pt_ARG_RAW_DRAW_F, raw_draw_f, 0);
PtSetArg( &args[1], Pt_ARG_DIM, &size, 0 );
drawarea = PtCreateWidget(PtRaw, window, 2, args);
PtAddCallback( drawarea, Pt_CB_RESIZE, resize_cb, NULL );
…
PtAppAddWorkProc( NULL, draw_frame, NULL );
Mesa 3D в Photon
void raw_draw_f(PtWidget_t *widget, PhTile_t *damage)
{
PhRect_t
*dst_rect = PtGetCanvas( widget ),
src_rect = { { 0, 0 }, { raw_width - 1, raw_height - 1 } };
// функция PtSuperClassDraw() не вызывается PgContextBlit( gf_surface_ref, &src_rect , NULL, dst_rect );
PgFFlush( Ph_DONE_DRAW );
PgWaitHWIdle();
return;
}
int draw_frame( void *data )
{
glFinish();
PtDamageWidget( drawarea );
return Pt_CONTINUE;
}
Qt в среде Photon
Приложение Qt Qt framework Photon libqphoton.so photon | photongl QNX Mesa 3D libGL.so GF3D | GL API io-­‐display / devg-­‐radeonhd.so Оборудование Запуск Qt в среде Photon
Два способа отрисовки Qt графики в Photon §  Средствами только Photon (без QNX Mesa 3D): # qt_application -p photon
§  Средствами OpenGL с библиотеками QNX Mesa 3D: # qt_application -p photongl
OpenGL в среде Qt
class MainWidget : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = 0);
virtual ~MainWidget();
protected:
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void timerEvent(QTimerEvent *e);
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void initShaders();
void initTextures();
…
};
OpenGL в среде Qt
void MainWidget::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::black);
initShaders();
initTextures();
// Enable depth buffer
glEnable(GL_DEPTH_TEST);
// Enable back face culling
glEnable(GL_CULL_FACE);
geometries->init();
timer->start(12, this);
}
void MainWidget::paintGL()
{
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate model view transformation
QMatrix4x4 matrix;
matrix.translate(0.0, 0.0, -5.0);
matrix.rotate(rotation);
// Set modelview-projection matrix
program->setUniformValue("mvp_matrix", projection * matrix);
// Using texture unit 0 which contains cube.png
program->setUniformValue("texture", 0);
// Draw cube geometry
geometries->drawCubeGeometry(program);
}
Доступность материалов
§  Сборка Qt 4.8.6 для QNX 6.5.0 §  Комплект QNX Mesa 3D §  Исходный код примеров §  Дополнительные материалы [email protected] forum.kpda.ru Олег Большаков Руководитель группы разработки (812) 346-­‐8956 доб. 108 [email protected] www.kpda.ru forum.kpda.ru