Bitmaps, hDC & Co
-
Hallo!
ich hätte zwei "kleine" fragen:
1.Frage:
------------------------------------------------------------------------
Ich versuche seid einiger Zeit ein kleines Spiel zu programmieren.
Von der Logik her funktioniert alles und ich will jetz natürlich auch Grafik einbauen.Ich schreibe das ganze unter Microsoft Visual C++, Win32 Anwendung
WINAPI ......Mein Problem liegt darin dass ich keine Bitmaps laden und dann im Speicher behalten kann!
Also wenn ich jetzt mittels LoadBitmap eine Bitmap lade die ich vorher eingebunden habe (was übrigens nicht so günstig is weil die dann eben nur 256 haben darf! vlt kennt ihr da eine andere bessere Methode?`) und dann mit SelectObject und dann BitBlt In ein hDC schreibe und dann aus der Funktion Bzw. Methode rausspringe dann is die geladene Bitmap beim nächsten Aufruf der Methode bzw Funktion nicht mehr im hDC drin ... sondern das hDC ist leer!...
Dann muss ich die Bitmap erneut laden und das kostet echt Rechnerleistung wenn ich ein raumschiff darstellen will und jedes mal wenn das (a la Space invaders) schüsse abfeuert diese dann immer (BEI JEDER BEWEGUNG) neugeladen werden müssen!Kurzform (Nur ungefähr...nicht tatsächlicher Quellcode)
class Rocket
{
HDC hDC;void LoadBitmap()
{
//LoadBitmap
//SelectObejct(hdc_memory,Bitmap)
}void Draw_Rocket()
{
//BitBlt(von hdc_memory in hDC) <--Das funktioniert nicht...da zeigt er einfach nichts von der bitmap an...
}}
meine frage jetzt eben....eigentlich müsste das HDC doch die bitmap "speichern" und ich könnte sie dann immer wieder darstellen....
aber es funktioniert einfach nicht....Die bitmap jedes mal neuzuladen wenn ich sie darstellen will is doch extrem rechnerunfreundlich...
Wisst ihr vlt eine bessere methode oder überhaupt eine andere art wie ich bitmaps laden/ anzeigen kann?
---------------------------------------------------------------------
2.frage:ich würde auch gerne sound dateien ausgeben...
im prinzip eigentlich egal ob wav oder Mp3....
vlt wisst ihr da ja eine geschickte methode?Würde mich freuen wenn ihr mir helfen könntet!
MfG Kuldren
-
Eine Bitmap darf sehr wohl mehr als 256 Farben haben, die GDI-Funktionen kommen damit auch prima klar. AlphaBlend() kann sogar 32-Bit-Bitmaps mit Alpha-Kanal verarbeiten - Kann es sein dass du die MSVC6-IDE benutzt, die gerne anzeigt dass es nur mit 256 Farben klar kommt ?
Ein Memory-DC benutzt immer eine Bitmap als Leinwand, ein Fenster-DC benutzt direkt den Bildschirm als Leinwand. D.h. mit SelectObject() kopierst du das Bild nicht in den DC, sondern der DC nutzt das rein-selektierte Bild.
Mit dem Pseudo-Code-Ausschnitt lässt sich der Fehler leider nicht finden ;/
Zum Abspielen von mp3s steht was in der Winapi-FAQ. Ansonsten benutzt mal die Forensuche, sowas wurde schon öfter gefragt
-
naja kurz gesagt ich will eigentlich nur einige bilder laden und in ein hDC zeichnen...
und dann dieses hDC als ganzes auf dem schirm ausgeben ...damit nichts flackert wenn ich dinge bewege (z.B: Rakete, raumschiff,etc)256 farben:
das weiß ich leider nicht genau...
wenn ich eine bitmap einbinden will die mehr als 256 farben hat dann kommt die meldung dass die bitmap nicht geladen werden kann weil sie mehr als 256 farben hat...
bis jetz hab ich eifnach immer die bilder mit 256 farben abgespeichert im photoshop und so...mit GDI kenn ich mich leider gar nicht aus
darstellen:
ich dachte ich könnte einfach die bitmap 1 mal laden und anschließend so oft ich mag einfach aus dem speicher nehmen und darstellen...wie es ja eigentlich auch gehört...wisst ihr vlt wie das geht`? ohne dass ich dutzende bibliotheken und unzählige sourcecode zeilen einbinden/eingeben muss?
es muss ja zumindest eine gute möglichkeit geben das in C++ zu schaffen:)Aber danke für den tip mit der musik...
ich versuch mein glck jetz mit PlaySound()...Greetz Kuldren
-
Kuldren schrieb:
wenn ich eine bitmap einbinden will die mehr als 256 farben hat dann kommt die meldung dass die bitmap nicht geladen werden kann weil sie mehr als 256 farben hat...
Hehe, die Fehlermeldung kannste ignorieren. MSVC6 ist nur zu blöd Bitmaps mit mehr als 256 direkt im eingebauten Bildeditor darzustellen, 24Bit-Bitmaps werden aber trotzdem mit in die exe integriert. Fehlermeldung also einfach ignorieren und an mehr Farben erfreuen, wenn du den eingebauten Bildeditor eh nicht benutzt
Ja, normalerweise sollte das gehen:
- Bild laden
- Memory-DC erzeugen (am besten CreateCompatibleDC() mit dem Desktop-DC als 1. Parameter aufrufen! Zum Desktop-kompatible DCs sind fix bei BitBlt())
- Bild in das Memory-DC selektieren
- BitBlt()en
- Irgendwann Bild und Memory-DC wieder freigeben.
Hast du mal Rückgabewerte geprüft ? Oder GDI-Objekte im Taskmanager von Win2k/XP eingeblendet und beobachtet ?
-
256 farben:
na supi...wenn ich das gewusst hätt...
Danke für den tip:)ja im Prinzip mach ich das mit dem alden und anzeigen genau so!
nur ich lade anfangs mit LoadBitmap aus dem eingebundenen file und dann wenn ichs eben in ein hDC_Mem speichern will damit ichs bei jeder bewgung der rakete neudarstellen kann...aber ned neu laden muss ...dann zeigt ers eben nicht mehr an....als ob das hdcmem leer wäre...Eigentlich müsste das hDC doch die Daten behalten wenn es ein Attribut der Raketenklasse is...
also (ungefähr):
class Rocket{
HDC hDC_mem;void Load(){
HDC Hdc_pre_mem;
//Loadbitmap()
//Selectobject(Hdc_pre_mem,bitmap)
BitBlt(Kopiert Hdc_pre_mem in hdc_mem hinein!)
}void draw(){
BitBlt(Kopiert hdc_mem auf hDC)}
}Rakete;
main(){
Rakete.Load(); // Bitmap wird ein einziges mal geladen
Rakete.Draw(); // bitmap wird zum ersten mal dargestelltdo{
Rakete.Move(); // wird halt bewegt
Rakete.Draw(); // wird wieder dargestellt
}while(GAME!=GAME_OVER);}
ob ich jetzt die bitmap aus hdc_mem direkt auf hDC(Bildschirm) kopiere oder wieder auf ein hDC_MEMORY_BEFORE_OUTPUT (wo alles draufkommt..hintergrund und alle rakteten umd dann als einziges bild ausgegeben zu werden) is ja eigentlich egal....wenn er mal das hDC behalten würde....
ich hätte noch ein frage...
wenn ich dieses Bitmaps ausgebe hab ich allerdings ein kleines problem...
wenn sich z.b. zwei bilder überlappen...
also ein schwertkämpfer den anderen mit dem schwert schlägt dann überlagert nicht nur das schwert den körper des anderen sondern das schwert und der rest er gesamten bitmap....
->der kämpfer wird also vollkommen verdeckt vom hintergrund des schwertes...weil an stellen wo in der btimap nicht mal eine farbe sein sollte zeichnet das MVC++ automatisch die farbe white rein...->was bei dem spiel dann nivcht so günsitg ausschaut!
Vlt kennt ihr ja eine lösungsmöglichkeit
MfG Kuldren
-
hallo
kannst du mir bitte den quelltext, der für dein bitmap "verantwortlich" ist, schicken?
ich schaffe das mit dem BMP nicht
also wie ladest du es und lässt es dann anzeigen?
-
Moment,
du machst quasi folgendes:- hdc_premem erzeugen (womit? CreateCompatibleDC() ?)
- Bitmap laden
- Bitmap in hdc_premem selektieren
- hdc_mem erzeugen? (wo? und womit ?)
- BitBlt() mit hdc_premem als Quelle und hdc_mem als Ziel ?
Wenn du Transparenz brauchst, kannst du in deiner Draw()-Methode TransparentBlt() verwenden oder evtl. AlphaBlend(). Bei TransparentBlt() unbedingt in der MSDN unten die Remarks lesen
-
ich erzeuge jedes hDC immer mit CreateCompatibleDC() ....
das hdc mem is ein attribut der klasse ( um das bild zu speichern)
hdc_mem=CreateCompatibleDC(hdC);-> steht dann im Konstruktor der Klasse (hab ich vergessen... sorry)
also:
- ja
- ja
- ja
- schon vorher im konstruktor
- ja!
und dann mit draw von hdc_mem auf den bildschirm!
@Phillip:
erst heut abend wenn ich mehr zeit hab...
schick mir einfach eine PN damit ich mich erinner@transparenz:
danke...werd schaun ob das geht!
-
vielen dank, wegen pn, muss man dazu nicht angemeldet sein?
ich schreibe dir einfach hier am abend!jedenfalls danke dass du mir deine zeit opferst, aber ich hänge im moment echt in der luft!
-
pn gibt es hier nicht. auch wenn man angemeldet ist.
-
kein pn^^
ja na ich hab ja icq da geht das schon...
zu den Problems:
ich werd das mit der transparenz einfahc mal versuchen...
das mit dem Speichern is mir allerdigns immer noch ein rätsel!
-
Kann ich mir auch nich erklären.
Hast du mal die Rückgabewerte der einzelnen Funktionen überprüft ?
-
nein eigentlich nichtz aber aufgerufen werden sie das weiß ich...und eigentlich funktioniert auch alles aber das HDC_mem is eifnach leer....
->hm?!
das der da die daten der bitmnap einfach verliert...
ich könnt höchsten ein große nehmen und in die alles reinspeichern...
und dann immer wieder hin und her übergeben...so müsst ichs nur einmal laden...habs auch schon mit den globalen hDCs probiert aber es funktioniert nicht...
die hDC daten gehen verloren wenn die Funktion / Methode in der die bitmap gealden wurde verlassen wird!...
->was auch logisch wäre...wenn die hDC`s nicht global wären!nebenfrage...
gibts einen Befehl mit dem ich in den vollbildmodus umschalkten kann?
also ohne titelleiste und ohne taskleiste?vlt gleich am anfang wenn ich das fenster aufbaue`?
sowas wie VISIBLE und co...
wie macht ihr das wenn ihr ein paar bitmapsdarstellen wollt? (Befehle...Programmreihenfolge und so)
(wenn man die ned dauernd neu zeichnet, das fenster aber minimiert dann sind die ja weg....auch so ein prob)
-
Vollbildmodus geht mit ChangeDisplaySettings() Fenster am besten nur mit WS_POPUP und WS_VISIBLE erstellen, dann wird keine Titelzeile und Rahmen etc. erzeugt.
-
danke...super!
das mit dem hDC...mal sehen vlt bekomm ich das ja nochmal hin...hm...
das mit dem soundabspielen is auch ok...nur dass wenn ich einen zweiten abspieln will der erste abgebrochen wird oder? (konnts noch ned testen)
muss ich dafür noch irgendwas besonderes runterladen oder ändern (Bibliotheken und so)?
Mfg Kuldren
-
Ich glaub PlaySound() hatte da nen Flag für - SND_ASYNC oder so.
-
hm..
ich muss zugeben dass ich damit nix anfangen kann...also mit flag und SND_ASYNC
Aber danke für die vielen Tips!
-
Du schriebst, du versuchst es so:
- hdc_premem erzeugen (womit? CreateCompatibleDC() ?)
- Bitmap laden
- Bitmap in hdc_premem selektieren
- hdc_mem erzeugen? (wo? und womit ?)
- BitBlt() mit hdc_premem als Quelle und hdc_mem als Ziel ?
1. Wieso der Umweg über hdc_premem? (den BitBlt-Aufruf kannst du dir dann sparen)
2. Ein Gerätekontext muss sich auf irgendetwas beziehen, z.B. Bildschirm, Drucker, Bitmap, etc. Dein hdc_mem bezieht sich auf ein 1x1px großes, monochomes Bitmap (ist standardmäßig in jedem DC), dort muss du vorher, wenn du den unnötigen Umstand bestehen lassen willst, ein, deinem Bitmap entsprechendes (Farbetiefe, Größe (CreateCompatibleBitmap!)), Bitmap hineinselektieren.
-
sorry, habe vergessen dich zu erinnern dass du mir den quellcode schickst, kannst du das bitte nachholen und ihn mir hier reinstellen?
danke
-
Ich hab den Umweg genommen weil das als zwischenspeicher dient bis ichs dort reinkopier (hDC_mem) wo es bleuben soll, und wo ichs mir auch immer rauskopieren kann( halt von hdc_mem auf hDC)
das mit dem 1x1Pixel monochromen bitmap hab ich ned gewusst...
d.h. ich muss das hDC_mem und pre_mem nicht als CreateCompatibledDC()
sondern als CreateCompatibleBitmap anlegen?
->vlt speichert er es deshalb nicht ab!...hm...was meinst ihr?@Phillip:
sorry ich hatte gestern abend so viel zu tun...ich kam ned mal dazu nach meinen mails zu gucken...
heut abend hab ich zeit...schreib einfach ins forum oder mich im icq an...
Dann geb ich dir den ganzen quellcode...jetz hab ich ihn leider nicht dabei...