#include #include #include #include #include PFNWGLGETPROCADDRESSPROC wglGetProcAddressDYN; PFNWGLCREATECONTEXTPROC wglCreateContextDYN; PFNWGLMAKECURRENTPROC wglMakeCurrentDYN; PFNSWAPBUFFERSPROC wglSwapBuffersDYN; PFNWGLDELETECONTEXTPROC wglDeleteContextDYN; PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; //============================================================================= template< typename T > void GetProc( HMODULE mod, PFNWGLGETPROCADDRESSPROC wglProcAddress, const char* name, T* out ) { *out = nullptr; if( wglProcAddress ) *out = reinterpret_cast< T >( wglProcAddress( name ) ); if( !*out ) *out = reinterpret_cast< T >( GetProcAddress( mod, name ) ); } //============================================================================= void GetExtensionFunctions( const HINSTANCE instance ) { const LPCSTR name = TEXT("dummy-window"); WNDCLASS wndclass; ZeroMemory( &wndclass, sizeof( wndclass ) ); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = DefWindowProc; wndclass.hInstance = instance; wndclass.lpszClassName = name; RegisterClass( &wndclass ); const HWND wnd = CreateWindow( name, "", WS_DISABLED, 0, 0, 1, 1, NULL, NULL, instance, NULL ); const HDC dc = GetDC( wnd ); PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof( pfd ); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.iLayerType = PFD_MAIN_PLANE; const int iPixelFormat = ChoosePixelFormat( dc, &pfd ); SetPixelFormat( dc, iPixelFormat, NULL ); const HMODULE mod = LoadLibrary( TEXT("opengl32.dll") ); GetProc( mod, NULL, "wglGetProcAddress", &wglGetProcAddressDYN ); GetProc( mod, NULL, "wglCreateContext", &wglCreateContextDYN ); GetProc( mod, NULL, "wglMakeCurrent", &wglMakeCurrentDYN ); GetProc( mod, NULL, "wglSwapBuffers", &wglSwapBuffersDYN ); GetProc( mod, NULL, "wglDeleteContext", &wglDeleteContextDYN ); const HGLRC rc = wglCreateContextDYN( dc ); wglMakeCurrentDYN( dc, rc ); GetProc( mod, wglGetProcAddressDYN, "wglGetExtensionsStringARB", &wglGetExtensionsStringARB ); GetProc( mod, wglGetProcAddressDYN, "wglChoosePixelFormatARB", &wglChoosePixelFormatARB ); GetProc( mod, wglGetProcAddressDYN, "wglCreateContextAttribsARB", &wglCreateContextAttribsARB ); FreeLibrary( mod ); wglMakeCurrentDYN( dc, NULL ); wglDeleteContextDYN( rc ); ReleaseDC( wnd, dc ); DestroyWindow( wnd ); UnregisterClass( name, instance ); } //============================================================================= int WINAPI WinMain( HINSTANCE instance, HINSTANCE prvInstance, PSTR cmdLine, int cmdShow ) { GetExtensionFunctions( instance ); const LPCSTR name = TEXT("OpenGLWindow"); WNDCLASS wndclass; ZeroMemory( &wndclass, sizeof( wndclass ) ); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = DefWindowProc; wndclass.hInstance = instance; wndclass.lpszClassName = name; RegisterClass( &wndclass ); const HWND wnd = CreateWindow( name, "", WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, NULL, NULL, instance, NULL ); const HDC dc = GetDC( wnd ); int format = 0; UINT numFormats = 0; int pixel_attributes[] = { WGL_SUPPORT_OPENGL_ARB, TRUE, WGL_DOUBLE_BUFFER_ARB, TRUE, #if 1 WGL_SWAP_METHOD_ARB, WGL_SWAP_UNDEFINED_ARB, #else WGL_SWAP_METHOD_ARB, WGL_SWAP_COPY_ARB, #endif 0 }; wglChoosePixelFormatARB( dc, pixel_attributes, NULL, 1, &format, &numFormats ); std::stringstream ss; ss << "numFormats: " << numFormats << std::endl; MessageBox( wnd, ss.str().c_str(), "Message", MB_OK ); ReleaseDC( wnd, dc ); DestroyWindow( wnd ); UnregisterClass( name, instance ); return 0; }