Hallo,
Ich habe folgendes Problem:
Ich habe ein Display mit 96x96 Pixel, das wird als Array mit 12 Byte pro
Line im Speicher dargestellt.(Display ist noch nicht vorhanden, bzw
aktuell defekt...kann deshalb sein das im Code unten noch ein Fehler
ist..am Debugger im Memory Fenster schaut's aber OK aus)
Ich habe jetzt eine 8x8 Font als Header, den ich in den Framebuffer
kopieren möchte. Mein erster Versuch kopiert das jeweilige Byte vom Font
Zeile für Zeile an die Cursor Position. Geht zum nächsten Zeichen usw.
Aber wie bekomm' ich dort jetzt einen Abstand von zB. 2 Pixel unter.
Ich stehe im Moment echt auf dem Schlauch...Kann mir wer einen Schubs in
die richtige Richtung geben?
Nun, so wie du es jetzt machst, kann ein Zeichen nur an einem Vielfachen
von 8 Pixeln stehen. Wenn du das pixelgenau positionieren willst, ist
das deutlich mehr Rechenaufwand, da jede Zeile deines Zeichens nun auf
zwei Bytes im Framebuffer verteilt werden muss. Dazu kommt noch, dass du
diese beiden Bytes nicht komplett überschreiben darfst, sondern sie erst
von dort einlesen, mit deinen neuen Bits befüllen und dann wieder
rausschreiben musst.
Ich würde die Zeichen nur 7 Pixel breit machen und einen Pixel leer
lassen, so dass man sie direkt nebeneinander zeichnen kann. Dann spart
man sich diese umständliche Handhabung. 7 Pixel sind eh geschickter.
Ist zwar eine Möglichkeit, aber löst leider das grundlegende Problem
nicht. Ich muss Bit genau adressieren.
Vielleicht sogar noch mehr Info: das Problem wird im Endausbau dann noch
schlimmer, wenn der Text auch aufs Pixel genau platziert werden muss.Und
dann setz ich noch eins drauf und muss mit 3Bit/Pixel (RGB jeweils 1
Bit) hantieren.
Mir ist es deshalb wichtig eine Lösung für das Problem zu finden und es
nicht zu umschiffen.
Ich hab jetzt auch noch weiterüberlegt:
Den Buffer auf 1Byte pro Pixel aufblasen, alle Framebuffer Operationen
dort erledigen und im Anschluss auf das Displayformat in einem Rutsch
runterbiegen. Nicht gerade Ressourcen schonend :(
Gut Bitmanipulation ist klar, wenn ich einzelne Bits schreiben will :)
Aber eine Möglichkeit wenn ich wirklich Pixel für Pixel schreiben will
ist mir dadurch trotzdem gekommen...Division bzw Modulo...mit der
Divison das richtige Byte im Array selektieren und um den Restwert
shiften. Pixel für Pixel, Bit für Bit...
Hmmm klingt wie wenn da trotzdem viel zum optimieren überbleibt?!
Man merkt, daß man alt wird. In den 80er und 90ern war das Schreiben in
Bitmap-Displays täglich Brot (alle Homecomputer arbeiteten so) und da
wurden unendlich Stunden reininvestiert um auf den lahmen Gurken
schnelle Algorithmen zu basteln.
Leider ist in unserem modernen Internet nicht mehr viel davon zu finden
und man muß das Rad neu basteln.
Für dein Problem ist es wahrscheinlich am einfachsten, die
Display-Bitmap nicht als char-Array, sondern als 16-Bit short-Array zu
betrachten (dann hast Du Platz, dein Zeichen an die richtige Stelle zu
shiften).
Du brauchst eine linke und eine rechte Bitmaske, die die Zielbits
markiert, die Du ändern willst (dazu shiftest Du einfach 0xffff um x % 8
einmal nach rechts und einmal nach links und machst ein short draus).
Dann holst Du dir das Bitmuster, das Du ändern willst, aus deinem
Displaybuffer, maskierst es mit der Maske, kopierst das geshiftete
Bitmuster des Zeichens, das Du schreiben willst, da rein und schreibst
das ganze Wort in den Displaybuffer zurück. Das machst Du für jede Zeile
des Zeichens und schon bist Du fertig.
Michael schrieb:> Und> dann setz ich noch eins drauf und muss mit 3Bit/Pixel (RGB jeweils 1> Bit) hantieren.
...also nur 8 unterschiedliche Farben oder wie viel Farben sollen pro
Pixel möglich sein?
Markus F. schrieb:> Für dein Problem ist es wahrscheinlich am einfachsten, die> Display-Bitmap nicht als char-Array, sondern als 16-Bit short-Array zu> betrachten (dann hast Du Platz, dein Zeichen an die richtige Stelle zu> shiften).
Danke! Jetzt hats Klick gemacht! 16bit war das Stichwort...kommt davon
wenn man die ganze Zeit auf der Leitung steht :)
@ Michael (Gast)
>Ist zwar eine Möglichkeit, aber löst leider das grundlegende Problem>nicht. Ich muss Bit genau adressieren.
Pixelgenau. Ist auch nicht WIRKLICH schwer. Wie es geht, wurde mehrfach
gesagt.
>Den Buffer auf 1Byte pro Pixel aufblasen, alle Framebuffer Operationen>dort erledigen und im Anschluss auf das Displayformat in einem Rutsch>runterbiegen. Nicht gerade Ressourcen schonend :(
Unsinn ^3!
Hier gibt es ein Beispiel, wie es in etwa funktioniert.
Beitrag "Re: ATMEGA8(Pong) - Grundsatzfrage bzgl. Überschreiben des alten Zustands der LED">Gut Bitmanipulation ist klar,
Wenn es dir WIRKLICH klar wäre, wärst du läbgst mit der Umsetzung
beschäftigt und würdest nciht sinnlos rumlabern.
>Aber eine Möglichkeit wenn ich wirklich Pixel für Pixel schreiben will>ist mir dadurch trotzdem gekommen...Division bzw Modulo...mit der>Divison das richtige Byte im Array selektieren und um den Restwert>shiften. Pixel für Pixel, Bit für Bit...
Diesen Unsinn macht keiner, denn das dauert deutlich länger, als mit ein
paar passenden Bitmasken je 2 Bytes / Zeile zu überschreiben.
sinngemäß so
Warum den so aggressiv? Ich sitze vormittag bei nem Kaffee und nicht
gleich vorm Code...
Falk B. schrieb:>>Gut Bitmanipulation ist klar,>> Wenn es dir WIRKLICH klar wäre, wärst du läbgst mit der Umsetzung> beschäftigt und würdest nciht sinnlos rumlabern.
Wie grundsätzlich Bitmanipulation funktioniert ist klar..das hat nichts
mit rumlabern zu tun. Hat mir nur nicht bei der Lösung des Problems
geholfen...der zweite Link von guest allerdings schon! Dafür hab ich
mich auch bedankt.
Man steht halt manchmal auf dem Schlauch wenn man mit dem Kopf eig. bei
ganz anderen Problem ist ;)
Zum Rest: Markus F. hat mich schon auf den richtigen Weg gebracht...
summsumm schrieb:> Michael schrieb:>> Und>> dann setz ich noch eins drauf und muss mit 3Bit/Pixel (RGB jeweils 1>> Bit) hantieren.> ...also nur 8 unterschiedliche Farben oder wie viel Farben sollen pro> Pixel möglich sein?
...und nochmal die Frage...! Da mir das etwas komisch vorkommt und die
Lösung dann etwas anders aussehen muss...
summsumm schrieb:>> Michael schrieb:>>> Und>>> dann setz ich noch eins drauf und muss mit 3Bit/Pixel (RGB jeweils 1>>> Bit) hantieren.
Ja ist so wie du sagst, aber das bekomm ich jetzt in den Griff..mir hat
nur ein Tritt in die richtige Richtung gefehlt :)
Ob Du in Deinem Array uint8_t oder uint16_t hast spielt eigentlich keine
Rolle, das Prinzip bleibt gleich und auch bei 16 Bit hast Du irgendwann
das Problem über eine Elementgrenze hinweg schreiben zu müssen. Kommt
auch auf den µC an, auf einem AVR sind sowieso alle Zugriffe 8-bittig,
da kommst Du mit uint8 am Ende besser weg. Auf einem ARM und X86 wäre
uint32_t besser und bei X64/ARM64 halt uint64_t.
Wenn Du RGB mit 1 Bit pro Farbe brauchst kannst Du überlegen, ob Du
jedem Pixel noch ein viertes Bit spendierst, also exakt 2 Pixel pro
Byte. Das erspart die Probleme mit dem Alignment kostet aber etwas
Speicher. Je nachdem was die Displayhardware tatsächlich hergibt könnte
man das zusätzliche Bit noch als Blink-/Helligkeitsbit interpretieren,
so ala CGA zu seligen DOS Zeiten.
Irgendwann landest Du sowieso bei etwas ähnlichem wie:
Michael schrieb:> Ich hab jetzt auch noch weiterüberlegt:> Den Buffer auf 1Byte pro Pixel aufblasen, alle Framebuffer Operationen> dort erledigen und im Anschluss auf das Displayformat in einem Rutsch> runterbiegen. Nicht gerade Ressourcen schonend :(
Denn egal wie Du Deinen Framebuffer organisierst, am Ende müssen die
Daten zum Display. Und wenn das Display einem eigenen Framebuffer hat,
kanns Du dessen Organisation eh nicht ändern (oder zumindest nur sehr
eingeschränkt).
Michael schrieb:> Aber wie bekomm' ich dort jetzt einen Abstand von zB. 2 Pixel unter.
Trenne mal zwischen der physischen Belegung und deinem logischen
Display-RAM. Wenn du was durchgängig funktionierendes haben willst, dann
lade dir die Lernbetty hier im Forum herunter. Ich hatte damals in der
BettyBase eine durchaus universell benutzbare Grafikschnittstelle
geschrieben. Als primitivste Funktion brauchst du dort was zum Setzen
eines Pixels (also sinngemäß SetzePixel(x,y,color);) und alle anderen
Funktionen wie CgPutChar und so sind dort draufgesetzt. Fonts gibt's
dazu auch, Positionierung ist frei wählbar.
W.S.