Skip to content

Commit beec847

Browse files
committed
Important fix; MSW matches GLFW where GL Options.version() specifies a specific version; else allocates context of the highest support version
1 parent ff82719 commit beec847

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

src/cinder/app/msw/RendererImplGlMsw.cpp

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -179,34 +179,77 @@ bool getWglFunctionPointers( PFNWGLCREATECONTEXTATTRIBSARB *resultCreateContextA
179179
}
180180
}
181181

182-
HGLRC createContext( HDC dc, bool coreProfile, bool debug, int majorVersion, int minorVersion, GLenum multigpu = 0 )
182+
HGLRC createContext( HDC dc, bool coreProfile, bool debug, bool profileSpecified, int majorVersion, int minorVersion, GLenum multigpu = 0 )
183183
{
184-
HGLRC result = 0;
185-
static bool initializedLoadOGL = false;
184+
HGLRC result = 0;
185+
static bool initializedLoadOGL = false; // kept from your original, in case it's used elsewhere
186186

187-
PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARBPtr = NULL;
188-
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBPtr = NULL;
189-
if( getWglFunctionPointers( &wglCreateContextAttribsARBPtr, &wglChoosePixelFormatARBPtr ) ) {
190-
int attribList[] = {
191-
WGL_CONTEXT_MAJOR_VERSION_ARB, majorVersion,
192-
WGL_CONTEXT_MINOR_VERSION_ARB, minorVersion,
193-
WGL_CONTEXT_FLAGS_ARB, (debug) ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
194-
WGL_CONTEXT_PROFILE_MASK_ARB, (coreProfile) ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
195-
0, 0,
196-
0
197-
};
187+
PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARBPtr = nullptr;
188+
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBPtr = nullptr;
189+
if( ! getWglFunctionPointers( &wglCreateContextAttribsARBPtr, &wglChoosePixelFormatARBPtr ) ) {
190+
throw ExcRendererAllocation( "wglCreateContextAttribsARB / wglChoosePixelFormatARB unavailable" );
191+
}
192+
193+
const int baseFlags = debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0;
194+
195+
auto tryCreate = [&]( int maj, int min ) -> HGLRC {
196+
int attribList[32];
197+
int idx = 0;
198+
199+
// Explicit version
200+
attribList[idx++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
201+
attribList[idx++] = maj;
202+
attribList[idx++] = WGL_CONTEXT_MINOR_VERSION_ARB;
203+
attribList[idx++] = min;
204+
205+
// Flags (only if non-zero)
206+
if( baseFlags != 0 ) {
207+
attribList[idx++] = WGL_CONTEXT_FLAGS_ARB;
208+
attribList[idx++] = baseFlags;
209+
}
210+
211+
// Profile mask only if the user actually specified a profile
212+
if( profileSpecified ) {
213+
const int profileMask = coreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
214+
attribList[idx++] = WGL_CONTEXT_PROFILE_MASK_ARB;
215+
attribList[idx++] = profileMask;
216+
}
217+
218+
// Optional multigpu
198219
if( multigpu != 0 ) {
199-
attribList[8] = WGL_CONTEXT_MULTIGPU_ATTRIB_NV;
200-
attribList[9] = multigpu;
201-
}
202-
result = (*wglCreateContextAttribsARBPtr)( dc, 0, attribList );
203-
return result;
220+
attribList[idx++] = WGL_CONTEXT_MULTIGPU_ATTRIB_NV;
221+
attribList[idx++] = multigpu;
222+
}
223+
224+
// Terminator
225+
attribList[idx++] = 0;
226+
attribList[idx++] = 0;
227+
228+
return wglCreateContextAttribsARBPtr( dc, 0, attribList );
229+
};
230+
231+
// version unspecified -> descending test of known versions
232+
if( majorVersion == 0 && minorVersion == 0 ) {
233+
static const int versions[][2] = { { 4, 6 }, { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 }, { 3, 3 }, { 3, 2 } };
234+
235+
const int numVersions = (int)( sizeof( versions ) / sizeof( versions[0] ) );
236+
for( int i = 0; i < numVersions; ++i ) {
237+
HGLRC ctx = tryCreate( versions[i][0], versions[i][1] );
238+
if( ctx )
239+
return ctx; // first successful (highest in our list)
240+
}
241+
242+
// If we get here, nothing in our list worked
243+
throw ExcRendererAllocation( "Failed to create any modern OpenGL context (tried 4.6 down to 3.2)" );
204244
}
205-
else {
206-
throw ExcRendererAllocation( "wglCreateContextAttribsARB / wglChoosePixelFormatARB unavailable" );
245+
else { // user specified a version - try only that one
246+
result = tryCreate( majorVersion, minorVersion );
247+
if( ! result )
248+
throw ExcRendererAllocation( "Failed to create requested OpenGL context" );
207249
}
208-
}
209250

251+
return result;
252+
}
210253
bool testPixelFormat( HDC dc, int colorSamples, int depthDepth, int msaaSamples, int stencilDepth, int *resultFormat )
211254
{
212255
PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARBPtr = NULL;
@@ -280,17 +323,14 @@ bool initializeGl( HWND /*wnd*/, HDC dc, HGLRC sharedRC, const RendererGl::Optio
280323
throw ExcRendererAllocation( "Failed to find suitable WGL pixel format" );
281324

282325
GLenum multigpu = 0;
283-
if( options.isMultiGpuEnabledNV() ) {
326+
if( options.isMultiGpuEnabledNV() )
284327
multigpu = getMultiGpuContextMode( options.getMultiGpuModeNV() );
285-
}
286328

287-
if( ! ( *resultRc = createContext( dc, options.getCoreProfile(), options.getDebug(), options.getVersion().first, options.getVersion().second, multigpu ) ) ) {
288-
return false;
289-
}
329+
if( ! ( *resultRc = createContext( dc, options.getCoreProfile(), options.getDebug(), options.getProfileSpecified(), options.getVersion().first, options.getVersion().second, multigpu ) ) )
330+
return false;
290331

291-
if( ! ::wglMakeCurrent( dc, *resultRc ) ){ // Try To Activate The Rendering Context
332+
if( ! ::wglMakeCurrent( dc, *resultRc ) ) // Try To Activate The Rendering Context
292333
return false;
293-
}
294334

295335
gl::Environment::setCore();
296336
gl::env()->initializeFunctionPointers();

0 commit comments

Comments
 (0)