# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlWin32/Win32Context.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlWin32/Win32Context.hpp>
    00033 #include <vlCore/Log.hpp>
    00034
    00035 using namespace vl;
    00036 using namespace vlWin32;
    00037
    00038 //-----------------------------------------------------------------------------
    00039 Win32Context::~Win32Context()
    00040 {
    00041 }
    00042 //-----------------------------------------------------------------------------
    00043 void Win32Context::shareOpenGLResources(HGLRC hGLRC)
    00044 {
    00045   if (hwnd() && mHDC && mHGLRC)
    00046     wglShareLists(hglrc(), hGLRC);
    00047 }
    00048 //-----------------------------------------------------------------------------
    00049 void Win32Context::makeCurrent()
    00050 {
    00051   if (mHDC && mHGLRC)
    00052     wglMakeCurrent(mHDC, mHGLRC);
    00053 }
    00054 //-----------------------------------------------------------------------------
    00055 void Win32Context::update()
    00056 {
    00057   if (hwnd())
    00058     PostMessage(hwnd(), WM_PAINT, 0, 0);
    00059 }
    00060 //-----------------------------------------------------------------------------
    00061 void Win32Context::quitApplication()
    00062 {
    00063   PostQuitMessage(0);
    00064 }
    00065 //-----------------------------------------------------------------------------
    00066 void Win32Context::setMouseVisible(bool visible)
    00067 {
    00068   mMouseVisible = visible;
    00069   if (visible)
    00070     while(ShowCursor(TRUE ) <  0) {}
    00071   else
    00072     while(ShowCursor(FALSE) >= 0) {}
    00073 }
    00074 //-----------------------------------------------------------------------------
    00075 void Win32Context::setPosition(int x, int y)
    00076 {
    00077   if (hwnd())
    00078       SetWindowPos(hwnd(), 0, x, y, 0, 0, SWP_NOSIZE );
    00079 }
    00080 //-----------------------------------------------------------------------------
    00081 void Win32Context::setSize(int w, int h)
    00082 {
    00083   if (hwnd())
    00084   {
    00085     RECT windowRect = { 0, 0, w, h };
    00086     AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
    00087     // computes the actual window based on the client dimensions
    00088     int cx = windowRect.right  - windowRect.left;
    00089     int cy = windowRect.bottom - windowRect.top;
    00090     SetWindowPos(hwnd(), 0, 0, 0, cx, cy, SWP_NOMOVE );
    00091   }
    00092 }
    00093 //-----------------------------------------------------------------------------
    00094 void Win32Context::setWindowSize(int w, int h)
    00095 {
    00096   // this are set by WM_SIZE event handler
    00097   // mRenderTarget->setWidth(w);
    00098   // mRenderTarget->setHeight(h);
    00099     SetWindowPos(hwnd(), 0, 0, 0, w, h, SWP_NOMOVE);
    00100 }
    00101 //-----------------------------------------------------------------------------
    00102 vl::ivec2 Win32Context::position() const
    00103 {
    00104   RECT r = {0,0,0,0};
    00105   if (hwnd())
    00106       GetWindowRect(hwnd(), &r);
    00107   return vl::ivec2(r.left,r.top);
    00108 }
    00109 //-----------------------------------------------------------------------------
    00110 vl::ivec2 Win32Context::windowSize() const
    00111 {
    00112   RECT r = {0,0,0,0};
    00113   if (hwnd())
    00114       GetWindowRect(hwnd(), &r);
    00115   return vl::ivec2(r.right - r.left, r.bottom - r.top);
    00116 }
    00117 //-----------------------------------------------------------------------------
    00118 vl::ivec2 Win32Context::size() const
    00119 {
    00120   RECT r = {0,0,0,0};
    00121   if (hwnd())
    00122       GetClientRect(hwnd(), &r);
    00123   return vl::ivec2(r.right - r.left, r.bottom - r.top);
    00124 //  return vl::ivec2(width(), height());
    00125 }
    00126 //-----------------------------------------------------------------------------
    00127 void Win32Context::setWindowTitle(const String& title)
    00128 {
    00129   if (hwnd())
    00130     SetWindowText(hwnd(), (wchar_t*)title.ptr());
    00131 }
    00132 //-----------------------------------------------------------------------------
    00133 void Win32Context::show()
    00134 {
    00135   if (hwnd())
    00136     ShowWindow(hwnd(), SW_SHOW);
    00137 }
    00138 //-----------------------------------------------------------------------------
    00139 void Win32Context::hide()
    00140 {
    00141   if (hwnd())
    00142     ShowWindow(hwnd(), SW_HIDE);
    00143 }
    00144 //-----------------------------------------------------------------------------
    00145 void Win32Context::getFocus()
    00146 {
    00147   if (hwnd())
    00148     SetFocus(hwnd());
    00149 }
    00150 //-----------------------------------------------------------------------------
    00151 void Win32Context::setMousePosition(int x, int y)
    00152 {
    00153   if (hwnd())
    00154   {
    00155     POINT pt = {x, y};
    00156     ClientToScreen( hwnd(), &pt );
    00157     SetCursorPos(pt.x, pt.y);
    00158   }
    00159 }
    00160 //-----------------------------------------------------------------------------
    00161 void Win32Context::swapBuffers()
    00162 {
    00163   if(hwnd() && hdc())
    00164     SwapBuffers(hdc());
    00165 }
    00166 //-----------------------------------------------------------------------------
    00167 bool Win32Context::setFullscreen(bool fullscreen_on)
    00168 {
    00169   if (!hwnd())
    00170     return false;
    00171
    00172   if (fullscreen_on == fullscreen())
    00173     return true;
    00174
    00175   if (!fullscreen_on)
    00176   {
    00177     SetWindowLongPtr(hwnd(), GWL_STYLE, mNormFlags/*swl_style*/);
    00178
    00179     if (!((mNormFlags & WS_MAXIMIZE) || (mNormFlags & WS_MINIMIZE)))
    00180     {
    00181       setPosition(mNormPosit.x(),mNormPosit.y());
    00182       setSize(mNormSize.x(), mNormSize.y());
    00183     }
    00184
    00185     SetWindowPos(hwnd(), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE);
    00186
    00187     // restores display settings
    00188     ChangeDisplaySettings(NULL, 0);
    00189   }
    00190   else
    00191   {
    00192     DEVMODE devmode;
    00193     EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
    00194
    00195     // devmode.dmPelsWidth  = ... leave current width
    00196     // devmode.dmPelsHeight = ... leave current height
    00197     // change color depth
    00198     devmode.dmBitsPerPel = openglContextInfo().bitsPerPixel();
    00199       devmode.dmFields       |= DM_BITSPERPEL;
    00200
    00201     mNormFlags = (unsigned int)GetWindowLongPtr(hwnd(), GWL_STYLE);
    00202     mNormPosit = position();
    00203     mNormSize  = size();
    00204
    00205     switch( ChangeDisplaySettings(&devmode, CDS_FULLSCREEN) )
    00206     {
    00207       case DISP_CHANGE_SUCCESSFUL:
    00208       {
    00209         RECT windowRect = { 0, 0, devmode.dmPelsWidth, devmode.dmPelsHeight };
    00210         /*mStyle = */SetWindowLongPtr(hwnd(), GWL_STYLE, WS_POPUP | WS_VISIBLE );
    00211         AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
    00212         SetWindowPos(hwnd(), HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_FRAMECHANGED );
    00213         break;
    00214       }
    00215       #if(_WIN32_WINNT >= 0x0501)
    00216         case DISP_CHANGE_BADDUALVIEW:
    00217           MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADDUALVIEW", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00218           return false;
    00219       #endif
    00220       case DISP_CHANGE_BADFLAGS:
    00221         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADFLAGS", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00222         return false;
    00223       case DISP_CHANGE_BADMODE:
    00224         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADMODE", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00225         return false;
    00226       case DISP_CHANGE_BADPARAM:
    00227         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_BADPARAM", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00228         return false;
    00229       case DISP_CHANGE_FAILED:
    00230         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_FAILED", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00231         return false;
    00232       case DISP_CHANGE_NOTUPDATED:
    00233         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_NOTUPDATED", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00234         return false;
    00235       case DISP_CHANGE_RESTART:
    00236         MessageBox(NULL, L"Full-screen mode switch failed: DISP_CHANGE_RESTART", L"Win32Context::setFullscreen() error!", MB_OK | MB_ICONEXCLAMATION);
    00237         return false;
    00238       default:
    00239         return false;
    00240     }
    00241   }
    00242
    00243   mFullscreen = fullscreen_on;
    00244   update();
    00245   return true;
    00246 }
    00247 //-----------------------------------------------------------------------------
    00248 bool Win32Context::initWin32GLContext(HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
    00249 {
    00250   class InOutContract
    00251   {
    00252     Win32Context* mContext;
    00253
    00254   public:
    00255     bool mOK;
    00256
    00257     InOutContract(Win32Context* context): mContext(context), mOK(true)
    00258     {
    00259       cleanup();
    00260     }
    00261
    00262     ~InOutContract()
    00263     {
    00264       if (!mOK)
    00265         cleanup();
    00266     }
    00267
    00268     void cleanup()
    00269     {
    00270       // delete HDC
    00271       if (mContext->mHDC)
    00272       {
    00273         DeleteDC(mContext->mHDC);
    00274         mContext->mHDC = NULL;
    00275       }
    00276
    00277       // delete HGLRC
    00278       if (mContext->mHGLRC)
    00279       {
    00280         if ( wglDeleteContext(mContext->mHGLRC) == FALSE )
    00281         {
    00282           MessageBox(NULL, L"OpenGL context cleanup failed.\n"
    00283            L"The handle either doesn't specify a valid context or the context is being used by another thread.",
    00284            L"Win32Context::init() error!", MB_OK);
    00285           mOK = false;
    00286         }
    00287         mContext->mHGLRC = NULL;
    00288       }
    00289     }
    00290   } contract(this);
    00291
    00292   if (!contract.mOK)
    00293     return false;
    00294
    00295   renderTarget()->setWidth(width);
    00296   renderTarget()->setHeight(height);
    00297
    00298   if (!hwnd())
    00299   {
    00300     MessageBox(NULL, L"Cannot create OpenGL context: null HWND.", L"Win32Context::init() error!", MB_OK);
    00301     return contract.mOK = false;
    00302   }
    00303
    00304   setWindowTitle(title);
    00305
    00306   VL_CHECK(mHDC == NULL);
    00307   mHDC = ::GetDC(hwnd());
    00308   if (!mHDC)
    00309   {
    00310     MessageBox(NULL, L"Device context acquisition failed.", L"Win32Context::init() error!", MB_OK);
    00311     return contract.mOK = false;
    00312   }
    00313
    00314   int pixel_format_index = vlWin32::choosePixelFormat(fmt);
    00315   if (pixel_format_index == -1)
    00316   {
    00317     MessageBox(NULL, L"No suitable pixel fmt found.", L"Win32Context::init() error!", MB_OK);
    00318     return contract.mOK = false;
    00319   }
    00320
    00321   if (SetPixelFormat(mHDC, pixel_format_index, NULL) == FALSE)
    00322   {
    00323     MessageBox(NULL, L"Pixel fmt setup failed.", L"Win32Context::init() error!", MB_OK);
    00324     return contract.mOK = false;
    00325   }
    00326
    00327   // OpenGL rendering context creation
    00328
    00329   if (wglCreateContextAttribsARB && mContextAttribs.size() > 1)
    00330   {
    00331     // must be 0-terminated list
    00332     VL_CHECK(mContextAttribs.back() == 0);
    00333     // Creates an OpenGL 3.x / 4.x context with the specified attributes.
    00334     mHGLRC = wglCreateContextAttribsARB(mHDC, 0, &mContextAttribs[0]);
    00335   }
    00336   else
    00337   {
    00338     // Creates default OpenGL context
    00339     mHGLRC = wglCreateContext(mHDC);
    00340   }
    00341
    00342   if (!mHGLRC)
    00343   {
    00344     MessageBox(NULL, L"OpenGL rendering context creation failed.", L"Win32Context::init() error!", MB_OK);
    00345     return contract.mOK = false;
    00346   }
    00347
    00348   // init GL context and makes it current
    00349   initGLContext();
    00350
    00351   if (fmt.multisample() && !WGLEW_ARB_multisample)
    00352     vl::Log::error("WGL_ARB_multisample not supported.\n");
    00353
    00354   dispatchInitEvent();
    00355
    00356   setPosition(x, y);
    00357
    00358   setSize(width, height);
    00359
    00360   if (WGLEW_EXT_swap_control)
    00361     wglSwapIntervalEXT( fmt.vSync() ? 1 : 0 );
    00362
    00363   if (share_context)
    00364     shareOpenGLResources(share_context);
    00365
    00366   if (fmt.fullscreen())
    00367     setFullscreen(true);
    00368
    00369   return contract.mOK = true;
    00370 }
    00371 //-----------------------------------------------------------------------------
    00372 void Win32Context::setContextAttribs(const int* attribs, int size)
    00373 {
    00374   mContextAttribs.resize(size);
    00375   for(int i = 0; i < size; ++i)
    00376     mContextAttribs[ i ] = attribs[ i ];
    00377 }
    00378 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:26.
Permission is granted to use this page to write and publish articles regarding Visualization Library.