For those who are interested…here’s my OpenGl create window/context code.
I don’t think I’m doing anything odd here.
{------------------------------------------------}
{ Attaches a OpenGL rendering context to Window }
{-------------------------------------------------}
function TOpenGLWindow.glWnd(Width, Height : Integer; Fullscreen : Boolean; PixelDepth : Integer) : Boolean;
var
dmScreenSettings : DEVMODE; // Screen settings (fullscreen, etc...)
PixelFormat : GLuint; // Settings for the OpenGL rendering
// h_Instance : HINST; // Current instance
pfd : PIXELFORMATDESCRIPTOR; // Settings for the OpenGL window
myScreen: Trect;
i,error: integer;
ContextArrtibs: TintegerArray;
const
// OpenGL context examples:
GLattribs31_core: array [0..6] of integer = (WGL_CONTEXT_MAJOR_VERSION_ARB, 3,WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,0);
GLattribs32: array [0..8] of integer = (WGL_CONTEXT_MAJOR_VERSION_ARB, 3,WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, 0,WGL_CONTEXT_PROFILE_MASK_ARB,WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0); //terminate with a Zero
GLattribs30: array [0..6] of integer = (WGL_CONTEXT_MAJOR_VERSION_ARB, 3,WGL_CONTEXT_MINOR_VERSION_ARB, 0,WGL_CONTEXT_FLAGS_ARB, 0, 0); //terminate with a Zero
GLattribs31: array [0..6] of integer = (WGL_CONTEXT_MAJOR_VERSION_ARB, 3,WGL_CONTEXT_MINOR_VERSION_ARB, 1,WGL_CONTEXT_FLAGS_ARB, 0, 0); //terminate with a Zero
begin
result := false;
// extgl_InitializeWGL; //need to call this before OpenGl init...becase of OpenGL 3.x context
// extgl_SetupWGL;
flags := 0;
SetWindowFlags;
if UseGLWindow then
begin
MakeGLWindow (fglFormw,fglFormh, fullscreen); //Create OpenGl Window
// h_Instance := GetModuleHandle(nil); //Grab An Instance For Our Window
// Change to fullscreen if so desired
fFullScreen := fullscreen;
if fFullscreen then
begin
EnumDisplaySettings(nil, ENUM_CURRENT_SETTINGS, DMsaved); // Save Current Display
// ZeroMemory(@DMSaved, SizeOf(DMSaved));
DMSaved.dmPelsWidth := screen.Width; // Window width
DMSaved.dmPelsHeight := screen.Height; // Window height
// ChangeDisplaySettings(DMSaved,CDS_TEST);
ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
with dmScreenSettings do begin // Set parameters for the screen setting
dmSize := SizeOf(dmScreenSettings);
dmPelsWidth := Width; // Window width
dmPelsHeight := Height; // Window height
dmBitsPerPel := PixelDepth; // Window color depth
dmDisplayFlags := 0; //DM_GRAYSCALE DM_INTERLACED
// dmDisplayFrequency := 60;
// dmFields := DM_DISPLAYFREQUENCY or DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFLAGS;
dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFLAGS;
end;
// Try to change screen mode to fullscreen. CDS_FULLSCREEN = Remove START bar
if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) <> DISP_CHANGE_SUCCESSFUL) then
begin
MessageBox(0, 'Unable to switch to fullscreen!', 'Error', MB_OK or MB_ICONERROR);
fFullscreen := False;
end;
end; {fullscreen}
// If we are not in fullscreen then
if NOT (fFullscreen) then ShowMouse (true) // Turn on in window mode
else ShowMouse (fShowCursor); // Turn off the cursor (gets in the way)
end {UseGlWindow}
else h_Wnd := GLhwnd; {user suplied window handle}
if h_Wnd = 0 then
begin
glKillWnd; // Undo all the settings we've changed
MessageBox(0, 'Unable to initialise window!', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
// Try to get a device context
h_DC := GetDC(h_wnd);
if (h_DC = 0) then
begin
glKillWnd;
MessageBox(0, 'Unable to get a device context!', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
// Settings for the OpenGL window
with pfd do
begin
nSize := SizeOf(PIXELFORMATDESCRIPTOR); // Size Of This Pixel Format Descriptor
nVersion := 1; // The version of this data structure
dwFlags := Flags;
iPixelType := PFD_TYPE_RGBA; // RGBA color format
cColorBits := PixelDepth; // OpenGL color depth
cRedBits := 0; // Number of red bitplanes
cRedShift := 0; // Shift count for red bitplanes
cGreenBits := 0; // Number of green bitplanes
cGreenShift := 0; // Shift count for green bitplanes
cBlueBits := 0; // Number of blue bitplanes
cBlueShift := 0; // Shift count for blue bitplanes
cAlphaBits := 0; // Not supported
cAlphaShift := 0; // Not supported
cAccumBits := 0; // No accumulation buffer
cAccumRedBits := 0; // Number of red bits in a-buffer
cAccumGreenBits := 0; // Number of green bits in a-buffer
cAccumBlueBits := 0; // Number of blue bits in a-buffer
cAccumAlphaBits := 0; // Number of alpha bits in a-buffer
cDepthBits := FDepthBits; // Specifies the depth of the depth buffer. (16-bits or 32-bits)
cStencilBits := 0; // Turn off stencil buffer
cAuxBuffers := 0; // Not supported
iLayerType := PFD_MAIN_PLANE; // Ignored
bReserved := 0; // Number of overlay and underlay planes
dwLayerMask := 0; // Ignored
dwVisibleMask := 0; // Transparent color of underlay plane
dwDamageMask := 0; // Ignored
end;
// If component's settings specifies that the accumulation buffer is enabled
// then set its depth (which enables it)
if FAccumBufferEnabled then
pfd.cAccumBits := FAccumBits;
// If component's settings specifies that the stencil buffer is enabled
// then set its depth (which enables it)
if FStencEnabled then
pfd.cStencilBits := FStencBits;
if not InitOpenGL (fGlLib,fGluLib) then
begin
MessageBox(0, 'Unable to initialise OpenGL library', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
// Attempts to find the pixel format supported by a device context that is the best match to a given pixel format specification.
PixelFormat := ChoosePixelFormat(h_DC, @pfd);
if (PixelFormat = 0) then
begin
glKillWnd;
MessageBox(0, 'Unable to find a suitable pixel format', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
// Sets the specified device context's pixel format to the format specified by the PixelFormat.
//NB can only be set once!
if Not glPixelSet then
if (not SetPixelFormat(h_DC, PixelFormat, @pfd)) then
begin
glKillWnd;
MessageBox(0, 'Unable to set the pixel format', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
glPixelset := true;
h_RC := wglCreateContext(h_DC);
if (h_RC = 0) then
begin
glKillWnd;
MessageBox(0, 'Unable to create a legacy OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
// Makes the specified OpenGL rendering context the calling thread's current rendering context
if (not wglMakeCurrent(h_DC, h_RC)) then
begin
glKillWnd;
MessageBox(0, 'Unable to activate OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
Result := False;
Exit;
end;
//Now have Open GL context. Initilialise all the GL functions.
extgl_Initialize;
// modify current context - add a OpenGL 3.x rendering context - not fully tested
if supportedExtensions.WGL[WGL_ARB_create_context] then
begin
oldh_RC := h_RC;
if supportedExtensions.OpenGL.Major < 3 then h_RC := wglCreateContextAttribsARB(h_DC,0,@GLattribs30)
else begin
//try and create a context using the new API using the highest available GL version.
//OpenGL 3.1 does not support the extended profile mask settings...
if (supportedExtensions.OpenGL.Major = 3) AND (supportedExtensions.OpenGL.Minor = 1) then h_RC := wglCreateContextAttribsARB(h_DC,0,@GLattribs31)
else begin
if NOT SupportedExtensions.wgl[WGL_ARB_create_context_profile] then
begin
setlength (ContextArrtibs, 7);
ContextArrtibs[0] := WGL_CONTEXT_MAJOR_VERSION_ARB; ContextArrtibs[1] := supportedExtensions.OpenGL.Major;
ContextArrtibs[2] := WGL_CONTEXT_MINOR_VERSION_ARB; ContextArrtibs[3] := supportedExtensions.OpenGL.minor;
ContextArrtibs[4] := WGL_CONTEXT_FLAGS_ARB; ContextArrtibs[5] := 0;
ContextArrtibs[6] := 0; //terminator
end else
begin
setlength (ContextArrtibs, 9);
ContextArrtibs[0] := WGL_CONTEXT_MAJOR_VERSION_ARB; ContextArrtibs[1] := supportedExtensions.OpenGL.Major;
ContextArrtibs[2] := WGL_CONTEXT_MINOR_VERSION_ARB; ContextArrtibs[3] := supportedExtensions.OpenGL.minor;
ContextArrtibs[4] := WGL_CONTEXT_FLAGS_ARB; ContextArrtibs[5] := 0;
ContextArrtibs[6] := WGL_CONTEXT_PROFILE_MASK_ARB; ContextArrtibs[7] := WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
ContextArrtibs[8] := 0; //terminator
end;
end;
h_RC := wglCreateContextAttribsARB(h_DC,0,@ContextArrtibs[0]);
end;
if (h_RC = 0) then
begin
MessageBox(0, 'Unable to set attributes for an OpenGL 3.x rendering context', 'Error', MB_OK or MB_ICONERROR);
error := getLastError ();
case error of
0:MessageBox(0, 'No information about the error from wglCreateContextAttribsARB available.', 'Error', MB_OK or MB_ICONERROR);
ERROR_INVALID_VERSION_ARB:MessageBox(0, 'Invalid OpenGL version requested', 'Error', MB_OK or MB_ICONERROR);
ERROR_INVALID_PROFILE_ARB:MessageBox(0, 'Invalid OpenGL profile requested', 'Error', MB_OK or MB_ICONERROR);
end;
h_RC := oldh_RC;
end else
begin
//release old GL context
wglMakeCurrent(h_DC, 0);
wglDeleteContext(oldh_RC);
end;
if (h_RC = 0) then
begin
glKillWnd;
Result := False;
Exit;
end;
//use new GL 3.x context
wglMakeCurrent(h_DC, h_RC); //use GL context
extgl_Initialize;
end;
//read back Pixel format to see what OpenGL has assigned
PixelFormat := GetPixelFormat(h_dc);
DescribePixelFormat(h_dc, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), runtime.screen.pfd);
frequestedPixelDepth := PixelDepth;
RunTime.Screen.ColorDepth := runtime.screen.pfd.cColorbits;
AUX_vars.JPG_ALPHA := 255; //All JPG have the same default alpha.
fglInit := true;
result := true;
exit;
// Call assinged initialization routine and resize routine
GetClientRect(h_Wnd, myScreen); // get screen dimensions
fWindowW := myScreen.right; // save initial screen size for later
fWindowH := myScreen.bottom;
glResizeWnd(fWindowW, fWindowH); //SetRunTimeScreen;
end;