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

amiga-news.de Forum > Programmierung > Maus über Grafik mit AOS-API erkennbar? [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

29.07.2013, 15:38 Uhr

Reth
Posts: 1753
Nutzer
Hallo zusammen,

ist leider etwas umständlich ausgedrückt. Mich beschäftigt die Frage ob (und wenn ja, wie am effektivsten) für ein graphisches Objekt, das kein GUI-Element (wie z.B. ein Button o.ä.) ist erkannt werden kann, wann sich der Mauszeiger darüber befindet?

Vorbild wäre z.B. so etwas wie Goodgame Empire, bei dem das jeweilige Gebäude durch einen Rahmen hervorgehoben wird, sobald es sich unter dem Mauszeiger befindet (zugegeben: Browser, HTML, CSS und JavaScript helfen da schon enorm mit).

Wie kann man den so etwas für das AmigaOS in C/C++ nachbauen, wenn man z.B. Grafiken in BitMaps verwendet? Die Prüfung sollte dann auch (wenigstens annähernd) den normalen Begrenzungen der Grafiken entsprechen und nicht dem rechteckigen Umriss, den die BitMap vorgibt.

Bisherige Suchen hier im Forum und im Web blieben für mich leider ergebnislos.

Vielen Dank schon einmal!

Ciao

[ - Antworten - Zitieren - Direktlink - ]

29.07.2013, 15:46 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Naja, zu irgendeinem Zeitpunkt hast du die GRafik ja auf den Bildschirm gemalt. Und deshalb kennst du die Koordinaten.
Dann prüft du zuerst, ob es innerhalb des Rechtecks sein soll. Wenn ja, dann kannst du noch detailierter die Bitmaske oder den Alphakanal testen, ob dort auch wirklich sichtbare Pixel sind. Ist das so schwer?

--
--
Author of
NTUI, AIDE, A/A++, HD-Rec, MacroWave, Sweeper, Samplemanager, ArTKanoid, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ImageConverter, ScreenCam, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de

[ - Antworten - Zitieren - Direktlink - ]

29.07.2013, 16:25 Uhr

Reth
Posts: 1753
Nutzer
@Der_Wanderer:

Danke. Der erste Teil nicht so sehr, der zweite Teil schon eher. Nach meiner Vorstellung müsste ich dafür die Mauskoordinaten auf die BitMaske abbilden/mappen und dort nach einem sichtbaren Pixel suchen.

Aber wie mach ich z.B. Letzteres (das mit dem Auffinden sichtbarer Pixel) vom Prinzip her? Da hätte ich noch keine Idee (die Koordinaten-Abbildung selbst schaff ich hoffentlich).

[ - Antworten - Zitieren - Direktlink - ]

29.07.2013, 18:44 Uhr

Thore
Posts: 2266
Nutzer
Kannst auch mit einer Farbmaske machen die im "Hintergrund" ist, und dann eben den Farbwert pro Koordinate abfragen. Braucht halt mehr Speicher aber geht schnell zu ermitteln wo der Grafikbereich ist.

[ - Antworten - Zitieren - Direktlink - ]

30.07.2013, 09:10 Uhr

Holger
Posts: 8037
Nutzer
@Reth:
Die erste Frage ist ja, in welcher Form Deine Grafik vorliegt. Im klassischen AmigaOS mit BitPlanes wird die Transparenz üblicherweise durch eine Maske, also eine zusätzliche BitPlane definiert. Da ist es natürlich simpel, den Wert für einen Punkt auszulesen, der dann entweder 0 oder eins ist.

Bei TrueColor-Grafiken mit Alphakanal musst Du selbst entscheiden, ab welchem Grad der Transparenz Du von einem Hintergrund-Pixel ausgehst. Dann ist der Rest allerdings auch einfach: lies aus der Grafik den Farbwert und prüfe, ob der Alpha-Wert größer oder kleiner als dieser Schwellwert ist.

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

[ - Antworten - Zitieren - Direktlink - ]

30.07.2013, 12:57 Uhr

Reth
Posts: 1753
Nutzer
@Thore:

Bin mir nicht sicher, ob ich Dir da folgen kann, drum muss ich nochmal nachfragen:
Wie hilft der Farbwert in diesem Fall bei der Zuordnung zu einem graphischen Objekt, um dieses zu identifizieren?
Wenn es keine Hintergrundfarbe ist, dann ist es ein Objekt? Stehe da wohl gerade auf dem Schlauch.

[ - Antworten - Zitieren - Direktlink - ]

30.07.2013, 21:35 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Du kennst die Koordinaten und Größen der Objekte. Damit kannst du ermitteln durch einfache Subtraktion, wo der gewünschte Punkt im Objekt liegt. Liegt er innerhalb des Begrenzungsrechtecks, dann muss genauer auf die Sichtbarkeit des Pixels geprüft werden. Und das geschieht indem man sich, je nach Grafikformat, die Bitmaske oder den Alphakanal an der betreffeneden Stelle anschaut. Ist die Bitmaske gesetzt, oder der Alphakanal größer als ein bestimmter Schwellwert, z.B. 192, dann gilt der Pixel als gesetzt und das Objekt als getroffen.

--
--
Author of
NTUI, AIDE, A/A++, HD-Rec, MacroWave, Sweeper, Samplemanager, ArTKanoid, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ImageConverter, ScreenCam, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de

[ - Antworten - Zitieren - Direktlink - ]

30.07.2013, 23:07 Uhr

Reth
Posts: 1753
Nutzer
@Der_Wanderer:
Das mit den Koordinaten und der Objektermittlung gibst bei mir schon (zumindest für einige Dinge).
Allerdings das Prüfen, ob ein Bit in der Maskenbitmap meines Objektes gesetzt ist, dafür hab ich noch keine Prüfung. Die muss ich mir noch überlegen bzw. bauen (da die BitMap ja als Abbild im Speicher liegt und mir gerade keine Funktion bekannt ist, gesetzte Bits zu prüfen).

Sorry, wenn ich nochmal nachfrage: Bei der Subtraktion hab ich doch schon ermittelt, dass der Punkt im umgebenden Rechteck liegt (mit der Subtraktion wird der genaue Ort bestimmt), oder meinst Du hier etwas Anderes?

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 09:31 Uhr

Holger
Posts: 8037
Nutzer
Zitat:
Original von Reth:
Allerdings das Prüfen, ob ein Bit in der Maskenbitmap meines Objektes gesetzt ist, dafür hab ich noch keine Prüfung. Die muss ich mir noch überlegen bzw. bauen (da die BitMap ja als Abbild im Speicher liegt und mir gerade keine Funktion bekannt ist, gesetzte Bits zu prüfen).

Wenn es eine BitMap ist, gibt es eine Funktion. Nur weil die primär dazu dient, die Farbe eines Bildpunktes auszulesen, bedeutet das ja nicht, dass sie nicht auch für eine Masken-BitMap funktioniert. Es ist der Programmierer, der entscheidet, welche Bedeutung der ausgelesene Wert hat.

Wenn es sich dagegen nur um eine BitPlane für die Maske handelt, kannst Du entweder manuell das Bit auslesen, oder einfach eine Pseudo-BitMap mit dieser einzelnen Plane konstruieren und die System-Funktion nutzen.
Zitat:
Sorry, wenn ich nochmal nachfrage: Bei der Subtraktion hab ich doch schon ermittelt, dass der Punkt im umgebenden Rechteck liegt (mit der Subtraktion wird der genaue Ort bestimmt), oder meinst Du hier etwas Anderes?
Die Subtraktion liefert Dir erst einmal gar keine Aussage, sondern nur Zahlen. Du überspringst da gedanklich etwas. Natürlich gilt, wenn die Subtraktion die relativen Koordinaten liefert, dass ein einfacher Vorzeichen-Check schon sagt, wenn die Koordinaten in zwei von vier Richtungen außerhalb des Objekts liegen. Trotzdem musst Du noch mit Höhe und Breite der Bounding Box (BitMap des Objekts) vergleichen, um alle vier Richtungen zu prüfen.

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

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 14:13 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Mit der Subtraktion meine ich, die Screen Koordinaten in Bitmap Koordinaten umzurechnen. Das hast du scheinbar bereits gemacht, und weist nun welchen X/Y Pixel der Bitmap du auf Transparenz befragen willst.
Wie das genau geht, hängt leider von dem Pixelformant der Bitmap ab, es gibt keine OS Funktion ReadOpacity() ala ReadPixel().
Wenn es sich um eine Bitmaske handlet, dann musst du die Addresse auf die Maske holen, die entsprechende Position berechnen und dann das bit ausmaskieren. Dazu musst du dich mit Bit Operatoren auseinandersetzen.

Wenn es ein Alphakanal ist, dann kannst du per Byte-Zugriff den Alphawert auslesen, entweder aus den ARGB Daten oder falls vorhanden externen Alpha Kanal Byte Array. Leider brauchst du in allen Fällen Zugriff auf die Bitmap, was dir z.B. AROS standardmäßig nicht erlaubt.
Evtl. ist es daher besser, die Bitmaps in einer eigenen Struktur zu halten und mit Read/WritePixelArray und einer eigenen Routine auf den Screen zu bringen. So mache ich das bei AB3 mit den Bitmaps.



--
--
Author of
NTUI, AIDE, A/A++, HD-Rec, MacroWave, Sweeper, Samplemanager, ArTKanoid, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ImageConverter, ScreenCam, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 14:20 Uhr

geit
Posts: 332
[Ex-Mitglied]
Am einfachsten und schnellsten geht es, wenn du alle dargestellten Objekte kennst, bzw dir merkst. Ich machte für sowas eine kleine Node die statt Namen die Struktur der Grafik enthält.

Beim Rendern eines Objects, allokier ich eine Struktur, trage die Grafik ein und linke das in eine Liste.

Der Vorteil ist du kannst überlappende Objekte von hinten nach vorne Rendern. Um jetzt schnell ein Objekt zu finden, brauchst du nur die Mauskoordinate mit allen Objekten in der Liste abgleichen. In diesem Fall rückwärts, weil das vorderste Objekt ja hinten liegt. Hast du ein Objekt gefunden, das in den Koordinaten liegt, dann kannst du den Pixel mit dem Alpha vergleichen. Ist der Pixel also 90% durchlässig oder größer, suchst du weiter, bis du ein Objekt hast, das Position und Pixel entspricht.

Nun kannst du das Objekt einfach mit mehr Helligkeit/weniger Transparenz drüber rendern und es leuchtet auf.

Sollen andere Objekte nicht übermalt werden, mußt du vom aktuellen Objekt an die Liste entlang aktualisieren. Das kann man noch durch eine Koordinatenkontrollierte Rekursion eingrenzen, weil du ja nur betroffene Objekte rendern willst, um Rechenzeit zu sparen. So werden dann nur Objekte neu gezeichnet die vor dem aufleuchtenden und (eben rekursiv) auch vor diesen Objekten liegen.

Geit



[ Dieser Beitrag wurde von geit am 31.07.2013 um 14:20 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 21:06 Uhr

Reth
Posts: 1753
Nutzer
Danke für eure Antworten

@Holger:
Ich vermute, Du hast ReadPixel() im Sinn? Dazu muss ich die Maskenbitmap aber erst in einen RastPort blitten, d.h. entweder einen allgemeinen für solche Tests zur Verfügung stellen, oder jeder Maskenbitmap einen eigenen mitgeben.
Da ich meine 6-eckigen Landschaftstiles prüfen will hab ich immer das Problem, dass in den Ecken jeweils zwei 6-Ecke unter dem Mauszeiger liegen, aber eines davon ist maskiert. Daher kann ich nicht direkt im RastPort des Fensters prüfen, sondern muss die Maskenbitmap in nen Rastport blitten, um dann dort mit ReadPixel() den Farbwert festzustellen.
Oder meintest Du etwas anderes?

@geit:
Für Überdeckungen hab ich schon einiges gebastelt, ich merke mir meine Grafiken in ihrer "Übereinanderlage" anhand der "Ebene", in der ich sie auf dem Bildschirm darstellen will (einiges dazu steht auch in meinem Thread zu Überdeckungen). Das läuft schon einigermaßen, aber zusammen mit dem Clipping, das ich benutze und der Wiederherstellung des Hintergrundes mit allen Objekten wenn eines seine Position verlässt bekomme ich noch Abstürze.

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 22:19 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Ich hoffe du fragst nicht, um das Hexagon zu bestimmen in das die Mauskoordinaten fallen, sondern um Objekte beliebiger Form testen zu können.
Also die Maske erstmal blitten um dann mit ReadPixel zu testen ist entweder furchtbar langsam (on-the-fly) oder hat Speicher overhead (gecached).
Warum testest du die Bitmaske nicht direkt?

(aus deinen Ausführungen errate ich mal, du hast Bitmasken, aber es wäre hilfreich wenn du verraten würdest wie du deine Bilder genau lädst und blittest, sonst kann keiner was genaueres sagen).

--
--
Author of
NTUI, AIDE, A/A++, HD-Rec, MacroWave, Sweeper, Samplemanager, ArTKanoid, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ImageConverter, ScreenCam, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 23:19 Uhr

Reth
Posts: 1753
Nutzer
@Der_Wanderer:
Richtig, einen arithmetischen Algo, das Hexagon zu bestimmen hab ich schon, ich möchte gern Objekte allgemein bestimmen können. Das mit langsam (on-the-fly) bzw. Speicheroverload (cachen) dachte ich mir auch schon, hatte aber für ReadPixel() noch keine andere Idee.

Meine Grafiken liegen alle in BitMaps, in die sie mit Hilfe eines RastPorts und WriteChunkyPixels() dort rein geschrieben werden. Das gilt auch für alle Masken. Jedes graphische Objekt enthält (neben anderen Attributen/Membern seine BitMap und seine MaskMap). Jedes dieser Objekte wird dann zum Blitten mit Maske in den RastPort des Fensters genutzt (mittels BltBitMapRastPort()). Dabei wird der Clipping verwendet, um den Bereich maximal einzugrenzen. Doublebuffering habe ich (noch) nicht.
Geladen werden sie nicht, die Daten liegen als UBYTE-Array in Headerfiles vor (später soll es ein Laden von Grafiken aus dem Dateisystem geben).

Leider habe ich noch keine andere Funktion (siehe Hinweis von Holger) außer ReadPixel() gefunden, mit der ich Farbwerte in einer BitMap bestimmen könnte.

[ - Antworten - Zitieren - Direktlink - ]

31.07.2013, 23:59 Uhr

thomas
Posts: 7649
Nutzer

Du machst es dir aber auch unnötig schwer.



code:
struct RastPort GlobalTempRP = {0};


int main (void)
{
InitRastPort (&GlobalTempRP);

...

}


ULONG BMReadPixel (struct BitMap *bm,long x,long y)
{
GlobalTempRP.BitMap = bm;
return (ReadPixel (&GlobalTempRP,x,y));
}



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

[ - Antworten - Zitieren - Direktlink - ]

01.08.2013, 00:07 Uhr

Reth
Posts: 1753
Nutzer
@thomas:
Danke, das meinte ich mit meinem Post oben, nur dachte ich, dass ich die BitMap nicht einfach so in den RastPort setzen kann, sondern blitten müsste.

[ - Antworten - Zitieren - Direktlink - ]

01.08.2013, 11:44 Uhr

thomas
Posts: 7649
Nutzer
@Reth:

Du musst deine Gedanken mal bis zum Ende durchdenken und nicht mittenderin anhalten. Wenn du die Bitmap irgendwo hin blitten müsstest, dann müsstest du das "irgendwo" ja auch aufbauen. Woraus bestünde denn das "irgendwo"? Doch sicher aus einem RastPort und einer BitMap. Und wie werden die beiden miteinander verbunden? Indem der Bitmap-Zeiger in den RastPort eingetragen wird. Und nach dem Blitten, wie sieht dann die "irgendwo"-Bitmap aus? Sie ist eine genaue Kopie der Quellbitmap. Was also ist der Unterschied ob du in eine temporäre Bitmap blittest und dann den Pixel ausliest oder die Quellbitmap direkt mit dem Rastport verbindest und den Pixel ausliest? Nur das überflüssige Blitten.


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

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Maus über Grafik mit AOS-API erkennbar? [ - Suche - Neue Beiträge - Registrieren - Login - ]


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