Probleme mit 2 OpenGL-Fenstern
-
JPSelter schrieb:
So, bin nun wieder an diesem Problem. Irgendwann muss es ja gelöst werden
Ich rätsel immernoch, wieso es 2 Pixeldeskriptoren sein müssen, weil in meinem bestehenden keine spezifischen Fensterinformationen drinstehen. Würde ich das machen, sähen beide Deskriptoren identisch aus.OpenGL will nunmal ne Verbindung vom Rendercontext zunm Devicecontext und das für jede Verbindung, sprich also für jedes Fenster. Sozusagen "Liebes liebes OpenGL, rendere bitte in diesen DC mit diesen gesetzten Eigenschaften"
Und das geht nunmal über den Pixeldeskriptor. Das du dann zweimal den selben setzt, ist doch egal dabei.JPSelter schrieb:
Mal eine andere Überlegung: Macht es Sinn, das OpenGL Control beim Verlassen des TabX zu zerstören und beim Entern von TabY neu zu createn? Darf man das mehrmals machen? Da käme ja dann dasselbe bei raus oder?
Musst du halt mal testen. ich würd aber sagen ja musst du machen. Ein neuer Tab hat nen neuen Handle und für das neue Handle brauchst du nen neuen DeviceContext. Diesen musst dann wieder mit dem Rendercontext verbinden usw.
Wie gesagt einfach mal testen^^
-
OK, soweit so gut. Meine Software zeichnet nun beide, aber nur den, der zuerst erzeugt wird und danach NUR den, also das Tab, das zuerst angeklickt wird. Alles was jetzt noch fehlt, ist eine Destroy-Methode. Jetzt sehe ich wieder, wie wenig Ahnung ich von C++ habe
Wie zerstöre ich denn das OpenGL-Objekt wieder?if (m_tabctrlMain.GetCurSel()==1) { ((tabDialog2*)m_tabctrlMain.GetTab(1))->DestroyOpenGL(); // plus eine Abfrage ob es überhaupt schon ein Objekt gibt ((tabDialog2*)m_tabctrlMain.GetTab(1))->CreateOpenGL(); ((tabDialog2*)m_tabctrlMain.GetTab(1))->ActivateRenderTimer(); } if (m_tabctrlMain.GetCurSel()==2) { ((tabDialog2*)m_tabctrlMain.GetTab(2))->DestroyOpenGL(); // plus eine Abfrage ob es überhaupt schon ein Objekt gibt ((tabDialog3*)m_tabctrlMain.GetTab(2))->CreateOpenGL(); ((tabDialog3*)m_tabctrlMain.GetTab(2))->ActivateRenderTimer(); }So ein CreateOpenGL sieht im Moment so aus (Beispiel aus tabDialog2):
void tabDialog2::CreateOpenGL() { m_oglGraph = new COpenGLCtrl(); <---- hier wirds konstruiert m_oglGraph->SetOGLDrawType(0); m_boolTimerActive=false; GetDlgItem(IDC_OPENGL)->GetWindowRect(rect_opengl); ScreenToClient(rect_opengl); // Create OpenGL Control window m_oglGraph->oglCreate(rect_opengl, this); }Wie sieht das DestroyOpenGL() aus? Sowas wie m_oglGraph.destroy() oder so? Das gibt es leider nur nicht. Vielen Dank für die Hilfe!
-
Habs gleich selbst gefunden
Ich rufe einfach den Destruktor von COpenGLCtrl auf. Jetzt muss ich nur noch überprüfen, ob das Objekt vorher schon da war.
-
edit: ok hat sich ja erledigt

-
Leider noch nicht ganz. Irgendwie wird das OpenGL nicht richtig gekillt. Ein Wechsel zwischen Tab2 - Tab3 - Tab2 - Tab3 endet in einer Exception, zudem addieren sich immer 2MB zum RAM hinzu. Die Exception kommt laut dem Debugger aus der Zeile
CreateEx(0, className, "OpenGL", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS, rect, parent, 0);
aus meinem OpenGLCreate. Wie kann ich das gesamte OpenGL killen? Gibts doch bestimmt Befehle für oder?
-
Mit Create legst du ein Windowsfenster an. Das hat noch nix mit OpenGL zu tun. Dieses sollte man auch wieder mit Destroy freigeben.
Dann holst du dir sicher irgendwo mit GetDC() nen Context. Dieses gibt man am Ende mit ReleaseDC wieder frei.
Und den Rendercontext löscht man mit wglDeleteContext. Das wäre dann das einzig OpenGL-spezifische.
-
Au mann, langsam drehe ich durch... kostet schonwieder viel zu viel zeit alles. In einem Tutorial steht, ich soll
ReleaseDC(hWnd,hdc)
benutzen, aber der Compiler meckert rum, er akzeptiert keine 2 Argumente. Dann lasse ich hWnd weg und nun meckert er rum
error C2664: 'CWnd::ReleaseDC' : cannot convert parameter 1 from 'HDC' to 'CDC *'
Gleich bei wglDeleteContext dann sicher dasselbe Spiel...
-
Wie holst du dir den DC?
Mit GetDC() oder mit GetDC(HWND); ?Bei zweiter Variante dann gib das frei mit **::**GetDC(HWND,HDC)
Ersteres ist nämlich ne Membermethode von CWnd, zweiteres ist ne WinAPI-Funktion
-
mit
hdc = GetDC()->m_hDC;
-
OK, hier hab ich was gefunden:
http://steinsoft.net/index.php?site=Programming/Tutorials/opengl_dialog&printable=1
Ist so ähnlich wie mein Code jetzt, sogar sehr ähnlich. Das Tutorial was ich benutzt habe ist leider wieder offline. Aber hiermit können wir schnell eine Antwort finden
Einfache Frage: Was würdet Ihr an diesem Tutorial verändern, damit man das Zielfenster während der Laufzeit ändern kann? Mein Problem ist einfach, dass ich da dieses "*parent" in ::Create sehe und dieses nur einmal aufgerufen wird. Also was muss verändert werden? Danke für weitere Hilfe!
-
Hm an sich nix^^
Der Code beschreibt ja ein OpenGL-Control, ob du dann nun 1, 2 oder 3 anlegst ist dabei egal.
Nur das Zeichnen in der OnPaint musst du anders realisieren, das du das zu zeichnende von außen setzen kannst.Was man nicht sieht momentan ist die Freigabe, aber die kann auch in der OpenGLDevice-Klassen "versteckt" sein.
-
Ich dachte, man könne nur eines davon haben? Am Anfang dieses Threads wurde das zumindest gesagt. Ich meiner Version dieser Klasse habe ich bereits eine Membervariable, die den Output steuert. Was gezeichnet wird, ist also nicht das Problem, sondern das "wohin". Ganz am Anfang hatte ich ja 2 Instanzen dieser Klasse, aber da bekam eine immer seltsame Streifen und Linien (wie ein TV das keinen Empfang hat)
*15 Minuten später*
Habe mal eben mit dem Typen von der oben verlinkten Seite gechattet. Er hat ein kleines Demoprogramm mit Code, wo er gleichzeitig in 9 Fenster rendert. Also das was ich suche. Er benutzt Threads, anscheinend klappts bei mir deshalb nicht gleichzeitig.
-
Also wenn das nur über Threads geht, dann ist seine Klassen nicht gerade die beste^^.
-
Ne, doch keine Threads. Habe seine Klasse nun an mein Programm angepasst. Es werden jetzt beide Statics gezeichnet
Allerdings bleiben beide schwarz
Beide Draw-Funktionen werden aber durchlaufen, na immerhin ein Fortschritt 
-
Zeig doch mal ein bissel mehr Code!
Oder frag weiter die Leute bei delphigl, obwohl da eher Pascal angesagt ist