Reicht GDI+ für 2D Spiele ?



  • mad_martin schrieb:

    Krux schrieb:

    von grund auf an jede möglichkeit der Plattformunabhängigkeit

    Bei sinnvollem Design nicht! Siehe rapsos Post.

    stimmt, aber man will sich ja nicht unnötig viel Arbeit machen. Dazu müsste man dann ja auch die andere Library kennen.



  • Kommt halt darauf an, was man will. Bisher hab ich das auch nicht so gemacht. Würde ich nochmal ein Projekt (neu-)anfangen, würde ich mir schon des Lerneffektes wegen die Arbeit machen.


  • Mod

    Krux schrieb:

    mad_martin schrieb:

    Krux schrieb:

    von grund auf an jede möglichkeit der Plattformunabhängigkeit

    Bei sinnvollem Design nicht! Siehe rapsos Post.

    stimmt, aber man will sich ja nicht unnötig viel Arbeit machen. Dazu müsste man dann ja auch die andere Library kennen.

    sauberes design hat schon seinen grund, es ist keine mehrarbeit, sondern eine grundlage. quer durch den ganzen source api-abhaengigkeiten zu haben ist die wirkliche mehrarbeit. im nachinein bist du darauf limitiert alle probleme so loesen zu muessen wie es deien api vorgibt, auch wenn es welche mit weit weniger arbeit gibt. du kannst unvorhergesehene dinge (weil du noch keine erfahrung mit der api hattest) sehr suboptimal loesen. z.b. wenn du ploetzlich rausfindest dass d3d9 beim taskswitch alle resourcen freigegeben haben moechte before du das device resettest.
    hast du deine factory und api unabhaengigkeit ist das max 1h tiparbeit. bist du aber ueberall von d3d9 abhaengig, musst du alle stellen finden an denen du ne resource halten koenntest oder du machst erst in diesem moment deinen resourcemanager bzw factory.
    oder du merkst dass sdl sau langsam ist, etwas neues drunter zu setzen ist dann fast ein komplettes neuschreiben...

    Saubers design hat seinen Grund 😉



  • ja Strukturiernung ist wichtig, aber wenn man nur eine API kennt, kann man das Projekt auch schlecht Portieren, wenn diese API nicht plattformunabhängig ist.



  • Krux schrieb:

    mad_martin schrieb:

    Krux schrieb:

    von grund auf an jede möglichkeit der Plattformunabhängigkeit

    Bei sinnvollem Design nicht! Siehe rapsos Post.

    stimmt, aber man will sich ja nicht unnötig viel Arbeit machen. Dazu müsste man dann ja auch die andere Library kennen.

    Nö dazu muss man die andere Library nicht kennen. Dafür braucht man nur etwas Übung und gesunden Hausverstand 🙂



  • Mit ein wenig Doublebuffering und Tricksen reicht GDI auf jeden Fall für normale 2D-Spiele. Wenns aber anspruchvoller werden soll, nicht mehr.



  • Hab jetzt mal angefangen mit GDI danach würde ich gerne OpenGL oder Direct X lernen, aber mal schaun...

    Zur zeit hab ich noch das Problem mit den Flackern, ich bekomm das mit dem double buffering irgendwie nicht hin und Inofmrationen zu GDI finde ich auch nicht viele (GDI nicht GDI+, hab die Headerdatein von GDI+ nicht)

    Danke für die vielen Ratschläge 🙂



  • Um deine Ausgangsfrage mittels eines realen Beispiels für eine Implementierung eines reinen C++, GDI und MFC 2D (Hobby-)Rundenstrategiespiels zu beantworten, kann ich dir einen Blick auf das Spiel Birth of the Empires empfehlen. Wir haben dort z.B. auch die Doublebuffering-Geschichte gelöst (d.h. unser Chefprogrammierer hat das, ich müsste ihn fragen, wie das geht, um dir da helfen zu können, bin selber kein waschechter cpp-Programmierer).

    Es darf allerdings nicht wirklich viel Bewegung auf der UI los sein, dennoch kann man - gutes Grafikpersonal vorausgesetzt - recht schöne Sachen machen, siehe hier:

    http://www.botf2.com/bote/Screenshots/con_diplomacy_eng2.png oder http://sirpustekuchen.si.funpic.de/phpBB3/viewtopic.php?f=3&t=792

    Was allerdings nicht geht mit der normalen GDI sind Transparenzeffekte, man muss also Buttons und andere Grafiken immer penibel genau aufeinander abstimmen, was den Hintergrund angeht. Aus diesem Grund stellen wir jetzt nach mittlerweile 4 Jahren intensiver Programmierarbeit auf GDI+ um, was aber einige Monate und etliche 1000 Codezeilen in Anspruch nehmen wird aufgrund der Fülle unserer Menüs und Grafikklassen. D.h. auch für die nachträgliche Möglichkeit der Umstellung von GDI auf "was besseres" dient unser Programm/Spiel als Anschauung.

    Aber selbst damit sind wir noch nicht wirklich glücklich. Wir wollen als Ultima Ratio auch auf OpenGL oder DirectX gewisse Teile der UI umstellen, z.B. die Planetensystemview ganz unten, in der dann die Planeten animiert rotieren sollen.

    Wir haben uns dazu auch schon ein paar Gedanken und Tests gemacht, die sich auch zur näheren Analyse und Diskussion eignen würden (ganzen Topic siehe hier: http://sirpustekuchen.si.funpic.de/phpBB3/viewtopic.php?f=1&p=11633#p11633):

    Zu den rotierenden Planetengrafiken haben wir uns schon ein paar Gedanken und Tests gemacht:
    Es ist möglich einen drehenden Würfel hinter einen mit GDI gezeichneten Text zu legen. Die Performance war okay. Das Problem an der Sache ist nur, dass man dann kein DoubleBuffering (sprich flickerfreies Zeichnen) aktivieren kann. Bei jedem Neuzeichnen der OpenGL Teile flackern die GDI gezeichneten Sachen. Wenn man DoubleBuffering benutzt, dann werden die zuvor gezeichneten OpenGL Teile überschrieben.

    Theoretisch gäbe es folgenden Ausweg: Man zeichne zuerst das GDI Zeugs, speichere dann den aktuellen Fensterinhalt in ein im Speicher liegendes Bitmap (also nicht extra auf Platte speichern), erzeuge aus diesem Bitmap eine OpenGL kompatible Textur, lege diese Textur mittels OpenGL in den Hintergrund und zeichne dann die OpenGL Sachen darüber bzw. dahinter. Das Problem dabei wird aber die Performance werden. Obwohl es da auch einen Ausweg gibt: Man müsste sich die Textur pro Runde einfach mal generieren lassen, dann könnte man sie sofort benutzen. Das müsste dann sogar richtig schnell gehen. Einfach ist es allerdings nicht. Keiner vom BotE-Team hat bisher richtig mit OpenGL gearbeitet.

    Zum Schiffsviewer:
    Was aber relativ einfach gehen müsste, ist die Darstellung von OpenGL Objekten (z.B. 3D-Modelle von Schiffen) in einem OpenGL Fenster, sofern man ausschließlich OpenGL Befehle benutzt. Man könnte also ein extra Fenster einbauen, in dem z.B. die Schiffe sich in 3D drehen.

    Die Frage ob OpenGL oder DirectX ist noch ungeklärt, allerdings gilt zu beachten:
    Mittels DirectX soll eine gleichzeitige Nutzung mit GDI laut MS kein Problem sein. Die schlechte OpenGL Unterstützung Vistas könnte ein weiterer Hinderungsgrund für letzteres sein.

    Was würdet ihr sagen, könnte man das so machen wie oben angesprochen, um dem Doublebuffering-Problem bei gleichzeitiger OpenGL und GDI+ Nutzung zu entfliehen?

    Noch ein kleiner Nachtrag in eigener Sache zum Projekt: Es nutzt dummerweise noch etliche Gebäude-, Skin- und Planetengrafiken aus dem alten Microprose-Spiel Birth of the Federation (was es eigentlich nicht müsste, wir sind auch dabei, diese Grafiken zu ersetzen). Von daher wäre es auch nicht so gut, wenn es von jemandem runtergeladen und woanders wieder hochgeladen/gemirrored wird (falls das jemand möchte). Das steht auch in der Readme, allerdings liest die nicht jeder. Ansonsten ist das Spiel aber frei von jeglichen Urheberrechtsproblematiken.



  • Hallo !

    Danke für den Link, euer Spiel sieht wirklich sehr gut aus!

    Ich poste mal hier den Code wo ich glaube das der Fehler liegt:

    case WM_PAINT:
            {
    
                hDC2 = CreateCompatibleDC(NULL);
                hBM = CreateCompatibleBitmap(hDC2,500,500);
                SelectObject(hDC2,hBM);
    
                FillRect(hDC2,&rect,NULL);
    
                DeleteObject(SelectObject(hDC2,hBM));
    
                hDC = BeginPaint(hWnd,&ps);
    
                BitBlt(hDC,0,0,500,500,hDC2,0,0,SRCCOPY);
    
                EndPaint(hWnd, &ps);
    
                return 0;
            }
    

    Das wäre mein Ansatz, aber da Fehlt glaub ich noch was.

    hDC2 ist der Backbuffer DC, mit dem ich auf ein HBITMAP hBM zeichne, und danach blitte ich es auf das Haupt hDC welches auf das Fenster zeichnet, zumindest glaube ich das ich das hier mache, wenn das falsch ist korrigiert mich bitte.

    Auch wenn ich CreateCompatibleDC als Parameter das Handle vom Fenster übergebe funktioniert es nicht, genau so wenn ich hDC als Parameter übergebe (nach der Zeile hDC = BeginPaint(..) natürlich) funktioniert es nicht.

    Es flackert immer und man sieht den Fensterhintergrund durch (wc.hbrBackground = hBrushBg;) darf ich dem Fenster keinen Hintergrund geben wenn ich mit GDI zeichne ? Der Hintergrund ist hBrushBg (= CreateSolidBrush(RGB(0,255,0));)
    Also grüner Hintergrund.

    Wenn ich blitte BitBlt(hDC,0,0,500,500,hDC2,0,0,SRCCOPY); dan wird der grüne Hintergrund schwarz übermalt, meine gezeichnetes Rectangle sehe ich aber.

    Falls jemand eine Idee hat was ich falsch mache würde ich mich freuen wenn er mir das sagt 🙂

    *edit*
    Auch wenn ich DeleteObject(...) erst nachdem ich geblittet habe aufrufe, ändert das nichts.



  • Ein bool müsste noch fehlen zum switchen der Buffer.

    Ich hab hier mal etwas gegoogelt und einige Codeschnipsel gefunden, die dir evtl. weiterhelfen (unser Chef ist über Pfingsten in Urlaub ;)):

    http://developia.krawall.de/forum/frage111865.html
    http://www.ureader.de/msg/1244557.aspx
    http://www.codeguru.com/Cpp/misc/misc/flickerfreedrawing/article.php/c389


Anmelden zum Antworten