Auf dem Weg von DDraw nach OpenGL ..

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Meine momentane Lösung für drei unterschiedliche Grafikmethoden:

Code: Alles auswählen

//.. aus der stdafx.h:
//>
//> Grafik-Methoden:
//> 
#define ZWIANER_DDRAW "DirectXDDraw"
//> #define ZWIANER_WIN32OPENGL "Win32OpengGL"
//> #define ZWIANER_WIN32SDL "Win32SDL"
//.. aus der main.cpp:
CKDDraw *g_pKDDraw = (CKDDraw *)NULL;
CKOpenGL *g_pKOpenGL = (CKOpenGL *)NULL;
CKSDL *g_pKSDL = (CKSDL *)NULL;
#ifdef ZWIANER_DDRAW
  CKDDraw *GetgpKGrafik(void)
  {
    return g_pKDDraw;
  }
  void DeleteKGrafik(void)
  {
    delete g_pKDDraw;
    g_pKDDraw = NULL;
    
  }
#else
  #ifdef ZWIANER_WIN32OPENGL
    CKOpenGL *GetgpKGrafik(void)
    {
      return g_pKOpenGL;
    }
    void DeleteKGrafik(void)
    {
      delete g_pKOpenGL;
      g_pKOpenGL = NULL;
      
    }
  #else
    #ifdef ZWIANER_WIN32SDL
      CKSDL *GetgpKGrafik(void)
      {
        return g_pKSDL;
      }
      void DeleteKGrafik(void)
      {
        delete g_pKSDL;
        g_pKSDL = NULL;
        
      }
   #endif
 #endif
#endif
//.. 
int APIENTRY _tWinMain
             (
               HINSTANCE hInst,
               HINSTANCE hPrevInstance,
               LPTSTR    lpCmdLine,
               int       nCmdShow
             )
{
  //..
  #ifdef ZWIANER_WIN32SDL
    g_pKSDL = new CKSDL
                  (
	            hInst,
	            SDL_INIT_VIDEO,
	            g_bHgAlt
	          );
    if (g_pKSDL != NULL)
    {
      g_hInst = g_pKSDL->GethInst();
      g_hWnd = g_pKSDL->GethWnd(); 
    }
  #else
    #ifdef ZWIANER_WIN32OPENGL
      g_pKOpenGL = new CKOpenGL
	               (
	                 hInst,
	                 800,
	                 600,
	                 WndProc,
	                 g_bHgAlt,
	                 1
	               );
      if (g_pKOpenGL != NULL)
      {
        g_hInst = g_pKOpenGL->GethInst();
        g_hWnd = g_pKOpenGL->GethWnd();
      }
    #else
      g_pKDDraw = new CKDDraw
    	              (
    	                hInst,
    	                nCmdShow,
    	                g_iPix,
    	                g_bHgAlt,
    	                WndProc,
    	                1
    	              );
    	                
      if (g_pKDDraw != NULL)                
      {
        g_hInst = g_pKDDraw->GethInst();
        g_hWnd = g_pKDDraw->GethWnd();	                
        
      }                  
    #endif
  #endif
  if 
  (
    (GetgpKGrafik() != NULL)
    &&
    (GetgpKGrafik()->GetbAllesOK() == true)
    //..
  //..
Ab hier wird nur noch über GetgpKGrafik() zugegriffen.
Alle public-Routinen von DDraw/OpenGL/SDL bieten in der jeweiligen Klasse eine für alle konstante Schnittstelle. Was die einzelnen Grafikmethoden im Detail machen, interessiert mich bei der weiteren Spielentwicklung nicht mehr.
Hinweis für gcc/Linux Anwender:
BildUnter VS ist im Quelltext schön zu sehen, welcher Teil gerade aktiv ist.
Zuletzt geändert von HeinzK am 24.09.2010, 14:33, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von kimmi »

Ist das Device bereits ein Interface, von denen die konkreten Implementierungen dann erben? Wenn nein: das macht den Code dann noch einfacher wartbar. Die Generierung der entsprechenden Instanz könntest du dann beispielsweise von einer Factory erzeugen lassen.

Gruß Kimmi
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Schrompf »

Solche Entscheidungen (Linux/OpenGL vs Windows/DDraw) sind doch keine Laufzeitentscheidungen, sondern Buildkonfig. Das als Interface zu gestalten, von dem die Implementationen ableiten, ist nur Verschwendung von Rechenzeit. Ein wirklich abstraktes Interface zum System sollten Klassen und Schnittstellen sein, die auf allen Plattformen identisch aussehen und identisches Verhalten bieten, und sich nur intern in ihrer Implementation je nach Plattform unterscheiden.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von kimmi »

Wenn es sich wirklich nur um Build-Konfigurationen handelt, ist das richtig. Ich persönlich abstrahiere das per Interface, um die Koppelung zwischen konkreter Implementierung und dem dahinterliegenden OpenGL- / D3D- / SDL-spezifischen Code möglichst gering zu halten. Gerade wenn man zwischen OpenGL und D3D unter Windows umschalten will, kann das Sinn machen, da man in der Regel keine 2 Executables für D3D oder OpenGL ausliefern will. Und will man per Mock-Object den Kram für Testsuiten testbar machen ( was bei mir eine Anforderung ist ),ist ein Interface hilfreich. Dafür muß ich dann den Performanceverlust halt in Kauf nehmen.
Aber prinzipiell stimme ich dir da zu, da kann man was sparen!

Gruß Kimmi
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Langsam, so schnell komm' ich bei euch heute morgen noch nicht mit.
Es ist gewiss keine Laufzeitentscheidung geplant. Es sind ja #define/#ifdef Konstruktionen.
Auf was ich hinaus will, ist folgendes: Sowenig Redundanz wie möglich. Und im Moment bin
ich ja noch am Testen. Unter Windows werden ich wahrscheinlich bei DDraw bleiben (solange es funktioniert) und
bei Linux werden ich vielleicht nur SDL verwenden. ??? :? ???
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von kimmi »

Dann bist du gut davor. Interfaces helfen nur, wenn du zur Laufzeit entscheiden mußt, welche konkrete Implementierung du brauchst.

Gruß Kimmi
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Biolunar »

Gibt es eigentlich einen Grund warum du unter den verschiedenen Plattformen verschiedene Backends verwenden möchtest? Wie du selbst siehst hast du dadurch einen imensen Mehraufwand...
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Gebranntes Kind? Vistageschädigt? Kein Vertrauen mehr in die Zukunft vorhandener Software? Reiz des Neuen?
Ich will mein Programm auf Linux portieren. Auch meine Firma 'liebäugelt' in diese Richtung. Und da will ich den
Anschluss nicht verpassen. Eigentlich wollte ich ja nur OpenGL einsetzen, aber dort wird meine Methode nicht von allen Grafikkarten unterstützt.
Warum dann der Aufwand mit SDL und OpenGL auf Windows? Hier habe ich ein Programm das bisher fehlerfrei funktioniert
(so weit man das bei Software je wissen kann). Unter Linux rechne ich noch mit vielen Überraschungen! Wenn ich das gleiche
Grafiksystem auf Windows und Linux habe (SDL/OpenGL) kann ich Fehlerquellen besser lokalisieren.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

SDL:
1. Problem beim Debuggen (Remote). Das Fenster bekommt beim Öffnen nicht immer den Fokus. Im Release-Modus scheint es aber zu funktionieren. D.h. es kommt unter die anderen offenen Fenster. Gibt es da eine Lösung (SetFocus(hWnd) funkt nicht)?
2. Das Fenster öffnet sich Kaskadenartig immer an einer anderen Position. Läßt sich das schon beim Anlegen irgendwie beeinflussen?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von kimmi »

Zu 1.: Hast du schon mal SetForeGroundWindow probiert? Hier ist die Funktion dokumentiert: http://msdn.microsoft.com/en-us/library ... 85%29.aspx . Ansonsten lies dir mal die Doku der Funktion SDL_ActiveEvent durch.
zu 2.: Da würde ich ebenfalls SDL_ActiveEvent benutzen.

Gruß Kimmi
glassbear
Establishment
Beiträge: 324
Registriert: 08.04.2003, 18:09
Alter Benutzername: Enrico_
Echter Name: Enrico
Wohnort: San Diego
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von glassbear »

HeinzK hat geschrieben:2. Das Fenster öffnet sich Kaskadenartig immer an einer anderen Position. Läßt sich das schon beim Anlegen irgendwie beeinflussen?
Google - Erster und zweiter Hit.

Und unter Linux lässt sich das nicht weiter beeinflussen, da der Window Manager die Positionierung übernimmt und der sagt, wo es lang geht...
Ein Hoch auf uns Männer... Auf die Frau, die uns HAT ( oder hat, und nicht weiß, dass sie uns hat ) ...auf die Idiotinnen ... besser gesagt VOLLPFOSTINNEN ... die uns hatten und uns verloren haben ... und auf die GLÜCKLICHEN, die das Vergnügen & Glück haben werden uns kennenzulernen!
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Testaufruf für DDraw, OpenGL und SDL unter Windows: http://www.zwianer.de/$PCSpiel$/Problem ... afikEn.htm
Download(Installation): http://www.zwianer.de/Download/ZwiAner4GrafikEn.exe
Download(Archiv):http://www.zwianer.de/Download/ZwiAner4GrafikEn.zip
Meine 'Grafik-Engine' ist nun so umgebaut, dass ich wahlweise DDraw, OpenGL oder SDL nutzen kann.
Die Linux-Version steht kurz vor dem Durchbruch .. nur .. leider fehlt mir im Moment die 'Freizeit' für's Hobby. Aber ich bleib dran!

Aufruf: Bitte installiert und testet den 'Download' auf möglichst vielen Windowsplattformen/Grafikkarten. Es wäre 8-) von euch, danke.

Bild
Bei den Testroutinen handelt es sich um leicht abgwandelte Bildschirmschoner (meine ganz privaten, fleißigen Programmtester).
T1(...) Alle möglichen Objekte (Astroiden, Planeten, Gravitatoren, Frachter und Co.) werden per Zufall
(Ort, Richtung, Geschwindigkeit) verteilt .. und .. die Gravitation nimmt ihren Lauf!
T2(...) Hier werden per Zufall 'Sonnensysteme' (Eine Sonne, Doppelsystem und 3 Sonnen) mit zufälligen
Planeten und Asteroiden getestet.
Als Vorbereitung für Linux sind die neuen Klassen aktiv: KString, KFile, KZeit, KZeichnen, KPixeln, KVector.
Es fehlt eigentlich nur noch als Fleißarbeit der Umbau der restlichen CPtrList, CPtrMap und Co's. Dann brauch'
ich nur noch einen Ersatz für DDInput und DDSound .. und .. ZwiAner läuft auch auf Linux!
Zuletzt geändert von HeinzK am 04.10.2010, 13:52, insgesamt 1-mal geändert.
Es ist leichter, einen Sack Flöhe zu hüten.
Gelöschter Benutzer 2
Beiträge: 12
Registriert: 16.06.2008, 17:13

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Gelöschter Benutzer 2 »

Betriebssystem: Windows 7 64 Bit

In CPU (Core i5 Mobil) integrierte Grafikkarte:
Version 1:
DDraw: Vollbild, scheint alles richtig dargestellt zu werden aber leider flimmerts die ersten 2 bis 3 Sekunden + man sieht kurz das Gittermodell.
OpenGL: Fenster welches deutlich kleiner ist als im Vollbild, so dass die Objekte alle recht gequetscht aussehen. Und die Partikel die es bei DDraw zu sehen gibt sind praktisch fast nicht vorhanden und sind nur weiße Punkte die kurz für eine halbe Sekunde etwa aufblitzen. Auch sieht man hier kurz am Anfang wieder das Gittermodell.
SDL: Wieder ein kleines Fenster, wieder kurz das Drahtgittermodell sichtbar ansonsten keine Probleme. Hatte den Eindruck, dass das irgendwie schnellsten lief.

Version 2:
DDraw: Einziges Probleme ist dass das Objekte in der Mitte (die Sonne?) bei manchen Starts komisch aussieht und zwar dass es ein Punkt mit einem Kreis drumherum ist und nicht ausgefüllt wie normalerweise sonst. Ansonsten keine Probeleme (Kein Flimmern und kein Gittermodell).
OpenGL: Das selbe wie bei DDraw nur im Fenster und wieder das selbe Problem mit den Partikel, einige sind nur Weiße (zu große?) Kreise die kurz sichtbar sind und bei Explosionen gibt es nur kurz ein aufploppen und dann sind die Partikel sofort wieder weg und nicht so wie bei DDraw.
SDL: Wieder Fenster. Ist diese Unmenge an Partikeln verglichen zu DDraw wirklich gewollt? Das ist ja ne richtig Explosionsflut. Und wieder der Eindruck dass es am schnellsten lief.

Radeon HD5650 Mobil (Der verwendete Treiber basiert glaub auf dem 10.6 Treiber, es ist ein an Switchable mit der Intel Grafikkarte (Intel Treiber sind enthalten) angepasster Treiber):
Version 1:
DDraw: Das selbe wie mit der Intel.
OpenGL: Das selbe wie mit der Intel nur dass man nun auch Partikel zu Geschicht bekommt die nicht sofort gleich wieder verschwinden.
SDL: Das selbe wie mit der Intel nur dass es nun nicht so aussieht, dass SDL schneller wäre sondern gleich schnell wie mit den anderen beiden.

Version 2:
DDraw: Das selbe wie mit der Intel auch wieder manchmal mit diesem Punkt und Kreis als Sonne.
OpenGL: Da gibt es aber ne ganze Menge Partikel, die durch die Gegend fliegen. Bei DDraw scheinen sie von der Sonne wieder angezogen zu werden und bei OpenGl davon abgestoßen zu werden. Auch scheinen allgemein die Planeten Bewegungen bei OpenGL trotz mehrmaligem starten deutlich Träger zu sein als bei DDraw. Die Punkt / Kreis Sonne gibts hier wieder manchmal.
SDL: Wie DDraw nur in ruckelig (also bei den schnellen Bewegungen der Partikel fällt es einem auf).

Also am Besten funktioniert wohl DDraw. Kompatiblität ist bei SDL auch in Ordnung aber gerade bei richtigen (nicht Intel) Grafikkarten hinkt die Performance den anderen beiden hinterher. OpenGl mach halt vor allem bei der Intel irgendwie Probelme.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2395
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Jonathan »

HeinzK hat geschrieben:Als Vorbereitung für Linux sind die neuen Klassen aktiv: KString, KFile, KZeit, KZeichnen, KPixeln, KVector.
Es fehlt eigentlich nur noch als Fleißarbeit der Umbau der restlichen CPtrList, CPtrMap und Co's. Dann brauch'
ich nur noch einen Ersatz für DDInput und DDSound .. und .. ZwiAner läuft auch auf Linux!
Hm, wieso braucht man eine KString und KVector Klasse, um plattformunabhängig zu sein? Was ist mit den Containern aus der STL?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2395
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Jonathan »

Bitte packt das ganze doch ein ein Archiv, ich hasse es Dinge installieren zu müssen, die ich vermutlich nicht lange nutzen werde (ich vertrau diesen Installern einfach nicht, dass mein System danach wieder sauber ist, außerdem sind zip-Dateien dann doch schneller extrahiert und anschließend wieder gelöscht).
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Zunächst einmal zu 'Jonathan':
.. Bitte packt das ganze doch ein ein Archiv ..
http://www.zwianer.de/Download/ZwiAner4GrafikEn.zip

'KString und Co.': Ich habe das Spiel auf ATL (MFC) entwickelt und mußte erstmal einen Ersatz für die vorhanden 'Strukturen' finden.

Nun zu 'BPhoenix':
Zuerst einmal Danke für den ausführlichen Bericht (du hast eine sehr gute Beobachtungsgabe).
DDraw: Das Flackern zu Beginn habe ich auch schon beobachtet. Aber es unterliegt nicht meinem Einfluss. Das Drahtgittermodell ist tatsächlich
im allerersten Bild (von 30 pro Sekunde) zu sehen. Da kann ich was tun. Danke für den Hinweis. DDraw wurde nie im Fenstermodus programmiert.
OpenGL und SDL werden im Test als Fenster mit 800/600 oder 1024/768 (je nach Auflösung der Grafikkarte) angezeigt.
Die Anzahl der Partikel und ihre Lebenszeit sind von der Framerate abhängig. Meine Grafikmethode kann unter OpenGL auf manchen
Grafikkarten sehr, sehr langsam sein. Das ist mir bewußt!
.. Wenn die Sonne komisch aussieht ..
Alle Beispiele sind (in gewissen Grenzen) zufallsbedingt. Wenn die Sonne (ich verwende Gravitatoren, also mehr Neutronensterne, weil Sonnen wären in
ihren Abmessungen so groß, dass nichts zum Spielen übrig bleiben würde) oder andere Objekte eine bestimmte Größe unterschreiten, wird ein
Ersatzsymbol angezeigt.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

.. und weiter geht's auf dem Weg ..
Inzwischen sind erfolgreich umgewandelt (http://www.zwianer.de/$PCSpiel$/Index_PCSpielEWInfo.htm):
CString in CKString,
CPtrList, CMapXToY und Co .in std::list, std::map und Co.
Auch die Serialisierung (CObject) habe ich erfolgreich nachprogrammiert.
Allerdings habe ich jetzt noch ein Problem!

Folgende Situation:

Code: Alles auswählen

class TestA
class TestB : public TestA
class TestC : public TestA
Nun mache ich bei der Serialisierung eine Iteration über die Basisklasse TestA!

Unter CObjekt und CArchive wurde hierbei immer automatisch auf das Serialize des 'letzten' Erben zugegriffen.
Ich habe gesehen, dass es in der Basisklasse den __vfptr der Virtual-Funktion-Table gibt. Wie kann ich auf diesen Zeiger zugreifen?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Zudomon »

[offtopic]
Hey Heinz... auch wenn dir das nicht so vorkam... aber hier bei uns auf der Erde ist unterdessen fast ein Jahr vergangen... :lol:
[/offtopic]
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ja, ich habe eben neben dem Hobby auch noch einen Beruf .. und konnte die letzte Zeit (uups ein ganzes Jahr) nur ab und zu an den ZwiAner arbeiten.
Die Umstellung ist verdammt viel, verdammt harte Arbeit gewesen. Aber nun bin ich mit dem 'gröbsten' durch.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von BeRsErKeR »

HeinzK hat geschrieben:.. und weiter geht's auf dem Weg ..
Inzwischen sind erfolgreich umgewandelt (http://www.zwianer.de/$PCSpiel$/Index_PCSpielEWInfo.htm):
CString in CKString,
CPtrList, CMapXToY und Co .in std::list, std::map und Co.
Auch die Serialisierung (CObject) habe ich erfolgreich nachprogrammiert.
Allerdings habe ich jetzt noch ein Problem!

Folgende Situation:

Code: Alles auswählen

class TestA
class TestB : public TestA
class TestC : public TestA
Nun mache ich bei der Serialisierung eine Iteration über die Basisklasse TestA!

Unter CObjekt und CArchive wurde hierbei immer automatisch auf das Serialize des 'letzten' Erben zugegriffen.
Ich habe gesehen, dass es in der Basisklasse den __vfptr der Virtual-Funktion-Table gibt. Wie kann ich auf diesen Zeiger zugreifen?
Lege die Methode Serialize einfach als virtual an. Beispiel:

Code: Alles auswählen

class TestA
{
public:
    virtual void Serialize(...){ // do something }
};

class TestB : public TestA
{
public:
    virtual void Serialize(...){ // do something else }
};

std::list<TestA *> my_list;

std::list<TestA *>::iterator iter = my_list.begin();

for(;iter != my_list.end(); ++iter)
    (*iter)->Serialize(...); // wenn (*iter) ein Zeiger auf TestB ist, wird "// do something else" ausgeführt
Ohne Input kein Output.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Das probier' ich heute abend gleich mal aus .. danke.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

OK, die Mittagpause hat zum Testen ausgereicht:
'Es gibt immer wieder Bäume, die die Sicht auf den Wald verstellen!'
Klar funktioniert es so! Ich war nur vor lauter 'CObject' in der falschen Fährte.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Gut, mit 'virtual' funktioniert Teil 1 .. die Speicherung. Aber mit Teil 2, dem Laden, habe ich noch Probleme:

Code: Alles auswählen

class TestA
{
public:
virtual void Serialize(...){ // do something }
};
class TestBvA : public TestA
{
public:
virtual void Serialize(...){ // do something else }
};
class TestCvA : public TestA
{
public:
virtual void Serialize(...){ // do something else }
};

std::list<TestA *> my_list;
//> Hier kenne ich die Anzahl der Elemente (int z):
for(int i = 0; (i < k); i++)
{
  //> Hier muss ich nun entweder TestBvA oder TestCvA anlegen:
  //> Ich habe die Information als String (std::string sS) "TestBvA" oder "TestCvA" vorliegen :
  if (sS == "TestBvA")
  {
    TestBvA *pC = new TestBvA();
  }
  if (sS == "TestCvA")
  {
    TestCvA *pC = new TestCvA();
  }
  pC->serialize(...);
  my_list.push_back(pC);
}
Hat jemand eine Idee, wie ich die 'Sprungtabelle' durch ein MAKRO oder Template mit etwa folgendem Aufruf 'NeueKlasse(sS)' ersetzten kann?

Code: Alles auswählen

  if (sS == "TestBvA")
  {
    TestBvA *pC = new TestBvA();
  }
  if (sS == "TestCvA")
  {
    TestCvA *pC = new TestCvA();
  }
Hinweis1: Mein Projekt hat ca. 250 Klassen ..
Hinweis2: Dies ist die vermutlich lezte Hürde auf dem Weg von MFC nach Linux .. oder von DDraw nach OpenGL.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von BeRsErKeR »

Du könntest eine Factory nutzen. Grobes Beispiel:

Code: Alles auswählen

template <typename T>
class Factory
{
public:
    static register_create_method(const std::string &name, class FactoryCreateMethod<T> &create_method)
    {
        methods[name] = create_method;
    }

    static T create(const std::string &name)
    {
        methods_t::const_iterator iter(methods.find(name));

        if (iter == methods.end()) throw std::runtime_error("Unknown type");

        return (*iter->second)();
    }

private:
    typedef std::map<std::string, class FactoryCreateMethod<T> *> methods_t;
    static methods_t methods;

protected:
    template <typename T0>
    class FactoryCreateMethod
    {
    public:
        virtual ~FactoryCreateMethod() {}
        virtual T0 operator()() = 0;
    };
};

Beispiel zur Anwendung:

Code: Alles auswählen

class BvA;
class CvA;

class A : public Factory<class A *>
{
    // ...

    static void register_create_methods()
    {
        register_create_method("BvA", create_BvA);
        register_create_method("CvA", create_CvA);
    }

    static class A * create(const std::string &name)
    {
        return Factory<class A *>::create(name);
    }

private:
    class BvACreateMethod : public Factory<class A *>::FactoryCreateMethod<class A *>
    {
    public:
        virtual class A * operator()() { return new BvA; }
    } create_BvA;

    class CvACreateMethod : public Factory<class A *>::FactoryCreateMethod<class A *>
    {
    public:
        virtual class A * operator()() { return new CvA; }
    } create_CvA;
};

class BvA : public A {};
class CvA : public A {};


int main(int argc, char **argv)
{
    A::register_create_methods();

    // ...

    std::list<class A *> my_list;
    for (size_t i=0; i<k; ++i)
        my_list.push_back(A::create(sS));

    // ...

    return 0;
}
Ohne Input kein Output.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Da werd' doch noch zum Fabrikarbeiter ..
Also dass muss ich mir Stück für Stück reinziehen .. Danke für die interessante Info.
*** *** ***
Mit 'Factory' habe ich bisher noch nie gearbeitet. Obwohl ich noch nicht jedes Detail verstehe .. ist der Ablauf gut zu erkennen (.. glaube ich).
Ich muss für jede Klasse das 'create_YvX' und Co. anlegen. Das ist im Ganzen mehr Schreibarbeit als meine 'Sprungtabelle':

Code: Alles auswählen

if (sS == "BvA")
{
  BvA *pK = new BvA();
  return pK;
}
Vorteil der 'Factory' ist, alles wird in der Klasse abgewickelt.
Nachteil meine Sprungtabelle .. sie muss ausserhalb der Klasse extra verwaltet werden.
PS:
Also wenn ich ein paar Stille Stunden finde (mit Regen draussen und dem ganzen sonstigen drum und dran) .. werde ich mich genauer mit dem 'Faktorieren' beschäftigen.
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

Ich nutze VS 2008 (VC9).
Bisher habe ich mit einem XP-Rechner (64x2 Dual Core 4200+ 990 MHz 1.0 GB RAM) gearbeitet.
Nun habe ich einen neuen Rechner: Win7 64 Bit i7-2600K 3.40 GHz (3.7 GHz) 16.0 GB RAM.
Das Kompilieren ist nun deutlich schneller (erkennt man: es wird wieder mehr Kaffe kalt).
Mein Problem ist das Debuggen (Remote-Debuggen).
Auf meinem alten System bin ich mit F10 von Zeile zu Zeile gesprungen (keine merkbare Wartezeit).
Mit dem Neuen muss ich immer ca. 3 Sekunden warten, bis die nächste Zeile aktiviert wird.
Was ist da los? Kann mir jemand einen Tipp geben?
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Schrompf »

Nicht wirklich einen Tipp, mehr eine Frage: warum remote debuggen? Läuft das Spiel nicht auf Deinem Entwicklungsrechner?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

1. Fullscreen-Anwendung (ich werd's auch mal im 'Fenster' testen)
2. Ist sehr bequem
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von Schrompf »

Naja.... bequemer als lokales Debuggen wird's wohl nicht. Und lokales Debuggen ist halt hundeschnell, deswegen empfehle ich das ja als Problemlösung. Das Fullscreen-Argument sehe ich allerdings ein - ich entwickle daher immer mit dem Spiel im Fenstermodus - selbst auf Windows7 und mit zweitem Bildschirm hat Windows immernoch Probleme, sinnvoll mit Fullscreen-Anwendungen umzugehen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
HeinzK
Establishment
Beiträge: 234
Registriert: 05.11.2009, 08:37
Benutzertext: ZwiAner
Echter Name: Heinz Kempter
Wohnort: Wald
Kontaktdaten:

Re: Auf dem Weg von DDraw nach OpenGL ..

Beitrag von HeinzK »

So kann ich mir bestimmt helfen .. aber ich wundere mich, dass ich unter XP keine Geschwindigkeitsprobleme hatte?
Es ist leichter, einen Sack Flöhe zu hüten.
Antworten