29 #include <sys/types.h>
30 #include <sys/timeb.h>
37 extern void InitModel();
38 extern void RenderModel();
39 extern Vector model_position;
40 extern Quaternion model_orientation;
50 Vector OldMouseVector;
52 float ViewAngle=45.0f;
55 HPALETTE hPalette = 0;
59 static int timeinit=0;
60 static int start,start2,current,last;
61 static int frame=0, frame2=0;
69 current=timeGetTime();
70 double dif=(double)(current-start)/CLOCKS_PER_SEC;
71 double rv = (dif)? (
double)frame/(double)dif:-1.0;
72 if(dif>2.0 && frame >10) {
75 start2 = timeGetTime();
78 DeltaT = (float)(current-last)/CLOCKS_PER_SEC;
80 DeltaT = 0.1f/CLOCKS_PER_SEC;
88 void ComputeMouseVector(){
89 OldMouseVector=MouseVector;
90 float spread = (float)
tan(ViewAngle/2*3.14/180);
91 float y = spread * ((Height-MouseY)-Height/2.0
f) /(Height/2.0f);
92 float x = spread * (MouseX-Width/2.0f) /(Height/2.0
f);
99 Quaternion VirtualTrackBall(Vector cop,Vector cor,Vector dir1,Vector dir2) {
110 Vector nrml = cor - cop;
111 float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f);
113 float dist = -(nrml^cor);
114 Vector u= planelineintersection(nrml,dist,cop,cop+dir1);
118 if(m>1) {u=u*1.0f/m;}
120 u=u - (nrml * (float)
sqrt(1-m*m));
122 Vector v= planelineintersection(nrml,dist,cop,cop+dir2);
126 if(m>1) {v=v*1.0f/m;}
128 v=v - (nrml * (float)
sqrt(1-m*m));
134 Quaternion q(Vector(1.0
f,0.0
f,0.0
f),0.0
f);
135 if(m>0 && (angle=(
float)
asin(m))>3.14/180) {
137 q=Quaternion(axis,angle);
144 Quaternion q=VirtualTrackBall(Vector(0,0,0),model_position,
145 OldMouseVector,MouseVector);
146 model_orientation=q*model_orientation;
149 void Reshape(
int width,
int height){
153 glViewport(0, 0, width, height);
154 glMatrixMode(GL_PROJECTION);
156 gluPerspective(ViewAngle, (
float)width/height, 0.1, 50.0);
157 glMatrixMode(GL_MODELVIEW);
162 char buf[1024];buf[0]=
'\0';
163 sprintf(buf,
"FPS: %5.2f ",FPS);
164 PostString(buf,0,-1,0);
169 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
183 LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
185 static PAINTSTRUCT ps;
186 static GLboolean left = GL_FALSE;
187 static GLboolean right = GL_FALSE;
188 static int omx, omy, mx, my;
192 BeginPaint(hWnd, &ps);
196 Reshape(LOWORD(lParam), HIWORD(lParam));
197 PostMessage(hWnd, WM_PAINT, 0, 0);
211 MouseX = LOWORD(lParam);
212 MouseY = HIWORD(lParam);
213 ComputeMouseVector();
218 MouseX = LOWORD(lParam);
219 MouseY = HIWORD(lParam);
220 if(MouseX & 1 << 15) MouseX -= (1 << 16);
221 if(MouseY & 1 << 15) MouseY -= (1 << 16);
222 ComputeMouseVector();
223 if(MouseState) SpinIt();
230 MouseX = LOWORD(lParam);
231 MouseY = HIWORD(lParam);
237 if(MouseX & 1 << 15) MouseX -= (1 << 16);
238 if(MouseY & 1 << 15) MouseY -= (1 << 16);
239 ComputeMouseVector();
240 if(MouseState) SpinIt();
243 case WM_PALETTECHANGED:
244 if (hWnd == (HWND)wParam)
break;
246 case WM_QUERYNEWPALETTE:
248 UnrealizeObject(hPalette);
249 SelectPalette(hDC, hPalette, FALSE);
259 return DefWindowProc(hWnd, uMsg, wParam, lParam);
262 HWND CreateOpenGLWindow(
char* title)
269 PIXELFORMATDESCRIPTOR pfd;
270 static HINSTANCE hInstance = 0;
274 hInstance = GetModuleHandle(NULL);
276 wc.lpfnWndProc = (WNDPROC)WindowProc;
279 wc.hInstance = hInstance;
280 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
281 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
282 wc.hbrBackground = NULL;
283 wc.lpszMenuName = NULL;
284 wc.lpszClassName =
"OpenGL";
286 if (!RegisterClass(&wc)) {
287 MessageBox(NULL,
"RegisterClass() failed: "
288 "Cannot register window class.",
"Error", MB_OK);
293 hWnd = CreateWindow(
"OpenGL", title, WS_OVERLAPPEDWINDOW |
294 WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
295 0,0,Width,Height, NULL, NULL, hInstance, NULL);
298 MessageBox(NULL,
"CreateWindow() failed: Cannot create a window.",
307 memset(&pfd, 0,
sizeof(pfd));
308 pfd.nSize =
sizeof(pfd);
310 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
311 pfd.iPixelType = PFD_TYPE_RGBA;
315 pf = ChoosePixelFormat(hDC, &pfd);
317 MessageBox(NULL,
"ChoosePixelFormat() failed: "
318 "Cannot find a suitable pixel format.",
"Error", MB_OK);
322 if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
323 MessageBox(NULL,
"SetPixelFormat() failed: "
324 "Cannot set format specified.",
"Error", MB_OK);
328 DescribePixelFormat(hDC, pf,
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
330 if (pfd.dwFlags & PFD_NEED_PALETTE ||
331 pfd.iPixelType == PFD_TYPE_COLORINDEX) {
333 n = 1 << pfd.cColorBits;
334 if (n > 256) n = 256;
336 lpPal = (LOGPALETTE*)malloc(
sizeof(LOGPALETTE) +
337 sizeof(PALETTEENTRY) * n);
338 memset(lpPal, 0,
sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * n);
339 lpPal->palVersion = 0x300;
340 lpPal->palNumEntries = n;
342 GetSystemPaletteEntries(hDC, 0, n, &lpPal->palPalEntry[0]);
346 if (pfd.iPixelType == PFD_TYPE_RGBA) {
347 int redMask = (1 << pfd.cRedBits) - 1;
348 int greenMask = (1 << pfd.cGreenBits) - 1;
349 int blueMask = (1 << pfd.cBlueBits) - 1;
353 for (i = 0; i < n; ++i) {
354 lpPal->palPalEntry[i].peRed =
355 (((i >> pfd.cRedShift) & redMask) * 255)/redMask;
356 lpPal->palPalEntry[i].peGreen =
357 (((i >> pfd.cGreenShift) & greenMask) * 255)/greenMask;
358 lpPal->palPalEntry[i].peBlue =
359 (((i >> pfd.cBlueShift) & blueMask) * 255)/blueMask;
360 lpPal->palPalEntry[i].peFlags = 0;
363 lpPal->palPalEntry[0].peRed = 0;
364 lpPal->palPalEntry[0].peGreen = 0;
365 lpPal->palPalEntry[0].peBlue = 0;
366 lpPal->palPalEntry[0].peFlags = PC_NOCOLLAPSE;
367 lpPal->palPalEntry[1].peRed = 255;
368 lpPal->palPalEntry[1].peGreen = 0;
369 lpPal->palPalEntry[1].peBlue = 0;
370 lpPal->palPalEntry[1].peFlags = PC_NOCOLLAPSE;
371 lpPal->palPalEntry[2].peRed = 0;
372 lpPal->palPalEntry[2].peGreen = 255;
373 lpPal->palPalEntry[2].peBlue = 0;
374 lpPal->palPalEntry[2].peFlags = PC_NOCOLLAPSE;
375 lpPal->palPalEntry[3].peRed = 0;
376 lpPal->palPalEntry[3].peGreen = 0;
377 lpPal->palPalEntry[3].peBlue = 255;
378 lpPal->palPalEntry[3].peFlags = PC_NOCOLLAPSE;
381 hPalette = CreatePalette(lpPal);
383 SelectPalette(hDC, hPalette, FALSE);
390 ReleaseDC(hDC, hWnd);
394 int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
395 LPSTR lpszCmdLine,
int nCmdShow)
408 hWnd = CreateOpenGLWindow(
"bunnylod by Stan Melax");
409 if (hWnd == NULL)
exit(1);
412 hRC = wglCreateContext(hDC);
413 wglMakeCurrent(hDC, hRC);
414 ShowWindow(hWnd, nCmdShow);
415 glEnable(GL_DEPTH_TEST);
417 PostString(
"Demo by Stan Melax (c)1998",5,-5,20);
418 PostString(
"Model by Viewpoint Datalabs (c)1996",5,-4,20);
420 PostString(
"Mesh Reduction Algorithm (non-optimized)",1,0,5);
421 sprintf(buf,
"was executed in %5.3f seconds",DeltaT);
422 PostString(buf,2,1,6);
425 while(PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE)) {
426 if(GetMessage(&msg, hWnd, 0, 0)) {
427 TranslateMessage(&msg);
428 DispatchMessage(&msg);
438 wglMakeCurrent(NULL, NULL);
439 ReleaseDC(hDC, hWnd);
440 wglDeleteContext(hRC);
442 if (hPalette) DeleteObject(hPalette);