正确设置上下文非常困难。
对于具有良好性能的可重复使用的控件,您很可能想要一个具有自己的 DC 的控件,但如果您每次绘制时都可以获得一个,那么您可能会没事。
查看http://glscene.cvs.sourceforge.net/viewvc/glscene/Source/Platform/GLWin32Viewer.pas?view=log了解 GLScene 如何创建可用于 OpenGL 的控件。
获取它自己的 DC 的关键部分是覆盖 CreateParams 过程 + 添加:
with Params do begin
Style:=Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS;
WindowClass.Style:=WindowClass.Style or CS_OWNDC;
end;
然后,您可以让 DC 在 CreateWnd 中使用,并在 DestroyWnd 中释放
获得 DC 后,您需要确保 PixelFormat 支持 OpenGL + 具有您想要的详细信息:
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);
使用完 RC 后,还应该调用 wglDeleteContext 进行清理。