00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if 1
00024 #ifndef _WIN32_WINNT
00025 #define _WIN32_WINNT 0x0400 // hack to allow access to mouse wheel events
00026 #endif
00027 #endif
00028 #include <windows.h>
00029 #include <winuser.h>
00030
00031 #include "VMDApp.h"
00032 #include "OpenGLDisplayDevice.h"
00033 #include "Inform.h"
00034 #include "utilities.h"
00035 #include "config.h"
00036
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <math.h>
00040 #include <GL/gl.h>
00041
00042 #include "../msvc/winvmd/res/resource.h"
00043
00044
00045
00046
00047 #include <GL/glext.h>
00048 #include <GL/wglext.h>
00049
00050
00051 static const char *glStereoNameStr[OPENGL_STEREO_MODES] =
00052 { "Off",
00053 "QuadBuffered",
00054 "DTI SideBySide",
00055 "Checkerboard",
00056 "ColumnInterleaved",
00057 "RowInterleaved",
00058 "Anaglyph",
00059 "SideBySide",
00060 "AboveBelow",
00061 "Left",
00062 "Right" };
00063
00064 static const char *glRenderNameStr[OPENGL_RENDER_MODES] =
00065 { "Normal",
00066 "GLSL",
00067 "Acrobat3D" };
00068
00069 static const char *glCacheNameStr[OPENGL_CACHE_MODES] =
00070 { "Off",
00071 "On" };
00072
00073 static char szAppName[] = "VMD";
00074 static char szAppTitle[]="VMD " VMDVERSION " OpenGL Display";
00075
00076 LRESULT WINAPI vmdWindowProc( HWND, UINT, WPARAM, LPARAM );
00077
00078 static int OpenWin32Connection(wgldata * glwsrv) {
00079 WNDCLASS wc;
00080 HINSTANCE hInstance = GetModuleHandle(NULL);
00081
00082
00083 memset(&wc, 0, sizeof(WNDCLASS));
00084 wc.style = CS_OWNDC;
00085 wc.lpfnWndProc = (WNDPROC) vmdWindowProc;
00086 wc.hInstance = hInstance;
00087 #if 1
00088
00089 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
00090 #else
00091 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00092 #endif
00093 wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
00094 wc.hbrBackground = NULL;
00095 wc.lpszMenuName = NULL;
00096 wc.lpszClassName = szAppName;
00097
00098 if(!RegisterClass(&wc)) {
00099 printf("Cannot register window class.\n");
00100 return -1;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 glwsrv->scrwidth = GetSystemMetrics(SM_CXSCREEN);
00112 glwsrv->scrheight = GetSystemMetrics(SM_CYSCREEN);
00113
00114 return 0;
00115 }
00116
00117 static int PFDHasStereo(int ID, HDC hDC) {
00118 PIXELFORMATDESCRIPTOR pfd;
00119 DescribePixelFormat(hDC, ID, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00120
00121 #if 0
00122
00123 if ((pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
00124 !(pfd.dwFlags & PFD_GENERIC_FORMAT))
00125 msgInfo << "Hardware 3D Acceleration enabled." << sendmsg;
00126 else
00127 msgInfo << "No hardware 3D Acceleration found." << sendmsg;
00128 #endif
00129
00130 if (pfd.dwFlags & PFD_STEREO)
00131 return 1;
00132
00133 return 0;
00134 }
00135
00136 #if 0
00137 static void PrintPFD(int ID, HDC hDC) {
00138 PIXELFORMATDESCRIPTOR pfd;
00139 FILE * ofp;
00140
00141 if (ID == 0) {
00142 int i, num;
00143 num = DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00144 for (i=1; i<num; i++)
00145 PrintPFD(i, hDC);
00146
00147 return;
00148 }
00149
00150 DescribePixelFormat(hDC, ID, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00151
00152 ofp=fopen("c:/video.txt", "a+");
00153 if (ofp == NULL)
00154 ofp=stdout;
00155
00156 if (pfd.cColorBits < 15) {
00157 fprintf(ofp, "Windows Pixel Format ID: %d -- not enough color bits\n", ID);
00158 }
00159 else {
00160 fprintf(ofp, "\nWindows Pixel Format ID: %d\n", ID);
00161 fprintf(ofp, " Color Buffer Depth: %d bits\n", pfd.cColorBits);
00162 fprintf(ofp, " Z Buffer Depth: %d bits\n", pfd.cDepthBits);
00163 if (pfd.dwFlags & PFD_DOUBLEBUFFER)
00164 fprintf(ofp, " PFD_DOUBLEBUFFER\n");
00165 if (pfd.dwFlags & PFD_STEREO)
00166 fprintf(ofp, " PFD_STEREO\n");
00167 if (pfd.dwFlags & PFD_DRAW_TO_WINDOW)
00168 fprintf(ofp, " PFD_DRAW_TO_WINDOW\n");
00169 if (pfd.dwFlags & PFD_SUPPORT_GDI)
00170 fprintf(ofp, " PFD_SUPPORT_GDI\n");
00171 if (pfd.dwFlags & PFD_SUPPORT_OPENGL)
00172 fprintf(ofp, " PFD_SUPPORT_OPENGL\n");
00173 if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
00174 fprintf(ofp, " PFD_SWAP_EXCHANGE\n");
00175 if (pfd.dwFlags & PFD_SWAP_COPY)
00176 fprintf(ofp, " PFD_SWAP_COPY\n");
00177 if (pfd.dwFlags & PFD_SWAP_LAYER_BUFFERS)
00178 fprintf(ofp, " PFD_SWAP_LAYER_BUFFERS\n");
00179 if (pfd.dwFlags & PFD_GENERIC_ACCELERATED)
00180 fprintf(ofp, " PFD_GENERIC_ACCELERATED\n");
00181 if (pfd.dwFlags & PFD_GENERIC_FORMAT)
00182 fprintf(ofp, " PFD_GENERIC_FORMAT\n");
00183 }
00184 if (ofp != NULL && ofp != stdout)
00185 fclose(ofp);
00186 }
00187 #endif
00188
00189 static HGLRC SetupOpenGL(wgldata *glwsrv) {
00190 int ID;
00191 HDC hDC;
00192 HGLRC hRC;
00193
00194 PIXELFORMATDESCRIPTOR pfd = {
00195 sizeof (PIXELFORMATDESCRIPTOR),
00196 1,
00197 PFD_DRAW_TO_WINDOW
00198 | PFD_DOUBLEBUFFER
00199 | PFD_STEREO
00200 | PFD_SUPPORT_OPENGL,
00201 PFD_TYPE_RGBA,
00202 16,
00203 0, 0, 0,
00204 0, 0, 0,
00205 0, 0,
00206 0, 0, 0, 0, 0,
00207 16,
00208 1,
00209 0,
00210 PFD_MAIN_PLANE,
00211 0,
00212 0,
00213 0,
00214 0
00215 };
00216
00217 hDC = GetDC(glwsrv->hWnd);
00218 ID = ChoosePixelFormat(hDC, &pfd);
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 if (ID == 0) {
00229 printf("Error selecting OpenGL Pixel Format!!\n");
00230 return NULL;
00231 }
00232
00233 glwsrv->PFDisStereo = PFDHasStereo(ID, hDC);
00234
00235
00236 SetPixelFormat( hDC, ID, &pfd );
00237
00238 hRC = wglCreateContext(hDC);
00239 ReleaseDC(glwsrv->hWnd, hDC);
00240
00241 return hRC;
00242 }
00243
00244 static int myCreateWindow(OpenGLDisplayDevice *ogldispdev,
00245 int xpos, int ypos, int xs, int ys) {
00246
00247 ogldispdev->glwsrv.hWnd =
00248 CreateWindow(
00249 szAppName,
00250 szAppTitle,
00251 WS_OVERLAPPEDWINDOW
00252 | WS_CLIPCHILDREN
00253 | WS_CLIPSIBLINGS,
00254 xpos, ypos,
00255 xs, ys,
00256 NULL,
00257 NULL,
00258 GetModuleHandle(NULL),
00259 ogldispdev
00260 );
00261
00262 if (!ogldispdev->glwsrv.hWnd) {
00263 printf("Couldn't Open Window!!\n");
00264 return -1;
00265 }
00266
00267 ogldispdev->glwsrv.hDC = GetDC(ogldispdev->glwsrv.hWnd);
00268 wglMakeCurrent(ogldispdev->glwsrv.hDC, ogldispdev->glwsrv.hRC);
00269
00270
00271 ShowWindow(ogldispdev->glwsrv.hWnd, SW_SHOW);
00272 UpdateWindow(ogldispdev->glwsrv.hWnd );
00273 DragAcceptFiles(ogldispdev->glwsrv.hWnd, TRUE);
00274
00275 return 0;
00276 }
00277
00278 static void vmd_transwin32mouse(OpenGLDisplayDevice * d, LPARAM l) {
00279 int x, y;
00280 x = LOWORD(l);
00281 y = HIWORD(l);
00282 if(x & 1 << 15) x -= (1 << 16);
00283 if(y & 1 << 15) y -= (1 << 16);
00284 d->glwsrv.MouseX = x;
00285 d->glwsrv.MouseY = (d->ySize) - y;
00286 }
00287
00288
00289 #ifdef VMDSPACEWARE
00290
00291 static void vmd_setupwin32spaceball(wgldata *glwsrv) {
00292 SiOpenData oData;
00293 enum SpwRetVal res;
00294
00295
00296
00297 glwsrv->sball = NULL;
00298
00299 switch (SiInitialize()) {
00300 case SPW_NO_ERROR:
00301 break;
00302
00303 case SPW_DLL_LOAD_ERROR:
00304 msgInfo << "Spaceball driver not installed. Spaceball interface disabled." << sendmsg;
00305 return;
00306
00307 default:
00308 msgInfo << "Spaceball did not initialize properly. Spaceball interface disabled." << sendmsg;
00309 return;
00310 }
00311
00312 SiOpenWinInit(&oData, glwsrv->hWnd);
00313 SiSetUiMode(glwsrv->sball, SI_UI_ALL_CONTROLS);
00314
00315
00316
00317 glwsrv->sball = SiOpen("VMD", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData);
00318 if ((glwsrv->sball == NULL) || (glwsrv->sball == SI_NO_HANDLE)) {
00319 SiTerminate();
00320 msgInfo << "Spaceball is unresponsive. Spaceball interface disabled." << sendmsg;
00321 glwsrv->sball = NULL;
00322 return;
00323 }
00324
00325 res = SiBeep(glwsrv->sball, "CcCc");
00326 if ((glwsrv->sball != NULL) && (glwsrv->sball != SI_NO_HANDLE))
00327 msgInfo << "Spaceball found, software interface initialized." << sendmsg;
00328 }
00329
00330 static void vmd_closewin32spaceball(wgldata *glwsrv) {
00331 enum SpwRetVal res;
00332
00333 if (glwsrv->sball != NULL) {
00334 res = SiClose(glwsrv->sball);
00335 if (res != SPW_NO_ERROR)
00336 msgInfo << "An error occured while shutting down the Spaceball device." << sendmsg;
00337
00338 SiTerminate();
00339 }
00340
00341 glwsrv->sball = NULL;
00342 }
00343
00344 static int vmd_processwin32spaceballevent(wgldata *glwsrv, UINT msg, WPARAM wParam, LPARAM lParam) {
00345
00346 if (glwsrv == NULL)
00347 return 0;
00348
00349 if (glwsrv->sball == NULL)
00350 return 0;
00351
00352
00353 SiGetEventWinInit(&glwsrv->spwedata, msg, wParam, lParam);
00354
00355 if (SiGetEvent(glwsrv->sball, 0, &glwsrv->spwedata, &glwsrv->spwevent) == SI_IS_EVENT) {
00356 return 1;
00357 }
00358
00359 return 0;
00360 }
00361 #endif
00362
00363
00364 LRESULT WINAPI vmdWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
00365 PAINTSTRUCT ps;
00366
00367
00368
00369 enum EventCodes { WIN_REDRAW, WIN_LEFT, WIN_MIDDLE, WIN_RIGHT,
00370 WIN_WHEELUP, WIN_WHEELDOWN, WIN_MOUSEX, WIN_MOUSEY,
00371 WIN_KBD,
00372 WIN_KBD_ESCAPE,
00373 WIN_KBD_UP,
00374 WIN_KBD_DOWN,
00375 WIN_KBD_LEFT,
00376 WIN_KBD_RIGHT,
00377 WIN_KBD_PAGE_UP,
00378 WIN_KBD_PAGE_DOWN,
00379 WIN_KBD_HOME,
00380 WIN_KBD_END,
00381 WIN_KBD_INSERT,
00382 WIN_KBD_DELETE,
00383 WIN_KBD_F1, WIN_KBD_F2, WIN_KBD_F3, WIN_KBD_F4,
00384 WIN_KBD_F5, WIN_KBD_F6, WIN_KBD_F7, WIN_KBD_F8,
00385 WIN_KBD_F9, WIN_KBD_F10, WIN_KBD_F11, WIN_KBD_F12,
00386 WIN_NOEVENT };
00387 wgldata *glwsrv;
00388 OpenGLDisplayDevice * ogldispdev;
00389
00390
00391
00392 if (msg == WM_NCCREATE) {
00393 #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64)
00394 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) (((CREATESTRUCT *) lParam)->lpCreateParams));
00395 #else
00396 SetWindowLong(hwnd, GWL_USERDATA, (LONG) (((CREATESTRUCT *) lParam)->lpCreateParams));
00397 #endif
00398 }
00399
00400
00401
00402 #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64)
00403 ogldispdev = (OpenGLDisplayDevice *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
00404 #else
00405 ogldispdev = (OpenGLDisplayDevice *) GetWindowLong(hwnd, GWL_USERDATA);
00406 #endif
00407
00408
00409
00410
00411
00412
00413
00414 if (ogldispdev == NULL)
00415 return DefWindowProc(hwnd, msg, wParam, lParam);
00416
00417 glwsrv = &ogldispdev->glwsrv;
00418
00419 #ifdef VMDSPACEWARE
00420
00421 if (vmd_processwin32spaceballevent(glwsrv, msg, wParam, lParam))
00422 return 0;
00423 #endif
00424
00425 switch(msg) {
00426 case WM_CREATE:
00427 glwsrv->hWnd = hwnd;
00428 glwsrv->hRC = SetupOpenGL(glwsrv);
00429 glwsrv->WEvents = WIN_REDRAW;
00430 return 0;
00431
00432 case WM_SIZE:
00433 wglMakeCurrent(glwsrv->hDC, glwsrv->hRC);
00434 ogldispdev->xSize = LOWORD(lParam);
00435 ogldispdev->ySize = HIWORD(lParam);
00436 ogldispdev->reshape();
00437 glViewport(0, 0, (GLsizei) ogldispdev->xSize, (GLsizei) ogldispdev->ySize);
00438 glwsrv->WEvents = WIN_REDRAW;
00439 return 0;
00440
00441 case WM_SIZING:
00442 wglMakeCurrent(glwsrv->hDC, glwsrv->hRC);
00443 glClear(GL_COLOR_BUFFER_BIT);
00444 SwapBuffers(glwsrv->hDC);
00445 glDrawBuffer(GL_BACK);
00446 return 0;
00447
00448 case WM_CLOSE:
00449 PostQuitMessage(0);
00450 return 0;
00451
00452 case WM_PAINT:
00453 BeginPaint(hwnd, &ps);
00454 EndPaint(hwnd, &ps);
00455 glwsrv->WEvents = WIN_REDRAW;
00456 return 0;
00457
00458 case WM_KEYDOWN:
00459 glwsrv->KeyFlag = MapVirtualKey((UINT) wParam, 2);
00460 glwsrv->WEvents = WIN_KBD;
00461 if (glwsrv->KeyFlag == 0) {
00462 unsigned int keysym = wParam;
00463 switch (keysym) {
00464 case VK_ESCAPE: glwsrv->WEvents = WIN_KBD_ESCAPE; break;
00465 case VK_UP: glwsrv->WEvents = WIN_KBD_UP; break;
00466 case VK_DOWN: glwsrv->WEvents = WIN_KBD_DOWN; break;
00467 case VK_LEFT: glwsrv->WEvents = WIN_KBD_LEFT; break;
00468 case VK_RIGHT: glwsrv->WEvents = WIN_KBD_RIGHT; break;
00469 case VK_PRIOR: glwsrv->WEvents = WIN_KBD_PAGE_UP; break;
00470 case VK_NEXT: glwsrv->WEvents = WIN_KBD_PAGE_DOWN; break;
00471 case VK_HOME: glwsrv->WEvents = WIN_KBD_HOME; break;
00472 case VK_END: glwsrv->WEvents = WIN_KBD_END; break;
00473 case VK_INSERT: glwsrv->WEvents = WIN_KBD_INSERT; break;
00474 case VK_DELETE: glwsrv->WEvents = WIN_KBD_DELETE; break;
00475 case VK_F1: glwsrv->WEvents = WIN_KBD_F1; break;
00476 case VK_F2: glwsrv->WEvents = WIN_KBD_F2; break;
00477 case VK_F3: glwsrv->WEvents = WIN_KBD_F3; break;
00478 case VK_F4: glwsrv->WEvents = WIN_KBD_F4; break;
00479 case VK_F5: glwsrv->WEvents = WIN_KBD_F5; break;
00480 case VK_F6: glwsrv->WEvents = WIN_KBD_F6; break;
00481 case VK_F7: glwsrv->WEvents = WIN_KBD_F7; break;
00482 case VK_F8: glwsrv->WEvents = WIN_KBD_F8; break;
00483 case VK_F9: glwsrv->WEvents = WIN_KBD_F9; break;
00484 case VK_F10: glwsrv->WEvents = WIN_KBD_F10; break;
00485 case VK_F11: glwsrv->WEvents = WIN_KBD_F11; break;
00486 case VK_F12: glwsrv->WEvents = WIN_KBD_F12; break;
00487 default:
00488 glwsrv->WEvents = WIN_NOEVENT;
00489 break;
00490 }
00491 }
00492 return 0;
00493
00494 case WM_MOUSEMOVE:
00495 vmd_transwin32mouse(ogldispdev, lParam);
00496 glwsrv->MouseFlags = (long) wParam;
00497 return 0;
00498
00499 case WM_MOUSEWHEEL:
00500 {
00501 int zDelta = ((short) HIWORD(wParam));
00502
00503
00504
00505
00506
00507
00508
00509
00510 if (zDelta > (WHEEL_DELTA / 2)) {
00511 glwsrv->WEvents = WIN_WHEELUP;
00512 } else if (zDelta < -(WHEEL_DELTA / 2)) {
00513 glwsrv->WEvents = WIN_WHEELDOWN;
00514 }
00515 }
00516 return 0;
00517
00518 case WM_LBUTTONDOWN:
00519 SetCapture(hwnd);
00520 vmd_transwin32mouse(ogldispdev, lParam);
00521 glwsrv->MouseFlags = (long) wParam;
00522 glwsrv->WEvents = WIN_LEFT;
00523 return 0;
00524
00525 case WM_LBUTTONUP:
00526 vmd_transwin32mouse(ogldispdev, lParam);
00527 glwsrv->MouseFlags = (long) wParam;
00528 glwsrv->WEvents = WIN_LEFT;
00529 if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
00530 ReleaseCapture();
00531 return 0;
00532
00533 case WM_MBUTTONDOWN:
00534 SetCapture(hwnd);
00535 vmd_transwin32mouse(ogldispdev, lParam);
00536 glwsrv->MouseFlags = (long) wParam;
00537 glwsrv->WEvents = WIN_MIDDLE;
00538 return 0;
00539
00540 case WM_MBUTTONUP:
00541 vmd_transwin32mouse(ogldispdev, lParam);
00542 glwsrv->MouseFlags = (long) wParam;
00543 glwsrv->WEvents = WIN_MIDDLE;
00544 if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
00545 ReleaseCapture();
00546 return 0;
00547
00548 case WM_RBUTTONDOWN:
00549 SetCapture(hwnd);
00550 vmd_transwin32mouse(ogldispdev, lParam);
00551 glwsrv->MouseFlags = (long) wParam;
00552 glwsrv->WEvents = WIN_RIGHT;
00553 return 0;
00554
00555 case WM_RBUTTONUP:
00556 vmd_transwin32mouse(ogldispdev, lParam);
00557 glwsrv->MouseFlags = (long) wParam;
00558 glwsrv->WEvents = WIN_RIGHT;
00559 if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
00560 ReleaseCapture();
00561 return 0;
00562
00563 case WM_SETCURSOR:
00564
00565
00566
00567 switch (LOWORD(lParam)) {
00568 case HTBOTTOM:
00569 case HTTOP:
00570 SetCursor(LoadCursor(NULL, IDC_SIZENS));
00571 break;
00572
00573 case HTLEFT:
00574 case HTRIGHT:
00575 SetCursor(LoadCursor(NULL, IDC_SIZEWE));
00576 break;
00577
00578 case HTTOPRIGHT:
00579 case HTBOTTOMLEFT:
00580 SetCursor(LoadCursor(NULL, IDC_SIZENESW));
00581 break;
00582
00583 case HTTOPLEFT:
00584 case HTBOTTOMRIGHT:
00585 SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
00586 break;
00587
00588 case HTCAPTION:
00589 SetCursor(LoadCursor(NULL, IDC_ARROW));
00590 break;
00591
00592 case HTCLIENT:
00593 default:
00594 ogldispdev->set_cursor(glwsrv->cursornum);
00595 }
00596 return 0;
00597
00598
00599
00600
00601
00602 case WM_DROPFILES:
00603 {
00604 char lpszFile[4096];
00605 UINT numfiles, fileindex, numc;
00606 HDROP hDropInfo = (HDROP)wParam;
00607
00608
00609 numfiles = DragQueryFile(hDropInfo, (DWORD)(-1), (LPSTR)NULL, 0);
00610
00611 msgInfo << "Ignoring Drag and Drop operation, received "
00612 << ((int) numfiles) << " files:" << sendmsg;
00613
00614 FileSpec spec;
00615 for (fileindex=0; fileindex<numfiles; fileindex++) {
00616
00617 numc = DragQueryFile(hDropInfo, fileindex, (char *) &lpszFile, 4096);
00618
00619
00620
00621
00622 msgInfo << " File(" << ((int) fileindex) << "): " << lpszFile
00623 << " (numc=" << ((int) numc) << ")" << sendmsg;
00624
00625
00626 ogldispdev->vmdapp->molecule_load(-1, lpszFile, NULL, &spec);
00627 }
00628 DragFinish(hDropInfo);
00629 }
00630 return 0;
00631
00632 default:
00633 return DefWindowProc(hwnd, msg, wParam, lParam);
00634 }
00635
00636 return 0;
00637 }
00638
00639
00641
00642 OpenGLDisplayDevice::OpenGLDisplayDevice()
00643 : OpenGLRenderer("VMD " VMDVERSION " OpenGL Display") {
00644
00645 stereoNames = glStereoNameStr;
00646 stereoModes = OPENGL_STEREO_MODES;
00647
00648 renderNames = glRenderNameStr;
00649 renderModes = OPENGL_RENDER_MODES;
00650
00651 cacheNames = glCacheNameStr;
00652 cacheModes = OPENGL_CACHE_MODES;
00653
00654 memset(&glwsrv, 0, sizeof(glwsrv));
00655 have_window = FALSE;
00656 screenX = screenY = 0;
00657 vmdapp = NULL;
00658 }
00659
00660
00661 int OpenGLDisplayDevice::init(int argc, char **argv, VMDApp *app, int *size, int *loc) {
00662 vmdapp = app;
00663
00664
00665 if (open_window(name, size, loc, argc, argv) != 0) return FALSE;
00666 if (!have_window) return FALSE;
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 screenX = GetSystemMetrics(SM_CXSCREEN);
00677 screenY = GetSystemMetrics(SM_CYSCREEN);
00678
00679
00680 ext->hasmultisample = FALSE;
00681 ext->nummultisamples = 0;
00682 aaAvailable = FALSE;
00683
00684
00685 if (ext->hasmultisample) {
00686 aa_on();
00687
00688
00689 }
00690
00691 cueingAvailable = TRUE;
00692 cueing_on();
00693
00694 cullingAvailable = TRUE;
00695 culling_off();
00696
00697 set_sphere_mode(sphereMode);
00698 set_sphere_res(sphereRes);
00699 set_line_width(lineWidth);
00700 set_line_style(lineStyle);
00701
00702
00703 reshape();
00704 normal();
00705 clear();
00706 update();
00707
00708
00709 return TRUE;
00710 }
00711
00712
00713 OpenGLDisplayDevice::~OpenGLDisplayDevice(void) {
00714 if (have_window) {
00715
00716 free_opengl_ctx();
00717
00718 #if VMDSPACEWARE
00719 vmd_closewin32spaceball(&glwsrv);
00720 #endif
00721 }
00722 }
00723
00724
00726
00727
00728 int OpenGLDisplayDevice::open_window(char *nm, int *size, int *loc,
00729 int argc, char** argv) {
00730 int SX = 596, SY = 190;
00731 if (loc) {
00732 SX = loc[0];
00733
00734
00735 SY = screenY - loc[1] - size[1];
00736 }
00737 glwsrv.cursornum = 0;
00738
00739
00740 int rc = OpenWin32Connection(&glwsrv);
00741 if (rc != 0) {
00742 return -1;
00743 }
00744
00745 xOrig = 0;
00746 yOrig = 0;
00747 xSize = size[0];
00748 ySize = size[1];
00749 glwsrv.width = xSize;
00750 glwsrv.height = ySize;
00751 rc = myCreateWindow(this, 0, 0, glwsrv.width, glwsrv.height);
00752 if (rc != 0) {
00753 return -1;
00754 }
00755
00756
00757 if (glwsrv.PFDisStereo == 0) {
00758 ext->hasstereo = FALSE;
00759 } else {
00760 ext->hasstereo = TRUE;
00761 }
00762 ext->stereodrawforced = FALSE;
00763
00764 setup_initial_opengl_state();
00765
00766 #ifdef VMDSPACEWARE
00767 vmd_setupwin32spaceball(&glwsrv);
00768 #endif
00769
00770
00771 have_window = TRUE;
00772
00773 return 0;
00774 }
00775
00776 void OpenGLDisplayDevice::do_resize_window(int width, int height) {
00777 RECT rcClient, rcWindow;
00778 POINT ptDiff;
00779 GetClientRect(glwsrv.hWnd, &rcClient);
00780 GetWindowRect(glwsrv.hWnd, &rcWindow);
00781 ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
00782 ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
00783 MoveWindow(glwsrv.hWnd, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, TRUE);
00784 }
00785
00786 void OpenGLDisplayDevice::do_reposition_window(int xpos, int ypos) {
00787 RECT rcClient, rcWindow;
00788 GetClientRect(glwsrv.hWnd, &rcClient);
00789 GetWindowRect(glwsrv.hWnd, &rcWindow);
00790 MoveWindow(glwsrv.hWnd, xpos, ypos, rcWindow.right-rcWindow.left, rcWindow.bottom-rcWindow.top, TRUE);
00791 }
00792
00793
00795
00796
00797
00798
00799
00800
00801 int OpenGLDisplayDevice::x(void) {
00802 return glwsrv.MouseX;
00803 }
00804
00805
00806 int OpenGLDisplayDevice::y(void) {
00807 return glwsrv.MouseY;
00808 }
00809
00810
00811 int OpenGLDisplayDevice::shift_state(void) {
00812 int retval = 0;
00813
00814 if ((glwsrv.MouseFlags & MK_SHIFT) != 0)
00815 retval |= SHIFT;
00816
00817 if ((glwsrv.MouseFlags & MK_CONTROL) != 0)
00818 retval |= CONTROL;
00819
00820 return retval;
00821 }
00822
00823
00824 int OpenGLDisplayDevice::spaceball(int *rx, int *ry, int *rz, int *tx, int *ty, int *tz, int *buttons) {
00825
00826 #ifdef VMDSPACEWARE
00827 if (glwsrv.sball != NULL) {
00828 *rx = glwsrv.spwevent.u.spwData.mData[SI_RX];
00829 *ry = glwsrv.spwevent.u.spwData.mData[SI_RY];
00830 *rz = glwsrv.spwevent.u.spwData.mData[SI_RZ];
00831 *tx = glwsrv.spwevent.u.spwData.mData[SI_TX];
00832 *ty = glwsrv.spwevent.u.spwData.mData[SI_TY];
00833 *tz = glwsrv.spwevent.u.spwData.mData[SI_TZ];
00834 *buttons = glwsrv.spwevent.u.spwData.bData.current;
00835 return 1;
00836 }
00837 #endif
00838
00839 return 0;
00840 }
00841
00842
00843
00844 void OpenGLDisplayDevice::set_cursor(int n) {
00845 glwsrv.cursornum = n;
00846
00847 switch (n) {
00848 default:
00849 case DisplayDevice::NORMAL_CURSOR:
00850 SetCursor(LoadCursor(NULL, IDC_ARROW));
00851 break;
00852
00853 case DisplayDevice::TRANS_CURSOR:
00854 SetCursor(LoadCursor(NULL, IDC_SIZEALL));
00855 break;
00856
00857 case DisplayDevice::SCALE_CURSOR:
00858 SetCursor(LoadCursor(NULL, IDC_SIZEWE));
00859 break;
00860
00861 case DisplayDevice::PICK_CURSOR:
00862 SetCursor(LoadCursor(NULL, IDC_CROSS));
00863 break;
00864
00865 case DisplayDevice::WAIT_CURSOR:
00866 SetCursor(LoadCursor(NULL, IDC_WAIT));
00867 break;
00868 }
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 void OpenGLDisplayDevice::queue_events(void) {
00880 }
00881
00882
00883
00884 int OpenGLDisplayDevice::read_event(long &retdev, long &retval) {
00885 MSG msg;
00886
00887
00888
00889 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
00890 TranslateMessage(&msg);
00891 DispatchMessage(&msg);
00892 }
00893
00894 retdev = glwsrv.WEvents;
00895
00896 switch (glwsrv.WEvents) {
00897 case WIN_REDRAW:
00898 glwsrv.WEvents = WIN_NOEVENT;
00899
00900 _needRedraw = 1;
00901 return FALSE;
00902
00903 case WIN_KBD:
00904 if (glwsrv.KeyFlag != '\0') {
00905 retval = glwsrv.KeyFlag;
00906 glwsrv.WEvents = WIN_NOEVENT;
00907 return TRUE;
00908 }
00909 break;
00910
00911 case WIN_KBD_ESCAPE:
00912 case WIN_KBD_UP:
00913 case WIN_KBD_DOWN:
00914 case WIN_KBD_LEFT:
00915 case WIN_KBD_RIGHT:
00916 case WIN_KBD_PAGE_UP:
00917 case WIN_KBD_PAGE_DOWN:
00918 case WIN_KBD_HOME:
00919 case WIN_KBD_END:
00920 case WIN_KBD_INSERT:
00921 case WIN_KBD_DELETE:
00922 case WIN_KBD_F1:
00923 case WIN_KBD_F2:
00924 case WIN_KBD_F3:
00925 case WIN_KBD_F4:
00926 case WIN_KBD_F5:
00927 case WIN_KBD_F6:
00928 case WIN_KBD_F7:
00929 case WIN_KBD_F8:
00930 case WIN_KBD_F9:
00931 case WIN_KBD_F10:
00932 case WIN_KBD_F11:
00933 case WIN_KBD_F12:
00934 retval = glwsrv.KeyFlag;
00935 glwsrv.WEvents = WIN_NOEVENT;
00936 return TRUE;
00937
00938 case WIN_WHEELUP:
00939 retval = 1;
00940 glwsrv.WEvents = WIN_NOEVENT;
00941 return TRUE;
00942
00943 case WIN_WHEELDOWN:
00944 retval = 1;
00945 glwsrv.WEvents = WIN_NOEVENT;
00946 return TRUE;
00947
00948 case WIN_LEFT:
00949
00950 retval = (glwsrv.MouseFlags & MK_LBUTTON) != 0;
00951 glwsrv.WEvents = WIN_NOEVENT;
00952 return TRUE;
00953
00954 case WIN_MIDDLE:
00955
00956 retval = (glwsrv.MouseFlags & MK_MBUTTON) != 0;
00957 glwsrv.WEvents = WIN_NOEVENT;
00958 return TRUE;
00959
00960 case WIN_RIGHT:
00961
00962 retval = (glwsrv.MouseFlags & MK_RBUTTON) != 0;
00963 glwsrv.WEvents = WIN_NOEVENT;
00964 return TRUE;
00965 }
00966
00967 retval = 0;
00968 glwsrv.WEvents = WIN_NOEVENT;
00969 return FALSE;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978 void OpenGLDisplayDevice::reshape(void) {
00979
00980
00981
00982 switch (inStereo) {
00983 case OPENGL_STEREO_SIDE:
00984 set_screen_pos(0.5f * (float)xSize / (float)ySize);
00985 break;
00986
00987 case OPENGL_STEREO_ABOVEBELOW:
00988 set_screen_pos(2.0f * (float)xSize / (float)ySize);
00989 break;
00990
00991 case OPENGL_STEREO_STENCIL_CHECKERBOARD:
00992 case OPENGL_STEREO_STENCIL_COLUMNS:
00993 case OPENGL_STEREO_STENCIL_ROWS:
00994 enable_stencil_stereo(inStereo);
00995 set_screen_pos((float)xSize / (float)ySize);
00996 break;
00997
00998 default:
00999 set_screen_pos((float)xSize / (float)ySize);
01000 break;
01001 }
01002 }
01003
01004 unsigned char * OpenGLDisplayDevice::readpixels(int &x, int &y) {
01005 unsigned char * img;
01006
01007 x = xSize;
01008 y = ySize;
01009
01010 if ((img = (unsigned char *) malloc(x * y * 3)) != NULL) {
01011 glPixelStorei(GL_PACK_ALIGNMENT, 1);
01012 glReadPixels(0, 0, x, y, GL_RGB, GL_UNSIGNED_BYTE, img);
01013 } else {
01014 x = 0;
01015 y = 0;
01016 }
01017
01018 return img;
01019 }
01020
01021
01022
01023 void OpenGLDisplayDevice::update(int do_update) {
01024 glFlush();
01025
01026 if(do_update)
01027 SwapBuffers(glwsrv.hDC);
01028
01029 glDrawBuffer(GL_BACK);
01030 }
01031
01032