Jump to content
  • Advertisement
Sign in to follow this  
Finalspace

OpenGL core context creation failed horribly

This topic is 390 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;
}

 

Share this post


Link to post
Share on other sites
Advertisement

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.
 

Share this post


Link to post
Share on other sites

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 :)

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!