762 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			762 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <windows.h>
 | |
| #include <stdio.h>
 | |
| #include <math.h>
 | |
| 
 | |
| #include <GL\gl.h>
 | |
| #include <GL\glu.h>
 | |
| 
 | |
| #include "mesh.h"
 | |
| #include "trackbal.h"
 | |
| #include "globals.h"
 | |
| 
 | |
| static const RGBA lightAmbient   = {0.21f, 0.21f, 0.21f, 1.0f};
 | |
| static const RGBA light0Ambient  = {0.0f, 0.0f, 0.0f, 1.0f};
 | |
| static const RGBA light0Diffuse  = {0.7f, 0.7f, 0.7f, 1.0f};
 | |
| static const RGBA light0Specular = {1.0f, 1.0f, 1.0f, 1.0f};
 | |
| static const GLfloat light0Pos[]      = {100.0f, 100.0f, 100.0f, 0.0f};
 | |
| 
 | |
| #define PALETTE_PER_MATL    32
 | |
| #define PALETTE_PER_DIFF    26
 | |
| #define PALETTE_PER_SPEC    6
 | |
| #define MATL_MAX            7
 | |
| MATERIAL Material[16];
 | |
| static RGBA matlColors[MATL_MAX] = {{1.0f, 0.0f, 0.0f, 1.0f},
 | |
|                                     {0.0f, 1.0f, 0.0f, 1.0f},
 | |
|                                     {0.0f, 0.0f, 1.0f, 1.0f},
 | |
|                                     {1.0f, 1.0f, 0.0f, 1.0f},
 | |
|                                     {0.0f, 1.0f, 1.0f, 1.0f},
 | |
|                                     {1.0f, 0.0f, 1.0f, 1.0f},
 | |
|                                     {0.235f, 0.0f, 0.78f, 1.0f},
 | |
|                                    };
 | |
| 
 | |
| // Global variables defining current position and orientation.
 | |
| GLuint  DListCube;
 | |
| UINT    guiTimerTick = 1;
 | |
| POINT   gptWindow;
 | |
| SIZE    gszWindow;
 | |
| RECT    grcCurWindow;
 | |
| float   curquat[4], lastquat[4];
 | |
| LONG    glMouseDownX, glMouseDownY;
 | |
| BOOL    gbLeftMouse = FALSE;
 | |
| BOOL    gbSpinning = FALSE;
 | |
| SHADE   gShadeMode = SHADE_FLAT;
 | |
| POLYDRAW gPolyDrawMode = POLYDRAW_FILLED;
 | |
| GLfloat gfCurEyeZ = 5.0f, gfGoToEyeZ = 5.0f;
 | |
| 
 | |
| MESH  mesh;
 | |
| CURVE curve;
 | |
| POINT3D apt[] = {
 | |
| //    {0.0f, 1.0f, 0.0f},
 | |
| //    {1.0f, 0.8f, 0.0f},
 | |
| //    {0.5f, -0.8f, 0.0f},
 | |
| //    {0.0f, -1.0f, 0.0f}
 | |
|     {0.3f, 0.5f, 0.0f},
 | |
|     {1.0f, 0.4f, 0.0f},
 | |
|     {0.5f, -0.4f, 0.0f},
 | |
|     {0.3f, -0.5f, 0.0f},
 | |
|     {0.3f, 0.5f, 0.0f}
 | |
|     };
 | |
| int steps = 12;
 | |
| 
 | |
| HGLRC ghrc = (HGLRC) 0;
 | |
| 
 | |
| HPALETTE ghpalOld, ghPalette = (HPALETTE) 0;
 | |
| 
 | |
| HWND ghwndObject;
 | |
| 
 | |
| void CreateObjectWindow( HINSTANCE   hInstance,
 | |
|                         HINSTANCE   hPrevInstance,
 | |
|                         LPSTR       lpCmdLine,
 | |
|                         int         nCmdShow
 | |
|                       )
 | |
| {
 | |
|     static char szAppName[] = "Lathe";
 | |
|     static char szIniFile[] = "lathe.ini";
 | |
|     RECT Rect;
 | |
|     WNDCLASS wndclass;
 | |
| 
 | |
|     if ( !hPrevInstance )
 | |
|     {
 | |
|         wndclass.style          = CS_OWNDC;
 | |
|         wndclass.lpfnWndProc    = (WNDPROC)WndProc;
 | |
|         wndclass.cbClsExtra     = 0;
 | |
|         wndclass.cbWndExtra     = 0;
 | |
|         wndclass.hInstance      = hInstance;
 | |
|         //wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
 | |
|         wndclass.hCursor        = NULL;
 | |
|         wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
 | |
|         wndclass.lpszMenuName   = NULL;
 | |
|         wndclass.lpszClassName  = szAppName;
 | |
| 
 | |
|         // With a NULL icon handle, app will paint into the icon window.
 | |
|         wndclass.hIcon          = NULL;
 | |
|         //wndclass.hIcon          = LoadIcon(hInstance, "CubeIcon");
 | |
| 
 | |
|         RegisterClass(&wndclass);
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      *  Make the windows a reasonable size and pick a
 | |
|      *  position for it.
 | |
|      */
 | |
| 
 | |
|     Rect.left   = GetPrivateProfileInt("ObjectWindow", "left",   500, szIniFile);
 | |
|     Rect.top    = GetPrivateProfileInt("ObjectWindow", "top",    50, szIniFile);
 | |
|     Rect.right  = GetPrivateProfileInt("ObjectWindow", "right",  900, szIniFile);
 | |
|     Rect.bottom = GetPrivateProfileInt("ObjectWindow", "bottom", 450, szIniFile);
 | |
|     guiTimerTick= GetPrivateProfileInt("Animate", "Timer", 1,  szIniFile);
 | |
| 
 | |
|     gptWindow.x = Rect.left;
 | |
|     gptWindow.y = Rect.top;
 | |
|     gszWindow.cx = WINDSIZEX(Rect);
 | |
|     gszWindow.cy = WINDSIZEY(Rect);
 | |
| 
 | |
|     AdjustWindowRect( &Rect, WS_OVERLAPPEDWINDOW, FALSE );
 | |
| 
 | |
|     ghwndObject = CreateWindow(szAppName,              // window class name
 | |
|                                "Lathe",                // window caption
 | |
|                                WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
 | |
|                                Rect.left,              // initial x position
 | |
|                                Rect.top,               // initial y position
 | |
|                                WINDSIZEX(Rect),        // initial x size
 | |
|                                WINDSIZEY(Rect),        // initial y size
 | |
|                                NULL,                   // parent window handle
 | |
|                                NULL,                   // window menu handle
 | |
|                                hInstance,              // program instance handle
 | |
|                                NULL                    // creation parameter
 | |
|                                );
 | |
| 
 | |
|     ShowWindow( ghwndObject, nCmdShow );
 | |
|     UpdateWindow( ghwndObject );
 | |
| 
 | |
|     SetTimer(ghwndObject, 1, guiTimerTick, NULL);
 | |
| }
 | |
| 
 | |
| long
 | |
| WndProc (   HWND hwnd,
 | |
|             UINT message,
 | |
|             WPARAM wParam,
 | |
|             LPARAM lParam
 | |
|         )
 | |
| {
 | |
|     HDC hdc;
 | |
|     PAINTSTRUCT ps;
 | |
| 
 | |
|     switch ( message )
 | |
|     {
 | |
|         case WM_CREATE:
 | |
|             if(hdc = GetDC(hwnd))
 | |
|             {
 | |
|                 if (ghrc == (HGLRC) 0)
 | |
|                     ghrc = hrcInitGL(hwnd, hdc);
 | |
| 
 | |
|                 ReleaseDC(hwnd,hdc);
 | |
|             }
 | |
|             break;
 | |
| 
 | |
|         case WM_PAINT:
 | |
|             hdc = BeginPaint( hwnd, &ps );
 | |
| 
 | |
|             if (ghrc == (HGLRC) 0)
 | |
|                 ghrc = hrcInitGL(hwnd, hdc);
 | |
| 
 | |
|             DoGlStuff( hwnd, hdc );
 | |
| 
 | |
|             EndPaint( hwnd, &ps );
 | |
|             return 0;
 | |
| 
 | |
|         case WM_MOVE:
 | |
|             gptWindow.x = (int) LOWORD(lParam);
 | |
|             gptWindow.y = (int) HIWORD(lParam);
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         case WM_SIZE:
 | |
|             gszWindow.cx = LOWORD(lParam);
 | |
|             gszWindow.cy = HIWORD(lParam);
 | |
|             vSetSize(hwnd);
 | |
|             ForceRedraw(hwnd);
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         case WM_PALETTECHANGED:
 | |
|             if (hwnd != (HWND) wParam)
 | |
|             {
 | |
|                 if (hdc = GetDC(hwnd))
 | |
|                 {
 | |
|                     UnrealizeObject(ghPalette);
 | |
|                     SelectPalette(hdc, ghPalette, TRUE);
 | |
|                     if (RealizePalette(hdc) != GDI_ERROR)
 | |
|                         return 1;
 | |
|                 }
 | |
|             }
 | |
|             return 0;
 | |
| 
 | |
|         case WM_QUERYNEWPALETTE:
 | |
| 
 | |
|             if (hdc = GetDC(hwnd))
 | |
|             {
 | |
|                 UnrealizeObject(ghPalette);
 | |
|                 SelectPalette(hdc, ghPalette, FALSE);
 | |
|                 if (RealizePalette(hdc) != GDI_ERROR)
 | |
|                     return 1;
 | |
|             }
 | |
|             return 0;
 | |
| 
 | |
|         case WM_KEYDOWN:
 | |
|             switch (wParam)
 | |
|             {
 | |
|             case VK_ESCAPE:
 | |
|                 PostMessage(hwnd, WM_DESTROY, 0, 0);
 | |
|                 break;
 | |
|             case VK_UP:
 | |
|                 gfGoToEyeZ -= 1.0f;
 | |
|                 break;
 | |
|             case VK_DOWN:
 | |
|                 gfGoToEyeZ += 1.0f;
 | |
|                 break;
 | |
|             default:
 | |
|                 break;
 | |
|             }
 | |
|             return 0;
 | |
| 
 | |
|         case WM_LBUTTONDOWN:
 | |
| 
 | |
|             SetCapture(hwnd);
 | |
| 
 | |
|             glMouseDownX = LOWORD(lParam);
 | |
|             glMouseDownY = HIWORD(lParam);
 | |
|             gbLeftMouse = TRUE;
 | |
| 
 | |
|             ForceRedraw(hwnd);
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         case WM_LBUTTONUP:
 | |
| 
 | |
|             ReleaseCapture();
 | |
| 
 | |
|             gbLeftMouse = FALSE;
 | |
| 
 | |
|             ForceRedraw(hwnd);
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         case WM_CHAR:
 | |
|             switch(wParam)
 | |
|             {
 | |
|                 case '[':
 | |
|                 case '{':
 | |
|                     guiTimerTick = guiTimerTick << 1;
 | |
|                     guiTimerTick = min(0x40000000, guiTimerTick);
 | |
| 
 | |
|                     KillTimer(hwnd, 1);
 | |
|                     SetTimer(hwnd, 1, guiTimerTick, NULL);
 | |
|                     break;
 | |
| 
 | |
|                 case ']':
 | |
|                 case '}':
 | |
|                     guiTimerTick = guiTimerTick >> 1;
 | |
|                     guiTimerTick = max(1, guiTimerTick);
 | |
| 
 | |
|                     KillTimer(hwnd, 1);
 | |
|                     SetTimer(hwnd, 1, guiTimerTick, NULL);
 | |
|                     break;
 | |
| 
 | |
|                 case ',':
 | |
|                 case '<':
 | |
|                     if (steps > 4)  // also have at least 3 sides -- its 3D!
 | |
|                     {
 | |
|                         steps--;
 | |
|                         vMakeObject();
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case '.':
 | |
|                 case '>':
 | |
|                     steps++;
 | |
|                     vMakeObject();
 | |
|                     break;
 | |
| 
 | |
|                 case 's':
 | |
|                 case 'S':
 | |
|                     gShadeMode = (gShadeMode + 1) % 3;
 | |
|                     switch (gShadeMode)
 | |
|                     {
 | |
|                         case SHADE_SMOOTH_AROUND:
 | |
|                         case SHADE_SMOOTH_BOTH:
 | |
|                             glShadeModel(GL_SMOOTH);
 | |
|                             break;
 | |
|                         case SHADE_FLAT:
 | |
|                         default:
 | |
|                             glShadeModel(GL_FLAT);
 | |
|                             break;
 | |
|                     }
 | |
|                     vMakeObject();
 | |
|                     break;
 | |
| 
 | |
|                 case 'w':
 | |
|                 case 'W':
 | |
|                     gPolyDrawMode = (gPolyDrawMode + 1) % 3;
 | |
|                     switch (gPolyDrawMode)
 | |
|                     {
 | |
|                         case POLYDRAW_POINTS:
 | |
|                             glDisable(GL_LIGHTING);
 | |
|                             glDisable(GL_CULL_FACE);
 | |
|                             glEnable(GL_FOG);
 | |
|                             //glDisable(GL_STENCIL_TEST);
 | |
|                             glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
 | |
|                             break;
 | |
|                         case POLYDRAW_LINES:
 | |
|                             glDisable(GL_LIGHTING);
 | |
|                             glDisable(GL_CULL_FACE);
 | |
|                             glEnable(GL_FOG);
 | |
|                             //glEnable(GL_STENCIL_TEST);
 | |
|                             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 | |
|                             break;
 | |
|                         case POLYDRAW_FILLED:
 | |
|                         default:
 | |
|                             glEnable(GL_LIGHTING);
 | |
|                             glEnable(GL_CULL_FACE);
 | |
|                             glDisable(GL_FOG);
 | |
|                             //glDisable(GL_STENCIL_TEST);
 | |
|                             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | |
|                             break;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         case WM_TIMER:
 | |
| 
 | |
|             hdc = GetDC(hwnd);
 | |
| 
 | |
|             if (ghrc == (HGLRC) 0)
 | |
|                 ghrc = hrcInitGL(hwnd, hdc);
 | |
| 
 | |
|             if ( fabs(gfCurEyeZ - gfGoToEyeZ) > 0.1f )
 | |
|             {
 | |
|                 gfCurEyeZ += (gfCurEyeZ < gfGoToEyeZ) ? 0.2f : -0.2f;
 | |
|                 vSetSize(hwnd);
 | |
|             }
 | |
| 
 | |
|             DoGlStuff( hwnd, hdc );
 | |
| 
 | |
|             ReleaseDC(hwnd, hdc);
 | |
| 
 | |
|             return 0;
 | |
| 
 | |
|         #if 1
 | |
|         case WM_DESTROY:
 | |
|             vCleanupGL(ghrc);
 | |
|             KillTimer(hwnd, 1);
 | |
|             PostQuitMessage( 0 );
 | |
|             PostMessage(ghwndInput, WM_QUIT, 0, 0);  // quit input thread too
 | |
|             return 0;
 | |
|         #endif
 | |
| 
 | |
|         case WM_USER_INPUTMESH:
 | |
|             vMeshToList();
 | |
|             return 0;
 | |
| 
 | |
|         default:
 | |
|             break;
 | |
|     }
 | |
|     return( DefWindowProc( hwnd, message, wParam, lParam ) );
 | |
| }
 | |
| 
 | |
| unsigned char threeto8[8] = {
 | |
|     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
 | |
| };
 | |
| 
 | |
| unsigned char twoto8[4] = {
 | |
|     0, 0x55, 0xaa, 0xff
 | |
| };
 | |
| 
 | |
| unsigned char oneto8[2] = {
 | |
|     0, 255
 | |
| };
 | |
| 
 | |
| unsigned char
 | |
| ComponentFromIndex(i, nbits, shift)
 | |
| {
 | |
|     unsigned char val;
 | |
| 
 | |
|     val = i >> shift;
 | |
|     switch (nbits) {
 | |
| 
 | |
|     case 1:
 | |
|         val &= 0x1;
 | |
|         return oneto8[val];
 | |
| 
 | |
|     case 2:
 | |
|         val &= 0x3;
 | |
|         return twoto8[val];
 | |
| 
 | |
|     case 3:
 | |
|         val &= 0x7;
 | |
|         return threeto8[val];
 | |
| 
 | |
|     default:
 | |
|         return 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| CreateRGBPalette(HDC hdc)
 | |
| {
 | |
|     PIXELFORMATDESCRIPTOR pfd, *ppfd;
 | |
|     LOGPALETTE *pPal;
 | |
|     int n, i;
 | |
| 
 | |
|     ppfd = &pfd;
 | |
|     n = GetPixelFormat(hdc);
 | |
|     DescribePixelFormat(hdc, n, sizeof(PIXELFORMATDESCRIPTOR), ppfd);
 | |
| 
 | |
|     if (ppfd->dwFlags & PFD_NEED_PALETTE) {
 | |
|         n = 1 << ppfd->cColorBits;
 | |
|         pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
 | |
|                 n * sizeof(PALETTEENTRY));
 | |
|         pPal->palVersion = 0x300;
 | |
|         pPal->palNumEntries = n;
 | |
|         for (i=0; i<n; i++) {
 | |
|             pPal->palPalEntry[i].peRed =
 | |
|                     ComponentFromIndex(i, ppfd->cRedBits, ppfd->cRedShift);
 | |
|             pPal->palPalEntry[i].peGreen =
 | |
|                     ComponentFromIndex(i, ppfd->cGreenBits, ppfd->cGreenShift);
 | |
|             pPal->palPalEntry[i].peBlue =
 | |
|                     ComponentFromIndex(i, ppfd->cBlueBits, ppfd->cBlueShift);
 | |
|             pPal->palPalEntry[i].peFlags = (i == 0 || i == 255) ? 0 : PC_NOCOLLAPSE;
 | |
|         }
 | |
|         ghPalette = CreatePalette(pPal);
 | |
|         LocalFree(pPal);
 | |
| 
 | |
|         //SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
 | |
| 
 | |
|         ghpalOld = SelectPalette(hdc, ghPalette, FALSE);
 | |
|         n = RealizePalette(hdc);
 | |
|         UnrealizeObject(ghPalette);
 | |
|         n = RealizePalette(hdc);
 | |
|     }
 | |
| }
 | |
| 
 | |
| BOOL bSetupPixelFormat(HDC hdc)
 | |
| {
 | |
|     PIXELFORMATDESCRIPTOR pfd, *ppfd;
 | |
|     int pixelformat;
 | |
| 
 | |
|     ppfd = &pfd;
 | |
| 
 | |
|     ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
 | |
|     ppfd->nVersion = 1;
 | |
|     ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
 | |
|     ppfd->dwLayerMask = PFD_MAIN_PLANE;
 | |
| 
 | |
|     ppfd->iPixelType = PFD_TYPE_RGBA;
 | |
|     ppfd->cColorBits = 24;
 | |
| 
 | |
|     ppfd->cDepthBits = 16;
 | |
|     ppfd->cAccumBits = 0;
 | |
|     ppfd->cStencilBits = 0;
 | |
| 
 | |
|     pixelformat = ChoosePixelFormat(hdc, ppfd);
 | |
| 
 | |
|     if ( (pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0 )
 | |
|     {
 | |
|         MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE)
 | |
|     {
 | |
|         MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     CreateRGBPalette(hdc);
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| void initMaterial(int id, float r, float g, float b, float a)
 | |
| {
 | |
|     Material[id].ka.r = r;
 | |
|     Material[id].ka.g = g;
 | |
|     Material[id].ka.b = b;
 | |
|     Material[id].ka.a = a;
 | |
| 
 | |
|     Material[id].kd.r = r;
 | |
|     Material[id].kd.g = g;
 | |
|     Material[id].kd.b = b;
 | |
|     Material[id].kd.a = a;
 | |
| 
 | |
|     Material[id].ks.r = 1.0f;
 | |
|     Material[id].ks.g = 1.0f;
 | |
|     Material[id].ks.b = 1.0f;
 | |
|     Material[id].ks.a = 1.0f;
 | |
| 
 | |
|     Material[id].specExp = 128.0f;
 | |
|     Material[id].indexStart = (float) (id * PALETTE_PER_MATL);
 | |
| }
 | |
| 
 | |
| HGLRC hrcInitGL(HWND hwnd, HDC hdc)
 | |
| {
 | |
|     HGLRC hrc;
 | |
|     int i;
 | |
|     GLfloat fDens = 0.25;
 | |
| 
 | |
|     /* Create a Rendering Context */
 | |
| 
 | |
|     bSetupPixelFormat( hdc );
 | |
|     hrc = wglCreateContext( hdc );
 | |
| 
 | |
|     /* Make it Current */
 | |
| 
 | |
|     wglMakeCurrent( hdc, hrc );
 | |
| 
 | |
|     glDrawBuffer(GL_BACK);
 | |
| 
 | |
|     /* Set the clear color */
 | |
| 
 | |
|     glClearColor( ZERO, ZERO, ZERO, ONE );
 | |
| 
 | |
|     /* Turn on z-buffer */
 | |
| 
 | |
|     glEnable(GL_DEPTH_TEST);
 | |
| 
 | |
|     /* Turn on backface culling */
 | |
| 
 | |
|     glEnable(GL_CULL_FACE);
 | |
| 
 | |
|     /* Shading */
 | |
| 
 | |
|     //glShadeModel(GL_SMOOTH);
 | |
|     glShadeModel(GL_FLAT);
 | |
| 
 | |
|     /* Initialize materials */
 | |
| 
 | |
|     for (i = 0; i < 7; i++)
 | |
|         initMaterial(i, matlColors[i].r, matlColors[i].g,
 | |
|                      matlColors[i].b, matlColors[i].a);
 | |
| 
 | |
|     /* Turn on the lights */
 | |
| 
 | |
|     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat *) &lightAmbient);
 | |
|     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
 | |
|     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
 | |
|     glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat *) &light0Ambient);
 | |
|     glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat *) &light0Diffuse);
 | |
|     glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat *) &light0Specular);
 | |
|     glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
 | |
|     glEnable(GL_LIGHTING);
 | |
|     glEnable(GL_LIGHT0);
 | |
| 
 | |
|     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *) &Material[0].ks);
 | |
|     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat *) &Material[0].specExp);
 | |
|     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (GLfloat *) &Material[0].kd);
 | |
| 
 | |
|     glColor4f( ONE, ONE, ONE, ONE );
 | |
|     glFogi(GL_FOG_MODE, GL_EXP);
 | |
|     glFogfv(GL_FOG_DENSITY, &fDens);
 | |
|     //glFogi(GL_FOG_MODE, GL_LINEAR);
 | |
|     //glFogi(GL_FOG_END, 10);
 | |
| 
 | |
|     /* Generate a display list for a cube */
 | |
| 
 | |
|     DListCube = glGenLists(1);
 | |
| 
 | |
|     curve.numPoints = sizeof(apt) / sizeof(POINT3D);
 | |
|     curve.pts = apt;
 | |
|     vMakeObject();
 | |
| 
 | |
|     vSetSize(hwnd);
 | |
| 
 | |
|     trackball(curquat, 0.0, 0.0, 0.0, 0.0);
 | |
| 
 | |
|     return hrc;
 | |
| }
 | |
| 
 | |
| VOID vMakeObject()
 | |
| {
 | |
|     if (glIsList(DListCube))
 | |
|     {
 | |
|         glDeleteLists(DListCube, 1);
 | |
|         delMesh(&mesh);
 | |
|     }
 | |
| 
 | |
|     revolveSurface(&mesh, &curve, steps);
 | |
|     MakeList(DListCube, &mesh);
 | |
| }
 | |
| 
 | |
| VOID vInputThreadMakeObject()
 | |
| {
 | |
|     delMesh(&mesh);
 | |
|     revolveSurface(&mesh, &curve, steps);
 | |
|     SendMessage(ghwndObject, WM_USER_INPUTMESH, 0, 0);
 | |
| }
 | |
| 
 | |
| VOID vMeshToList()
 | |
| {
 | |
|     if (glIsList(DListCube))
 | |
|     {
 | |
|         glDeleteLists(DListCube, 1);
 | |
|     }
 | |
| 
 | |
|     MakeList(DListCube, &mesh);
 | |
| }
 | |
| 
 | |
| VOID vSetSize(HWND hwnd)
 | |
| {
 | |
|     /* Set up viewport extents */
 | |
| 
 | |
|     glViewport(0, 0, gszWindow.cx, gszWindow.cy);
 | |
| 
 | |
|     /* Set up the projection matrix */
 | |
| 
 | |
|     glMatrixMode(GL_PROJECTION);
 | |
|     glLoadIdentity();
 | |
|     gluPerspective(45, 1.0, 0.1, 100.0);
 | |
| 
 | |
|     /* Set up the model matrix */
 | |
| 
 | |
|     glMatrixMode(GL_MODELVIEW);
 | |
|     glLoadIdentity();
 | |
|     gluLookAt(0,0,gfCurEyeZ, 0,0,0, 0,-1,0);
 | |
| }
 | |
| 
 | |
| void
 | |
| vCleanupGL(HGLRC hrc)
 | |
| {
 | |
|     glDeleteLists(DListCube, 1);
 | |
|     delMesh(&mesh);
 | |
| 
 | |
|     //if (ghPalette)
 | |
|     //    DeleteObject(SelectObject(ghdcMem, ghpalOld));
 | |
| 
 | |
|     /*  Destroy our context */
 | |
| 
 | |
|     wglDeleteContext( hrc );
 | |
| 
 | |
| }
 | |
| 
 | |
| void
 | |
| ForceRedraw(HWND hwnd)
 | |
| {
 | |
|     MSG msg;
 | |
| 
 | |
|     if (!PeekMessage(&msg, hwnd, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
 | |
|     {
 | |
|         InvalidateRect(hwnd, NULL, FALSE);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| DoGlStuff( HWND hwnd, HDC hdc )
 | |
| {
 | |
|     USHORT usMouseCurX, usMouseCurY;
 | |
|     POINT  pt;
 | |
|     float  matRot[4][4];
 | |
| 
 | |
|     if (gbLeftMouse)
 | |
|     {
 | |
|         if (GetCursorPos(&pt))
 | |
|         {
 | |
|         // Subtract current window origin to convert to window coordinates.
 | |
| 
 | |
|             pt.x -= gptWindow.x;
 | |
|             pt.y -= gptWindow.y;
 | |
| 
 | |
|         // If mouse has moved since button was pressed, change quaternion.
 | |
| 
 | |
|             if (pt.x != glMouseDownX || pt.y != glMouseDownY)
 | |
|             {
 | |
|                 trackball(lastquat,
 | |
|                           2.0*(gszWindow.cx-glMouseDownX)/gszWindow.cx-1.0,
 | |
|                           2.0*glMouseDownY/gszWindow.cy-1.0,
 | |
|                           2.0*(gszWindow.cx-pt.x)/gszWindow.cx-1.0,
 | |
|                           2.0*pt.y/gszWindow.cy-1.0);
 | |
| 
 | |
|                 gbSpinning = TRUE;
 | |
|             }
 | |
|             else
 | |
|                 gbSpinning = FALSE;
 | |
| 
 | |
|             glMouseDownX = pt.x;
 | |
|             glMouseDownY = pt.y;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     glPushMatrix();
 | |
| 
 | |
|     if (gbSpinning)
 | |
|         add_quats(lastquat, curquat, curquat);
 | |
| 
 | |
|     build_rotmatrix(matRot, curquat);
 | |
|     glMultMatrixf(&(matRot[0][0]));
 | |
| 
 | |
| #if 0
 | |
|     if (gPolyDrawMode == POLYDRAW_LINES)
 | |
|     {
 | |
|     // Use stencil buffer technique to do hidden line removal.
 | |
| 
 | |
|         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
 | |
| 
 | |
| #if 1
 | |
|     // Create a stencil mask using the lines.
 | |
| 
 | |
|         glStencilFunc( GL_ALWAYS, 0, 1 );
 | |
|         glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT );
 | |
|         glColor4f( ONE, ONE, ONE, ONE );
 | |
|         glCallList(DListCube);
 | |
| 
 | |
|     // Fill in the faces where there aren't already lines.
 | |
| 
 | |
|         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | |
| 
 | |
|         glStencilFunc( GL_EQUAL, 0, 1 );
 | |
|         glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
 | |
|         glColor4f( ZERO, ZERO, ZERO, ONE );
 | |
|         glCallList(DListCube);
 | |
| 
 | |
|     // ????
 | |
| 
 | |
|         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 | |
| 
 | |
|         glStencilFunc( GL_ALWAYS, 0, 1 );
 | |
|         glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT );
 | |
|         glColor4f( ONE, ONE, ONE, ONE );
 | |
|         glCallList(DListCube);
 | |
| #else
 | |
|         glDisable(GL_STENCIL_TEST);
 | |
|         glDepthFunc(GL_LEQUAL);
 | |
| 
 | |
|         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | |
| 
 | |
|         glColor4f( ZERO, ZERO, ZERO, ONE );
 | |
|         glCallList(DListCube);
 | |
| 
 | |
|         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 | |
| 
 | |
|         glColor4f( ONE, ONE, ONE, ONE );
 | |
|         glCallList(DListCube);
 | |
| 
 | |
|         glDepthFunc(GL_LESS);
 | |
| #endif
 | |
|     }
 | |
|     else
 | |
| #endif
 | |
|     {
 | |
|         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 | |
|         glCallList(DListCube);
 | |
|     }
 | |
| 
 | |
|     glPopMatrix();
 | |
| 
 | |
|     SwapBuffers(hdc);
 | |
| }
 |