Wenn die Fliesen etwas mehr Fliesen wären. Über die Grenzen der naiven Vorstellungskraft hinausgehen

Bild



Jeder, der jemals darüber nachgedacht hat, wie der grafische Teil eines 2D-Retro-Beschleunigers funktioniert, stellt grob dar, wie er diese berüchtigten Kacheln zeichnet, die übrigens aus der Definition nicht rechteckig sein müssen. Beim Fliesen geht es um Fliesen. Ja, meistens verstehen die Entwickler der Eisen-API dies und die Methoden heißen dementsprechend drawRect und nicht drawTile. Jedes Rechteck kann zwar eine Kachel sein, aber das Gegenteil ist nicht der Fall! Und dann braut sich die Frage zusammen: Warum 2D-Beschleuniger nur direkt dauerhaft beschleunigen ... Die einfache Antwort auf diese Frage ist, dass alles andere für ein einfaches Stück Hardware zu kompliziert ist. Aber hier würde ich streiten. Es kann mindestens eine einfache, aber hochfunktionale Erweiterung dieser grundlegenden Abstraktion vorgeschlagen werden:



Ich habe lange nicht mehr an Habr geschrieben. Weil ich es die ganze Zeit perfekt machen wollte ... Ich habe eine solche Krankheit. Habr selbst hat inzwischen die Messlatte deutlich gesenkt, und ich schreibe immer noch nicht und schreibe nicht. Daher wurde der heutige Artikel ohne Vorbereitung aus einem Gespräch mit einem Freund geboren. Es gibt jedoch Freunde, mit denen Sie tief und gründlich sprechen möchten.



Lassen Sie es vielleicht meine Rückkehr zur Regelmäßigkeit sein. Wenn solch ein Plus oder Minus leicht zu lesen ist, hastig in eine Farbe geworfen wird, aber zur Klärung nur minimal ausreicht, ist die Erzählung nicht mit Details überladen, sondern immer noch mit einem konzeptuellen Akzent, und wie früher wird eine Lampe wie ein teurer Leser.



Mit anderen Worten, heute suche ich nach einem Kompromiss zwischen der Qualität des Inhalts und der Zeit, die ich ihm widmen kann. Hoffe auf Verständnis.



Also, fangen wir an ...



Betrachten Sie als Beispiel die allgemeine Funktion des Kopierens eines beliebigen rechteckigen Bereichs. Wir sehen, dass dies nur eine Doppelschleife durch die Linien und durch die Elemente der Linien ist:



Bild



Beachten Sie, dass dieser Codeblock normalerweise trivial in x4-Kombinationen von Durchlaufrichtungen beider Schleifen wiederholt wird, um Reflexionen zu implementieren:



Bild



Weitere x2-Kombinationen werden durch die Permutation der Ordnung durch dst [x] [y] gegeben, die entlang der Achse reflektiert wird y = x.

Auf dem Weg sind diese 8 Optionen für Reflexionen alle möglichen Rotationen in Vielfachen von 90 g mit all ihren Spiegelreflexionen von links nach rechts.



Und nun schauen wir uns an, wie dieses Grundelement selbst mit minimalen Ergänzungen stark modifiziert werden kann.



Vielleicht ist es niemandem in den Sinn gekommen, aber warum kann eine Fliese zum Beispiel kein Parallelepiped sein? Mit Blick auf die Zukunft werde ich sagen, dass diese Erweiterung nur einen minimalen Overhead mit sich bringt, da Sie zur Implementierung nur ein paar Inkremente pro Zeile hinzufügen müssen:



Bild



Durch die Kombination mit der x / y-Permutation erhalten wir ein Parallelepiped mit einem Seitenpaar, das immer entlang einer Orthogonale ausgerichtet ist, und die anderen beiden sind in einem Winkel ... Was gibt uns diese billig erhaltene Kleinigkeit? Nun, erstens die Möglichkeit, drei feste Projektionen zu verwenden:



Bild



Wenn das Inkrement nicht als Konstante, sondern als Bruchzahl festgelegt wird, kann der Verschiebungswinkel frei werden. Was sowohl für die Wirkung schwankender Fliesen im Side Scroller



Bild



als auch für den Bau von Wänden im Raum isometrischer Projektionen perfekt genutzt werden kann :



Bild



Und denken Sie daran, dass gebrochenes Sprechen nicht unbedingt Float-Unterstützung bedeutet! Was ein moderner verwöhnter Programmierer manchmal vergisst. float ist ein Bruchteil des Gleitkommas, aber hier ist es völlig unnötig. Tatsächlich hat jeder Prozessor mit zwei Registern, bei denen der obere Teil des Paares als separater Wert gelesen werden kann, eine "Unterstützung" für einen gebrochenen Festpunkt (Festpunkt). Darüber hinaus wird in diesem Fall KEINE einzelne zusätzliche Anweisung hinzugefügt. (Nun, außer dass die Steigung auf 256. Schläge eingestellt wird) Also ist alles kostenlos, nimm Jungs!



Ein weiterer ähnlicher Schritt, den der aufmerksame Leser induktiv fordern sollte, ist die Wiederholung dieser Funktion bis zur zweiten Grenze der Aufzählung der inneren Schleife. Wir können das Endinkrement separat entkoppeln. Und dann können wir im allgemeinen Fall alle Trapeze zeichnen, die mit der Basis auf einem der Orthogonalen liegen (als Sonderfall von Dreiecken):



Bild



Und was zum Teufel haben sie uns aufgegeben? Sie werden denken, aber Sie werden sofort vermuten, dass Sie in nur zwei solchen Zeichnungsaufrufen einfach eine Ebene aus orthogonal ausgerichteten Sechsecken oder diagonal ausgerichteten Rauten aus einem dafür vorbereiteten Kachelsatz texturieren. Übrigens Kachelfälle, die in der Spielebranche weit verbreitet sind.



In den Tagen von J2ME
J2ME , . , ,



Es wäre großartig, Hardware-Unterstützung für sie auf dem Beschleuniger zu haben:



Bild



Was weiter beschrieben wird, ist seitdem eher eine Bonusfunktionalität Sie können es besser zielgerichtet implementieren. Wenn wir jedoch unter anderem nur davon sprechen, das Grundelement nur mit Farbe (oder einem flachen Muster) zu füllen, um den vorhandenen Spielraum einfach zu ergänzen ...



Das gleiche Paar von Zeichenaufrufen kann jedes Dreieck bilden, das nicht auf Einzelheiten beschränkt ist (es wird einfach durch eine orthogonale Linie entlang der Mitte in zwei Teile geschnitten Punkt, dies ist seinem klassischen Zeichenalgorithmus sehr ähnlich.) Und daraus ist es bereits möglich, Konstruktionen in Perspektive zu erstellen. Übrigens wird von den Trapezoiden selbst beispielsweise eine vertikal fixierte 3D-Projektion DOOM1 der Form elementar kostengünstig erhalten:

Bild



Wenn Sie möchten, können Sie versuchen, mit einer Füllung zu malen, sogar mit etwas mehr oder weniger großem Voxel. Abhängig von den Freiheitsgraden der Projektion werden mehr oder weniger Anrufe getätigt. Die ersten beiden perspektivischen Projektionen unten sind fest, haben jedoch jeweils 4 symmetrische Ansichten - für insgesamt 8 Anzeigewinkel. Der dritte ist ein häufiger Fall und wird nur vertikal festgelegt. Wenn Sie sich um die vertikale Achse drehen, wechselt sie zwischen der ersten und der zweiten:



Bild



Es ist besser, Figuren, wenn möglich, in Trapeze aufzuteilen, die entlang der Orthogonale des Schnitts länger sind, da die zusätzliche Anruffunktionalität, obwohl sie nicht teuer ist, mit Iterationen des äußeren Zyklus verbunden ist, von denen es wünschenswert wäre, weniger zu sein. Dies gilt sogar für das Zeichnen des grundlegenden Rechteckalgorithmus - horizontales Zeichnen ist effizienter als vertikales Zeichnen.



Es ist möglich, eine perspektivische Texturierung der Bonusfunktionalität in diesen Aufrufen durchzuführen, dies erfordert jedoch die Implementierung einer gebrochenen Skalierung und ist mit der Einführung zusätzlicher Divergenzkoeffizienten für src und Dezimierungskoeffizienten verbunden, die darüber hinaus in 3D-Dynamik eher schief berechnet werden müssen, was hierfür nicht ratsam ist einfache Architektur.



Nun, nachdem ich die Rache vor Habr für mein eigenes Interesse beendet habe, kann ich immer noch nicht widerstehen, kurz zu erklären, woher all diese Magie der Inkrementkoeffizienten algebraisch kommt. Die Formel der Geraden y = kx + b, die in Schulen gelehrt wird, schickt uns hier zweimal auf einmal Hallo. Alle Koeffizienten haben sich an ihren Stellen als nützlich erwiesen:



Bild



Warum bin ich bei einer solchen Implementierung von Kacheln nicht auf 2D-Hardwarebeschleuniger gestoßen, kann ich nur raten:



  • Tiles Konzept war in der Praxis ein so starres Muster, dass niemand dachte, sie könnten ein bisschen mehr tun ... viel mehr bekommen.
  • Entweder wollte niemand auch nur ein paar Taktzyklen für solche Funktionen aufwenden, weil sie die beschriebenen weit verbreiteten Konsequenzen nicht analysierten, oder die damaligen Entwickler mit einfachen Spielen stellten keine Nachfrage nach ihnen. Trotzdem gab es mode7 (einen Cheat-Algorithmus zur Implementierung der perspektivischen Texturierung durch Ausgabe von rechteckigen Sprites auf Hardware mit Unterstützung für die fraktionierte Skalierung).
  • Oder ich bin nicht alt genug und ich muss weitermachen ...



All Articles