[futurebasic] Fast Polygon Drawing

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : June 1999 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Thu, 24 Jun 1999 00:29:38 +1200
From observation of the list traffic there would seem to be several members
interested in 3D graphics, and therefore in fast polygon-drawing. As a
recent disciple of this topic I have experimented with ways of speeding up
PAINTPOLY. The normal method of painting a triangle (see FN PaintTriangle
below) requires 8 QuickDraw calls. A small optimisation reduces this to 7,
by not "closing" the triangle -- closure is needed for FRAMEPOLY, but not
for PAINTPOLY.

A more substantial speedup is shown in FN FastPaintTriangle, where the
polygon information is poked into a pre-existing handle, thus reducing the
overhead -- but not of course the time actually required for PAINTPOLY to
do its drawing. In a typical 3D graphics application, involving the
painting of about 3000 small triangles, my frame rate was nearly doubled by
this simple trick.

Considerably more speed can be obtained from a custom PaintPoly routine. My
current attempt uses a mixture of FB and assembler; it paints triangles and
larger polygons, but is depressingly complicated and fails on many types of
convex polygon. Does anyone have a contribution to this holy grail?

COMPILE ,_dimmedvarsOnly
LOCAL FN FastPaintTriangle(pt0&,pt1&,pt2&,triangleH&)
  'accelerated PAINTPOLY;  pt0& etc are pointers to points
  DIM rect.0,ymin,xmin,ymax,xmax' bounds rect
  rect.topLeft&;4=pt0&: rect.botRight&;4=pt0&
  IF pt1&.v%<ymin THEN ymin=pt1&.v%
  IF pt1&.v%>ymax THEN ymax=pt1&.v%
  IF pt1&.h%<xmin THEN xmin=pt1&.h%
  IF pt1&.h%>xmax THEN xmax=pt1&.h%
  IF pt2&.v%<ymin THEN ymin=pt2&.v%
  IF pt2&.v%>ymax THEN ymax=pt2&.v%
  IF pt2&.h%<xmin THEN xmin=pt2&.h%
  IF pt2&.h%>xmax THEN xmax=pt2&.h%
  & [triangleH&]+2,rect.topLeft&' bounds rect
  & [triangleH&]+6,rect.botRight&' bounds rect
  & [triangleH&]+10,[pt0&]
  & [triangleH&]+14,[pt1&]
  & [triangleH&]+18,[pt2&]
  CALL PAINTPOLY(triangleH&)
END FN

LOCAL FN PaintTriangle(pt0&,pt1&,pt2&)
  ' normal QuickDraw;  pt0& etc are pointers to points
  DIM thePolyH&
  thePolyH&=FN OPENPOLY
  CALL MOVETO(pt0&.h%,pt0&.v%)
  CALL LINETO(pt1&.h%,pt1&.v%)
  CALL LINETO(pt2&.h%,pt2&.v%)
  'CALL LINETO(pt0&.h%,pt0&.v%)  'not needed for PAINTPOLY
  CALL CLOSEPOLY
  CALL PAINTPOLY(thePolyH&)
  CALL KILLPOLY(thePolyH&)
END FN

DIM pt0&;0,y0,x0, pt1&;0,y1,x1, pt2&;0,y2,x2 ' the vertices
DIM triangleH&,err,j,n,ticks&
WINDOW 1
_triangHSize=22                 ' for 3 points not closed
triangleH&=FN NEWHANDLE(_triangHSize)' used by FastPaintTriangle
POKE WORD [triangleH&],_triangHSize' preset

x0=100:y0=100: x1=110:y1=120: x2=120:y2=100
n=10000
ticks&=FN TICKCOUNT
FOR j=1 TO n
  FN PaintTriangle(@pt0&,@pt1&,@pt2&)
NEXT
ticks&=FN TICKCOUNT-ticks&
PRINT %(x2,y2) ticks& "ticks"

x0=x0+128: x1=x1+128 :x2=x2+128' offset
ticks&=FN TICKCOUNT
FOR j=1 TO n
  FN FastPaintTriangle(@pt0&,@pt1&,@pt2&,triangleH&)
NEXT
ticks&=FN TICKCOUNT-ticks&
PRINT %(x2,y2) ticks& "ticks"

DO: HANDLEEVENTS: UNTIL FN BUTTON
err=FN DISPOSHANDLE(triangleH&)
END

Robert Purves