Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Servus,
also ich habe folgendes Problem:
ich habe eine Anwendung, die hat mehrere Fenster. In jedem dieser Fenster soll jetzt ein OpenGL-Kontext drin sein, und die sollen voneinander unabhängig sein.
Jetzt habe ich aber das Problem, das da irgendwas durcheinander geworfen wird. Mache ich ein Fenster auf, klappt es wunderbar. Mache ich das zweite Fenster auf (unterschiedliche TForms) vergisst er alles was im ersten Fenster sein sollte und zeichnet nur noch das zweite Fenster.
Eine Suche mit dem Debugger hat ergeben, das der Wert der RenderingContext Variable der gleiche ist.
Die Einstellungen für die beiden Kontexte sind die gleichen (und sollen es auch wenn möglich bleiben), nur der Device-Context ist unterschiedlich.
Problem tritt sowohl mit MDIChild-Fenstern als auch mit "normalen" Fenstern auf.
Hat da irgendwer ne Idee bzw. noch besser ne Lösung?
Grüße
Wolf
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
in jedem Formular vorm rendern machen (so habs ich gemacht, aber ich habe zwei Panels mit je einem rendering- und DeviceContext)
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Hab mal das
Code:
ActivateRenderingContext
durch ein
Code:
wglMakeCurrent
getauscht.
Fehler bleibt der gleiche.
Ich habe pro Fenster mehrere Kontexte jeweils auf einem Panel liegen. Das funktioniert einwandfrei. Sobald ich aber ein neues Fenster öffne, wo Rendering-Kontexte drin liegen, vergisst der einfach das in dem alten Fenster auch noch Kontexte drin waren.
Solange alle Kontexte in einem Fenster liegen, kein Problem. Auch auf TabControls und was weiß ich noch alles. Klappt alles. Nur bei dem zweiten Fenster (das ja einen anderen DeviceContext hat) spielt er verrückt.
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Renderst Du im OnIdle?
Wenn ja, weist Du vielleicht in jedem Fenster bein kreieren Application.OnIdle einen Event zu?
Wenn ja, dann liegts daran.
Du mußt einen Globalen OnIdle Handler haben, in dem du dann alle Formulate abklapperst und dort das Rendern anschmeißt.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Ich seh schon, ohne Code kommen wir hier nicht weiter.
Also im Anhang mal die zwei benötigten Sachen. Ein Package OGLComponents, das die entsprechenden Panels etc. zur Verfügung stellt und FinalGUI.zip, wo der Rest drinliegt.
Problematisch ist jetzt das folgende:
Ich öffne die GUI, klicke auf den Button Volume, schiebe das Fenster zur Seite. Klicke auf den Button Artefact Remove und schiebe das Fenster über das Volume Fenster. Wenn ich das Artefact Fenster jetzt wegbewege, dann wird Volume nicht neu gezeichnet.
Sehr schön auch der Effekt wenn ich das Artefact Fenster zuerst erzeuge, dann das Volume Fenster, dann das Artefact Fenster schließe. Aus irgendeinem Grund zeichnet der mir dann in das Volume-Fenster den Teil aus dem Artefakt Fenster...
Problem tritt sowohl mit Nvidia als auch mit ATI Karten auf.
Grüße
Wolf
P.S.: Evtl. muß der Pfad zur dglOpenGL (nutze Version 1.9) umgesetzt werden.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Bin grad auf Arbeit .. da isses schlecht mit downlaods und so .. aber ich schaus mir heute abend mal an, wenn dus nicht zu eilig hast.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Unit UGlobalTypes.pas fehlt leider, drum kann ichs nicht debuggen .. vom Code her find ich erstmal nix, außer dass mir schleierhaft ist, wo Du das Rendern anschmeißt .. ist zwar ein Handler da für Application.OnIdle, wird aber nie zugewiesen...
Stell mal bitte die Unit noch bereit, damit ich das Ganze mal in Aktion sehen kann.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Sorry. Die UGlobalTypes.pas liegt (noch) in nem anderen Verzeichnis mit den bereits fertigen Sachen. Anbei als Anhang.
Auf dem Formular FrmMain sollte eigentlich eine Komponente vom Typ TApplicationEvents liegen, die unter anderem die Eigenschaft OnIdle kapselt. Findet sich bei mir im Reiter 'Zusätzlich' der VCL-Komponentenleiste.
Da mir aber schonmal untergekommen ist das dies nicht bei jeder Delphi Version dabei ist (hab es selbst unter Delphi 7PE und Delphi 7 Pro) kann es passieren das Du Dir selbst nen Handler schreiben mußt.
Gruß
Wolf
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Ist bei mir schon dabei, aber ich finde, diese nicht-visuellen Komponenten stören ungemein den Entwurf von Formularen (hässlich, die kleinen Dinger und immer sind sie im Weg), darum hab ich an sowas nicht gedacht.
Ich schreib in einem solchen Fall immer irgendwo im Konstruktor 'Application.OnIdle:=...', oder wenn ich einen Timer brauch, dann deklarier ich dem im Code.
p.s. hab mir gestern einen Wolf gesucht
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Ok, also ich habe den Fehler mal weiter eingeschränkt.
Die TOGLPanel.Activate wurde so verändert, das sie jetzt wie folgt aussieht:
Code:
procedure TOGLPanel.Activate();
begin
if myDC = 0 then
exit;
wglMakeCurrent(myDC,myRC);
if wglGetCurrentDC() <> myDC then
raise Exception.Create('Wrong Device Context');
end;
desweiteren wurde ein Formular so verändert, das eine Aktivierung des Formulars alle entsprechenden TOGLPanels aktiviert. Und siehe da, die Exception wurde ausgelöst. Das heißt das Problem liegt darin, das der Device-Kontext DC nicht vernünftig umgeschaltet wird.
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Was aber an sich putzig ist, weil man ja schon dann verschiedene DCs hat, wenn zwei Panels auf einem Formular liegen. Bei zwei Formularen mit je einem GLPanel klappts meines Wissens nämlich auch.
Vielleicht kann sich auch mal einer von den GURUS das anschauen, weil ich erstmal mit meinem Latein am Ende bin (ich schaus mir heute Abend trotzdem nochmal an)
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Ok, here we are:
folgender Umbau brachte den folgenden Fehler zu Tage:
Code:
if not wglMakeCurrent(myDC,myRC) then
RaiseLastOSError;
Zitat:
--------------------------- Benachrichtigung über Debugger-Exception --------------------------- Im Projekt Final.exe ist eine Exception der Klasse EOSError aufgetreten. Meldung: 'Systemfehler. Code: 2000. Das Pixelformat ist ungültig'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen. --------------------------- OK Hilfe ---------------------------
Fragt sich nur, warum das Pixelformat auf einmal ungültig ist.
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Sidorion hat geschrieben:
Vielleicht kann sich auch mal einer von den GURUS das anschauen, weil ich erstmal mit meinem Latein am Ende bin (ich schaus mir heute Abend trotzdem nochmal an)
Weiß ja nicht ob ich mich als "Guru" bezeichnen darf oder soll aber ich habe mir das mal angesehen. Bevor du es erwähnt hattest.
Der Fehler ist ziemlich einfach wenn auch nicht so ganz nahe liegend. Nach leichtem Debugging habe ich gesehen, dass OpenGL (CreateRenderContext) die RCs mehrfach vergibt. Was im Normalfall ziemlich ungewöhnlich ist. Dann hatte ich mal (weil ich mir so etwas ähnlches gedacht hatte) einen Breakpoint in InitOpenGL gemacht. Und siehe da. InitOpenGL wird sehr häufig aufgerufen. InitOpenGL geht aber her und entlädt die Opengl32.dll wenn sie bereits geladen wurde. Das führt natürlich dazu, dass deine bereits erstellten RCs futsch sind. Und da es im Create aufgerufen wird passiert das nicht mittendrin sondern nur am Anfang beim Erstellen. Sonst hättest du nur einen funktionierenden RC. Das Verhalten der dglOpenGL ist richtig. An der Stelle kann man sich darüber natürlich streiten aber zum Laden einer alternativen OpenGL Dll ist das leider notwendig.
CreateRenderContext ruft intern InitOpenGL bei bedarf auf. Also entferne nur überall InitOpenGL dann gehts.
Ein paar Sachen die mir so noch aufgefallen sind.
Ein Formular ist noch im automatischen Erstellprozess beim Starten enthalten. Wenn du das nicht benutzt empfehle ich die Globalen Variablen zu entfernen. Dann kann das nicht ausversehen passieren.
Und das mit dem in OnIdle Rendern würde ich mir bei dem Projekt noch mal stark überlegen. Das sorgt nur dafür, dass die CPU zu 100% belastet wird obwohl du nichts anderes als ein leeres Fenster zu Anfang an zeigst. In deinem Falle wäre es besser, wenn du dir das OnPaint ode WM_PAINT des Panels schnappst und dieses dann automatisch in OnRender weiter leitest. Dann wird es genau dann neu gezeichnet wenn notwendig. Wenn sich etwas an den Werten verändert müsstest du Panel.Repaint aufrufen. Ist zwar ein wenig komplizierter aber viele werden es dir danken. Sofern du natürlich Animationen oder so etwas haben könntest müsstest du wieder mit OnIdle oder ähnlichem arbeiten. Aber für die meisten Fälle bei solchen Visualisierungstools reicht es ohne aus.
Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.