Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 045

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Пишу нечто вроде игрового движка (OpenGL). Проблемма с окнами Api, а именно с получением сообщений. Вот основной цикл.

while true do
begin
Window.ProcessMessages;
Paint;
if Window.Exit then break;
end;

function TVEApiWindow.ProcessMessages: Boolean;
begin
if GetMessage(fmmsg,0,0,0) then
begin
translatemessage(fmmsg);
dispatchmessage(fmmsg);
result := true;
end else
Result := false;
end;

Если все делать именно так, то появляются проблеммы с перерисовкой, а если водить мышью, то приложение грузит проц на 50-60%. Если делать так :

function TVEApiWindow.ProcessMessages: Boolean;
begin
if PickMessage(fmmsg,0,0,0, PM_REMOVE) then
begin
translatemessage(fmmsg);
dispatchmessage(fmmsg);
result := true;
end else
Result := false;
end;

То перерисовка идёт нормально, но проц стабильно грузиться на 50-60%.

Собственно вопрос : Как сделать, чтобы шло нармальное получение сообщений и чтобы перерисовка шла стабильно и постоянно?

В приложении код WinProc.

Приложение:
  1. function WinProcStd(wnd: hwnd; msg: integer; wparam: wparam;
  2. lparam: lparam): lresult; stdcall;
  3. begin
  4. Result := 0;
  5. if Assigned(fVEApiWindow.OnMessage) then fVEApiWindow.OnMessage;
  6. case msg of
  7. WM_ACTIVATE: // Watch For Window Activate Message
  8. begin
  9. if (wParam <> 0) then // Check Minimization State
  10. fVEApiWindow.Active := TRUE // Program Is Active
  11. else
  12. fVEApiWindow.Active := FALSE; // Program Is No Longer Active
  13. exit;
  14. end;
  15. WM_PAINT :
  16. begin
  17. if Assigned(fVEApiWindow.OnPaint) then fVEApiWindow.OnPaint;
  18. end;
  19. WM_CLOSE:
  20. begin
  21. fVEApiWindow.Exit := true;
  22. exit;
  23. end;
  24. WM_DESTROY:
  25. begin
  26. fVEApiWindow.Exit := true;
  27. postquitmessage(0);
  28. exit;
  29. end;
  30. WM_SYSCOMMAND:
  31. begin
  32. case (wParam) of // Check System Calls
  33. SC_SCREENSAVE: begin result := 0; exit; end; // Screensaver Trying To Start?
  34. SC_MONITORPOWER: begin result := 0; exit; end; // Monitor Trying To Enter Powersave?
  35. // Prevent From Happening
  36. end;
  37. if Assigned(fVEApiWindow.OnRestore) then fVEApiWindow.OnRestore;
  38. end;
  39. WM_KEYDOWN:
  40. begin
  41. fVEApiWindow.KeyState[wParam] := true;
  42. if Assigned(fVEApiWindow.OnKeyPress) then fVEApiWindow.OnKeyPress(wParam, true);
  43. exit;
  44. end;
  45. WM_KEYUP:
  46. begin
  47. fVEApiWindow.KeyState[wParam] := false;
  48. if Assigned(fVEApiWindow.OnKeyPress) then fVEApiWindow.OnKeyPress(wParam, false);
  49. exit;
  50. end;
  51. WM_SIZE:
  52. begin
  53. if Assigned(fVEApiWindow.OnResize) then fVEApiWindow.OnResize;
  54. exit;
  55. end;
  56. end;
  57. result := defwindowproc(wnd,msg,wparam,lparam);
  58. end;


Виталий Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Виталий (статус: 2-ой класс)
Вопрос отправлен: 4 ноября 2008, 13:37
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 6; последнее сообщение — 4 ноября 2008, 15:16; участников в обсуждении: 2.
Вадим К

Вадим К (статус: Академик), 4 ноября 2008, 13:44 [#1]:

А вы посчитайте, сколько кадров в секунду получается у вас. Если рисуете полноэкранную картинку, 1024х768х32 и 50 кадров в секунду, то такая нагрузка процессора вполне нормальная.
Галочка "подтверждения прочтения" - вселенское зло.
Виталий

Виталий (статус: 2-ой класс), 4 ноября 2008, 14:02 [#2]:

102 кадра в секунду. я уже проверял, проблемма не в функции рисования, а с сообщениями. Если сделать так

function TVEApiWindow.ProcessMessages: Boolean;
begin
if PeekMessage(fmmsg,0,0,0, PM_REMOVE) then
begin
translatemessage(fmmsg);
dispatchmessage(fmmsg);
result := true;
end else
Result := false;
end;

и закомментировать перерисовку, то все равно загрузка проца на 50-60%, но не рисуется ничего, а если раскомм., то нагрузка совршенно не меняется

малость описался кстати PeekMessage
Вадим К

Вадим К (статус: Академик), 4 ноября 2008, 14:18 [#3]:

Попробуйте сделать так. Сообщения выбирать через GetMessage. А также паралельно завести таймер, который с заданной частотой будет генерить событие WM_Paint. Отдельно ставим обработчик этого события и там рисуем (и только там). Хитро, но будет работать.
Галочка "подтверждения прочтения" - вселенское зло.
Виталий

Виталий (статус: 2-ой класс), 4 ноября 2008, 14:50 [#4]:

Да всё работает, но вот щяс реально проблемма в отрисовке. Вот скажите как может грузить на 50% двухъядерный проц вот такая процедура :

procedure Paint;
begin
Render.BeginRender;

glClearColor (0.85, 0.75, 0.5, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity;

glRotatef(anglex, 1, 0, 0);
glRotatef(angley, 0, 1, 0);

glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex2f(0, 0.5);
glColor3f(0,1,0);
glVertex2f(-0.5, -0.5);
glColor3f(0,0,1);
glVertex2f(0.5, -0.5);
glEnd;

Render.EndRender;
end;
Виталий

Виталий (статус: 2-ой класс), 4 ноября 2008, 14:54 [#5]:

Всё уже разобрался! Благодарю за помощь. Если кому интересно, то проблемма была в отрисовке : каждый цикл переключались устройства, и из-за этого была загрузка.
Вадим К

Вадим К (статус: Академик), 4 ноября 2008, 15:16 [#6]:

а 50% - так как два проца. А Вы грузите полностью один:)
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:44
Выполнено за 0.03 сек.