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

amiga-news.de Forum > Programmierung > Bounding Box eines Layers [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

14.03.2012, 16:02 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Gibt es einen legalen Weg, um an die Bounding Box eines Layer zu kommen, vielmehr der ClipRegion die installiert ist?
Mit Bounding Box ist das kleinste Rechteck gemeint, das alle bemalbaren Bereiche einer ClipRegion enthält.

Warum brauche ich das?

Normalerweise soll man bei einem Refresh einfach den Damage Bereich setzen (BeginRefresh) und alles malen.
Das ist bei einfachen Oberflächen auch i.O. so, da die Hauptlast auf dem malen und nicht auf der Logik dahinter liegt. Wenn wir jetzt aber etwas sehr komplexes haben, dann ist das nicht mehr egal. Dann möchte ich nicht Megabyte Daten durchackern müssen um eine kleines Rechteck neu zu malen. d.h. wenn die Zeichenfunktion den Bereich aktiv kennt, ist sie sehr viel schneller.

Bisher mache ich das so:
code:
;///////////////////////////////////////////////////////////////////////////////
;/                                                                             /
;/ Syntax: !image_GetClipBounds{*rp.RastPort,minx.l,miny.l,maxx.l,maxy.l}      /
;/                                                                             /
;/ Description:                                                                /
;/ Get the outer clip bounds of a RastPort with a layer attached, relative t:: /
;/ o the underlying bitmap.                                                    /
;/                                                                             /
;/ Inputs:                                                                     /
;/ - *rp.RastPort    : RastPort to get the clip bounds from                    /
;/ - minx.l    : x of top left edge                                            /
;/ - miny.l    : y of top left edge                                            /
;/ - maxx.l    : x of bottom right edge                                        /
;/ - maxy.l    : y of bottom right edge                                        /
;/                                                                             /
;///////////////////////////////////////////////////////////////////////////////
Macro image_GetClipBounds ;{*rp.RastPort,minx.l,miny.l,maxx.l,maxy.l}
    If *rp\Layer
      If *rp\Layer\ClipRegion ; get the bbox from clipregion
        *cliprec.Rectangle = *rp\Layer\ClipRegion\bounds
        minx = *cliprec\MinX
        miny = *cliprec\MinY
        maxx = *cliprec\MaxX
        maxy = *cliprec\MaxY
      Else ; no clipregion, get the bbox from layer bounds
        *cliprec = *rp\Layer\bounds
        minx = 0
        miny = 0
        maxx = *cliprec\MaxX - *cliprec\MinX
        maxy = *cliprec\MaxY - *cliprec\MinY
      End If
    Else ; no layer? 
      minx = 0
      miny = 0
      If *rp\BitMap ; ask the bitmap
        maxx = GetBitMapAttr_(*rp\BitMap,#BMA_WIDTH)
        maxy = GetBitMapAttr_(*rp\BitMap,#BMA_HEIGHT)
      Else
        maxx = 0
        maxy = 0
      End If
    End If
End Macro


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 14.03.2012 um 16:05 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

14.03.2012, 18:26 Uhr

Holger
Posts: 8116
Nutzer
@Der_Wanderer:
Das, was Du da machst, ist der einzige mir bekannte Weg. Und wenn Du Dich zwischen BeginRefresh und EndRefresh befindest, sind die Layer auch gelockt, ich sehe also keinerlei Legalitätsprobleme.

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

[ - Antworten - Zitieren - Direktlink - ]

15.03.2012, 09:44 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Meine Befürchtung ist nur, dass evtl. unter neueren AmigaOS Varianten die Strukturen nicht aufgebaut werden, wenn z.B. die ClipRegion eine Maske ist und keine Ansammlung von Rechtecken.
Wenn ich mir das oben gepostete anschaue, dann ist das aber auch recht harmlos, stimmt. In TUI hatte ich das etwas komplizierter, wo ich tatsächlich durch alle Rectangles durchgehe und die minimale Box selbst berechne. Aber hier lese ich eigentlich nur die "bounds" Werte aus, und die sollten eigentlich immer gesetzt werden können.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

15.03.2012, 15:43 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Der_Wanderer:
Meine Befürchtung ist nur, dass evtl. unter neueren AmigaOS Varianten die Strukturen nicht aufgebaut werden, wenn z.B. die ClipRegion eine Maske ist und keine Ansammlung von Rechtecken.

Dann sollte es aber auch keine ClipRegion-Struktur geben, die zu der Annahme verführt, man könne die Bounds auslesen. Also, entweder null oder gültige Bounds.

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

[ - Antworten - Zitieren - Direktlink - ]

15.03.2012, 21:08 Uhr

Reth
Posts: 1858
Nutzer
Hi,

hab leider nicht genau verstanden, was Du mit dem Folgenden genau meinst:
Zitat:
Original von Der_Wanderer:
Normalerweise soll man bei einem Refresh einfach den Damage Bereich setzen (BeginRefresh) und alles malen.
Das ist bei einfachen Oberflächen auch i.O. so, da die Hauptlast auf dem malen und nicht auf der Logik dahinter liegt. Wenn wir jetzt aber etwas sehr komplexes haben, dann ist das nicht mehr egal. Dann möchte ich nicht Megabyte Daten durchackern müssen um eine kleines Rechteck neu zu malen. d.h. wenn die Zeichenfunktion den Bereich aktiv kennt, ist sie sehr viel schneller.


Ich hab ein ähnliches Problem: Ich wollte mittels Clipping dafür sorgen, dass nur die notwendigen Bereiche neu geblittet werden. Dafür hab ich aus der bestehenden DamageRegion mittels der Rectangle- und Regionfunktionen alle meine beschädigten Bereiche hinzugefügt. Nach einem EraseRect wurden dann alle Objekte neu geblittet. Trifft das in Deinem Fall auch zu? Oder meinst Du mit Deiner Beschreibung was Anderes?
Leider ist das für mich etwas komplex und sehr fehleranfällig in meinem Fall. Denn das ging irgendwie schief, glaub beim Beenden des Programmes und bei oder nach dem Freigeben meiner Regions fror das ganze System (AOS4) ein. Hatte also noch nen dicken Fehler drin.

Nachdem ich Flare kennengelernt und einiges mit dessem Autor ausgetauscht hatte hab ich mich vorerst mal gegen Clipping entschieden.
Grund: Flare läuft auf meinem Peg4 für mich ausreichend schnell genug und dort wird alles (wohl auch die GUI) mit SDL immer neu geblittet! Und die Geschwindigkeit ist für mich OK.

[ - Antworten - Zitieren - Direktlink - ]

15.03.2012, 21:19 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Um das Clipping musst du dich ja nicht aktiv kümmern.
Innerhalb von BeginRefresh und EndRefresh wird die Clipregion so gesetzt, dass nur die getrashten Bereiche neu gemalt werden.
Das ist auch ok so, solange eben die Hauptlast auf den Zeichenfunktionen liegt.
Wenn deine GUI aber etwas recht Komplexes darstellt und man viel Rechnen muss und viele einzlene Grafikoperationen hat, dann ist es doch sehr aufwendig. z.B. bei dem Arranger Fesnter in HD-Rec. Wenn da nur ein Ecke des Fensters refreshed wird muss ich nicht deshalb alle Waveformen neu malen, da die Zeichenoperationen sowieso ins Nirvana gehen.
Als Optimierung lese ich mir dann die Clip Bounds aus, und male nur Elemente neu, die mit der Bounding Box überlappen. Alle ausserhalb kann ich überspringen.

z.B. hier:

Wenn ich hier eines der Vordergrund Fenster bewege, muss ich oft nur ein oder zwei der "Elemente" neu zeichnen, aber nicht alle 100 mit all ihren kleinen Details.
Bild: http://hd-rec.de/HD-Rec/pics/screenshots/hdrec_sweeper.png


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 15.03.2012 um 21:20 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 00:37 Uhr

Reth
Posts: 1858
Nutzer
@Der_Wanderer:

Ich glaub wir reden vom Selben. In meinem Fall (s. hier) ist das ja die gleiche Situation. Nur das hier die "Beschädigung" nicht durch drüberliegende Fenster kommt, sondern durch übereinanderliegende grafische Objekte des Spieles selbst. Da ich diese selbst manipuliere und dann blitte klappt das auch nicht so mit den von Intuition geschickten Refresh-Meldungen.

Um das Clipping muss man sich natürlich nicht aktiv kümmern, aber der für das Clipping notwendige Bereich wird in Deinem Bsp. und in dem von mir genannten Thread aktiv zusammengestellt, um Neuzeichnen in nicht veränderten Regionen zu unterbinden.
Bei mir führte das aber zu Problemen (hab meinen Fehler noch nicht finden können). Daher hab ich diesen Modus erst einmal deaktiviert, wie gesagt aufgrund dessen, dass bei Flare die Methode "immer alles neu blitten" sogar mit SDL ziemlich gut funktioniert (zumindest auf Peg2).

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 11:13 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Nur das hier die "Beschädigung" nicht durch drüberliegende Fenster kommt, sondern durch übereinanderliegende grafische Objekte des Spieles selbst. Da ich diese selbst manipuliere und dann blitte klappt das auch nicht so mit den von Intuition geschickten Refresh-Meldungen.

Und das ist natürlich ein gewaltiger Unterschied.

Deshalb spricht man in Deinem Fall i.A. nicht von „beschädigtem“, sondern von „veraltetem“ Inhalt.

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

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 13:43 Uhr

Der_Wanderer
Posts: 1229
Nutzer
@Reth
In deinem Fall kannst du natürlich über die selbe Funktion malen, RedrawMyPlayfield(RastPort,x1,y1,x2,y2), rufst die aber auf Eigeninitiative auf. Mit den InutiMessages hat das nichts zu tun, da ja nicht Intuition den Bereich "damaged", sondern du in deinem Programmablauf selbst entscheidest dass dieser Bereich neu gezeichnet werden muss. Wenn neu-malen schnell genug ist, hast du ja sowieso überhaupt kein Problem. Theoretisch kannst du dann auch NOCAREREFRESH nutzen, dein Fenster ist ja dann maximal für einen Frame "damaged".

@Holger
Danke. Ich wollte mir nur deinen Segen dazu abholen.
Wobei im Falle eines BeginRefresh/EndRefreh kann ich mir die Bounding Box auch so besorgen, oder?

code:
BeginRefresh_ *oswin
clip.tuiRect\left   = *oswin\WLayer\DamageList\bounds\MinX
clip.tuiRect\top    = *oswin\WLayer\DamageList\bounds\MinY
clip.tuiRect\right  = *oswin\WLayer\DamageList\bounds\MaxX
clip.tuiRect\bottom = *oswin\WLayer\DamageList\bounds\MaxY
EndRefresh_ *oswin,1
_ntui_Redraw{*obj,clip}


Und da taucht eine weitere Frage auf:

Wenn ich innerhalb des Refreshs neu zeichne, freezed das System. Deshalb steht _ntui_Redraw{} nach dem EndRefresh.

Ich denke mal das liegt daran, dass ich in _ntui_Redraw{} selbst die ClipRegion manipuliere. Ich stelle zwar fein säuberlich sicher, dass beim Verlassen von _ntui_Redraw{} die alte ClipRegion wiederhergestellt ist, aber vermutlich darf ich erst gar keine neue setzen weil die Layer (oder LayerInfo) gelockt sind?

Da stellt sich mir die Frage: Wann darf ich InstallClipRegion() NICHT aufrufen? Wenn der Layer oder die LayerInfo gelockt ist?

Desweiteren habe ich eine Funktion in NTUI die es dem User erlaubt den RastPort eines bestimmten GUI Objectes zu holen. Dazu gibt es

code:
ntui_ObtainRastPort{*obj}
...
ntui_ReleaseRastPort{*obj}

Der Grund warum ich Obtain und Release mache ist, dass der User garantiert bekommt, dass ihm der RastPort in der Zwischenzeit nicht weggenommen wird und ihm auch niemand anderes (z.B. NTUI) reinmalt.
NTUI selbst nutzt auch diese beiden Funktionen wenn es neu zeichnen will.

Ist es sinnvoll auch ein LockLayer zu machen um zu verhindern dass innherhalb dieser Zeit intuition das Fenster nicht resized oder den Layer ändert?
Welchen Layer müsste ich dazu Locken? in einem Beispiel habe ich gesehen, der Screen LayerInfo wird gelockt.


--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 16.03.2012 um 13:47 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 16:32 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Der_Wanderer:
Theoretisch kannst du dann auch NOCAREREFRESH nutzen, dein Fenster ist ja dann maximal für einen Frame "damaged".

Sofern man ständig neu malt, ja. Wenn man nicht den gesamten Bereich neu zeichnet, kann man auch NOCAREREFRESH benutzen, solange man sicherstellt, dass immer Updates stattfinden und dass sowohl die veralteten als auch die beschädigten Bereiche neu gezeichnet werden.

Zitat:
Wobei im Falle eines BeginRefresh/EndRefreh kann ich mir die Bounding Box auch so besorgen, oder?
Äh, ja. Wobei Du das „auch“ streichen kannst. Die Bounding Box der Damage-Region ist nicht die Bounding Box der Clip-Region (siehe unten).

Zitat:

Ich denke mal das liegt daran, dass ich in _ntui_Redraw{} selbst die ClipRegion manipuliere.

Nein, daran kann es nicht liegen. Und zwar aus folgendem Grund:

http://amiga-news.de/forum/thread.php?id=33602&start=91&BoardID=7#350915

Offenbar ist Reths Thread doch ganz interessant.

Zitat:
Ich stelle zwar fein säuberlich sicher, dass beim Verlassen von _ntui_Redraw{} die alte ClipRegion wiederhergestellt ist, aber vermutlich darf ich erst gar keine neue setzen weil die Layer (oder LayerInfo) gelockt sind?
Das ist nicht das Problem. Die Frage ist vielmehr: wo kommt die alte Clip-Region überhaupt her?

Zitat:
Der Grund warum ich Obtain und Release mache ist, dass der User garantiert bekommt, dass ihm der RastPort in der Zwischenzeit nicht weggenommen wird und ihm auch niemand anderes (z.B. NTUI) reinmalt.
Benutzt Du mehrere Tasks? Ein Minenfeld…

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

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 17:26 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von Der_Wanderer:
Theoretisch kannst du dann auch NOCAREREFRESH nutzen, dein Fenster ist ja dann maximal für einen Frame "damaged".

Sofern man ständig neu malt, ja. Wenn man nicht den gesamten Bereich
Das schrieb ja Reth.

Zitat:
Zitat:
Wobei im Falle eines BeginRefresh/EndRefreh kann ich mir die Bounding Box auch so besorgen, oder?
Äh, ja. Wobei Du das „auch“ streichen kannst. Die Bounding Box der Damage-Region ist nicht die Bounding Box der Clip-Region (siehe unten).
Wenn ich alles richtig verstehe, ist die Bounding Box der Damage Region eine Über-Fläche der Bounding Box innerhalb von Begin/EndRefresh. Insofern kann ich nichts verpassen, höchstens etwas zu viel zeichnen.

Zitat:
Zitat:
Ich stelle zwar fein säuberlich sicher, dass beim Verlassen von _ntui_Redraw{} die alte ClipRegion wiederhergestellt ist, aber vermutlich darf ich erst gar keine neue setzen weil die Layer (oder LayerInfo) gelockt sind?
Das ist nicht das Problem. Die Frage ist vielmehr: wo kommt die alte Clip-Region überhaupt her?
Also InstallClipRegion gibt die alte Region zurück. Die kann man dann später wieder herstellen, und danach die eigene freigeben.

Zitat:
Benutzt Du mehrere Tasks? Ein Minenfeld…
Jain. Zumindest will ich es mir nicht verbauen.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 18:01 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Der_Wanderer:
Wenn ich alles richtig verstehe, ist die Bounding Box der Damage Region eine Über-Fläche der Bounding Box innerhalb von Begin/EndRefresh. Insofern kann ich nichts verpassen, höchstens etwas zu viel zeichnen.

Nein, worum es mir in meinem Kommentar ging (lies den verlinkten Thread), ist, dass Tests ergeben haben, dass zumindest unter AOS3 die Damage-Region nicht in die ClipRegion geschrieben wird.

Das heißt, solange Du Dich zwischen BeginRefresh und EndRefresh befindest, werden zwar effektiv Damage-Region und ClipRegion AND-verknüpft, um den beschreibbaren Bereich zu definieren, aber das Ergebnis der Verknüpfung steht nicht in der ClipRegion. Dort steht ausschließlich der User-defined Clip, also Deiner (default null).

Wenn Du also die Bounds der Damage-Region wissen willst, musst Du auch die Damage-Region auslesen. Im Clip stehen die nicht. Wenn Du einen nicht-null Clip hast, musst Du dessen BoundingBox ebenfalls überprüfen und beide manuell verknüpfen.

Zitat:
Also InstallClipRegion gibt die alte Region zurück. Die kann man dann später wieder herstellen, und danach die eigene freigeben.
Ja, aber sie ist per default null, wenn Du nicht selber eine gesetzt hast. Das müsste Dir an der Stelle aufgefallen sein, wo Du sie manipulieren willst. Oder genau das ist das Problem: Du überprüfst nicht auf null, bevor Du sie mit einer weiteren Region verknüpfst. Dann knallts.

Zitat:
Zitat:
Benutzt Du mehrere Tasks? Ein Minenfeld…
Jain. Zumindest will ich es mir nicht verbauen.
Es hat seinen Grund, warum die meisten Toolkits darum einen Bogen machen. Ein korrektes Protokoll wer wann wohin zeichnen darf, ist schwer zu implementieren und man gewinnt nichts. Die Grafik-Hardware/Pipeline bearbeitet die Zeichenbefehle trotzdem sequentiell.

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

[ - Antworten - Zitieren - Direktlink - ]

16.03.2012, 21:32 Uhr

Der_Wanderer
Posts: 1229
Nutzer
@Holger:
Ok, ich habe den Link gelesen und verifiziert. Bei mir unser OS3+AfA ist auch die ClipRegion tatsächlich Null.

Wenn ich das recht verstehe, Clipped aber AmigaOS trotzdem alle Zeichenaufrufe innerhalb Begin/End Refresh. Ich meine, was wäre sonst der sinn der ganzen, bzw. der einzige Sinn wäre die Garbadge Collection der DamageList.

Was ich jetzt auch nicht verstehe ist, warum es sich aufhängt wenn ich innerhalb Begin/EndRefresh neuzeichne. Scheinbar mache ich da irgendwas, was AmigaOS nicht passt. Ich dachte es wäre die Manipulation der ClipRegion.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 09:58 Uhr

Georg
Posts: 107
Nutzer
Zitat:
Original von Der_Wanderer:

Was ich jetzt auch nicht verstehe ist, warum es sich aufhängt wenn ich innerhalb Begin/EndRefresh neuzeichne. Scheinbar mache ich da irgendwas, was AmigaOS nicht passt. Ich dachte es wäre die Manipulation der ClipRegion.


Die AOS layers.library verträgt es nicht, wenn man InstallClipRegion() innerhalb Begin/EndRefresh aufruft. Deshalb muß man in so einem Fall kurz wieder aus dem Refresh State rausgehen, die Clip Region installieren, und dann wieder in den Refresh State rein:

Folgender Code ist z. B. aus der reqtools.library:
C code:
static struct Region *MyInstallRegion (struct Window *win, struct Region *reg, int refresh)
{
    struct Region *oldregion;

    LockLayerInfo(&win->WScreen->LayerInfo);
    
    if (refresh) GT_EndRefresh (win, FALSE);
    
    oldregion = InstallClipRegion (win->WLayer, reg);
    if (refresh) GT_BeginRefresh (win);

    UnlockLayerInfo(&win->WScreen->LayerInfo);
    
    return (oldregion);
}



[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 10:30 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Ja, so ähnlich ist das Beispiel im RKM auch aufgebaut. Das ist nur etwas blöd, weil ich NTUI ziemlich oft ClipRegions brauche, und der Zeichenvorgang müsste dann immer wissen, ob er sich innerhalb Begin/EndRefresh befindet oder nicht.

Allerdings könnte ich das wie im Code oben lösen, denn die einzelnen Widgets machen natürlich nicht selbst die ClipRegion sondern rufen eine NTUI Funktion dafür auf.
Wobei man den Parameter "refresh" sich sparen könnte, denn das Window hat das "WFLG_REFRESHWINDOW" gesetzt.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 11:59 Uhr

Georg
Posts: 107
Nutzer
@Der_Wanderer:

MUI setzt ein Flag MUIMRI_REFRESHMODE innerhalb BeginRefresh/EndRefresh.

Theoretisch wäre es wegen dem installclipregion-geht-nicht-wenn-in-refresh-state Problem übrigens ne Optimierung, wenn man das so macht, daß man gar nicht rendert innerhalb BeginRefresh/EndRefresh, sondern sich nur ne Kopie von der DamageListe macht, und dann immer beim ClipRegion setzen diese dazu ANDet:
C code:
myinstallclipregion(region)
{
 struct Region *clipregion = region;

 if (region)
 {
   if (damageregion) AndRegionRegion(damageregion,region);
 }
 else
 {
   if (damageregion) clipregion = damageregion;
 }

 InstallClipRegion(clipregion);
}


[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 17:13 Uhr

Der_Wanderer
Posts: 1229
Nutzer
@Georg
Ja so ähnlich macht das NTUI.
Jedes Widget, das zum Zeichnen eine ClipRegion installieren möchte, setzt diese nicht direkt sondern AND-verknüpft sie auf die aktuelle, und nachdem alles gezeichnet ist stellt die die wieder her. Das ist notwendig, weil ein Widget ja nicht unbedingt komplett sichbar ist, z.B. innerhalb eines ScrollViews.
Im Refresh Fall mache ich eine Kopie der Damage Region innerhalb des Begin/EndRefreshs. Dann rufe ich EndRefresh auf, installiere die Kopie und das normale Zeichnen kann beginnen.

Ich habe das jetzt nochmal versucht mit
code:
...
if (win->Flags&WFLG_WINDOWREFRESH) {
  EndRefresh(win, FALSE);
}

oldRegion = InstallClipRegion(newRegion);

if (win->Flags&WFLG_WINDOWREFRESH) {
  BeginRefresh(win);
}
...
// Draw widget //
...
// restore oldRegion and dispose newRegion


, wenn WFLG_WINDOWREFRESH gesetzt ist. Das scheint aber nicht das Problem gewesen zu sein, weshalb mein Code freezed wenn ich innerhalb Begin/EndRefresh neuzeichne.
Ich habe übrigends festgestellt, dass der erste Refresh durchläuft, und es freezed in zweiten Aufruf von BeginRefresh, also wenn die zweite IDCMP_WINDOWREFRESH message kommt.

Mein Refresh funktioniert fast Ok auch ausserhalb Begin/EndRefresh, ich könnte also zufrieden sein. Allerdings nur fast, bei wildem Resizen des Fensters übermale ich beim Verkleinern des Fensters den Fensterrahmen mit einer veralteten, zu grossen Position und Intuition malt danach den Fensterrahmen nicht mehr neu.
Ich musste das so fixen, dass ich den Rahmen manuell neuzeichne, was für meinen Geschmack aber 1x Neuzeichnen zu viel ist.
Ich erhoffe mir davon, innerhalb des Begin/EndRefreshs zu malen, dass ich mir das dann sparen kann und optimales Refresh erreicht habe.




--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 17.03.2012 um 17:18 Uhr geändert. ]

[ Dieser Beitrag wurde von Der_Wanderer am 17.03.2012 um 17:20 Uhr geändert. ]

[ Dieser Beitrag wurde von Der_Wanderer am 17.03.2012 um 17:20 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 19:30 Uhr

Georg
Posts: 107
Nutzer
[quote]
Original von Der_Wanderer:

code:
...
if (win->Flags&WFLG_WINDOWREFRESH) {
  EndRefresh(win, FALSE);
}

oldRegion = InstallClipRegion(newRegion);

if (win->Flags&WFLG_WINDOWREFRESH) {
  BeginRefresh(win);
}
...
// Draw widget //
...
// restore oldRegion and dispose newRegion


Hier hast du ein Problem mit dem 2. "if" Check, weil WFLG_WINDOWREFRESH wegen dem "EndRefresh(win, FALSE)" nach dem 1. Check nicht mehr gesetzt sein wird. Du mußt das cachen, also z. B. "BOOL in_refresh = (win->Flags&WFLG_WINDOWREFRESH) ? TRUE : FALSE" und dann bei den "if"s in_refresh abfragen.



[ - Antworten - Zitieren - Direktlink - ]

17.03.2012, 22:58 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Das war nur ein versehen in dem Pseudo Code fürs Posting. Das merke ich mir natürlich in einer extra Variablen.

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

18.03.2012, 10:46 Uhr

Georg
Posts: 107
Nutzer
@Der_Wanderer:

Gibts da irgendwelche Refreshes oder Ähnliches von Intuition Gadgets (evtl. indirekt über RefreshWindowFrame()). Das darf man innerhalb BeginRefresh/EndRefresh auch nicht machen.


[ - Antworten - Zitieren - Direktlink - ]

18.03.2012, 16:35 Uhr

Der_Wanderer
Posts: 1229
Nutzer
* kopfklatsch *

Das RefreshWindowFrame() war noch drin.
Wenn ich das rausnehme, funktioniert mein Refresh auch innterhalb des Begin/EndRefreshes. Danke für den Hinweis.
Allerdings kam di eErnüchterung ziemlich schnell: Auch hier bin ich beim Resizen nicht davor geschützt, den Rand zu übermalen. Desweiteren bekomme ich Aussetzer beim Refresh, vermutlich muss ich noch den ScreenLayerInfo locken.

EDIT: soo, mit ScreenLayerInfo Lock funktioniert es nun wie es soll. Puh! Keine triviale Sache, das mit dem Refresh...

--
--
Author of
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de



[ Dieser Beitrag wurde von Der_Wanderer am 18.03.2012 um 16:39 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Bounding Box eines Layers [ - Suche - Neue Beiträge - Registrieren - Login - ]


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