C++ Opengl in Windows Forms



  • Hallo,

    benutze das VS05 und die Dateien gl.h / glut.h in C++
    soweit so gut.
    Nun möchte ich in einer C++ Windows Forms Anwendung OGL integrieren.
    z.B. In einem Panel. Wie funktioniert das?
    In C# geht das wunderschön mit CsGl oder dem TaoFramework
    im rechten Panel habe ich einen Trackball
    im linken das Fenster wo dann die Kamera gedreht wird.

    da hab ich mal ein Screenshot gemacht

    <img alt="" src="http://www.asselborn-matthias.de/asselborn.JPG">
    

    Vielen Dank
    mit freundlichen Grüßen
    Matthias Asselborn



  • http://www.codeproject.com/KB/miscctrl/OpenGLViewWinForms.aspx

    Lese dir auch die Kommentare unter dem Artikel durch. Dort werden einige Probleme des Tutorials behandelt....



  • Hallo,

    Dankeschön!
    habe nun 2 Ogl Fenster erstellt
    von der selben Klasse
    aber das eine Fenster bleibt schwarz das andere läuft
    habe es mit unterschiedlichen Klassen porbiert
    da geht es auch nicht
    warum?

    Konstruktor

    public:
    		Form1(void)
    		{
    			InitializeComponent();
    			this->OpenGL = gcnew COpenGL(this,0,0,200,200);
    			this->track = gcnew Trackball(this,200,200,200,200);
    		}
    

    Variablen

    private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    
    		OpenGLForm::COpenGL ^ OpenGL;
    
    		OpenGLForm::Trackball ^ track;
    

    und der Timer

    private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e)
    			 {
    				 UNREFERENCED_PARAMETER(sender);
    				 UNREFERENCED_PARAMETER(e);
    				 track->Render();
    				 track->SwapOpenGLBuffers();
    				 OpenGL->Render();
    				 OpenGL->SwapOpenGLBuffers();
    			 }
    	};
    

    sollte doch alle spassen?
    die Klasse Trackball hab ich erstellt mit dem selben Inhalt
    nur anderer Name

    wenn ich nur jeweils ein Fenster aktiviere geht es
    nur beide nicht
    😕

    Gruß Matthias



  • Habe bisher nur einen Viewport verwendet.
    Deshalb kenne ich mich damit leider nicht aus.
    Aber wurden in den Kommentaren zu dem Link nicht auch Mehrfach-Viewports diskutiert ?



  • hast du es geschafft diesen einen Viewport in ein Panel zu integrieren?
    das will bei mir auch noch nicht

    leider wurde nur von einem wegen der Resize Methode bei 2 Viewports
    in je einem Panel gefragt. Den Code postete er aber nicht.

    Gruß Matthias



  • Bin mir nicht mehr sicher wie ichs genau gemacht habe aber das war der Konstruktor für die OpenGL-Klasse:

    COpenGL::COpenGL(System::Windows::Forms::Panel ^ parent)
    {
    
    CreateParams^ cp = gcnew CreateParams();
    
    // Set the position on the form
    cp->X = 0;
    cp->Y = 0;
    
    cp->Height = parent->Height;
    cp->Width = parent->Width;
    
    // Specify the form as the parent.
    cp->Parent = parent->Handle;
    
    // Create as a child of the specified parent and make OpenGL compliant (no clipping)
    cp->Style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED;
    // Create the actual window
    this->CreateHandle(cp);
    
    m_hDC = GetDC((HWND)this->Handle.ToPointer());
    
    if(m_hDC)
    {
    MySetPixelFormat(m_hDC);
    ReSizeGLScene(cp->Width, cp->Height);
    InitGL();
    }
    }
    

    Irgendwo im Konstruktor meiner Form deklariere ich COpenGL:

    COpenGL ^ OpenGL;
    

    Die Initialisierung bzw. Aktivierung rufe ich erst auf wenn ein 3D-Modell geladen und visualisiert werden soll (In Panel1 wird das COpenGL eingebettet):

    private: System::Void activateMouseAndRendering(){
    				 OpenGL = gcnew COpenGL(this->OutputSplit->Panel1);			
    				 this->OutputSplit->Panel1->MouseDown += gcnew System::Windows::Forms::MouseEventHandler( this, &Form1::panel_MouseDown );
    				 this->OutputSplit->Panel1->MouseEnter += gcnew System::EventHandler(this, &Form1::panel_MouseEnter);
    				 this->OutputSplit->Panel1->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::panel_OnKeyboard);
    				 this->OutputSplit->Panel1->MouseWheel += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::panel_MouseWheel);
    

    Meine Resize-Funktion sieht so aus :

    private: System::Void myResize(System::Object^  sender, System::EventArgs^  e) {
    
    				 UNREFERENCED_PARAMETER(sender);
    				 UNREFERENCED_PARAMETER(e);
    
    				 if(OpenGL){
    					 OpenGL->ReSizeGLScene(this->OutputSplit->Panel1->Width, this->OutputSplit->Panel1->Height);
    
    					 OpenGL->DestroyHandle();
    					 OpenGL = gcnew COpenGL(this->OutputSplit->Panel1);
    
    					 OpenGL->Render();
    					 OpenGL->SwapOpenGLBuffers();
    				 }
    
    			 }
    

    Damit nach einem Resize der Inhalt des OpenGL-Fensters "konstant" bleibt, sollten alle relevanten Daten in der COpenGL-Klasse static sein.

    Keine Ahnung ob es ein guter Stil ist, aber es funktioniert.

    Grüße
    Blue



  • nun passt alles nochmal Vielen Dank

    hab noch die Methode

    virtual System::Void MySetCurrentGLRC()
    					{ 
    						if(m_hDC)
    							{
    								if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL)
    									{
    										MessageBox::Show("wglMakeCurrent Failed");
    									}
    							}
    					}
    

    hinzugefügt
    nun kann ich weitermachen


Anmelden zum Antworten