Страница 1 из 1

Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 23.02.2014 11:40:35
ya_vanka
Добрый день.

В моем кроссплатформенном проекте большая часть реализована на OpenGL (основное окно визуализации информации). Для создания окон и контекстов OpenGL используется библиотека GLFW.
А вот диалоговые окна (настройка параметров приложения) хочу пока оставить на LCL.

У библиотеки GLFW, которая создает окно для OpenGL есть своя обработка сообщений с вызовом callback-функций:

Код: Выделить всё
while not Terminated do
begin
  ...
  glfwPollEvents;
end;



И для работы окон с LCL тоже нужна своя обработка сообщений:

Код: Выделить всё
while not Terminated do
begin
  ...
  Application.ProcessMessages;
end;



В моем случае надо их как-то скрестить. Я сделал так:

Код: Выделить всё
Application.Initialize;

  StartUpPanel := TStartUpPanel.Create(nil);
  StartUpPanel.Show;

  OpenSaveDlgForm := TOpenSaveDlgForm.Create(nil);
  OpenSaveDlgForm.Show;

  Application.ProcessMessages;

  OpenSaveDlgForm.Hide;

  Application.ProcessMessages;

  ...

  StartUpPanel.Hide;

  while not Terminated do
  begin
    ...
    glfwPollEvents;
    Application.ProcessMessages;
  end;

  ...

  StartUpPanel.Free;
  OpenSaveDlgForm.Free;



Но есть проблемы, которые проявляются только под Linux:

1. Примерно в половине случаев (может меньше, но не суть) на старте программа подвисает. Появляется первое окно с LCL (просто черный прямоугольник) и все. В остальных случаях все работает как надо.

2. Если перед использованием окна с LCL не выполнить последовательность
Код: Выделить всё
  OpenSaveDlgForm.Show;

  Application.ProcessMessages;

  OpenSaveDlgForm.Hide;

то при вызове диалога (OpenSaveDlgForm.Show) этот диалог подвиснет. Указанная последовательность вроде спасает, но как-то не красиво. Такое ощущение, что окно и его контролы создаются не в момент OpenSaveDlgForm := TOpenSaveDlgForm.Create(nil), а когда вызывается OpenSaveDlgForm.Show.

3. При закрытии программы процессор грузится целиком и так продолжается от 5 до 30 секунд.


Голову сломал уже, не знаю что с этим делать.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 23.02.2014 12:04:01
Дож
1. Зачем использовать обработчик сообщений GLFW, если уже есть LCL? Я ведь правильно понимаю, что и тот, и другой ловят одни и те же оконные сообщения?
2. Что будет, если в линуксе не использовать сообщений GLFW?

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 23.02.2014 12:28:39
Mirage
Вероятно, обработчик GLFW еще и буфера свапает.
Я использовал GLUT и FreeGLUT. Последний является надстройкой над первым, позволяя прицеплять свои обработчики для инициализации, отрисовки, переинициализации контекста и т.д. Гораздо больший контроль.
Все работает как отдельно, так и под VCL. С LCL не пробовал.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 23.02.2014 12:36:08
Дож
Вероятно, обработчик GLFW еще и буфера свапает.


Для свапа буферов есть функция glfwSwapBuffers, внутри которой запускается обработчик сообщений, но это отключается настройкой GLFW_AUTO_POLL_EVENTS.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 12:57:11
ya_vanka
Зачем использовать обработчик сообщений GLFW, если уже есть LCL? Я ведь правильно понимаю, что и тот, и другой ловят одни и те же оконные сообщения?


Я стал использовать GLFW так как он создает окна и контекст OpenGL для них и под Windows и под Unix.
Да, LCL тоже ловит сообщения окна, но вот создать контекст OpenGL для уже созданного LCL окна в Unix (насколько я понимаю) невозможно. Т.е. под Unix при создании окна надо указывать, что оно будет использоваться для OpenGL.

Если кто знает как создать контекст OpenGL для уже созданного LCL окна в Unix, то расскажите.

Добавлено спустя 4 минуты 15 секунд:
Вероятно, обработчик GLFW еще и буфера свапает.


Нет, в версии 3, которую я использую, glfwPollEvents не вызывается из glfwSwapBuffers.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 14:24:01
zub
>>Если кто знает как создать контекст OpenGL для уже созданного LCL окна в Unix, то расскажите.
Странное желание, почему нужно именно так, а не просто использовать TOpenGLContext?
Но даже если нужно для уже созданного окна, то имхо это можно стелать и в линуксе, по крайней мере для qt

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 14:35:12
ya_vanka
Странное желание, почему нужно именно так, а не просто использовать TOpenGLContext?


Например, используя TOpenGLContext я не могу задать произвольный формат пиксела, версию контекста.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 14:39:11
Дож
Я стал использовать GLFW так как он создает окна и контекст OpenGL для них и под Windows и под Unix.
Да, LCL тоже ловит сообщения окна, но вот создать контекст OpenGL для уже созданного LCL окна в Unix (насколько я понимаю) невозможно. Т.е. под Unix при создании окна надо указывать, что оно будет использоваться для OpenGL.


Для создания контекста OpenGL разве нужен обработчик сообщений GLFW?

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 14:45:54
ya_vanka
Дож

Нет, для создания контекста OpenGL обработчик не нужен.
Но если я создал окно с помощью GLFW разве я могу его подцепить к обработчику сообщений LCL?

Добавлено спустя 1 минуту 4 секунды:
Mirage

Я использовал GLUT и FreeGLUT. Последний является надстройкой над первым, позволяя прицеплять свои обработчики для инициализации, отрисовки, переинициализации контекста и т.д. Гораздо больший контроль.
Все работает как отдельно, так и под VCL. С LCL не пробовал.


Раз не пробовали с LCL, то, видимо, и под Unix не использовали. А у меня под Unix проблемы. В Windows все работает.

Но все равно посмотрел бы примерчик связки VCL и FreeGLUT.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 15:05:18
zub
Формат пиксела вроде там настраивается, возможно не полностью, но чтото есть. С версией да, глухо.
Может лучше доработать TOpenGLContext и оформить багрепорт с патчем? чем использовать непонятно какие схемы?

>>Но если я создал окно с помощью GLFW разве я могу его подцепить к обработчику сообщений LCL?
по идее - нет не можешь, хотя возможно в некоторых окружениях это и будет работать

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 24.02.2014 17:19:30
Mirage
ya_vanka писал(а):Раз не пробовали с LCL, то, видимо, и под Unix не использовали. А у меня под Unix проблемы. В Windows все работает.


Немного неверно выразился. GLUT я использовал как раз чтобы окно создать кроссплатформенно, в которое потом можно рендерить и сообщения системные тоже вроде оно обрабатывает - реакция на взаимодействием с неклиентской частью окна и т.п.
Для VCL GLUT не нужен, т.к. он сам окно создает и сообщения обрабатывает.
Собственно чтобы под линухом работало GLUT и использовал. Под линухом мне GUI не нужен был.
Вот модуль работы с GLUT/FreeGLUT:
https://github.com/casteng/base/blob/de ... itGLUT.pas

FreGLUT хорош тем, что его как раз можно подключить к своему циклу. В VCL/LCL вызовы его обработчиков можно посадить на таймер или onIdle.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 26.02.2014 13:55:31
ya_vanka
А можно интересно сделать отдельное приложение (LCL) с формами диалогов, запускать его из главного приложения (которое через GLFW работает) и каким-то образом обмениваться информацией с формами диалогов?

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 26.02.2014 18:07:02
Mirage
Можно, конечно. IPC в помощь.
Только сдается мне это как из пушки по воробьям. Конечная цель какая?

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 27.02.2014 21:44:41
ya_vanka
Конечная цель все та же. Обеспечить взаимодействие LCL и Glfw окон.

Скачал файлы вашего проекта, но пока еще не успел пристально посмотреть. А free glut умеет работать с несколькими окнами и мониторами? В моем проекте это необходимо.

Re: Совместная работа двух циклов обработки сообщений

СообщениеДобавлено: 28.02.2014 23:30:02
Mirage
Взаимодействие разное бывает.
Непонятно какое взаимодействие требуется от окна, в котором Opengl.

Насчет нескольких окон и мониторов лучше в документации посмотреть. Я не пробовал.
Хотя что ему до кол-ва мониторов?