1. У нас есть программа, работающая на Windows-XP/7. Коротко о программе. Программа принимает по СОМ-порту от внешнего контроллера раз в секунды показания нескольких датчиков и информацию от GPS-приемника (широта, долгота, курс, скорость). Есть несколько графических окно для отображения датчиков и одно полноэкранное окно, -навигация. Из главного полноэкранного окна при нажатии кнопок могут открываться несколько обычных графических окон (в полный экран) и одно окно навигации на opengl (в полный экран). Программа написана на C#, .Net в VisualSudio, окно навигации писалось с использование TaoFramework (это портированный OpenGL в .Net).
2. Задача, -портировать эту программу на iMX53 в Linux с применением Qt.
2.1. Графическое окно с отображением датчиков перенесено на Qt и работает, проблем нет. Графика программы выводится с использование фреймбуфера:
prog -qws
2.2. Навигационное окно, выполненное в виде отдельного приложения, реализовано и работает:
navig –display simplegl:rgb16 -qws
Через форум сайта
www.starterkit.ru был получен buildroot с библиотеками OpenGL, c поддержкой OpenGL ES2, на этом навигация и сделана. Согласно возможностям драйвера поддержки OpenGL, описанном в
http://qt.gitorious.org/qt-labs/simplegl/blobs/master/README
окно OpenGL может быть только одно потоке (приложении) и только на полный экран. По этому утверждению объединить обычное графическое окно на Qt и окно (в полный экран) на opengl es2 в одном приложении, как мы поняли, невозможно. Мы уже готовы с этим смириться, остается только наладить взаимодействие этих программ.
2.3. Пытаемся, пока безуспешно, наладить механизм переключения между этими программами: prog и navig. Обе программы грузятся при включении системы. Главная программа с обычной графикой открывает главное окно и по СОМ-порту начинает принимать и обрабатывать информацию. Программа на OpenGL (однооконное в полный размер) скрыто, принимает информацию, обрабатывает, но не показывает.
При нажатии кнопки на главном окне (программа prog) оно прячется: this.hide(), навигационное окно (программа navig) открывается: this->show(). Таким образом, переключения на OpenGL выполняется. Главное окно действительно исчезает, появляется окно навигации (на OpenGL). Проблема в обратном переключении. Метод hide() для окна OpenGL не работает, minimize() тоже. Погасить окно OpenGL можно либо сняв приложение (например, Control+C, -это нам не подходит), либо закрасить окно черным цветом. Причем закрашивать нужно как минимум два раза, иногда даже три раза.
glearColor(0.0f, 0.0f, 1.0f, 1.0f);//задаем черный цвет
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//красим
swapBuffers();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//красим
swapBuffers();
Самая главная проблема: КАК ЗАСТАВИТЬ ОТКРЫТЬСЯ ОКНУ ОБЫЧНОГО ГРАФИЧЕСКОГО ПРИЛОЖЕНИЕ (программа prog). Иногда оно все таки открывается, но чаще всего нет.
3. В базовом классе QGLWidget есть двойная буферизация для вывода графики. То есть рисуем в одном буфере, а когда все нарисовали, делаем swapbuffer(), который меняет буфера местами. Тот, куда мы рисовали, отображается разом на экране, а второй с экрана перемещается в память для заполнение следующим кадром. По моим экспериментам получается, что буферов не два, а три. Я занес последовательно в буфера несколько кадров, затем занесение отключил, а swapbuffer() продолжает переключать раз в секунду, и я вижу три последних кадра по кругу, пока не остановлю систему.
4. В обычном графическом окне базового класса QWidget буферизации нет (я ее не нашел). Как я понимаю, физически буфер экрана в системе один. Но как эти два приложения заставить работать последовательно, чтобы сначала один рисовал на экране, затем, по команде другой?
5. Я провел такой эксперимент. Запустил обе программы, и заставил их рисовать одновременно. Но, так как обе рисуют раз в секунду (достаточно редко для глаза), я на экране вижу поочередное отображение окон обоих приложений.
5.1. Затем даю команду hide() обычному окну, -оно прячется, видно только окно openGL (оно раз в секунду продолжает рисовать свои кадры). Затем даю команду обычному окну открыться show(), -обычное окно появляется и начинается снова калейдоскоп поочередного отображения окон обоих приложений. То есть обычное окно правильно появляется и прячется.
5.2. Затем даю команду приложению OpenGL спрятаться: hide(). Как правило, после этой команды окно OpenGL замирает, а обычное графическое окно вообще не появляется.
Затем даю команду приложению OpenGL открыться: show(). Снова начинается калейдоскоп поочередного отображения окон обоих приложений.
6. Пытался команду спрятаться приложению OpenGL давать не через hide(), а через флаг, запрещающий в переопределенном методе рисования GLWidget::paintGL() что-либо рисовать. Поведение аналогичное.
7. Если во время калейдоскопа (поочередного отображения окон двух приложений) подгадать момент, сразу после фазы отображения обычного графического окна дать команду окну openGL скрыться (не перерисовывать себя), окно OpenGL дествительно исчезает, а окно обычной графики появляется. Но реализовать это программно, чтобы переключение выполнялось без осечек, не получается.