@@ -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+ }
210253bool 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