Mikrocontroller 3D-Engine
Update (10.06.2005): Sourcecode verfügbar!

3D-Grafik mit einem 8-Bit PIC Mikrocontroller??? Ja, es geht!
Als Basis für dieses Projekt dient der Minicomputer mit Grafikdisplay. Das Programm läuft auf einem PIC18F4525 mit 40 Mhz.

Zunächst ein paar Fotos & ein Video:

Rotierender Würfel

Mit den Tasten unter dem Display kann das 3D-Objekt bewegt und gezoomt werden.

(Bild anklicken zum Vergrößern)
Man beachte das Hardware-Antialiasing und -Motionblur :)
Da das Display für schnelle Bildwechsel scheinbar nicht gedacht ist, erzeugt die Rotation des 3D-Objektes 'Schlieren', was die Animation sehr weich und flüssig erscheinen lässt...
(Bild anklicken zum Vergrößern)
Ein rotierender Würfel ist schon toll, aber ein Zylinder ist noch ein klein wenig eindrucksvoller!
Das Objekt wird vor dem Start der Render-Schleife berechnet und im RAM abgelegt.
(Bild anklicken zum Vergrößern)
Mit steigender Anzahl an Linien sinkt logischerweise auch die Anzahl der Frames pro Sekunde.
32 Frames sind aber nicht schlecht...schließlich ist das Programm ausschließlich in C programmiert.
(Bild anklicken zum Vergrößern)
<<Video downloaden>> Einfache Bilder sind in diesem Fall einfach nicht repräsentativ genug.
Das Video (AVI-Format, ca. 3,5 MB) ist dafür besser geeignet!


Die Mikrocontroller der 18F-Serie haben eine beachtliche Rechenleistung erreicht. In Verbindung mit dem CCS C Compiler von Custom Computer Systems, Inc lassen sich aufwendige Projekte verwirklichen.
Die komplexe Floating-Point Mathematik kann einfach in C programmiert werden, der Compiler erzeugt einen offensichtlich recht effizienten Code. Sinus- und Cosinusberechnungen benötigen wie am PC sehr viel Zeit. So benötigt eine Sinusberechnung inclusive umwandlung des Winkels in Rad 5084 Befehle. Bei 40 Mhz sind das 1,02 ms pro Sinusberechnung, pro Frame sind 3 Sinus- und 3 Cosinusberechnungen nötig. Ein Großteil der Rechenzeit wird jedoch bei den Matrix - Matrix - Multiplikationen für die Rotation des 3D-Objektes benötigt. Anschließend erfolgt die Projektion der 3D-Vektoren in die 2D-Ebene.
Um zumindest die Rechenzeit der Trigonometriebefehle zu verkürzen werden vor Ablauf der Render-Schleife Lookup-Tables erzeugt. Man muss hierbei leider einen Kompromiß eingehen und in 2°-Schritten die sin- & cos-Werte berechnen, da der RAM des Controllers für 2x 360 Floatingpoint-Variablen nicht mehr ausreicht (512 Bytes werden bereits für den Grafikspeicher benötigt). Die Rotation der 3D-Objekte erfolgt deswegen auch nur in 2°-Schritten, was allerdings keineswegs bei der Animation auffällt.
Insgesamt hat das Programm hohe Speicheranforderungen. Da die Geometriedaten der 3D-Objekte sowie die Rotationsmatrizen als 4-Byte Float-Variablen abgespeichert werden müssen kommt man schnell an die Grenzen der 3986 Bytes des 18F4525. Die Trigonometrie-Lookup-Tables sowie die Geometriedaten im ROM abzulegen wäre hier wahrscheinlich eine Lösung...

WARUM???
Okay, einen besonderen Zweck erfüllt dieses Projekt eher nicht. Allerdings plagte mich schon seit dem Zusammenlöten des Minicomputers die Frage, ob auch aufwendigere Grafikspielereien mit dem teuren Display in Kombination mit einem PIC-Mikrocontroller möglich sind, auch wenn die PICs für solche Spielereien bestimmt nicht erfunden wurden. Gut, den Beweis habe ich wohl nun angetreten!
(ausserdem bin ich trotz ausgiebigem Googeln auf nichts vergleichbares gestoßen, somit war für mich klar, dass ich die Sache in die Hand nehmen muss! :)

So völlig sinnlos ist es eigentlich auch nicht, eine 3D-Engine für einen Mikrocontroller zu haben. Z.B. lassen sich so Messwerte sehr anschaulich als 3D-Diagramm oder das Zündkennfeld eines Kfz-Motors darstellen (und verändern....Yeah, The Fast & the Furious lässt grüßen ;)

Das Programm kann einfach an unterschiedliche Grafikdisplays bzw. an unterschiedliche Grafikdisplaycontroller (z.B. SED1335 oder Toshiba T6963) angepasst werden, da ausschließlich eine displayspezifische Putpixel-Funktion nötig ist.



SOURCECODE
Hier gibt es den Sourcecode von der 3D-Engine. Es werden zusätzlich die Datei
GRAPHICS.C sowie ein passender Display-Driver (wie z.B. KS0108.C) benötigt. Beide Dateien sind beim CCS C - Compiler dabei.

So sieht die Ausgabe des Beispielprogramms aus. Zusätzlich zu dem Linienmodell werden an den Würfelecken Kugeln gezeichnet. Im Inneren des Würfels befinden sich 6 weitere Kugeln, die sinusförmig animiert werden.

Das Beispielprogramm benötigt ca. 2800 Bytes RAM, läßt sich deshalb nur für den 18F4525 oder PICs mit ähnlich viel RAM kompilieren.
Will man das Programm für z.B. 18F458 kompilieren, so muss man wohl auf die Sinus/Cosinus-Tabellen verzichten. Diese verschlingen immerhin 1440 Bytes RAM! Wenn es nicht auf Genauigkeit ankommt, könnte man die Trigonomietabellen auch als Byte-Werte im Bereich von -127 und +128 abspeichern, der Speicherbedarf würde sich dadurch vierteln, allerdings erfordert dies auch ein paar weitere Rechenoperationen bei der Benutzung der sin/cos-Werte.
Eine andere Möglichkeit um RAM zu sparen wäre der Verzicht auf den Grafikspeicher. Jeder Pixel müsste dann einzeln an das Display geschrieben werden. Dies beeinträchtigt aber deutlich die Performance.

Die Dateien:

3DCubePIC.zip

Das Archiv beinhaltet die Dateien:
3d.c
3dmath.c
3dmath.h

Die Datei 3d.c ist kommentiert (Englisch), bei den Mathematikfunktionen wollte ich nicht weiter ins Detail gehen (in jedem 3D-Grafik-Buch zu finden)

Home
Letztes Update: 28.10.2007