//----------------------------------------------------------------------------- bool Win32Context::initWin32GLContext(HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height) { class InOutContract { Win32Context* mContext; public: bool mOK; InOutContract(Win32Context* context): mContext(context), mOK(true) { cleanup(); } ~InOutContract() { if (!mOK) cleanup(); } void cleanup() { // delete HDC if (mContext->mHDC) { DeleteDC(mContext->mHDC); mContext->mHDC = NULL; } // delete HGLRC if (mContext->mHGLRC) { if ( wglDeleteContext(mContext->mHGLRC) == FALSE ) { MessageBox(NULL, L"OpenGL context cleanup failed.\n" L"The handle either doesn't specify a valid context or the context is being used by another thread.", L"Win32Context::init() error!", MB_OK); mOK = false; } mContext->mHGLRC = NULL; } } } contract(this); if (!contract.mOK) return false; framebuffer()->setWidth(width); framebuffer()->setHeight(height); if (!hwnd()) { MessageBox(NULL, L"Cannot create OpenGL context: null HWND.", L"Win32Context::init() error!", MB_OK); return contract.mOK = false; } setWindowTitle(title); VL_CHECK(mHDC == NULL); mHDC = ::GetDC(hwnd()); if (!mHDC) { MessageBox(NULL, L"Device context acquisition failed.", L"Win32Context::init() error!", MB_OK); return contract.mOK = false; } int pixel_format_index = vlWin32::choosePixelFormat(fmt); if (pixel_format_index == -1) { MessageBox(NULL, L"No suitable pixel fmt found.", L"Win32Context::init() error!", MB_OK); return contract.mOK = false; } if (SetPixelFormat(mHDC, pixel_format_index, NULL) == FALSE) { MessageBox(NULL, L"Pixel fmt setup failed.", L"Win32Context::init() error!", MB_OK); return contract.mOK = false; } // OpenGL rendering context creation if (wglCreateContextAttribsARB && mContextAttribs.size() > 1) { // must be 0-terminated list VL_CHECK(mContextAttribs.back() == 0); // Creates an OpenGL 3.x / 4.x context with the specified attributes. mHGLRC = wglCreateContextAttribsARB(mHDC, 0, &mContextAttribs[0]); } else { // Creates default OpenGL context mHGLRC = wglCreateContext(mHDC); } if (!mHGLRC) { MessageBox(NULL, L"OpenGL rendering context creation failed.", L"Win32Context::init() error!", MB_OK); return contract.mOK = false; } // init GL context and makes it current // mic fixme: check this also on all the other GUI bindings. if( !initGLContext() ) return contract.mOK = false; if (fmt.multisample() && !Has_GL_ARB_multisample) vl::Log::error("WGL_ARB_multisample not supported.\n"); dispatchInitEvent(); setPosition(x, y); setSize(width, height); if (Has_GL_EXT_swap_control) wglSwapIntervalEXT( fmt.vSync() ? 1 : 0 ); if (share_context) shareOpenGLResources(share_context); if (fmt.fullscreen()) setFullscreen(true); return contract.mOK = true; }
//----------------------------------------------------------------------------- bool SDLWindow::initSDLWindow(const vl::String& title, const vl::OpenGLContextFormat& info, int x, int y, int width, int height) { if (mScreen || mSDLWindow) { vl::Log::error("SDL supports only one window at a time.\n"); VL_TRAP(); return false; } framebuffer()->setWidth(width); framebuffer()->setHeight(height); mSDLWindow = this; // init key translation map for(int i=0; key_translation_vec[i]; i+=2) key_translation_map[ key_translation_vec[i] ] = (vl::EKey)key_translation_vec[i+1]; // SDL_VIDEO_WINDOW_POS char win_pos[32] = {0}; sprintf ( win_pos, "SDL_VIDEO_WINDOW_POS=%d,%d", x, y ); SDL_putenv(win_pos); // setenv("SDL_VIDEO_CENTERED", "YES", 0); // init SDL if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { printf("Unable to init SDL: %s\n", SDL_GetError()); return false; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, info.rgbaBits().r()); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, info.rgbaBits().g()); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, info.rgbaBits().b()); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, info.rgbaBits().a()); SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, info.accumRGBABits().r()); SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, info.accumRGBABits().g()); SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, info.accumRGBABits().b()); SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, info.accumRGBABits().a()); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, info.depthBufferBits()); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, info.stencilBufferBits()); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, info.doubleBuffer()?1:0); SDL_GL_SetAttribute(SDL_GL_STEREO, info.stereo()); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, info.multisample()?1:0); if (info.multisample()) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info.multisampleSamples()); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, info.vSync()); int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel; Uint32 flags = SDL_OPENGL | (info.fullscreen() ? SDL_FULLSCREEN : 0); width = width !=0 ? width : SDL_GetVideoInfo()->current_w; height = height !=0 ? height : SDL_GetVideoInfo()->current_h; mScreen = SDL_SetVideoMode( width, height, bpp, flags ); if (mScreen == 0) { vl::Log::print( vl::Say("\n error: SDL_SetVideoMode(%n, %n, %n, %hn) failed: %s\n") << width << height << bpp << flags << SDL_GetError() ); exit(1); } // window size problem int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); VL_CHECK(viewport[0] == 0); VL_CHECK(viewport[1] == 0); if (viewport[2] != mScreen->w || viewport[3] != mScreen->h) { vl::Log::print( vl::Say("\n warning: OpenGL reported %nx%n as video size but SDL says %nx%n\n") << viewport[2] << viewport[3] << mScreen->w << mScreen->h ); VL_TRAP() }