OpenGL core context creation failed horribly

Started by
5 comments, last by Shaarigan 6 years, 6 months ago

I have problems getting a core opengl context up and running with pure win32 and glew on my system (NVIDIA GTX 970, x64, Win 10, VC++ 2017).

 

The context gets created successfully, but when i want to initialize glew() i get the following error:

Missing GL version

 

Also when i query for glGetString with GL_VERSION, GL_VENDOR, GL_RENDERER it returns null...

What is wrong?

 

A normal rendering context works just fine:

Spoiler

OpenGL version: 4.5.0 NVIDIA 382.05
OpenGL vendor: NVIDIA Corporation
OpenGL renderer: GeForce GTX 970/PCIe/SSE2
OpenGL GLSL version: 4.50 NVIDIA

 

With the new context this is totally null:

Spoiler

OpenGL version: (null)
OpenGL vendor: (null)
OpenGL renderer: (null)

 

Glew is not at fault because even without glew i still get null for any values and not a single opengl call works. They dont crash, but they simply dont work.

Even glClear() does not work -.-

 

Here is my code (I dont see any error at all):


static void Win32LoadOpenGLExtensions_Internal(const Win32State_Internal &win32State) {
  globalWGLExtensions.choosePixelFormatArb = (wgl_choose_pixel_format_arb *)wglGetProcAddress("wglChoosePixelFormatARB");
  globalWGLExtensions.createContextAttribsArb = (wgl_create_context_attribs_arb *)wglGetProcAddress("wglCreateContextAttribsARB");
  globalWGLExtensions.swapIntervalExt = (wgl_swap_interval_ext *)wglGetProcAddress("wglSwapIntervalEXT");
}

static bool Win32CreateOpenGL_Internal(Win32State_Internal &win32State, const VideoSettings &videoSettings) {
	HDC deviceContext = win32State.window.deviceContext;
	HWND handle = win32State.window.windowHandle;

	PIXELFORMATDESCRIPTOR pfd = {};
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 32;
	pfd.cDepthBits = 32;
	pfd.cAlphaBits = 8;
	pfd.iLayerType = PFD_MAIN_PLANE;

	int pixelFormat = ChoosePixelFormat(deviceContext, &pfd);
	if (!pixelFormat) {
		PushError_Internal("[Win32] Failed choosing RGBA Legacy Pixelformat for Color/Depth/Alpha (%d,%d,%d) and DC '%x'\n", pfd.cColorBits, pfd.cDepthBits, pfd.cAlphaBits, deviceContext);
		return false;
	}

	if (!SetPixelFormat(deviceContext, pixelFormat, &pfd)) {
		PushError_Internal("[Win32] Failed setting RGBA Pixelformat '%d' for Color/Depth/Alpha (%d,%d,%d and DC '%x')\n", pixelFormat, pfd.cColorBits, pfd.cDepthBits, pfd.cAlphaBits, deviceContext);
		return false;
	}

	HGLRC legacyRenderingContext = wglCreateContext(deviceContext);
	if (!legacyRenderingContext) {
		PushError_Internal("[Win32] Failed creating Legacy OpenGL Rendering Context for DC '%x')\n", deviceContext);
		return false;
	}

	if (!wglMakeCurrent(deviceContext, legacyRenderingContext)) {
		PushError_Internal("[Win32] Failed activating Legacy OpenGL Rendering Context for DC '%x' and RC '%x')\n", deviceContext, legacyRenderingContext);
		wglDeleteContext(legacyRenderingContext);
		return false;
	}

	Win32LoadOpenGLExtensions_Internal(win32State);

	HGLRC activeRenderingContext = legacyRenderingContext;
	if (videoSettings.profile != VideoCompabilityProfile::Legacy) {
		if (!(videoSettings.majorVersion > 0 && videoSettings.minorVersion >= 0)) {
			PushError_Internal("[Win32] The specified major version '%llu' and minorVersion '%llu' is invalid!\n", videoSettings.majorVersion, videoSettings.minorVersion);
			return false;
		}

		if (!globalWGLExtensions.choosePixelFormatArb) {
			PushError_Internal("[Win32] wglChoosePixelFormatARB is not available, please select a different video profile!\n");
			return false;
		}
		if (!globalWGLExtensions.createContextAttribsArb) {
			PushError_Internal("[Win32] wglCreateContextAttribsARB is not available, please select a different video profile!\n");
			return false;
		}

		int contextAttribList[32 + 1] = {};
		int contextAttribCount = 0;
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
		contextAttribList[contextAttribCount++] = (int)videoSettings.majorVersion;
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_MINOR_VERSION_ARB;
		contextAttribList[contextAttribCount++] = (int)videoSettings.minorVersion;
#if 0
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_FLAGS_ARB;
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_PROFILE_MASK_ARB;
		contextAttribList[contextAttribCount++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
#endif
		contextAttribList[contextAttribCount++] = 0;

		HGLRC newContext = globalWGLExtensions.createContextAttribsArb(deviceContext, nullptr, contextAttribList);
		if (newContext) {
			if (!wglMakeCurrent(deviceContext, newContext)) {
				PushError_Internal("[Win32] Warning: Failed activating Modern OpenGL Rendering Context for version (%llu.%llu) and DC '%x') -> Fallback to legacy context.\n", videoSettings.majorVersion, videoSettings.minorVersion, deviceContext);
				wglDeleteContext(newContext);
				newContext = nullptr;
			} else {
				// Destroy legacy rendering context
				wglMakeCurrent(nullptr, nullptr);
				wglDeleteContext(legacyRenderingContext);
				activeRenderingContext = newContext;
			}
		} else {
			PushError_Internal("[Win32] Warning: Failed creating Modern OpenGL Rendering Context for version (%llu.%llu) and DC '%x') -> Fallback to legacy context.\n", videoSettings.majorVersion, videoSettings.minorVersion, deviceContext);
		}
	}

	FPL_ASSERT(activeRenderingContext != nullptr);

	win32State.opengl.renderingContext = activeRenderingContext;

	// Set vertical syncronisation if available
	if (globalWGLExtensions.swapIntervalExt != nullptr) {
		int swapInterval = videoSettings.isVSync ? 1 : 0;
		globalWGLExtensions.swapIntervalExt(swapInterval);
	}

	return true;
}

 

Advertisement

Use GLFW or something, pretty please...


Where are we and when are we and who are we?
How many people in how many places at how many times?

The code is a little bit hard on the eyes, but I don't see where you are calling wglChoosePixelFormatARB or however you get to this to choose the correct pixel format for the device context used to create the OpenGL context.
I suggest you take a look at this 
https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL)    to verify that you are not missing a few steps. A few attributes are required to get the correct pixel format, but its should be pretty straightforward.
 

wglChoosePixelFormatARB should not be the problem because I do it the same way without and it works pretty well. Two options, check for GetLastError() and glGetError to be sure nothing happened in the background.

Maybe your initialisation of the attributes is a littler bit failing what I could not verify yet. I do it this way for simplicity


int32 attributes[] = 
{  
	WGL_CONTEXT_MAJOR_VERSION_ARB, profile.Version.Major, 
	WGL_CONTEXT_MINOR_VERSION_ARB, profile.Version.Minor, 
	WGL_CONTEXT_FLAGS_ARB, flags,
	WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
	0  
};

HGLRC rc = CreateContextAttribsPtr((HDC)context.deviceHandle, 0, attributes);

But as I write this and look into my own code as reference I see a major mistake you do in yours


if (!wglMakeCurrent(deviceContext, newContext)) {
				PushError_Internal("[Win32] Warning: Failed activating Modern OpenGL Rendering Context for version (%llu.%llu) and DC '%x') -> Fallback to legacy context.\n", videoSettings.majorVersion, videoSettings.minorVersion, deviceContext);
				wglDeleteContext(newContext);
				newContext = nullptr;
			} else {
				// Destroy legacy rendering context
				wglMakeCurrent(nullptr, nullptr);
				wglDeleteContext(legacyRenderingContext);
				activeRenderingContext = newContext;
			}

Looking at this when I do not oversee something, you test for setting your newly created context current. Thas fine but if it is successfull you remove all context calling wglMakeCurrent(nullptr, nullptr); to delete your legacy one and dont set the newly created core context active anywhere else then.

If I dont be wrong here, this results in no active context and glew fails because any gl operation proceedes on a null-context. You should call wglMakeCurrent after you received a valid context above the line


win32State.opengl.renderingContext

in your code and it should work :)

35 minutes ago, Shaarigan said:

wglChoosePixelFormatARB should not be the problem because I do it the same way without and it works pretty well. Two options, check for GetLastError() and glGetError to be sure nothing happened in the background.

Maybe your initialisation of the attributes is a littler bit failing what I could not verify yet. I do it this way for simplicity



int32 attributes[] = 
{  
	WGL_CONTEXT_MAJOR_VERSION_ARB, profile.Version.Major, 
	WGL_CONTEXT_MINOR_VERSION_ARB, profile.Version.Minor, 
	WGL_CONTEXT_FLAGS_ARB, flags,
	WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
	0  
};

HGLRC rc = CreateContextAttribsPtr((HDC)context.deviceHandle, 0, attributes);

But as I write this and look into my own code as reference I see a major mistake you do in yours



if (!wglMakeCurrent(deviceContext, newContext)) {
				PushError_Internal("[Win32] Warning: Failed activating Modern OpenGL Rendering Context for version (%llu.%llu) and DC '%x') -> Fallback to legacy context.\n", videoSettings.majorVersion, videoSettings.minorVersion, deviceContext);
				wglDeleteContext(newContext);
				newContext = nullptr;
			} else {
				// Destroy legacy rendering context
				wglMakeCurrent(nullptr, nullptr);
				wglDeleteContext(legacyRenderingContext);
				activeRenderingContext = newContext;
			}

Looking at this when I do not oversee something, you test for setting your newly created context current. Thas fine but if it is successfull you remove all context calling wglMakeCurrent(nullptr, nullptr); to delete your legacy one and dont set the newly created core context active anywhere else then.

If I dont be wrong here, this results in no active context and glew fails because any gl operation proceedes on a null-context. You should call wglMakeCurrent after you received a valid context above the line



win32State.opengl.renderingContext

in your code and it should work :)

Thanks, that was it. Deactivating the legacy rendering context before creating the new one solved the problem!

<Place something here about wood and trees> ;)

This topic is closed to new replies.

Advertisement