Warum ist SetPixel(); so langsam?`
-
Hi, ich wollte mir ein Gradient Rect zeichnen lassen, indem ich mir 2 for-Schleifen erstelle und dann die Pixel mit den RGB Werten zeichne. Das Problem ist nur, dass er bei einer Breite von 256 x 256 Pixeln total langsam wird. Liegt es daran, weil die Funktion zu oft aufgerufen wird? Wie wird dann bitte Rectangle(); realisiert, dort werden ja auch Pixel gezeichnet. Weiß jemand, wie ich Rechtecke mit dem Gradient Rect Effekt benutzen kann, ohne die vorgefertigte GradientRect(); Funktion zu benutzen? Das liegt daran, weil ich mir z.B. auch Farbübergänge bei Linien und Kreisen benutzen möchte. Wie machen es dann die von der SDL, Allegro und DirectX solche Farbübergänge zu erzielen?
-meep
-
Es ist einfach mit verdammt viel Verwaltungsaufwand verbunden, etwas im Grafikspeicher zu verändern. Und der Aufwand bleibt fast immer gleich, egal ob du 1 Pixel oder 100 umänderst.
Stell dir vor, deine Sparkasse will jedesmal 80 Cent von dir, wenn du Geld überweisen möchtest. Dann ist das natürlich ok, wenn du mal 100€ auf einmal überweisen willst. Aber wenn du 100x einen Euro überweist, dann wirst du bald arm.
Deshalb bearbeitet man auch die Grafik möglichst im Arbeitsspeicher und kopiert sie dann in einem Rutsch. Z.B mit BitBlt.
-
Ja so habe ich mir das beinahe gedacht aber wie genau löse ich das mit der BitBlt Funktion? Damit habe ich bisher nur Bitmaps gezeichnet.
-meep
-
Wenn du sowieso ein komplettes Rechteck auf den Schirm malen willst kannst du SetDIBitsToDevice verwenden.
Dazu "malst" du deine Pixel in ein normales Array im Speicher (DWORD Array, ein DWORD = 1 Pixel). Dann füllst du ne BITMAPINFO Struktur aus die das 32 Bit BGRA Format beschreibt, und rufst SetDIBitsToDevice auf.
void foo() { DWORD pixels[256*256]; // pixels anfüllen HDC dc = ...; // woher auch immer // BITMAPINFO ausfüllen BITMAPINFO bi = {0}; bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = 256; bi.bmiHeader.biHeight = 256; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; // auf den Bildschirm kopieren SetDIBitsToDevice( dc, destX, destY, 256, // width 256, // height 0, // source X 0, // source Y 0, 256, pixels, &bi, 0 ); }Hab jetzt nicht versucht das zu compilieren, aber grundsätzlich geht das so.