Laden...

[erledigt] Tao-Framework: Unvollstaendige Darstellung bei mehrfacher Formerzeugung

Erstellt von Christoph1968 vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.294 Views
C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren
[erledigt] Tao-Framework: Unvollstaendige Darstellung bei mehrfacher Formerzeugung

Hallo zusammen,

ich verwende die drawing3d.dll basierend auf dem Tao-Framework,
um vor einem schwarzen Hintergrund eine Anzahl von Messwerten durch eine Hand voll Linien,
Kontrollpunkte und ein paar Texte auszugeben
und stosse nun auf folgendes Problem:
Beim ersten Generieren des Dialogs erscheint alles wie im ScreenShot1 dargestellt.

Beim zweiten und nachfolgenden Generieren des Dialogs erscheinen nur die Linien und die Kontrollpunkte, nicht aber die Texte.
Auch nimmt die Performance bei Transformationen stark ab.
Nach Neustart der Anwendung ist die Darstellung wieder (beim ersten mal) perfekt.

Zur Anzeige wird ein neues Dialogfenster erzeugt, dessen Konstruktor folgendermassen aussieht:


public DiagramViewer3d()
        {
            InitializeComponent();

            _listDiagramDataEntities = new List<DiagramDataEntity>();

            _openGlDevice = new Drawing3d.Devices.OpenGlDevice();
            _openGlDevice.WinControl = this;
            _openGlDevice.Ambient = Color.White;
            _openGlDevice.Navigate = NavigateKind.ZoomRotateTrans;
            _openGlDevice.NearClipping = 0.1;
            _openGlDevice.OnPaint += new EventHandler(_openGlDevice_OnPaint);
            _openGlDevice.ClearScreen(Color.Black);
            
            _coordinateAxes = new Drawing3d.Editors.CoordinateAxes();
            _coordinateAxes.Size = new Drawing3d.Math.xyz(25.0, 25.0, 5.0);
            
            _coordinateAxes.Dim3d = true;
            _coordinateAxes.TextHeight = 1.0;
            _coordinateAxes.Parent = _openGlDevice.Work;

            this.Load += new EventHandler(DiagramViewer3D_Load);

            this.FormClosing += new FormClosingEventHandler(DiagramViewer3d_FormClosing);

        }//public DiagramViewer3D()

Im FormClosing EventHandler passiert das:


	void DiagramViewer3d_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                _openGlDevice.Close();
                _openGlDevice.Dispose();
            }
            
        }//void DiagramViewer3d_FormClosing(object sender, FormClosingEventArgs e)

Ich stehe da vor einem Raetsel und habe bereits folgendes probiert:

Den Dialog static deklarieren und nur einmal erzeugen anstelle eines neuen Dialogs den vorhandenen einfach ein- bzw. auszublenden -> keine Aenderung

Einsatz einer anderen Rechnerhardware mit anderer Grafikkarte -> keine Aenderung

Ohne FormClosing EventHandler -> keine Aenderung

Setzen von


_openGlDevice.WinControl = this; 

im Konstruktor oder im Load-EventHandler -> keine Aenderung

Hat jemand eine Idee, was ich da noch tun koennte ?

Vielen Dank fuer jeglichen Tip und liebe Gruesse

Christoph

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo Christoph1968,

das _openGlDevice wird nicht freigegeben da die Event-Handler noch darauf zeigen. Also deregestriere diese mit -= und dann sollte es passen.
Auch der _coordinateAxes hat noch eine Referenz auf das Device. Es müssen alle Referenzen entfernt werden (inkl. Ereignis-Handler), damit es vom GC weggeräumt werden kann.

BTW: die Form muss nicht ihre eigenen Events abonnieren - hierzu können auch die OnXXX-Methode verwendet werden. Also statt dem DiagramViewer3d_FormClosing kann override OnFormClosing verwendet werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Hallo gfoidl,

vielen Dank fuer Deine Antwort,
werde das gleich morgen frueh umsetzen und berichten.

Schoenen Abend und liebe Gruesse,

Christoph

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Hallo gfoidl,

ich habe jetzt folgende Aenderungen getestet:

Das Objekt _coordinateAxes habe ich entfernt.

Den Closing EventHandler habe ich durch die override OnClosing
ersetzt.

Die Funktion sieht derzeit so aus:


        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            //DeRegister OnPaint-EventHandler
            _openGlDevice.OnPaint -= _openGlDevice_OnPaint;
            //Close the OpenGlDevice
            _openGlDevice.Close();
            _openGlDevice.Work.Dispose();
            _openGlDevice.Dispose();
            
        }//protected override void OnClosing(CancelEventArgs e)

Das hat leider nichts gebracht. Das Verhalten ist unveraendert.

Ich habe parallel dazu getestet, was passiert, wenn ich dieses Form
nicht modal (also DiagramViewer3d.ShowDialog()) einblende
sondern nicht-modal ( DiagramViewer3d.Show() ) und dann mehrere
Instanzen parallel erzeuge.
Der Screenshot3 zeigt das Ergebnis: Im ersten Fenster (links oben) ist
alles wie gewuenscht, in den anderen Fenstern fehlt eben der Text. Ansonsten funktioniert alles. (Navigation, Zoom)

Hast Du noch eine Idee, was das sein koennte ?
Ist da unter Umstaenden an dieser Library (die mir wirklich suuuupergut gefaellt,
ich denke, interaktive 3D-Grafik war noch nie so einfach) etwas faul ?
Leider bleiben meine Kontaktversuche ueber http://www.drawing3d.de erfolglos.

Wenn Du Dir jetzt ansiehst, was ich da anzeigen moechte, also diese Messwerte, die Linien, vielleicht noch ein paar Quader, es waere auch schoen,
wenn man fuer jeden Messwert einen Marker haette
um ueber diesen nach einem Click-Event feststellen zu koennen, welcher Messwert das war.
Das ist ja nicht wirklich anspruchsvoll, welchen Ansatz wuerdest Du waehlen.

Vielen Dank fuer Deine Hilfe

Christoph

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Nochmal ein Bild, auf einem voellig anderen System und voellig anderem Programm (HelloWorld aus dem Tutorial leicht modifiziert)

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo Christoph1968,

welchen Ansatz wuerdest Du waehlen.

Für Visualisierungen - so ähnlich wie du sie hast - verwende ich VTK. Da gibts auch einen C#-Wrapper (bzw. mehrere). Das ist speziell für das wissenschaftliche Visualsieren erschaffen worden. Auch über die Forumssuche nach vtk findest du ein paar (Anfangs-) Info.

Das Problem mit OpenGL ist dass man alles selbst machen muss. Daher werden oft "Aufsätze" verwendet welche die typischen Aufgaben dann für dich erledigen und viele Komfortmethode anbieten. Das ist auch bei VTK so.

Eine andere Möglichkeit die ich eigentlich noch eher für Visualisierungen verwende ist dass mein Programm nur die Daten für die Visualsierung erzeugt und für Visualisierung verwende ich dann ParaView. Einfach deshalb weil das sehr mächtig ist und ich viel zu lange brauchen würde um ähnliches in mein Programm zu integrieren.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

1.130 Beiträge seit 2007
vor 12 Jahren

Nunja auch wenn ich zugegebnermaßen den thread nicht ganz gelsen habe kommt mir bei den bildern sofort ein verdacht:

Bei opengl hat man ja jeweils nen kontext. Dieser kontext wird jeweils für den aktuellen thread festgelegt und bezieht sich auf das fenster, für das er erzeugt wurde.

Wenn du also eine textur laden willst oder zeichnen willst, musst du immer dafür sorgen, dass du den richtigen context gesetzt hast (sowohl beim laden alsauch beim zeichnen)!
Und wenn du eine textur mit dem kontext von fenster 1 geladen hast, dann solltest du diese nicht im fenter 2 verwenden!

Den context zu wechseln ist nicht schwer:
Nativ heißt die api wglMakeCurrent und wird in wrappern gerne als device.MakeCurrent() eingebunden (musst dir raussuchen).

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Hallo Floste,

vielen Dank fuer Deine Antwort.
Ich habe Deinen Tip auch gleich getestet, aber das Verhalten ist unveraendert.
Das Problem ist, dass wenn das OpenGl-Fenster nach Start meiner Applikation zum wiederholten mal geoeffnet wird, wobei es keinen Unterschied zu machen scheint, ob es erzeugt oder nur ein- bzw. ausgeblendet wird, wird kein Text mehr dargestellt. Alles andere ist ja da und wird korrekt gerendert.

Mein Verdacht ist, dass die drawing3d.dll, die ich da einsetze,
nicht alle Resourcen freigibt, wenn die openGlDevice aufgegeben wird.

Aber moeglicherweise kann ich auf den RenderingContext zugreifen und das manuell machen, da muss ich mich aber erst reinarbeiten.
Die Bilder, die ich angehaengt habe, erfordern ca. 10 Zeilen Code incl. vollstaendiger Navigation, Skalierung und identifizierbaren Markern.
Das finde ich fantastisch !!! Deshalb will ich auch da noch nicht gleich aufgeben.

@gfoidl: Vielen Dank fuer Deinen Tip, ich seh mir das mal an, wenn ich da nicht weiterkomme.

Vielen Dank Euch beiden und liebe Grueße

Christoph

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Hallo gfoidl,
hallo Floste,

ich habe nun doch einen Weg gefunden, mit dem ich in diesem Falle und nur
ganz leicht zaehneknirschend leben kann:

Wenn ich verhindere, daß das Form, das den OpenGL-Kontext innehat,
geschlossen wird sondern nur ausgeblendet wird,


DiagramViewer3d.hide();

dann kann ich im VisibleChanged-EventHandler


if(this.Visible)
{
    _openGlDevice.MakeCurrent();
}

aufrufen, was dann tatsaechlich dazu fuehrt, dass die gerenderten Texte nicht verschwinden.

Jedenfalls vielen lieben Dank fuer Eure Hilfe, ich waere da sonst vielleicht sehr viel spaeter oder gar nicht draufgekommen.

Ein schoenes Wochenende und viele Gruesse

Christoph

1.130 Beiträge seit 2007
vor 12 Jahren

Und wenn du statdessen vor jedem rendern und vor jedwedem erzeugen oder anfassen der font (natürlich seperate fontobjekte je form verwenden) jeweils dauernd das entsprechende MakeCurrent aufrufst, dann hilft es nix?

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 12 Jahren

Hallo Floste,

nein, das bringt definitiv nichts. Ich kann mir die Ursache fuer dieses
Verhalten nur durch einen Fehler in der Bibliothek erklaeren.
Ich weiss nicht, was passiert denn, wenn z.B. diese Bibliothek nicht alle Resourcen
freigibt, bzw. wenn mehrere Kontexte erzeugt werden, wenn gerade die Funktion,
die den Text rendert nicht auf den neuen Kontext gesetzt wird.
Denn alles andere wird ja dargestellt, was auch immer es sein mag. Flaechen,
Koerper, Texturen, nur der Text fehlt.

Viele Gruesse

Christoph