Java für große Spiele geeignet ?

schalentier

Gesperrter Benutzer
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

Top Contributor
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...
 

huckleberry

Bekanntes Mitglied
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?
 

Kr0e

Gesperrter Benutzer
@Huckleberry:

Was war zuerst da? Huhn oder Ei ? :D


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!
 
Zuletzt bearbeitet:

huckleberry

Bekanntes Mitglied
Was war zuerst da? Huhn oder Ei ? :D

Haha :p 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 :p
 

Kr0e

Gesperrter Benutzer
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

Top Contributor
Haha :p 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 :p

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

Gesperrter Benutzer
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:

Code:
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:
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

Gesperrter Benutzer
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 :D - 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.
 
G

Guest2

Gast
Moin,

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

Gesperrter Benutzer
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

Gesperrter Benutzer
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 ?)
 
Zuletzt bearbeitet:
G

Guest2

Gast
[..]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 :D) 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.

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

Top Contributor
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

Gesperrter Benutzer
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.

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

Top Contributor
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

Gesperrter Benutzer
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

Gesperrter Benutzer
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

Top Contributor
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

Gesperrter Benutzer
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
 
G

Guest2

Gast
[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.


[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.


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.


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

Gesperrter Benutzer
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

Top Contributor
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

Gesperrter Benutzer
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 ? :D

Gruß,
Chris
 

Fu3L

Top Contributor
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^^ :D

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^^ :D
 
Zuletzt bearbeitet:

Kr0e

Gesperrter Benutzer
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 :D
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.
 
G

Guest2

Gast
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.

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).


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^^)
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

Top Contributor
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. ;)
 
G

Guest2

Gast
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

Bekanntes Mitglied
[...]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

Top Contributor
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

Top Contributor
(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

Gesperrter Benutzer
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

Gesperrter Benutzer
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...
 

schalentier

Gesperrter Benutzer
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

Top Contributor
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

Gesperrter Benutzer
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.
 
G

Guest2

Gast
[..]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.


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.


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.


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

Gesperrter Benutzer
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

Gesperrter Benutzer
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 =(
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Bestes Bildformat für Spielegrafiken und deren Einbindung in Java Spiele- und Multimedia-Programmierung 2
M Minecraft weitere Java Entwickler für minecraft projekt gesucht Spiele- und Multimedia-Programmierung 0
Guybrush Threepwood Ketzerische Frage: Opus-Codec für Java Spiele- und Multimedia-Programmierung 14
Kenan89 Kleines Projekt für Java Spiele- und Multimedia-Programmierung 5
M Java als Programmiersprache für kommerzielle Spieleentwicklung? Spiele- und Multimedia-Programmierung 3
Gossi Probleme beim Laden der Images aus dem "Tutorial für Java-Spiele" Spiele- und Multimedia-Programmierung 4
M Minecraft Suche Java Programmierer (für Minecraft) Spiele- und Multimedia-Programmierung 2
W 3D-APIs für Java - Eine Übersicht Spiele- und Multimedia-Programmierung 8
S Grafik erstellen für Java Spiel Spiele- und Multimedia-Programmierung 8
D STARTHILFE gesucht !! Java-Projekt für Schule !! Spiele- und Multimedia-Programmierung 73
T Java-Klasse für Spielfeld? Spiele- und Multimedia-Programmierung 2
S Java Delay für Shuffle funktion? Spiele- und Multimedia-Programmierung 4
D sehr simple Java Spiele Platformübergreifend für Handys/PDAs Spiele- und Multimedia-Programmierung 3
S Optimale Grafikkarte für Java 3D programmierung? Spiele- und Multimedia-Programmierung 13
S Gesucht: Java Profis für MMOG Projekt Spiele- und Multimedia-Programmierung 2
M Sound-Lösung für Java/JMF Spiele- und Multimedia-Programmierung 8
R Eignet sich Java für ein Beat'em'Up? Spiele- und Multimedia-Programmierung 3
C |DOMINOSPIEL| Starthilfe für Java-Anfänger Spiele- und Multimedia-Programmierung 2
xFearofdarkness Feinde überlappen sich in Java Spiel Spiele- und Multimedia-Programmierung 3
A Minecraft Java Buch fehlermeldung Spiele- und Multimedia-Programmierung 61
yakazuqi Minecraft java.lang.Error: Watchdog Spiele- und Multimedia-Programmierung 3
L Fehler bei "Nochmal Spielen" (Java) Spiele- und Multimedia-Programmierung 1
N Minecraft Java Error Spiele- und Multimedia-Programmierung 6
M "Java Datei" Cannot be resolved to a variable Spiele- und Multimedia-Programmierung 2
1Spinne Minecraft Fabric Modding Java Error Spiele- und Multimedia-Programmierung 2
Joris Minecraft Minecraft Java Server Spiele- und Multimedia-Programmierung 6
Shanic Minecraft Minecraft Forge Server "Falsche Java Version" Spiele- und Multimedia-Programmierung 6
O Browser-basiertes online Pokerspiel mit Java Spiele- und Multimedia-Programmierung 1
M Spiel Mühle-Programmierung Java Spiele- und Multimedia-Programmierung 9
G VST-Plugins in Java verwenden Spiele- und Multimedia-Programmierung 0
P Audio Visualizer mit OpenGL in Java? Spiele- und Multimedia-Programmierung 4
P Snake Java Hilfe Spiele- und Multimedia-Programmierung 4
D Minecraft [Minecraft] Java Start Fehler (Core-Dump) Spiele- und Multimedia-Programmierung 1
T Welche packages aus der java api doku ist hilfreich zur Android Spieleprogrammierung Spiele- und Multimedia-Programmierung 2
A Programmieren eines Memorys mit Java (in Eclipse) Spiele- und Multimedia-Programmierung 5
L Sound in Java Spiel Spiele- und Multimedia-Programmierung 5
C Java findet FluidSynth nicht Spiele- und Multimedia-Programmierung 2
I Java Andere Fenster in Borderless-Mode setzen Spiele- und Multimedia-Programmierung 16
leon_krys Java-Bußgeldrechner Spiele- und Multimedia-Programmierung 5
G [Java/KryoNet/LibGDX] Mutliplayer Packet Frage Spiele- und Multimedia-Programmierung 2
P Website mit Java Backend? Spiele- und Multimedia-Programmierung 1
D Java Bild bewegen funktioniert nicht Spiele- und Multimedia-Programmierung 8
J Fertigungstechnik.. PLS HALP.. Quellcode vom Text in java-Klasse speichern Spiele- und Multimedia-Programmierung 2
E Kalah Java Implementation Spiele- und Multimedia-Programmierung 1
G [Java] Vereinfachung von Boolean Abfragen Spiele- und Multimedia-Programmierung 3
G [LibGDX/Java] ArrayList Object Speicher Spiele- und Multimedia-Programmierung 3
T Java 3D Spiele- und Multimedia-Programmierung 2
A Spielfelder erstellen mit Jogl Java durch ein Koordinaten Array Spiele- und Multimedia-Programmierung 1
J Java Buttons Spiele- und Multimedia-Programmierung 6
T Java Kalender Spiele- und Multimedia-Programmierung 5
Ice4P4rty Java Optische Oberfläche Spiele- und Multimedia-Programmierung 2
MABY Eine mp3 Datei in Java abspielen Spiele- und Multimedia-Programmierung 14
D Java Bomberman Probleme java.lang.NullPointerException Spiele- und Multimedia-Programmierung 1
N Spiele-Menü in Java Spiele- und Multimedia-Programmierung 9
J HDMI Ausgänge mit Java programmieren? Spiele- und Multimedia-Programmierung 18
H Yu-Gi-Oh! Mit Java was tun? Spiele- und Multimedia-Programmierung 6
G Component System Java 2D Game LibGDX Spiele- und Multimedia-Programmierung 6
S Pong java.lang.StackOverflowError Spiele- und Multimedia-Programmierung 3
C Java aus Klasse rausgehen Spiele- und Multimedia-Programmierung 2
MaxG. Java Internet Radio Spiele- und Multimedia-Programmierung 6
G [Java Server] Allgemeine Frage zum Thema Networking in Videospielen Spiele- und Multimedia-Programmierung 15
P java.lang.NoClassDefFoundError: in Greenfoot Spiele- und Multimedia-Programmierung 0
G Java Achsen invertieren Spiele- und Multimedia-Programmierung 2
G Java 2D Spiel mit LWJGL verbinden Spiele- und Multimedia-Programmierung 1
$ Einstieg in Java Game Development Spiele- und Multimedia-Programmierung 11
BraunBerry Java Game Pixel "einfärben" Spiele- und Multimedia-Programmierung 6
BraunBerry Java Game verbesserte Kollisionserkennung Spiele- und Multimedia-Programmierung 18
BraunBerry Java Game Waypoint System Spiele- und Multimedia-Programmierung 3
S Hilfe bei Java Gui Spiele- und Multimedia-Programmierung 2
D Java sound pulseaudio Spiele- und Multimedia-Programmierung 0
David Schwarzbeck Java 3 dimensionale Kollisions Abfrage Spiele- und Multimedia-Programmierung 2
M Gesellschaftsspiel Mühle in Java programmieren Spiele- und Multimedia-Programmierung 3
beatles Java Minesweeper - OS X und Win7 Unterschied Spiele- und Multimedia-Programmierung 2
D Minecraft Java JDK installiert - Minecraft läuft nichtmehr in 64 Bit Spiele- und Multimedia-Programmierung 2
E TMX - Dateien in Java laden Spiele- und Multimedia-Programmierung 1
K Erstellen eines Fotoalbums mit Java Spiele- und Multimedia-Programmierung 8
windl MoviePlayer in Java Spiele- und Multimedia-Programmierung 0
S 2D-Render Probleme LWJGL 2 (Java) Spiele- und Multimedia-Programmierung 1
F Klausurersatz: Ein Java-Programm erstellen und dieses präsentieren. Spiele- und Multimedia-Programmierung 2
E Java Jump and Run Map zu groß Spiele- und Multimedia-Programmierung 14
P java lwjgl Game Spiele- und Multimedia-Programmierung 0
J programm mit java-plugin Spiele- und Multimedia-Programmierung 2
D Java Webgame, welche Frameworks oder Techs sind von Nöten? Spiele- und Multimedia-Programmierung 5
P Java 2D Bug? Spiele- und Multimedia-Programmierung 8
T Problem mit Eclipse (java)-(minecraft) Spiele- und Multimedia-Programmierung 3
R Java App sendet Midi Daten über Flash Spiele- und Multimedia-Programmierung 3
O Java Zeile aus Textdatei zufällig ausgeben Spiele- und Multimedia-Programmierung 8
D JAVA Basiertes Spiel aus dem Internet in eigenem Client laden Spiele- und Multimedia-Programmierung 1
T Alle Referenzen zu einer Klasse aus Java Bytecode ersetzt, JVM sucht trotzdem diese Klasse Spiele- und Multimedia-Programmierung 1
J Java Kollisionsabfrage Spiele- und Multimedia-Programmierung 21
Flo. android java tastatureingaben abfangen. Spiele- und Multimedia-Programmierung 1
J Java Steuerberechnung hilfe Spiele- und Multimedia-Programmierung 17
C Export als .jar funktioniert nicht richtig (JAVA 3D) Spiele- und Multimedia-Programmierung 5
P Java Grafiken mit Rechnungen verknüpfen Spiele- und Multimedia-Programmierung 4
U Minecraft Mit Java auf Minecraft Server anmelden Spiele- und Multimedia-Programmierung 11
F Das sag mir einer Java ist plattform unabhänig ! Spiele- und Multimedia-Programmierung 10
C virtueller stereomix (java sound API) Spiele- und Multimedia-Programmierung 0
S Engine2D - Java 2D Engine Spiele- und Multimedia-Programmierung 20
J Java Game performance Probleme Spiele- und Multimedia-Programmierung 7
C Java Kollisionserkennung Spiele- und Multimedia-Programmierung 4

Ähnliche Java Themen

Neue Themen


Oben