Hello, i hope you excuse my bad english, because i am from germany. I’m trying to open several mdichild windows in a main form. Every child window is an instance of class Subclass, that i defined. The code is based on NeHe tutorial with comes with Tao. In the constructor i wrote the complete initialization of OpenGL. Than i filled in code on resize and on paint and on close. But i cannot get it to work, i get error messages if i try to make the rendercontext current with makecurrent. I am stuck at this about 1 month. If i delete the line: this.MdiParent = MainForm; than all works fine, painting is done and windows closed right. But than i have normal windows not MDI Windows like intended. I wonder why OpenGL get problems with MDI. Sorry to post such a long code, but i have no idear wether the error is.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using Tao.Platform.Windows;
namespace Test2
{
public partial class SubForm : Form
{
private IntPtr hDC; // Private GDI Device Context
private IntPtr hRC; // Permanent Rendering Context
public SubForm(Form MainForm)
{
this.CreateParams.Classstyle = this.CreateParams.Classstyle | // Redraw On Size, And Own DC For Window.
User.CS_HREDRAW | User.CS_VREDRAW | User.CS_OWNDC;
this.Setstyle(Controlstyles.AllPaintingInWmPaint, true); // No Need To Erase Form Background
this.Setstyle(Controlstyles.DoubleBuffer, true); // Buffer Control
this.Setstyle(Controlstyles.Opaque, true); // No Need To Draw Form Background
this.Setstyle(Controlstyles.ResizeRedraw, true); // Redraw On Resize
this.Setstyle(Controlstyles.UserPaint, true); // We'll Handle Painting Ourselves
InitializeComponent();
Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR(); // pfd Tells Windows How We Want Things To Be
pfd.nSize = (short)Marshal.SizeOf(pfd); // Size Of This Pixel Format Descriptor
pfd.nVersion = 1; // Version Number
pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW | // Format Must Support Window
Gdi.PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
Gdi.PFD_DOUBLEBUFFER; // Format Must Support Double Buffering
pfd.iPixelType = (byte)Gdi.PFD_TYPE_RGBA; // Request An RGBA Format
pfd.cColorBits = (byte)32; // Select Our Color Depth
pfd.cRedBits = 0; // Color Bits Ignored
pfd.cRedShift = 0;
pfd.cGreenBits = 0;
pfd.cGreenShift = 0;
pfd.cBlueBits = 0;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0; // No Alpha Buffer
pfd.cAlphaShift = 0; // Shift Bit Ignored
pfd.cAccumBits = 0; // No Accumulation Buffer
pfd.cAccumRedBits = 0; // Accumulation Bits Ignored
pfd.cAccumGreenBits = 0;
pfd.cAccumBlueBits = 0;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 16; // 16Bit Z-Buffer (Depth Buffer)
pfd.cStencilBits = 0; // No Stencil Buffer
pfd.cAuxBuffers = 0; // No Auxiliary Buffer
pfd.iLayerType = (byte)Gdi.PFD_MAIN_PLANE; // Main Drawing Layer
pfd.bReserved = 0; // Reserved
pfd.dwLayerMask = 0; // Layer Masks Ignored
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;
hDC = User.GetDC(this.Handle); // Attempt To Get A Device Context
if (hDC == IntPtr.Zero)
{ // Did We Get A Device Context?
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Create A GL Device Context. Constructor ", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
int pixelFormat = Gdi.ChoosePixelFormat(hDC, ref pfd); // Attempt To Find An Appropriate Pixel Format
if (pixelFormat == 0)
{ // Did Windows Find A Matching Pixel Format?
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Find A Suitable PixelFormat. Constructor", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
if (!Gdi.SetPixelFormat(hDC, pixelFormat, ref pfd))
{ // Are We Able To Set The Pixel Format?
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Set The PixelFormat. Constructor", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
hRC = Wgl.wglCreateContext(hDC); // Attempt To Get The Rendering Context
if (hRC == IntPtr.Zero)
{ // Are We Able To Get A Rendering Context?
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Create A GL Rendering Context. Constructor", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
SubForm_Resize(null, null);
this.MdiParent = MainForm;
}
private void SubForm_Resize(object sender, EventArgs e)
{
if (!Wgl.wglMakeCurrent(hDC, hRC))
{ // Try To Activate The Rendering Context
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Activate The GL Rendering Context. Resize", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
if (this.Height == 0)
{ // Prevent A Divide By Zero...
this.Height = 1; // By Making Height Equal To One
}
Gl.glViewport(0, 0, this.Width, this.Height); // Reset The Current Viewport
Gl.glMatrixMode(Gl.GL_PROJECTION); // Select The Projection Matrix
Gl.glLoadIdentity(); // Reset The Projection Matrix
Glu.gluPerspective(45, this.Width / (double)this.Height, 0.1, 100); // Calculate The Aspect Ratio Of The Window
Gl.glMatrixMode(Gl.GL_MODELVIEW); // Select The Modelview Matrix
Gl.glLoadIdentity();
if (!Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero))
{ // Are We Able To Release The DC and RC Contexts?
MessageBox.Show("Release Of DC And RC Failed. Resize ", "SHUTDOWN ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SubForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (!Wgl.wglDeleteContext(hRC))
{ // Are We Able To Delete The RC?
MessageBox.Show("Release Rendering Context Failed. Closing ", "SHUTDOWN ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
hRC = IntPtr.Zero; // Set RC To Null
}
private void SubForm_Paint(object sender, PaintEventArgs e)
{
if (!Wgl.wglMakeCurrent(hDC, hRC))
{ // Try To Activate The Rendering Context
//Program.KillGLWindow(); // Reset The Display
MessageBox.Show("Can't Activate The GL Rendering Context. Paint", "ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
//return false;
}
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
Gl.glLoadIdentity(); // Reset The Current Modelview Matrix
Gl.glTranslatef(-1.5f, 0, -6); // Move Left 1.5 Units And Into The Screen 6.0
Gl.glBegin(Gl.GL_TRIANGLES); // Drawing Using Triangles
Gl.glVertex3f(0, 1, 0); // Top
Gl.glVertex3f(-1, -1, 0); // Bottom Left
Gl.glVertex3f(1, -1, 0); // Bottom Right
Gl.glEnd(); // Finished Drawing The Triangle
Gl.glTranslatef(3, 0, 0); // Move Right 3 Units
Gl.glBegin(Gl.GL_QUADS); // Draw A Quad
Gl.glVertex3f(-1, 1, 0); // Top Left
Gl.glVertex3f(1, 1, 0); // Top Right
Gl.glVertex3f(1, -1, 0); // Bottom Right
Gl.glVertex3f(-1, -1, 0); // Bottom Left
Gl.glEnd();
// Done Drawing The Quad
Gdi.SwapBuffers(hDC); // Swap Buffers (Double Buffering)
if (!Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero))
{ // Are We Able To Release The DC and RC Contexts?
MessageBox.Show("Release Of DC And RC Failed. Paint ", "SHUTDOWN ERROR",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
Thx, Therion