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