Bitmaps, hDC & Co
-
Probiers mal so (für n Bitmaps):
// irgendwo statisch oder global: HBITMAP hBitmap[n]; HDC hdcBitmap[n]; // irgendwo am Anfang des Programms: HDC hdc = GetDC(NULL); hBitmap[0] = LoadImage(...); hdcBitmap[0] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[0], hBitmap[0]); //... hBitmap[n] = LoadImage(...); hdcBitmap[n] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[n], hBitmap[n]); ReleaseDC(NULL, hdc); // ab hier kannst du die Bitmaps über hdcBitmap[i] ansprechen
Wichtig die Bitmaps und Gerätekontexte musst du später wieder freigeben, also:
DeleteDC(hdcBitmap[0]); //... DeleteDC(hdcBitmap[n]); DeleteObject(hBitmap[0]); //... DeleteObject(hBitmap[n]);
(Normalerweise sollte man einen Gerätekontext zwar so zurückgeben wie man ihn bekommen hat (also die vorigen Gdi-Objekte wieder hineinselektieren), aber so sollte es für den Anfang auch gehen.)
Wenn du sehr viele Bitmaps hast geht obiger Ansatz mit eigenem DC für jedes Bitmap evtl. nicht (ich weiß nicht wieviele DCs Windows bereitstellt, Windows XP wahrscheinlich aber genug).
Dann musst du vor jedem zeichnen eines Bitmaps, dieses in einen DC selektieren, zeichnen und dann das nächste selektieren, zeichnen, usw.
-
also nach:
// irgendwo statisch oder global: HBITMAP hBitmap[n]; HDC hdcBitmap[n]; // irgendwo am Anfang des Programms: HDC hdc = GetDC(NULL); hBitmap[0] = LoadImage(...); hdcBitmap[0] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[0], hBitmap[0]); //... hBitmap[n] = LoadImage(...); hdcBitmap[n] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[n], hBitmap[n]); ReleaseDC(NULL, hdc); // ab hier kannst du die Bitmaps über hdcBitmap[i] ansprechen
kann ich die einzelnen Bitmaps mit hdcBitmap[irgendeine] ansprechen...
muss ich dann SelectObejct(hDC_mem,hdcBitmap[0])
und danach BitBlt(hDC,,,,,,hDC_mem);oder nur BitBlt(hDC,,,,hdcBitmap[0]);
schreiben...?
ich hoffe die bleiben dann darin gespeichert und ich kann sie dann mehrere Male verwenden...(das sie ned scho wieder verschwinden *grml*)
-
Kuldren schrieb:
d.h. ich muss das hDC_mem und pre_mem nicht als CreateCompatibleDC()
sondern als CreateCompatibleBitmap anlegen?Nicht ganz, d.h. du musst hdc_mem und hdc_pre_mem zwar mit CreateCompatibleDC() erzeugen, aber anschließend noch für beide mit CreateCompatibleBitmap() eine Bitmap mit der entsprechenden Größe erzeugen und mit SelectObject() jeweils in die beiden DCs selektieren.
Mit CreateCompatibleBitmap() noch beim 1. Parameter aufpassen, als 1. Parameter NICHT das gerade mit CreateCompatibleDC() erzeugte HDC verwenden, sonst ist die erzeugte Bitmap nämlich monochrom, da ja in den erzeugten DCs nur eine 1x1 große monochrom-Bitmap sitzt. Stattdessen den Desktop-DC angeben (den man mit GetDC(NULL) bekommt - hinterher ReleaseDC() nicht vergessen...)
CreateCompatibleDC() erzeugt ein Memory-DC.
GetDC() holt ein Display-DC.
Es gibt auch noch Printer-DCs...
Ein DeviceContext (DC) speichert lediglich Infos zu reinselektierten Objekten (Pen, Brush, Bitmap, etc...) und anderes Zeugs. Ein DC ist allerdings keine Zielfläche für Grafikoptionen, aber mit der Zielfläche verbunden.Bei einem Memory-DC ist die Zielfläche quasi die rein-selektierte Bitmap.
Bei einem Display-DC ist es direkt der Bildschirm oder ein Teil davon.
Bei einem Printer-DC ist es der Drucker.Daher sieht man bei einem frisch mit CreateCompatibleDC() erzeugten Memory-DC nichts (höchstens 1x1 Pixel ;D), sofern man nicht eine Bitmap reinselektiert, die groß genug ist.
Btw: Wenn das nen Spiel wird, würde ich evtl. über DirectDraw oder neuer nachdenken. DirectDraw ist meistens deutlich schneller als die GDI-Funktionen.
Du lädst da die Grafiken in Surfaces und hast die Probleme mit den DCs nicht.
Ich hab selber mal nen bisschen mit dem alten DirectDraw von DirectX7 rumprobiert und das ganze scheint recht unkompliziert zu sein.
-
hm...mit DirectDraw hab ich eigntlich noch gar nichts gemacht...
aber das mit dem 1x1 Pixel...is vielleicht ein grund dafür wieso er das ned anzeigt (was das ursprüngliche problem war)
aber danke ich werds mit dem versuchen und schaun ob das geht...:)
-
Kuldren schrieb:
muss ich dann SelectObejct(hDC_mem,hdcBitmap[0])
und danach BitBlt(hDC,,,,,,hDC_mem);oder nur BitBlt(hDC,,,,hdcBitmap[0]);
schreiben...?
natürlich nur BitBlt(hDC,,,,hdcBitmap[0]);
du kannst doch kein DC in einen anderen DC selektieren, nur GDI-Objekte
-
a supi...
danke...danke auch für den tip mit dem vollbild!->funktioniert super...
allerdings hätt ich noch ne frage...das hab ich leider nirgends gefunden:
wie hol ich mir die aktuelle auflösung damit ich beim beenden des spiels wieder auf die auflösung umstellen kann die eigentlich auf dem desktop war?...
-
Mit ChangeDisplaySettings(NULL,0) wird die in der registry gespeicherte Auflösung wiederhergestellt (sofern du nicht noch beim ersten Auflösung setzen noch CDS_UPDATEREGISTRY angegeben hast ;D)
-
ah super...:)
hab das gestern noch ausprobiert...
leider is mein rechner schon so im eimer das ich jetz formatieren darf und alles neu raufspieln muss...dann probier ich noch das mit dem CDS_UPDATEREGISTRY...
-
wenn ich das schreibe...(natürlich verändert):
// irgendwo statisch oder global: HBITMAP hBitmap[n]; HDC hdcBitmap[n]; // irgendwo am Anfang des Programms: HDC hdc = GetDC(NULL); hBitmap[0] = LoadImage(...); <-------------------------Fehler hdcBitmap[0] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[0], hBitmap[0]); //... hBitmap[n] = LoadImage(...); <--------------------------Fehler hdcBitmap[n] = CreateCompatibleDC(hdc); SelectObject(hdcBitmap[n], hBitmap[n]); ReleaseDC(NULL, hdc); // ab hier kannst du die Bitmaps über hdcBitmap[i] ansprechen
dann kommt bei der markierten stelle diese meldung:
error C2440: '=' : 'void *' kann nicht in 'struct HBITMAP__ ' konvertiert werden
Konvertierung von 'void' in Zeiger auf nicht-'void' erfordert eine explizite Typumwandlung<<ich weiß leider ned was ich falsch gemacht haben könnte...(oder ich bin zu müde um es zu checken)
hm...
-
*gähn*
-
hBitmap[0] = (HBITMAP)LoadImage(...); <-------------------------Fehler weg
-
Danke,... der Fehler is weg...
aber es funktioniert immer noch nicht...
-
A...habs doch geschafft...es lebe MSDN
-
[quote="geeky"]
Kuldren schrieb:
Mit CreateCompatibleBitmap() noch beim 1. Parameter aufpassen, als 1. Parameter NICHT das gerade mit CreateCompatibleDC() erzeugte HDC verwenden, sonst ist die erzeugte Bitmap nämlich monochrom, da ja in den erzeugten DCs nur eine 1x1 große monochrom-Bitmap sitzt. Stattdessen den Desktop-DC angeben (den man mit GetDC(NULL) bekommt - hinterher ReleaseDC() nicht vergessen...)
CreateCompatibleDC() erzeugt ein Memory-DC.
GetDC() holt ein Display-DC.
Es gibt auch noch Printer-DCs...
Ein DeviceContext (DC) speichert lediglich Infos zu reinselektierten Objekten (Pen, Brush, Bitmap, etc...) und anderes Zeugs. Ein DC ist allerdings keine Zielfläche für Grafikoptionen, aber mit der Zielfläche verbunden.Kannst du das nochmal erläutern?
Wenn ich zum Beispiel kein Spiel programmiere, aber in einem Fenster ein Diagramm erstellen möchte, welches alle paar Millisekunden aktualisiert wird, wie sollte ich das machen?
Momentan nutze ich auch ein MemoryDC mit CreateCompatibleDC().
Erzeuge mir ein Bitmap mit der Grösse des Clientbereichs. Wenn ich dann aber wieder blitte habe ich auch das Problem, dass ich statt des Windows-Grau einen schwarzen Dialog habe.
Umgangen bin ich das bisher, indem ich die das MemoryDC erst komplett grau fülle.-> Frisst sehr viel Performance.
-
Paul_C. schrieb:
Umgangen bin ich das bisher, indem ich die das MemoryDC erst komplett grau fülle.
-> Frisst sehr viel Performance.
Weiß' zwar nicht, ob das geschwindigkeitsmäßig etwas bringt, aber du könntest auch noch einen weiteren Memory-DC erstellen, in den du all das reinzeichnest, was sich nicht verändert (z.B. auch den Hintergrund) und diesen dann zu Beginn immer in deinen anderen Memory-DC blittest