File:  [WindowsNT SDKs] / q_a / samples / spincube / paint.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:29:20 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-oct-1992, HEAD
Microsoft Windows NT Build 328 10-12-1992

/******************************************************************************\
*
*  MODULE:      PAINT.C
*
*  PURPOSE:     This is the module responsible for painting the SPINCUBE
*               custom control. When Paint() is called, the SPINCUBEINFO
*               associated with the calling window is queried; this will
*               provide the current X, Y, and Z rotation angles for the
*               polyhedron we'll draw. Using these angles we compute the
*               3x2 transformation matrix (there's no need for a 3x3
*               matrix since we never look at the Z-values of tranformed
*               points). Next, we compute the normalized polyhedron
*               vertices based on our current window size, and then
*               tranform them the using the above matrix. We begin draw-
*               ing by erasing the window and drawing an outline. Then
*               we walk through the facet list, drawing each facet whose
*               outward normal faces us (using parallel projection).
*
*  FUNCTIONS:   Paint()         - the paint routine
*               ComputeXform()  - computes 3x2 trnaformation matrix
*                                 given x, y, and z rotation angles
*               XformVertices() - transforms normalized polyhedron
*                                 vertices using above matrix
*
*
*                           Microsoft Developer Support
*                     Copyright (c) 1992 Microsoft Corporation
*
\******************************************************************************/

#include <windows.h>
#include <math.h>
#include "spincube.h"
#include "paint.h"



/******************************************************************************\
*
*  FUNCTION:     Paint
*
*  INPUTS:       hWnd - Handle of the window to draw into.
*
*  GLOBAL VARS:  m      - Contains transformation matrix.
*                v      - Vertices of normalized polyhedron.
*                xv     - Contains points to transform; results stored here.
*                facets - A list if integers (indexes into xv) describing
*                         the facets of the polyhedron.
*
*  COMMENTS:     Draws a polyhedron in the window.
*
\******************************************************************************/

void Paint (HWND hWnd)
{
  HANDLE         hSCI;
  PSPINCUBEINFO  pSCI;
  RECT           rect;
  int            i;
  LONG           scale;
  PAINTSTRUCT    ps;
  HBRUSH         hBrush, hBrushSave;
  int            facetIndex, numPoints;
  POINT          polygn[MAX_POINTS_PER_FACET];
  POINT          vector1, vector2;
  COLORREF       crColor;

  hSCI = (HANDLE) GetWindowLong (hWnd, GWL_SPINCUBEDATA);
  pSCI = (PSPINCUBEINFO) LocalLock (hSCI);

  ComputeXform (pSCI->xRotAngle, pSCI->yRotAngle, pSCI->zRotAngle);

  //
  // if inMotion increment the rotation angles and release the memory
  //

  if (pSCI->inMotion)
  {
    if ((pSCI->xRotAngle += XROT_INCREMENT) > (float) 6.28)
      pSCI->xRotAngle = (float) 0.0;
    if ((pSCI->yRotAngle += YROT_INCREMENT) > (float) 6.28)
      pSCI->yRotAngle = (float) 0.0;
    if ((pSCI->zRotAngle += ZROT_INCREMENT) > (float) 6.28)
      pSCI->zRotAngle = (float) 0.0;
  }
  LocalUnlock (hSCI);

  GetWindowRect (hWnd, &rect);

  //
  // The rectangle we get back is in Desktop coordinates, so we need to
  //   modify it to reflect coordinates relative to this window.
  //

  rect.right  -= rect.left;
  rect.bottom -= rect.top;
  rect.left = rect.top = 0;

  //
  // Determine a "best fit" scale factor for our polyhedron
  //

  scale = (rect.right > rect.bottom) ? rect.bottom/4 : rect.right/4;
  for (i = 0; i < NUMVERTICES; i++)
  {
    xv[i]   =  v[i];
    xv[i].x *= scale;
    xv[i].y *= scale;
    xv[i].z *= scale;
  }

  XformVertices (rect.right/2, rect.bottom/2);

  BeginPaint (hWnd, &ps);

  //
  // Draw the window frame & background
  //

  SelectObject (ps.hdc, GetStockObject (GRAY_BRUSH));
  Rectangle (ps.hdc, (int)rect.left, (int)rect.top, (int)rect.right,
             (int)rect.bottom);

  //
  // Draw the polyhedron. We'll walk through the facets list and compute
  //   the normal for each facet- if the normal has z > 0, then the facet
  //   faces us and we'll draw it. Note that this algorithim is ONLY valid
  //   for scenes with a single, convex polyhedron.
  //

  crColor = 0x00000f;

  for (i = 0, facetIndex = 0; i < NUMFACETS; i++)
  {
    vector1.x = xv[facets[facetIndex + 1]].x - xv[facets[facetIndex]].x;
    vector1.y = xv[facets[facetIndex + 1]].y - xv[facets[facetIndex]].y;
    vector2.x = xv[facets[facetIndex + 2]].x - xv[facets[facetIndex + 1]].x;
    vector2.y = xv[facets[facetIndex + 2]].y - xv[facets[facetIndex + 1]].y;

    for (numPoints = 0; facets[facetIndex] != -1; numPoints++, facetIndex++)
    {
      polygn[numPoints].x = xv[facets[facetIndex]].x;
      polygn[numPoints].y = xv[facets[facetIndex]].y;
    }

    crColor = crColor << 4;

    facetIndex++; /* skip over the -1's in the facets list */
    if ((vector1.x*vector2.y - vector1.y*vector2.x) > 0)
    {
      hBrush     = CreateSolidBrush (crColor);
      hBrushSave = (HBRUSH) SelectObject (ps.hdc, hBrush);

      Polygon (ps.hdc, &polygn[0], numPoints);

      SelectObject (ps.hdc, hBrushSave);
      DeleteObject (hBrush);

    }
  }
  EndPaint (hWnd, &ps);
}



/******************************************************************************\
*
*  FUNCTION:    ComputeXform
*
*  INPUTS:      xRotAngle - Angle to rotate about X axis.
*               yRotAngle - Angle to rotate about Y axis.
*               zRotAngle - Angle to rotate about Z axis.
*
*  GLOBAL VARS: m - Resulting transformation stored here.
*
*  COMMENTS:    Computes a 3x2 tranformation matrix which rotates about
*               the Z axis, the Y axis, and the X axis, respectively.
*
\******************************************************************************/

void ComputeXform (float xRotAngle, float yRotAngle, float zRotAngle)
{
  float sinX, cosX, sinY, cosY, sinZ, cosZ;

  sinX = (float) sin ((double) xRotAngle);
  cosX = (float) cos ((double) xRotAngle);
  sinY = (float) sin ((double) yRotAngle);
  cosY = (float) cos ((double) yRotAngle);
  sinZ = (float) sin ((double) zRotAngle);
  cosZ = (float) cos ((double) zRotAngle);

  m[0][0] =  cosY*cosZ;
  m[0][1] = -cosY*sinZ;
  m[0][2] =  sinY;
  m[1][0] =  sinX*sinY*cosZ + cosX*sinZ;
  m[1][1] = -sinX*sinY*sinZ + cosX*cosZ;
  m[1][2] = -sinX*cosY;
}



/******************************************************************************\
*
*  FUNCTION:     XformVertices
*
*  INPUTS:       xCenterWindow - Horizontal midpoint of the window.
*                yCenterWindow - Vertical midpoint of the window.
*
*  GLOBAL VARS:  m  - Contains transformation matrix.
*                xv - Contains points to transform; results stored here.
*
*  COMMENTS:     Points are computed as: xv[i]' = m * xv[i].
*                The values xCenterWindow and yCenterWindow are then added
*                to translate each point so that it positioned relative to
*                the center of the window.
*
\******************************************************************************/

void XformVertices (int xCenterWindow, int yCenterWindow)
{
  int  i;

  for (i = 0; i < NUMVERTICES; i++)
  {
    LONG tempX;

    tempX   = (LONG) (m[0][0]*xv[i].x + m[0][1]*xv[i].y + m[0][2]*xv[i].z)
                    + xCenterWindow;
    xv[i].y = (LONG) (m[1][0]*xv[i].x + m[1][1]*xv[i].y + m[1][2]*xv[i].z)
                    + yCenterWindow;
    xv[i].x = tempX;
  }
}

unix.superglobalmegacorp.com

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