Performanz beim Verschieben eines Fensters
-
MSDN schrieb:
A window may receive internal paint messages as a result of calling RedrawWindow with the RDW_INTERNALPAINT flag set. In this case, the window may not have an update region. An application should call the GetUpdateRect function to determine whether the window has an update region. If GetUpdateRect returns zero, the application should not call the BeginPaint and EndPaint functions.
War mir auch neu...
Hab' auch noch kein Programm gesehen dass sich darum schert
-
Hey,
danke erstmal! Ich habe bisher diesen Code im WM_PAINT. Ich google mal die 3 Begriffe, die ihr genannt habt, bis dahin könnt ihr ja mal schaun, was man optimieren kann
Bin halt relativ neu auf dem Gebiet. Hatte vorher mein TCanvas und ne Form bei der ich DoubleBuffered auf true gesetzt hab
case WM_PAINT: { HBITMAP bmp; bmp = CreateDIBSection(NULL, bmpInfo, DIB_RGB_COLORS, (void**) &rgbValues, NULL, 0); for (int y = 0; y < width; y++) { const int lineStart = y * rowLength ; for (int x = 0; x < height; x++) { int mandelValue = mandelbrot((double)(x - width / 2) * zoom + dx, (double)(y - height / 2) * zoom - dy, 255); int pixelIndex = lineStart + x * 3; rgbValues[pixelIndex] = mandelValue; rgbValues[pixelIndex + 1] = mandelValue; rgbValues[pixelIndex + 2] = mandelValue; } } HDC hdc = GetDC(hWnd); SetDIBitsToDevice(hdc, 0, 0, width, height, 0, 0, 0, height, rgbValues, bmpInfo, DIB_RGB_COLORS); ReleaseDC(hWnd, hdc); DeleteObject(bmp); return 0; }
PS: Der Code stammt von einem Freund, ich selbst habe nie mit CreateDIBSection() und SetDIBitsToDevice() gearbeitet. Ist aber jedenfalls schneller als SetPixel
-
Dieser Code gehört in die Sektion: FALSCH!
Wenn dies ein WM_PAINT Handler sein soll, dann Fehlen hier die grundsätzlichen Funktionen BeginPaint und EndPaint. Dadurch wird auch der falsche DC verwendet.
Ein Fall für: Lies bitte mal die Grundlagen zur Windows Programmierung...
-
hustbaer schrieb:
Frolo schrieb:
Die Mandelbrotmenge wird natürlich im WM_PAINT gezeichnet
Hoffentlich nur gezeichnet, und nicht auch berechnet
-
Erstmal kenne ich die Grundlagen, dieser Code war eher eine Antwort auf "Wie mache ich es schneller" und so nebenbei macht der Code genau das, was er soll also verstehe ich nicht, was das Problem ist. Wie sollte das denn eurer Meinung nach aussehen?
Achja und wieso sollte der falsche DC verwendet werden? Ich bekomm genau den richtigen...
Zweitens stimmt das mit dem Berechnen. Ich berechne derzeit die Mandelbrotmenge komplett im WM_PAINT Event. Das Problem ist nur, dass ich nicht weiß, wo ich sie sonst berechnen soll. Ich meine ich könnte alle paar Millisekunden die Bitmap berechnen lassen, aber sollte man das so machen?
-
Frolo schrieb:
Erstmal kenne ich die Grundlagen, dieser Code war eher eine Antwort auf "Wie mache ich es schneller" und so nebenbei macht der Code genau das, was er soll also verstehe ich nicht, was das Problem ist. Wie sollte das denn eurer Meinung nach aussehen?
Achja und wieso sollte der falsche DC verwendet werden? Ich bekomm genau den richtigen...
Der Code macht nicht was er soll, und es ist der falsche DC.
Deine Ansicht wird nie valide, d.h. WM_PAINT wird immer gefeuert, obwohl evtl. nichts neu zu berechnen ist.Und ja. Berechnen, würde ich in einem Workerthread und "bei Bedarf", zeichnen...
-
Okay danke dir für die Antwort (die viel konstruktiver ist). Verstehe ich das richtig, das WM_PAINT immer ausgeführt wird, wenn ich es nicht ordnungsgemäß mit BeginPaint und EndPaint ausführe? Ich dachte immer ich kann das genauseo mit GetDC() machen.
Und deiner Meinung nach soll die Bitmap in einem Thread immer wieder neu berechnet werden. Geht das nicht verdammit auf die PC Leistung?
-
Die Bitmap sollte nur dann neuberechnet werden, wenn sich auch etwas daran ändert.
Und bei der WM_PAINT Nachricht solltest du daher nur diese Bitmap anzeigen (anstatt jedesmal die Berechnung auszuführen).
Ob du die Berechnung wirklich in einen eigenen Thread auslagern musst, kommt drauf an, ob die Berechnung länger als ca. 50ms dauert.
-
Martin Richter schrieb:
Und ja. Berechnen, würde ich in einem Workerthread und "bei Bedarf", zeichnen...
Idealerweise zeichnet man das Apfelmännchen in ein Offscreen-Image und blittet das dann bei WM_PAINT ins Fenster.
BeginPaint
BitBlt
EndPaint... mehr muss im WM_PAINT-Handler nicht stehen.
-
Frolo schrieb:
Hey,
danke erstmal! Ich habe bisher diesen Code im WM_PAINT. Ich google mal die 3 Begriffe, die ihr genannt habt, bis dahin könnt ihr ja mal schaun, was man optimieren kann
Bin halt relativ neu auf dem Gebiet. Hatte vorher mein TCanvas und ne Form bei der ich DoubleBuffered auf true gesetzt hab
[code="cpp"]case WM_PAINT:
{HBITMAP bmp;
bmp = CreateDIBSection(NULL, bmpInfo, DIB_RGB_COLORS, (void**) &rgbValues, NULL, 0);
...Leider fehlen essentielle Teile um das ganze auszuprobieren ...
Wenn ich das richtig sehe wird CreateDIBSection() verwendet um Speicher für die Pixel zu besorgen.
Dafür müsste aber in bmpinfo die Groesse der Bitmap stehen.- Woher kommen width und height ? Sind die konstant ?
->Im Programm werden die Begriffe vertauscht verwendet
- bmpInfo müsste dann damit initialisiert werden- Wenn das (vermutlich) alles konstant ist, wieso wird dann bei jedem
Zeichnen immer wieder eine neue BitMap erzeugt und gelöscht ?Das Erzeugen der Bitmap sowie das Berechnen der Grafik gehört definitiv nicht nach WM_PAINT.
Wenn sich weder Grösse noch Berechnung ändern könnte man das in InitInstance oder WM_CREATE
erledigen. Sollte sich die Grafik mit der Fenstergroesse aendern koennte man es mit der entsprechenden
Message neu machen.Es wäre nett wenn Du die fehlenden Variablen sowie die Funktion mandelbrot() noch referenzieren koenntest.