Affine Texture Mapping in BASIC

  • Affine Texture Mapping in BASIC

    Ich habe mal mit etwas rumgespielt, wofür BASIC nun eigentlich so gar nicht taugt: Texture Mapping! Das ganze ist ohne Perspektivkorrektur, also Playstation 1-Style und wie zu erwarten nicht sehr schnell. Eigentlich habe ich es für dieses Projekt als Fingerübung gebaut: BASIC V2 in Java

    Aber dann habe ich es auch mal, wo ich doch neulich so einen schönen 128er erworben habe, auf echter Hardware laufen lassen. An einem Frame rendert das Programm (ohne Setup-Arbeiten wie Bildschirm löschen usw, die auch alle in feinstem BASIC sind) ungefähr 6 Min. Compiliert mit Basic-Boss sind es aber nur noch etwa 24 Sek. Immer noch nicht so richtig Echtzeit, aber naja. Auf dem oben verlinkten BASIC-Interpreter-Ersatz läuft es allerdings in Echtzeit (siehe GIF).

    Wen es interessiert, hier ist das BASIC-Programm: jpct.de/stuff/affine/affine.prg
    Und hier eine compilierte Fassung: jpct.de/stuff/affine/affine compiled.prg

    Das Programm nutzt Integer-Variablen wo möglich (und teilweise auch nötig) (also die mit %). Ja, ich weiß, dass das im BASIC-Interpreter langsamer ist. Aber so ist deutlicher, welchen Wertebereich welche Variable wirklich haben muss und für den Basic-Boss ist es auch nützlich.

    So sieht das auf dem C128 aus (im C64-Modus...natürlich... ;) :(


























    Und so in meinem eigenen BASIC V2-Interpreter/Compiler in Echtzeit:
  • Tale-X schrieb:

    Gefällt mir! Was dagegen, wenn ich mich dran versuche, das in ne andere Sprache (Pascal) zu portieren? :)
    Nee, klar. Hau in die Tasten. Vielleicht noch zwei Anmerkungen:

    1. Der Code enthält kein 3D- und auch kein 2D-Clipping, d.h. alles, was die Sichtpyramide verlässt, sieht entweder komisch aus oder malt im Speicher rum. Mit den aktuellen Einstellungen ist das aber kein Problem.
    2. Die Textur liegt als 64*64-Bitmap im Speicher ab C000. In den Datas steht sie als RLE-gepackte (immer Anzahl Bytes, Wert) Quasi-Multicolor-Bitmap, allerdings planar. Also ohne diese Merkwürdigkeit beim C64 mit 8-Byte-Blöcken, sondern einfach hintereinander weg. Das Programm packt das Multicolor-Byteformat dann wieder aus, so das pro Byte ein Pixel vorliegt. Das muss man aber nicht so machen. Letztendlich liegen die Texturkoordinaten in der inneren Schleife in u% und v% (mit 128 multipliziert) vor. Du kannst darauf basierend also auch irgendwelche anderen Farbwerte von irgendwo auslesen.
  • Moin moin!

    Hier schon mal ein erster Zwischenstand (weitesgehend 1:1, aber plot-Befehl zum Zeichnen anstelle von Poke/Peek) - aber nur als compilierte Fassung :D

    Was mir alles dabei auffiel:
    1. Obwohl ich eigentlich mit denselben Werten arbeite, ist die Grafik bei der GPascal-Lösung etwas kleiner. Ein Grund könnte im Wertebereich der Sinusfunktion liegen (-511 bis 512 bei der Basiclösung, -511 bis 511 bei meiner Routine).
    2. Die Ränder sind bei mir ausgefranst (Rundungsfehler?)
    3. Die Basic-Version zeichnet _VIEL_ schneller (ungefähr doppelt so schnell - direkter Speicherzugriff schlägt Zeichenbefehl)
    4. Durch die Runtime wird das kompilierte Programm fast doppelt so groß.


    Gibt also noch einiges zu tun...
    Dateien
    • affintrans.prg

      (12,04 kB, 13 mal heruntergeladen, zuletzt: )
    Wissen ist das einzige Gut, das sich beim Teilen vermehrt. Also seid vorsichtig damit!
  • Interessant...die Fransen am Rand sind wirklich merkwürdig. Ich glaube, da stimmt eher was in der Berechnung nicht ganz. Für Rundungsfehler sind die etwas viel...denke ich. Vielleicht auch nicht...!?

    Ich habe die BASIC-Version noch etwas optimiert: jpct.de/download/tmp/affine.d64

    ...und eine Version gebaut, bei der die innere Schleife in (recht unoptimiertem) Assembler gebaut ist: jpct.de/download/tmp/affine_fast.d64
  • Wenn ich beim Nachschlagen der Pixel eine Bereichsprüfung einbaue, dann sind die Ausfransungen weg. Offenbar fängt er in einem Abschnitt manchmal einen Pixel zu früh an bzw. hört in dem anderen manchmal einen Pixel zu spät auf.

    Bei der Performance hatte ich spaßeshalber mal den Plotbefehl durch den Speicherzugriff wie im Basicprogramm realisiert - war dann noch langsamer. Könnte zwar jetzt auch den Assemblerweg nehmen, aber mich interessiert wie die Sprachen/Compiler gegeneinander bestehen :)
    Wissen ist das einzige Gut, das sich beim Teilen vermehrt. Also seid vorsichtig damit!
  • Bin im Basicprogramm noch auf eine Optimierungsmöglichkeit gestossen - die Tabelle mit den Sinuswerten. Zum einen wird im Programm nur auf die Einträge mit geradem Index zugegriffen (ganzzahlige Winkelangaben * 2). Zum anderen wird im schlimmsten Fall die Sinusfunktion 30mal verwendet - da kostet das Vorberechnen (viel) mehr als nachher eingespart wird.
    Wissen ist das einzige Gut, das sich beim Teilen vermehrt. Also seid vorsichtig damit!
  • Hallo,

    ich find das ja recht spannend. Wollte mir den BASIC-Code anschauen, aber wie lade ich ein prg-File in den Emulator, ohne das es gleich ausgeführt wird? Also das ich mir mit list den Code anschauen kann?

    EDIT: Oh, sehe gerade, da ist ja auch ein d64-file dabei.
  • Benutzer online 1

    1 Besucher