|
Вопрос # 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.
Приложение: Переключить в обычный режим- function WinProcStd(wnd: hwnd; msg: integer; wparam: wparam;
- lparam: lparam): lresult; stdcall;
- begin
- Result := 0;
- if Assigned(fVEApiWindow.OnMessage) then fVEApiWindow.OnMessage;
- case msg of
- WM_ACTIVATE: // Watch For Window Activate Message
- begin
- if (wParam <> 0) then // Check Minimization State
- fVEApiWindow.Active := TRUE // Program Is Active
- else
- fVEApiWindow.Active := FALSE; // Program Is No Longer Active
- exit;
- end;
- WM_PAINT :
- begin
- if Assigned(fVEApiWindow.OnPaint) then fVEApiWindow.OnPaint;
- end;
- WM_CLOSE:
- begin
- fVEApiWindow.Exit := true;
- exit;
- end;
- WM_DESTROY:
- begin
- fVEApiWindow.Exit := true;
- postquitmessage(0);
- exit;
- end;
- WM_SYSCOMMAND:
- begin
- case (wParam) of // Check System Calls
- SC_SCREENSAVE: begin result := 0; exit; end; // Screensaver Trying To Start?
- SC_MONITORPOWER: begin result := 0; exit; end; // Monitor Trying To Enter Powersave?
- // Prevent From Happening
- end;
- if Assigned(fVEApiWindow.OnRestore) then fVEApiWindow.OnRestore;
- end;
- WM_KEYDOWN:
- begin
- fVEApiWindow.KeyState[wParam] := true;
- if Assigned(fVEApiWindow.OnKeyPress) then fVEApiWindow.OnKeyPress(wParam, true);
- exit;
- end;
- WM_KEYUP:
- begin
- fVEApiWindow.KeyState[wParam] := false;
- if Assigned(fVEApiWindow.OnKeyPress) then fVEApiWindow.OnKeyPress(wParam, false);
- exit;
- end;
- WM_SIZE:
- begin
- if Assigned(fVEApiWindow.OnResize) then fVEApiWindow.OnResize;
- exit;
- end;
- end;
- result := defwindowproc(wnd,msg,wparam,lparam);
- 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% - так как два проца. А Вы грузите полностью один
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|