2017-12-21 5 views
1

Grundsätzlich versuche ich ein gControl-Fenster auf Widows Forms in Echtzeit zu erstellen. Ich mache das, weil ich mehrere Fenster verwenden werde, und wahrscheinlich ihre Position neu justieren, und ich möchte das nicht manuell machen.Erstellen von glControl Window Realtime

Ich verstehe nicht, warum mein Code nicht funktioniert. Hier ist es:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

using System.Diagnostics; 

using OpenTK; 
using OpenTK.Graphics; 
using OpenTK.Graphics.OpenGL; 
using OpenTK.Platform; 

namespace Draw3Dv01wf 
{ 
    public partial class Form1 : Form 
    { 
     GLControl renderCanvas1; 
     int winX, winY, winW, winH; 

     public Form1() 
     { 
      // required method for designer support 
      InitializeComponent(); 
     } 


     // load event handler 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      // create and setup gl.control windows 
      this.renderCanvas1 = new GLControl(); 
      //this.SuspendLayout(); 

      winX = this.Location.X; winY = this.Location.Y; 
      winW = this.Width; winH = this.Height; 

      this.renderCanvas1.BackColor = System.Drawing.Color.CadetBlue; 
      this.renderCanvas1.Location = 
       new System.Drawing.Point(winX + 50, winY + 50); 
      this.renderCanvas1.Name = "renderCanvas1"; 
      this.renderCanvas1.Size = new System.Drawing.Size(winW/3, winH/2); 
      this.renderCanvas1.TabIndex = 1; 
      this.renderCanvas1.VSync = false; 
      this.renderCanvas1.Load += 
       new System.EventHandler(this.renderCanvas_Load); 
      this.renderCanvas1.Paint += 
       new System.Windows.Forms.PaintEventHandler(
        this.renderCanvas_Paint); 
      //renderCanvas1.Paint += renderCanvas_Paint; 
      //this.ResumeLayout(false); 
     } 

     private void renderCanvas_Paint(object sender, PaintEventArgs e) 
     { 
      GL.Viewport(winX + 20, winY + 25, Width, Height); 

      // Clear the render canvas with the current color 
      GL.Clear(
       ClearBufferMask.ColorBufferBit | 
       ClearBufferMask.DepthBufferBit); 

      GL.Flush(); 
      renderCanvas1.SwapBuffers(); 
     } 

     private void renderCanvas_Load(object sender, EventArgs e) 
     { 
      // Specify the color for clearing 
      GL.ClearColor(Color.SkyBlue); 
     } 
    } 
} 

Ich sehe nur die Windows-Form. Das glControl-Fenster wird nicht angezeigt. Allerdings, wenn ich die glControl zum Formular manuell hinzufügen, und fügen Sie diesen Code:

//____________________________________________ 

    private void glControl1_Load(object sender, EventArgs e) 
    { 
     // Specify the color for clearing 
     GL.ClearColor(Color.SkyBlue); 

     this.Paint += new PaintEventHandler(glControl1_Paint); 
    } 

    private void glControl1_Paint(object sender, PaintEventArgs e) 
    { 
     GL.Viewport(this.Location.X, this.Location.Y, Width, Height); 

     // Clear the render canvas with the current color 
     GL.Clear(
      ClearBufferMask.ColorBufferBit | 
      ClearBufferMask.DepthBufferBit); 

     GL.Flush(); 
     glControl1.SwapBuffers(); 
    } 

    //________________________________________________________ 

... In diesem Fenster wird auf dem Formular oben.

Der Code in meinem Programm ist nicht anders als der Code im Designer, so dass ich völlig verwirrt bin.

Dies ist der Designer-Code:

this.glControl1 = new OpenTK.GLControl(); 
    this.SuspendLayout(); 
    // 
    // glControl1 
    // 
    this.glControl1.BackColor = System.Drawing.Color.Black; 
    this.glControl1.Location = new System.Drawing.Point(385, 12); 
    this.glControl1.Name = "glControl1"; 
    this.glControl1.Size = new System.Drawing.Size(476, 284); 
    this.glControl1.TabIndex = 0; 
    this.glControl1.VSync = false; 
    this.glControl1.Load += new System.EventHandler(this.glControl1_Load); 
    // 
    // Form1 
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
    this.BackColor = System.Drawing.SystemColors.Desktop; 
    this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 
    this.ClientSize = new System.Drawing.Size(1264, 681); 
    this.Controls.Add(this.glControl1); 
    this.HelpButton = true; 
    this.MaximumSize = new System.Drawing.Size(3840, 2160); 
    this.MinimumSize = new System.Drawing.Size(640, 480); 
    this.Name = "Form1"; 
    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 
    this.Text = "Draw3D"; 
    this.ResumeLayout(false); 
+0

Der Designer-Code diese Zeile hat 'this.Controls.Fügen Sie (this.glControl1) hinzu: 'was Ihnen fehlt. Ohne es ist es keine Überraschung, dass das GL-Fenster nicht angezeigt wird. Sie erstellen es (außerhalb des Bildschirms) und fügen es nie einem sichtbaren Formular hinzu. –

+0

Danke. Das habe ich total vermisst, aber ich muss noch etwas vermissen, denn obwohl ich diesen Code "this.Controls.Add (this.renderCanvas1);" Im Ereignishandler Form1_Load wird das Fenster immer noch nicht angezeigt. Siehst du noch etwas, das ich übersehen habe? – Jillinger

Antwort

1

Ich habe versucht, etwas von einem anderen glControl zu schaffen, aber dieses Mal, das Formular nicht in den Load-Ereignishandler von.

public Form1() 
{ 
    // required method for designer support 
    InitializeComponent(); 
    initSetup(); 
} 

private void initSetup() 
{ 
    winX = this.Location.X; winY = this.Location.Y; 
    winW = this.Width; winH = this.Height; 

    this.renderCanvas2 = new GLControl(); 
    this.renderCanvas2.BackColor = System.Drawing.Color.DeepSkyBlue; 
    this.renderCanvas2.Location = 
     new System.Drawing.Point(winX + 150, winY + 150); 
    this.renderCanvas2.Name = "renderCanvas2"; 
    this.renderCanvas2.Size = 
     new System.Drawing.Size(winW/2, winH/2); 
    this.renderCanvas2.TabIndex = 1; 
    this.renderCanvas2.VSync = false; 
    this.renderCanvas2.Load += 
     new System.EventHandler(this.renderCanvas2_Load); 
    this.renderCanvas2.Paint += 
     new System.Windows.Forms.PaintEventHandler(
      this.renderCanvas2_Paint); 

    this.Controls.Add(this.renderCanvas2); 
} 

... und es hat funktioniert. Ich weiß nicht, warum das so ist. Es verursachte auch, dass das manuell erstellte glControl-Fenster in schwarz geändert wurde - an seinem ursprünglichen Ort oder weiß - wenn es verschoben wurde. Aber zumindest habe ich Ergebnisse. Ich werde weiter damit spielen und sehen, was ich herausfinden kann. Ich habe das Gefühl, dass es pufferbezogen sein könnte. Die andere Option, die ich habe, ist, die Fenster manuell zu erstellen, und ihre Position und Größe durch Code anzupassen, da das auch funktioniert. Ich würde immer noch jede Eingabe begrüßen, warum der Code nicht in Load Event Handler des Formulars funktioniert, wenn jemand weiß. Danke

BEARBEITEN Ich mache Fortschritte. Ich habe nur einen letzten Schritt. Jetzt verwende ich ein Array von glControls, um meine Fenster zu erstellen, aber ich wollte nicht mehrere Ereignishandler erstellen, um jedes Fenster zu verwalten, also versuche ich Ergebnisse mit nur einem Load-Ereignis und einem Paint-Ereignis zu erhalten. Allerdings habe ich Probleme mit der Einstellung der Farbe auf allen Fenstern. Ich bin mir nicht sicher, ob diese Methode möglich ist. Ich würde mich über jede Hilfe freuen. Hier ist mein Testcode:

using... 

namespace Draw3Dv01wf 
{ 
    public partial class Form1 : Form 
    { 
     GLControl[] renderCanvas = new GLControl[10]; 
     private int 
      winX, winY, winW, winH, winDist, winNum, 
      aCol, rCol, gCol, bCol; 
     Random randNum = new Random(); 
     //byte[] num = new byte[255]; 
     byte r, g, b, a; 
     Color4 winCol; 
     private bool winCreated; 
     private bool eHandlerIs; 

     TextBox tb = new TextBox(); 

     public Form1() 
     { 
      // required method for designer support 
      InitializeComponent(); 
      initSetup(); 
     } 

     private void initSetup() 
     { 
      winX = this.Location.X; winY = this.Location.Y; 
      winW = this.Width; winH = this.Height; 
      rCol = 255; gCol = 255; bCol = 255; aCol = 255; 

      // debugging text 
      tb.Location = new Point(5, 5); 
      tb.Size = new Size(200, 15); 
      tb.Name = "textBox1"; 
      tb.TabIndex = 0; 
      tb.BackColor = Color.Black; 
      tb.ForeColor = Color.White; 
      tb.Text = winNum.ToString(); 
      this.Controls.Add(this.tb); 

      // create windows 
      for (int w=0; w<8; w++) 
      { 
       // window distance 
       winDist += 32; 
       // make sure window with index 0 is created 
       if (winCreated) { winNum += 1; } 

       // create windows 
       this.renderCanvas[w] = new GLControl(); 
       //this.SuspendLayout(); 
       this.renderCanvas[w].BackColor = 
        System.Drawing.Color.DeepSkyBlue; 
       this.renderCanvas[w].Location = 
        new System.Drawing.Point(winX + winDist, winY + winDist); 
       this.renderCanvas[w].Name = "renderCanvas" + w; 
       this.renderCanvas[w].Size = 
        new System.Drawing.Size(winW/2, winH/2); 
       this.renderCanvas[w].TabIndex = 1; 
       this.renderCanvas[w].VSync = false; 
       // create event handler 
       this.renderCanvas[w].Load += 
        new System.EventHandler(this.renderCanvas_Load); 
       if (!eHandlerIs) 
       { 
        this.renderCanvas[w].Paint += 
         new System.Windows.Forms.PaintEventHandler(
          this.renderCanvas_Paint); 
        //eHandlerIs = true; 
       } 
       //this.ResumeLayout(false); 

       // add specified control to the control collection 
       this.Controls.Add(this.renderCanvas[w]); 
       winCreated = true; // first window created 
      } 
     } 

     private void renderCanvas_Paint(object sender, PaintEventArgs e) 
     { 
      tb.Text = r.ToString(); 
      if (winNum < 7) 
      { 
       //GL.Viewport(
       // renderCanvas[winNum].Location.X, 
       // renderCanvas[winNum].Location.Y, Width, Height); 

       //// Clear the render canvas with the current color 
       //GL.Clear(
       // ClearBufferMask.ColorBufferBit | 
       // ClearBufferMask.DepthBufferBit); 

       //GL.Flush(); 
       //renderCanvas[winNum].SwapBuffers(); 
      } 
      else if (winNum >= 7) 
      { 
       for (int w = 0; w < 8; w++) 
       { 
        GL.Viewport(
        renderCanvas[w].Location.X, 
        renderCanvas[w].Location.Y, Width, Height); 

        // Clear the render canvas with the current color 
        GL.Clear(
         ClearBufferMask.ColorBufferBit | 
         ClearBufferMask.DepthBufferBit); 

        GL.Flush(); 
        renderCanvas[w].SwapBuffers(); 
       } 
      } 
     } 

     private void renderCanvas_Load(object sender, EventArgs e) 
     { 
      // randomize color (min & max int) 
      rCol = randNum.Next(100, 255); 
      gCol = randNum.Next(100, 255); 
      bCol = randNum.Next(100, 255); 
      aCol = 255; 
      // convert int to (32) byte 
      r = (byte)(rCol >> 32); 
      g = (byte)(gCol >> 32); 
      b = (byte)(bCol >> 32); 
      a = (byte)(aCol >> 32); 
      // window final color 
      winCol = new Color4(r, g, b, a); 

      // Specify the color for clearing 
      GL.ClearColor(winCol); 
     } 
    } 
} 

... und hier ist das Ergebnis: enter image description here

Nur ein Fenster bekommt eine Farbe. Alle anderen werden schwarz. Ich freue mich über jede Rückmeldung.

BEARBEITEN Got it! MakeCurrent zur Rettung. void OpenTK.GLControl.MakeCurrent()
Macht das zugrundeliegende GLControl im aufrufenden Thread aktuell. Alle ausgegebenen OpenGL-Befehle werden nachfolgend von diesem GLControl interpretiert. Hier ist ein Update des Codes:

GLControl[] renderCanvas = new GLControl[10]; 
private int 
    winX, winY, winW, winH, winDist, winNum, win, 
    aCol, rCol, gCol, bCol; 
Random randNum = new Random(); 
//byte[] num = new byte[255]; 
byte r, g, b, a; 
Color4 winCol; 
private bool winCreated; 
private bool eHandlerIs; 

TextBox tb = new TextBox(); 

public Form1() 
{ 
    // required method for designer support 
    InitializeComponent(); 
    initSetup(); 
} 

private void initSetup() 
{ 
    winX = this.Location.X; winY = this.Location.Y; 
    winW = this.Width; winH = this.Height; 
    rCol = 255; gCol = 255; bCol = 255; aCol = 255; 

    // debugging text 
    tb.Location = new Point(5, 5); 
    tb.Size = new Size(200, 15); 
    tb.Name = "textBox1"; 
    tb.TabIndex = 0; 
    tb.BackColor = Color.Black; 
    tb.ForeColor = Color.White; 
    tb.Text = winNum.ToString(); 
    this.Controls.Add(this.tb); 

    // create windows 
    for (int w=0; w<8; w++) 
    { 
     // window distance 
     winDist += 32; 
     // make sure window with index 0 is created 
     if (winCreated) { winNum += 1; } 

     // create windows 
     this.renderCanvas[w] = new GLControl(); 
     //this.SuspendLayout(); 
     this.renderCanvas[w].BackColor = 
      System.Drawing.Color.DeepSkyBlue; 
     this.renderCanvas[w].Location = 
      new System.Drawing.Point(winX + winDist, winY + winDist); 
     this.renderCanvas[w].Name = "renderCanvas" + w; 
     this.renderCanvas[w].Size = 
      new System.Drawing.Size(winW/2, winH/2); 
     this.renderCanvas[w].TabIndex = 1; 
     this.renderCanvas[w].VSync = false; 
     // create event handler 
     this.renderCanvas[w].Load += 
      new System.EventHandler(this.renderCanvas_Load); 
     if (!eHandlerIs) 
     { 
      this.renderCanvas[w].Paint += 
       new System.Windows.Forms.PaintEventHandler(
        this.renderCanvas_Paint); 
      //eHandlerIs = true; 
     } 
     //this.ResumeLayout(false); 

     // add specified control to the control collection 
     this.Controls.Add(this.renderCanvas[w]); 
     winCreated = true; // first window created 
    } 
} 

private void renderCanvas_Paint(object sender, PaintEventArgs e) 
{ 
    tb.Text = r.ToString(); 
    if (winNum < 7) 
    { 

    } 
    else if (winNum >= 7) 
    { 
     for (int w = 0; w < 8; w++) 
     { 
      for (int n = 0; n < 8; n++) 
      { 
       if (w != n) 
       { 
        if (renderCanvas[n].Created && 
         renderCanvas[n].Context.IsCurrent) 
        { renderCanvas[n].Context.MakeCurrent(null); } 
       } 
      } 

      if (renderCanvas[w].Context.IsCurrent == false) 
      { renderCanvas[w].MakeCurrent(); } 

      GL.Viewport(
      renderCanvas[w].Location.X, 
      renderCanvas[w].Location.Y, Width, Height); 

      // Clear the render canvas with the current color 
      GL.Clear(
       ClearBufferMask.ColorBufferBit | 
       ClearBufferMask.DepthBufferBit); 

      GL.Flush(); 
      renderCanvas[w].SwapBuffers(); 
     } 
    } 
} 

private void renderCanvas_Load(object sender, EventArgs e) 
{ 
    // randomize color (min & max int) 
    rCol = randNum.Next(100, 255); 
    gCol = randNum.Next(100, 255); 
    bCol = randNum.Next(100, 255); 
    aCol = 255; 
    // convert int to (32) byte 
    r = (byte)(rCol >> 32); 
    g = (byte)(gCol >> 32); 
    b = (byte)(bCol >> 32); 
    a = (byte)(aCol >> 32); 
    // window final color 
    winCol = new Color4(r, g, b, a); 

    for (int n = 0; n < 8; n++) 
    { 
     if (win != n) 
     { 
      if (renderCanvas[n].Created && 
       renderCanvas[n].Context.IsCurrent) 
      { renderCanvas[n].Context.MakeCurrent(null); } 
     } 
    } 

    if (renderCanvas[win].Context.IsCurrent == false) 
    { renderCanvas[win].MakeCurrent(); } 

    // Specify the color for clearing 
    GL.ClearColor(winCol); 
    win += 1; 
} 

... und das Ergebnis: enter image description here