Programm ruckelt wenn es lustig ist
-
Der Titel klingt vielleicht komisch, aber es ist eigentlich genauso: Mein WinAPI Programm lief eigentlich immer ganz gut, doch plötzlich ruckelt es total, obwohl ich nichts geändert hatte, ich hab erstmal ne Nacht drüber geschlafen, am nächsten Tag war das Problem auch weg. Im Laufe des Tages kam es aber wieder, und es verschwand, als ich ShowCorsur(false); auskommentiert habe. Dann hab ich die Kommentarstriche weggemacht und nochmal compiliert, da war trotzdem alles wieder in Ordnung. Manchmal gibt es auch andere Fehler, z.B. ist das Fenster nicht mehr Maximiert, obwohl ich das eingestellt habe, dann compilliere ich nochmal, und alles ist wieder in Ordnung. Ich benutze DevC++ 5 und mein Programm macht eigentlich nur ein paar simple Grafikausgaben, die manchmal aber total viel CPUAuslastung ziehen und damit das Programm ruckeln lassen. Mein Programm benutzt DoubleBuffering, aber das hat eigentlich immer funktioniert, und den Fehler kann ich ja nicht ausmachen, weil er manchmal kommt und genauso schnell wieder verschwindet...

mfg.
-
zeig uns das programm und dessen quelltext und wir schauen mal nach.
-
Das Problem könnte bei WM_PAINT liegen.
Hast Du zufällig auf BeginPaint und EndPaint verzichtet?Cya
-
FlanDerZ schrieb:
Das Problem könnte bei WM_PAINT liegen.
Hast Du zufällig auf BeginPaint und EndPaint verzichtet?Cya
case WM_PAINT: hdc = BeginPaint (hwnd,&ps); SwapBackBuffer(); EndPaint (hwnd, &ps); return (0); break;Hier der Quellcode zum DoubleBuffering (hab ich nicht selber geschrieben):
#ifndef WND_BGCOLOR #define WND_BGCOLOR (HBRUSH) GetStockObject(LTGRAY_BRUSH) #endif #ifndef EIGENEDOUBLEBUFFERINGH #define EIGENEDOUBLEBUFFERINGH struct BUFFER // This is our back buffering structure { HWND hwnd; // This holds the current window's handle RECT scrnRect; // This holds the client rectangle of the window HANDLE hCompBitmap; // This holds the compatible bitmap for the backbuffer HANDLE hOldBitmap; // This is used for storage to free when the program quits HANDLE hOldBitmap2; // This is used as storage to swap between selected bitmaps when using selectObject() HDC hdcFront; // This is the front buffer (The part we see) HDC hdcBack; // This is the back buffer (the part we draw to, then flip) HDC hdcBitmap; // This is a temp buffer to swap the bitmap back and forth from }; BUFFER gBuffer; BUFFER *pBuffer = &gBuffer; void CreateDoubleBuffering(HWND hwnd) { pBuffer->hwnd = hwnd; GetClientRect(hwnd, &(pBuffer->scrnRect)); pBuffer->hdcFront = GetDC(pBuffer->hwnd); pBuffer->hdcBack = CreateCompatibleDC(pBuffer->hdcFront); pBuffer->hdcBitmap = CreateCompatibleDC(pBuffer->hdcFront); pBuffer->hCompBitmap = CreateCompatibleBitmap(pBuffer->hdcFront, pBuffer->scrnRect.right, pBuffer->scrnRect.bottom); pBuffer->hOldBitmap = (HBITMAP)SelectObject(pBuffer->hdcBack, pBuffer->hCompBitmap); } void zeigeBitmap(HBITMAP hBitmap, int x, int y) { pBuffer->hOldBitmap2 = (HBITMAP) SelectObject(pBuffer->hdcBitmap, hBitmap); BitBlt(pBuffer->hdcBack, x, y, pBuffer->scrnRect.right, pBuffer->scrnRect.bottom, pBuffer->hdcBitmap, 0, 0, SRCCOPY); SelectObject(pBuffer->hdcBitmap, pBuffer->hOldBitmap2); } void ClearScreen() { FillRect(pBuffer->hdcBack, &pBuffer->scrnRect, WND_BGCOLOR); } void SwapBackBuffer() { BitBlt(pBuffer->hdcFront, pBuffer->scrnRect.left, pBuffer->scrnRect.top, pBuffer->scrnRect.right, pBuffer->scrnRect.bottom, pBuffer->hdcBack, 0, 0, SRCCOPY); } void SwapUmgekehrt() { BitBlt(pBuffer->hdcBack, pBuffer->scrnRect.left, pBuffer->scrnRect.top, pBuffer->scrnRect.right, pBuffer->scrnRect.bottom, pBuffer->hdcBack, 0, 0, DSTINVERT); BitBlt(pBuffer->hdcFront, pBuffer->scrnRect.left, pBuffer->scrnRect.top, pBuffer->scrnRect.right, pBuffer->scrnRect.bottom, pBuffer->hdcBack, 0, 0, SRCCOPY); } #endif
-
Boah, Schwede...was für nen Aufwand für Double-Buffering...
Nimm lieber das: http://home.arcor.de/ksros/gfxlib
CU
-
FlanDerZ schrieb:
Boah, Schwede...was für nen Aufwand für Double-Buffering...
Nimm lieber das: http://home.arcor.de/ksros/gfxlib
CU
Geht die denn auch für Dev-C++ 5??? Keine Ahnung, aber ich bekomme da Fehlermeldungen und im Toturial finde ich keine Antworten auf meine Fragen... Außerdem finde ich meine Möglichkeit ziemlich leicht, überhaupt kein Aufwand. Aber es hat immer funktioniert, bis jetzt...

-
Und wenn du das rausnimmst? Ruckel es dann immer noch? Kannst du eventuell den ganzen Quelltext posten?
-
algo schrieb:
Und wenn du das rausnimmst? Ruckel es dann immer noch? Kannst du eventuell den ganzen Quelltext posten?
Das Problem ist ja, das im Moment auch Flüßigläuft, ohne dass ich es rausnehme. Es läuft ja nur nach Lust und Laune nicht. Der Quellcode ist sehr riesig, mit vielen eigenen Headerdateien, deswegen kann ich ihn nicht posten.
-
In WM_PAINT einen BitBlt() uebers ganze Fenster zu machen, ist der Grund. BitBlt() kann bei sowas bei grossen Fenstern sehr lange dauern, da ja viel Speicher bewegt werden muss (bei 32-Bit Farbtiefe und 1280 x 1024 Aufloesung, waeren das bspw. bei einem Fullscreen-Fenster 1280 x 1024 x 4 Bytes, also ca. 4 MB).
WM_PAINT wird naemlich sehr oft aufgerufen. Besser waere es, mit SetTimer() einen Timer zu setzen mit mindestens 1/10 sec. (100 ms) Abstand (besser 1/5 sec., 200 ms), und in WM_TIMER dann GetDC() / ReleaseDC() verwenden und reinblitten.
WM_PAINT macht dann nur noch BeginPaint()/EndPaint() und setzt ggf. noch ein Update-Flag (dadurch zeichnest Du in WM_TIMER dann nur noch, wenn tatsaechlich noetig).
Wenn Du schnelles DoubleBuffering benoetigst, nimm lieber DirectX Graphics statt GDI.
-
Power Off schrieb:
In WM_PAINT einen BitBlt() uebers ganze Fenster zu machen, ist der Grund. BitBlt() kann bei sowas bei grossen Fenstern sehr lange dauern, da ja viel Speicher bewegt werden muss (bei 32-Bit Farbtiefe und 1280 x 1024 Aufloesung, waeren das bspw. bei einem Fullscreen-Fenster 1280 x 1024 x 4 Bytes, also ca. 4 MB).
WM_PAINT wird naemlich sehr oft aufgerufen. Besser waere es, mit SetTimer() einen Timer zu setzen mit mindestens 1/10 sec. (100 ms) Abstand (besser 1/5 sec., 200 ms), und in WM_TIMER dann GetDC() / ReleaseDC() verwenden und reinblitten.
WM_PAINT macht dann nur noch BeginPaint()/EndPaint() und setzt ggf. noch ein Update-Flag (dadurch zeichnest Du in WM_TIMER dann nur noch, wenn tatsaechlich noetig).
Wenn Du schnelles DoubleBuffering benoetigst, nimm lieber DirectX Graphics statt GDI.
Bei meinem Programm handelt es sich um ein Spiel, deswegen brauche ich ja mindestens so an die 60 fps nicht? Momentan arbeite ich mit 100 fps, also 100 mal BitBlt in der Sekunde, ja das ist schon ziemlich viel, aber würde es mit einem teimer der nur 10 fps hat nicht total sichtbar ruckeln?
Dann hab ich noch das Problem, das es manchmal einwandfrei funktioniert, woran könnte das liegen??? Das muss ja irgentwas mit dem Speicher zu tun haben...
mfg.
PS: Ich glaub ich schau mir DirectX oder OpenGL bald mal an, bis jetzt sind meine Spiele nicht sehr aufwendig...
-
Schonmal die Speicher- und CPU-auslastung während des Spiels beobachtet?
-
the_alien schrieb:
Schonmal die Speicher- und CPU-auslastung während des Spiels beobachtet?
jo:
optimal:
cpu = 0 - 13 %;wenns lustig ist:
cpu = 90 - 100 %;Aber wie kann ich die Speicherauslastung überwachen?
-
joomoo schrieb:
Aber wie kann ich die Speicherauslastung überwachen?
Kannst du dir doch auch im Taskmanager anschauen

-
flenders schrieb:
joomoo schrieb:
Aber wie kann ich die Speicherauslastung überwachen?
Kannst du dir doch auch im Taskmanager anschauen

Und wo im Taskmanager? (XP Pro)
-
Systemleistung -> physikalischer Speicher
-
the_alien schrieb:
Systemleistung -> physikalischer Speicher
Da seh ich ja nur den gesamten Speicher, ich meine nur für das Programm, hab ich aber schon eben selber gefunden. Die Speicherauslastung ist ungefähr 1000k, ändert sich auch net.
-
wichtiger wären ja wohl die GDI Objekte.
-
gdi- schrieb:
wichtiger wären ja wohl die GDI Objekte.
wie meinst du das?
-
joomoo schrieb:
gdi- schrieb:
wichtiger wären ja wohl die GDI Objekte.
wie meinst du das?
wieviel gdi objekt dein programm benutzt bzw. schlecht wäre es wenn die zahl ständig steigt.
taskmananger-->ansicht-->spalten wählen
-
miller_m schrieb:
joomoo schrieb:
gdi- schrieb:
wichtiger wären ja wohl die GDI Objekte.
wie meinst du das?
wieviel gdi objekt dein programm benutzt bzw. schlecht wäre es wenn die zahl ständig steigt.
taskmananger-->ansicht-->spalten wählenliegt bei 11, ändert sich nicht.