Семинар «Российские информационные технологии ответственного назначения» «Композиция технологий 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
© Copyright 2024 ExpyDoc