vtkWin32OpenGLRenderWindow.cxx 40.2 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3
/*=========================================================================

Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
Module:    vtkWin32OpenGLRenderWindow.cxx
Ken Martin's avatar
Ken Martin committed
5 6 7 8 9 10 11 12 13 14

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkWin32OpenGLRenderWindow.h"
Ken Martin's avatar
Ken Martin committed
16 17 18

#include "vtkIdList.h"
#include "vtkCommand.h"
19
#include "vtkNew.h"
Ken Martin's avatar
Ken Martin committed
20
#include "vtkObjectFactory.h"
21 22
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLRenderWindow.h"
Ken Martin's avatar
Ken Martin committed
23
#include "vtkOpenGLError.h"
24
#include "vtkOpenGLShaderCache.h"
Ken Martin's avatar
Ken Martin committed
25
#include "vtkRendererCollection.h"
26
#include "vtkStringOutputWindow.h"
27
#include "vtkWin32RenderWindowInteractor.h"
Ken Martin's avatar
Ken Martin committed
28

29
#include <cmath>
30
#include <sstream>
Ken Martin's avatar
Ken Martin committed
31 32 33

#include "vtkOpenGLError.h"

34 35 36 37 38 39 40
// Mouse wheel support
// In an ideal world we would just have to include <zmouse.h>, but it is not
// always available with all compilers/headers
#ifndef WM_MOUSEWHEEL
#  define WM_MOUSEWHEEL                   0x020A
#endif  //WM_MOUSEWHEEL

Ken Martin's avatar
Ken Martin committed
41
vtkStandardNewMacro(vtkWin32OpenGLRenderWindow);
Ken Martin's avatar
Ken Martin committed
42

Ken Martin's avatar
Ken Martin committed
43
vtkWin32OpenGLRenderWindow::vtkWin32OpenGLRenderWindow()
Ken Martin's avatar
Ken Martin committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
{
  this->ApplicationInstance =  NULL;
  this->Palette = NULL;
  this->ContextId = 0;
  this->WindowId = 0;
  this->ParentId = 0;
  this->NextWindowId = 0;
  this->DeviceContext = (HDC)0;         // hsr
  this->MFChandledWindow = FALSE;       // hsr
  this->StereoType = VTK_STEREO_CRYSTAL_EYES;
  this->CursorHidden = 0;
  this->Capabilities = 0;

  this->CreatingOffScreenWindow = 0;
  this->WindowIdReferenceCount = 0;
}

Ken Martin's avatar
Ken Martin committed
61
vtkWin32OpenGLRenderWindow::~vtkWin32OpenGLRenderWindow()
Ken Martin's avatar
Ken Martin committed
62 63 64 65 66 67 68
{
  this->Finalize();

  vtkRenderer *ren;
  vtkCollectionSimpleIterator rit;
  this->Renderers->InitTraversal(rit);
  while ( (ren = this->Renderers->GetNextRenderer(rit)) )
69
  {
Ken Martin's avatar
Ken Martin committed
70
    ren->SetRenderWindow(NULL);
71
  }
Ken Martin's avatar
Ken Martin committed
72 73 74 75

  delete[] this->Capabilities;
}

Ken Martin's avatar
Ken Martin committed
76
void vtkWin32OpenGLRenderWindow::Clean()
Ken Martin's avatar
Ken Martin committed
77 78 79
{
  /* finish OpenGL rendering */
  if (this->OwnContext && this->ContextId)
80
  {
Ken Martin's avatar
Ken Martin committed
81 82 83 84 85 86 87 88
    this->MakeCurrent();
    this->CleanUpRenderers();

    // Note: wglMakeCurrent(NULL,NULL) is valid according to the documentation
    // and works with nVidia and ATI but not with Intel. Passing an existing
    // device context works in any case.
    // see VTK Bug 7119.
    if(wglMakeCurrent(this->DeviceContext,NULL)!=TRUE)
89
    {
Ken Martin's avatar
Ken Martin committed
90
      vtkErrorMacro("wglMakeCurrent failed in Clean(), error: " << GetLastError());
91
    }
Ken Martin's avatar
Ken Martin committed
92
    if (wglDeleteContext(this->ContextId) != TRUE)
93
    {
Ken Martin's avatar
Ken Martin committed
94 95
      vtkErrorMacro("wglDeleteContext failed in Clean(), error: " << GetLastError());
    }
96
  }
Ken Martin's avatar
Ken Martin committed
97 98 99
  this->ContextId = NULL;

  if (this->Palette)
100
  {
Ken Martin's avatar
Ken Martin committed
101 102 103
    SelectPalette(this->DeviceContext, this->OldPalette, FALSE); // SVA delete the old palette
    DeleteObject(this->Palette);
    this->Palette = NULL;
104
  }
Ken Martin's avatar
Ken Martin committed
105 106
}

Ken Martin's avatar
Ken Martin committed
107
void vtkWin32OpenGLRenderWindow::CleanUpRenderers()
Ken Martin's avatar
Ken Martin committed
108 109 110 111
{
  // tell each of the renderers that this render window/graphics context
  // is being removed (the RendererCollection is removed by vtkRenderWindow's
  // destructor)
112
  this->ReleaseGraphicsResources(this);
Ken Martin's avatar
Ken Martin committed
113 114
}

Ken Martin's avatar
Ken Martin committed
115
LRESULT APIENTRY vtkWin32OpenGLRenderWindow::WndProc(HWND hWnd, UINT message,
Ken Martin's avatar
Ken Martin committed
116 117 118 119 120
                                                     WPARAM wParam,
                                                     LPARAM lParam)
{
  LRESULT res;

Ken Martin's avatar
Ken Martin committed
121 122
  vtkWin32OpenGLRenderWindow *me =
    (vtkWin32OpenGLRenderWindow *)vtkGetWindowLong(hWnd,sizeof(vtkLONG));
Ken Martin's avatar
Ken Martin committed
123 124

  if (me && me->GetReferenceCount()>0)
125
  {
Ken Martin's avatar
Ken Martin committed
126 127 128
    me->Register(me);
    res = me->MessageProc(hWnd, message, wParam, lParam);
    me->UnRegister(me);
129
  }
Ken Martin's avatar
Ken Martin committed
130
  else
131
  {
Ken Martin's avatar
Ken Martin committed
132
    res = DefWindowProc(hWnd, message, wParam, lParam);
133
  }
Ken Martin's avatar
Ken Martin committed
134 135 136 137

  return res;
}

Ken Martin's avatar
Ken Martin committed
138
void vtkWin32OpenGLRenderWindow::SetWindowName( const char * _arg )
Ken Martin's avatar
Ken Martin committed
139 140 141
{
  vtkWindow::SetWindowName(_arg);
  if (this->WindowId)
142
  {
Ken Martin's avatar
Ken Martin committed
143 144 145 146 147 148 149 150
#ifdef UNICODE
    wchar_t *wname = new wchar_t [mbstowcs(NULL, this->WindowName, 32000)+1];
    mbstowcs(wname, this->WindowName, 32000);
    SetWindowText(this->WindowId, wname);
    delete [] wname;
#else
    SetWindowText(this->WindowId, this->WindowName);
#endif
151
  }
Ken Martin's avatar
Ken Martin committed
152 153
}

Ken Martin's avatar
Ken Martin committed
154
int vtkWin32OpenGLRenderWindow::GetEventPending()
Ken Martin's avatar
Ken Martin committed
155 156 157
{
  MSG msg;
  if (PeekMessage(&msg,this->WindowId,WM_MOUSEFIRST,WM_MOUSELAST,PM_NOREMOVE))
158
  {
Ken Martin's avatar
Ken Martin committed
159
    if (msg.message == WM_MOUSEMOVE)
160
    {
Ken Martin's avatar
Ken Martin committed
161
      PeekMessage(&msg,this->WindowId,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE);
162
    }
Ken Martin's avatar
Ken Martin committed
163 164
    if ((msg.message == WM_LBUTTONDOWN) ||
        (msg.message == WM_RBUTTONDOWN) ||
165 166
        (msg.message == WM_MBUTTONDOWN) ||
        (msg.message == WM_MOUSEWHEEL))
167
    {
Ken Martin's avatar
Ken Martin committed
168 169
      return 1;
    }
170
  }
Ken Martin's avatar
Ken Martin committed
171 172 173 174 175

  return 0;
}

// ----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
176
bool vtkWin32OpenGLRenderWindow::InitializeFromCurrentContext()
Ken Martin's avatar
Ken Martin committed
177 178 179
{
  HGLRC currentContext = wglGetCurrentContext();
  if (currentContext != NULL)
180
  {
Ken Martin's avatar
Ken Martin committed
181 182 183 184 185 186
    this->SetWindowId(WindowFromDC(wglGetCurrentDC()));
    this->SetDeviceContext(wglGetCurrentDC());
    this->SetContextId(currentContext);
    this->OpenGLInit();
    this->OwnContext = 0;
    return true;
187
  }
Ken Martin's avatar
Ken Martin committed
188 189 190 191
  return false;
}

// ----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
192
void vtkWin32OpenGLRenderWindow::MakeCurrent()
Ken Martin's avatar
Ken Martin committed
193 194 195 196
{
  // Try to avoid doing anything (for performance).
  HGLRC current = wglGetCurrentContext();
  if (this->ContextId != current)
197
  {
Ken Martin's avatar
Ken Martin committed
198
    if(this->IsPicking && current)
199
    {
Ken Martin's avatar
Ken Martin committed
200 201 202
      vtkErrorMacro("Attempting to call MakeCurrent for a different window"
                    " than the one doing the picking, this can causes crashes"
                    " and/or bad pick results");
203
    }
Ken Martin's avatar
Ken Martin committed
204
    else
205
    {
Ken Martin's avatar
Ken Martin committed
206
      if (wglMakeCurrent(this->DeviceContext, this->ContextId) != TRUE)
207
      {
Ken Martin's avatar
Ken Martin committed
208 209 210 211 212 213 214 215 216 217 218 219 220
        LPVOID lpMsgBuf;
        ::FormatMessage(
          FORMAT_MESSAGE_ALLOCATE_BUFFER |
          FORMAT_MESSAGE_FROM_SYSTEM |
          FORMAT_MESSAGE_IGNORE_INSERTS,
          NULL,
          GetLastError(),
          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
          (LPTSTR) &lpMsgBuf,
          0,
          NULL
          );
        if(lpMsgBuf)
221
        {
Ken Martin's avatar
Ken Martin committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
#ifdef UNICODE
          wchar_t *wmsg = new wchar_t [mbstowcs(NULL, (const char*)lpMsgBuf, 32000)+1];
          wchar_t *wtemp = new wchar_t [mbstowcs(NULL, "wglMakeCurrent failed in MakeCurrent(), error: ", 32000)+1];
          mbstowcs(wmsg, (const char*)lpMsgBuf, 32000);
          mbstowcs(wtemp, "wglMakeCurrent failed in MakeCurrent(), error: ", 32000);
          vtkErrorMacro(<< wcscat(wtemp, wmsg));
          delete [] wmsg;
          delete [] wtemp;
#else
          vtkErrorMacro("wglMakeCurrent failed in MakeCurrent(), error: "
                        << (LPCTSTR)lpMsgBuf);
#endif
          ::LocalFree( lpMsgBuf );
        }
      }
    }
238
  }
Ken Martin's avatar
Ken Martin committed
239 240
}

241 242 243 244 245 246
void vtkWin32OpenGLRenderWindow::PushContext()
{
  HGLRC current = wglGetCurrentContext();
  this->ContextStack.push(current);
  this->DCStack.push(wglGetCurrentDC());
  if (current != this->ContextId)
247
  {
248
    this->MakeCurrent();
249
  }
250 251 252 253 254 255 256 257 258 259
}

void vtkWin32OpenGLRenderWindow::PopContext()
{
  HGLRC current = wglGetCurrentContext();
  HGLRC target = this->ContextStack.top();
  HDC dc = this->DCStack.top();
  this->ContextStack.pop();
  this->DCStack.pop();
  if (target != current)
260
  {
261
    wglMakeCurrent(dc, target);
262
  }
263 264
}

Ken Martin's avatar
Ken Martin committed
265 266 267
// ----------------------------------------------------------------------------
// Description:
// Tells if this window is the current OpenGL context for the calling thread.
Ken Martin's avatar
Ken Martin committed
268
bool vtkWin32OpenGLRenderWindow::IsCurrent()
Ken Martin's avatar
Ken Martin committed
269 270 271 272
{
  return this->ContextId!=0 && this->ContextId==wglGetCurrentContext();
}

273
// ----------------------------------------------------------------------------
274
void AdjustWindowRectForBorders(HWND hwnd, DWORD style, const int x, const int y,
275 276
                                const int width, const int height, RECT &r)
{
277
  if (!style && hwnd)
278
  {
279
    style = GetWindowLong(hwnd, GWL_STYLE);
280
  }
281 282 283 284 285 286
  r.left = x;
  r.top = y;
  r.right = r.left + width;
  r.bottom = r.top + height;
  BOOL result = AdjustWindowRect(&r, style, FALSE);
  if (!result)
287
  {
288 289
    vtkGenericWarningMacro("AdjustWindowRect failed, error: "
      << GetLastError());
290
  }
291 292
}

Ken Martin's avatar
Ken Martin committed
293
// ----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
294
void vtkWin32OpenGLRenderWindow::SetSize(int x, int y)
Ken Martin's avatar
Ken Martin committed
295 296 297
{
  static int resizing = 0;
  if ((this->Size[0] != x) || (this->Size[1] != y))
298
  {
299
    this->Superclass::SetSize(x, y);
Ken Martin's avatar
Ken Martin committed
300 301

    if (this->Interactor)
302
    {
Ken Martin's avatar
Ken Martin committed
303
      this->Interactor->SetSize(x, y);
304
    }
Ken Martin's avatar
Ken Martin committed
305 306

    if (this->OffScreenRendering)
307
    {
Ken Martin's avatar
Ken Martin committed
308
      if(!this->CreatingOffScreenWindow)
309
      {
Ken Martin's avatar
Ken Martin committed
310
        if (!resizing)
311
        {
Ken Martin's avatar
Ken Martin committed
312 313 314 315 316 317
          resizing = 1;
          this->CleanUpOffScreenRendering();
          this->CreateOffScreenWindow(x,y);
          resizing = 0;
        }
      }
318
    }
Ken Martin's avatar
Ken Martin committed
319 320

    else if (this->Mapped)
321
    {
Ken Martin's avatar
Ken Martin committed
322
      if (!resizing)
323
      {
Ken Martin's avatar
Ken Martin committed
324 325 326
        resizing = 1;

        if (this->ParentId)
327
        {
328 329 330
          SetWindowExtEx(this->DeviceContext, x, y, NULL);
          SetViewportExtEx(this->DeviceContext, x, y, NULL);
          SetWindowPos(this->WindowId, HWND_TOP, 0, 0,
Ken Martin's avatar
Ken Martin committed
331
                       x, y, SWP_NOMOVE | SWP_NOZORDER);
332
        }
Ken Martin's avatar
Ken Martin committed
333
        else
334
        {
335
          RECT r;
336
          AdjustWindowRectForBorders(this->WindowId, 0, 0, 0, x, y, r);
337 338 339
          SetWindowPos(this->WindowId, HWND_TOP, 0, 0,
                       r.right - r.left,
                       r.bottom - r.top,
Ken Martin's avatar
Ken Martin committed
340 341
                       SWP_NOMOVE | SWP_NOZORDER);
        }
342
        resizing = 0;
Ken Martin's avatar
Ken Martin committed
343 344
      }
    }
345
  }
Ken Martin's avatar
Ken Martin committed
346 347
}

Ken Martin's avatar
Ken Martin committed
348
void vtkWin32OpenGLRenderWindow::SetPosition(int x, int y)
Ken Martin's avatar
Ken Martin committed
349 350 351 352
{
  static int resizing = 0;

  if ((this->Position[0] != x) || (this->Position[1] != y))
353
  {
Ken Martin's avatar
Ken Martin committed
354 355 356 357
    this->Modified();
    this->Position[0] = x;
    this->Position[1] = y;
    if (this->Mapped)
358
    {
Ken Martin's avatar
Ken Martin committed
359
      if (!resizing)
360
      {
Ken Martin's avatar
Ken Martin committed
361 362 363 364 365 366 367
        resizing = 1;

        SetWindowPos(this->WindowId,HWND_TOP,x,y,
                     0, 0, SWP_NOSIZE | SWP_NOZORDER);
        resizing = 0;
      }
    }
368
  }
Ken Martin's avatar
Ken Martin committed
369 370 371 372
}


// End the rendering process and display the image.
Ken Martin's avatar
Ken Martin committed
373
void vtkWin32OpenGLRenderWindow::Frame(void)
Ken Martin's avatar
Ken Martin committed
374 375 376
{
  this->MakeCurrent();
  if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers)
377
  {
Ken Martin's avatar
Ken Martin committed
378 379
    // If this check is not enforced, we crash in offscreen rendering
    if (this->DeviceContext)
380
    {
Ken Martin's avatar
Ken Martin committed
381 382 383 384 385
      // use global scope to get Win32 API SwapBuffers and not be
      // confused with this->SwapBuffers
      ::SwapBuffers(this->DeviceContext);
      vtkDebugMacro(<< " SwapBuffers\n");
    }
386
  }
Ken Martin's avatar
Ken Martin committed
387 388
}

389 390 391 392 393 394 395 396 397
void vtkWin32OpenGLRenderWindow::VTKRegisterClass()
{
  // has the class been registered ?
  WNDCLASS wndClass;
#ifdef UNICODE
  if (!GetClassInfo(this->ApplicationInstance,L"vtkOpenGL",&wndClass))
#else
  if (!GetClassInfo(this->ApplicationInstance,"vtkOpenGL",&wndClass))
#endif
398
  {
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
    wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
    wndClass.lpfnWndProc = vtkWin32OpenGLRenderWindow::WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.hInstance = this->ApplicationInstance;
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndClass.lpszMenuName = NULL;
#ifdef UNICODE
    wndClass.lpszClassName = L"vtkOpenGL";
#else
    wndClass.lpszClassName = "vtkOpenGL";
#endif
    // vtk doesn't use the first extra vtkLONG's worth of bytes,
    // but app writers may want them, so we provide them. VTK
    // does use the second vtkLONG's worth of bytes of extra space.
    wndClass.cbWndExtra = 2 * sizeof(vtkLONG);
    RegisterClass(&wndClass);
417
  }
418 419
}

Ken Martin's avatar
Ken Martin committed
420
int vtkWin32OpenGLRenderWindow::IsDirect()
Ken Martin's avatar
Ken Martin committed
421
{
422
  this->MakeCurrent();
Ken Martin's avatar
Ken Martin committed
423
  if (!this->DeviceContext)
424
  {
Ken Martin's avatar
Ken Martin committed
425
    return 0;
426
  }
Ken Martin's avatar
Ken Martin committed
427 428 429 430 431 432 433 434 435 436 437 438

  int pixelFormat = GetPixelFormat(this->DeviceContext);
  PIXELFORMATDESCRIPTOR pfd;

  DescribePixelFormat(this->DeviceContext, pixelFormat,
                      sizeof(PIXELFORMATDESCRIPTOR), &pfd);

  return (pfd.dwFlags & PFD_GENERIC_FORMAT) ? 0:1;

}


Ken Martin's avatar
Ken Martin committed
439
const char* vtkWin32OpenGLRenderWindow::ReportCapabilities()
Ken Martin's avatar
Ken Martin committed
440
{
441
  this->MakeCurrent();
Ken Martin's avatar
Ken Martin committed
442 443

  if (!this->DeviceContext)
444
  {
Ken Martin's avatar
Ken Martin committed
445
    return "no device context";
446
  }
Ken Martin's avatar
Ken Martin committed
447 448 449 450 451 452 453 454 455 456 457

  int pixelFormat = GetPixelFormat(this->DeviceContext);
  PIXELFORMATDESCRIPTOR pfd;

  DescribePixelFormat(this->DeviceContext, pixelFormat,
                      sizeof(PIXELFORMATDESCRIPTOR), &pfd);

  const char *glVendor = (const char *) glGetString(GL_VENDOR);
  const char *glRenderer = (const char *) glGetString(GL_RENDERER);
  const char *glVersion = (const char *) glGetString(GL_VERSION);

458 459 460 461 462 463 464 465
std::ostringstream strm;
  if(glVendor)
    strm << "OpenGL vendor string:  " << glVendor << endl;
  if(glRenderer)
    strm << "OpenGL renderer string:  " << glRenderer << endl;
  if(glVersion)
    strm << "OpenGL version string:  " << glVersion << endl;

466 467 468 469
  strm << "OpenGL extensions:  " << endl;
  GLint n, i;
  glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  for (i = 0; i < n; i++)
470
  {
471 472
    const char *ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
    strm << "  " << ext << endl;
473
  }
Ken Martin's avatar
Ken Martin committed
474 475 476
  strm << "PixelFormat Descriptor:" << endl;
  strm << "depth:  " << static_cast<int>(pfd.cDepthBits) << endl;
  if (pfd.cColorBits <= 8)
477
  {
Ken Martin's avatar
Ken Martin committed
478
    strm << "class:  PseudoColor" << endl;
479
  }
Ken Martin's avatar
Ken Martin committed
480
  else
481
  {
Ken Martin's avatar
Ken Martin committed
482
    strm << "class:  TrueColor" << endl;
483
  }
Ken Martin's avatar
Ken Martin committed
484 485 486
  strm << "buffer size:  " << static_cast<int>(pfd.cColorBits) << endl;
  strm << "level:  " << static_cast<int>(pfd.bReserved) << endl;
  if (pfd.iPixelType == PFD_TYPE_RGBA)
487
  {
Ken Martin's avatar
Ken Martin committed
488
    strm << "renderType:  rgba" << endl;
489
  }
Ken Martin's avatar
Ken Martin committed
490
  else
491
  {
Ken Martin's avatar
Ken Martin committed
492
    strm <<"renderType:  ci" << endl;
493
  }
Ken Martin's avatar
Ken Martin committed
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
  if (pfd.dwFlags & PFD_DOUBLEBUFFER) {
  strm << "double buffer:  True" << endl;
  } else {
  strm << "double buffer:  False" << endl;
  }
  if (pfd.dwFlags & PFD_STEREO) {
  strm << "stereo:  True" << endl;
  } else {
  strm << "stereo:  False" << endl;
  }
  if (pfd.dwFlags & PFD_GENERIC_FORMAT) {
  strm << "hardware acceleration:  False" << endl;
  } else {
  strm << "hardware acceleration:  True" << endl;
  }
  strm << "rgba:  redSize=" << static_cast<int>(pfd.cRedBits) << " greenSize=" << static_cast<int>(pfd.cGreenBits) << "blueSize=" << static_cast<int>(pfd.cBlueBits) << "alphaSize=" << static_cast<int>(pfd.cAlphaBits) << endl;
  strm << "aux buffers:  " << static_cast<int>(pfd.cAuxBuffers)<< endl;
  strm << "depth size:  " << static_cast<int>(pfd.cDepthBits) << endl;
  strm << "stencil size:  " << static_cast<int>(pfd.cStencilBits) << endl;
  strm << "accum:  redSize=" << static_cast<int>(pfd.cAccumRedBits) << " greenSize=" << static_cast<int>(pfd.cAccumGreenBits) << "blueSize=" << static_cast<int>(pfd.cAccumBlueBits) << "alphaSize=" << static_cast<int>(pfd.cAccumAlphaBits) << endl;

  delete[] this->Capabilities;

  size_t len = strm.str().length() + 1;
  this->Capabilities = new char[len];
  strncpy(this->Capabilities, strm.str().c_str(), len);

  return this->Capabilities;
}

typedef bool (APIENTRY *wglChoosePixelFormatARBType)(HDC, const int*, const float*, unsigned int, int*, unsigned int*);

Ken Martin's avatar
Ken Martin committed
526 527 528 529
void vtkWin32OpenGLRenderWindow::SetupPixelFormatPaletteAndContext(
  HDC hDC, DWORD dwFlags,
  int debug, int bpp,
  int zbpp)
Ken Martin's avatar
Ken Martin committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
{
  // Create a dummy window, needed for calling wglGetProcAddress.
#ifdef UNICODE
  HWND tempId = CreateWindow(L"vtkOpenGL", 0, 0, 0, 0, 1, 1, 0, 0, this->ApplicationInstance, 0);
#else
  HWND tempId = CreateWindow("vtkOpenGL", 0, 0, 0, 0, 1, 1, 0, 0, this->ApplicationInstance, 0);
#endif
  HDC tempDC = GetDC(tempId);
  PIXELFORMATDESCRIPTOR tempPfd;
  memset(&tempPfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
  tempPfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  tempPfd.nVersion = 1;
  tempPfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
  tempPfd.iPixelType = PFD_TYPE_RGBA;
  int tempPixelFormat = ChoosePixelFormat(tempDC, &tempPfd);
545
  SetPixelFormat(tempDC, tempPixelFormat, &tempPfd);
Ken Martin's avatar
Ken Martin committed
546
  HGLRC tempContext = wglCreateContext(tempDC);
547
  if (!wglMakeCurrent(tempDC, tempContext))
548
  {
549
    vtkErrorMacro("failed to create temporary windows OpenGL context with errror: " << GetLastError());
550
  }
Ken Martin's avatar
Ken Martin committed
551

Ken Martin's avatar
Ken Martin committed
552 553 554
  // make sure glew is initialized with fake window
  this->OpenGLInit();

Ken Martin's avatar
Ken Martin committed
555 556
  // First we try to use the newer wglChoosePixelFormatARB which enables
  // features like multisamples.
557
  PIXELFORMATDESCRIPTOR pfd;
Ken Martin's avatar
Ken Martin committed
558
  int pixelFormat = 0;
559
  if (wglChoosePixelFormatARB)
560
  {
Ken Martin's avatar
Ken Martin committed
561
    int attrib[] = {
Ken Martin's avatar
Ken Martin committed
562 563 564 565 566 567 568
      WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
      WGL_SUPPORT_OPENGL_ARB, TRUE,
      WGL_DRAW_TO_WINDOW_ARB, TRUE,
      WGL_DOUBLE_BUFFER_ARB, TRUE,
      WGL_COLOR_BITS_ARB, bpp/4*3,
      WGL_DEPTH_BITS_ARB, zbpp/4*3,
      WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
Ken Martin's avatar
Ken Martin committed
569 570 571
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    unsigned int n = 14;
    if (this->AlphaBitPlanes)
572
    {
Ken Martin's avatar
Ken Martin committed
573
      attrib[n] = WGL_ALPHA_BITS_ARB;
Ken Martin's avatar
Ken Martin committed
574 575
      attrib[n+1] = bpp/4;
      n += 2;
576
    }
Ken Martin's avatar
Ken Martin committed
577
    if (this->StencilCapable)
578
    {
Ken Martin's avatar
Ken Martin committed
579
      attrib[n] = WGL_STENCIL_BITS_ARB;
Ken Martin's avatar
Ken Martin committed
580 581
      attrib[n+1] = 8;
      n += 2;
582
    }
583
    unsigned int stereoAttributeIndex = 0;
Ken Martin's avatar
Ken Martin committed
584
    if (dwFlags & PFD_STEREO)
585
    {
Ken Martin's avatar
Ken Martin committed
586
      attrib[n] = WGL_STEREO_ARB;
Ken Martin's avatar
Ken Martin committed
587
      attrib[n+1] = TRUE;
588
      stereoAttributeIndex = n+1;
Ken Martin's avatar
Ken Martin committed
589
      n += 2;
590
    }
Ken Martin's avatar
Ken Martin committed
591
    unsigned int multiSampleAttributeIndex = 0;
592
    unsigned int multiSampleBuffersIndex = 0;
593 594
    if (this->MultiSamples > 1 &&
        wglewIsSupported("WGL_ARB_multisample"))
595
    {
Ken Martin's avatar
Ken Martin committed
596
      attrib[n] = WGL_SAMPLE_BUFFERS_ARB;
Ken Martin's avatar
Ken Martin committed
597
      attrib[n+1] = 1;
Ken Martin's avatar
Ken Martin committed
598
      attrib[n+2] = WGL_SAMPLES_ARB;
Ken Martin's avatar
Ken Martin committed
599
      attrib[n+3] = this->MultiSamples;
600
      multiSampleBuffersIndex = n+1;
Ken Martin's avatar
Ken Martin committed
601 602
      multiSampleAttributeIndex = n+3;
      n += 4;
603
    }
Ken Martin's avatar
Ken Martin committed
604
    unsigned int numFormats;
605 606
    if (!wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats)
      || numFormats == 0)
607
    {
608 609 610
      // if we are trying for stereo and multisamples
      // then drop stereo first if we cannot get a context
      if (stereoAttributeIndex && multiSampleAttributeIndex)
611
      {
612 613 614 615 616 617 618
        attrib[stereoAttributeIndex] = FALSE;
        wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats);
      }
      // Next try dropping multisamples if requested
      if (multiSampleAttributeIndex && numFormats == 0)
      {
        while (numFormats == 0 && attrib[multiSampleAttributeIndex] > 0)
619
        {
620 621
          attrib[multiSampleAttributeIndex] /= 2;
          if (attrib[multiSampleAttributeIndex] < 2)
622
          {
623
            // try disabling multisampling altogether
624
            attrib[multiSampleAttributeIndex] = 0;
625 626 627 628
            if (multiSampleBuffersIndex)
            {
              attrib[multiSampleBuffersIndex] = 0;
            }
629
          }
630
          wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats);
Ken Martin's avatar
Ken Martin committed
631
        }
632
      }
633
      // finally try dropping stereo when requested without multisamples
634
      if (stereoAttributeIndex && numFormats == 0)
635
      {
636 637
        attrib[stereoAttributeIndex] = FALSE;
        wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats);
Ken Martin's avatar
Ken Martin committed
638
      }
639
    }
640

Ken Martin's avatar
Ken Martin committed
641 642
    DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &pfd);
    if (!SetPixelFormat(hDC, pixelFormat, &pfd))
643
    {
Ken Martin's avatar
Ken Martin committed
644
      pixelFormat = 0;
645
    }
Ken Martin's avatar
Ken Martin committed
646
    else
647
    {
Ken Martin's avatar
Ken Martin committed
648
      if (debug && (dwFlags & PFD_STEREO) && !(pfd.dwFlags & PFD_STEREO))
649
      {
Ken Martin's avatar
Ken Martin committed
650 651 652
        vtkGenericWarningMacro("No Stereo Available!");
        this->StereoCapableWindow = 0;
      }
Ken Martin's avatar
Ken Martin committed
653
    }
654
  }
655
  else
656
  {
657
    vtkErrorMacro("failed to get wglChoosePixelFormatARB");
658
  }
Ken Martin's avatar
Ken Martin committed
659

660
  // see if we can get a 3.2 context
Ken Martin's avatar
Ken Martin committed
661
  if (pixelFormat)
662
  {
Ken Martin's avatar
Ken Martin committed
663 664 665
    this->SetupPalette(hDC);

    // create a context
666 667
    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
      reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
668
    this->ContextId = 0;
669
    if (wglCreateContextAttribsARB)
670
    {
671 672
      // we believe that these later versions are all compatible with
      // OpenGL 3.2 so get a more recent context if we can.
673
      int attemptedVersions[] = {4,5, 4,4, 4,3, 4,2, 4,1, 4,0, 3,3, 3,2, 3,1};
674 675 676 677 678 679 680 681 682 683
      int iContextAttribs[] =
        {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 2,
        WGL_CONTEXT_FLAGS_ARB, 0,
        // WGL_CONTEXT_PROFILE_MASK_ARB,
        // WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
        // WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        0 // End of attributes list
        };
684
      for (int i = 0; i < 9 && !this->ContextId; i++)
685
      {
686 687 688
        iContextAttribs[1] = attemptedVersions[i*2];
        iContextAttribs[3] = attemptedVersions[i*2+1];
        this->ContextId = wglCreateContextAttribsARB(hDC, 0, iContextAttribs);
689
      }
690
      if (this->ContextId)
691
      {
692 693
        // if it is a 3.1 context check for systems that we allow
        if (iContextAttribs[1] == 3 && iContextAttribs[3] == 1)
694
        {
695 696 697 698
          std::string vendor = (const char *)glGetString(GL_VENDOR);
          std::string renderer = (const char *)glGetString(GL_RENDERER);
          std::string version = (const char *)glGetString(GL_VERSION);
          if (vendor.find("Intel") != std::string::npos &&
699 700
              (renderer.find("HD Graphics 3000") != std::string::npos ||
               renderer.find("HD Graphics 2000") != std::string::npos))
701
          {
702 703 704 705
            vtkErrorMacro("We have determined that your graphics system is"
            " an Intel SandyBridge based system. These systems only partially "
            " support VTK. If you encounter any issues please make sure"
            " your graphics drivers from Intel are up to date.");
706
          }
707
          else
708
          {
709 710 711 712
            wglDeleteContext(this->ContextId);
            this->ContextId = NULL;
          }
        }
713
      }
714 715
      if (this->ContextId &&
          (iContextAttribs[1] >= 4 || iContextAttribs[3] >= 2))
716
      {
717
        this->SetContextSupportsOpenGL32(true);
718
      }
719
    }
720 721
    // fallback on old approach
    if (!this->ContextId)
722
    {
Ken Martin's avatar
Ken Martin committed
723
      this->ContextId = wglCreateContext(hDC);
724
    }
Ken Martin's avatar
Ken Martin committed
725
    if (this->ContextId == NULL)
726
    {
Ken Martin's avatar
Ken Martin committed
727 728
      vtkErrorMacro("wglCreateContext failed in CreateAWindow(), error: " << GetLastError());
    }
729
  }
Ken Martin's avatar
Ken Martin committed
730

Ken Martin's avatar
Ken Martin committed
731 732 733 734 735 736 737
  // Delete the dummy window
  wglMakeCurrent(tempDC, 0);
  wglDeleteContext(tempContext);
  ReleaseDC(tempId, tempDC);
  ::DestroyWindow(tempId); // windows api

  // If we got a valid pixel format in the process, we are done.
738 739
  // Otherwise fail as the OpenGL does not support even 2.1
  if (!pixelFormat)
740
  {
741
    vtkErrorMacro("failed to get valid pixel format.");
742
  }
Ken Martin's avatar
Ken Martin committed
743

744
  return;
Ken Martin's avatar
Ken Martin committed
745 746
}

Ken Martin's avatar
Ken Martin committed
747
void vtkWin32OpenGLRenderWindow::SetupPalette(HDC hDC)
Ken Martin's avatar
Ken Martin committed
748 749 750 751 752 753 754 755
{
  int pixelFormat = GetPixelFormat(hDC);
  PIXELFORMATDESCRIPTOR pfd;
  LOGPALETTE* pPal;
  int paletteSize;

  DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

Ken Martin's avatar
Ken Martin committed
756
  if (pfd.dwFlags & PFD_NEED_PALETTE)
757
  {
Ken Martin's avatar
Ken Martin committed
758
    paletteSize = 1 << pfd.cColorBits;
759
  }
Ken Martin's avatar
Ken Martin committed
760
  else
761
  {
Ken Martin's avatar
Ken Martin committed
762
    return;
763
  }
Ken Martin's avatar
Ken Martin committed
764 765 766 767 768 769 770 771 772 773 774 775 776

  pPal = (LOGPALETTE*)
    malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  pPal->palVersion = 0x300;
  pPal->palNumEntries = paletteSize;

  /* build a simple RGB color palette */
  {
  int redMask = (1 << pfd.cRedBits) - 1;
  int greenMask = (1 << pfd.cGreenBits) - 1;
  int blueMask = (1 << pfd.cBlueBits) - 1;
  int i;

Ken Martin's avatar
Ken Martin committed
777
  for (i=0; i<paletteSize; ++i)
778
  {
Ken Martin's avatar
Ken Martin committed
779 780 781 782 783 784 785
    pPal->palPalEntry[i].peRed =
      (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
    pPal->palPalEntry[i].peGreen =
      (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
    pPal->palPalEntry[i].peBlue =
      (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
    pPal->palPalEntry[i].peFlags = 0;
786
  }
Ken Martin's avatar
Ken Martin committed
787 788 789 790 791
  }

  this->Palette = CreatePalette(pPal);
  free(pPal);

Ken Martin's avatar
Ken Martin committed
792
  if (this->Palette)
793
  {
Ken Martin's avatar
Ken Martin committed
794 795
    this->OldPalette = SelectPalette(hDC, this->Palette, FALSE);
    RealizePalette(hDC);
796
  }
Ken Martin's avatar
Ken Martin committed
797 798 799
}


Ken Martin's avatar
Ken Martin committed
800
LRESULT vtkWin32OpenGLRenderWindow::MessageProc(HWND hWnd, UINT message,
Ken Martin's avatar
Ken Martin committed
801 802 803
                                                WPARAM wParam, LPARAM lParam)
{
  switch (message)
804
  {
Ken Martin's avatar
Ken Martin committed
805 806 807 808 809 810 811 812 813
    case WM_CREATE:
    {
    // nothing to be done here, opengl is initilized after the call to
    // create now
    return 0;
    }
    case WM_DESTROY:
      this->Clean();
      if (this->DeviceContext)
814
      {
Ken Martin's avatar
Ken Martin committed
815 816 817
        ReleaseDC(this->WindowId, this->DeviceContext);
        this->DeviceContext = NULL;
        this->WindowId = NULL;
818
      }
Ken Martin's avatar
Ken Martin committed
819 820 821 822
      return 0;
    case WM_SIZE:
      /* track window size changes */
      if (this->ContextId)
823
      {
Ken Martin's avatar
Ken Martin committed
824 825
        this->SetSize((int) LOWORD(lParam),(int) HIWORD(lParam));
        return 0;
826
      }
Ken Martin's avatar
Ken Martin committed
827 828 829
    case WM_PALETTECHANGED:
      /* realize palette if this is *not* the current window */
      if (this->ContextId && this->Palette && (HWND) wParam != hWnd)
830
      {
Ken Martin's avatar
Ken Martin committed
831 832 833 834 835 836
        SelectPalette(this->DeviceContext, this->OldPalette, FALSE);
        UnrealizeObject(this->Palette);
        this->OldPalette = SelectPalette(this->DeviceContext,
                                         this->Palette, FALSE);
        RealizePalette(this->DeviceContext);
        this->Render();
837
      }
Ken Martin's avatar
Ken Martin committed
838 839 840 841
      break;
    case WM_QUERYNEWPALETTE:
      /* realize palette if this is the current window */
      if (this->ContextId && this->Palette)
842
      {
Ken Martin's avatar
Ken Martin committed
843 844 845 846 847 848 849
        SelectPalette(this->DeviceContext, this->OldPalette, FALSE);
        UnrealizeObject(this->Palette);
        this->OldPalette = SelectPalette(this->DeviceContext,
                                         this->Palette, FALSE);
        RealizePalette(this->DeviceContext);
        this->Render();
        return TRUE;
850
      }
Ken Martin's avatar
Ken Martin committed
851 852 853 854 855 856
      break;
    case WM_PAINT:
    {
    PAINTSTRUCT ps;
    BeginPaint(hWnd, &ps);
    if (this->ContextId)
857
    {
Ken Martin's avatar
Ken Martin committed
858
      this->Render();
859
    }
Ken Martin's avatar
Ken Martin committed
860 861 862 863 864 865 866 867
    EndPaint(hWnd, &ps);
    return 0;
    }
    break;
    case WM_ERASEBKGND:
      return TRUE;
    case WM_SETCURSOR:
      if (HTCLIENT == LOWORD(lParam))
868
      {
Ken Martin's avatar
Ken Martin committed
869 870
        this->SetCurrentCursor(this->GetCurrentCursor());
        return TRUE;
871
      }
Ken Martin's avatar
Ken Martin committed
872 873 874 875
      break;
    default:
      this->InvokeEvent(vtkCommand::RenderWindowMessageEvent, &message);
      break;
876
  }
Ken Martin's avatar
Ken Martin committed
877 878 879 880
  return DefWindowProc(hWnd, message, wParam, lParam);
}


Ken Martin's avatar
Ken Martin committed
881
void vtkWin32OpenGLRenderWindow::InitializeApplication()
Ken Martin's avatar
Ken Martin committed
882 883 884
{
  // get the application instance if we don't have one already
  if (!this->ApplicationInstance)
885
  {
Ken Martin's avatar
Ken Martin committed
886 887
    // if we have a parent window get the app instance from it
    if (this->ParentId)
888
    {
Ken Martin's avatar
Ken Martin committed
889
      this->ApplicationInstance = (HINSTANCE)vtkGetWindowLong(this->ParentId,vtkGWL_HINSTANCE);
890
    }
Ken Martin's avatar
Ken Martin committed
891
    else
892
    {
Ken Martin's avatar
Ken Martin committed
893 894
      this->ApplicationInstance = GetModuleHandle(NULL); /*AfxGetInstanceHandle();*/
    }
895
  }
Ken Martin's avatar
Ken Martin committed
896 897
}

Ken Martin's avatar
Ken Martin committed
898
void vtkWin32OpenGLRenderWindow::CreateAWindow()
Ken Martin's avatar
Ken Martin committed
899
{
900
  this->VTKRegisterClass();
Ken Martin's avatar
Ken Martin committed
901 902

  if(this->WindowIdReferenceCount == 0)
903
  {
Ken Martin's avatar
Ken Martin committed
904 905 906 907
    static int count = 1;
    char *windowName;

    if (!this->WindowId)
908
    {
Ken Martin's avatar
Ken Martin committed
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
      this->DeviceContext = 0;

      int len = static_cast<int>(strlen("Visualization Toolkit - Win32OpenGL #"))
        + (int)ceil( (double) log10( (double)(count+1) ) )
        + 1;
      windowName = new char [ len ];
      sprintf(windowName,"Visualization Toolkit - Win32OpenGL #%i",count++);
      this->SetWindowName(windowName);
      delete [] windowName;

#ifdef UNICODE
      wchar_t *wname = new wchar_t [mbstowcs(NULL, this->WindowName, 32000)+1];
      mbstowcs(wname, this->WindowName, 32000);
#endif
      int x = ((this->Position[0] >= 0) ? this->Position[0] : 5);
      int y = ((this->Position[1] >= 0) ? this->Position[1] : 5);
      int height = ((this->Size[1] > 0) ? this->Size[1] : 300);
      int width = ((this->Size[0] > 0) ? this->Size[0] : 300);

      /* create window */
      if (this->ParentId)
930
      {
Ken Martin's avatar
Ken Martin committed
931 932 933 934 935 936 937 938 939 940 941 942 943
#ifdef UNICODE
        this->WindowId = CreateWindow(
          L"vtkOpenGL", wname,
          WS_CHILD | WS_CLIPCHILDREN /*| WS_CLIPSIBLINGS*/,
          x, y, width, height,
          this->ParentId, NULL, this->ApplicationInstance, NULL);
#else
        this->WindowId = CreateWindow(
          "vtkOpenGL", this->WindowName,
          WS_CHILD | WS_CLIPCHILDREN /*| WS_CLIPSIBLINGS*/,
          x, y, width, height,
          this->ParentId, NULL, this->ApplicationInstance, NULL);
#endif
944
      }
Ken Martin's avatar
Ken Martin committed
945
      else
946
      {
Ken Martin's avatar
Ken Martin committed
947 948
        DWORD style;
        if (this->Borders)
949
        {
Ken Martin's avatar
Ken Martin committed
950
          style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN /*| WS_CLIPSIBLINGS*/;
951
        }
Ken Martin's avatar
Ken Martin committed
952
        else
953
        {
Ken Martin's avatar
Ken Martin committed
954
          style = WS_POPUP | WS_CLIPCHILDREN /*| WS_CLIPSIBLINGS*/;
955
        }
Ken Martin's avatar
Ken Martin committed
956
        RECT r;
957
        AdjustWindowRectForBorders(0, style, x, y, width, height, r);
Ken Martin's avatar
Ken Martin committed
958 959 960 961 962 963 964 965 966 967 968
#ifdef UNICODE
        this->WindowId = CreateWindow(
          L"vtkOpenGL", wname, style,
          x, y, r.right-r.left, r.bottom-r.top,
          NULL, NULL, this->ApplicationInstance, NULL);
#else
        this->WindowId = CreateWindow(
          "vtkOpenGL", this->WindowName, style,
          x, y, r.right-r.left, r.bottom-r.top,
          NULL, NULL, this->ApplicationInstance, NULL);
#endif
969
      }
Ken Martin's avatar
Ken Martin committed
970 971 972 973 974
#ifdef UNICODE
      delete [] wname;
#endif

      if (!this->WindowId)
975
      {
Ken Martin's avatar
Ken Martin committed
976 977
        vtkErrorMacro("Could not create window, error:  " << GetLastError());
        return;
978
      }
Ken Martin's avatar
Ken Martin committed
979 980 981 982
      // extract the create info

      /* display window */
      if(!this->OffScreenRendering)
983
      {
Ken Martin's avatar
Ken Martin committed
984
        ShowWindow(this->WindowId, SW_SHOW);
985
      }
Ken Martin's avatar
Ken Martin committed
986 987 988
      //UpdateWindow(this->WindowId);
      this->OwnWindow = 1;
      vtkSetWindowLong(this->WindowId,sizeof(vtkLONG),(intptr_t)this);
989
    }
Ken Martin's avatar
Ken Martin committed
990
    if (!this->DeviceContext)
991
    {
Ken Martin's avatar
Ken Martin committed
992
      this->DeviceContext = GetDC(this->WindowId);
993
    }
Ken Martin's avatar
Ken Martin committed
994
    if (this->StereoCapableWindow)
995
    {
Ken Martin's avatar
Ken Martin committed
996
      this->SetupPixelFormatPaletteAndContext(this->DeviceContext, PFD_SUPPORT_OPENGL |
Ken Martin's avatar
Ken Martin committed
997 998
                             PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER |
                             PFD_STEREO, this->GetDebug(), 32, 32);
999
    }
Ken Martin's avatar
Ken Martin committed
1000
    else
1001
    {
Ken Martin's avatar
Ken Martin committed
1002
      this->SetupPixelFormatPaletteAndContext(this->DeviceContext, PFD_SUPPORT_OPENGL |
Ken Martin's avatar
Ken Martin committed
1003 1004
                             PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER,
                             this->GetDebug(), 32, 32);
1005
    }
Ken Martin's avatar
Ken Martin committed
1006 1007 1008
    this->MakeCurrent();

    // wipe out any existing display lists
1009
    this->ReleaseGraphicsResources(this);
Ken Martin's avatar
Ken Martin committed
1010 1011 1012
    this->OpenGLInit();
    this->Mapped = 1;
    this->WindowIdReferenceCount = 1;
1013
  }
Ken Martin's avatar
Ken Martin committed
1014
  else
1015
  {
Ken Martin's avatar
Ken Martin committed
1016
    ++this->WindowIdReferenceCount;
1017
  }
Ken Martin's avatar
Ken Martin committed
1018 1019 1020
}

// Initialize the window for rendering.
Ken Martin's avatar
Ken Martin committed
1021
void vtkWin32OpenGLRenderWindow::WindowInitialize()
Ken Martin's avatar
Ken Martin committed
1022 1023 1024 1025
{
  // create our own window if not already set
  this->OwnWindow = 0;
  if (!this->MFChandledWindow)
1026
  {
Ken Martin's avatar
Ken Martin committed
1027 1028
    this->InitializeApplication();
    this->CreateAWindow();
1029
  }
Ken Martin's avatar
Ken Martin committed
1030
  else
1031
  {
Ken Martin's avatar
Ken Martin committed
1032 1033
    this->MakeCurrent(); // hsr
    this->OpenGLInit();
1034
  }
Ken Martin's avatar
Ken Martin committed
1035 1036 1037
}

// Initialize the rendering window.
Ken Martin's avatar
Ken Martin committed
1038
void vtkWin32OpenGLRenderWindow::Initialize (void)
Ken Martin's avatar
Ken Martin committed
1039 1040 1041
{
  // make sure we havent already been initialized
  if (!this->OffScreenRendering && !this->ContextId)
1042
  {
Ken Martin's avatar
Ken Martin committed
1043
    this->WindowInitialize();
1044
  }
Ken Martin's avatar
Ken Martin committed
1045
  else
1046
  {
Ken Martin's avatar
Ken Martin committed
1047 1048
    if(this->OffScreenRendering && !(this->ContextId ||
                                     this->OffScreenUseFrameBuffer))
1049
    {
Ken Martin's avatar
Ken Martin committed
1050 1051 1052 1053 1054
      this->InitializeApplication();
      int width = ((this->Size[0] > 0) ? this->Size[0] : 300);
      int height = ((this->Size[1] > 0) ? this->Size[1] : 300);
      this->CreateOffScreenWindow(width,height);
    }
1055
  }
Ken Martin's avatar
Ken Martin committed
1056 1057
}

Ken Martin's avatar
Ken Martin committed
1058
void vtkWin32OpenGLRenderWindow::Finalize (void)
Ken Martin's avatar
Ken Martin committed
1059 1060
{
  if (this->CursorHidden)
1061
  {
Ken Martin's avatar
Ken Martin committed
1062
    this->ShowCursor();
1063
  }
Ken Martin's avatar
Ken Martin committed
1064 1065

  if (this->OffScreenRendering)
1066
  {
Ken Martin's avatar
Ken Martin committed
1067
    this->CleanUpOffScreenRendering();
1068
  }
Ken Martin's avatar
Ken Martin committed
1069 1070 1071
  this->DestroyWindow();
}

Ken Martin's avatar
Ken Martin committed
1072
void vtkWin32OpenGLRenderWindow::DestroyWindow()
Ken Martin's avatar
Ken Martin committed
1073 1074
{
  if(this->WindowIdReferenceCount > 0)
1075
  {
Ken Martin's avatar
Ken Martin committed
1076 1077
    --this->WindowIdReferenceCount;
    if(this->WindowIdReferenceCount == 0)
1078
    {
1079
      this->Clean();
Ken Martin's avatar
Ken Martin committed
1080
      if (this->WindowId)
1081
      {
Ken Martin's avatar
Ken Martin committed
1082 1083 1084 1085 1086 1087 1088
        ReleaseDC(this->WindowId, this->DeviceContext);
        // can't set WindowId=NULL, needed for DestroyWindow
        this->DeviceContext = NULL;

        // clear the extra data before calling destroy
        vtkSetWindowLong(this->WindowId,sizeof(vtkLONG),(vtkLONG)0);
        if(this->OwnWindow)
1089
        {
Ken Martin's avatar
Ken Martin committed
1090 1091 1092 1093 1094
          ::DestroyWindow(this->WindowId); // windows api
          this->WindowId=0;
        }
      }
    }
1095
  }
Ken Martin's avatar
Ken Martin committed
1096 1097 1098
}

// Get the current size of the window.
Ken Martin's avatar
Ken Martin committed
1099
int *vtkWin32OpenGLRenderWindow::GetSize(void)
Ken Martin's avatar
Ken Martin committed
1100 1101 1102
{
  // if we aren't mapped then just return the ivar
  if (this->Mapped)
1103
  {
Ken Martin's avatar
Ken Martin committed
1104 1105 1106 1107
    RECT rect;

    //  Find the current window size
    if (GetClientRect(this->WindowId, &rect))
1108
    {
Ken Martin's avatar
Ken Martin committed
1109 1110
      this->Size[0] = rect.right;
      this->Size[1] = rect.bottom;
1111
    }
Ken Martin's avatar
Ken Martin committed
1112
    else
1113
    {
Ken Martin's avatar
Ken Martin committed
1114 1115 1116 1117
      this->Size[0] = 0;
      this->Size[1] = 0;
    }

1118 1119
  }

1120
  return this->vtkOpenGLRenderWindow::GetSize();
Ken Martin's avatar
Ken Martin committed
1121 1122
}

1123
// Get the size of the whole screen.
Ken Martin's avatar
Ken Martin committed
1124
int *vtkWin32OpenGLRenderWindow::GetScreenSize(void)
Ken Martin's avatar
Ken Martin committed
1125
{
1126 1127
  HDC hDC = ::GetDC(NULL);
  if (hDC)
1128
  {
1129 1130 1131 1132 1133
    // This technique yields the screen size of the primary monitor
    // only in a multi-monitor configuration...
    this->Size[0] = ::GetDeviceCaps(hDC, HORZRES);
    this->Size[1] = ::GetDeviceCaps(hDC, VERTRES);
    ::ReleaseDC(NULL, hDC);
1134
  }
1135
  else
1136
  {
1137 1138 1139 1140 1141
    // This technique gets the "work area" (the whole screen except
    // for the bit covered by the Windows task bar) -- use it as a
    // fallback if there's an error calling GetDC.
    RECT rect;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
Ken Martin's avatar
Ken Martin committed
1142

1143 1144
    this->Size[0] = rect.right - rect.left;
    this->Size[1] = rect.bottom - rect.top;
1145
  }
Ken Martin's avatar
Ken Martin committed
1146 1147 1148 1149 1150

  return this->Size;
}

// Get the position in screen coordinates of the window.
Ken Martin's avatar
Ken Martin committed
1151
int *vtkWin32OpenGLRenderWindow::GetPosition(void)
Ken Martin's avatar
Ken Martin committed
1152 1153 1154
{
  // if we aren't mapped then just return the ivar
  if (!this->Mapped)
1155
  {
Ken Martin's avatar
Ken Martin committed
1156
    return this->Position;
1157
  }
Ken Martin's avatar
Ken Martin committed
1158 1159 1160 1161 1162 1163 1164 1165

  //  Find the current window position
  //  x,y,&this->Position[0],&this->Position[1],&child);

  return this->Position;
}

// Change the window to fill the entire screen.
Ken Martin's avatar
Ken Martin committed
1166
void vtkWin32OpenGLRenderWindow::SetFullScreen(int arg)
Ken Martin's avatar
Ken Martin committed
1167 1168 1169 1170
{
  int *temp;

  if (this->FullScreen == arg)
1171
  {
Ken Martin's avatar
Ken Martin committed
1172
    return;
1173
  }
Ken Martin's avatar
Ken Martin committed
1174 1175

  if (!this->Mapped)
1176
  {
Ken Martin's avatar
Ken Martin committed
1177 1178
    this->PrefFullScreen();
    return;
1179
  }