PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/applications/utilities/surface/surfaceCoarsen/bunnylod/winmain.C

https://gitlab.com/johnvarv/OpenFOAM-3.0.x
C | 453 lines | 345 code | 49 blank | 59 comment | 43 complexity | 4b11d16aab996e3c3f1044711d4aed85 MD5 | raw file
  1. /*
  2. * Polygon Reduction Demo by Stan Melax (c) 1998
  3. * Permission to use any of this code wherever you want is granted..
  4. * Although, please do acknowledge authorship if appropriate.
  5. *
  6. * This module contains the window setup code, mouse input, timing
  7. * routines, and that sort of stuff. The interesting modules
  8. * to see are bunnygut.cpp and progmesh.cpp.
  9. *
  10. * The windows 95 specific code for this application was taken from
  11. * an example of processing mouse events in an OpenGL program using
  12. * the Win32 API from the www.opengl.org web site.
  13. *
  14. * Under Project->Settings, Link Options, General Category
  15. * Add:
  16. * Opengl32.lib glu32.lib winmm.lib
  17. * to the Object/Library Modules
  18. *
  19. * You will need have OpenGL libs and include files to compile this
  20. * Go to the www.opengl.org web site if you need help with this.
  21. */
  22. #include <windows.h> /* must include this before GL/gl.h */
  23. #include <GL/gl.h> /* OpenGL header file */
  24. #include <GL/glu.h> /* OpenGL utilities header file */
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <sys/timeb.h>
  28. #include <time.h>
  29. #include "vector.h"
  30. #include "font.h"
  31. // Functions and Variables from bunny module
  32. extern void InitModel();
  33. extern void RenderModel();
  34. extern Vector model_position; // position of bunny
  35. extern Quaternion model_orientation; // orientation of bunny
  36. // Global Variables
  37. float DeltaT = 0.1f;
  38. float FPS;
  39. int Width = 512;
  40. int Height = 512;
  41. int MouseX = 0;
  42. int MouseY = 0;
  43. Vector MouseVector; // 3D direction mouse points
  44. Vector OldMouseVector;
  45. int MouseState=0; // true iff left button down
  46. float ViewAngle=45.0f;
  47. HDC hDC; /* device context */
  48. HPALETTE hPalette = 0; /* custom palette (if needed) */
  49. void CalcFPSDeltaT(){
  50. static int timeinit=0;
  51. static int start,start2,current,last;
  52. static int frame=0, frame2=0;
  53. if(!timeinit){
  54. frame=0;
  55. start=timeGetTime();
  56. timeinit=1;
  57. }
  58. frame++;
  59. frame2++;
  60. current=timeGetTime(); // found in winmm.lib
  61. double dif=(double)(current-start)/CLOCKS_PER_SEC;
  62. double rv = (dif)? (double)frame/(double)dif:-1.0;
  63. if(dif>2.0 && frame >10) {
  64. start = start2;
  65. frame = frame2;
  66. start2 = timeGetTime();
  67. frame2 = 0;
  68. }
  69. DeltaT = (float)(current-last)/CLOCKS_PER_SEC;
  70. if(current==last) {
  71. DeltaT = 0.1f/CLOCKS_PER_SEC; // it just cant be 0
  72. }
  73. // if(DeltaT>1.0) DeltaT=1.0;
  74. FPS = (float)rv;
  75. last = current;
  76. }
  77. void ComputeMouseVector(){
  78. OldMouseVector=MouseVector;
  79. float spread = (float)tan(ViewAngle/2*3.14/180);
  80. float y = spread * ((Height-MouseY)-Height/2.0f) /(Height/2.0f);
  81. float x = spread * (MouseX-Width/2.0f) /(Height/2.0f);
  82. Vector v(x ,y,-1);
  83. // v=UserOrientation *v;
  84. v=normalize(v);
  85. MouseVector = v;
  86. }
  87. Quaternion VirtualTrackBall(Vector cop,Vector cor,Vector dir1,Vector dir2) {
  88. // Implement track ball functionality to spin stuf on the screen
  89. // cop center of projection
  90. // cor center of rotation
  91. // dir1 old mouse direction
  92. // dir2 new mouse direction
  93. // pretend there is a sphere around cor. Then find the points
  94. // where dir1 and dir2 intersect that sphere. Find the
  95. // rotation that takes the first point to the second.
  96. float m;
  97. // compute plane
  98. Vector nrml = cor - cop;
  99. // since trackball proportional to distance from cop
  100. float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f);
  101. nrml = normalize(nrml);
  102. float dist = -(nrml^cor);
  103. Vector u= planelineintersection(nrml,dist,cop,cop+dir1);
  104. u=u-cor;
  105. u=u*fudgefactor;
  106. m= magnitude(u);
  107. if(m>1) {u=u*1.0f/m;}
  108. else {
  109. u=u - (nrml * (float)sqrt(1-m*m));
  110. }
  111. Vector v= planelineintersection(nrml,dist,cop,cop+dir2);
  112. v=v-cor;
  113. v=v*fudgefactor;
  114. m= magnitude(v);
  115. if(m>1) {v=v*1.0f/m;}
  116. else {
  117. v=v - (nrml * (float)sqrt(1-m*m));
  118. }
  119. Vector axis = u*v;
  120. float angle;
  121. m=magnitude(axis);
  122. if(m>1)m=1; // avoid potential floating point error
  123. Quaternion q(Vector(1.0f,0.0f,0.0f),0.0f);
  124. if(m>0 && (angle=(float)asin(m))>3.14/180) {
  125. axis = normalize(axis);
  126. q=Quaternion(axis,angle);
  127. }
  128. return q;
  129. }
  130. void SpinIt(){
  131. // Change the orientation of the bunny according to mouse drag
  132. Quaternion q=VirtualTrackBall(Vector(0,0,0),model_position,
  133. OldMouseVector,MouseVector);
  134. model_orientation=q*model_orientation;
  135. }
  136. void Reshape(int width, int height){
  137. // called initially and when the window changes size
  138. Width=width;
  139. Height=height;
  140. glViewport(0, 0, width, height);
  141. glMatrixMode(GL_PROJECTION);
  142. glLoadIdentity();
  143. gluPerspective(ViewAngle, (float)width/height, 0.1, 50.0);
  144. glMatrixMode(GL_MODELVIEW);
  145. glLoadIdentity();
  146. }
  147. void PrintStats(){
  148. char buf[1024];buf[0]='\0';
  149. sprintf(buf,"FPS: %5.2f ",FPS);
  150. PostString(buf,0,-1,0);
  151. }
  152. void Display(){
  153. // main drawing routine - called every frame
  154. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  155. glPushMatrix();
  156. glLoadIdentity();
  157. // camera at default (zero) position and orientation
  158. RenderModel();
  159. PrintStats();
  160. glLoadIdentity();
  161. RenderStrings();
  162. glPopMatrix();
  163. glFlush();
  164. SwapBuffers(hDC); /* nop if singlebuffered */
  165. }
  166. LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  167. {
  168. static PAINTSTRUCT ps;
  169. static GLboolean left = GL_FALSE; /* left button currently down? */
  170. static GLboolean right = GL_FALSE; /* right button currently down? */
  171. static int omx, omy, mx, my;
  172. switch(uMsg) {
  173. case WM_PAINT:
  174. BeginPaint(hWnd, &ps);
  175. EndPaint(hWnd, &ps);
  176. return 0;
  177. case WM_SIZE:
  178. Reshape(LOWORD(lParam), HIWORD(lParam));
  179. PostMessage(hWnd, WM_PAINT, 0, 0);
  180. return 0;
  181. case WM_CHAR:
  182. switch (wParam) {
  183. case 27: /* ESC key */
  184. PostQuitMessage(0);
  185. break;
  186. }
  187. return 0;
  188. case WM_LBUTTONDOWN:
  189. /* if we don't set the capture we won't get mouse move
  190. messages when the mouse moves outside the window. */
  191. SetCapture(hWnd);
  192. MouseX = LOWORD(lParam);
  193. MouseY = HIWORD(lParam);
  194. ComputeMouseVector();
  195. MouseState = 1;
  196. return 0;
  197. case WM_LBUTTONUP:
  198. MouseX = LOWORD(lParam);
  199. MouseY = HIWORD(lParam);
  200. if(MouseX & 1 << 15) MouseX -= (1 << 16);
  201. if(MouseY & 1 << 15) MouseY -= (1 << 16);
  202. ComputeMouseVector();
  203. if(MouseState) SpinIt();
  204. MouseState=0;
  205. /* remember to release the capture when we are finished. */
  206. ReleaseCapture();
  207. return 0;
  208. case WM_MOUSEMOVE:
  209. MouseX = LOWORD(lParam);
  210. MouseY = HIWORD(lParam);
  211. /* Win32 is pretty braindead about the x, y position that
  212. it returns when the mouse is off the left or top edge
  213. of the window (due to them being unsigned). therefore,
  214. roll the Win32's 0..2^16 pointer co-ord range to the
  215. more amenable (and useful) 0..+/-2^15. */
  216. if(MouseX & 1 << 15) MouseX -= (1 << 16);
  217. if(MouseY & 1 << 15) MouseY -= (1 << 16);
  218. ComputeMouseVector();
  219. if(MouseState) SpinIt();
  220. return 0;
  221. case WM_PALETTECHANGED:
  222. if (hWnd == (HWND)wParam) break;
  223. /* fall through to WM_QUERYNEWPALETTE */
  224. case WM_QUERYNEWPALETTE:
  225. if (hPalette) {
  226. UnrealizeObject(hPalette);
  227. SelectPalette(hDC, hPalette, FALSE);
  228. RealizePalette(hDC);
  229. return TRUE;
  230. }
  231. return FALSE;
  232. case WM_CLOSE:
  233. PostQuitMessage(0);
  234. return 0;
  235. }
  236. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  237. }
  238. HWND CreateOpenGLWindow(char* title)
  239. {
  240. // make a double-buffered, rgba, opengl window
  241. int n, pf;
  242. HWND hWnd;
  243. WNDCLASS wc;
  244. LOGPALETTE* lpPal;
  245. PIXELFORMATDESCRIPTOR pfd;
  246. static HINSTANCE hInstance = 0;
  247. /* only register the window class once - use hInstance as a flag. */
  248. if (!hInstance) {
  249. hInstance = GetModuleHandle(NULL);
  250. wc.style = CS_OWNDC;
  251. wc.lpfnWndProc = (WNDPROC)WindowProc;
  252. wc.cbClsExtra = 0;
  253. wc.cbWndExtra = 0;
  254. wc.hInstance = hInstance;
  255. wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
  256. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  257. wc.hbrBackground = NULL;
  258. wc.lpszMenuName = NULL;
  259. wc.lpszClassName = "OpenGL";
  260. if (!RegisterClass(&wc)) {
  261. MessageBox(NULL, "RegisterClass() failed: "
  262. "Cannot register window class.",
  263. "Error", MB_OK);
  264. return NULL;
  265. }
  266. }
  267. hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
  268. WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  269. 0,0,Width,Height, NULL, NULL, hInstance, NULL);
  270. if (hWnd == NULL) {
  271. MessageBox(NULL,
  272. "CreateWindow() failed: Cannot create a window.",
  273. "Error", MB_OK);
  274. return NULL;
  275. }
  276. hDC = GetDC(hWnd);
  277. /* there is no guarantee that the contents of the stack that become
  278. the pfd are zeroed, therefore _make sure_ to clear these bits. */
  279. memset(&pfd, 0, sizeof(pfd));
  280. pfd.nSize = sizeof(pfd);
  281. pfd.nVersion = 1;
  282. pfd.dwFlags = PFD_DRAW_TO_WINDOW
  283. | PFD_SUPPORT_OPENGL
  284. | PFD_DOUBLEBUFFER;
  285. pfd.iPixelType = PFD_TYPE_RGBA;
  286. pfd.cDepthBits = 32;
  287. pfd.cColorBits = 32;
  288. pf = ChoosePixelFormat(hDC, &pfd);
  289. if (pf == 0) {
  290. MessageBox(NULL, "ChoosePixelFormat() failed: "
  291. "Cannot find a suitable pixel format.",
  292. "Error", MB_OK);
  293. return 0;
  294. }
  295. if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
  296. MessageBox(NULL, "SetPixelFormat() failed: "
  297. "Cannot set format specified.", "Error", MB_OK);
  298. return 0;
  299. }
  300. DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  301. if (pfd.dwFlags & PFD_NEED_PALETTE ||
  302. pfd.iPixelType == PFD_TYPE_COLORINDEX) {
  303. n = 1 << pfd.cColorBits;
  304. if (n > 256) n = 256;
  305. lpPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
  306. sizeof(PALETTEENTRY) * n);
  307. memset(lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
  308. lpPal->palVersion = 0x300;
  309. lpPal->palNumEntries = n;
  310. GetSystemPaletteEntries(hDC, 0, n, &lpPal->palPalEntry[0]);
  311. /* if the pixel type is RGBA, then we want to make an RGB ramp,
  312. otherwise (color index) set individual colors. */
  313. if (pfd.iPixelType == PFD_TYPE_RGBA) {
  314. int redMask = (1 << pfd.cRedBits) - 1;
  315. int greenMask = (1 << pfd.cGreenBits) - 1;
  316. int blueMask = (1 << pfd.cBlueBits) - 1;
  317. int i;
  318. /* fill in the entries with an RGB color ramp. */
  319. for (i = 0; i < n; ++i) {
  320. lpPal->palPalEntry[i].peRed =
  321. (((i >> pfd.cRedShift) & redMask) * 255)
  322. /redMask;
  323. lpPal->palPalEntry[i].peGreen =
  324. (((i >> pfd.cGreenShift) & greenMask) * 255)
  325. /greenMask;
  326. lpPal->palPalEntry[i].peBlue =
  327. (((i >> pfd.cBlueShift) & blueMask) * 255)
  328. /blueMask;
  329. lpPal->palPalEntry[i].peFlags = 0;
  330. }
  331. } else {
  332. lpPal->palPalEntry[0].peRed = 0;
  333. lpPal->palPalEntry[0].peGreen = 0;
  334. lpPal->palPalEntry[0].peBlue = 0;
  335. lpPal->palPalEntry[0].peFlags = PC_NOCOLLAPSE;
  336. lpPal->palPalEntry[1].peRed = 255;
  337. lpPal->palPalEntry[1].peGreen = 0;
  338. lpPal->palPalEntry[1].peBlue = 0;
  339. lpPal->palPalEntry[1].peFlags = PC_NOCOLLAPSE;
  340. lpPal->palPalEntry[2].peRed = 0;
  341. lpPal->palPalEntry[2].peGreen = 255;
  342. lpPal->palPalEntry[2].peBlue = 0;
  343. lpPal->palPalEntry[2].peFlags = PC_NOCOLLAPSE;
  344. lpPal->palPalEntry[3].peRed = 0;
  345. lpPal->palPalEntry[3].peGreen = 0;
  346. lpPal->palPalEntry[3].peBlue = 255;
  347. lpPal->palPalEntry[3].peFlags = PC_NOCOLLAPSE;
  348. }
  349. hPalette = CreatePalette(lpPal);
  350. if (hPalette) {
  351. SelectPalette(hDC, hPalette, FALSE);
  352. RealizePalette(hDC);
  353. }
  354. free(lpPal);
  355. }
  356. ReleaseDC(hDC, hWnd);
  357. return hWnd;
  358. }
  359. int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
  360. LPSTR lpszCmdLine, int nCmdShow)
  361. {
  362. HGLRC hRC; /* opengl context */
  363. HWND hWnd; /* window */
  364. MSG msg; /* message */
  365. // InitModel() initializes some data structures and
  366. // does the progressive mesh polygon reduction algorithm
  367. // on the model.
  368. CalcFPSDeltaT(); // to time the algorithm
  369. InitModel();
  370. CalcFPSDeltaT();
  371. hWnd = CreateOpenGLWindow("bunnylod by Stan Melax");
  372. if (hWnd == NULL) exit(1);
  373. hDC = GetDC(hWnd);
  374. hRC = wglCreateContext(hDC);
  375. wglMakeCurrent(hDC, hRC);
  376. ShowWindow(hWnd, nCmdShow);
  377. glEnable(GL_DEPTH_TEST);
  378. PostString("Demo by Stan Melax (c)1998",5,-5,20);
  379. PostString("Model by Viewpoint Datalabs (c)1996",5,-4,20);
  380. char buf[128];
  381. PostString("Mesh Reduction Algorithm (non-optimized)",1,0,5);
  382. sprintf(buf,"was executed in %5.3f seconds",DeltaT);
  383. PostString(buf,2,1,6);
  384. while (1) {
  385. while(PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE)) {
  386. if(GetMessage(&msg, hWnd, 0, 0)) {
  387. TranslateMessage(&msg);
  388. DispatchMessage(&msg);
  389. } else {
  390. // This 'goto' was in the sample code
  391. goto quit;
  392. }
  393. }
  394. CalcFPSDeltaT();
  395. Display();
  396. }
  397. quit:
  398. wglMakeCurrent(NULL, NULL);
  399. ReleaseDC(hDC, hWnd);
  400. wglDeleteContext(hRC);
  401. DestroyWindow(hWnd);
  402. if (hPalette) DeleteObject(hPalette);
  403. return msg.wParam;
  404. }