/*********************************************************************** * * ELMER, A Computational Fluid Dynamics Program. * * Copyright 1st April 1995 - , Center for Scientific Computing, * Finland. * * All rights reserved. No part of this program may be used, * reproduced or transmitted in any form or by any means * without the written permission of CSC. * * Address: Center for Scientific Computing * Tietotie 6, P.O. BOX 405 * 02101 Espoo, Finland * Tel. +358 0 457 2001 * Telefax: +358 0 457 2302 * EMail: Jari.Jarvinen@csc.fi ************************************************************************/ /*********************************************************************** Program: ELMER Front Module: ecif_oglWIN32renderer.hpp Language: C++ Date: 08.04.97 Version: 1.00 Author(s): Martti Verho Revisions: Abstract: Include type file. WIN specific parts for OGLrenderer class. ************************************************************************/ #define WM_INIT WM_USER // WIN32 codes: //MK_LBUTTON 0x0001 //MK_RBUTTON 0x0002 //MK_SHIFT 0x0004 //MK_CONTROL 0x0008 //MK_MBUTTON 0x0010 void setDCPixelFormat(HDC hdc); void Renderer_OGL::createGLWindow(Hinst app_instance, const char* pName, int xPos, int yPos, int pWidth, int pHeight, WindowInfo& winfo) { winfo.display = NULL; WNDCLASS wndclass; wndclass.lpszClassName = oglWinClass; wndclass.hInstance = app_instance; wndclass.lpfnWndProc = windowProcedure; wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(LONG); RegisterClass(&wndclass ); HWND hWnd = CreateWindow( oglWinClass, pName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, xPos,//CW_USEDEFAULT, yPos,//CW_USEDEFAULT, pWidth, pHeight, HWND_DESKTOP, NULL, app_instance, NULL); winfo.window = hWnd; // Create GL-rendering contex and attach window to it. HDC hdc = GetDC(hWnd); setDCPixelFormat(hdc); HGLRC hrc = wglCreateContext(hdc); wglMakeCurrent(hdc, hrc); } // First a helper functions. void Renderer_OGL::destroyWindow(Hdisplay* display, Hwindow window) { DestroyWindow(window); status = HAS_NO_WINDOW; visible = FALSE; } // *** This must be defined, but not really used in WIN32 *** void Renderer_OGL::dummyWindowProc() { } void Renderer::findRendererWindowSize(int& w, int& h) { RECT rect; //int result = GetWindowRect(rendererWindow, &rect); int result = GetClientRect(rendererWindow, &rect); w = rect.right - rect.left; h = rect.bottom - rect.top ; } void Renderer_OGL::paintRenderer() { SendMessage(rendererWindow, WM_INIT, 0, 0L); ShowWindow(rendererWindow, SW_SHOWNORMAL); //UpdateWindow(rendererWindow); Renderer::visible = TRUE; refresh(); } // Function sets the pixel format for a device context. // Needed in order to create a OpenGL-rendering context. void setDCPixelFormat(HDC hdc) { HANDLE hHeap; int nColors, i; LPLOGPALETTE lpPalette; BYTE byRedMask, byGreenMask, byBlueMask; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure 1, // Version number PFD_DRAW_TO_WINDOW | // Flags PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, // Use RGBA pixel values 24, // Try to use 24-bit color 0, 0, 0, 0, 0, 0, // Don't care about these 0, 0, // No alpha buffer 32, 0, 0, 0, 0, // 32-bit accumulation buffer 32, // 32-bit depth buffer 0, // No stencil buffer 0, // No auxiliary buffers PFD_MAIN_PLANE, // Layer type 0, // Reserved (must be 0) 0, 0, 0 // No layer masks }; int nPixelFormat; nPixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, nPixelFormat, &pfd); DescribePixelFormat(hdc, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); if(pfd.dwFlags & PFD_NEED_PALETTE) { nColors = 1 << pfd.cColorBits; hHeap = GetProcessHeap(); lpPalette = (LPLOGPALETTE) HeapAlloc(hHeap, 0, sizeof(LOGPALETTE) + (nColors * sizeof(PALETTEENTRY))); lpPalette->palVersion = 0x300; lpPalette->palNumEntries = nColors; byRedMask = (1 << pfd.cRedBits) - 1; byGreenMask = (1 << pfd.cGreenBits) - 1; byBlueMask = (1 << pfd.cBlueBits) - 1; for(i = 0; i < nColors; i++) { lpPalette->palPalEntry[i].peRed = (((i >> pfd.cRedShift) & byRedMask) * 255) / byRedMask; lpPalette->palPalEntry[i].peGreen = (((i >> pfd.cGreenShift) & byGreenMask) * 255) / byGreenMask; lpPalette->palPalEntry[i].peBlue = (((i >> pfd.cBlueShift) & byBlueMask) * 255) / byBlueMask; lpPalette->palPalEntry[i].peFlags = 0; } // Create the palette and free the allocated memory HPALETTE m_hPalette = CreatePalette(lpPalette); HeapFree(hHeap, 0, lpPalette); // Realize the color palette if(m_hPalette != NULL) { SelectPalette(hdc, m_hPalette, FALSE); RealizePalette(hdc); } } } void Renderer_OGL::setWindowTitle(char* title) { // Call Win32 API function SetWindowText(rendererWindow, title); } void Renderer_OGL::swapBuffers() { SwapBuffers(wglGetCurrentDC()); } // *** WIN32 WindowProc for the OGLRenderer *** LresCallback Renderer_OGL::windowProcedure(Hwindow hWnd, Event wMsg, Wparam wParam, Lparam lParam) { //RECT rect; ////bool result = GetWindowRect(rendererWindow, &rect); //bool result = GetClientRect(hWnd, &rect); //int x_size = rect.right - rect.left; //int y_size = rect.bottom - rect.top; Renderer* renderer = theControlCenter->getRenderer(); if (renderer == NULL) return DefWindowProc(hWnd, wMsg, wParam, lParam); int x_size, y_size; renderer->getRendererWindowSize(x_size, y_size); HDC hdc; PAINTSTRUCT ps; static int xPos1 = -1; static int yPos1 = -1; int xPos2, yPos2; int keyCode = -1; static bool ctrlPressed = false; switch (wMsg) { case WM_INIT: break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); display(renderer); EndPaint(hWnd, &ps); return 0; case WM_SIZE: renderer->reshape(); break; case WM_MOVE: case WM_MOVING: //theUI->generateEvent(); break; case WM_MOUSEMOVE: if ( wParam != 0 && xPos1 != -1 ) { xPos2 = LOWORD(lParam); yPos2 = y_size - HIWORD(lParam); mouse_move_action(int(wParam), xPos1, xPos2, yPos1, yPos2); xPos1 = xPos2; yPos1 = yPos2; } else if ( wParam != 0 ) { xPos1 = LOWORD(lParam); yPos1 = y_size - HIWORD(lParam); } break; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: xPos1 = LOWORD(lParam); yPos1 = y_size - HIWORD(lParam); if ( wParam & (MK_SHIFT | MK_CONTROL) ) { mouse_clck_action(int(wParam), xPos1, yPos1); } break; case WM_MBUTTONDOWN: xPos1 = LOWORD(lParam); yPos1 = y_size - HIWORD(lParam); break; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: xPos1 = -1; yPos1 = -1; break; case WM_LBUTTONDBLCLK: xPos1 = LOWORD(lParam); yPos1 = y_size - HIWORD(lParam); mouse_dblclck_action(int(wParam), xPos1, yPos1); break; case WM_KEYDOWN: keyCode = wParam; // Ctrl pressed if ( keyCode == VK_CONTROL ) { ctrlPressed = true; } // A letter pressed while Ctrl-key is down if (ctrlPressed) { switch (keyCode) { case 'b': case 'B': theControlCenter->handleKeyAction(KEY_CTRL_B); break; case 'h': case 'H': theControlCenter->handleKeyAction(KEY_CTRL_H); break; case 'l': case 'L': theControlCenter->handleKeyAction(KEY_CTRL_L); break; case 'r': case 'R': theControlCenter->handleKeyAction(KEY_CTRL_R); break; case 'x': case 'X': theControlCenter->handleKeyAction(KEY_CTRL_X); break; case 'y': case 'Y': theControlCenter->handleKeyAction(KEY_CTRL_Y); break; case 'z': case 'Z': theControlCenter->handleKeyAction(KEY_CTRL_Z); break; } } return 0; case WM_KEYUP: keyCode = wParam; // Ctrl released if ( keyCode == VK_CONTROL ) { ctrlPressed = false; } return 0; case WM_CLOSE: theControlCenter->rendererIsClosed(); break; case WM_DESTROY: { // Possible GL-rendering context is released Hglrc hrc = wglGetCurrentContext(); if (hrc) { Hdc hdc = wglGetCurrentDC(); wglMakeCurrent(NULL, NULL); wglDeleteContext(hrc); ReleaseDC(hWnd, hdc); } //status = HAS_NO_WINDOW; } break; case WM_QUIT: break; default: break; } return DefWindowProc(hWnd, wMsg, wParam, lParam); }