# Java für große Spiele geeignet ?



## Chris787 (27. Apr 2011)

Ich möchte anfangen Java zu lernen und später damit auch ein Spiel machen, jetzt wollte ich aber vorher fragen ob man mit Java auch große Spiele machen kann mit einer "rießigen Welt" .
Was ich auch noch gerne wissen möchte, welche Bücher könnt ihr mir als Anfänger empfehlen?


----------



## darekkay (27. Apr 2011)

Mit Java lässt sich so ziemlich "alles" realisieren - möchtest du aber speziell in Richtung Spieleprogrammierung gehen, würd ich dann doch zu etwas anderem greifen (C++/OpenGL bsp.)


----------



## s4ke (27. Apr 2011)

Naja, jMonkeyEngine ist doch schon ein Projekt, das sich sehen lassen kann?


----------



## Chris787 (27. Apr 2011)

Und was hat C++ für Vorteile gegenüber Java, ist das leichter zu lernen?


----------



## Network (27. Apr 2011)

Chris787 hat gesagt.:


> Und was hat C++ für Vorteile gegenüber Java, ist das leichter zu lernen?



Vorteile:
Diverse Komponenten in Sachen Stabilität und Geschwindigkeit wie zum Beispiel DirectX. Bei Java nicht direkt implementiert, geht aber auch, ist nur viel umständlicher.

Java ist jedoch hundertmal einfacher zu lernen als C++. C++ ist sowas von extrem Programmiererunfreundlich... Ich bin glücklich, als C#/C++ Programmierer auf Java umgestiegen zu sein.


----------



## Firephoenix (27. Apr 2011)

Hi,
Es gibt ja schon einige Artikel die Java auf Spieletauglichkeit analysieren und als Ergebnis findet man eigentlich an vielen Stellen, dass sich Java durchaus für taugliche große Spiele eignet.
Viel Performance zieht man sowieso aus geschickteren Algorythmen als aus der Wahl der Sprache.
Im Spielebereich wird trotzdem hauptsächlich zu C-Varianten gegriffen, da diese sich dort einfach eingebürgert haben, einige Spiele sind aber trotzdem in Java entstanden oder am entstehen.
(Ein Beispiel für ein Java-Game ist z.b. League of Legends)
Gruß


----------



## Gastredner (27. Apr 2011)

Zuallererst sollte dir erst einmal klar sein, dass du nicht ein halbes Jahr lang Sprache XY lernen und anschließend in der Lage sein wirst, "große Spiele" zu programmieren. Dafür solltest du wesentlich mehr Zeit einplanen, denn zum Entwickeln von Software benötigt man mehr als nur das Wissen um Syntax und einfachen Gebrauch der gewählten Sprache.
Daher ist es für den Anfang vermutlich sowieso irrelevant, ob sich Java für die Entwicklung sher anspruchsvoller Spiele eignet. Nimm dir eine Sprache, lerne sie, arbeite damit und wenn du dann genug Erfahrung hast, dann beginne an deinem Spiel zu arbeiten oder eine Sprache zu lernen, die dies einfacher gestaltet. Der Vorteil: du hast bereits Erfahrung in der Entwicklung und musst im optimalen Fall nur die neue Syntax sowie die individuellen Fallstricke und Eigenheiten der neuen Sprache lernen, das restliche Prozedere kannst du aus deiner Erfahrung heraus übertragen.
Meine Empfehlung wäre daher: such dir eine Sprache (ich finde Java z. B. ganz hübsch) und nähere dich in kleinen Schritten (Syntax und Tools lernen und beherrschen -> einfache Übungen -> kleine Programme -> einfache kleine Spiele -> größere Programme -> komplexere Programme/Spiele -> etc) deinem Ziel an und spezialisiere dich dabei auf die Dinge, die für die Spieleprogrammierung wichtig sind (z. B. DirectX- oder OpenGL-Programmierung, im Java-Umfeld eher letzteres). Sobald du soweit bist, kannst du erst einmal versuchen, dein Spiel mit Java zu entwickeln. Sollte sich dies als unfruchtbar erweisen, sattle um auf eine andere Sprache. C# würde sich dann beispielweise anbieten, aufgrund der Nähe zu Java.
Alternativ könntest du dich auch gleich mit C# beschäftigen und später dann XNA zur Entwicklung von Spielen nutzen, anstatt deine eigene Engine von Grund auf zu schreiben. Oder lerne UnrealScript und setze dich mit dem UDK auseinander. Viele Wege führen nach Rom, und auch wenn der Java-Weg länger sein mag, so dürfte er durchaus ans Ziel führen (verglichen mit anderen Wegen vielleicht sogar mit durch die zusätzliche Zeit erkauften Boni).


----------



## darekkay (27. Apr 2011)

Firephoenix hat gesagt.:


> (Ein Beispiel für ein Java-Game ist z.b. League of Legends)



LoL ist kein Java-Game. Das Spiel selbst ist, wie hätte es anders sein können, in C++ geschrieben. Java wird nur für die Server benutzt.



> we use at least the following languages here
> C++ (the core game is written in this)
> Lua (core game)
> C# (game tools)
> ...



Quelle


----------



## Marco13 (27. Apr 2011)

Der klassische Link zum Quake2-Klon in Java: Bytonic Software

Hab' neulich Videos von Battlefield 3 und der CryEngine gesehen :shock: Natürlich würde man sowas nicht in Java machen :lol: Aber alles, wovon ein einzelner Mensch (oder auch ein Team von semiprofessionellen Programmierern mit einem Budget von weniger als 10 Millionen Dollar) es auch nur in Erwägung ziehen könnte in Erwägung zu ziehen (sic) es umzusetzen würde man mit Java um ein vielfaches einfacher und schneller hinbekommen. "Schneller" ist hier primär in bezug auf den Zeitaufwand zu verstehen, aber auch in bezug darauf, dass ... es "relativ wenige" Menschen gibt, die überhaupt C++ programmieren können, verschwindend wenige, die "gut" C++ programmieren können (auch wenn nicht ganz so wenige das glauben  ) und diejenigen, die gut und effizient C++ programmieren können sich dessen bewußt sind und sich ohnehin auf anderen Levels bewegen als wir "Script-Kiddies" hier in unserem "Java will auch mal eine Programmiersprache werden wenn es groß ist"-Forum.
(Nicht so erst nehmen  )


----------



## Noctarius (27. Apr 2011)

Einige Daedalic Entertainment Games (z.B. Edna bricht aus) sind komplett Java


----------



## Gast2 (27. Apr 2011)

Chris787 hat gesagt.:


> jetzt wollte ich aber vorher fragen ob man mit Java auch große Spiele machen kann mit einer "rießigen Welt" .


ja sicher ... in meiner Welt (vgl. Signatur) benötigst Du in Realzeit ca. 80 Jahre (bei einer Auswertung pro Woche) ... ist Dir das groß genug?

es kommt darauf an was für ein Spiel Du mit Java machen willst


----------



## EgonOlsen (27. Apr 2011)

Chris787 hat gesagt.:


> ...ob man mit Java auch große Spiele machen kann mit einer "rießigen Welt" .


Ja, z.B. Minecraft...


----------



## Firephoenix (28. Apr 2011)

darekkay hat gesagt.:


> LoL ist kein Java-Game. Das Spiel selbst ist, wie hätte es anders sein können, in C++ geschrieben. Java wird nur für die Server benutzt.
> 
> 
> 
> Quelle



Mist, da war tatsächlich meine Info falsch  Und die Server von denen sind ja kein gutes Beispiel...

Aber das Minecraft erst so spät kommt finde ich lustig, bei uns in der uni kennt das eig. jeder der info studiert 
Gruß


----------



## Evil-Devil (28. Apr 2011)

Was verstehst du denn unter einem "großen Spiel"? EIn umfangreiches/großes Spiel muss nicht zwangsläufig mit Grafiken glänzen.

Java-Games die mir neben Minecraft pauschal noch einfallen.

Tribal Trouble
Starfarer

LWJGL Project Page: lwjgl.org - Home of the Lightweight Java Game Library

JGO Forum: JavaGaming.org - home of the largest java game developer community

Ansonsten Google anschmeißen und nach den Games suchen


----------



## Kr0e (1. Mai 2011)

Ohne Witz, der Thread sollte nicht weitergeführt werden... Das endet sonst wo 

Java ist prinzipiell genauso gut für Spiele geeignet... C++ Überlegenheit ist vorbei... Es gibt nur einen Grund, warum beständig auf C++ gesetzt wird: Die meisten Engines (Havok etc.) sind nunmal in C++ geschrieben.. und man schreibt ne Engine nicht mal eben in 5 min.. Ergo macht es einfach keinen Sinn für die Firmen erstmal ne neue Engine in Java zu schreiben, die sich mit bereit bestehenden und seit Jahren erprobten Engines vergleichen lässt.

Mal GANZ daonv abgesehen, dass C# bald eher geeignet ist. Das .NET Framework ist genial und bietet managed Direct X was unter vielen Gesichtspunkten besser ist... C++ besitzt unzählige Altlasten.. solange du nicht iwelche Treiber schreiben willst, vergiss C/C++.

Vom Syntax her tun die sich wenig... C++ bietet ein paar unschöne Paradigmen, die eigentlcih als unsicher gelten... 

Also, Spiele sind in Java mehr als möglich, viele wurden bereits realisiert...

Frag doch direkt, ob es möglich ist, mit einem Auto zu fahren 

jMonkeyEngine ist zur Zeit der beste Anhaltspunkt für eine 3D-Engine in Java.. Aber es gibt vieeele mehr:

Ardor3D, jPTC, Slick(Ok, das ist 2D ), Espresso3D, Java3D, ogre4j(Cool!)... es gibt noch mehr.. aber die anderen fallen mir grad nich ein..

Aber meine Vorredner haben Recht: Wenn du alleine ein  Spiel kreierst, muss dir klar sein, dass das ne MENGE Arbeit ist.
Du brauchst eigentlcih ein Team um alle Bereiche (Webauftritt, Art&Design, Sounds&Effekte, Netzwerk ggf.) abzudecken.

....

@Marco13:

C++ ist nichts magisches, was nur die Auserwählten können. Ich habe Erfahrung mit C++ und muss sagen: Es ist ähnlcih wie bei Java: Es kommt nur darauf an, die existierenden Frameworks und Engines zu beherrschen. Kein vernünftiges C++ Projekt würde ich z.B. ohne Zusatzbibliotheken wie "C++ Boost" beginnen. Bei Spielen würde ich dann OGRE oder Irrlicht nehmen... Alles ähnlcih einfach gehalten, wie jMonkeyEngine... Das sind doch alles nur Sprachen ... Jeweils mit Vor und Nachteilen...

Und der Fakt, dass man als "Skriptkiddy" nichts großes auf die Beine stellen kann, hat nichts mit der Sprache zu tun, sondern ist schlicht und einfach ein Zeitproblem. Auch der MegaHighendC++Programmierer würde Probleme haben, ein Spiel zu schreiben. Das Problem ist ja nicht die dahinter stehende Technik, sondern alles vernünftig in adequater Zeit zu verbinden...


----------



## Noctarius (1. Mai 2011)

Gerade C# wird sich unter Windows / XBOX / Windows Phone schnell durchsetzen dank XNA


----------



## Fu3L (1. Mai 2011)

Ich bin gerade dabei mich in die JMonkeyEngine einzuarbeiten und bin wirklich überrascht, wie leicht man die Grundlagen eines Spiels damit erstellen kann. Ein Tag konzentriertes Tutoriale lesen und ich habe eine Spielfigur, die über ein Terrain läuft, dessen Relief durch eine Heightmap individuell vorgegeben werden kann. Inklusive Frei-beweglicher Kamera, Physik, HUD (Head-Up Display) und Multithreading-support. Die Dokumentation der Klassen an sich ist leider etwas dürftig, aber vieles wird in den Tutorials erklärt und zur Not kann man auch den mitgelieferten Quelltext zu Rate ziehen.

Betreffend der "riesiegen Welt": Das Terrain, dass ich erstelle is ziemlich groß (das ganze "Spiel" belegt 500 MB Arbeitsspeicher^^), aber mein Prozessor (die langsamste denkbare Variante des i7 für Notebooks^^) lässt sich davon beim Umherlaufen nichts anmerken. Zugegebenerweise habe ich auch keine Objekte außer die Spielfigur platziert... 

Durch den JIT läuft Java ja sowieso schon optimiert und die JMonkeyEngine reicht viele Befehle an OpenGL weiter, sodass dort eh native Methoden aufgerufen werden. Der Performanceunterschied ist also, wenn überhaupt, nur gering.
Selbst die Physik-Engine von JMonkey, die noch in Java implementiert ist, soll laut demjenigen, der gerade dabei ist, sie auf native Methoden umzustellen, genauso schnell laufen, wie die native Implementierung (jMonkeyEngine.org | Groups | Troubleshooting - Physics | Forum | Performance of jBullet
Dafür musst du dich nicht mit Dingen rumschlagen, durch die ich meinen Versuch, C++ zu lernen, entnervt beendet habe, wie Speicherverwaltung (zumindest nur ein wenig^^) oder (für mich als Java-Muttersprachler am schlimmsten) das ganze Referenzen/Pointer etc. Gewirr inklusive .h files und undurchsichtige Compilerfehlermeldungen^^


----------



## Titanpharao (1. Mai 2011)

Schließe mich meinen Vorrednern gern an. Wenns nicht gerade Crysis 2 werden soll, sollte Java immer ausreichen.

Habe selbst ein großes Spiel am laufen,ist zwar kein 3D, hat aber mehr "Inhalt" als so manches andere Solo-RPG. (3D n der Spielgröße würde man auch niemals allein hinbekommen, ich arbeite jetzt schon 3 Jahre dran.)

IMoY Wujinyou

Vielleicht kommt noch Sound dazu ... experimentiere gerade etwas rum, wobei ich sagen muss das es sehr bescheident ist, was es zu Sound & Video AKTUELLES auf dem Markt gibt ... das meiste ist vor 2007 entstanden. Knobel immer noch mit meinem Sound schneller/langsamer abspielen Problem. Dafür gibts jetzt ein Intro-Movie  aber nur unter Windows


----------



## Noctarius (1. Mai 2011)

Nett wenn es auch noch an NES / SNES erinnert aber Hut ab davor das durchzuziehen


----------



## ProgX (1. Mai 2011)

@Titanpharao: Gefällt mir auch ganz gut!


----------



## Marco13 (1. Mai 2011)

Kr0e hat gesagt.:


> Ohne Witz, der Thread sollte nicht weitergeführt werden... Das endet sonst wo


Wie üblich werden sich einige Zweige in Diskussionen darüber verlieren, welche Sprache oder welches Framework das beste ist, und zwei (oder mehr) "Seiten" werden ihre Argumente auflisten und ignorieren und ignoriert werden. Es gibt Pros und Cons, jeder mag sich selbst ein Bild machen.




> C++ ist nichts magisches, was nur die Auserwählten können. Ich habe Erfahrung mit C++ und muss sagen: Es ist ähnlcih wie bei Java: Es kommt nur darauf an, die existierenden Frameworks und Engines zu beherrschen.



Definitiv richtig. Mein Einlass bezog sich auf damit verwandte Dinge: Java macht einen zweifellos vieles leichter als C++. Das fängt bei low-level-Sprachaspekten an (Speicherverwaltung) und geht über medium-level Dinge (Klassenstrukturen und Methodensignaturen, in C++ viiiieeel schwieriger "gut" zu machen als in Java), bis zu high-level-Dingen wie Frameworks und deren Verwendung. Letzteres auch wieder auf mehreren Ebenen: Vom Einbinden (in Java: Rechtsklick auf JAR->"Add to build path", in C++ ... beliebig kompliziert, was die Hemmschwelle, andere Libs einzubinden, dramatisch erhöht) bis zur API-Doku, die bei Java fast prinzipedingt vollständiger (weil einfacher zu generieren) ist, als ein nebenher erstelltes (und IMHO auch nicht so übersichtliches) Doxygen.

Sicher ist auch an C++ nicht "magisches". Ich wollte (vereinfacht gesagt) andeuteten, dass es viel, viel, viel einfacher ist, ein "guter Java-Programmierer" zu sein, als ein "guter C++-Programmierer". Ich weiß zumindest, dass es Leute gibt, die meinen, sie würden ("gut"???) C++ programmieren, und verwenden zum Zahlen/String-Konvertieren dann atoi & Co, schreiben sich ihre eigene String- oder Vector-Klasse weil "...da sind noch ein paar praktische Zusatzfunktionen dabei" :autsch:, lesen Files über "File"-Objekte, kennen die STL nur vom Hörensagen, und meinen allen ernstes: "Ach, ob die Methoden und Variablen nun private oder public sind ist doch egal..." (Auch wenn das teilweise nichts mit der Sprache zu tun hat). Der Aufwand für ein "gutes Programm" ist bei C++ um mehrere Größenordnungen (!) höher - einerseits auf "intellektuell-akademischer" Seite, bezogen auf die Fähigkeiten und den Wissensstand über die Sprachdetails und best practices, andererseits als auch in bezug auf den Code, den man am Ende hinschreiben muss.

Ich habe schon lange nichts mehr mit C++ gemacht, aber bei dem wenigen, was ich gemacht habe, seit ich mit Java arbeite, habe ich gemerkt, dass sich mein Programmierstil stark an Java anlehnt: Alles sind Pointer, alles erstmal komplett virtuelle Klassen, usw... Um die Sprache nicht nur für "low-level-Programmierung" sondern für Softwareentwicklung auf einem sinnvollen, übergeordnet-abstrahierenden Level nutzen zu können, kommt man um Dinge wie boost's shared_ptr IMHO eigentlich nicht drumrum, und konsequent weitergedacht ... (C++-Fans werden mich jetzt hauen  ) ... bindet man erstmal 50 Libs ein, damit man mit 100mal komplizierterer Syntax so ähnlich programmieren kann wie mit Java von vornherein


----------



## Titanpharao (1. Mai 2011)

@Noctarius/ProgX dann spielst doch auch mal, ab besten wärend der Arbeit :-D oder UNI und hinterlasst mal einen Eintrag ins Forum :-( das so Leeeeeer ...

Glaube nicht das NES schon PNG Bilder hatte ^^ aber sonst kommts da ganz gut ran ja ...


----------



## Kr0e (1. Mai 2011)

@Marco13:

Da hast du Recht... C++ läd oft zum schlechten Stil sein... Alleine mal die Zusatzbibliothek Boost ans Laufen zu kriegen ohne mit Fehlermeldungen zugemüllt zu werden... Ich persönlich war immer geheimer Fan von C++ (Hab damit angefangen), aber je mehr ich mit Java (Und auch C#) gemacht habe, desto unangenehmer fand ich C++. Java und C# sind eben im Gegensatz zu C++ produktive Sprachen wo man nich erstmal die Nägel geradebiegen muss, bevor man ein  Baumhaus baut 

Gruß,

Chris


----------



## Gast2 (1. Mai 2011)

Noctarius hat gesagt.:


> Nett wenn es auch noch an NES / SNES erinnert aber Hut ab davor das durchzuziehen



das Problem ist für einen Informatiker weniger das Programm bzw. Spiel - als die Grafik und Sound :-( ... ich werde das gleiche Problem haben, wenn ich anfange einen eigenen Client für mein Spiel zu schreiben


----------



## Fu3L (1. Mai 2011)

mogel hat gesagt.:


> das Problem ist für einen Informatiker weniger das Programm bzw. Spiel - als die Grafik und Sound :-( ... ich werde das gleiche Problem haben, wenn ich anfange einen eigenen Client für mein Spiel zu schreiben



Ohh jaa ... Ich habs geschafft, dass ein künstlerisch begabter Freund von mir sich das 3D-Modelling aneignet.. Aber selbst wenn man bereit ist viel zu lernen, kann man nicht eben stimmige Hintergrundmusik (am besten noch mit Harven oder anderen exotische Instrumenten) kreieren... Und Sounds von Seiten wie freesound.org zusammenzuzimmern, ist wahrscheinlich* auch höchstens eine Übergangslösung... 

Ich habe noch nicht viel Zeit mit demDurchstöbern des Archivs verbracht und kann es daher nicht mir Sicherheit sagen^^

Edit: Um einen  Bezug zum Thread Thema herzustellen: Mit der JMonkeyEngine ist es wenigstens relativ einfach Sounds über OpenAL im Dreidimensionalen Raum abzuspielen. Also auch dies klappt gut mit Java


----------



## Ulathar (17. Jun 2011)

ooohja... ich hab auch so meine liebe not mit dem erstellen von 3D models... textures gehen noch halbwegs (Paint style!! ).

aber zum thema:

evtl ist diese tabelle aufschlussreich:
Google Publishes C++, Go, Java and Scala Performance Benchmarks


----------



## Marco13 (17. Jun 2011)

*seufz*. Irgendwann schreib' ich mal einen Benchmark, bei dem Java gewinnt :joke:


----------



## Ulathar (17. Jun 2011)

dazu zitiere ich mal das schlusswort aus dem link oben:



> The phrase "lies, damn lies and benchmarks" is by now a cliche. Suffice it to say, benchmarks never tell the full story, and there are many factors to consider when choosing a programming language. That said, you may find parts of this paper enlightening, especially with regards to Scala performance.



sagt ja keiner, dass das 100%ig eindeutig ist . ich bin und bleibe auch bei java einfach weils "idiotenischer" ist (naja fast ^^).
wenn ich überlege, wieviel mehraufwand ich in c/c++ betreiben muss um eine saubere speicherverwaltung sicherzustellen und auch dieses verdammt unübersichtliche headergedöhns mit den .h files und namespaces.... nee da verzicht ich im zweifelsfall lieber auf performance und bleib bei java.

zumal die 3D darstellung für games oder sonstiges ja so oder so nativ ausgeführt wird.


----------



## ARadauer (17. Jun 2011)

> ich bin und bleibe auch bei java einfach weils "idiotenischer" ist


naja... das würde ich jetzt nicht unterschreiben...


----------



## Illuvatar (17. Jun 2011)

Zu dem Google-Paper möcht ich jetzt dann doch noch folgendes Zitat anbringen:


> Jeremy Manson brought the performance of Java on par
> with the original C++ version. This version is kept in the
> java_pro directory. Note that Jeremy deliberately refused
> to optimize the code further, many of the C++ optimizations
> would apply to the Java version as well.


----------



## Marco13 (17. Jun 2011)

Hmja, da hat auch bei dem Blog-Eintrag jemand drauf hingewiesen. Ich hatte das Paper nur überflogen, und dort kam dann hat sowas wie List<Set<Integer>> vor :autsch: Klar sind das die zur Verfügung stehenden Sprachmittel, und es wäre schön, wenn Primitive Collections Teil der API (oder besser: Teil der Sprache an sich!) wären, aber geben tut's die schon...


----------



## masii (30. Aug 2011)

Vielleicht ganz interessant für den ein oder anderen. Ein ehemaliger NCsoft Programmierer hat an einem MMO Client in Java und der jMonkeyEngine gearbeitet. 

Unter seinem Youtube Video ist auch sein Blog verlinkt.


----------



## Ulathar (30. Aug 2011)

hui der editor (video in seinem blog) würd mich ja mal brennend interessieren, vor allem dessen source code!


----------



## Noctarius (30. Aug 2011)

Die jMonkeyEngine gehörte eine Weile lang NCsoft und wurde maßgeblich von denen für ein Projekt vorangetrieben. Dann wurde das Projekt leider eingestampft.


----------



## Paddelpirat (30. Aug 2011)

Naja das Video sieht nicht schlecht aus, aber im Vergleich zu dem was auf dem Markt ist, kann ich schon verstehen, dass man sich dann doch für andere Ansätze entschieden hat. Fragt sich natürlich noch aus welchem Jahr der Content im Video stammt.


----------



## Fu3L (30. Aug 2011)

Ich hab mich mal noch mehr schlau gemacht, was Engines angeht und wenn man heute liest:

CryEngine 3 frei für nicht kommerzielle Projekte, bei kommerziellen Projekten 20% an CryTek
UnrealEngine 3 frei für nicht kommerzielle Projekte, bei kommerziellen Projekten einmalig 99 € und dann ab 50k Gewinn 25% an Epic Games
Quake 3 Arena Engine unter GPL

Da kommt man schon in Versuchung alles mit Java aus der Liste zu streichen^^


----------



## Paddelpirat (30. Aug 2011)

Vor allem sind diese Engines auch erprobt und es gibt den nötigen Support von den Entwicklern, falls was nicht so auf Anhieb funktioniert. Ich glaub bei Java müsste man sehr vieles selber Regeln, was den Support und das Testen betrifft.


----------



## Kr0e (30. Aug 2011)

DAs Problem ist eben, dass es keine Infrastruktur gibt für Spiele. Die Firmen treiben leider diesen Ansatz nie voran. An und für such ist JAva durchaus geeignet aber ohne Support von den großen Firmen mit GEld wird das leider nichts...


----------



## Empire Phoenix (30. Aug 2011)

Naja dafür kann ist die Quake engine schrott aus heutiger sicht vonner grafic, da is jme schon meilenweit vorraus was Shader und so angeht.

Bei den anderen beiden biste sowie du irgetwas im sourcecode machen must verlassen oder zahlst mal schnell nen paar millionen.


----------



## Evil-Devil (31. Aug 2011)

Millionen jetzt nicht gerade, aber allein die Tatsache das heutige AAA Engines aus sehr viel Middleware bestehen bzw. sich zusammensetzen lassen.

Da wären u.a. SpeedTree, Lightmass, Havok,  RAD, Scaleform und wie sie alle heißen. Das kann man nicht mal so eben aufholen.


----------



## Noctarius (31. Aug 2011)

Och das es geht zeigen immer wieder plötzlich auftauchende, neue Engines.
Zuletzt waren da die CryEngine (die auch noch nicht wirklich alt ist) und die Whiteengine von SquareEnix (FF XIII / FF XIIII).


----------



## Paddelpirat (31. Aug 2011)

Hmm die sieben Jahre von der Cryengine (seit dem ersten Spiel damit) ist schon eine lange Zeit und im Vergleich zur Unreal Engine die deutlich älter ist, ist sie nicht sehr weit verbreitet, das kommt wohl erst noch. Und bei der White Engine würde ich mal behaupten, dass die Entwickler einfach genug Geld mit den vorherigen 12 FF-Teilen gesammelt haben *g*.

Naja aber die Frage ist ja eigentlich: Wieso sollte man überhaupt versuchen ein AAA Spiel mit Java zu machen? Welche Vorteile sollte Java gegenüber C, bzw. evtl. C++ haben, die die Entwicklungskosten einer vergleichbaren Engine rechtfertigen würden? Damit die Spiele auch unter Linux laufen?


----------



## Ulathar (31. Aug 2011)

Wart mal ab bis die neue Consolen Generation raus ist. Dann werden DEUTLICH mehr Spiele auf CryEngine Basis erscheinen, darauf kannst du wetten.
Evtl geht dann auch endlich mal die Entwicklung der KI voran. So gut die Grafik mittlerweile ist, so mies ist die KI.
Ich als leidenschaftlicher PC Zocker verfluche jedenfalls diese blöden Kästchen fürs Wohnzimmer (Consolen) die heut zu Tage die "Leadplatform" darstellen .

Das is wie fahren mit angezogener Handbremse ^^.


----------



## Fu3L (31. Aug 2011)

Ich habe Mr. Molyneux verflucht, weil er Fable 2 nicht für den PC hat erscheinen lassen 

Für ein gutes, großes Spiel muss es aber auch nicht immer eine Triple A Engine sein. Die von Fable 1 würde mir vollkommen reichen^^ Dieser Comic-Stil hat eben auch seinen Reiz und es hat mich kaum ein Spiel bisher so in seinen Bann gezogen wie Fable 1 (aber da kommen auch noch so Sachen wie die Vertonung dazu), obwohl die Kämpfe zu leicht waren^^
Natürlich fehlen da die Objekte, die von Physik beeinflusst werden und pflanzenbewachsener Boden, aber grafisch ist die mMn super^^


----------



## Evil-Devil (31. Aug 2011)

Das deutlich mehr Spiele auf Basis der CE3 herauskommen werden muss sich erst noch zeigen. Es ist halt immer die Frage wie schnell/leicht man eine Engine "vergewaltigen" kann. Die Unreal Engine hat sich von einer Outdoor FPS Engine zu einem Allrounder gemausert. Neben dem MMO Branch (hat CE2 auch) kann man eben sehr schnell viel erreichen. Der Sandbox Editor der CryEngine kann ja ähnliches, nur hat es Crytek bisher versäumt seine Engine vernünftig zu vermarkten. Da ist Epic eindeutig Marktführer.

@Warum Java: Weil man es kann? weil es sauberer sein kann. Ok, die aktuellste Version von C++ hat nun auch diese ganzen neuen Multicore Features, doch wird sich die Industrie wohl kaum auf eine andere Sprache einigen, nur weil es dort Features gibt die C/C++ nicht hat. Dann schreibt man halt einen Workaround...

@Warum von C++ wechsel: Warum sollte man Milliarden Investitionen wegschmeißen? Man schmeißt einen JEE Server auch nicht einfach weg, nur weil manches anderswo einfacher/komfortabler ist.

Letzten Endes bleibt es an uns hängen, dass man etwas schafft das von anderen verwendet werden kann. Ich fände zb. einen JavaFX Export ähnlich der Funktionsweise von Scaleform geil.


----------



## Empire Phoenix (31. Aug 2011)

Naja in java grafisch geht eigntlich problemlos mit jbullet gibts auchen halbwegs gute physicengine (kann zumindest mit der der source engineprobemlos mithalten).

Warum jetzt java? Sobald man eine der großen engines nimmt muss man auch deren Toolsets nehmen.
Das kann teils super sein, aber es besteht immer die chance das man an eine grenze trifft, und dann ist man wenn man nciht gerade großkunde ist oder sourcecodezugriff kauft aufgeschmissen.

In Java kann man schneller das selbe wie in c++ erreichen durch geringeren Programmieraufwand.
Spiele in java kann man auch relativ problemlos auf mac und linux benutzen/ verkaufen.

Wenn ich ein reines Grafikblenderspiel amchen will, würde ich aber auch zu einer der großen engines tendieren, erst bei speziellen Krams hat mand avon mehr anchteile als vorteile.

(Beispielsweise wäre Minecraft mit den genannten Engines eher schwer möglich gewesen, mangels guter lowlevel api's für meshmanipulationen)


----------



## schalentier (1. Sep 2011)

Empire Phoenix hat gesagt.:


> In Java kann man schneller das selbe wie in c++ erreichen durch geringeren Programmieraufwand.



Mit solchen pauschalen Aussagen waere ich vorsichtiger. Wenns so stimmen wuerde, wuerde es mehr in Java geschriebene Spiele oder Engines geben.

Das Hauptproblem (und gleichzeitig einer der groessten Segen) seh ich darin, dass man keine Kontrolle ueber den Speicher hat. Sobald man mit richtig vielen Daten arbeitet (durchsuchen, auf Festplatte auslagern, nachladen, etc), kaempft man eigentlich meistens gegen den geliebten Garbage Collector. Und diese Engines machen eigentlich nur eins: grosse Datenmengen an Dreiecken durchsuchen und nur sichtbare an die Grafikkarte schicken. 

Das zweite Problem (und gleichzeitig der zweitwichtigste Segen) sind die fehlenden Pointer. Hat man grosse Datenmengen und will auf einzelne Informationen zugreifen, nimmt man mit C/C++ nen Pointer auf ne struct und setzt den auf die korrekte Position im Speicher. Mit Java speichert man entweder alles in einem eignen Objekt (OOP) oder versucht mit ByteBuffer & Co den fehlenden Pointer nachzubauen. Letzeres ist meistens (ab einer gewissen Datenmenge) schneller als Fuer-Alles-Ein-Objekt, aber der Code wird noch viel unleserlicher als äquivalenter C/C++ Code. Und zumindest in genau diesem Fall ist C/C++ einfach schneller ;-)

Das dritte Problem (und ja, der drittwichtigste Segen) ist die Hardwareabstraktion. Die Algorithmen die bei Unreal, CryTech oder der SourceEngine eingestetzt werden sind unter Garantie mit viel Wissen ueber die Hardware optimiert. Da sind sicherlich einige Kniffe und Genialitaeten drin versteckt, die man mit Java einfach nicht nachbauen kann (auch wenns am Ende nur ein paar Zeilen Assembler sind, um nochmal 0.2% mehr Frames zu schaffen). 

Letzlich sind diese Engines ja nicht viel anders als die JVM: Die "VM" dort bietet nur mehr Zeug fuer grafiklastige Probleme an. 

Ich will damit nicht sagen, dass man mit Java keine Spiele programmieren kann - Minecraft ist wohl das beste Gegenbeispiel - aber ich wuerde Java auch nicht als _die_ Sprache fuer jeden Zweck herausstellen.


----------



## Noctarius (1. Sep 2011)

Naja ich kann auch in Java (zu mindestens in aktuellen Versionen) direkt auf dem Speicher manipulieren. 


> A direct byte buffer may be created by invoking the allocateDirect factory method of this class. The buffers returned by this method typically have somewhat higher allocation and deallocation costs than non-direct buffers. The contents of direct buffers may reside outside of the normal garbage-collected heap, and so their impact upon the memory footprint of an application might not be obvious. It is therefore recommended that direct buffers be allocated primarily for large, long-lived buffers that are subject to the underlying system's native I/O operations. In general it is best to allocate direct buffers only when they yield a measureable gain in program performance.



Oder z.B. MappedByteBuffer (MappedByteBuffer (Java Platform SE 6))


----------



## Gast2 (1. Sep 2011)

Noctarius hat gesagt.:


> Naja ich kann auch in Java (zu mindestens in aktuellen Versionen) direkt auf dem Speicher manipulieren.



klingt ja interessant - damit könnte man durchaus auch Treiber "schreiben"


----------



## schalentier (1. Sep 2011)

Mit direct byte buffers habsch auch schon rumexperimentiert. Ich meine aber sowas:

In einem aktuellen Projekt hab ich ein 13 Byte langen Key. Der dient als Key in einem BTree. Natuerlich kann man nun beim Erzeugen des Keys aus den Eingangsdaten (es handelt sich um Koordinaten) diesen nun byteweise berechnen. Aber es ist deutlich flinker, einfach 3x nen Integer zu berechnen und die zu setzen. Das geht leider nicht mit den direct buffers. Das 13. Byte muss dann uebrigens wieder als Byte angesprochen werden.

In C/C++ ist das einfach ne struct oder man greift direkt auf den Datenstrom zu (z.B. um alles auf die Platte auszulagern). 

Ja, man kann all das auch mit Java machen, aber ich rede grad von wirklich vielen dieser 13-Byte-Keys. Und genau da kann Java (ganz prinzipiell) einfach nicht mit C/C++ mithalten.


----------



## Noctarius (1. Sep 2011)

@Mogel:
Naja geht so, dazu gehört ja schon noch etwas mehr.

Wir haben die MappedByteBuffer auf einem Gameserver eingesetzt um die fast 800MB Geodaten "in den Speicher" zu laden 

@schalentier:
Geht doch auch mit einem BitSet (http://download.oracle.com/javase/6/docs/api/java/util/BitSet.html)?


----------



## schalentier (1. Sep 2011)

Noctarius hat gesagt.:


> Geht doch auch mit einem BitSet?[/url]



Ich bezweifel mal, dass ein BitSet schneller gefuellt ist, als 3 Integer und 1 Byte hintereinander in den Speicher zu schieben. Zudem vermisse ich am BitSet ein compare (das brauch ich fuer den BTree). Und die Keys nun bitweise zu vergleichen... das ist unter Garantie langsamer, als ByteBuffer.compareTo. Mit C koennte ich uebrigens 3 Ints und ein Byte vergleichen, was nochmal deutlich schneller ist, als 13 Bytes zu vergleichen.


----------



## Evil-Devil (1. Sep 2011)

Empire Phoenix hat gesagt.:


> Warum jetzt java? Sobald man eine der großen engines nimmt muss man auch deren Toolsets nehmen.
> Das kann teils super sein, aber es besteht immer die chance das man an eine grenze trifft, und dann ist man wenn man nciht gerade großkunde ist oder sourcecodezugriff kauft aufgeschmissen.


Das kommt stark auf die Engines drauf an. Ich hab die letzten 10 Jahre als Hobbyist mit der Unreal Engine gearbeitet. Mit dem Editor und den verfügbaren Schnittstellen konnte man soweit sehr vieles ohne den Source erstellen. Jetzt mit den SDKs von CryEngine, UDK (UnrealEngine) etc sind noch mehr Schnittstellen verfügbar. Zb. bietet das UDK an eigene DLLs einzubinden. Und externe Toolsets ala Maya/Photoshop und Co sind unabdingbar.

Und ich wage zu behaupten, das jemand der nicht gerade ein Highend Game mit neuen Möglichkeiten entwickeln will sich die Engine nicht leisten kann bzw. nicht in der Lage ist selbst zu ermitteln ob die Engine für seine Zwecke geeignet ist. Man muss sich nur mal die Spiele am Markt anschauen welche Features der Engines sie nutzen und welche nicht...


----------



## Empire Phoenix (1. Sep 2011)

Pointers in Java - ein Knol-Artikel von Ajith Joseph

Grid Designer's Blog: Tricks with Direct Memory Access in Java

Java keine Pointer ? Also gehen tut das schon wenn man will.


----------



## huckleberry (1. Sep 2011)

Eigentlich wäre es doch eine logische Folgerung, wenn die JVM, JRE auch in Java geschrieben wäre. 
Meines Wissens ist aber die JVM in C++ geschrieben, hatte ich mal bei SUN gelesen (google search).

Wie der Stand bei der 7er Version ist, weiss ich nicht.. vermute mal auch so?

Warum schreibt man die JVM nicht in Java?


----------



## inv_zim (1. Sep 2011)

huckleberry hat gesagt.:


> Warum schreibt man die JVM nicht in Java?



Auf welcher JVM soll die JVM denn laufen?


----------



## Kr0e (1. Sep 2011)

@Huckleberry:

Was war zuerst da? Huhn oder Ei ? 


Ne, aber mal im Ernst: Java bietet keinen nativen Zugriff. Java ist quasi eine Abstraktion und muss erstmal mit C/C++ implementiert werden.

@Empire Pheonix:

Ok, es gibt Pointersupport... Aber es soll dir ja auch was bringen. Geschwindigkeitsvorteile machst mit dieser Variante die vorallem auf com.sun.* Pakete angewiesen ist nicht. C Pointer sind schon nochmal was anderes 

Aber ich wüsste nicht, warum man Pointer braucht, um highend Spiele zuschreiben - DAs ist ne ganz andere Frage!


----------



## huckleberry (1. Sep 2011)

Kr0e hat gesagt.:


> Was war zuerst da? Huhn oder Ei ?



Haha  Ja, dass die allererste JVM in einer bereits bestehenden Sprache geschrieben sein muss, is ja klar.. aber mittlerweile gibt es ja javacompiler bereits.. also ist das ja kein HenneEi problem.. einfach exakt die selbe Funktionalität in Java nachbauen sozusagen.. :bae:

Analog: Der allererste C-Compiler wurde in asm oder so geschrieben, aber mittlerweile gibts es ja c compiler.. also kann man ja in c schrieben


----------



## Kr0e (1. Sep 2011)

Ich denke, der Hauptgrund ist einfach, dass es iwo keinen Sinn machen würde. Wenn man eine Sprache implementieren will, die auf native Resourcen zurückgreift (z.b. direkte ByteBuffer) und nun implementiert man die Sprache mit Java... Dann würde man spätestens bei den direkten ByteBuffern (ES gibt zahllose andere Bereiche wo nativer Zugriff benötigt wird) auf JNA, JNI zurückgreifen müssen was also das ganze Vorhaben sinnfrei macht...


----------



## Fu3L (1. Sep 2011)

huckleberry hat gesagt.:


> Haha  Ja, dass die allererste JVM in einer bereits bestehenden Sprache geschrieben sein muss, is ja klar.. aber mittlerweile gibt es ja javacompiler bereits.. also ist das ja kein HenneEi problem.. einfach exakt die selbe Funktionalität in Java nachbauen sozusagen.. :bae:
> 
> Analog: Der allererste C-Compiler wurde in asm oder so geschrieben, aber mittlerweile gibts es ja c compiler.. also kann man ja in c schrieben



Die JVM läuft aber zur Laufzeit und nicht zur Kompilierzeit und führt den Java Bytecode aus. Da muss ein mindestmaß an Maschinensprache vorhanden sein, um erst einmal den Bytecode einer in Java geschriebenen JVM zu übersetzen... Das endet in einer Rekursion, wie die Frage danach, wer Gott erschaffen hat, wenn doch alles einen Schöpfer braucht 
Obs mit einem Ahead of Time Compiler möglich wäre, eine JVM in Java zu schreiben, weiß ich nicht, aber dann kann man auch gleich in C++ schreiben^^


----------



## schalentier (1. Sep 2011)

Kr0e hat gesagt.:


> Aber ich wüsste nicht, warum man Pointer braucht, um highend Spiele zuschreiben - DAs ist ne ganz andere Frage!



Braucht man nicht. Aber um das letzte Stueckel aus der Hardware rauszuholen (das tun ja die besagten Engines) sind sie sehr praktisch. 

Schon mal mit OpenGL VBOs gearbeitet? Das sind quasi ByteBuffer, die direkt an die Grafikkarte geschickt werden koennen. Dort kann man z.B. Vertexinformationen (Koordinate, Farbe, Normale, etc) ablegen und dann sehr viele Dreiecke auf einmal zeichnen. In C/C++ wuerde das so aehnlich aussehen:


```
struct {
  float x, y, z;
  rgba_t color;
  byte nx, ny, nz;
} vertex_t;

vertex_t *buffer = ...
buffer->x = 10; // erster vertex
buffer ++;
buffer->x = 20; // zweiter vertex
```
Analog geht natuerlich auch Lesen. (bin mir mit der Syntax nicht sicher, aber irgendwie so geht das jedenfalls)

In Java:

```
public class Vertex{
  float x, y, z;
  Color color;
  short nx, ny, nz;
  public void write( ByteBuffer bb ) { bb.putFloat( x );  //... }
}
ByteBuffer bb;
Vertex v = new Vertex( 10, ... ); //erster
v.write(bb);
...
```

Im Worstcase hast du dann alle Vertexdaten doppelt im RAM. Einmal korrekt OOP modelliert als Instanz von Vertex und einmal "komprimiert" im ByteBuffer. Sicher kann man versuchen, dass alles irgendwie direkt auf dem Buffer zu machen oder mit so kruden Geschichten wie diese Unsafe Klasse. Aber dann macht man doch kein Java mehr und koennte genauso gut gleich C++ nehmen.

Und wenn man doch mit Java das gleiche machen kann wie mit C++ (ausser ne JVM) und dazu noch einfacher - warum gibts dann keine High-End-Spiele, die komplett in Java geschrieben sind? 

Achso und nen Treiber, der erstmal ne JVM hochfahren moechte, faend ich auch sehr unpraktisch


----------



## Kr0e (1. Sep 2011)

Mit VBOs noch nicht aber intensiv mit PBOs, dort könnte es ähnliche Probleme geben. Ich denke der Hauptgrund ist ganz einfach... Die Engines, auf denen bisher alles aufbaut sind eben in C/C++ geschrieben. Also wäre es 1. für die Firmen zu teuer/schwachsinnig ihre alten Produkte wegzuschmeißen und iwas from scratch neu zuschreiben. Außerdem sind die meisten Entwickler bei solchen Firmen (Spielefirmen) vermutlich(größtenteils) mit C und den Libraries in C vertraut. Hier kämen erneut Kosten auf die Firmen hinzu.

Außerdem geht es ja uahc nicht nur um Highendspiele. Immerhin gibt ja wirklich kaum(fast garkeine) kommerziellen Javaspiele (Ok, Minecraft mal ausgenommen  - Guter Anfang!). Also ich sagmal z.B. Strategiespiele könnte man ohne jegliche Probleme mit Java machen - Aber es macht eben keiner weil der eventuelle Nutzen (Plattformneutral) nicht im Verhältnis steht zu den neuen Ausgaben.


----------



## Kr0e (1. Sep 2011)

schalentier hat gesagt.:


> Achso und nen Treiber, der erstmal ne JVM hochfahren moechte, faend ich auch sehr unpraktisch



Jagut, dafür ist Java auch nicht gedacht (gemacht)... So lowlevel Zeugs kann man ruhig in C schreiben.


----------



## Guest2 (1. Sep 2011)

Moin,



Kr0e hat gesagt.:


> Außerdem sind die meisten Entwickler bei solchen Firmen (Spielefirmen) vermutlich(größtenteils) mit C und den Libraries in C vertraut. Hier kämen erneut Kosten auf die Firmen hinzu.




imho ist das der entscheidende Punkt. Bei dem, was man als Außenstehender z.B. auf gamasutra.com über die Entwicklung von Spielen zu lesen bekommt, scheint sich die Spieleentwicklung vollkommen unabhängig von der Anwendungsentwicklung entwickelt zu haben.      Praktisch dürften Entwickler zwischen den Gebieten nur mit relativ großem Aufwand wechseln können. Und gute Spieleentwickler mit ausreichenden Java Kenntnissen sind vermutlich einfach eine Minderheit. Wenn sich dann noch ein Studio bei einem Publisher um (richtig viel) Risikokapital bewerben muss, dürften die nicht gerade die Spendierhosen anhaben, wenn dann rauskommt, dass nur wenig erfahrene Leute an Bord sind.

Aus technologischer Sicht spricht imho höchstens die Anbindung an die Grafikkarte bzw. Soundkarte gegen die Verwendung von Java. JOGL und LWJGL sind zwar tolle Projekte, aber ein eigenes möglicherweise millionenschweres Projekt daran aufzuhängen, ist nicht ohne.

Ansonsten halte ich Java aber eigentlich für die perfekte Sprache zur Spieleentwicklung. Java und die Toolchain darum sind einfach unglaublich effizient. Auch ein frischer Wind von "neuen" Technologien / Verfahren würde imho der Spielentwicklung guttun. Ich habe z.B. noch von keinem kommerziellen Spiel gelesen, das DI einsetzt, während es in der kommerziellen Anwendungsentwicklung fast Usus ist.

Auch die hier angesprochenen "Nachteile" von wegen Pointerarithmetik und direkten Speicherfummeleien halte ich für nicht mehr sonderlich relevant. Ich wüsste z.B. nicht, warum mich der Inhalt eines VBO noch interessieren sollte? Der wird als binärer Datenstrom eingelesen und 1:1 auf die Grafikkarte geschoben. Occlusion culling, collision detection und die Animationen macht dann die GPU. Die CPU sieht Dreiecke doch höchstens noch innerhalb von Entwicklungstools, z.B. um die Geometriedaten vorzubereiten. Früher als man noch BSP oder Octrees fürs rendering nutzen musste, sah das natürlich anders aus.

Gruß,
Fancy


----------



## schalentier (1. Sep 2011)

Ich glaub ohne konkreter zu werden ist eine sinnvolle Diskussion nicht wirklich moeglich. 

Fancy, auch heute braucht man noch Octrees oder BSP. Du hast Recht, es muss nicht mehr so viel wie vielleicht frueher in der CPU berechnet werden, aber es ist auch heute nicht zweckmaessig, das komplette Level oder die komplette Welt in die Grafikkarte zu laden. Dafuer reicht ihr Speicher auch ueberhaupt nicht aus. Aber auch das stimmt so nicht unbedingt, denn wenn es sich um ein komplett statisches Level handelt, koennte man schon wieder drueber nachdenken, es doch komplett in die Graka zu hauen...

Machen wir es doch konkret: Was ich aktuell versuche, so viele Wuerfel (jaja, Minecraft geschaedigt) mit Java darzustellen wie nur irgendwie moeglich (nur Farbe, keine Textur). Die Welt sollte eine maximale Groesse von 2ˆ31x2ˆ31x2ˆ31 adressieren koennen. Dargestellt werden muessen natuerlich nur Dreiecke, die man auch sehen kann. Derzeit schaff ich mit Java, LWJGL ca 20 Frames bei einer Kugel von 10 Cubes Radius. Was nicht besonders ist.

Meine C Implementierung kann zwar noch keine Dreiecke malen, aber suuuper schnell den Octree-Baum durchsuchen. Da benutz ich uebrigens intensiv Pointerarithmetik und Bitgefummel. ;-)


----------



## Kr0e (1. Sep 2011)

Es ist mit Java genauso wie mit jeder anderen Sprache: Die PErformance hängt fast zu 100% von der Programmierung ab. Die paar Prozent.... Java beherrscht dafür multihreading besser als jede andere Sprache von Haus aus und die mitgelieferten Tools sind ebenfalls geil.

Aber bevor hier eine Java vs. C Debatte losgeht (Ich höre bei dir eindeutig heraus, dass du C bevorzugst und vermutlcih dafür auch deine GRünde haben wirst), sollte man besser aufhören 

Gruß,
Chris

EDIT: Wenn deine Javaimpl sehr viel langsamer ist, als deine C-Variante, müsste man schauen woran es liegt. LWJGL ist nicht sehr viel langsamer als C, sofern überhaupt overhead entstehen sollte... Kann es vlt am Garbage Collector liegen ? (also vlt iwie in einer Schleife ständig neue Objekte erstellen oder so ?)


----------



## Guest2 (1. Sep 2011)

schalentier hat gesagt.:


> [..]das komplette Level oder die komplette Welt in die Grafikkarte zu laden[..]




Ziemlich genau so stand es Ende der 90er in einem Nvidia Paper. 

In der Tat sind viele Welten aber inzwischen zu groß geworden, um das so noch effizient handhaben zu können. Auch der Einsatz von baumartigen Datenstrukturen ist natürlich sinnvoll. Allerdings hat das heute nichts mehr damit zu tun wie z.B. Carmack die BSPs in Doom gebaut hat. Das Stichwort dazu occlusion culling (diesmal mit Link ) hab ich ja bereits erwähnt. Das Entscheidende daran ist, dass die Grafikkarte sagt, welche Knoten des Baumes aktuell sichtbar sind und welche nicht. Ein Durchwühlen von Dreiecken oder großen Speicherbereichen ist dann nicht mehr notwendig. Und damit dann auch nicht mehr die Speicherfummeleien.



schalentier hat gesagt.:


> Derzeit schaff ich mit Java, LWJGL ca 20 Frames bei einer Kugel von 10 Cubes Radius. Was nicht besonders ist.



Hast Du mal versucht, wie schnell das ist, wenn Du keinerlei Optimierungen anwendest? Das dürften doch grob geschätzt gerade mal ~64k Dreiecke sein? Die Grafikkarte macht frustum culling und backface culling eh selbst. Und von dem Rest wird ein ganzer Haufen vom depth test verworfen. Das passiert alles so früh, dass es der Grafikkarte faktisch nichts ausmachen sollte. Verglichen mit dem occlusion culling von oben, wäre Deine Kugel in etwa die Größenordnung ab der man überlegen könnte für die ein kleines Blatt anzulegen. Sprich, wenn die Grafikkarte sagt, die Boundingbox der Kugel wäre sichtbar, werden alle Würfel der Kugel gezeichnet. Eine Optimierung in kleinere Strukturen kostet normalerweise mehr als es bringt.

Bei Deinem Vorhaben würde ich ggf. ehr an geometry instancing oder allgemein an Spielereien mit dem geometrie shader denken, als zu versuchen die tollsten ausgefuchsten Bäume aufzuspannen.

Gruß,
Fancy


----------



## Empire Phoenix (2. Sep 2011)

Der fall da schreit nach geometry batching, 64k dreieicke? da lohnt nicht eine einzige cpu basierte optimierung (ausser vielleicht frustrum cullung) Hau mal alle geomettry datan in eine einzelnes Mesh, und benutz dann entsprechend nen Texturatlas. Der witz an minecraft ist ja das es eben nciht allles aus einzelnen Würfln zusammen setzt.

Das Java hierbeie twas langsamer ist wird schlichtweg am höheren overhead durch jni liegen. Aber da dein draw system algorithmisch sowieso eine katastrophe ist macht das auch soviel aus. Normalerweise spürt man sowas kaum.

Zudem die Frage wie zeichnest du das in java und wie in c++, ? engines oder opengl calls?


----------



## schalentier (2. Sep 2011)

Guest2 hat gesagt.:


> Hast Du mal versucht, wie schnell das ist, wenn Du keinerlei Optimierungen anwendest? Das dürften doch grob geschätzt gerade mal ~64k Dreiecke sein?



Genau, ca 60k Dreiecke sind das. Ohne Octree gehts logischerweise viel schneller, allerdings skaliert es nicht. Wie gesagt, meine Welt ist prinzipiell 2^(31*3) Wuerfel gross.



Guest2 hat gesagt.:


> Sprich, wenn die Grafikkarte sagt, die Boundingbox der Kugel wäre sichtbar, werden alle Würfel der Kugel gezeichnet. Eine Optimierung in kleinere Strukturen kostet normalerweise mehr als es bringt.



Das Problem ist, die Kugel ist nicht als "Kugel" modelliert, sondern das sind einfach ein paar Cubes in der Welt, die zufaellig in Form einer Kugel angeordnet sind. Aber natuerlich ist es korrekt, den Octree nicht bis zum Ende zu verfolgen, sondern irgendwann (z.B. bei 256^3 Cubes) diese direkt zu rendern.



			
				Empire Phoenix hat gesagt.:
			
		

> Der fall da schreit nach geometry batching, 64k dreieicke? da lohnt nicht eine einzige cpu basierte optimierung (ausser vielleicht frustrum cullung) Hau mal alle geomettry datan in eine einzelnes Mesh, und benutz dann entsprechend nen Texturatlas. Der witz an minecraft ist ja das es eben nciht allles aus einzelnen Würfln zusammen setzt.



So einfach ist das nicht. Die Cubewelt kann natuerlich veraendert werden, sonst waere es ja langweilig. Natuerlich koennte man die Teile, die gerade nicht veraendert werden, in eine Mesh kompilieren und die dann rendern. Allerdings muesste man die dann verwerfen, wenn sich was aendert und ein neues Mesh kompilieren. Bin mir nicht sicher, ob das am Ende schneller wird.

Minecraft rendert alles aus einzelnen Wuerfeln. Die einzige Optimierung dort ist, dass nur solche Wuerfelseiten gemalt werden, die zwischen einem festen Block und einem Luftblock liegen (nur die kann man sehen). Das will ich natuerlich auch so machen, aber dafuer fehlt mir aktuell eine schnelle Moeglichkeit, die Nachbarn in einem Octree zu finden. Und hier zeigen meine Experimente, dass ich da mit C deutlich schneller bin. Also deutlich. 

Rendern tue ich uebrigens mit LWJGL.


----------



## Empire Phoenix (2. Sep 2011)

Schnller biemr egnereiren:
Ist es, und zwar mehrere hundermal, natürlich ncit ein einzlenes mesh sondern chunks die aus zb 32x32x32 blöcken bestehen. 

Minecraft rendert alles aus einzelnen Wuerfeln.
FALSCH! das stimmt nicht, das packt die sichtbaren faces zusammen in ein einzelnes Mesh pro chunk und benutzt auch textureatlanten.

Vollkommen egal ob mit c++ oder ajva bei ca. 10k objecten bricht jede consumer grafikkarte langsam aber sicher zusammen. Meistens schon früher.


----------



## Kr0e (2. Sep 2011)

Empire Phoenix hat gesagt.:


> Minecraft rendert alles aus einzelnen Wuerfeln.
> FALSCH! das stimmt nicht, das packt die sichtbaren faces zusammen in ein einzelnes Mesh pro chunk und benutzt auch textureatlanten.



Ja, das hab ich auch mal gehört. Ich finds faszinierend, dass das wirklich schneller ist... Das Zusammenfassen zu einem Mesh müsste doch theoretisch kurze "Lags" verursachen, oder wie kann man sich das vorstellen ?


----------



## schalentier (2. Sep 2011)

Also als ich mir das ziemlich genau angesehen hab, wurden alle sichtbaren Dreiecke in ein VBO gepackt und direkt gerendert. Keine Meshs. Kann aber sein, dass sich da was geaendert hat.


----------



## Empire Phoenix (2. Sep 2011)

Von mir aus ist es ein VBO, aber die logic ist identisch, es Batcht die objecte, ob jetzt in ein mesh, oder in ein VBO. Auf jeden fall weiß ich aufgrund von einem im JME forum das das mit einem Mesh ähnlich bis besser läuft. 

Mythruna - Role Crafting Game


Zu de lags.

bei 50fps hat man 20ms pro frame.
Es wird sich normalerweise nicht mehr als 0-4 chunks pro frame ändern. Und die zeit pro die man bracht um das mesh neu zu generieren ist irgetwo um 2 ms. 4*2 ms = 8 ms dann bleiben noch 12 für die restliche logik, was normalerweise bei sinnvollem update loop keine Probleme machen sollte. Also im prinzip sind microlags da aber in geringen ms bereich, das kann unserer Auge schlichtweg nicht wahrnehmen. (Und meshes können problemlos geupdated werden. ich sage nur animationen!). Der minmale Zeitverlust beim zusammenfassen ist wenn das intelligent  angegangen wrid vernachlässigbar.

ProTip: Geänderte chunks ersmal als einzlene boxen rendern, und im Hintergrund einen zweiten Thread die optiierungen machen lassen, dannach durch das optimierte Mesh  austauschen, dann ist die minimale verzögerung auch eleminiert.


----------



## schalentier (2. Sep 2011)

Jetzt hau mal bitte nicht alles wild durcheinander.

Display Lists != VBO. Das hat miteinander nichts gemein, ausser dass beides OpenGL ist. Mit Display Lists kann man eine komplexe Geometrie in die Grafikkarte laden und dann mit einem Befehl darstellen. Nebenbei kann man ein solchen Mesh transformieren und auch "schachteln" (Nested Display Lists). Das ist super schnell und die wohl effizienteste Moeglichkeit, abertausende Dreiecke zu rendern - und mittels Transformationen auch animierte Bone-Meshes realisieren. 

Allerdings kann man die Display Lists _nicht_ aendern. Man kann sie nur wegwerfen und erneut uebertragen - wie du jetzt auf 2ms kommst, weiss ich nicht.

VBO sind ByteBuffer, die sauschnell Daten in die Grafikkarte schieben. Unter anderem die Daten fuer Display Lists. Oder einfach Dreiecke, die gerendert und sofort "vergessen" werden. Das ist der Weg, wie Minecraft programmiert ist.

Multithreaded OpenGL ist mir auch grad neu. Glaub ich ehrlich gesagt nicht, dass man parallel irgendwelche OpenGL Befehle abschicken kann. 

PS: OpenGL FAQ / 16 Display Lists and Vertex Arrays


----------



## Guest2 (2. Sep 2011)

schalentier hat gesagt.:


> [Display Listen:]Das ist super schnell und die wohl effizienteste Moeglichkeit, abertausende Dreiecke zu rendern




Display Listen sind veraltet und werden von den aktuellen GL-Profilen nicht mehr unterstützt. In Hartware werden diese ebenfalls nicht mehr unterstützt, GL2-Treiber setzen diese in Software um. Abgesehen von einigen alten Bürorechnern unterstützen alle Plattformen VBOs, sodass diese verwendet werden sollten, wenn auch veraltete Hartware unterstützt werden soll. Die aktuelle OpenGL Spezifikation sieht VBOs, welche an ein VAO gehangen werden, als einzige Möglichkeit vor um Vertexdaten an die GPU zu übertragen (neben Vertex Arrays (VA sind (heute) wie VBO nur ohne Buffer)). glDrawArrays und glDrawElements (und Ihre Verwandten) sind die einzigen Befehle, welche ein Zeichnen anstoßen sollten.

Die Dokumentationen und FAQs zu OpenGL sind leider teilweise völlig veraltet (auch auf opengl.org). Das Einzige, was immer aktuell ist, ist die jeweilige Spezifikation.




schalentier hat gesagt.:


> [VBOs:]Oder einfach Dreiecke, die gerendert und sofort "vergessen" werden.




Wie die Daten intern optimiert werden, hängt vom 4. Parameter bei glBufferData ab: z.B. STREAM_DRAW, STATIC_DRAW, DYNAMIC_DRAW. "Vergessen" werden sollte da aber nichts. Das Anlegen des Buffers ist relativ teuer, wenn sich die Daten regelmäßig ändern, ist z.B. DYNAMIC_DRAW das Mittel der Wahl. 




schalentier hat gesagt.:


> Multithreaded OpenGL ist mir auch grad neu. Glaub ich ehrlich gesagt nicht, dass man parallel irgendwelche OpenGL Befehle abschicken kann.




Das ist ein schwieriges Thema. Die Kurzfassung ist, dass man es nicht sollte. Das hindert Dich aber nicht daran, Deine Vertexdaten auf einem CPU-Thread vorzubereiten und dann mit dem GL-Thread an die GPU zu übertragen. Wird mit dem GL-Thread viel auf der CPU berechnet, kommt es bei der GPU zu Wartezeiten und damit zum einbrechen der Framerate.




schalentier hat gesagt.:


> Genau, ca 60k Dreiecke sind das. Ohne Octree gehts logischerweise viel schneller, allerdings skaliert es nicht. Wie gesagt, meine Welt ist prinzipiell 2^(31*3) Wuerfel gross.



Wie sieht den Deine Datenstruktur genauer aus? Sprich, was speicherst Du wenn von Deinen 2^(31*3) Würfeln alle gesetzt sind, außer einer Handvoll an freien Plätzen?

Gruß,
Fancy


----------



## schalentier (2. Sep 2011)

Guest2 hat gesagt.:


> Wie sieht den Deine Datenstruktur genauer aus? Sprich, was speicherst Du wenn von Deinen 2^(31*3) Würfeln alle gesetzt sind, außer einer Handvoll an freien Plätzen?



Aktuell hab ich ein Octree, den ich in einem BTree speichere. Dazu berechne ich fuer jeden Octree Knoten einen eineindeutigen Key aus den Koordinaten und dem "Level" des Knoten. Dafuer verwende ich den Morton Code. In kurz: Aus den drei Koordinaten (x, y, z) wird eine Bitfolge berechnet, bei der zuerst die jeweils ersten Bits von x, y und z kommen, dann die zweiten Bits usw. Liest man dann immer 3 Bits (2^3 = 8) ergibt sich der Pfad durch den Octree Baum.

Dann hab ich ein View Frustum (bestehend aus 6 Flaechen), mit dem ich den Baum rekursiv durchlaufe. Alle Octree Nodes, deren Bounding Sphere komplett ausserhalb des Octrees liegen, werden ignoriert. Von allen anderen gehts rekursiv an deren Kinderknoten. Das wird bis zum Level 31 gemacht, dort wird dann der Cube gerendert. 

Das Rendern selbst ist total simpel, es werden einfach alle Vertexdaten in ein VBO geschrieben, sobald es voll ist, wird es an die Grafikkarte geschickt. Hier ist noch seeeehr viel Potential zum Optimieren.

Wuerde man jeden Knoten im Octree setzen, braeuchte man alleine fuer die Keys 13*2^(31*3) Bytes Platz. Das ist natuerlich praktisch nicht moeglich - aber es sind ja auch noch so viele offene Ende, an denen man optimieren kann (sind alle Kindknoten belegt, muss man nur diese Information speichern, nicht jedes Kind). 

Das Ganze ist auch nur ein kleine Experiment, um einer Antwort auf die Frage naeher zu kommen, wieviele Cubes man mit Java so rendern kann.
Aktuell schreib ich das Berechnen des Morton Codes und den BTree in C neu - und will dann bisschen mit JNI rumspielen ;-)


----------



## Fu3L (2. Sep 2011)

Lasst mich diesen Thread auch noch etwas zweckentfremden: Wie schwer ist es, von einem C++ Programm aus ein .jar anzusprechen/einzubinden? (Falls ich mal was größeres basteln will und es nützlich sein sollte für was anderes. Dann will ich nich merken, dass ich alles in C++ umschreiben muss^^)


----------



## Kr0e (2. Sep 2011)

Hey Fu3L,

ähm. Auf deine Frage ansich kann ich dir keien Antwort geben. Aber ich glaube, dass du ansich nicht in so eine Situation kommen dürftest. Lass dich hier nicht irre führen, Java ist nicht massivst langsamer als C, wie es hie rmanchmal den Anschein hat. Es komm auf die Art und Weise an, wie du programmierst. Wenn du clever vorgehst, gibt es kaum einen Unterschied.

Um deine Frage vlt. geringfügig zu beantworten: Ich halte es nicht für sinnvoll eine Java aus C heraus zu starten/benutzen. Was genau hat denn dann C für einn Vorteil, wenn du dann eh auf Java zurückgreifst. Die Zeiten wo Java langsam war, sind vorbei. Die C Junkies wollen das niuch so gern einsehen, aber Java ist eine echte Konkurrenz und um einiges produktiver. Fährst du lieber nen neuen, schicken Audi oder nen uhralten, unzerstörbaren VW Bus ? 

Gruß,
Chris


----------



## Fu3L (3. Sep 2011)

Deswegen frage ich ja, ob man Java aufrufen kann (das würde ich ja nicht tun, wenn ich Java für vollkommen ungeeignet hielte). Ich habs letztens sogar im C++ Forum gewagt Java als "wenn nicht schneller" zu bezeichnen^^ 

Nur wenn ich in Java (Spiel)logik schreiben möchte (was ich tun will, hab da ne (umfangreiche) Idee, die mich wohl einiges an Zeit und Lernaufwand* kosten wird^^) und das vorerst zum Test einfach spartanisch irgendwie darstelle, aber das später weiterverwenden kann, dann wäre ich ja evtl. mit den vorhandenen C++ Libraries zur Darstellung besser beraten und es wäre dann ätzend, den Java Teil wieder umzuschreiben^^

*: Was mir besonders Spaß macht, bin neugierig^^


----------



## Kr0e (3. Sep 2011)

Bleib bei dem was du kannst/magst. Solange nciht ein großer böser, unwissender Boss hinter dir stehst steht und dich zwingt gegen deinen Willen mit Zahnbürsten das Deck zu schrubben,solltest du die Frieheit haben, alles selbst zu entscheiden. Das ursprüngliche Thema entfernt isch immer mehr 
Java ist nicht langsamer als C und selbst wenn, dann würden das höchetns Benchmarks zeigen. Vlt muss man bei Java auf andere Programmierparadigmen setzen als bei C, aber Fortschritt ist meistens gut  Ich bin froh, das man nciht mehr gezwungen ist, mit dem alten C/c++ arbeiten zu müssen (Sofern man nicht für anderes bezahlt wird ;-) ). Die Firmen verhalten sich wie Strom, der Weg des geringsten Widerstandes. Ok, es fehlen vergleichabre Engines in Java, aber das Potenzial ist bei weitem vorhanden. Allein Eclipse RCP oder Netbeans RCP... Man hat sooooviel Out-of-the-box... ICh habe danaks hin und wieder mit C/c++ gearbeitet und es war nie ein vergnügen. Die 3-7 % die man an Leistung gewinnt, rechtfertigen nicht den Stress der Compilierprobleme oder generell mangelnden Sprachmitteln. 

Im Endeffekt muss man sich entshceiden: Nimmt man C und setzt auf nostalgische Werte oder nimmt man moderne Srpachen (Auch C# + .NET ist eine tolle Sache!), die einem helfen, Ziele zu erreichen anstatt einen daran zuhindern.


----------



## Guest2 (3. Sep 2011)

schalentier hat gesagt.:


> Dann hab ich ein View Frustum (bestehend aus 6 Flaechen), mit dem ich den Baum rekursiv durchlaufe. Alle Octree Nodes, deren Bounding Sphere komplett ausserhalb des Octrees liegen, werden ignoriert. Von allen anderen gehts rekursiv an deren Kinderknoten. Das wird bis zum Level 31 gemacht, dort wird dann der Cube gerendert.




Ok, das ist nicht genau das, auf was ich hinaus wollte bzw. es ist schon zu detailliert.

Wenn Deine Welt aus einem XYZ-Koordinatensystem besteht, deren Achsen jeweils 2^31 Einheiten aufweisen, dann sagt das erstmal nur etwas über den möglichen Adressraum aus. Nicht jedoch darüber, wie viele Objekte darin vorkommen und auch nicht, was eine realistische Problemgröße ist.

Beim Speichern von Blöcken in Deiner Welt fallen mir spontan erstmal 3 Möglichkeiten ein (erstmal ohne jegliche zusätzliche Verwaltungsstruktur):

Sei ohne Beschränkung der Allgemeinheit und vollkommen willkürlich die Spielwelt 1 GByte groß und die Nutzinformation jedes Blocks 4 Byte groß (z.B. für die Farbe)

1. Speicherung der Blöcke als direktes Array:

Dann ergibt sich direkt aus der Position des Blocks im Array die Position des Blocks in der Welt. Der Speicherverbrauch eines Blocks ist dann lediglich 4 Byte, sodass (bei 1GByte) insgesamt 268435456 Blöcke vorhanden sein können. Die Speicherung des vollen 2^(3*31) Adressraum würde 4096 Yottabyte benötigen. Bei 1GByte ist die Kantenlänge auf lediglich 645 Einheiten beschränkt. 
- Also viel zu klein.

2. Speicherung der Blöcke als jeweilige XYZ-Koordinate:

Jeder Block benötigt nun 16 Byte (XYZ und die Farbe). Es können bei 1GByte also 67108864 Blöcke gespeichert werden. 
- 70M + X Blöcke scheint mir eine realistische Problemgröße.

3. Speicherung der Blöcke als Flächen:

Es werden keine einzelnen Blöcke mehr gespeichert, sondern das Ganze ist als Mesh Manipulation aufgebaut. Schlimmster Fall, wenn jemand ein 3D Schachbrett baut, dann können die Flächen nicht zusammengefasst werden bzw. es müssen mindestens die Koordinaten gespeichert werden bei dem sich die Farben ändern. Dann benötigt ein Block ~2*XYZ und die Farbe macht 28 Byte. 1GByte bietet also Platz für ~38347922 Blöcke. 
- Aufwendig und ist evtl. schlechter als Version 2.


Alle drei Varianten sind aber ganz weit weg von 2^(3*31), so das die Größe des Adressraums keinen sonderlich großen Einfluss auf das Laufzeitverhalten der Anwendung hat. Ein Occtree mit einer Tiefe von 31 (!) und Berücksichtigung des Frustum erscheint mir übertrieben, selbst wenn die Spielwelt 1TByte umfassen sollte.

Eine aktuelle Mittelklasse-Grafikkarte hat einen (geschönten) Durchsatz an Dreiecken von ~800MTriangles/s. Bei 12 Dreiecken pro Block und 60 FPS würde das ~1M Blöcke bedeuten (halte ich aber für unrealistisch). Nichtsdestotrotz, bei einer Auflösung von jeweils 2^31 Einheiten sind die weiter entfernten Blöcke viel kleiner als ein Pixel. Ein Blick von einem Ende der Welt zum Anderen ist also ohne zusätzliches LOD eh nicht möglich.

Imho, sollte es reichen einfach alle Blöcke die ungefähr in der Nähe der Kamera liegen an die Grafikkarte zu schicken. Die verwirft schon alles, was sie nicht brauchen kann, dafür ist sie schließlich da.



schalentier hat gesagt.:


> Das Ganze ist auch nur ein kleine Experiment, um einer Antwort auf die Frage naeher zu kommen, wieviele Cubes man mit Java so rendern kann.
> Aktuell schreib ich das Berechnen des Morton Codes und den BTree in C neu - und will dann bisschen mit JNI rumspielen ;-)




Ok, wenn Du dann mit C das Maximum bestimmt hast, kannst Du das Beispiel ja mal hier posten. Ggf. poste ich dann mal zum Vergleich ein Beispiel in Java (wenn ich Zeit hab auch evtl. schon vorher).




Fu3L hat gesagt.:


> Lasst mich diesen Thread auch noch etwas zweckentfremden: Wie schwer ist es, von einem C++ Programm aus ein .jar anzusprechen/einzubinden? (Falls ich mal was größeres basteln will und es nützlich sein sollte für was anderes. Dann will ich nich merken, dass ich alles in C++ umschreiben muss^^)





Kr0e hat gesagt.:


> Aber ich glaube, dass du ansich nicht in so eine Situation kommen dürftest. Lass dich hier nicht irre führen, Java ist nicht massivst langsamer als C, wie es hie rmanchmal den Anschein hat. Es komm auf die Art und Weise an, wie du programmierst. Wenn du clever vorgehst, gibt es kaum einen Unterschied.



Volle Zustimmung. Ich würde sogar behaupten, dasselbe Programm, geschrieben einmal in Java und einmal in C, von einem jeweils durchschnittlich begabten Programmieren und mit demselben Zeitaufwand ist in Java schneller. Erst wenn der C-Programmierer ganz viel Zeit und Können reinlegt, wird er ein etwas schnelleres Programm entwickeln können. 


Gruß,
Fancy


----------



## Fu3L (3. Sep 2011)

Wie gesagt, ich behaupte nicht, dass C++ für irgendeines meiner Ziele besser geeignet wäre. Nur die C++ Infrastruktur in Sachen Games/Grafikdarstellung (wie sich hier im Thread festellen ließ).

Deswegen lasst mich meine Frage etwas ausschmücken:
Die großen Engines nutzen alle eine Skriptsprache, um die eigentliche Spiellogik umzusetzen, bilden also eine Schnittstelle zu einer anderen Sprache, die allerdings direkt von der Engine interpretiert wird.

Was wäre nun, wenn ich einen Teil der Logik*  in Java schreiben würde und dann das ganze später für was größeres wiederverwenden und eine C++ - Engine zur Darstellung nutzen wollte? Wäre das möglich oder übertrieben viel extra Aufwand? Erstmal prinzipiell. Ob es dann daran scheitert, dass man nicht an den SourceCode kommt, sei erstmal egal. An dem Punkt käme ich eh alleine nicht mehr weiter^^ 
Ich will halt nicht lange an etwas arbeiten, was vllt sogar mal echten Mehrwert bekommt mit der Zeit und dann merken, dass ich besser anders hätte anfangen sollen^^

*: Konkret wo ich drüber nachdenke: Das Generieren einer Welt und das Wirtschaftssystem innerhalb dieser Welt. Damit will ich erstmal was "kleines" in 2,5D baun. An Ideen mangelt es nicht.


----------



## Guest2 (3. Sep 2011)

Fu3L hat gesagt.:


> Wie gesagt, ich behaupte nicht, dass C++ für irgendeines meiner Ziele besser geeignet wäre. Nur die C++ Infrastruktur in Sachen Games/Grafikdarstellung (wie sich hier im Thread festellen ließ).



Das ist alles relativ. Wenn Du Beziehungen zu einen Publisher oder einen 8-stelligen Kontostand hast und fest entschlossen bist Dein eigenes Studio zu gründen, um ein AAA-Titel zu entwickeln, dann ja in C gibt es bessere Unterstützung. Auch wenn Du das nur zur Übung machst und später in die kommerzielle AAA-Spieleentwicklung wechseln willst, ist C ebenfalls besser. Dort wird gewöhnlich von Einsteigern Beispielcode erwartet. Nach Feierabend unter dem Schreibtisch zu schlafen kann dann aber auch dazugehören (Fehleinschätzungen des Aufwands von 500% - 1000% sind wohl nicht unüblich – mit den entsprechenden Konsequenzen).

Auf der C-Haben-Seite stehen eben die bekannten großen C-Engines, deren Tooling sowie den kommerziellen Support der Anbieter. Auf der C-Soll-Seite die schlechte Infrastruktur der Spache selbst.

Wenn Du das als Hobby machst oder (langfristig) den Casual Markt anstrebst ist wohl Java die bessere Wahl. jME/jBullet sind tolle Projekte und alles was Du (als Einzelner) in Deiner Freizeit realisieren kannst (zeitlich) sollte sich damit umsetzen lassen. Wenn Du mehr / anderes willst, greif selber in die Tasten (ggf. via JOGL / LWJGL). Java ist da viel effektiver als C. Wenn der Java-Entwickler schon fertig ist und in Mittagspause geht, schiebt der C-Entwickler noch h-Dateien durch die Gegend und versucht dabei den Compiler zu beruhigen. Du kannst das dann auch nutzen um Dich Stück für Stück durch die komplette Java-Toolchain zu fräsen, das macht sich dann auch beim späteren Arbeitgeber positiv bemerkbar.

Frei aus einem Postmortem eines AAA-C-Entwicklers (irgendwo auf gamasutra.com): "Ja, continuous integration ist Pflicht, wir brauchen das, um zu sehen ob der Code nach einem commit noch compiliert... Unit-Tests haben wir versucht, die sind aber immer zu Integrationstests degeneriert, die wurden dann weggelassen...". Bei einem Java Entwickler, der was auf seine Toolchain hält, könnte das ein suffisantes Lächeln auslösen. 


(Aber ja, C mit Java verbinden geht (irgendwie) immer. Der Aufwand kann dabei von geht sofort bis beliebig aufwendig variieren. Wirklich notwendig ist das aber nie (ja, Ausnahmen). Bleib bei Java und alles wird gut! )

Gruß,
Fancy


----------



## ThreadPool (3. Sep 2011)

Guest2 hat gesagt.:


> [...]Volle Zustimmung. Ich würde sogar behaupten, dasselbe Programm, geschrieben einmal in Java und einmal in C, von einem jeweils durchschnittlich begabten Programmieren und mit demselben Zeitaufwand ist in Java schneller. Erst wenn der C-Programmierer ganz viel Zeit und Können reinlegt, wird er ein etwas schnelleres Programm entwickeln können.



Da muss man auch in Java ordentlich basteln. C++ bietet noch den hier noch nicht aufgeführten Vorteil der Kompaktheit von Objekten im Speicher. Ein Java-Objekt verbraucht grundsätzlich irgendwie immer ein paar Bytes mehr Speicher, bedingt z.B. durch die Polymorphie von Object usw. zumindest ist das mein letzter Stand als ich mir die Größe eines einfachen C++ Objekts ausgeben lassen habe und die eines Java-Objekts per Profiler gecheckt hatte.
Ein weiterer Vorteil von C++ auf der Speichereffizienzseite ist das nicht alles als "Pointertyp"gespeichert werden muss. Hier merkt man das z.B. bei Immutables. Was ich damit sagen möchte, in Java hat man ein Array vom Typ T, das enthält bestenfalls (nach meinem Kenntnissstand) eine Menge von Pointern auf Objekte der Größe s. In C++ kannst du das aber ohne weiteres so stricken das du ein Array hast das die Objekte selbst enthält, was einem eine bessere "Locality of Reference" gibt.
C# hat dafür glaube ich sogar extra "struct" eingeführt (was in C++ etwas anderes ist) um das zu erreichen, nichtstdestotrotz ist die VM von C# noch nicht auf dem Stand von Java aber das wird kommen.


----------



## Empire Phoenix (3. Sep 2011)

C# hat nur den Nachteil nur auf windows vernünftig zu laufen, kann man natürlich je anch Zeilgruppe vernachlässigen. Hat auch einige schöne Sachen, zb das alle C# programme im Hintergrund von windows nach updates der VM ahead of time compiliert werdne, und daher nicht das Java typische initial lagging haben (klar gibt es auch für java ahead of time compiler, aber leider nicht als fester bestandteil der jvm's).


----------



## Fu3L (4. Sep 2011)

> (Aber ja, C mit Java verbinden geht (irgendwie) immer. Der Aufwand kann dabei von geht sofort bis beliebig aufwendig variieren. Wirklich notwendig ist das aber nie (ja, Ausnahmen). Bleib bei Java und alles wird gut! )



Danke für deine ausführliche Antwort  
Diese klare Aussage von dir hat mich überzeugt, dass ich erst einmal bei Java bleibe und darin mein größeres kleines Spielchen schreibe 
Sollte ich dann später doch noch C++ für mich entdecken wollen, kann ich mich immer noch entsheiden, muss ja eh erstmal 5 Jahre studieren^^ (Wobei ich mir Technische Informatik kaum ohne C(++) Lernen vorstellen kann.. Aber erstmal ein Modul Scheme und eins Java ))).


----------



## schalentier (4. Sep 2011)

So, ich hab am Wochenende nun nochmal alles neu durchdacht und implementiert. Ich hab jetzt einen Octree, dessen Blaetter Chunks von fest definierter Groesse sind, die dann in einem Rutsch zu Dreiecken werden.

Mittels Frustum Culling bestimme ich dann, welche Chunks gerendert werden. Damit schaff ich jetzt ne Kugel mit nem Radius von 230 Bloecken. Guggt man direkt auf die Kugel sinds ca 500 000 Dreiecke, die ich mit 3-4 fps darstellen kann. Fliegt man am Rand der Kugel lang, sinds um die 40fps bei etwa 80 000 Dreiecken.

Der Profiler zeigt nun folgendes Bild:
- 19% der Zeit verbringe ich mit dem Suchen der Nachbarbloecke, die nicht im gleichen Chunk liegen (dazu muss der Octree "durchsucht" werden)
- 30% der Zeit verbringe ich mit dem durchlaufen der Chunks (letztlich eine Schleife ueber x, y und z).
- 50% braucht ByteBuffer.putFloat fuer das Beschreiben des VBO

Das eigentliche Uebertragen zur Grafikkarte spielt keine Rolle (0%)

Die beiden ersten Zeitfresser kann ich sicherlich noch optimieren, aber bei ByteBuffer.putFloat seh ich kaum noch Potential. Und ich bin erst bei 0.5M Dreiecken. Wenn ich Zeit finde, werd ich mal genau dieses Beschreiben des VBO in C programmieren und mittels JNI anbinden. Mal sehen obs was bringt ;-)

Wenn man uebrigens die Chunkgroesse sehr klein macht (auf 2 oder sogar nur 1), steigt der Speicherbedarf massiv an (weil der Octree viel groesser wird), dafuer steigen aber auch die FPS (wenn man net direkt auf die Kugel schaut), da insgesamt einfach weniger Dreiecke gerendert werden muessen.

Fazit: Meine These von oben, dass der Buffer unter Java _deutlich_ langsamer ist als in C/C++ hat sich bisher bestaetigt. Denn die 50% cputime fuer putFloat gaebe es mit Pointerarithmetik einfach nicht.


----------



## Kr0e (4. Sep 2011)

Dazu hätte ich ein paar Fragen:

Wie steht es mit der ByteOrder ? Wenn der Buffer auf Big_ENDIAN steht, dann werden die Floats unter Windows erstmal in Litte_ENDIAN kopiert und dann erst erfolgt der native putFloat befehl. Hatte mal so ein Problem mit dem PBO. Der lieferte auch erst grottige Ergebnisse und es war mir klar, dass das einfahc nicht an Java liegen kann, vorallem weil es sich keiner in anderen Foren erklären konnte.

Wie gesagt, ist nur ne Idee  Ich denke weiterhin, dass iwo anders der Wurm drin ist. Aber siehs mal so: Wenn du C lieber magst, dann nimm doch lieber C...


----------



## Empire Phoenix (5. Sep 2011)

- 50% braucht ByteBuffer.putFloat fuer das Beschreiben des VBO

Regenerierst du den jedes Frame? Wenn ja wozu?


----------



## schalentier (5. Sep 2011)

Was meinst du mit regenerieren?

Ich hab zwei Buffer, die ich wechselseitig mit den Vertexdaten der Dreiecke fuelle. Immer wenn der Buffer voll ist, wird er zur Graka geschickt und der andre zum weiterfuellen genutzt.


----------



## Empire Phoenix (5. Sep 2011)

Wozu, wie gesagt wenn du das ganze mit Meshes machst, kannst du die solange immer wieder rendern wie sich ncihts änderst, und sparst dir somit den größten teil des zeitfressens.


----------



## schalentier (5. Sep 2011)

Wie ich bereits mehrfach gesagt habe, meine Welt ist potentiell unendlich gross. Es ist nicht moeglich alle Dreiecke aller Cubes in die Graka zu stecken. Dafuer reicht der Speicher einfach nicht aus.


----------



## Empire Phoenix (5. Sep 2011)

Niemand sagt dass du alle im Ram/Grakarte halten musst. Kann man zb sehr schön mit paging algorithmen lösen.


----------



## Guest2 (5. Sep 2011)

ThreadPool hat gesagt.:


> [..]C++ bietet noch den hier noch nicht aufgeführten Vorteil der Kompaktheit von Objekten im Speicher. Ein Java-Objekt verbraucht grundsätzlich irgendwie immer ein paar Bytes mehr Speicher, bedingt z.B. durch die Polymorphie von Object usw. zumindest ist das mein letzter Stand als ich mir die Größe eines einfachen C++ Objekts ausgeben lassen habe und die eines Java-Objekts per Profiler gecheckt hatte.
> Ein weiterer Vorteil von C++ auf der Speichereffizienzseite ist das nicht alles als "Pointertyp"gespeichert werden muss. Hier merkt man das z.B. bei Immutables. Was ich damit sagen möchte, in Java hat man ein Array vom Typ T, das enthält bestenfalls (nach meinem Kenntnissstand) eine Menge von Pointern auf Objekte der Größe s. In C++ kannst du das aber ohne weiteres so stricken das du ein Array hast das die Objekte selbst enthält, was einem eine bessere "Locality of Reference" gibt.




Grundsätzlich ist das sicherlich nicht falsch. Allerdings reicht mein Wissen leider nicht um eine wasserdichte Aussage treffen zu können, was nach dem JIT nun immer ganz genau im Speicher steht. Andererseits ist es aber auch z.B. immer noch so, dass ein Array über ein struct von jeweils 64 Byte Größe, im Zugriff schneller ist, als ein Array über ein struct mit jeweils 62 Byte. Sodass es (wenn man auf Zugriffszeiten optimiert) sinnvoll sein kann ein padding von jeweils 2 "dummy" Bytes anzuhängen. Die Zugriffzeiten auf einzelnen Variablen in einem struct (und bei C++ auch bei Objekten) hängt auch von der Reihenfolge (genauer dem Alignment) der einzelnen Variablen ab. So das "kompakt = besser" nicht unbedingt immer gilt. Moderne Compiler sind zwar bei der Optimierung von structs relativ konservativ, wenn man es ihnen aber erlaubt (z.B. weil man weis das keine Referenzen nach "außen" gegeben werden, sehr leistungsfähig. Das, was am Ende rauskommt, hat dann nicht mehr viel mit dem zu tun, was der C/C++ Entwickler hingeschrieben hat (Hartware nahes programmieren ist dann schon relativ). Auch Pointer in Arrays sind erstmal nicht so "schlimm". Aktuelle Prozessoren erkennen solche Situationen relativ zuverlässig über das instruction prefetch / den branch predictor, sodass der Inhalt der relevanten Speicherzellen (zumindest relativ oft) rechzeitig bereitsteht.

Parallel zur Ausrichtung von Variablen im Hauptspeicher (zur Optimierung der Zugriffszeit) gibt es bei OpenGL Vergleichbares. Während es bei VBOs derzeit lediglich Empfehlungen gibt, wie die Daten übertragen werden sollten, entscheidet das bei UBOs der GLSL-Compiler erst zur Laufzeit des Programms (es sei den man deaktiviert diese Optimierung)! Der C-Entwickler kann also gar kein passendes struct mehr anlegen. Imho wird ein äquivalentes Verfahren zukünftig auch für VBOs eingeführt.




Fu3L hat gesagt.:


> Danke für deine ausführliche Antwort
> Diese klare Aussage von dir hat mich überzeugt, dass ich erst einmal bei Java bleibe und darin mein größeres kleines Spielchen schreibe
> Sollte ich dann später doch noch C++ für mich entdecken wollen, kann ich mich immer noch entsheiden, muss ja eh erstmal 5 Jahre studieren^^ (Wobei ich mir Technische Informatik kaum ohne C(++) Lernen vorstellen kann.. Aber erstmal ein Modul Scheme und eins Java ))).



Nuja, meine Aussage spiegelt auch nur meine Meinung wieder und ist damit auch nur relativ zu sehen. 

Das Schöne am Studium ist aber das man die Gelegenheit bekommt in vieles mal reinzuschnuppern und ein paar Grundkonzepte mitzunehmen. Was man aber am Ende draus macht und wo man was damit umsetzt bzw. vertieft, ist etwas anderes. Ich "kann" z.B. auch Assembler, aber ich würde mir ehr einen Holzpflock ins Herz treiben als zu versuchen damit ein aktuelles Spiel umzusetzen. Andererseits kann ich die Konzepte dahinter aktuell relativ gut gebrauchen. Imho ist das bei fast allen Bereichen der Informatik so.




schalentier hat gesagt.:


> Immer wenn der Buffer voll ist, wird er zur Graka geschickt und der andre zum weiterfuellen genutzt.



Das passende Stichwort dazu ist temporal coherence of visibility. Praktisch alle aktuellen Algorithmen berücksichtigt das. Auch in dem Link zu occlusion queries von oben wird dies erläutert. Kurz, zwischen 2 Frames ändert sich normalerweise nicht viel, so das die Informationen aus dem vorhergehenden Frame genutzt werden können, um das aktuelle Frame zu beschleunigen.

Wenn Du z.B. der Grafikkarte viel mehr Dreiecke gibst, als aktuell benötigt werden, brauchst Du das VBO erst zu aktuallisieren, wenn der Spieler sich ein ganzes Stück weiterbewegt oder wenn er Blöcke verändert hat.




schalentier hat gesagt.:


> Wie ich bereits mehrfach gesagt habe, meine Welt ist potentiell unendlich gross. Es ist nicht moeglich alle Dreiecke aller Cubes in die Graka zu stecken. Dafuer reicht der Speicher einfach nicht aus.




Für "potenziell unendlich" reicht aber auch weder der Hauptspeicher noch der Festplattenspeicher. Eine Optimierung eines Parameters (z.B. möglichst viele Blöcke) geht immer auf Kosten anderer Parameter (z.B. die Geschwindigkeit). Eine sinnvolle Optimierung (Aufbau des Algorithmus) benötigt für gewöhnlich eine sinnvolle Problemgröße. Und wie bereits oben erwähnt, ist die ganz weit weg von "potenziell unendlich".

Als Beispiel, Grafikkarte mit 1GB Speicher. Wenn man es drauf anlegt, passen auf die Grafikkarte ~50 Millionen Blöcke. Das ist aber schon viel mehr als sich sinnvoll darstellen lassen. Wenn sich der Spieler also bewegt, hast Du noch elend lange Zeit alte Daten wieder freizugeben und neue nachzuladen, ohne das der Spieler in einen Bereich kommt, zu dem noch keine Daten vorhanden sind. Empire Phoenix hat ein passendes Stichwort ja schon geliefert.


Gruß,
Fancy


----------



## schalentier (27. Sep 2011)

So, ich hab mich nun noch eine ganze Weile mit dem oben genannten Problem beschaeftigt :-D

Falls es interessiert, hier noch die Ergebnisse meiner Experimente:

- Der erste Ansatz, in jedem Frame alle sichtbaren Chunks in Dreiecksdaten zu verwandeln und mittels VBO zur Graka zu transferieren ist viel zu langsam. Zwar schoen einfach zu implementieren, aber man kommt nicht ueber ca. 5 fps.

- Der zweite Versuch, einmal generierte VBOs so lange vorzuhalten, bis sich was am Chunk aendert, oder er nicht mehr im sichtbaren Bereich ist, ist deutlich schneller. Je nach Parameterisierung (Chunkgroesse, initiale VBO Groesse, etc) erreicht man locker dreistellige fps Zahlen. Allerdings ist die Implementierung kniffliger, da nun nicht mehr sichtbare Chunk-VBOs wieder freigegeben werden muessen. Zudem ist zu Beginn des Renderns eines Chunks nicht bekannt, wieviele Dreiecke herauskommen - also muss der VBO wachsen, was wahlweise ordentlich Performance kostet, oder viel Speicher verschwendet.

- Am besten gefaellt mir bisher Weg 3: Ich nutze den ersten Ansatz zum Rendern eines Chunks, allerdings stell ich diesen nicht direkt dar (glDrawArrays), sondern nutze DisplayLists mit GL_COMPILE. Vorteil: Ich muss mich nicht um das Speichermanagement der VBOs kuemmern, das macht die Grafikkarte fuer mich. Es ist sauschnell und vergleichsweise einfach zu implementieren. 

Weiterhin: ByteBuffer.putFloat ist s******e langsam (hab ich oben schonmal geschrieben). Deutlich schneller gehts, wenn man mit Float.floatToRawIntBits zunaechst in einen int-Array schreibt und diesen dann per IntBuffer.put(int[]) in den Buffer packt. 

Damit hab ich, nachdem der sichtbare Bereich komplett als DisplayLists vorliegt, Frameraten ueber 1000 (also nicht sinnvoll messbar). Das Problem nun ist das eigentliche Generieren - besonders wenn man sich schnell durch die Welt bewegt. Wenn ich 4 Chunks von 32x32x32 Groesse pro Frame berechne, komm ich auf noch akzeptable 40-50fps, allerdings reicht das nicht, wenn man nur schnell genug fliegen kann ;-)

Als Naechstes werd ich versuchen, das Generieren auf mehrere Threads zu verteilen. Ich halt euch auf dem Laufenden


----------



## Kr0e (27. Sep 2011)

schalentier hat gesagt.:


> Als Naechstes werd ich versuchen, das Generieren auf mehrere Threads zu verteilen. Ich halt euch auf dem Laufenden



Und da hat dann Java wieder etliche Vorteile gegenüber C/C++ ;-) Viel Erfolg!


----------



## schalentier (27. Sep 2011)

Ich mach aktuell alles (bis auf die native Libs von LWJGL) mit Java ;-)


----------



## Evil-Devil (27. Sep 2011)

Wenn dir die regulären ByteBuffer zu langsam sind, dann schau dir mal die Fast MappedObjects von Raven an. (letzten Seite des Threads)
Once again! fast MappedObjects implementation - Java-Gaming.org

Damit kannst dann noch den Rest an PErformance herausquetschen ^^


----------



## Kr0e (27. Sep 2011)

Noch was interessantes: Seit Java7 sind die Bytebuffer erheblich verbessert und man soll nun wo es geht möglichst direkte Puffer verwenden. Dummerweise ist mir der Link entfallen =(


----------



## Empire Phoenix (27. Sep 2011)

Benutzt du eigntlich driectbytebuffer oder heap basierte? Direkt sind wesentlich schneller weil die als pointer durchgereicht werden können auf nativer seite


----------



## schalentier (27. Sep 2011)

Natuerlich direkte Buffer.

Java 7 werd ich mal ausprobieren, genauso wie die MappedObjects. Allerdings gehts da ziemlich rund im Link von Evil-Devil ;-)

Hat jemand Erfahrungen mit Weak-/SoftReferences? Ich hab damit bisschen gespielt, um Chunks aus dem Speicher zu hauen, wenns knapp wird. Allerdings fliegen die bei WeakReferences extrem schnell aus dem Speicher und bei SoftReferences bricht die Performance extrem ein :-/ Wahrscheinlich sollte ich mich doch lieber selbst um das Aufraeumen alter Chunks kuemmern, oder?


----------



## Empire Phoenix (28. Sep 2011)

Weak ändert garnichts daran wie das gc vorgeht
Soft hält so lange wie ram frei im ram.


----------

