amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Write/ReadPixelLine8 [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 [ - Beitrag schreiben - ]

10.12.2005, 18:58 Uhr

MaikG
Posts: 5172
Nutzer
Ich hab mir ja schon die Anleitungen aus dem NDK für OS3.9
durchgelesen. rp,xstart,ystart,width hab ich verstanden :-)
Bei Array und temprp bin ich mir unsicher.

Für Array hab ich gedacht Speicher mit AllocVec holen,
aber wieviel? Was ist das für eine berechnung (((width+15)>>4)<<4)?
Und wozu ist temprp eigentlich gut? Muss ich damit irgendwas
ausser
struct RastPort temprp;
machen?

Da eine 8 dahinter steht gehe ich davon aus das die Anzahl der Pixel
die ich haben möchte durch 8 teilbar sein muss?

Eigentlich muss ich nur eine Linie zwischenspeichern und dann wieder
zeichnen.

[ - Antworten - Zitieren - Direktlink - ]

10.12.2005, 19:58 Uhr

whose
Posts: 2156
Nutzer
@MaikG:

Also: Array ist der Speicher, in den die Farbwerte der Pixel einer von Dir spezifizierten Linie im sichtbaren Bild ausgelesen werden (ReadPixelLine8) oder aus dem die Farbwerte für eine ins sichtbare Bild zu bringende Linie genommen werden (WritePixelLine8). Das bedeutet, daß Array so groß sein muß, daß alle Farbwerte hineinpassen.

Dazu paßt auch die "seltsame" Berechnung (((width+15)>>4)<<4). Diese Berechnung sorgt dafür, daß die Breite der Linie eine durch 16 teilbare Zahl ergibt .

Um auch hier gleich die Erklärung zu liefern: Schreib Dir die tatsächliche Breite als binäre Zahl auf ein Stück Papier. Dann addierst Du 15 hinzu (wieder binär aufschreiben). Danach verschiebst Du alle Bits des Ergebnisses um 4 Stellen nach rechts und füllst links mit Nullen auf. Mach Dir keine Gedanken, wenn 4 Bits rechts "herausfallen" sollten, das ist der Gag dabei. Nun schiebst Du diese Bits (also OHNE evtl. verloren gegangene Bits) wieder 4 Stellen nach links und füllst rechts mit Nullen auf. Danach teile die entstandene Zahl durch 16. Wird immer glatt aufgehen ;)

Ist ein kleiner "Trick", um ganze Zahlen zu erhalten, die durch eine gewünschte 2er Potenz restlos teilbar sind. Bei einem gewünschten Mehrfachen von 8 z.B. würdest Du (((zahl+7)>>3)<<3) schreiben.

Read-/WritePixelLine8 und auch WritePixelArray8 benötigen die Daten in einer durch 16 teilbaren Anzahl pro Linie, weil diese Funktionen u.A. in ein anderes Ziel-Pixelformat konvertieren können. Diese Konvertierung wird in "Chunks" von 16 Bytes pro Vorgang durchgeführt, also muß eine Linie eine durch 16 teilbare Breite haben, damit die Konvertierung nicht "aus dem Tritt gerät". Dafür wird u.A. auch temprp benötigt.

Die 8, die hinter den Funktionsnamen steht, deutet darauf hin, daß diese Funktionen mit einer Farbtiefe von max. 8Bit (!) arbeiten.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233


[ Dieser Beitrag wurde von whose am 10.12.2005 um 20:10 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

10.12.2005, 23:33 Uhr

MaikG
Posts: 5172
Nutzer
>Read-/WritePixelLine8 und auch WritePixelArray8 benötigen
>die Daten in einer durch 16 teilbaren Anzahl pro Linie,
>weil diese Funktionen u.A. in ein anderes Ziel-Pixelformat
>konvertieren können. Diese Konvertierung wird in "Chunks"
>von 16 Bytes pro Vorgang durchgeführt, also muß eine Linie
>eine durch 16 teilbare Breite haben, damit die Konvertierung
>nicht "aus dem Tritt gerät".

Aha, dieses Shiften << >> hab ich noch nie gemacht, von daher
ist die gleichung für mich etwas unbekannt.

> Dafür wird u.A. auch temprp benötigt.

Aber da reicht dann dieses
struct RastPort temprp;
Muss ich also nichts weiter damit machen?

>Die 8, die hinter den Funktionsnamen steht, deutet darauf hin,
>daß diese Funktionen mit einer Farbtiefe von max. 8Bit (!)
>arbeiten.

Die Linie darf nur max. 8 Bit tief sein, das es in einem Fenster
auf der Workbench mit 16 Bit ist stört ja nicht, wenn ich das
richtig verstehe. Hab ja schon kurz die WritePixelArray8 benutzt.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 00:11 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:

Aha, dieses Shiften << >> hab ich noch nie gemacht, von daher
ist die gleichung für mich etwas unbekannt.


Nun weißt Du, wozu das gut ist :D Wie gesagt, das kann man auch bei anderen Gelegenheiten gut gebrauchen.

Zitat:
> Dafür wird u.A. auch temprp benötigt.

Aber da reicht dann dieses
struct RastPort temprp;
Muss ich also nichts weiter damit machen?


Du hast Dir die Parameter von Write-/ReadPixelLine8() nicht gründlich angeschaut, oder? Der letzte Parameter dieser Funktionen ist ein "struct RastPort *", nämlich ein Zeiger auf eben diesen temprp. Den mußt Du in Deinem Fall mittels &-Operator übergeben, also z.B. WritePixelLine8(......., &temprp);

Warum mit &? Wenn die RastPort-Struktur in Deinem Prog so angelegt wird, wie oben von Dir angegeben, handelt es sich um eine vom Compiler auf dem Heap angelegte Struktur und nicht um einen Zeiger darauf. Da ein Zeiger auf die Struktur von Write-/ReadPixelLine8() gewünscht wird, mußt Du dann logischerweise die Adresse auf diese Struktur übergeben, nicht den "Wert" der Struktur.

Zitat:
>Die 8, die hinter den Funktionsnamen steht, deutet darauf hin,
>daß diese Funktionen mit einer Farbtiefe von max. 8Bit (!)
>arbeiten.

Die Linie darf nur max. 8 Bit tief sein, das es in einem Fenster
auf der Workbench mit 16 Bit ist stört ja nicht, wenn ich das
richtig verstehe. Hab ja schon kurz die WritePixelArray8 benutzt.


Nein, es stört nicht (CGFX/P96 "emulieren" auch auf Screens >8Bit eine 8Bit-Palette). Du bekommst in jedem Fall nur Palette-Indizes zurück, also 8Bit-Einträge. Es kann Dir natürlich passieren, wenn Du die ...8()-Funktionen und CGFX/P96-Funktionen (also die ohne 8 ) mischst, daß Du dann eine 0 zurückbekommst. Also Obacht und darauf testen. Ist zwar nicht offiziell so dokumentiert, aber ich meine, bei ReadPixelLine8() käme als "count" 0 bzw. eine Zahl kleiner als Deine Linienbreite, wenn sich kein Palette-Index zuweisen läßt

Beim Setzen einer Linie passiert das Gleiche, es wird von WritePixelLine8() nur eine Linie mit den Farben der entsprechenden Paletten-Indizes aus Deinem Array gezeichnet.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233


[ Dieser Beitrag wurde von whose am 11.12.2005 um 00:21 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 10:38 Uhr

MaikG
Posts: 5172
Nutzer
Struct hab ich noch nicht kapiert, gabs unter basic nicht.

da war das halt rp&=PEEKL(mywin&+rport) - irgendwas definieren musste
ich nicht...


Gut mit den #?8 Funktionen bekommt man also nur die ersten 256 Farben
der Workbench.

Dann werde ich das mal ausprobieren, danke erstmal!

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 10:44 Uhr

thomas
Posts: 7717
Nutzer
@MaikG:

Zitat:
Aber da reicht dann dieses
struct RastPort temprp;
Muss ich also nichts weiter damit machen?


Doch. Laut Autodocs muß Temprp eine Kopie des RastPorts sein, in den du schreiben möchtest, aber mit dem Layer-Feld auf NULL gesetzt und mit einer Bitmap, die eine Zeile hoch ist und genauso breit wie das Feld, das du schreiben möchtest.

Also

code:
struct RastPort temprp;

temprp = *rp;
temprp.Layer = NULL
temprp.BitMap = AllocBitMap (w,1,8,0,NULL);
WritePixelArray8 (rp,x,y,x+w-1,y+h-1,array,&temprp);
FreeBitMap (temprp.BitMap);


Dabei ist (x,y) die Position im Fenster und (w,h) die Breite und Höhe des Feldes.

Zitat:
Aha, dieses Shiften << >> hab ich noch nie gemacht, von daher
ist die gleichung für mich etwas unbekannt.


Ein Shift nach links (<<) ist gleichbedeutent mit mal zwei und ein Shift nach rechts (>>) ist durch zwei, wobei der Rest abgeschnitten wird. Dementsprechend bedeutet << 4 viermal mal zwei, das ist einmal mal 16.

Die Formel ist also gleichbedeutend mit (((width+15)/16)*16). Shiften ist in Assembler schneller als Multiplizieren und Dividieren, deshalb wird es bevorzugt, wenn man mit Zweierpotenzen arbeitet.

Gruß Thomas
--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 12:40 Uhr

Ralf27
Posts: 2779
Nutzer
Mit diese Befehlen hab ich auch Anfang des Jahres zu kämpfen gehabt. Aber inzwischen läuft es auch ( :D ) bei mir.

Anbei auch nochmal danke an Thomas und whose.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 14:14 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomas:
Ein Shift nach links (<<) ist gleichbedeutent mit mal zwei und ein Shift nach rechts (>>) ist durch zwei, wobei der Rest abgeschnitten wird. Dementsprechend bedeutet << 4 viermal mal zwei, das ist einmal mal 16.

Und weil "mal mal" so blöd klingt, sagt der Mathematiker "mal 2 hoch 4"
Zitat:
Die Formel ist also gleichbedeutend mit (((width+15)/16)*16). Shiften ist in Assembler schneller als Multiplizieren und Dividieren, deshalb wird es bevorzugt, wenn man mit Zweierpotenzen arbeitet.
Aber an dieser Stelle totaler Unsinn. Wenn ich durch 16 Teile und danach wieder mit 16 Multipliziere, (oder das ganze mit shift nachbilde), dann nur, weil es bei integer-Operationen den Nebeneffekt hat, daß es die unteren 4 Bits auf 0 setzt, was einem Abrunden auf ein Vielfaches von 16 entspricht.
Das kann man natürlich auch direkt machen, (width+15)&(~15). >> und << mag ja schneller sein als / und *, aber noch schneller ist in jedem Fall gar keine dieser Operationen durchzuführen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 14:52 Uhr

whose
Posts: 2156
Nutzer
@Holger:

Öhm, ist ja richtig, daß es noch schneller ist, gar keine dieser Operationen durchzuführen, sofern das machbar ist. Hier gings aber um Read-/WritePixelLine8() sowie WritePixelArray8(), und diese Funktionen benötigen nun einmal ihre Daten in einer durch 16 teilbaren Anzahl.

Manchmal läßt es sich eben nicht vermeiden, daß man die Daten in einer anderen Anzahl vorliegen hat, dann sind diese Operationen auf jeden Fall notwendig. Wie willst Du z.B. eine Linie mittels WritePixelLine8() ins Bild bringen, die 325 Pixel lang ist, ohne den Rechner zum Absturz zu bringen, wenn Du diese Datenmenge nicht auf 336 Bytes erweiterst?

Das man mit (((width+15)>>4)<<4) eine Eigenschaft von Integerzahlen in ihrer binären Repräsentation ausnutzt, ist dabei doch nur natürlich. Und auf 68K-Maschinen ist das schneller als die entsprechenden logischen Operationen. Streng genommen eigentlich auf nahezu allen älteren CPUs.

Die logischen Operationen, die Du vorgeschlagen hast, sind aus Compilersicht natürlich "sauberer", das ist wahr. Aber hey, hier gehts um Amiga, da muß man sich noch nicht so dermaßen Gedanken darüber machen, ob ein Shift auf der nächsten Maschine noch etwas taugt oder nicht :D

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233


[ Dieser Beitrag wurde von whose am 11.12.2005 um 15:16 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 15:10 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
Struct hab ich noch nicht kapiert, gabs unter basic nicht.

da war das halt rp&=PEEKL(mywin&+rport) - irgendwas definieren musste
ich nicht...


Ok, aber der PEEKL oben ist schon sowas in der Art, was unter C mit Strukturen passiert. Die Zeile bedeutet, daß Du den Zeiger auf die RastPort-Struktur aus der Window-Struktur in die Zeigervariable rp übertragen hast. Ähnlich sieht das unter C aus, da hieße es

rp = mywin->rport

rp ist hier eine Variable der Art "struct RastPort *", also ein Zeiger auf eine RastPort-Struktur.

In Deinem Beispiel wars etwas anders, da hattest Du stehen

struct RastPort temprp;

Das veranlaßt den Compiler, Speicherplatz für eine komplette RastPort-Struktur bereitzustellen, also nicht nur für einen Zeiger. Wenn Du WritePixelLine8() als temprp die komplette Struktur übergibst (bildlich gesprochen), kommt da nichts brauchbares bei heraus. Der Compiler übergibt dann als Parameter etwas, womit WritePixelLine8() nichts besonders sinnvolles anfangen kann.

Veranlaßt Du den Compiler aber mittels &-Operator, als Parameter einen Zeiger auf den Beginn der von Dir angelegten temprp-Struktur zu übergeben, dann paßts.

Strukturen sind nichts anderes als ein kleiner Teil Speicher, in dem Werte unterschiedlicher Größen untergebracht werden können, jeder Wert an einer durch die Struktur vorbestimmten Stelle, gezählt vom Beginn der Struktur. Ist so ähnlich wie ein eindimensionales Array, nur mit dem Unterschied, daß die Einträge unterschiedliche Größen haben können.

Zitat:
Gut mit den #?8 Funktionen bekommt man also nur die ersten 256 Farben
der Workbench.


*hüstel* nein, Du bekommst die maximal möglichen 256 Farben der Palette der Workbench, sofern vorhanden. Und das sogar in Modi, die gar keine Palette im herkömmlichen Sinn bieten.

Bietet der Bildschirm aber weniger als 256 Farben, bekommst Du auch dementsprechend nur kleinere Palettenindizes, z.B. bis maximal 128, sofern die Farbtiefe des Bildschirms so eingestellt ist. Du solltest immer daran denken, daß die Bittiefe durchaus auch mal kleiner als 8 sein kann.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 19:40 Uhr

MaikG
Posts: 5172
Nutzer
Es geht nicht :-(


struct Window *win;
struct RastPort temprp;
struct RastPort *rp;
UBYTE *LinieS; /* Speicher für Linien zwischenpufferung*/

Fenster öffnen, Font öffnen...

LinieS = AllocVec((((304+15)>>4)<<4), MEMF_CHIP+MEMF_CLEAR);
if (LinieS)
{
temprp = *win->RPort;
temprp.Layer = NULL;
temprp.BitMap = AllocBitMap (304,1,8,0,NULL);
ReadPixelLine8 (rp,20,40,304,LinieS,&temprp);
WritePixelLine8 (rp,20,41,304,LinieS,&temprp);
FreeBitMap (temprp.BitMap);
FreeVec(LinieS);
}

Habs erst mit MEMF_CLEAR versucht, mit Chip und dann mit
beiden. Ich bekomme nur eine graue Linie.
Ich hatte auch noch 324 u. 323 statt 304 probiert.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:12 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Öhm, ist ja richtig, daß es noch schneller ist, gar keine dieser Operationen durchzuführen, sofern das machbar ist. Hier gings aber um Read-/WritePixelLine8() sowie WritePixelArray8(), und diese Funktionen benötigen nun einmal ihre Daten in einer durch 16 teilbaren Anzahl.

Wo man aber weder Multiplikation/Division, noch shift benötigt.
Zitat:
Das man mit (((width+15)>>4)<<4) eine Eigenschaft von Integerzahlen in ihrer binären Repräsentation ausnutzt, ist dabei doch nur natürlich. Und auf 68K-Maschinen ist das schneller als die entsprechenden logischen Operationen. Streng genommen eigentlich auf nahezu allen älteren CPUs.
Das will ich doch mal sehr bezweifeln. Auf dem 68060 beanspruchst beide integer-Einheiten mit von einander abhängigen Operationen, auf dem 68000 hängt die Ausführungszeit von der shift-Weite ab, und ab irgendwo dazwischen ein Prozessortyp existiert, bei dem zwei shift-Operationen tatsächlich schneller als eine AND-Operation sind, und der tatsächlich in einem realen AMiga verbaut wurde, vielleicht, ich glaube es aber eher nicht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:14 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
Es geht nicht :-(


struct Window *win;
struct RastPort temprp;
struct RastPort *rp;
UBYTE *LinieS; /* Speicher für Linien zwischenpufferung*/

Fenster öffnen, Font öffnen...

LinieS = AllocVec((((304+15)>>4)<<4), MEMF_CHIP+MEMF_CLEAR);
if (LinieS)
{
temprp = *win->RPort;
temprp.Layer = NULL;
temprp.BitMap = AllocBitMap (304,1,8,0,NULL);
ReadPixelLine8 (rp,20,40,304,LinieS,&temprp);
WritePixelLine8 (rp,20,41,304,LinieS,&temprp);
FreeBitMap (temprp.BitMap);
FreeVec(LinieS);
}

Habs erst mit MEMF_CLEAR versucht, mit Chip und dann mit
beiden. Ich bekomme nur eine graue Linie.
Ich hatte auch noch 324 u. 323 statt 304 probiert.


Ok, also als erstes solltest Du etwas bei den MemType-Flags ändern. Korrekt lautet das

MEMF_CHIP|MEMF_CLEAR

also ODER-verknüpfen.

Des weiteren hast Du einen winzig kleinen Fehler in

temprp = *win->RPort;

Der * gehört da nicht hin, denn damit erreichst Du genau das, was bei temprp ohne &-Operator passiert. Es wird der Inhalt der RastPort-Struktur übergeben, nicht der Zeiger auf den Beginn dieser Struktur.

Deswegen erhältst Du auch die graue Linie. Das, was da als scheinbarer RastPort übergeben wird, zeigt irgendwohin im Speicher, da die Linie grau wird, offensichtlich ein Bereich, welcher mit 0 gefüllt ist. Bemerkenswerterweise wird ja trotzdem eine Linie gezeichnet, obwohl rp "irgendwohin" zeigt, nur nicht auf den RastPort des gemeinten Fesnters. Frag mich aber jetzt nicht, warum da sichtbar gezeichnet wird. Vermutlich ein (ungewollter) Seiteneffekt der Struktur.

Nimm den * bei *win->RPort weg, dann sollte es funktionieren.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:15 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Habs erst mit MEMF_CLEAR versucht, mit Chip und dann mit
beiden. Ich bekomme nur eine graue Linie.


Laß mich raten, Deine Hintergrundfarbe ist grau?

Was hast Du denn erwartet?

mfg

Nachtrag: Wenn ich mich recht entsinne, beherrschte die CV64 das konvertieren von True/Pseudocolor in die 8Bit-Werte passend zur jeweils aktuellen Palette. Bei anderen Grafikkarten kannst Du das nicht erwarten...

[ Dieser Beitrag wurde von Holger am 11.12.2005 um 20:19 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:21 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von whose:
Öhm, ist ja richtig, daß es noch schneller ist, gar keine dieser Operationen durchzuführen, sofern das machbar ist. Hier gings aber um Read-/WritePixelLine8() sowie WritePixelArray8(), und diese Funktionen benötigen nun einmal ihre Daten in einer durch 16 teilbaren Anzahl.

Wo man aber weder Multiplikation/Division, noch shift benötigt.

Das habe ich ja schon zugegeben, daß man das auch "sauberer" mit logischen Verknüpfungen machen kann. Von "müssen" war meines Wissens nie die Rede.

Zitat:
Zitat:
Das man mit (((width+15)>>4)<<4) eine Eigenschaft von Integerzahlen in ihrer binären Repräsentation ausnutzt, ist dabei doch nur natürlich. Und auf 68K-Maschinen ist das schneller als die entsprechenden logischen Operationen. Streng genommen eigentlich auf nahezu allen älteren CPUs.
Das will ich doch mal sehr bezweifeln. Auf dem 68060 beanspruchst beide integer-Einheiten mit von einander abhängigen Operationen, auf dem 68000 hängt die Ausführungszeit von der shift-Weite ab, und ab irgendwo dazwischen ein Prozessortyp existiert, bei dem zwei shift-Operationen tatsächlich schneller als eine AND-Operation sind, und der tatsächlich in einem realen AMiga verbaut wurde, vielleicht, ich glaube es aber eher nicht.

Du denkst aber hoffentlich noch an die NOT-Operation, die auf das AND folgt? Sieh Dir das Ganze mal als Assembler-Quelltext an, beide Versionen. Dann urteile, was mehr und was weniger Zyklen benötigt. Ich glaube kaum, daß sich die Gurus das aus Jux und Dollerei ausgedacht haben, oder weil die etwas gegen "saubere" Programmierung hatten. Das hatte (wie eigentlich immer) seinen ganz speziellen Grund.

Schaden kanns jedenfalls nicht, wenn man ihm erklärt, was da genau passiert und warum, und ich denke, er wird sich die von Dir vorgeschlagene Variante auch schon mal in Binärrepräsentation angesehen haben. Wenn nicht, wird er es spätestens jetzt tun, denk ich :)

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:26 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Des weiteren hast Du einen winzig kleinen Fehler in

temprp = *win->RPort;

Der * gehört da nicht hin, denn damit erreichst Du genau das, was bei temprp ohne &-Operator passiert. Es wird der Inhalt der RastPort-Struktur übergeben, nicht der Zeiger auf den Beginn dieser Struktur.

Genau das will er ja auch: er legt eine Kopie des RastPorts an.
Zitat:
Deswegen erhältst Du auch die graue Linie. Das, was da als scheinbarer RastPort übergeben wird, zeigt irgendwohin im Speicher, ...
Bemerkenswerterweise wird ja trotzdem eine Linie gezeichnet, obwohl rp "irgendwohin" zeigt, nur nicht auf den RastPort des gemeinten Fesnters.


So ein Schmarrn. Du kannst nicht einen Pointer auf eine Struktur zuweisen oder umgekehrt. Unter C geht ja so einiges selbstzerstörerische, aber so etwas geht selbst unter C nicht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:29 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von MaikG:
Habs erst mit MEMF_CLEAR versucht, mit Chip und dann mit
beiden. Ich bekomme nur eine graue Linie.


Laß mich raten, Deine Hintergrundfarbe ist grau?

Was hast Du denn erwartet?

mfg

Nachtrag: Wenn ich mich recht entsinne, beherrschte die CV64 das konvertieren von True/Pseudocolor in die 8Bit-Werte passend zur jeweils aktuellen Palette. Bei anderen Grafikkarten kannst Du das nicht erwarten...

[ Dieser Beitrag wurde von Holger am 11.12.2005 um 20:19 Uhr editiert. ]


Was er erwartet hat? Das ReadPixelLine8() die korrekten Palette-Werte in sein Array schreibt. Das kann allerdings nicht funktionieren, wenn er "irgendwas" als Quell-RastPort angibt (rp = *win->RPort).

Mit der CV64 hast Du insofern Recht, wenn denn ROMBLER drauf sitzt. Ansonsten wird das von der GraKa-Software gehandhabt (Stichwort WriteChunkyPixels() und deren Fähigkeit, Hardware für die Konversion zu benutzen, sofern vorhanden. Ansonsten Software). Inzwischen sind CGFX/P96 so weit, daß die Palette-Emulation in allen Modi sehr gut funktioniert. Sonst würde kein Programm, welches auf Paletten-Indizes basiert, auf einem HighColor/TrueColor-Bildschirm vernünftig laufen.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:37 Uhr

whose
Posts: 2156
Nutzer
@Holger:

Stimmt, Du hast Recht. Ich war da ein klein wenig durcheinander geraten.

Andererseits: Wohin zeigt denn dann rp? Da der nirgendwo zugewiesen wird, offensichtlich "irgendwohin". Wenn da zufällig ne Reihe von Nullen steht, ist klar, weshalb ReadPixelLine8() nen Schwung Nullen liefert. Wobei ich mich immer noch frage, wie da eine Linie im sichtbaren Bild erscheinen kann.

Und man braucht inzwischen wirklich keine Hardware mehr, um auch auf High-/TrueColor-Bildschirmen mit Paletten zu hantieren.

@Maik:

Schau doch einmal in Deinem Programm, was da mit "rp" passiert. Wird rp dort ein Wert zugewiesen?

Ansonsten sollte das nämlich funktionieren.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233


[ Dieser Beitrag wurde von whose am 11.12.2005 um 20:38 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:38 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Du denkst aber hoffentlich noch an die NOT-Operation, die auf das AND folgt? Sieh Dir das Ganze mal als Assembler-Quelltext an, beide Versionen.

Meine Güte, NOT 15 ist eine Konstante.

Variante mit shift:

addq #7, d0
; pipeline stall
addq #7, d0
; pipeline stall
lsr #4, d0
; pipeline stall
lsl #4, d0

Variante mit AND
addq #7, d0
moveq #-16, d1
addq #7, d0
; pipeline stall
and d1, d0

So in etwa...
Zitat:
Dann urteile, was mehr und was weniger Zyklen benötigt. Ich glaube kaum, daß sich die Gurus das aus Jux und Dollerei ausgedacht haben, oder weil die etwas gegen "saubere" Programmierung hatten. Das hatte (wie eigentlich immer) seinen ganz speziellen Grund.
Die code-Beispiele von Commodore sind voll von Fragmenten, die wohl eher auf "Jux und Dollerei", manchmal auch aufgrund von Schwachsinn oder ähnlichem so entworfen wurden. Warum wohl, enthalten die Entwicklerdokumentationen Code-Beispiele, vor denen Commodore rückblickend selbst warnt, sie so einzusetzen und darauf hinweist, daß sie nur noch zu Informationszwecken beiliegen?
Zitat:
Schaden kanns jedenfalls nicht, wenn man ihm erklärt, was da genau passiert und warum, und ich denke, er wird sich die von Dir vorgeschlagene Variante auch schon mal in Binärrepräsentation angesehen haben. Wenn nicht, wird er es spätestens jetzt tun, denk ich :)

Schaden können Erklärungen niemals, genauso wie es auch nicht schadet, sich selbst mal zu fragen, warum etwas so dasteht, wie es jemand mal hingeschrieben hat, selbst dann, wenn es "die Gurus sich so ausgedacht haben".

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:46 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
@Holger:
Andererseits: Wohin zeigt denn dann rp? Da der nirgendwo zugewiesen wird, offensichtlich "irgendwohin".

Stimmt, die Zuweisung für rp fehlt, eventuell hat er sie aber nur beim posten weggelassen, so wie win, etc. ja auch.
Zitat:
Und man braucht inzwischen wirklich keine Hardware mehr, um auch auf High-/TrueColor-Bildschirmen mit Paletten zu hantieren.
Beim Schreiben, ja. Diese Operation ist auch wesentlich einfacher. Außerdem müssen dazu auch auf Palette-basierten Systemen die Pens gelockt sein, um konsistente Ergebnisse zu liefern.
Beim Lesen spielen Pens aber keine Rolle, weswegen das Ergebnis ohnehin nicht konsistent ist. Außerdem ist die 24/16Bit->8Bit Konvertierung wesentlich aufwendiger. Meines Wissens unterstützen die RTG-Systeme bis auf diese eine Ausnahme diese Operation nicht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 20:58 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Holger:

Beim Schreiben, ja. Diese Operation ist auch wesentlich einfacher. Außerdem müssen dazu auch auf Palette-basierten Systemen die Pens gelockt sein, um konsistente Ergebnisse zu liefern.
Beim Lesen spielen Pens aber keine Rolle, weswegen das Ergebnis ohnehin nicht konsistent ist. Außerdem ist die 24/16Bit->8Bit Konvertierung wesentlich aufwendiger. Meines Wissens unterstützen die RTG-Systeme bis auf diese eine Ausnahme diese Operation nicht.


Hmmm... soweit ich weiß, werden die Palette-Informationen des Fensters "wie gewohnt" gehandhabt und erst beim Blitten der "Planes" ins sichtbare Bild konvertiert, so daß die Palette-Informationen stets korrekt gehandhabt werden, auch beim Lesen. Probleme gibts erst, sobald man ausdrücklich Bitmaps höherer Farbtiefe anfordert und z.B. ins Fenster einhängt. Oder ganz ohne Fenster in einem High-/TrueColor-Modus arbeitet. Oder (am schlimmsten) selbst auf die "Planes" zugreift, um sich den Paletten-Index zu besorgen.

Ich denke, er sollte das mal auf einem Extra-Screen probieren, 8Bit Farbtiefe. Wenns dann tut, liegts an dem, was Du sagtest. Tuts dann immer noch nicht, liegt das Problem wohl doch woanders.

Mit absoluter Bestimmtheit kann ich dazu sowieso nichts sagen, weil ich bisher nur mit ReadPixel() gearbeitet habe. Mit Erfolg.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 21:12 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Hmmm... soweit ich weiß, werden die Palette-Informationen des Fensters "wie gewohnt" gehandhabt und erst beim Blitten der "Planes" ins sichtbare Bild konvertiert, so daß die Palette-Informationen stets korrekt gehandhabt werden, auch beim Lesen.

Auf Grafikkarten benutzt man normalerweise SimpleRefresh, aus Performancegründen. Sonst würde je jegliches Grafikprimitive einen Blit-Transfer erfordern, wenn es wie Du beschreibst in einem anderen Grafikmodus stattfinden würde, wär es die Hölle.
OS3.x unterstützt auch keine Palette pro Fenster, es gibt zwar ein Tag, aber das wird nicht benutzt.

Wenn man SuperBitmap oder SmartRefresh benutzt, hat ein Fenster vielleicht eine eigene BitMaps, aber normalerweise im gleichen Format, wie die Grafikkarte.
Zitat:
Ich denke, er sollte das mal auf einem Extra-Screen probieren, 8Bit Farbtiefe. Wenns dann tut, liegts an dem, was Du sagtest. Tuts dann immer noch nicht, liegt das Problem wohl doch woanders.
Das ist natürlich ein guter Test.
Zitat:
Mit absoluter Bestimmtheit kann ich dazu sowieso nichts sagen, weil ich bisher nur mit ReadPixel() gearbeitet habe. Mit Erfolg.

Unter welchem OS (RTG-System)?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 11.12.2005 um 21:13 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 21:20 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Holger:

Auf Grafikkarten benutzt man normalerweise SimpleRefresh, aus Performancegründen. Sonst würde je jegliches Grafikprimitive einen Blit-Transfer erfordern, wenn es wie Du beschreibst in einem anderen Grafikmodus stattfinden würde, wär es die Hölle.
OS3.x unterstützt auch keine Palette pro Fenster, es gibt zwar ein Tag, aber das wird nicht benutzt.


Das wohl nicht, aber es existiert ja die Screen-eigene Palette. Und die muß ja irgendwie umgesetzt werden. Ansonsten könnte man sich sämtliche Palette-basierten Funktionen einfach sparen. Ich sehe ein, daß das mit den Read-Funktionen dann nicht gerade einfach wäre, gerade bei Simple Refresh.

Zitat:
Zitat:
Ich denke, er sollte das mal auf einem Extra-Screen probieren, 8Bit Farbtiefe. Wenns dann tut, liegts an dem, was Du sagtest. Tuts dann immer noch nicht, liegt das Problem wohl doch woanders.
Das ist natürlich ein guter Test.

Ist zumindest die naheliegendste Lösung. Die Modi sind ja zum Glück auf nahezu allen Karten Palette-basiert.

Zitat:
Zitat:
Mit absoluter Bestimmtheit kann ich dazu sowieso nichts sagen, weil ich bisher nur mit ReadPixel() gearbeitet habe. Mit Erfolg.

Unter welchem OS (RTG-System)?


OS3.9, CyberGraphX V4.1. P96 ließe sich einfach testen auf WinUAE. Allerdings lief das Progrämmchen auf einem eigenen 8Bit-Bildschirm.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

P.S.: Ich kenne die Shifterei in Assembler aber etwas anders als Du gezeigt hast (nur ein lsl). Evtl. kann Thomas dazu nochmal was genaueres sagen. Ansonsten muß ich mal nachschauen, was ich in meinen alten Quellen noch schönes habe. Hab laaaaaange nicht mehr in Assembler gearbeitet.

[ Dieser Beitrag wurde von whose am 11.12.2005 um 21:28 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 21:51 Uhr

NoImag
Posts: 1050
Nutzer
Zitat:
Original von whose:
Zitat:
Zitat:
Mit absoluter Bestimmtheit kann ich dazu sowieso nichts sagen, weil ich bisher nur mit ReadPixel() gearbeitet habe. Mit Erfolg.

Unter welchem OS (RTG-System)?


OS3.9, CyberGraphX V4.1. P96 ließe sich einfach testen auf WinUAE.


Habe ich das richtig verstanden, du hast auf einem >8Bit-Bildschirm mit ReadPixel() den Farbstift, mit dem der Pixel gemahlt wurde ausgelesen?

Tschüß,



[ Dieser Beitrag wurde von NoImag am 11.12.2005 um 21:52 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 22:02 Uhr

whose
Posts: 2156
Nutzer
Hm, es gibt einfach Tage, an denen man besser nicht postet. Ich war jetzt die ganze Zeit intern bei 8Bit-Modi. Dabei habe ich doch schon vorher Maik darauf hingewiesen, daß er den Rückgabewert von ReadPixelLine8() testen soll, wenn er mit CGFX/P96 arbeitet... tststs :lach:

@Maik

Bau doch bitte den Test ein, den ich ein paar Beiträge weiter oben angeregt habe. Kommt da ne 0 bei raus, is nix mit ReadPixelLine8(). Es ist völlig richtig, daß das auf Screens >8Bit mit Pixel lesen nicht funktioniert. Das geht nur auf Screens mit einem Bildschirmmodus, der palettenbasiert arbeitet. Auf den allermeisten GraKas geht das in Modi mit 8Bit Farbtiefe. Wenn Du auf einem Bildschirm mit einer Farbtiefe >8Bit die Farbinformationen haben willst, geht das nur mit den entsprechenden Funktionen von CGFX/P96 (ReadPixelArray, korrekt?).

Sry nochmal für meine Verwirrtheit heute. Ich bin wohl schon zu alt für Weihnachtsmärkte und Glühwein :glow:

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 23:36 Uhr

MaikG
Posts: 5172
Nutzer
Ja, das mit den *win ist schon richtig, der tmprp wird auch
vorher schon benutzt. Hab jetzt kurz mal die WB auf 8Bit,
da gehts.

Also muss ich jetzt die noch kompliziertere Funktion
ReadPixelArray benutzten? Und die geht dann auf beidem
AGA und CGX?

[ - Antworten - Zitieren - Direktlink - ]

11.12.2005, 23:49 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
Ja, das mit den *win ist schon richtig, der tmprp wird auch
vorher schon benutzt. Hab jetzt kurz mal die WB auf 8Bit,
da gehts.

Also muss ich jetzt die noch kompliziertere Funktion
ReadPixelArray benutzten? Und die geht dann auf beidem
AGA und CGX?


Nein, da mußt Du unterscheiden. Ist aber nicht schwer, wenn Du zu Beginn schon feststellst, welche Farbtiefe Dein Bildschirm hat und ob das Pixelformat CLUT ist. Wenn >8Bit oder nicht CLUT, dann solltest Du ReadPixelArray benutzen (das ist allerdings wirklich etwas komplexer wegen der vielen möglichen Pixelformate). Ansonsten funktionieren ReadPixelLine8() und Co.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

12.12.2005, 08:26 Uhr

thomas
Posts: 7717
Nutzer

Was ist bei ReadPixelArray kompliziert ? Ich finde die Funktion wesentlich einfacher als ReadPixelArray8. Da brauchts keinen Temprp, kein Shiften. Und "viele Pixelformate" gibt es auch nicht. Du gibst das Format an, das du haben möchtest (üblicherweise RECTFMT_RGB24) und brauchst dir keine weiteren Gedanken zu machen.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

12.12.2005, 09:41 Uhr

MaikG
Posts: 5172
Nutzer
>Nein, da mußt Du unterscheiden. Ist aber nicht schwer,
>wenn Du zu Beginn schon feststellst, welche Farbtiefe
>Dein Bildschirm hat und ob das Pixelformat CLUT ist.

Mh, wie geht das? Bei Basic hatte ich da SYSTAB, damit
konnte ich höhe,breite und Tiefe der WB Abfragen.



>Was ist bei ReadPixelArray kompliziert ? Ich finde die
>Funktion wesentlich einfacher als ReadPixelArray8.
>Da brauchts keinen Temprp, kein Shiften. Und "viele
>Pixelformate" gibt es auch nicht. Du gibst das Format an,
>das du haben möchtest (üblicherweise RECTFMT_RGB24) und
>brauchst dir keine weiteren Gedanken zu machen.


RECTFMT_RGB24 - geht das auch beim 16 Bit Schirm?
Kannst du mir nicht ein beispiel geben? Nur eine Linie
von a nach b brauche ich.

[ - Antworten - Zitieren - Direktlink - ]

12.12.2005, 09:53 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von MaikG:
>Nein, da mußt Du unterscheiden. Ist aber nicht schwer,
>wenn Du zu Beginn schon feststellst, welche Farbtiefe
>Dein Bildschirm hat und ob das Pixelformat CLUT ist.

Mh, wie geht das? Bei Basic hatte ich da SYSTAB, damit
konnte ich höhe,breite und Tiefe der WB Abfragen.


Ist nicht böse gemeint, aber Du solltest erstmal lernen was struct bedeutet. Dann wirs Du feststellen, daß es screen Strukturen gibt, deren Komponenten die gewünschten Informationen enthalten.


--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Write/ReadPixelLine8 [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.