struct PointList* FillPolygon(struct PointListHeader * VertexList, int Color, int PolygonShape, int XOffset, int YOffset) { struct EdgeState *EdgeTableBuffer; int CurrentY; InitDraw(); // inits point list that will be "drawn" (added) to the list #ifdef CONVEX_CODE_LINKED /* Pass convex polygons through to fast convex polygon filler */ if (PolygonShape == CONVEX) return(FillConvexPolygon(VertexList, Color, XOffset, YOffset)); #endif /* It takes a minimum of 3 vertices to cause any pixels to be drawn; reject polygons that are guaranteed to be invisible */ if (VertexList->Length < 3) return(0); /* Get enough memory to store the entire edge table */ if ((EdgeTableBuffer = (struct EdgeState *) (malloc(sizeof(struct EdgeState) * VertexList->Length))) == NULL) return(0); /* couldn't get memory for the edge table */ /* Build the global edge table */ BuildGET(VertexList, EdgeTableBuffer, XOffset, YOffset); /* Scan down through the polygon edges, one scan line at a time, so long as at least one edge remains in either the GET or AET */ AETPtr = NULL; /* initialize the active edge table to empty */ CurrentY = GETPtr->StartY; /* start at the top polygon vertex */ while ((GETPtr != NULL) || (AETPtr != NULL)) { MoveXSortedToAET(CurrentY); /* update AET for this scan line */ ScanOutAET(CurrentY, Color); /* draw this scan line from AET */ AdvanceAET(); /* advance AET edges 1 scan line */ XSortAET(); /* resort on X */ CurrentY++; /* advance to the next scan line */ } /* Release the memory we've allocated and we're done */ free(EdgeTableBuffer); return(pointListTop); }
int CreateScanLinesFromPolygon (int iVertexCount, SPoint *pVertexList, CG16bitRegion::SRun **retpLines) // CreateScanLinesFromPolygon // // Creates a new array of scanlines from the given polygon. Returns the number of scanlines // in the array. The caller is responsible for freeing the newly allocated array. // // NOTE: This function is NOT thread-safe--it must never be called from more than one // thread simultaneously. // // Michael Abrash. Graphics Programming Black Book. Chapter 40. { // Reject polycons that have less then 3 vertices if (iVertexCount < 3) return 0; // Initialize the output g_iRunAlloc = INIT_ARRAY_ALLOC; g_pRuns = new CG16bitRegion::SRun [g_iRunAlloc]; g_iRunCount = 0; // Build the global edge table. This initializes g_pGET. SEdgeState *EdgeTableBuffer = new SEdgeState [iVertexCount]; BuildGlobalEdgeTable(iVertexCount, pVertexList, EdgeTableBuffer); // Active Edge Table is empty g_pAET = NULL; // Start at the top polygon vertex int yCurrent = g_pGET->yStart; // Scan down through the polygon edges, one scan line at a time, // so long as at least one edge remains in either the GET or AET while ((g_pGET != NULL) || (g_pAET != NULL)) { // Update AET for this scan line MoveXSortedToAET(yCurrent); // Add to lines ScanOutAET(yCurrent); // Advance AET edges 1 scan line AdvanceAET(); // Resort on X XSortAET(); // Next yCurrent++; } // Done if (g_iRunCount > 0) *retpLines = g_pRuns; else delete [] g_pRuns; return g_iRunCount; }