Einleitung
Zum Verständnis ist das b3d-Format nicht schlecht. Man wird damit mangels gutem Editor vermutlich keine komplexen Gebilde erstellen wollen, aber als Einstieg ist es sehr gut dazu geeignet, das Prinzip der Texturerstellung zu verstehen.
b3d ist vom Informationsinhalt her dem Zusi-ls-Format recht ähnlich, es hat aber natürlich noch eine Information über die Textur. Als Editor dient i.d.R. ein üblicher Texteditor. Alternativ geht auch der Loksim-Editor, der einen b3d-Export bietet (in diesem sind kleine Fehler vorhanden, s. auch hier http://zusiforum.eisenbahn-seiten.de/vi ... php?t=2780)
Um das Getippte zu kontrollieren bietet sich der Zusi3-Betrachter an, bei bve soll es auch einen b3d-Viewer geben.
b3d-Format
Zunächst werfen wir mal einen Blick in eine b3d-Datei.
Beispiel:
Code: Alles auswählen
[MeshBuilder]
Vertex 0.6, 5.7, 8.6
Vertex 0.6, 5.7, -0.6
Vertex -6.6, 5.7, -0.6
Vertex -3, 7.5, 3
Vertex -3, 7.5, 5
Face 1, 2, 3
Face 0, 1, 3, 4
Color 48, 48, 48
[MeshBuilder]
Vertex 0, 0, -1
Vertex 0, 4, -1
Vertex 2, 4, -1
Vertex 2, 0, -1
Face 0, 1, 2, 3
[Texture]
Load Tree.bmp
Coordinates 1, 0, 0
Coordinates 2, 1, 0
Coordinates 0, 0, 1
Coordinates 3, 1, 1
Transparent 0, 0, 0
[MeshBuilder]
Vertex 1, 0, -2
Vertex 1, 4, -2
Vertex 1, 4, 0
Vertex 1, 0, 0
Face 0, 1, 2, 3
[Texture]
Load Tree.bmp
Coordinates 1, 0, 0
Coordinates 2, 1, 0
Coordinates 0, 0, 1
Coordinates 3, 1, 1
Transparent 0, 0, 0
[MeshBuilder] bedeutet, dass Informationen über die Vertices (Polygon-Eckpunkte) und die daraus gebildeten Polygone (Faces) folgen.
[Texture] bedeutet, dass Die Texturinformation, also Bitmap-Datei und Texturkoordinaten folgen.
Eine b3d-Datei kann aus mehreren solcher Blöcke bestehen, also [MeshBuilder] und [Texture] für die erste Polygongruppe, dann [MeshBuilder] und [Texture] für die zweite Polygongruppe usw. Wenn wie bei Zusi-ls Polygone ohne Textur erstellt werden sollen, dann kann der [Texture]-Abschnitt ersatzlos entfallen.
Kommentare sind überall möglich, indem ein ein Semikolon vorangestellt wird (Alles nach dem Semikolon wird dann beim Laden ignoriert).
Bau einer einfachen Lf-Tafel als b3d-Datei
Der Mast als untexturiertes Polygon
Die Bedeutung der Einträge sollen am Beispiel einer einfachen Lf2-Tafel erklärt werden. Diese soll aus einem Mast und der viereckigen Tafel bestehen. Der Mast soll als untexturiertes schwarzes Polygon dargestellt werden, das Signalbild und die Rückseite als Textur.
Die Koordinaten sind einer Zusi-Lf-Tafel entnommen und ins neue Koordinatensystem übertragen (x wird z, y wird -x, z wird y):
Für den Mast sind das vier Punkte, wir schreiben also im Meshbuilder-Abschnitt
Code: Alles auswählen
[MeshBuilder]
Vertex 3.143, -1.0, 0
Vertex 3.143, 1.93, 0
Vertex 3.043, 1.93, 0
Vertex 3.043, -1.0, 0
Code: Alles auswählen
Face 3, 2, 1, 0
Nun können wir aus denselben vier Punkten auch noch die Mastrückseite erstellen. Das hat gegenüber Zusi-ls den Vorteil, dass weniger Vertices benötigt werden, was gut für die Performance ist. Es folgt also eine zweite Face-Angabe mit unseren 4 Punkten in umgekehrter Reihenfolge:
Code: Alles auswählen
Face 0, 1, 2, 3
Code: Alles auswählen
Color 0, 0, 0
Das Signalbild mit Textur
Für das Signal wird auch ein Viereck benötigt. Der erste Schritt entspricht also dem Mastbau und führt zu folgendem Code für die Vorderseite:
Code: Alles auswählen
[MeshBuilder]
Vertex 2.87, 1.93, 0
Vertex 3.33, 1.93, 0
Vertex 3.33, 2.63, 0
Vertex 2.87, 2.63, 0
Face 3, 2, 1, 0
Texturen werden bei allen Dateiformaten als separate Datei mitgeliefert. Diese Datei wird mit einem Bitmapeditor erzeugt und im bmp-Format in demselben Verzeichnis wie die b3d-datei abgelegt. Es sind auch andere Texturformate wie tga möglich, es kann aber sein, dass der aktuelle Zusi-Betrachter diese noch nicht einliest.
DirectX kann nur Texturen verwalten, die als Kantenlänge einer 2er Potenz haben, also 2x2, 4x4, 8x8 usw. bis 1024x1024. Die meisten Grafikkarten können auch bis 4096x4096, aber manche haben ein Limit bei 1024x1024, dieser Wert sollte also nicht überschritten werden. Wenn Bitmapdateien mit anderen Abmessungen geladen werden, benötigen die immer soviel Speicher wie die nächstgrößere 2er Potenz. Eine 3x65 Pixel große Textur schlägt also mit 128x128 Pixel Speicherbedarf zu.
Es ist ganz wichtig, die Texturen so klein wie möglich zu machen, da die Texturen DER Engpaß bei Zusi 3 sein werden.
Wenn ein Polygon mit einer Textur versehen wird, kann man sich das wie ein Tapezieren vorstellen, bei dem man aus dem Tapetenvorrat für jede einzelne Fläche ein genau passendes Stück herausschneidet. Jedes einzelne Dreieck des Polygons wird also mit einem Stück Bitmap belegt. Die Textur wird dabei nicht als Ganzes über unsere Landschaft "gestülpt", sondern es wird jedes Dreick einzeln betrachtet und jedes Dreieck mit einem genau zu definierendes Ausschnitt aus der Textur belegt. Ein Texturausschnitt kann auch mehrmals benutzt werden (z.B. Mauerornament, das mehrmls im Haus verbaut ist, muß nur einmal auf der Textur vorhanden sein) - in diesem Punkt unterscheidet sich das ganze erfreulicherweise etwas vom echten Tapezieren.
Beim Zeichnen eines Dreiecks muß jetzt irgendwie definiert werden, welcher Ausschnitt der Textur auf das Dreieck gezeichnet werden soll. Diese Aufgabe erledigen die sogannnten Texturkoordinaten: Diese werden auch als u und v bezeichnet (da ein Bitmap eine zweidimensionale Angelegenheit ist, gibt es nur zwei Koordinaten, u ist die waagerechte, v die senkrechte Bitmapkoordinate). Jeder Vertex enthält also neben den altbekannten x-, y-, und z-Koordinaten auch noch eine u- und v-Koordinate. Um die Koordinaten unabhängig von der Größe des Bitmaps zu halten, sind sie auf 1 normiert. Also Koordinatenwert x Bitmapbreite ergibt das jeweilige Pixel. Der folgendes Abschnitt zeigt das am Beispiel der Tafel.
Bitmap für die Lf-Tafel (32x32):
Zur Ermittlung der Texturkoordinaten siehe folgendes Bild:
Der einzige Punkt, bei dem man etwas rechnen muß, ist der blau eingetragene Abschnitt, der Rest läßt sich sofort ablesen, nämlich
Punkt 0: u=0 v="blau"
Punkt 1: u=0.5 v="blau"
Punkt 2: u=0.5 v=0
Punkt 3: u=0 v=0
Der Wert für blau ergibt sich Abzählen der Pixel. Der blaue Strich ist 23 Pixel, geteilt durch die Texturhöhe 32 erhält man 0.72
Der b3d-Texturabschnitt
Im Texturabschnitt wird zunächst die zu ladende Datei "lf.bmp" angegeben.
Code: Alles auswählen
[Texture]
Load lf.bmp
Code: Alles auswählen
Coordinates 0, 0, 0.72
Coordinates 1, 0.5, 0.72
Coordinates 2, 0.5, 0
Coordinates 3, 0, 0
Meshbuilder- und Textur-Abschnitt werden also entsprechend erweitert.
[MeshBuilder]
Vertex 2.87, 1.93, 0
Vertex 3.33, 1.93, 0
Vertex 3.33, 2.63, 0
Vertex 2.87, 2.63, 0
Vertex 2.87, 1.93, 0
Vertex 3.33, 1.93, 0
Vertex 3.33, 2.63, 0
Vertex 2.87, 2.63, 0
Face 3, 2, 1, 0
Face 4, 5, 6, 7
[Texture]
Load lf.bmp
Coordinates 0, 0, 0.72
Coordinates 1, 0.5, 0.72
Coordinates 2, 0.5, 0
Coordinates 3, 0, 0
Coordinates 4, 1, 0.72
Coordinates 5, 0.5, 0.72
Coordinates 6, 0.5, 0
Coordinates 7, 1, 0
Zum Abschluß noch einmal der gesamte b3d-Inhalt:
Code: Alles auswählen
; Mast
[MeshBuilder]
Vertex 3.143, -1.0, 0
Vertex 3.143, 1.93, 0
Vertex 3.043, 1.93, 0
Vertex 3.043, -1.0, 0
Face 3, 2, 1, 0
Face 0, 1, 2, 3
Color 0, 0, 0
; Signalbild
[MeshBuilder]
Vertex 2.87, 1.93, 0
Vertex 3.33, 1.93, 0
Vertex 3.33, 2.63, 0
Vertex 2.87, 2.63, 0
Vertex 2.87, 1.93, 0
Vertex 3.33, 1.93, 0
Vertex 3.33, 2.63, 0
Vertex 2.87, 2.63, 0
Face 3, 2, 1, 0
Face 4, 5, 6, 7
[Texture]
Load lf.bmp
Coordinates 0, 0, 0.72
Coordinates 1, 0.5, 0.72
Coordinates 2, 0.5, 0
Coordinates 3, 0, 0
Coordinates 4, 1, 0.72
Coordinates 5, 0.5, 0.72
Coordinates 6, 0.5, 0
Coordinates 7, 1, 0