JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.phpMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

[DirectDraw]Programm lässt sich lediglich 1 mal minimieren

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 23.07.2006, 14:00    Titel: [DirectDraw]Programm lässt sich lediglich 1 mal minimieren Antworten mit Zitat

Hi ihr,

Ich bin vor kurzem in die Programmierung mit einer Grafik api(in meinem Fall DirectDraw) und vor einer etwas längeren-kurzen Zeit ins programmieren überhaupt eingestiegen. Dies hier ist sozusagen mein allererstes Projekt in der Art. Und nun hab ich mein erstes Problem, dass ich nicht durch stunden langes googlen und Tutorials durchforsten lösen kann...

Und zwar verfügt mein kleines Programm jetzt schon über die Fähigkeit bei einem Surface/device(wie auch immer) lost zu reagieren, sprich alles zu löschen und wieder herzustellen. Das funktioniert auch alles wunderbar, und dank einem Tutorial auf germangamedev hab ich es sogar verstanden Very Happy. Doch nun kommt besagtes Problem.

ich habe eine kleine Klasse, zum laden von Bitmaps und um diese zu in den Backbuffer zu blitten, gschrieben. Rufe ich jetzt die Funktion " DDLoadBitmap(lpDD, filename, width, height) " auf um einem std::vector ein weiteres Bild hinzuzufügen, funktioniert das Minimieren des Spiels nur einmal. Das Ganze sieht so aus, dass ich einmal minimieren und dannach wieder zum Programm wechseln kann, wenn ich aber jetzt wieder minimieren will(alt+tab), dann passiert das auch, bloß wird immernoch alles gezeichnet und es ist so als ob sich das Programm nicht minimieren würde. Ich bekomme dann zwar immernoch den Frontbuffer meines programms auf meinen Monitor geklatscht, kann aber theoretisch ganz normal mit Windows arbeiten. Praktisch jedoch nicht, da man ja nichts von Windows sieht...

Ist echt schwer zu erklären...

Jetzt ist meine Frage ob mir da irgendjemand weiter helfen kann. ich poste am besten mal ein bisschen von meinem (peinlichen?) Anfängercode um zu zeigen, wie ich das ganze ungefähr mache. Smile

[.......] = hier würde noch anderer, aber glaub belangloser, code stehen

CBitmap.h // die klasse zum laden von Bitmaps
CPP:
struct BMP
{
   LPDIRECTDRAWSURFACE7   Bitmap;
   int                  width;
   int                  height;
};


class CBitmap
{
   public:
        [.......]
      bool AddImage(LPDIRECTDRAW7 lpDD, HWND hWnd, LPCSTR filename, int width, int height);
        [..........]
   protected:
      std::vector<BMP>      bitmap;
               [ ........]
//Ich habe quasi einen vector vom typ der struktur BMP angelegt um mehrere unterschiedliche Bilder mit verschiedener Breite und Höhe zu laden. Z.B. wenn ich mehrere animieren wollte.
};


CBitmap.cpp mit dem problem-funktionsaufruf
CPP:
bool CBitmap::AddImage(LPDIRECTDRAW7 lpDD, HWND hWnd, LPCSTR filename, int width, int height)
{
        [.......]
   m_size++; // bei jedem aufruf die benötigte Größe des vectors um 1 erhöhen
   bitmap.resize(m_size);
   bitmap[m_anzImages].Bitmap = NULL;
   bitmap[m_anzImages].Bitmap = DDLoadBitmap(lpDD, filename, width, height); // Wenn ich diesen Funktionsaufruf weglasse, funktioniert alles perfekt, sprich ich kann mein programm so oft minimieren, wie ich halt bock habe
        [.........]
}


ein ausschnitt aus dem gameloop meiner main.cpp
CPP:
      if(::active && active)
      {
         if(iDD.checkLost()) //lost?
         {
            iDD.ClearScreen(200, 200, 255);
            iDD.DrawGDITextEx(0, 0, 0, "Hallo DirectDraw", 300, 140, 20, 10, 80);
            iDD.DrawGDITextEx(0, 0, 0, "Text geht schon", 300, 200, 25, 12, -80);
            iDD.DrawGDITextEx(0, 0, 0, "Aber sowas von", 300, 300, 20, 10, 80);
            bmp->drawThis(iDD.getBack(), 10, 10);            
                                iDD.flipBuffers();
         }
         else //ja! lost ==> aufräumen und alles wieder herstellen
         {
            iDD.restore();
            Shutdown();
            InitStuff();
         }
      }


Hab ich alles Grottenfalsch gemacht? Embarassed oder warum funktioniert das minimieren nur 1 mal wenn ich die besagte funktion, zum laden von bmp Dateien in ein Surface, aufrufe?
vielen dank für jede Antwort Very Happy

[Info]
DDLoadBitmap() ist in der , mit dem DirectX SDK mitgelieferten, headerdatei "ddutil.h" und quelldatei "ddutil.cpp"
[/info]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 23.07.2006, 23:05    Titel: Antworten mit Zitat

hi,

könntest du bitte noch folgende Codeausschnitte posten? Ich denke, dass man den Fehler dadurch besser aufspüren könnte:

1. bmp->drawThis() - ist bmp eine Instanz von CBitmap? Poste bitte die Funktione drawThis()
2. CBitmap::CBitmap() - also den Konstrukor
3. den Teil deiner CBitmap::AddImage() vor m_size++
4. schreibe bitte kurz auf, welche Sachen die Shutdown()-Methode und die InitStuff()-Methode aufrufen. Wird die Instans bmp dort auch zerstört und neu angelegt? Ich glaube nicht, wenn doch poste bitte auch den Destruktor von CBitmap (wenn bmp wie gesagt eine Instanz von CBitmap ist

Ich weiß, das ist viel, aber genau so schwer wie es für dich ist, das Problem zu beschreiben, so schwer ist es auch für uns, sich ein Bild davon zu machen. Danke

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 23.07.2006, 23:14    Titel: Antworten mit Zitat

Ja. bmp ist eine instanz von CBitmap

CBitmap::drawThis()
CPP:
bool CBitmap::drawThis(LPDIRECTDRAWSURFACE7 lpBack, int x, int y)
{
   if(m_ok)//mindestens ein Bild wurde geladen
   {
      if(bitmap[m_frame].Bitmap != NULL)
      {
         SetRect(& m_rectBitmap, x, y, x + bitmap[m_frame].width, y + bitmap[m_frame].height);
         lpBack->Blt(&m_rectBitmap, bitmap[m_frame].Bitmap, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
      }
      else
      {
         return false;
      }
      m_aniTimer++; // wenn alles geht, mach ichs mit zeit
      if(m_aniTimer >= 160)
      {
         m_aniTimer = 0;
         m_frame++;
      }
      if(m_frame > m_anzImages-1)
      {
         m_frame = 0;
      }
   }
   else
   {
      return false;
   }

   return true;
}


konstruktor und gleich noch der destruktor von CBitmap:
CPP:
CBitmap::CBitmap()
{
   m_low            = 0;
   m_heigh            = 0;
   m_size            = 0;
   m_anzImages         = 0;
   m_aniTimer         = 0;
   m_frame            = 0;
   m_ok            = false;
   bitmap.resize(m_size);
}

CBitmap::~CBitmap()
{
   //delete all
   for(int i = 0; i < m_size; i++)
   {
      if(bitmap[i].Bitmap != NULL)
      {
         bitmap[i].Bitmap->Release();
         bitmap[i].Bitmap = NULL;
      }
   }
   bitmap.resize(0);
}


die komplette AddImage:
CPP:
bool CBitmap::AddImage(LPDIRECTDRAW7 lpDD, HWND hWnd, LPCSTR filename, int width, int height)
{
   m_size++;
   bitmap.resize(m_size);
   bitmap[m_anzImages].Bitmap = NULL;
   bitmap[m_anzImages].Bitmap = DDLoadBitmap(lpDD, filename, width, height);

   bitmap[m_anzImages].width = width;
   bitmap[m_anzImages].height = height;
   if(bitmap[m_anzImages].Bitmap == NULL)
   {//Fehler
      MessageBox(hWnd, "Fehler beim laden der Bitmap Datei!", "CBitmap ERROR", MB_OK | MB_ICONEXCLAMATION);
      return false;
   }
   else
   {
      AddColorKey(bitmap[m_anzImages].Bitmap);
      m_anzImages++;
      m_ok = true;
   }
   return true;
}



und die shutdown + initStuff.
CPP:
int InitStuff()
{
   bmp = new CBitmap;
   bmp->AddImage(iDD.getLPDD(), hWnd, "test.bmp", 100, 100);
   bmp->AddImage(iDD.getLPDD(), hWnd, "test2.bmp", 100, 100);
   return 1;
}

int Shutdown()
{
   delete bmp;
   bmp = NULL;
   return 1;
}


bmp ist global.
CPP:
CBitmap            *bmp;


Aber wie gesagt. Ansonsten läuft alles wunderprächtig... bloß halt das dumme mit dem minimieren...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 23.07.2006, 23:42    Titel: Antworten mit Zitat

hast du bei if(::active && active) noch irgendwelche else-Zweige oder anderer Code der ausgeführt wird, wenn minimiert wird? Poste den bitte auch noch(sry, ich will net, dass du hier dein ganzen Projekt postest, aber was sein muss muss sein^^) Bis jetzt vermute ich, dass das so abläuft: wenn active, also net minimiert, wird geprüft, ob etwas verloren wurde. wenn nein, ganz normal rendern ( if(iDD.checkLost()) ). Wenn ja, springt er wahrscheinlich nicht in die if(::active && active). Wenn das Programm nach dem minimieren wieder aktiviert wird, springt er hierrein, oder?:
CPP:
iDD.restore();
Shutdown();
InitStuff();
oder springt er darrein, wenn gerade minimiert wird? Ich nehme an, dass er trotzdem weiterzeichnet, also trotzdem in die if(iDD.checkLost()) springt, obwohl das Programm minimiert ist. Ansonsten: Kann es sein, dass du nach dem Minimieren keinen Clear-Aufruf mehr ausführst?

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 23.07.2006, 23:49    Titel: Antworten mit Zitat

Also wenn das Programm minimiert ist, wird kein Code Ausgeführt. es wird lediglich geprüft ob Nachrichten vorhanden sind.

CPP:
    while(running) //Spielschliefe// läuft solange running true ist
    {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
           if (msg.message == WM_QUIT) break;
           TranslateMessage(&msg);
           DispatchMessage(&msg);
        }
      active = !::IsIconic(hWnd);
       //Gameloop
      if(::active && active)
      {
         if(iDD.checkLost()) //lost?
         {
            iDD.ClearScreen(200, 200, 255);
            iDD.DrawGDITextEx(0, 0, 0, "Hallo DirectDraw", 300, 140, 20, 10, 80);
            iDD.DrawGDITextEx(0, 0, 0, "Text geht schon", 300, 200, 25, 12, -80);
            iDD.DrawGDITextEx(0, 0, 0, "Aber sowas von", 300, 300, 20, 10, 80);
            bmp->drawThis(iDD.getBack(), 10, 10);            iDD.flipBuffers();
         }
         else //ja! lost ==> aufräumen und alles wieder herstellen
         {
            iDD.restore();
            Shutdown();
            InitStuff();
         }
      }
    }



der Zweig mit dem
CPP:
            iDD.restore();
            Shutdown();
            InitStuff();

wird dann ausgeführt, wenn wieder zum Programm gewechselt ist, sprich, wenn verloren wurde...

Aber dasran darf es doch eigentlich nicht liegen, denn wenn ich die Funktion zum Laden der Bitmap Datei weglasse funktioniert ja alles. Mein Front und Backbuffer wird nach jedem minimieren wieder korrekt geladen etc... Also an der technik mit dem lost sollte eigentlich alles passen, vorallem, da ich se mehr oder weniger aus Patricks Tutorial habe Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 24.07.2006, 00:03    Titel: Antworten mit Zitat

Also, wenn minimiert wird, wird nur das Bild in der Bitmap weitergezeichnet? Der Rest wird minimiert? Dann liegt das dadran, dass du den Inhalt des Buffers vor dem Minimieren nochmal löschen musst, z.B. mit Clear().
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 24.07.2006, 00:11    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:
Also, wenn minimiert wird, wird nur das Bild in der Bitmap weitergezeichnet? Der Rest wird minimiert? Dann liegt das dadran, dass du den Inhalt des Buffers vor dem Minimieren nochmal löschen musst, z.B. mit Clear().

Hm. verstehe ich nicht ganz. Also wenn minimiert wird, wird eigentlich garnichts gezeichnet. Auch nicht das Bitmap. Hm einmal minimieren funktioniert ja auch noch. Ist ja erst ab dem zweiten mal.. und ich bin echt ratlos....

Zum Buffer löschen. Ich würde halt den Buffer mit einer Farbe füllen. Meinst du das? Wie kann ich das genau vor dem Minimieren machen. Wie finde ich herraus, dass das Programm gerade minimiert wird?

Irgendwie führt alles auf:
DDLoadBitmap(lpDD, filename, width, height);
zurück. Kommentiere ich diese Funktion aus, läuft alles.
Ahja. ich hab es vielleicht vergessen zu erwähnen. Auch wenn ich das Bitmap nichtmal zeichne, sondern nur lade, tritt der fehler schon auf. Ein programm, das sich nicht 2 mal minimieren lässt ist auch irgendwie uncool.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 24.07.2006, 00:48    Titel: Antworten mit Zitat

OK. Das Problem ist gelöst.

Ich hab soeben gedacht, dass ich das Problem einfach ignoriere und mal ein bisschen weitermache. Dann ist mir aufgefallen, dass Surfaces, die teilweise aus dem Bild hinausgehen sofort verschwinden...
Hab dann ein bisschen gesucht und erfahren, dass ich einen Clipper aktivieren muss (oder so ähnlich) um das zu vermeiden. Ich habe dann gerade auch ein tutorial gefunden, das mir gezeigt hat wie es geht und seit dem ich nen Clipper aktiv habe, ist das problem verschwunden...

Ist mir zwar etwas zu hoch, aber wenigstens funktioniert jetzt alles.


Danke trotzdem für die unerschöpfliche Hilfe DirectXer Smile
Hier gibts echt nur nette Leute....

gruß&gute nacht,
manu
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 25.07.2006, 08:47    Titel: Antworten mit Zitat

manu hat Folgendes geschrieben:
Ich habe dann gerade auch ein tutorial gefunden, das mir gezeigt hat wie es geht und seit dem ich nen Clipper aktiv habe, ist das problem verschwunden...

Ist mir zwar etwas zu hoch, aber wenigstens funktioniert jetzt alles.

Die Sache mit dem Clipper ist eigentlich recht simpel, der macht nix weiter als die Teile einer Surface wegzuschnippeln, die über den Bildschirm bzw. einen Zeichenbereich hinausragen. DD besitzt im übrigen die blöde Eigenschaft im Fenstermodus auch das Zeichnen außerhalb des Fensters zu erlauben, auch da hilft ein Clipper. Theoretisch kann man einen Clipper auch sehr einfach per Hand implementieren, wenn das deinem Verständnis hilft. Der DD-Clipper muss wohl mal hardwarebeschleunigt gewesen sein, ich glaube aber, das spielt heute eh nicht mehr die Rolle bzw. wird sicher über die Software emuliert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 25.07.2006, 11:49    Titel: Antworten mit Zitat

GreveN hat Folgendes geschrieben:
manu hat Folgendes geschrieben:
Ich habe dann gerade auch ein tutorial gefunden, das mir gezeigt hat wie es geht und seit dem ich nen Clipper aktiv habe, ist das problem verschwunden...

Ist mir zwar etwas zu hoch, aber wenigstens funktioniert jetzt alles.

Die Sache mit dem Clipper ist eigentlich recht simpel, der macht nix weiter als die Teile einer Surface wegzuschnippeln, die über den Bildschirm bzw. einen Zeichenbereich hinausragen. DD besitzt im übrigen die blöde Eigenschaft im Fenstermodus auch das Zeichnen außerhalb des Fensters zu erlauben, auch da hilft ein Clipper. Theoretisch kann man einen Clipper auch sehr einfach per Hand implementieren, wenn das deinem Verständnis hilft. Der DD-Clipper muss wohl mal hardwarebeschleunigt gewesen sein, ich glaube aber, das spielt heute eh nicht mehr die Rolle bzw. wird sicher über die Software emuliert.

Jo danke, hab mich jetzt nochmal im Web informiert und so langsam verstehe ich das schon. Ob ich einen Clipper per Hand implementieren könnte, bezweilfe ich, da ich kein Plan hätte wie ich die Surfaces, welche das "Backbuffer Rechteck" teilweise verlassen, zurechtschnippeln sollte. Rolling Eyes
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 25.07.2006, 11:57    Titel: Antworten mit Zitat

Naja, einfach beim Blitten das Source-Rect entsprechend anpassen, wäre z.B. eine Möglichkeit. ;)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 25.07.2006, 12:00    Titel: Antworten mit Zitat

GreveN hat Folgendes geschrieben:
Naja, einfach beim Blitten das Source-Rect entsprechend anpassen, wäre z.B. eine Möglichkeit. Wink

Ach stimmt. Ich habe immer gemeint, dass das Surface dann gezerrt wird, aber das passiert glaub nur beim verändern des destination rects...

Naja, jetzt gucke ich, dass ich meinem Progrämmchen noch DirectInput - ein gutes Tutorial hab ich schon gefunden - hinzufüge (dann hätte ich alles, was ich für ein kleines Spiel bräuchte) und dann versuche ich mich vielleicht noch mit nem eigenen Clipper. Smile
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum