|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.