Example #1
0
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);
}
Example #2
0
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;
	}