3D-Grundkurs für Anfänger

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

The_Nici

Betreff: 3D-Grundkurs für Anfänger

BeitragMi, Okt 29, 2008 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Einleitung

Eigentlich wollte ich schon immer ein Tutorial schreiben, also mache ich einmal ein kleines Tutorial über 3D.
Voraussetzung wäre Robs BBkurs oder ein anderes Grundtutorial, optional sind auch 2D Kenntnisse.

1.1. Theorie und Vorteile hingegen zu 2D

Bevor wir uns voller Vorfreude auf unsere IDE stürzen müssen wir erst einmal damit befassen, was überhaupt 3D ist. Ich werde hier nur Grundlegendes erläutern, ich will nicht gerade Neulinge im Gebiet 3D mit Vertices und Triangles zubomben. Also betrachten wir einmal den Unterschied zwischen 3D und 2D. Auffallend ist schonmal, dass wir eine dritte Dimension haben, also eine dritte Achse!
2D:
Code: [AUSKLAPPEN]

Y
|
|
|
|_ _ _ _ _ _ X


Jedoch in 3D kommt noch eine Z-, eine Tiefenachse hinzu!
Code: [AUSKLAPPEN]

Y
|      Z
|    /
|  /
|/_ _ _ _ _ _ X


Schön, nicht?
Dank dem Entity-System von BlitzBasic3D brauchen wir auch keine Koordinaten mehr zu speichern, denn da gibt es die Commands EntityX, EntityY und EntityZ. Diese geben uns die jeweilige Koordinate eines 3D-Objektes zurück.
Aber halt, was ist nun ein Entity?
Ein Entity (auf gut Deutsch "Objekt") ist entweder eine 3D-Figur, eine Kamera oder eine Lichtquelle.
Häh, Kamera?
Gut, jetzt für was brauchen wir eine Kamera?
Die Kamera nimmt ein Bild auf und projeziert es auf den Bildschirm.
Das klingt jetzt kompliziert, ist aber einfach. Die Kamera ist eigentlich der Beobachter.
Code: [AUSKLAPPEN]

                  ______
\ O/ - - - - -   |      |
  |              |  O_O |
 /\              |______|


Das tolle Strichmännchen (Unsere Kamera) sieht einen lustigen unförmigen Klotz mit einem Gesicht darauf (Unser Entity)
Nun sehen wir das aber nicht als dritter, sondern wir sehen das was die Kamera sieht (hier unser Strichmännchen). In unserem Falle etwa das:
Code: [AUSKLAPPEN]

 _______
|       |
|       |
|_______|


Manche mögen jetzt vielleicht noch die Frage haben "Was ist ein Licht?".
Ein Licht ist, tatsächlich ein Licht. Jedoch nicht mit Stencil Shadows etc, es gibt nur Vertices-Schatten an. Heisst, ein paar Seiten des Würfels sind dann einfach dunkler.

1.2. Praktische Umsetzung unseres theoretischen Beispiels

Nun wollen wir erst einmal den 3D-Grafikmodus + BackBuffer initialisieren.
Code: [AUSKLAPPEN]

Graphics3D 800,600,32,1 ;3D Grafikmodus mit der Auflösung 800x600, der Farbtiefe 32bits und im Vollbild.
SetBuffer BackBuffer() ;Der BackBuffer

Nun brauchen wir eine Kamera und ein Licht.

Code: [AUSKLAPPEN]

Graphics3D 800,600,32,1 ;3D Grafikmodus mit der Auflösung 800x600, der Farbtiefe 32bits und im Vollbild.
SetBuffer BackBuffer() ;Der BackBuffer

camera = CreateCamera() ;Erstellt eine Kamera namens "camera".
light = CreateLight() ;Erstellt ein Licht mit dem schönen Namen "light".

Wenn wir das Ausführen sehen wir natürlich noch nichts.
Also, platzieren wir etwas, das wir sehen können.
Für unser Beispiel einen Würfel.

Code: [AUSKLAPPEN]

Graphics3D 800,600,32,1 ;3D Grafikmodus mit der Auflösung 800x600, der Farbtiefe 32bits und im Vollbild.
SetBuffer BackBuffer() ;Der BackBuffer

camera = CreateCamera() ;Erstellt eine Kamera namens "camera".
light = CreateLight() ;Erstellt ein Licht mit dem schönen Namen "light".
cube = CreateCube() ;Erstellt einen Würfel namens "cube".


Jetzt haben wir ein Problem. Blitz3D erstellt alle Entitys beim Nullpunkt, also auf der Position 0,0,0 (X,Y,Z).
Also müssen wir unsere Objekte positionieren und rotieren. Dies machen wir mit den Befehlen PositionEntity und RotateEntity

Code: [AUSKLAPPEN]

Graphics3D 800,600,32,1 ;3D Grafikmodus mit der Auflösung 800x600, der Farbtiefe 32bits und im Vollbild.
SetBuffer BackBuffer() ;Der BackBuffer

camera = CreateCamera()
light = CreateLight()
cube = CreateCube()
PositionEntity camera, 0,3,5 ;Positioniert die Kamera auf dem Punkt 0,3,5
PositionEntity light, 10,10,0 ;Siehe oben
RotateEntity camera, 30,180,0 ;Dreht die Kamera 30° um die X- und 180° um die Y-Achse.


Oh toll! Aber wir sehen immer noch nichts. Sad
Warum denn? Na ist doch klar, die Kamera hat noch nichts aufnehmen können, da noch nichts gezeichnet wurde! Wir können die ganze 3D-Welt mit einem Befehl "rendern", also zeichnen. Dieser lautet RenderWorld.

Code: [AUSKLAPPEN]

Graphics3D 800,600,32,1 ;3D Grafikmodus mit der Auflösung 800x600, der Farbtiefe 32bits und im Vollbild.
SetBuffer BackBuffer() ;Der BackBuffer

camera = CreateCamera()
light = CreateLight()
cube = CreateCube()
PositionEntity camera, 0,3,5
PositionEntity light, 10,10,0
RotateEntity camera, 30,180,0
RenderWorld ;Welt zeichnen
Flip ;Buffer tauschen
WaitKey() ;Auf Tasteneingabe warten
End ;Beenden


Tadaa, wir sollten nun einen schönen Würfel sehen!
Wollen wir nicht noch etwas Bewegung reinbringen? Oh ja, wir wollen!
Lasst uns den Würfel drehen. Mit RotateEntity? Nöö, das erwartet doch absolute Angaben. Also nehmen wir lieber TurnEntity. TurnEntity dreht ein 3D-Objekt einen gewissen Wert um eine oder mehrere Achsen.
Beispiel:
Code: [AUSKLAPPEN]

TurnEntity tollerwuerfel, 0,1,0 ;Dreht tollerwuerfel um ein Grad um die Y-Achse. d.h. ein grad zur aktuellen Drehung dazu!


Was brauchen wir also noch? Genau, eine Schleife.
Der fertige Code könnte so aussehen:


Code: [AUSKLAPPEN]

;Grafikmodus + Buffer
Graphics3D 800,600,32,1
SetBuffer BackBuffer()

;Entitys
camera = CreateCamera()
light = CreateLight()
cube = CreateCube()
;Objekte richtig ausrichten
PositionEntity camera, 0,3,5
PositionEntity light, 10,10,0
RotateEntity camera, 30,180,0
;Schleife
While Not KeyHit(1)
   ;Objekte bewegen
   TurnEntity cube, 0,1,0
   ;Objekte zeichnen
   RenderWorld
   Flip ;Buffer flippen
   Cls ;Buffer löschen
Wend
End


--Ende des ersten Teiles--
...to be continued...

Würde mich über Anregungen, Beschimpfungen und Danksagungen freuen!

Mit freundlichen Grüssen
The_Nici

Eingeproggt

BeitragMi, Okt 29, 2008 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm.. Weiß nicht so recht. Du hast dir sichtlich Mühe gegeben. Alles erklärt, aufn ersten Blick keine Rechtsschreibfehler entdeckt, "Skizzen" sind dabei... Alles soweit ok.

In diesem Tutorial erklärst du aber lang und breit einen Code, wie man ihn auch in der Hilfe findet (so ähnlich) den man aber mit den Grundkenntnissen aus dem RobKurs eh im großen und ganzen verstehen sollte, oder hab ich da jetzt eine etwas zu hohe Erwartungshaltung?

EDIT: Hab den Code ein bissi nachbearbeitet, wie er mir besser gefällt... Nunja, Geschmackssache...
Code: [AUSKLAPPEN]
;Grafikmodus + Buffer
Graphics3D 800,600,0,0
SetBuffer BackBuffer()

timer=CreateTimer(50)

;Entitys
camera = CreateCamera()
light = CreateLight()
cube = CreateCube()
;Objekte richtig ausrichten
PositionEntity camera, 0,3,5
PositionEntity light, 10,10,0
PointEntity camera,cube
;Schleife
While Not KeyHit(1)
   ;Objekte bewegen
   TurnEntity cube, 0,1,0
   ;Objekte zeichnen
   RenderWorld
   ;Auf Timer warten, damit CPU nicht voll ausgelastet wird
   WaitTimer(timer)
   Flip 0;Buffer flippen
   Cls ;Buffer löschen
Wend
End


mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

flona

BeitragMi, Okt 29, 2008 20:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr anfängerfreundlich erklärt *daumenhochhalten* Exclamation
Könntest bei der Kamera noch kurz erwähnen in welche Richtung die denn erstellt wird, da dort nur steht wie weit sie gedreht wird, aber nicht warum.
www.Dreier-Florian.kilu.de
Intel Core 2 Quad Q9400 | Zotac 9800GT | 4GB RAM | 1TB HDD | Windows 7 Professional 32bit

The_Nici

BeitragMi, Okt 29, 2008 21:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Eingeproggt: Danke, den Timer habe ich extra weggelassen, ich will nicht die Leute verwirren. Rechtschreibfehler werde ich ausbessern wenn ich welche finde.

flona: Danke, die Kamera wird am Anfang logischerweise im Winkel 0,0,0 gedreht. Ich hätte sie auf 3,-5 verschieben müssen, um den Würfel noch ohne Drehung zu sehen. Da sich RotateEntity jedoch gerade anbot mit eingenommen zu werden, habe ich es gerade dazugenommen. ;>

MfG
The_Nici

PS: Teil 2 wird sich um weitere Objekte(Meshes, Pivots) und Texturen kümmern.

Xeres

Moderator

BeitragMi, Okt 29, 2008 21:49
Antworten mit Zitat
Benutzer-Profile anzeigen
The_Nici hat Folgendes geschrieben:
Eingeproggt: Danke, den Timer habe ich extra weggelassen, ich will nicht die Leute verwirren.
Ich glaube, es wäre weniger verwirrend, wenn Timer in allen Beispielen vor kämen. Wenn du Grundkenntnisse voraussetzt, musst du das warum ja nicht lang und breit erklären.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Der Eisvogel

BeitragSa, Nov 01, 2008 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann mir mal jmd sagen wie ich mir da ein Koordinatensystem einzeichnen kann, damit ich es besser verstehe?
Ungarische Notation kann nützlich sein.
BlitzMax ; Blitz3D
Win 7 Pro 64 Bit ; Intel Core i7-860 ; 8 GB Ram ; ATI HD 5750 1 GB
Projekte: Window-Crasher
Ich liebe es mit der WinAPI zu spielen.

Eingeproggt

BeitragSa, Nov 01, 2008 15:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Diesen Code nach Renderworld und vor Flip einfügen (und event. noch die "20" ändern. Ich hab das einfach mal so aus einem Code rauskopiert)
Code: [AUSKLAPPEN]
CameraProject cam,0,0,0
   x0=ProjectedX()
   y0=ProjectedY()
   z0=ProjectedZ()
   CameraProject cam,20,0,0
   Color 255,0,0
   If z0 Then Line x0,y0,ProjectedX(),ProjectedY()
   If ProjectedZ() Then Text ProjectedX(),ProjectedY(),"X"
   CameraProject cam,0,20,0
   Color 0,255,0
   If z0 Then Line x0,y0,ProjectedX(),ProjectedY()
   If ProjectedZ() Then Text ProjectedX(),ProjectedY(),"Y"
   CameraProject cam,0,0,20
   Color 0,0,255
   If z0 Then Line x0,y0,ProjectedX(),ProjectedY()
   If ProjectedZ() Then Text ProjectedX(),ProjectedY(),"Z"
   Color 255,255,255


mfG, Christoph.

EDIT: Würde etwas einfacher gehen, wenn man sich zB Cones als Koordinatenkreuz zurecht legt, aber mir gefällts mit CameraProject besser Smile
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Der Eisvogel

BeitragSa, Nov 01, 2008 16:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Noch ne Frage:
Wie kann ich den Mittelpunkt von einem Kegel ermitteln?
Oder wie kann man die Breite/Höhe/Tiefe eines Kegels ermitteln?
Ungarische Notation kann nützlich sein.
BlitzMax ; Blitz3D
Win 7 Pro 64 Bit ; Intel Core i7-860 ; 8 GB Ram ; ATI HD 5750 1 GB
Projekte: Window-Crasher
Ich liebe es mit der WinAPI zu spielen.

the FR3AK

BeitragSa, Nov 01, 2008 16:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Tiefe/Höhe/Breite:

MeshDepth,MeshHeight,MeshWidth

das alles durch 2 Teilen dann sollte es der MittelPunkt sein:

MeshWidth/2,MeshHeight/2,MeshDepth/2

Der Eisvogel

BeitragSa, Nov 01, 2008 16:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah, Danke.
Wenn ich mit PositionEntity ein Mesh versetzte, wird dann die linke,obere,vordere Ecke an die angegebene Posiotn gesetzt oder der Mittelpunkt des Mesh?
Ungarische Notation kann nützlich sein.
BlitzMax ; Blitz3D
Win 7 Pro 64 Bit ; Intel Core i7-860 ; 8 GB Ram ; ATI HD 5750 1 GB
Projekte: Window-Crasher
Ich liebe es mit der WinAPI zu spielen.
 

Phlox

BeitragSa, Nov 01, 2008 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Der relative Nullpunkt. (Meistens der Mittelpunkt des Meshes)

The_Nici

BeitragSa, Nov 01, 2008 19:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit PositionMesh kannst du auch den Mittelpunkt verändern, jedoch muss dieser Befehl vor allen Entity-Befehlen den du mit dem Mesh machst ausgeführt werden.

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group