I've created my own OpenGL context using native API calls and NativeWindow in C#. I based on WIN32 OpenGL examples and got this:
public class OpenGLControl : System.Windows.Forms.NativeWindow{
private IntPtr HDC;
//private Form Parent;
#region Imports
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern int ChoosePixelFormat(IntPtr hdc, [In] ref PIXELFORMATDESCRIPTOR ppfd);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern bool SetPixelFormat(IntPtr hdc, int iPixelFormat, ref PIXELFORMATDESCRIPTOR ppfd);
[StructLayout(LayoutKind.Sequential)]
struct PIXELFORMATDESCRIPTOR
{
ushort nSize;
ushort nVersion;
PFD_FLAGS dwFlags;
PFD_PIXEL_TYPE iPixelType;
byte cColorBits;
byte cRedBits;
byte cRedShift;
byte cGreenBits;
byte cGreenShift;
byte cBlueBits;
byte cBlueShift;
byte cAlphaBits;
byte cAlphaShift;
byte cAccumBits;
byte cAccumRedBits;
byte cAccumGreenBits;
byte cAccumBlueBits;
byte cAccumAlphaBits;
byte cDepthBits;
byte cStencilBits;
byte cAuxBuffers;
PFD_LAYER_TYPES iLayerType;
byte bReserved;
uint dwLayerMask;
uint dwVisibleMask;
uint dwDamageMask;
public void Init()
{
nSize = (ushort) Marshal.SizeOf(typeof (PIXELFORMATDESCRIPTOR));
nVersion = 1;
dwFlags = PFD_FLAGS.PFD_DRAW_TO_WINDOW | PFD_FLAGS.PFD_SUPPORT_OPENGL | PFD_FLAGS.PFD_DOUBLEBUFFER | PFD_FLAGS.PFD_SUPPORT_COMPOSITION;
iPixelType = PFD_PIXEL_TYPE.PFD_TYPE_RGBA;
cColorBits = 24;
cRedBits = cRedShift = cGreenBits = cGreenShift = cBlueBits = cBlueShift = 0;
cAlphaBits = cAlphaShift = 0;
cAccumBits = cAccumRedBits = cAccumGreenBits = cAccumBlueBits = cAccumAlphaBits = 0;
cDepthBits = 32;
cStencilBits = cAuxBuffers = 0;
iLayerType = PFD_LAYER_TYPES.PFD_MAIN_PLANE;
bReserved = 0;
dwLayerMask = dwVisibleMask = dwDamageMask = 0;
}
}
#endregion
#region Flags Win32
[Flags]
enum PFD_FLAGS : uint
{
PFD_DOUBLEBUFFER = 0x00000001,
PFD_STEREO = 0x00000002,
PFD_DRAW_TO_WINDOW = 0x00000004,
PFD_DRAW_TO_BITMAP = 0x00000008,
PFD_SUPPORT_GDI = 0x00000010,
PFD_SUPPORT_OPENGL = 0x00000020,
PFD_GENERIC_FORMAT = 0x00000040,
PFD_NEED_PALETTE = 0x00000080,
PFD_NEED_SYSTEM_PALETTE = 0x00000100,
PFD_SWAP_EXCHANGE = 0x00000200,
PFD_SWAP_COPY = 0x00000400,
PFD_SWAP_LAYER_BUFFERS = 0x00000800,
PFD_GENERIC_ACCELERATED = 0x00001000,
PFD_SUPPORT_DIRECTDRAW = 0x00002000,
PFD_DIRECT3D_ACCELERATED = 0x00004000,
PFD_SUPPORT_COMPOSITION = 0x00008000,
PFD_DEPTH_DONTCARE = 0x20000000,
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000,
PFD_STEREO_DONTCARE = 0x80000000
}
enum PFD_LAYER_TYPES : byte
{
PFD_MAIN_PLANE = 0,
PFD_OVERLAY_PLANE = 1,
PFD_UNDERLAY_PLANE = 255
}
enum PFD_PIXEL_TYPE : byte
{
PFD_TYPE_RGBA = 0,
PFD_TYPE_COLORINDEX = 1
}
#endregion
public OpenGLControl(Form Parent){
//this.Parent = Parent;
CreateParams cp = new CreateParams(){
X = 0,
Y = 0,
Height = Parent.Height,
Width = Parent.Width,
Parent = Parent.Handle,
Style = 0x40000000 | 0x10000000 | 0x04000000 | 0x02000000
};
CreateHandle(cp);
HDC = GetDC(Parent.Handle);
if(!SetPixelFormat(HDC))
MessageBox.Show("Error creando el control OpenGL", "¡Error!");
SetShadeMode(ShadeModes.SMOOTH);
ClearColor(1.0f, 0.0f, 0.0f, 0.5f);
ClearDepth(1.0f);
Enable(Caps.DEPTH_TEST);
DepthFunction(DepthFunctions.LEQUAL);
Hint(TargetHints.PERSPECTIVE_CORRECTION, TargetModes.NICEST);
}
~OpenGLControl(){
this.DestroyHandle();
}
public void Resize(Form container){
ViewPort(0,0, container.Width, container.Height);
SetMatrixMode(MatrixModes.PROJECTION);
LoadIdentity();
GLU.Perspective(45.0f, (float)container.Width/(float)container.Height, 0.1f, 100.0f);
SetMatrixMode(MatrixModes.MODELVIEW);
LoadIdentity();
}
protected Boolean SetPixelFormat(IntPtr hWnd){
PIXELFORMATDESCRIPTOR PFD = new PIXELFORMATDESCRIPTOR();
PFD.Init();
int PixelFormat;
if((PixelFormat = ChoosePixelFormat(HDC, ref PFD)) == 0){
MessageBox.Show("ChoosePixel Error");
return false;
}
if(!SetPixelFormat(HDC, PixelFormat, ref PFD)){
MessageBox.Show("SetPixel Error");
return false;
}
IntPtr HGLRC;
if((HGLRC = OpenGL.CreateRenderingContext(HDC)) == IntPtr.Zero){
MessageBox.Show("HGLRC Error");
return false;
}
if(!OpenGL.CreateGLContext(HDC, HGLRC)){
MessageBox.Show("CreateGL Context Error");
return false;
}
return true;
}
}
When I compile the code, it works and show a White box, which is the GLContext, but now I don't know HOW to render on this control. How can I draw on this, what events do I need to override? I tried overriding the parent Form
events OnResize()
and OnPaint()
but nothing works :c
This is what I added to the OnPaint
event:
glShadeModel(GL_SMOOTH);
glClearColor(1.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//The this:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
But in WIN32
examples, these functions are done in the MessageLoop:
if (!PeekMessage(&msg,NULL,0,0,PM_REMOVE){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
But nothing happens. Do I need to add something more?
EDIT: The example I used as base: http://www.ism.univmed.fr/mestre/CDRV-C/Documents/7_Doc_Avancee/1/Lesson5.cpp
User contributions licensed under CC BY-SA 3.0