Setting up the context correctly is quite hard.
For a re-usable control with decent performance, you'll most likely want a control with it's own DC, but if you can acquire one each time you paint, you might be okay.
Take a look at http://glscene.cvs.sourceforge.net/viewvc/glscene/Source/Platform/GLWin32Viewer.pas?view=log to see how GLScene creates a control that's usable with OpenGL.
The key part in acquiring it's own DC, is overriding the CreateParams procedure + adding:
with Params do begin
Style:=Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS;
WindowClass.Style:=WindowClass.Style or CS_OWNDC;
end;
You can then get the DC to use in CreateWnd, and release in DestroyWnd
Once you've got the DC, you'll need to make sure the PixelFormat supports OpenGL + has the details you want:
const pfd: PIXELFORMATDESCRIPTOR = (
nSize: sizeof(PIXELFORMATDESCRIPTOR);
nVersion: 1; // version
dwFlags: PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType: PFD_TYPE_RGBA;
cColorBits: 24; // 24-bit color depth
cRedBits: 0;
cRedShift: 0;
cGreenBits: 0;
cGreenShift: 0;
cBlueBits: 0;
cBlueShift: 0;
cAlphaBits: 8; // alpha bits
cAlphaShift: 0;
cAccumBits: 0; // accumulation buffer
cAccumRedBits: 0;
cAccumGreenBits: 0;
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits: 32; // z-buffer
cStencilBits: 16; // stencil buffer
cAuxBuffers: 0; // auxiliary buffer
iLayerType: PFD_MAIN_PLANE; // main layer
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0
);
var
pf: Integer;
begin
pf := ChoosePixelFormat(dc, @pfd);
if not SetPixelFormat(dc, pf, @pfd) then
Assert(false);//failed, could retry with other settings
rc := wglCreateContext(dc);
if not wglMakeCurrent(dc, rc) then
Assert(false);// failed
// we should now have a rc so to test, we'll just clear
glClearColor(1, 0.5, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
// If we're double-buffered, then swap
SwapBuffers(dc);
wglMakeCurrent(0, 0);
After you've finished using the RC, you should also clean up by calling wglDeleteContext.