3d/Game Engine in C++ oder C#



  • Zuerst mal hallo an alle.

    Würde gerne eure Meinung dazu wissen.
    Oder ob ihr schon gewisse Erfahrung mit C# und OpenGL habt.
    Die Engine sollte auf jeden fall mit OpenGL aufgebaut werden. (Win32, Linux, Mac)

    Also ich sollte dazu sagen, das ich jetzt 3 Wochen test zeit mit C#
    (Mono, Win NET) hinter mir habe und die Ergebnisse der Performance erschreckend wahren.

    Aber was halltet ihr für sinnvoller?
    Auf jeden fall sollen auch große Games damit möglich sein...
    Die Engine hat auch ein Driver Model um auf jeder Plattform verfügbar zu sein z.B. auch PS3.

    Ich danke euch für eure Hilfe.



  • Du schreibst in einem C++-Forum. Welche Antwort erwartest du?

    Du kannst sicher deine Engine in Beiden Sprachen schreiben. Es könnte aber sein, dass du bei C# später an mehr stellen optimieren musst, als bei C++. Außerdem ist es bei C++ vermutlich einfacher, z.B. Inline-Assembly zu benutzten, um noch mehr Performance zu bekommen.

    Sinnvoll kann beides sein, muss es nicht. Die meisten Leute verwenden für eine Game-Engine C++, aber das musst du ja nicht.



  • Also ich selbst bevorzuge auch C++.
    Aber als ich mir XNA angesehen hab, dachte ich mir es währe auch C# möglich.
    Nur hab ich bemerkt das XNA eine extreme Performance hat, das hab ich in meinen test trotz Optimierungen nicht hinbekommen.
    Deshalb vermute ich stark dass hinter XNA native Komponenten stecken.

    Aber ich bekomme in C++, glaub ich das gleiche Konzept hin.

    C++

    namespace MyGame
    {
    	/// <summary>
    	/// Initializes a new instance of this game,
    	/// which provides basic graphics device initialization,
    	/// game logic, rendering code, and a game loop.
    	/// </summary>
    	Game1::Game1()
    	{
    	}
    
    	Game1::~Game1()
    	{
    	}
    
    	/// <summary>
    	/// Allows the game to perform any initialization it needs to before starting to run.
    	/// </summary>
    	void Game1::Initialize()
    	{
    
    	}
    
    	/// <summary>
    	/// Allows the game to run logic such as updating the world,
    	/// checking for collisions, gathering input and playing audio.
    	/// </summary>
    	void Game1::Update(__int64 Time)
    	{
    		Engine::Game::Update(Time);
    	}
    
    	/// <summary>
    	/// This is called when the game should draw itself.
    	/// </summary>
    	void Game1::Draw(__int64 Time)
    	{
    
    	}
    }
    

    C#

    namespace MyGame
    {
        class Game1 : Engine.Game
        {
            GraphicsDevice graphics;
    
            Model model;
    
            public Game1()
            {
                graphics = new GraphicsDevice(this);
            }
    
            /// <summary>
            /// Allows the game to perform any initialization it needs to before starting to run.
            /// This is where it can query for any required services and load any non-graphic
            /// related content. Calling base.Initialize will enumerate through any components
            /// and initialize them as well.
            /// </summary>
            protected override void Initialize()
            {
                base.Initialize();
    
                // TODO: Add your initialization logic here
    
                model = Loaders.Loader3DS.Load("C:\\spaceship.3DS");
            }
    
            /// <summary>
            /// Allows the game to run logic such as updating the world,
            /// checking for collisions, gathering input and playing audio.
            /// </summary>
            public override void Update()
            {
                graphics.Perspective(45.0, 800 / 600, 1.0, 2000.0);
    
                base.Update();
            }
    
            /// <summary>
            /// This is called when the game should draw itself.
            /// </summary>
            protected override void Draw()
            {
                graphics.Clear(System.Drawing.Color.CornflowerBlue);
    
                GL.glPushMatrix();
    
                GL.glTranslatef(0.0f, 0.0f, -650.0f);
    
                foreach (Mesh mesh in model.Meshes)
                {
                    mesh.Render();
                }
    
                GL.glPopMatrix();
            }
        }
    }
    

    Deshalb dachte ich das vielleicht jemand schon mehr Erfahrung in C# mit OpenGL hat als ich.



  • XNA ist c# (?) ! zumindest muss man VS2005 C# EE instaliert haben ...

    abgesehen davon haben verschiedene tests ergeben das c++ schneller ist als c#

    und wenn man die wahl hat ... sollte man eine richtige entscheidung treffen 😉



  • Teamdevel schrieb:

    Aber ich bekomme in C++, glaub ich das gleiche Konzept hin.

    Konzepte lassen sich Grundsätzlich in allen Programmiersprachen umsetzen. In den einen schwieriger in den anderen leichter, aber da C++ und C# nicht so verschieden sind, ist da wohl kaum ein großer Unterschied.



  • Teamdevel schrieb:

    Also ich sollte dazu sagen, das ich jetzt 3 Wochen test zeit mit C#
    (Mono, Win NET) hinter mir habe und die Ergebnisse der Performance erschreckend wahren.

    Die Performance deiner Engine hängt von sehr vielen Faktoren ab. Ich kenne die Performance von Mono nicht und weiß auch nicht, wie du sie getestet hast, aber es definitiv möglich, auch eine langsame C++-Engine zu schreiben. 😉

    Wenn du wie in Oblivion einfach alles brute force renderst und dich nicht kümmerst, dass die Objekte in einem anderen Raum sind und du auf eine Wand schaust, wirst du mit beiden Sprachen Probleme bekommen. Und dann kannst du das rumfrickeln anfangen (zum Beispiel die Stockwerke eines Hauses als eigene Levels mit nie sichtbar geöffneter Tür immer neu laden, wenn man die Tür durchschreitet). Oder du machst eine intelligente Raumunterteilung und renderst nur was sichtbar ist, dann wirst du vermutlich in beiden Sprachen zu zufriedenstellenden Ergebnissen kommen. Spiele sind meistens eher dann CPU-limitiert wenn komplexe Physik im Spiel ist, aber ein bisschen scene graph traversal geht normal schon ganz gut. Die ganze restliche CPU-Arbeit macht der Grafikkartentreiber und den schreibst du eh nicht selber (der ist dann auch wieder gefrickelt, Gruß an NVIDIA).



  • Optimizer schrieb:

    Teamdevel schrieb:

    Also ich sollte dazu sagen, das ich jetzt 3 Wochen test zeit mit C#
    (Mono, Win NET) hinter mir habe und die Ergebnisse der Performance erschreckend wahren.

    Die Performance deiner Engine hängt von sehr vielen Faktoren ab. Ich kenne die Performance von Mono nicht und weiß auch nicht, wie du sie getestet hast, aber es definitiv möglich, auch eine langsame C++-Engine zu schreiben. 😉

    Wenn du wie in Oblivion einfach alles brute force renderst und dich nicht kümmerst, dass die Objekte in einem anderen Raum sind und du auf eine Wand schaust, wirst du mit beiden Sprachen Probleme bekommen. Und dann kannst du das rumfrickeln anfangen (zum Beispiel die Stockwerke eines Hauses als eigene Levels mit nie sichtbar geöffneter Tür immer neu laden, wenn man die Tür durchschreitet). Oder du machst eine intelligente Raumunterteilung und renderst nur was sichtbar ist, dann wirst du vermutlich in beiden Sprachen zu zufriedenstellenden Ergebnissen kommen. Spiele sind meistens eher dann CPU-limitiert wenn komplexe Physik im Spiel ist, aber ein bisschen scene graph traversal geht normal schon ganz gut. Die ganze restliche CPU-Arbeit macht der Grafikkartentreiber und den schreibst du eh nicht selber (der ist dann auch wieder gefrickelt, Gruß an NVIDIA).

    Da hast du natürlich recht, meine test haben sich aber eher auf Matrix palette skinning und Real-time Skeletal Deformation beschränkt.

    Obwohl ich einiges über Vertex Shader gelöst habe, waren die Ergebnisse einfach zu schlecht.

    Mir gefiel das Konzept des XNA Frameworks und dachte das währe für Unix und Mac auch nicht schlecht, aber bevor ich jetzt einen Mix aus Managed und Unmanaged mache konzentriere ich mich gleich auf C++.



  • Ich denke die Plattformen und die Art des Spiels legen die Techniken automatisch fest. So grob würde ich sagen:
    Nur PC mit WTF-Highend-Grafik: C++ & DX
    PC Spiel, das nicht gerade Crysi-Grafik benötigt: MDX, XNA oder C++/DX
    PC und Xbox360: XNA oder C++/DX
    PC und Linux: C++/OpenGL

    Je nachdem wie gut du dich dann in den Techniken auskennst, kannste deine Wahl treffen. Ferner solltest du immer abwägen, ob sich der (nicht zu unterschätzende) Mehraufwand bei Verwendung von C++ wirklich lohnt.

    PS: Es heißt "wäre" und "waren" und nicht "währe" und "wahren"
    😉



  • pc und linux ???
    eher windows und linux

    und xbox360 mit c++ ?? wenn es ne stl gibt ok so weit ich weis gibts danur xna und das ist automatisch mit c# gebunden ... also fällt da irgendwas flach 😉


  • Mod

    Optimizer schrieb:

    Spiele sind meistens eher dann CPU-limitiert wenn komplexe Physik im Spiel ist, aber ein bisschen scene graph traversal geht normal schon ganz gut. Die ganze restliche CPU-Arbeit macht der Grafikkartentreiber und den schreibst du eh nicht selber (der ist dann auch wieder gefrickelt, Gruß an NVIDIA).

    und wieso fragst du dann hier alle zeit lang wieder wie du deine wegfindung optimieren kannst? das hat doch nichts mit physic zu tun 😃

    Jedes spiel heutzutage ist CPU limitiert zu einem gewissen grad. Wenn man MS fragt wie limitiert c# ist, besonders in bezug auf Xbox360, sagen sie die frage sei irrelevant, weil alle Spiele nur graphiklimitiert sind. das stimmt bei der xbox360 und dem c# zu nem gewissen grad, weil die leute die das nutzen oft vom shadern und graphik an sich noch weniger ahnung haben als vom normalen programmieren (es zielt ja speziel auf einsteiger, alle "richtigen" xbox360 spiele werden in c++ geschrieben) und deswegen alle schon vorhandenen generischen (und oft etwas langsamen) mittel nutzen, aber fuer ein-mann-teams ist das ok.

    In richtigen Spielen ist man hingegen so gut wie immer CPU limitiert. das liegt ganz einfach daran, dass es komplexe zusammenhaenge gibt die am anfang sehr viel unoptimierter sind und sehr viel schlechter einschaetzbar sind als graphik. bei der graphik weiss man mit einem simplen test, ob kurzere shader, kleinere texturen, weniger polygone, weniger overdraw usw. das spiel schneller machen wuerden. bei cpu-algorithmen weiss man das nicht so einfach, es kann sehr gut sein, dass wenn man dem culling mehr zeit gibt, dadurch ploetzlich soviel besser gecullt wird, dass die framerate nun viel besser ist (obwohl man ploetzlich viel mehr cpu-limitiert ist)

    weiter sind spiele sehr sehr oft auch ram limitiert. sowohl die groesse von 2GB (es haben leider wenige leute ein 64bit OS) als auch die bandbreite und latenz. wann auch immer jemand durch baeume traversiert, ist es natuerlich schnell, weil meist O(log n) und bla... aber bei sowas hat man dann auch cachemisses ohne ende und dann steht die cpu fuer ein paar hundert takte und wartet auf die naechste node bei der sie dann wieder solange warten kann. Deswegen ist speicheroptimierung extrem wichtig. ich denke heutzutage kommt kein spiel ohne memorymanagement aus. durch pooling kann man sehr viele daten cacheoptimieren und durch einfachereres management auch daten und cpu-zeit sparen. durch allignment von daten kann man manchmal die cachehitrate verdoppeln. durch verfolgen von allokationen kann man manchmal fehlerhafte allokationen auffinden. manche programmierer haben auch die soliditaet waehrend des spielablaufs nicht eine allokation zu machen und ihr ganze memory-layout sauber definiert zu haben.

    deswegen, wie optimizer schon sagte, kannst du auch mit c++ eine schlechte engine machen. jeder muss im leben mehrere engines schreiben bis er den dreh in etwa raus hat wuerd ich schaetzen. selbst wenn es weiterhin die version 1.0a ist. soweit ich weiss hat TimSweeney die rasterizer-engine fuer das erste unreal auch ca 6mal komplett neu geschrieben bis sie gut war. mit c# hast du den vorteil, dass du es nicht zu deiner lebensaufgabe machen musst, sondern als kleines hobby zu respektablen ergebnissen kommst (zumal dir viel fertig geboten wird). bei c++ stehen dir hingegen die toren weit offen alles machen zu koennen, entsprechend musst du auch mehr machen und eventuell auch zwei mal bis du die leistung erreichst wie bei c#-libs und dann nochmal ne iteration bis du das ubertrifst.



  • Ich bin froh, dass es C# gibt. Performence hin oder her, lieber habe ich eine intelligent designte Sprache, Compiler und IDE als mich um jeden Mist(vor allem Memoryleaks) zu kümmern. Ich kann aus eigener Erfahrung sprechen, dass meist der Mangel an Rendering-Techniken der Grund für unperformante 3D-Engines ist als die Sprache. BSP, Octree usw. sorgen für nötige Geschwindigkeit nicht Compiler o.ä.

    mfg olli



  • um jeden Mist(vor allem Memoryleaks) zu kümmern

    also ich finde es nicht weiter schlimm ein paar mal "delete xyz" in den destruktor zu schreiben.
    sonst macht es von der arbeit her bei einer grafik-engine wohl keinen so großen unterschied welche sprache du verwendest. der größte aufwand liegt halt beim code desgin.


  • Mod

    es ist ein sehr grosser trugschluss dass ein GC vor memoryleaks scheutzt. wenn du in sprachen die einen GC haben auf einen speicher referenzierst und vergisst ihn zu deferenzieren, kannst du trotzdem ein memoryleak haben. weiter gibt es resourcen wie z.b. texturen die du weiterhin managen musst.



  • also memoryleak-frei proggen geht ... mann muss nur bei jeder funktion wo man new/malloc verwendet gleichzeitig am ende oder im destructor das zu gehörige delete/free schreiben ...

    bei einem spiel wo ich den server bei mir aufm root hoste ist da extrem schlampig gearbeitet: nach 3-4 tageb 50-60MB memoryleaks also für meine begriffe mehr als nur schlampig... es handelt sich um Raven Shield und desse stand alone dedicated server.



  • Das ist ja garnichts.

    Vietcong 1 dedicated server: Paar hundert MB alle 24 Stunden 😃
    Da heißts jeden Tag neu starten oder crash.

    Trotzdem der beste egoshooter.

    VIETCONG 1 FOR EVER!

    MfG


  • Mod

    bei 60MB in 24h muss es kein memleak sein, es kann auch durch speicherfragmentierung kommen oder logs die gespeichert werden.



  • LinkeT schrieb:

    also memoryleak-frei proggen geht ... mann muss nur bei jeder funktion wo man new/malloc verwendet gleichzeitig am ende oder im destructor das zu gehörige delete/free schreiben ...

    Nichtmal. Es gibt ja auch noch auto_ptr und Ähnliches.



  • Das ist genauso komisches Gerede wie dass ein GC vor Memory Leaks schütze. Klar, es ist ganz einfach. Einfach immer nen smart-pointer benutzen, so leicht ist das Leben. 🤡 👍

    Ich überlasse jedem selber die Entscheidung was er leichter findet. Ich ziehe GC vor, da muss man aber auch aufpassen dass man nichts verbockt und muss profilen und die Speichernutzung analysieren, damit er nicht zum Flaschenhals wird.

    Dafür hat man ohne GC anderes Probleme, durch Fragmentierung, mögliche Fehler durch benutzen eines deallokierten Objekts, usw. und es ist nicht einfach immer "an delete denken" oder "smartpointer benutzen" Jeder kann sich da sein Gift aussuchen.



  • LinkeT schrieb:

    pc und linux ???
    eher windows und linux

    und xbox360 mit c++ ?? wenn es ne stl gibt ok so weit ich weis gibts danur xna und das ist automatisch mit c# gebunden ... also fällt da irgendwas flach 😉

    Dein Wissen ist falsch.



  • da ham die was geändert ... die S.... xD


Anmelden zum Antworten