Annotation of q_a/samples/spincube/paint.c, revision 1.1.1.2

1.1.1.2 ! root        1: /******************************************************************************\
1.1       root        2: *
                      3: *  MODULE:      PAINT.C
                      4: *
                      5: *  PURPOSE:     This is the module responsible for painting the SPINCUBE
                      6: *               custom control. When Paint() is called, the SPINCUBEINFO
                      7: *               associated with the calling window is queried; this will
                      8: *               provide the current X, Y, and Z rotation angles for the
                      9: *               polyhedron we'll draw. Using these angles we compute the
                     10: *               3x2 transformation matrix (there's no need for a 3x3
                     11: *               matrix since we never look at the Z-values of tranformed
                     12: *               points). Next, we compute the normalized polyhedron
                     13: *               vertices based on our current window size, and then
                     14: *               tranform them the using the above matrix. We begin draw-
                     15: *               ing by erasing the window and drawing an outline. Then
                     16: *               we walk through the facet list, drawing each facet whose
                     17: *               outward normal faces us (using parallel projection).
                     18: *
                     19: *  FUNCTIONS:   Paint()         - the paint routine
                     20: *               ComputeXform()  - computes 3x2 trnaformation matrix
                     21: *                                 given x, y, and z rotation angles
                     22: *               XformVertices() - transforms normalized polyhedron
                     23: *                                 vertices using above matrix
                     24: *
1.1.1.2 ! root       25: *
        !            26: *                           Microsoft Developer Support
        !            27: *                     Copyright (c) 1992 Microsoft Corporation
        !            28: *
        !            29: \******************************************************************************/
1.1       root       30: 
                     31: #include <windows.h>
                     32: #include <math.h>
                     33: #include "spincube.h"
                     34: #include "paint.h"
                     35: 
                     36: 
                     37: 
1.1.1.2 ! root       38: /******************************************************************************\
1.1       root       39: *
                     40: *  FUNCTION:     Paint
                     41: *
                     42: *  INPUTS:       hWnd - Handle of the window to draw into.
                     43: *
                     44: *  GLOBAL VARS:  m      - Contains transformation matrix.
                     45: *                v      - Vertices of normalized polyhedron.
                     46: *                xv     - Contains points to transform; results stored here.
                     47: *                facets - A list if integers (indexes into xv) describing
                     48: *                         the facets of the polyhedron.
                     49: *
                     50: *  COMMENTS:     Draws a polyhedron in the window.
                     51: *
1.1.1.2 ! root       52: \******************************************************************************/
1.1       root       53: 
                     54: void Paint (HWND hWnd)
                     55: {
                     56:   HANDLE         hSCI;
                     57:   PSPINCUBEINFO  pSCI;
                     58:   RECT           rect;
                     59:   int            i;
                     60:   LONG           scale;
                     61:   PAINTSTRUCT    ps;
                     62:   HBRUSH         hBrush, hBrushSave;
                     63:   int            facetIndex, numPoints;
                     64:   POINT          polygn[MAX_POINTS_PER_FACET];
                     65:   POINT          vector1, vector2;
                     66:   COLORREF       crColor;
                     67: 
                     68:   hSCI = (HANDLE) GetWindowLong (hWnd, GWL_SPINCUBEDATA);
                     69:   pSCI = (PSPINCUBEINFO) LocalLock (hSCI);
                     70: 
                     71:   ComputeXform (pSCI->xRotAngle, pSCI->yRotAngle, pSCI->zRotAngle);
                     72: 
1.1.1.2 ! root       73:   //
        !            74:   // if inMotion increment the rotation angles and release the memory
        !            75:   //
1.1       root       76: 
                     77:   if (pSCI->inMotion)
                     78:   {
                     79:     if ((pSCI->xRotAngle += XROT_INCREMENT) > (float) 6.28)
                     80:       pSCI->xRotAngle = (float) 0.0;
                     81:     if ((pSCI->yRotAngle += YROT_INCREMENT) > (float) 6.28)
                     82:       pSCI->yRotAngle = (float) 0.0;
                     83:     if ((pSCI->zRotAngle += ZROT_INCREMENT) > (float) 6.28)
                     84:       pSCI->zRotAngle = (float) 0.0;
                     85:   }
                     86:   LocalUnlock (hSCI);
                     87: 
                     88:   GetWindowRect (hWnd, &rect);
                     89: 
1.1.1.2 ! root       90:   //
        !            91:   // The rectangle we get back is in Desktop coordinates, so we need to
        !            92:   //   modify it to reflect coordinates relative to this window.
        !            93:   //
1.1       root       94: 
                     95:   rect.right  -= rect.left;
                     96:   rect.bottom -= rect.top;
                     97:   rect.left = rect.top = 0;
                     98: 
1.1.1.2 ! root       99:   //
        !           100:   // Determine a "best fit" scale factor for our polyhedron
        !           101:   //
1.1       root      102: 
                    103:   scale = (rect.right > rect.bottom) ? rect.bottom/4 : rect.right/4;
                    104:   for (i = 0; i < NUMVERTICES; i++)
                    105:   {
                    106:     xv[i]   =  v[i];
                    107:     xv[i].x *= scale;
                    108:     xv[i].y *= scale;
                    109:     xv[i].z *= scale;
                    110:   }
                    111: 
                    112:   XformVertices (rect.right/2, rect.bottom/2);
                    113: 
                    114:   BeginPaint (hWnd, &ps);
                    115: 
1.1.1.2 ! root      116:   //
        !           117:   // Draw the window frame & background
        !           118:   //
1.1       root      119: 
                    120:   SelectObject (ps.hdc, GetStockObject (GRAY_BRUSH));
                    121:   Rectangle (ps.hdc, (int)rect.left, (int)rect.top, (int)rect.right,
                    122:              (int)rect.bottom);
                    123: 
1.1.1.2 ! root      124:   //
        !           125:   // Draw the polyhedron. We'll walk through the facets list and compute
        !           126:   //   the normal for each facet- if the normal has z > 0, then the facet
        !           127:   //   faces us and we'll draw it. Note that this algorithim is ONLY valid
        !           128:   //   for scenes with a single, convex polyhedron.
        !           129:   //
1.1       root      130: 
                    131:   crColor = 0x00000f;
                    132: 
                    133:   for (i = 0, facetIndex = 0; i < NUMFACETS; i++)
                    134:   {
                    135:     vector1.x = xv[facets[facetIndex + 1]].x - xv[facets[facetIndex]].x;
                    136:     vector1.y = xv[facets[facetIndex + 1]].y - xv[facets[facetIndex]].y;
                    137:     vector2.x = xv[facets[facetIndex + 2]].x - xv[facets[facetIndex + 1]].x;
                    138:     vector2.y = xv[facets[facetIndex + 2]].y - xv[facets[facetIndex + 1]].y;
                    139: 
                    140:     for (numPoints = 0; facets[facetIndex] != -1; numPoints++, facetIndex++)
                    141:     {
                    142:       polygn[numPoints].x = xv[facets[facetIndex]].x;
                    143:       polygn[numPoints].y = xv[facets[facetIndex]].y;
                    144:     }
                    145: 
                    146:     crColor = crColor << 4;
                    147: 
                    148:     facetIndex++; /* skip over the -1's in the facets list */
                    149:     if ((vector1.x*vector2.y - vector1.y*vector2.x) > 0)
                    150:     {
                    151:       hBrush     = CreateSolidBrush (crColor);
                    152:       hBrushSave = (HBRUSH) SelectObject (ps.hdc, hBrush);
                    153: 
                    154:       Polygon (ps.hdc, &polygn[0], numPoints);
                    155: 
                    156:       SelectObject (ps.hdc, hBrushSave);
                    157:       DeleteObject (hBrush);
                    158: 
                    159:     }
                    160:   }
                    161:   EndPaint (hWnd, &ps);
                    162: }
                    163: 
                    164: 
                    165: 
1.1.1.2 ! root      166: /******************************************************************************\
1.1       root      167: *
                    168: *  FUNCTION:    ComputeXform
                    169: *
                    170: *  INPUTS:      xRotAngle - Angle to rotate about X axis.
                    171: *               yRotAngle - Angle to rotate about Y axis.
                    172: *               zRotAngle - Angle to rotate about Z axis.
                    173: *
                    174: *  GLOBAL VARS: m - Resulting transformation stored here.
                    175: *
                    176: *  COMMENTS:    Computes a 3x2 tranformation matrix which rotates about
                    177: *               the Z axis, the Y axis, and the X axis, respectively.
                    178: *
1.1.1.2 ! root      179: \******************************************************************************/
1.1       root      180: 
                    181: void ComputeXform (float xRotAngle, float yRotAngle, float zRotAngle)
                    182: {
                    183:   float sinX, cosX, sinY, cosY, sinZ, cosZ;
                    184: 
                    185:   sinX = (float) sin ((double) xRotAngle);
                    186:   cosX = (float) cos ((double) xRotAngle);
                    187:   sinY = (float) sin ((double) yRotAngle);
                    188:   cosY = (float) cos ((double) yRotAngle);
                    189:   sinZ = (float) sin ((double) zRotAngle);
                    190:   cosZ = (float) cos ((double) zRotAngle);
                    191: 
                    192:   m[0][0] =  cosY*cosZ;
                    193:   m[0][1] = -cosY*sinZ;
                    194:   m[0][2] =  sinY;
                    195:   m[1][0] =  sinX*sinY*cosZ + cosX*sinZ;
                    196:   m[1][1] = -sinX*sinY*sinZ + cosX*cosZ;
                    197:   m[1][2] = -sinX*cosY;
                    198: }
                    199: 
                    200: 
                    201: 
1.1.1.2 ! root      202: /******************************************************************************\
1.1       root      203: *
                    204: *  FUNCTION:     XformVertices
                    205: *
                    206: *  INPUTS:       xCenterWindow - Horizontal midpoint of the window.
                    207: *                yCenterWindow - Vertical midpoint of the window.
                    208: *
                    209: *  GLOBAL VARS:  m  - Contains transformation matrix.
                    210: *                xv - Contains points to transform; results stored here.
                    211: *
                    212: *  COMMENTS:     Points are computed as: xv[i]' = m * xv[i].
                    213: *                The values xCenterWindow and yCenterWindow are then added
                    214: *                to translate each point so that it positioned relative to
                    215: *                the center of the window.
                    216: *
1.1.1.2 ! root      217: \******************************************************************************/
1.1       root      218: 
                    219: void XformVertices (int xCenterWindow, int yCenterWindow)
                    220: {
                    221:   int  i;
                    222: 
                    223:   for (i = 0; i < NUMVERTICES; i++)
                    224:   {
                    225:     LONG tempX;
                    226: 
                    227:     tempX   = (LONG) (m[0][0]*xv[i].x + m[0][1]*xv[i].y + m[0][2]*xv[i].z)
                    228:                     + xCenterWindow;
                    229:     xv[i].y = (LONG) (m[1][0]*xv[i].x + m[1][1]*xv[i].y + m[1][2]*xv[i].z)
                    230:                     + yCenterWindow;
                    231:     xv[i].x = tempX;
                    232:   }
                    233: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.