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

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

unix.superglobalmegacorp.com

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