CIRCLE schien mir der harmloseste Befehl im Handbuch. Bis ich für mein MMBasic-Vektorspiel mal mit TIMER umrahmt habe, was er pro Frame kostet. Das Ergebnis war einer der dicksten Posten im ganzen Renderer, und der war ohne großen Verlust loszuwerden.
Wo ich CIRCLE verwendet habe
Zwei Stellen im Spiel haben jeden Frame CIRCLE aufgerufen.
Erstens, an jeder Polygon-Ecke meiner Asteroiden ein kleiner gefüllter Punkt mit Radius 1, als Vertex-Marker im Vektor-Stil. Pro Asteroid mit zehn Ecken zehn CIRCLE-Aufrufe, mal vierzig Asteroiden gleich vierhundert Aufrufe pro Frame.
Zweitens, Schüsse waren als kleine gefüllte Kreise mit Radius 1 gezeichnet, also pro aktivem Schuss einer.
' alt: an jeder Asteroid-Ecke
FOR i = 0 TO num_verts - 1
CIRCLE temp_x(i), temp_y(i), 1, , , COL_WHITE, COL_WHITE
NEXT i
Was das Profiling gezeigt hat
Ich habe mit TIMER die einzelnen Phasen vom Frame umrahmt und jede Sekunde die ms-Werte rausgeschrieben. Der Drawing-Block war der dickste, und in dem Drawing-Block waren die CIRCLE-Aufrufe der dominante Posten. Ich glaube, dass CIRCLE intern Antialiasing oder zumindest mehrere Pixel-Operationen pro Aufruf macht, das relative Mehrfache von PIXEL entsteht aus dem Per-Aufruf-Overhead plus der eigentlichen Zeichenarbeit.
Was ich gemacht habe
Die Vertex-Marker als CIRCLE waren reine Optik. Die Polygone werden ohnehin mit POLYGON als geschlossener Linienzug gezeichnet, der Punkt an der Ecke hat dem nichts hinzugefügt, was nicht auch schon da war. Ergebnis: ersatzlos gestrichen.
' neu: einfach POLYGON, fertig
POLYGON num_verts, tmp_x(), tmp_y(), COL_WHITE
Für die Schüsse, die wirklich nur ein Pixel breit sein sollten, habe ich CIRCLE durch PIXEL ersetzt:
' alt
CIRCLE shot_x(i), shot_y(i), 1, , , COL_WHITE, COL_WHITE
' neu
PIXEL shot_x(i), shot_y(i), COL_WHITE
PIXEL setzt ein einzelnes Pixel, mehr nicht, und ist dadurch deutlich billiger.
Das war einer der größten Einzelgewinne im Renderer, die FPS sind danach merklich gestiegen. Nebenher ist mir aufgefallen, dass ein gefüllter CIRCLE mit Radius 1 nicht das Gleiche ist wie ein PIXEL — er belegt mehrere Pixel und wirkt im Vektor-Stil eher klobig. Selbst ohne den Performance-Aspekt wäre PIXEL für die Optik die saubere Wahl gewesen. Seitdem prüfe ich bei jedem Grafik-Befehl in der Hotloop, ob er wirklich das ist, was ich meine: PIXEL für einzelne Punkte, LINE für Striche, POLYGON für geschlossene Vektorformen, CIRCLE nur dann, wenn ich wirklich einen Kreis brauche.