/* Passing a NULL path means load pointers from the application */ int WIN_GL_LoadLibrary(_THIS, const char* path) { HMODULE handle; if ( gl_active ) { SDL_SetError("OpenGL context already created"); return -1; } if ( path == NULL ) { path = DEFAULT_GL_DRIVER_PATH; } handle = LoadLibrary(path); if ( handle == NULL ) { SDL_SetError("Could not load OpenGL library"); return -1; } /* Unload the old driver and reset the pointers */ WIN_GL_UnloadLibrary(this); /* Load new function pointers */ SDL_memset(this->gl_data, 0, sizeof(*this->gl_data)); this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *)) GetProcAddress(handle, "wglGetProcAddress"); this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) GetProcAddress(handle, "wglCreateContext"); this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC)) GetProcAddress(handle, "wglDeleteContext"); this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC)) GetProcAddress(handle, "wglMakeCurrent"); this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int)) GetProcAddress(handle, "wglSwapIntervalEXT"); this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void)) GetProcAddress(handle, "wglGetSwapIntervalEXT"); if ( (this->gl_data->wglGetProcAddress == NULL) || (this->gl_data->wglCreateContext == NULL) || (this->gl_data->wglDeleteContext == NULL) || (this->gl_data->wglMakeCurrent == NULL) ) { SDL_SetError("Could not retrieve OpenGL functions"); FreeLibrary(handle); return -1; } this->gl_config.dll_handle = handle; SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path)); this->gl_config.driver_loaded = 1; return 0; }
void WIN_GL_ShutDown(_THIS) { #if SDL_VIDEO_OPENGL /* Clean up OpenGL */ if ( GL_hrc ) { this->gl_data->wglMakeCurrent(NULL, NULL); this->gl_data->wglDeleteContext(GL_hrc); GL_hrc = NULL; } if ( GL_hdc ) { ReleaseDC(SDL_Window, GL_hdc); GL_hdc = NULL; } gl_active = 0; WIN_GL_UnloadLibrary(this); #endif /* SDL_VIDEO_OPENGL */ }
SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window) { HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; HGLRC context, share_context; if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile) { #if SDL_VIDEO_OPENGL_EGL /* Switch to EGL based functions */ WIN_GL_UnloadLibrary(_this); _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; _this->GL_GetProcAddress = WIN_GLES_GetProcAddress; _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; _this->GL_CreateContext = WIN_GLES_CreateContext; _this->GL_MakeCurrent = WIN_GLES_MakeCurrent; _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; _this->GL_SwapWindow = WIN_GLES_SwapWindow; _this->GL_DeleteContext = WIN_GLES_DeleteContext; if (WIN_GLES_LoadLibrary(_this, NULL) != 0) { return NULL; } return WIN_GLES_CreateContext(_this, window); #else SDL_SetError("SDL not configured with EGL support"); return NULL; #endif } if (_this->gl_config.share_with_current_context) { share_context = (HGLRC)SDL_GL_GetCurrentContext(); } else { share_context = 0; } if (_this->gl_config.major_version < 3 && _this->gl_config.profile_mask == 0 && _this->gl_config.flags == 0) { /* Create legacy context */ context = _this->gl_data->wglCreateContext(hdc); if( share_context != 0 ) { _this->gl_data->wglShareLists(share_context, context); } } else { PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; HGLRC temp_context = _this->gl_data->wglCreateContext(hdc); if (!temp_context) { SDL_SetError("Could not create GL context"); return NULL; } /* Make the context current */ if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) { WIN_GL_DeleteContext(_this, temp_context); return NULL; } wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data-> wglGetProcAddress("wglCreateContextAttribsARB"); if (!wglCreateContextAttribsARB) { SDL_SetError("GL 3.x is not supported"); context = temp_context; } else { /* max 10 attributes plus terminator */ int attribs[11] = { WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, 0 }; int iattr = 4; /* SDL profile bits match WGL profile bits */ if (_this->gl_config.profile_mask != 0) { attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB; attribs[iattr++] = _this->gl_config.profile_mask; } /* SDL flags match WGL flags */ if (_this->gl_config.flags != 0) { attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB; attribs[iattr++] = _this->gl_config.flags; } /* only set if wgl extension is available */ if (_this->gl_data->HAS_WGL_ARB_context_flush_control) { attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB; attribs[iattr++] = _this->gl_config.release_behavior ? WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; } attribs[iattr++] = 0; /* Create the GL 3.x context */ context = wglCreateContextAttribsARB(hdc, share_context, attribs); /* Delete the GL 2.x context */ _this->gl_data->wglDeleteContext(temp_context); } } if (!context) { WIN_SetError("Could not create GL context"); return NULL; } if (WIN_GL_MakeCurrent(_this, window, context) < 0) { WIN_GL_DeleteContext(_this, context); return NULL; } return context; }