Blitz3d Kurs – von INpac

[mehr Tutorials auf www.INpacProducts.de.vu]

 

Willkommen in meinem ersten Blitz3D-Kurs. Der Kurs dient zum Grundlagewissen, um einen leichten Start zu haben. Voraussetzungen sind einfache BlitzBasic-Gebiete wie Buffer, Schleifen, …

 

INDEX:

  1. Einführung in Blitz3D
  2. Programmaufbau
  3. Erstellen von verschiedenen Entitys / Meshs
  4. Laden von Meshes
  5. Ändern von Eigenschaften von Meshes
  6. Meshes verschönern mit Texturen und Effekten
  7. Terrains

 

 

Fangen wir gleich an.

 

1.    Einführung in Blitz3D

 

Mit Blitz3D könnt ihr wie der Name schon sagt, eine 3dimensionale Umgebung (oder Szene) erstellen. Zur Erinnerung: 2dimesional bedeutet es gibt zwei Dimension, also hoch/runter, links/rechts. Im 3Dimensionalen gibt es anschließend noch die hier rot gekennzeichnete Tiefe:

 

 

Ihr müsst es euch außerdem wie einen Film vorstellen, es gibt dort eine Kulisse, Gegenstände, … und alles wird mit (mind.) einer Kamera aufgenommen, sodass man es später sehen kann. Dazu kommen noch Lichter, die alles gut beleuchten. Wie das alles funktioniert und wie man so was kreiert zeig ich euch im nächsten Kapitel. Man beachte das auch hier gilt: der Ursprung der 3 Achsen ist links oben!

 

Noch ein paar grundlegenden 3D-Sachen:

 

Vertexe sind kleine Punkte im 3D-Raum, jedes sichtbares 3dimensionale Objekt in BB3D hat mind. 1 Polygon. 3 zusammengeschlossene Vertexe bilden ein Polygon.

 

Polygone sind kleine Dreiecke, 3 Vertexe bilden ein Polygon.

 

Wireframe bedeutet, dass man nicht mehr die Texturen und Farben sieht, sondern nur die Polygone, hier ein Beispiel:

2.    Programmaufbau

 

Ein typischer Programmaufbau:

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

 

;

;laden von Meshs, Texturen, etc.

;

 

camera=CreateCamera()

PositionEntity camera,0,10,0

 

While Not KeyHit(1)

 

;

;Eigentliches Programm in der Schleife

;

UpdateWorld

RenderWorld

Flip

Wend

ClearWorld

End

 

Der Befehl Graphics3D funktioniert genauso wie Graphics in Blitz2D (den man in BB3D natürlich auch einsetzen kann). Er sagt nur BB3D, dass jetzt eine 3dimesionale Umgebung erstellt wird, wer den Befehl Graphics nicht kennt, schaue doch bitte auf www.blitzbase.de nach.

 

Die benötigte Kamera erzeugt man mit CreateCamera(), diese kann man im Spiel nicht sehen, sie dient einfach nur zum „Filmen“ der 3D-Szene.

 

PositionEntity setzt ein Entity (ein „Ding“) an die gennate Position, also PositionEntity entityname,xpos,ypos,zpos

 

UpdateWorld checkt Entitys auf Kollisionen, spielt Animationen ab, und vieles mehr…

RenderWorld rendert die aktuelle 3D-Szene und „schreibt“ sie in den Backbuffer, mit Flip wird dann alles ausgelesen.

ClearWorld löscht die ganze 3D-Szene aus dem Arbeitsspeicher, so wird der zuvor benötigte Platz wider freigegeben für neue Dateien und Daten!

 

Nun haben wir aber noch nichts, was wir sehen können. Also erstellen wir mal ein paar Meshs!

 

3.    Erstellen von verschiedenen Entitys / Meshes

 

Entitys sind „Dinger“, das kann jetzt alles sein, eine Kamera ist auch ein Entity… Jetzt erstellen wir aber mal ein paar geometrische Figuren (primitives). Zur Auswahl stehen: Würfel (Cube), Kugel (Sphere), Zylinder (Cylinder) und Kegel (Cone). Hier mal in der Wireframe-Ansicht:

 

Um in den „Wireframe-Modus“ zu schalten, verwende später einfach den Befehl „Wireframe 1“, oder wenn du den Modus verlassen willst „Wireframe 0“.

 

Die Befehle dafür sind einfach:

Meinwuerfel      = CreateCube()

Kugel      = CreateSphere(polygone)

Zylinder   = CreateCylinder(polygone)

Kegel      = CreateCone(polygone)

 

Der Wert Polygone bestimmt die Anzahl der Polygone. Je mehr Polygone, desto glatter ist das Objekt. Ich würde 20 nehmen, jedoch müsst ihr natürlich aufpassen, dass ihr nicht zu viele wählt, da ja so viel mehr Polygone berechnet werden => Geschwindigkeitsverlust…

 

Schreiben wir mal ein kleines Programm, ein Programm in dem man alle 4 Primitives sieht, und diese an allen (drei) Achsen gedreht werden:

 

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

SeedRnd MilliSecs()

 

cube=CreateCube()

sphere=CreateSphere(21)

cone=CreateCone(21)

Cylinder=CreateCylinder(21)

 

MoveEntity cube, 3,0,10

MoveEntity sphere, 0,0,10

MoveEntity cone, -3,0,10

MoveEntity cylinder, -6,0,10

 

EntityColor cube, Rand (1,255), Rand (1,255), Rand (1,255)

EntityColor sphere, Rand (1,255), Rand (1,255), Rand (1,255)

EntityColor cone, Rand (1,255), Rand (1,255), Rand (1,255)

EntityColor cylinder, Rand (1,255), Rand (1,255), Rand (1,255)

 

cam=CreateCamera()

PositionEntity cam,0,10,0

CameraClsColor cam,0,100,255

PointEntity cam,sphere

 

While Not KeyHit(1)

 

TurnEntity cube,1,1,1

TurnEntity sphere,1,1,1

TurnEntity cone,1,1,1

TurnEntity cylinder,1,1,1

 

UpdateWorld

RenderWorld

Flip

Wend

End

 

Zu sehen sind nun die 4 Meshes, alle in zufällig generierten Farben auf einem himmelblauen Hintergrund!

MoveEntity verschiebt ein Objekt um(= relativ)  die angegebenen Koordinaten. Es können auch negative Zahlen sein! Mit -um- meine ich, dass die Koordinaten des Objektes wirklich UM die Zahlen verschoben werden: „PositionEntity“ verschiebt die Koordinaten „absolut“ auf die angegebenen Werte, Beispiel:

 

Ein Objekt ist auf … z.B. der Koordinate „120,630,70“.

Wenn wir jetzt „MoveEntity objekt,10,30,-20“ benutzen, kommen nach her die Koord. „130,660,50“ raus. Bei „PositionEntity objekt ,10,30,-20“ kommt folgendes heraus: „10,30,-20“

Verstanden?

 

EntityColor Entity,r,g,b setzt die Farbe des „Entity“ auf die angegebenen RGB-Werten. Ich habe das hier so gemacht, dass die RGB-Werte zufallsgeneriert sind, sodass immer wieder andre Farben erscheinen!

 

PointEntity entity , zielentity dreht das Objekt an seinen 3 Achsen so, dass es auf das Objekt „zielentity“ gerichtet ist:

Ich habe es hier benutzt, dass die Kamera gleich ein Objekt (in diesem Fall ja das Objekt „sphere“) sieht, und da alle Primitives nah beisammen sind, sieht man halt auch gleich alle!

Das war es auch schon, zum Thema „Erstellen von Meshs“…

 

4.    Laden von Meshs

Ok, jetzt können wir schöne Kegel und Kugeln erstellen, aber wie macht man das dann, dass man später eine Figur im Spiel hat?? Diese einzeln mit tausenden von Primitiven zu erstellen wäre nicht sehr bequem… Deswegen kann man mit andren 3D-Programmen erstellte Meshs in Blitz3D mit dem Befehl

 

Mesh=LoadMesh („mesh1.b3d“)

 

einfach und schön in sein Programm laden. Ihr habt schon gesehen: als Endungen der Datei habe ich hier „b3d“ angegeben: b3d bedeutet hier einfach nur „BlitzBasic 3D“. Dieses Format wurde extra für Bliz3D entwickelt und sollte bevorzugt angewendet werden. Jedoch gibt es da ein Problem: Die Demoversion von Blitz3D unterstützt nur die Formate „3ds“ (3Ds Max)  oder „x“ (DirectX-File). Mit denen ist aber auch was anzufangen…!

 

Übrigens: Solche 3D-Meshs werden, wie schon gesagt, extern mit sog. „3D-Modelling-Tools“ erstellt. Mein Favorit unter diesen Programmen  ist weiterhin „Milkshape“. Ihr findet dieses Programm unter der Seite http://www.milkshape3d.com. Jedoch ist dieses Programm eine „Trial-Version“, ihr dürft das Tool also nur 30 Tage lang ausprobieren, danach könnt ihr eure Meshs nicht mehr abspeichern! Wenn ihr Screenshots von Milkshape sehen wollt, klickt hier!

 

In der Demoversion sind auch schon ein paar modellierte Meshs enthalten: Wenn ihr in den Ordner von Blitz3D geht und dann in den Ordner „samples“ geht, seht ihr hier ganz viele Beispielprogramme wie z.B. „Xfighter“. Dieses Spiel soll ein kleiner Anfang eines Flugzeugspiel darstellen. Das Hauptmesh im Spiel ist, klar, das Flugzeug: es wurde ebenfalls mit dem Befehl „LoadMesh“ geladen und zwar steht es dort genau so da:

 

plane=LoadMesh( „biplane.x“, pivot )

 

Jetzt ist euch vielleicht aufgefallen, dass hinter „... .x“ ein „…, pivot“ steht. Erstens: Wieso steht da noch was? Zweitens was ist ein Pivot?

Also, fangen wir mit der ersten Frage an. Zu einem Meshs oder Entity kann man immer ein „Parent“ hinzufügen. Das geht immer mit dem Befehl

„EntityParent entity(das hinzugefügt werden soll), Zielobjekt (zudem das Entity hinzugefügt wird)“ oder es wird halt so wie oben bei (z.B.) dem Befehl „LoadMesh“ gleich angegeben!

So, aber was bringt das, wenn’s hinzugefügt wird? Das ist etwas ganz praktisches: Nehmen wir an, ein Objekt soll immer so verändert werden, wie ein andres, also z.B. das es immer gedreht wird, wenn das Zielobjekt gedreht wird oder das es immer verschoben werden soll. Man könnte das ja so schreiben:

 

Cone = CreateCone (21) ;Normales Objekt, also Zielobjekt

Cube = Createcube() ;Mesh, das immer die Eigenschaften haben soll wie “Cone”

 

MoveEntity Cone,1,20,300

MoveEntity Cube,1,20,300

 

TurnEntity Cone,90,60,90

TurnEntity Cube,90,60,90

 

So, und jetzt macht “Cube” immer das selbe wie “Cone“. Aber das immer so nacheinander alles aufzuschreiben, wäre sicherlich nicht bequem, und bequem wollen wir doch immer sein. Lösen wir das Problem also mit dem Parent-Kram:

 

Cone = CreateCone(21) ;Normales Objekt, also Zielobjekt

Cube = CreateCube(Cone) ;Mesh wird „parent“ auf das Objekt „Cone“

 

MoveEntity Cone,1,20,300

 

TurnEntity Cone,90,60,90

 

Und jetzt erhalten wir dieselben Ergebnisse wir oben! Wir könnten auch schreiben:

 

Cone = CreateCone (21) ;Normales Objekt, also Zielobjekt

Cube = Createcube()

EntityParent Cube, Cone  ;Mesh wird „parent“ auf das Objekt „Cone“

 

MoveEntity Cone,1,20,300

 

TurnEntity Cone,90,60,90

 

Da kommt auch dasselbe raus, nur haben wir hier viel mehr Text eingeben müssen, nämlich zusätzlich noch den Befehl „EntityParent“ ;) ! Folgende Befehle werden auf das parente Objekt ausgeführt, wenn das Zielobjekt die Befehle erhält:

-MoveEntity

-TurnEntity

-und noch viele mehr, die wir hier aber noch nicht besprochen haben…

Ok, jetzt wissen wir was „parent“ heißt. Kommen wir nun zum Thema „Pivot“. Das ist gar nicht schwer, wenn man es mal kapiert hat, und ich versuche jetzt einfach mal es zu erklären.

Zunächst ein Bild:

Zur Erklärung:

Bsp 1)

Jedes Mesh hat irgendwo einen Punkt, an dem die Koordinaten 0,0,0 sind, also der Ursprung des Meshs, wenn man ein Mesh kreiert, ist der Mittelpunkt automatisch am Ursprung positioniert. Wenn man ein Mesh ganz normal mit „TurnEntity“ dreht, so wird es automatisch am Mittelpunkt gedreht. In beiden Bsp. Wurde das Mesh um jeweils 50° gedreht. Im ersten Bsp. sieht man aber keine Veränderung der Koordinaten, X bleibt x, y bleibt y, z bleibt z!

Bsp 2)

Um ein Mesh um einen anderen Drehpunkt zu drehen, muss man erst einen neuen Drehpunkt erstellen:

 

Pivot=CreatePivot([parent*])

 

*hier kann man immer den Nahe eines Entitys oder Meshs eingeben, sodass das Objekt, indem Fall der Pivot, parent zum angegebenen Entity wird!

 

Und um anzugeben, dass der Pivot nun der Drehpunkt für ein bestimmtes Mesh sein soll, muss man das beliebige Mesh parent zum Pivot machen!

 

Mesh =LoadMesh („mesh.x“,pivot)

 

Ist ja verständlich…

Alles was am kreiert wird, wird an der Stelle 0,0,0 kreiert! Wenn wir jetzt einmal einen Pivot und dann ein Mesh kreieren (laden ist ja auch kreieren!), so werden beide Objekte an derselben Stelle kreiert!, da würde es jetzt auch nicht bringen, das Mesh um den Pivot zu drehen, da der Pivot dann ja an der selben Stelle liegt, wie der natürlich Mittelpunkt des Meshs. Also könnte man das Mesh gleich mit dem eigenen Befehl „TurnEntity mesh…“ drehen, das würde keinen Unterschied machen! So, aber um den Pivot effektiv einsetzen zu können, muss die Position des Meshs an einer andren Stelle sein, wie die des Pivots:

 

Pivot=CreatePivot()

Mesh=CreateCube(pivot)   ;das Mesh wird kreiert, und gleich parent auf “pivot” gemacht!

MoveEntity Pivot,10,10,40

MoveEntity Cube, -40,-34,10

 

So, und um nun das Mesh um den neuen Drehpunkt zu drehen, müssen wir nicht etwa das Mesh selbst drehen, sondern den Pivot, und da das Mesh ja parent ist, wird das Mesh auch gedreht, aber UM den Pivot!

 

Pivot=CreatePivot()

Mesh=CreateCube(pivot)   ;das Mesh wird kreiert, und gleich parent auf “pivot” gemacht!

MoveEntity Pivot,10,10,40

MoveEntity Cube, -40,-34,10

TurnEntity Pivot,10,-50,280

 

Wenn ihr euch fragt, zu was das ganze nützlich ist, denkt z.B. an die GTA 3-Steuerung: Die Kamera steht immer hinter der eigentlichen Spielfigur. Der Drehpunkt der Kamera liegt dort wo wie Figur steht, und wenn man die Maus bewegt, dreht sich der Pivot, und somit auch darum die Kamera!

 

So, das war nun eine ziemlich lange, aber aufschlussreichende Erklärung, ich hoffe ihr habt es verstanden!

Ja, und das war es auch schon zum Thema „Laden von Meshs“, sie werden einfach nur wie normale Meshs benutzt, die so mit primitiven Befehlen, wie CreateCube etc. erstellt werden, benutzt!

 

5.    Ändern der Eigenschaften von Meshs

Oft müssen Meshs geändert werden, z.B. kann man jetzt Meshs in alle Richtungen vergrößern, verkleinern, Drehen,  …

Die Befehle sind recht einfach:

Zum Drehen verwendet man

TurnEntity

RotateEntity

Zum Vergrößern/Verkleinern

ScaleMesh

Ja, und das war’s auch schon im Großen und Ganzen! Schreiben wir halt mal ein Programm, mit dem ein Mesh beliebig mit den Richtungstasten drehen kann und mithilfe der Tasten „A“ und „Y“ vergrößern kann:

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

 

mesh=CreateCone(21):PositionEntity mesh,0,0,0

EntityColor mesh,0,255,0

ScaleMesh mesh,10,10,10

pivot=CreatePivot():PositionEntity pivot,0,0,0

cam=CreateCamera(pivot):MoveEntity cam,0,0,100

PointEntity cam,mesh

CameraClsColor cam,0,100,255

light=CreateLight()

TurnEntity light,0,-45,45

 

While Not KeyHit(1)

If KeyDown(200) Then TurnEntity mesh,1,0,0

If KeyDown(208) Then TurnEntity mesh,-1,0,0

If KeyDown(203) Then TurnEntity mesh,0,1,0

If KeyDown(205) Then TurnEntity mesh,0,-1,0

If KeyDown(30) Then ScaleMesh mesh,0.9,0.9,0.9

If KeyDown(44) Then ScaleMesh mesh,1.1,1.1,1.1

 

UpdateWorld

RenderWorld

Flip

Wend

ClearWorld

End

 

Ihr seht wahrscheinlich solch ein bild hier:

 

Die Befehle sind ja ganz einfach:

ScaleMesh mesh, x, y, z

reduziert die Größe von „mesh“ um den angegebenen Prozentsatz: das heißt: Wenn man ein Objekt doppelt so groß machen will, als es davor war, muss man das Objekt um 100% vergrößern, das heißt ja also AUF 200%: ScaleMesh mesh,2,2,2 (200 % = 2; 145%=1,45 usw)

Genauso geht das mit den Minuswerten, wenn man ein Objekt auf die Hälfte verkleinern will: ScaleMesh mesh,0.5,0.5,0.5!

Das war’s auch schon. Kommen wir nun zu den Texturen, denn wir wollen ja nicht nur einfarbige Meshs haben!

 

6.  Meshes verschönern mit Texturen und Effekten

 

Kommen wir zuerst zu den Texturen!

Texturen sind sehr wichtig in einem guten Spiel, sie sind notwendig, um realistische Mauern oder Bäume darstellen zu können oder auch sont. Objekte, wie Menschen, Waffen etc. Die Befehle dafür sind auch nicht schwer. Um eine Textur zu laden, schreibt man folgenden Befehl:

Texture=LoadTexture(„texture.bmp“)

Und um ein Objekt damit zu „textuieren“, sagt man

EntityTexture mesh, texture

„texture“ wurde ja vorher natürlich mit dem LoadTexture-Befehl geladen und gespeichert!

 

Texturen, also die eigentlichen Bilder, speichert man am besten im Format 128 x 128 Pixel oder 256 x 256 Pixel ab. Wenn eine Textur z.B. die Größe 70 x 234 hat, muss Blitz3D erst jeden einzelnen Pixel (in dem Fall 70 x 234= 16380!) neu berechnen, und als (z.B.) 256x256-Format umwandeln, um die Textur richtig benutzen zu können!

Diese Formate werden unterstützt, jedoch müsst ihr darauf achten, dass je größer die Textur ist, die Rechenleistung beeinträchtigt wird, und der Programmablauf verlangsamt wird, aber die Qualität natürlich viel besser (/schärfer) ist!

Und ebenfalls: je kleiner die Textur, desto schneller der Programmablauf, aber dann ist die Textur hässlich verzerrt, weil sie ja über das ganze Mesh gezogen wird…

 

Schreiben wir ein kleines Programm, das 3 Objekte erstellt, und es mit diesen Texturen verziert:

Schön, gell? ;)

 

Also, hier mal das Programm:

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

AppTitle "Texturen in BB3D",1

 

cube=CreateCube ()

cube_text=LoadTexture ("text1.bmp")

EntityTexture cube,cube_text

 

cone=CreateCone (21)

cone_text=LoadTexture ("text2.bmp")

EntityTexture cone,cone_text

MoveEntity cone,15,0,0

 

sphere=CreateSphere (21)

sphere_text=LoadTexture ("text3.bmp")

EntityTexture sphere,sphere_text

MoveEntity sphere,-15,0,0

 

cam=CreateCamera()

CameraClsColor cam,0,100,255

MoveEntity cam,0,0,-30

PointEntity cam,cube

 

ScaleMesh cube,5,5,5

ScaleMesh cone,5,5,5

ScaleMesh sphere,5,5,5

 

While Not KeyHit(1)

 

TurnEntity cone,1,1,1

TurnEntity cube,1,1,1

TurnEntity sphere,1,1,1

 

UpdateWorld

RenderWorld

Flip

Wend

ClearWorld

End

 

Wahrscheinlich werdet ihr so was hier sehen:

 

Schön, mit Texturen wir also schon ein bisschen umgehen…

 

Übrigens: Wenn ihr in 3D-Modellingtools Meshes mit Texturen verseht, müsst ihr die später natürlich nicht mehr in Blitz3D einzeln laden und einzeln auch textuieren! Ihr müsst einfach nur die Texturen, die ihr im 3DTool geladen habt, in denselben Ordner tun, wo ihr auch euer BB-Programm abgespeichert habt!

 

Befehle für Texturen gibt es in Blitz3D sehr viele; ich werde hier nur die wesentlichen erklären, da sonstige nur selten benutzt werden!

 

Also, kommen wir zum nächsten Befehl!

ScaleTexture texture, Xwert,Ywert

Vergrößert eure Textur um die angegebenen Werte: beachtet, dass Texturen wiederum nur 2dimensional sind, und nur die X- und die Y-Koordinate enthält.

In das obige Programm könnt ihr ausprobieren, was passiert, wenn ihr eine Textur verändert:

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

AppTitle "Texturen in BB3D",1

 

cube=CreateCube ()

cube_text=LoadTexture ("text1.bmp")

EntityTexture cube,cube_text

 

cone=CreateCone (21)

cone_text=LoadTexture ("text2.bmp")

EntityTexture cone,cone_text

MoveEntity cone,15,0,0

 

sphere=CreateSphere (21)

sphere_text=LoadTexture ("text3.bmp")

EntityTexture sphere,sphere_text

MoveEntity sphere,-15,0,0

 

cam=CreateCamera()

CameraClsColor cam,0,100,255

MoveEntity cam,0,0,-30

PointEntity cam,cube

 

ScaleMesh cube,5,5,5

ScaleMesh cone,5,5,5

ScaleMesh sphere,5,5,5

 

xwert#=1

ywert#=1

While Not KeyHit(1)

If KeyHit(4) Then SaveBuffer FrontBuffer(),"image_textur1.bmp"

TurnEntity cone,1,1,1

TurnEntity cube,1,1,1

TurnEntity sphere,1,1,1

 

If KeyDown(200) Then

    xwert=xwert+0.1

    ywert=ywert+0.1

    ScaleTexture cone_text,xwert,ywert

    ScaleTexture cube_text,xwert,ywert

    ScaleTexture sphere_Text,xwert,ywert

EndIf

If KeyDown(208) Then

    xwert=xwert-0.1

    ywert=ywert-0.1

    ScaleTexture cone_text,xwert,ywert

    ScaleTexture cube_text,xwert,ywert

    ScaleTexture sphere_Text,xwert,ywert

EndIf

 

UpdateWorld

RenderWorld

Flip

Wend

ClearWorld

End

 

Wenn ihr eine Textur sehr klein macht, kann das so aussehen:

 

 

Hier sieht man, das eigentlich meine Textur schlecht ist, sie lässt sich nämlich nicht „kacheln“! Das bedeutet, dass wenn man eine Textur mehrmals auf einem Objekt hat, man die einzelne Textur (hier in dem roten Kreis) immer noch erkennen kann, und das sieht gar nicht schön aus!

Um das zu umgehen, gibt’s eigentlich nur diese Möglichkeiten:

Entweder man skaliert die Textur gleich so, dass die Textur über das ganze Objekt reicht, das macht ja Blitz3D von alleine…

Oder man malt einfach die Textur einfach so, dass man keine „Gleichheiten“ erkennen kann, und das kann man nur machen, indem man ausprobiert, wie die aktuelle Textur skaliert aussieht (Oder mit speziellen Programmen, die einem gleich die Textur nebeneinander anzeigt!

 

Aber wollen wir nun langsam zu den Objekten rübergehen!

Zunächst mal die Textureffekte:

 

Man kann beim Laden einer Textur gleich ein paar Effektsbefehle zuweisen:

Texture=LoadTexture („texture.bmp“,EffektNummer)

So, und „EffketNummer“ kann jetzt folgendes sein:

 

(1) Die Textur wird so ganz normal eingezeichnet wie man die gemalt hat

(2) Die Textur benutzt Alpha Map für Transparenz. Wenn dieser Effekt eingeschaltet ist, werden dunkle Stellen (sprich z.B. schwarz etc) auf der Textur transparenter eingezeichnet!

(4) Schwarze Flächen werden überhaupt nicht eingezeichnet.

(8) für weite Entfernungen wird eine Textur mit weniger Details benutzt.

(16) Textur-Koordinate U wird fixiert.

(32) Textur-Koordinate V wird fixiert.

(64) Spherical Reflection Map = Reflektionseffekt

(128) Reserviert für Cubic Environment Mapping

(256) Speichert Textur in VRAM = schneller

(512) Erstellt HighColor-Textur. So kann die Textur auch bei 16-Bit Farbtiefe weiterhin Alpha-Informationen enthalten.

[Beitrag aus der Onlinehilfe on blitzbase.de, danke an TheShadow]

 

Wichtig sind die Effekte 1,2,4 und vielleicht auch 64!

Also, noch mal:

Effekt 1 malt die Textur ganz normal: wenn man schreibt:

Text1=LoadTexture („muu.bmp“,1)

Kommt dasselbe raus, wie wenn man sagt:

Text1=LoadTexture („muu.bmp“)

 

Effekt 2 ist sehr hilfreich: er macht dunkle Stellen im Spiel später transparenter! Wenn man also eine Textur wie diese hier

 

nimmt, werden die dunkelroten Stellen transparenter eingezeichnet, als die normal roten Stellen!

 

Effekt 4 zeichnet schwarze stellen überhaupt nicht ein:

Die schwarzen stellen sind komplett transparent!

 

Effekt 64 benutzt die Textur als Spherical Reflection Map! Ein seltsamer Effekt, denn man sich aber ruhig mal vornehemen sollte! Schaut mal auf www.blitzbase.de im Lexikon nach! Ich habe jetzt keine Lust und vielleicht auch nicht das Wissen, euch das hier jetzt zu erklären, wie das genau funktioniert! Ein schönes Sample zu diesem Effekt liegt bei der Demoversion von Blitz3D dabei, nämlich „teapot“, schaut’ s euch an!

 

Alle anderen Effekte sind wie gesagt nur selten zu benutzen! Wenn euch doch einer interessiert schaut einfach mal in die Onlinehilfe!

Außerdem könnt ihr auch einfach selbst ein wenig mit den Effekten rumspielen!

 

Übrigens: Man kann auch mehrere Effekte gleichzeitig anwenden: Man muss nur schreiben …bmp“,1+4+64)!

 

Kommen wir nun zu den Effekten der Meshes: Man kann bei einem Entity

 

Die Tranzparenz sollte ja eigentlich klar sein: der Wert 0 macht es ganz durchsichtig, 1 vollkommen undurchsichtig!

Wenn man ein Objekt leuchtent macht, sieht halt aus, als würde es leuchten!

Und wenn man die Shininess auf 1 setzt kommt so was hier raus:

Ihr seht in der Mitte der Kugel einen hellen gelben Fleck, ihn kann man mit dem Effekt einschalten!

Ich habe hier unser kleines Programm ein wenig erweitert: Mit den Tasten [Hoch] und [Runter] kann man die Texturen vergrößern/verkleinern. Die Kugel wurde auf Shininess 1 gesetzt, und der Cone wurde mit einer Spherical-Reflection-Map versehen! Außerdem wird ständig ein Licht im Hintergrund gedreht, dass Auswirkungen auf den Shininess-Fleck hat!

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

AppTitle "Texturen in BB3D",1

 

cube=CreateCube ()

cube_text=LoadTexture ("text1.bmp")

EntityTexture cube,cube_text

EntityAlpha cube,0.5                        ;halb durchsichtig gemacht!

 

cone=CreateCone (21)

cone_text=LoadTexture ("text2.bmp",64)      ; mit SphericalReflectionMap versehen!

EntityTexture cone,cone_text

MoveEntity cone,15,0,0

 

 

sphere=CreateSphere (21)

sphere_text=LoadTexture ("text3.bmp")

EntityTexture sphere,sphere_text

MoveEntity sphere,-15,0,0

EntityShininess sphere,1                    ;Shininess auf 1 gesetzt1

 

cam=CreateCamera()

CameraClsColor cam,0,100,255

MoveEntity cam,0,0,-30

PointEntity cam,cube

 

ScaleMesh cube,5,5,5

ScaleMesh cone,5,5,5

ScaleMesh sphere,5,5,5

 

light=CreateLight()

TurnEntity light,45,45,0

 

xwert#=1

ywert#=1

While Not KeyHit(1)

If KeyHit(4) Then SaveBuffer FrontBuffer(),"image_textur1.bmp"

TurnEntity cone,1,1,1

TurnEntity cube,1,1,1

TurnEntity sphere,1,1,1

TurnEntity light,1,1,1

If KeyDown(200) Then

    xwert=xwert+0.1

    ywert=ywert+0.1

    ScaleTexture cone_text,xwert,ywert

    ScaleTexture cube_text,xwert,ywert

    ScaleTexture sphere_Text,xwert,ywert

EndIf

If KeyDown(208) Then

    xwert=xwert-0.1

    ywert=ywert-0.1

    ScaleTexture cone_text,xwert,ywert

    ScaleTexture cube_text,xwert,ywert

    ScaleTexture sphere_Text,xwert,ywert

EndIf

 

UpdateWorld

RenderWorld

Flip

Wend

ClearWorld

End

 

Jau, und das war’ s eigentlich auch schon mit den Effekten… bevor wir zu den Terrains kommen, möchte ich noch das MultiTexturing ansprechen!

  1. b) Multitexturing

 

Manchmal ist es notwendig, bestimmte Meshes mit 2 Texturen gleichzeitig zu versehen! Bei einem Terrain z.B. kann man eine Textur nehmen, die Gras, Erde und so darstellt! Um das ganze zu verschönern, kann man noch eine 2. Textur drüberziehen, die z.B. Dreck, Schotter etc. darstellt. Der Vorteil: Die Texturen können immer noch verschieden unabhängig voneinander skaliert werden. Hier mal ein Bsp:

Man erkennt gleich: links wurde Multitexturing angewendet, aber auf beiden Bildern ist die gleiche "Umgebungstextur", also das ockerfarbene drauf! Ich finde natürlich, dass das linke Terrain schöner aussieht, als das andere!

 

Die Befehle für Multitexturimg sind nicht speziell:

Erst mal die 2 Texturen laden:

Text1=LoadTexture(„textur1.bmp“)

Text2=LoadTexture(„textur2.bmp“)

 

Und dann ganz einfach beim EntityTexture-Befehl den Index, also die Schicht angeben!

EntityTexture beliebigesmesh, text1 ,0 ,0

EntityTexture beliebigesmesh, text1 ,0 ,1

 

Also, die erste Null (…,0,..) steht für den animationsframe, der soll uns jetzt nicht interessieren! Und die zweite Ziffer steht für die Schicht (0,1,2 oder 3)!

Es können jeweils nur 3 Schichten auf einem Mesh benutzt werden, jedoch gilt auch hier wieder, je mehr Texturen, desto höher der Rechenaufwand!! Außerdem muss man drauf achten, dass Multitexturing relativ neu ist und erst ab Grafikkarten der Generation GForce 3 benutzt werden kann, ihr könn ja in eurem Spiel die Option „Multitexturing“ optional angeben!

 

Kommen wir nun zu den Terrains!

 

  1. Terrains, Ebenen und Spiegel

 

Zunächst mal ein paar kleine Bilder, sie zeigen die Benutzung von Terrains:

Terrains werden sehr häufig benutzt, schon allein, weil sie so einfach zu erstellen sind. Die Terrains in Blitz3D werden mit sog. Heightmaps (Höhenkarte) geladen, solch eine Karte kann so aussehen:

  

Ihr seht gleich, es ist schwarzweiß! Blitz3D schaut sich jeden Pixel an, und ermittelt die Farbanteile, danach wird aus allen Pixels und Daten ein Terrain erstellt! Die Farbe Weiß bedeutet: hier ist die Map am höchstens, und ebenfalls bedeutet schwarz, dass hier die niedrigste Stelle ist. Also noch mal: dunkel bedeutet flach, hell bedeutet hoch!

Ganz einfach!

Jedoch woher bekommt man solche Heightmaps? Am besten macht man sich die natürlich selbst, aber was tun, wenn man nur Standartprogramme wie Paint und so hat und nicht die Möglichkeiten hat, solche „weichen“ Verläufe zwischen Hell und Dunkel zu erstellen? Ladet euch am besten „gimp“ runter! Einfach bei google.de ein bisschen gucken!

 

Der Befehl ist genauso einfach:

Terrain=LoadTerrain(„terrain.bmp“,[parent?])

 

Hier gilt genauso : „terrain.bmp“ sollte eine Größe haben wie 256 x 256 oder so! Außerdem können natürlich wie bei den Texturen auch Jpg- und Png-Dateien gelden werden, sofern ihr die Vollversion besitzt!

 

Schreiben wir doch mal ein kleines, aber diesmal längeres Programm, es ladet ein Terrain, mit der Kamera kann man über dieses Terrain drüberfliegen!

Die Texturen: terrain text1l.bmp

Und bei Multitexturing: mapt2.bmp

 

Hier der Code:

(Bei Multitext. Macht die „;“ weg!)

 

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

 

terrain=LoadTerrain("heightmap.bmp")

text1=LoadTexture ("terrain text1.bmp")

;text2=LoadTexture ("mapt2.png")

EntityTexture terrain,text1,0,0

;EntityTexture terrain,text2,0,1

ScaleEntity terrain,50,290,50

ScaleTexture text1,50,50

;ScaleTexture text2,3,3

 

 

cam=CreateCamera()

MoveEntity cam,1000,800,1000

CameraFogMode cam,1

CameraRange cam,1,30000

CameraFogRange cam,100,4000

CameraFogColor cam,40,140,255

CameraClsColor cam,40,140,255

light=CreateLight()

TurnEntity light,45,45,0

 

While Not KeyHit(1)

 

RotateEntity cam,EntityPitch(cam)+MouseYSpeed(),EntityYaw(cam)-MouseXSpeed(),0

MoveMouse 512,384

 

MoveEntity cam,0,0,2

 

RenderWorld

Flip

Wend

ClearWorld

End

 

Schön. Man fliegt mit einer kleinen Kamera über ein großes Terrain!

Eigentlich gibt es nicht viel zu erklären: Am Anfang wird ein Terrain geladen, es mit einer vergrößerten Textur angepinselt, das Terrain wird ebenfalls vergrößert und dann kommt halt noch der schöne Mouselook: Er ist ganz einfach zu Programmieren:

Jedes Mal wird der Drehung der Kamera die aktuelle Verschiebung der Maus an der Y-Achse hinzugefügt, und die Verschiebung and der X-Achse abgezogen! Dann wird nur noch die Drehung auf der Z-Achse auf 0 gesetzt, weil man keine Z-Drehung haben will!

 

Kommen wir nun zu den andren „Terrains“, nämlich erst mal die Ebenen, oder auch „Planen“. Eine Ebene ist unendlich groß: Erstellt man eine Ebene, und man fliegt immer weiter an einer Achse entlang, wird sich NIE ein Ende zeigen, also unendlich!

 

Der Befehl dafür ist:

Plane=CreatePlane()

Das ist ganz einfach, man kann diese Plane ganz normal wie ein Mesh behandeln: Texturen, drehen, alles kein Problem!

 

Da es hier drüber nicht mehr viel zu erzählen gibt, gehe ich nun zu den Spiegeln, Mirrors!

Auf dem Bild seht ihr rechts und links ein Terrain, in der Mitte Wasser, spiegelndes Wasser! Nun, wie erstellt man denn solches Wasser?

 

Mirror=CreateMirror()

 

Ich empfehle, nicht mehr als einen Mirror zu erstellen, es wird bei mehreren Spiegeln Probleme geben!

Erweitern wir doch mal unser Terrainsample mit einer transparenten Wasseroberfläche!

 

Textur für das Wasser: Wasser.bmp

Code:

Graphics3D 800,600,32,1

SetBuffer BackBuffer()

 

terrain=LoadTerrain("heightmap.bmp")

text1=LoadTexture ("terrain text1.bmp")

;text2=LoadTexture ("mapt2.png")

EntityTexture terrain,text1,0,0

;EntityTexture terrain,text2,0,1

ScaleEntity terrain,50,290,50

ScaleTexture text1,50,50

;ScaleTexture text2,3,3

 

water=CreatePlane()

watertext=LoadTexture ("water.bmp",4)

EntityTexture water,watertext

ScaleTexture watertext,100,100

MoveEntity water,0,10,0

EntityAlpha water,0.6

cam=CreateCamera()

 

MoveEntity cam,1000,800,1000

CameraFogMode cam,1

CameraRange cam,1,30000

CameraFogRange cam,100,4000

CameraFogColor cam,40,140,255

CameraClsColor cam,40,140,255

light=CreateLight()

TurnEntity light,45,45,0

 

While Not KeyHit(1)

 

RotateEntity cam,EntityPitch(cam)+MouseYSpeed(),EntityYaw(cam)-MouseXSpeed(),0

MoveMouse 512,384

 

MoveEntity cam,0,0,2

 

RenderWorld

Flip

Wend

ClearWorld

End

 

Ok, dieses Thema haben wir auch abgeschlossen!

 

Zum ersten war' s das auch schon mit meinem BB3D-Tutoria! Iich hoffe, es hat euch geholfen, und einen kleinen Einblick in Blitz3D gegeben!

Bei Fragen, Vorschlägen, Kritiken (auch negative ;) mailt ihr mir bitte: inpac@arcor.de

                                Cu