do_tris.c revision 533545b5
1/*****************************************************************************
2Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3
4                        All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22******************************************************************************/
23
24
25#undef POLYTRIANGLE_HACK    /* don't use this code */
26#ifdef POLYTRIANGLE_HACK
27#include <X11/Xlibint.h>
28#endif
29
30#include "x11perf.h"
31#include "bitmaps.h"
32#include <stdio.h>
33#include <math.h>
34
35#define NUM_POINTS 3   /* 3 points to a triangle */
36static XPoint *points;
37static GC     pgc;
38
39#ifndef PI
40#define PI  3.14159265357989
41#endif
42
43static double
44Area(XPoint p1, XPoint p2, XPoint p3)
45{
46    return
47      (p1.x*p2.y - p1.x*p3.y + p2.x*p3.y - p2.x*p1.y + p3.x*p1.y - p3.x*p2.y)/2;
48}
49
50/*
51static double
52Distance(XPoint p1, XPoint p2)
53{
54    return sqrt((float) ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)));
55}
56*/
57
58int
59InitTriangles(XParms xp, Parms p, int64_t reps)
60{
61    int     i, j, numPoints;
62    int     rows;
63    int     x, y;
64    int     size, iradius;
65    double  phi, phiinc, radius, delta, phi2, area, aarea;
66    XPoint  *curPoint;
67
68    pgc = xp->fggc;
69
70    size = p->special;
71    phi = 0.0;
72    delta = 2.0 * PI / ((double) NUM_POINTS);
73    if (xp->version == VERSION1_2) {
74	radius = ((double) size) * sqrt(3.0)/2.0;
75	phiinc = delta/10.0;
76    } else {
77	/* Version 1.2's radius computation was completely bogus, and resulted
78	   in triangles with sides about 50% longer than advertised.  However,
79	   this inadvertently resulted in triangles with areas just a little bit
80	   smaller than the triangle that covers size^2 pixels, which would
81	   make the area directly comparable to 10x10 rectangles and 10x10
82	   trapezoids.  So here's the new computation so -triangleN has the same
83	   area as -rectN.
84	 */
85	radius = ((double) size) * sqrt(sqrt(16.0/27.0));
86	phiinc = 1.75*PI / ((double) p->objects);
87    }
88    iradius = (int) (radius + 0.5);
89
90    numPoints = (p->objects) * NUM_POINTS;
91    points = (XPoint *)malloc(numPoints * sizeof(XPoint));
92    curPoint = points;
93    x = iradius;
94    y = iradius;
95    rows = 0;
96    aarea = 0.0;
97
98    for (i = 0; i != p->objects; i++) {
99	for (j = 0; j != NUM_POINTS; j++) {
100	    phi2 = phi + ((double) j) * delta;
101	    curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5);
102	    curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5);
103	    curPoint++;
104	}
105	area = Area(curPoint[-1], curPoint[-2], curPoint[-3]);
106	aarea += area;
107/*	printf("%6.1lf %6.1lf %6.1lf   %6.1lf\n",
108	    Distance(curPoint[-1], curPoint[-2]),
109	    Distance(curPoint[-1], curPoint[-3]),
110	    Distance(curPoint[-2], curPoint[-3]),
111	    area);
112*/
113	phi += phiinc;
114	y += 2 * iradius;
115	rows++;
116	if (y + iradius > HEIGHT || rows == MAXROWS) {
117	    rows = 0;
118	    y = iradius;
119	    x += 2 * iradius;
120	    if (x + iradius > WIDTH) {
121		x = iradius;
122	    }
123	}
124    }
125/*    printf("Average area = %6.2lf\n", aarea/p->objects); */
126
127    SetFillStyle(xp, p);
128
129    return reps;
130}
131
132#ifndef POLYTRIANGLE_HACK
133
134void
135DoTriangles(XParms xp, Parms p, int64_t reps)
136{
137    int     i, j;
138    XPoint  *curPoint;
139
140    for (i = 0; i != reps; i++) {
141        curPoint = points;
142        for (j = 0; j != p->objects; j++) {
143            XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Convex,
144			 CoordModeOrigin);
145            curPoint += NUM_POINTS;
146	}
147        if (pgc == xp->bggc)
148            pgc = xp->fggc;
149        else
150            pgc = xp->bggc;
151	CheckAbort ();
152    }
153}
154
155#else
156
157static xReq _dummy_request = {
158	0, 0, 0
159};
160
161static void
162XPolyTriangle(register Display *dpy,
163	      Drawable d, GC gc, XPoint *points,
164	      int n_triangles, int shape, int mode)
165{
166    register xFillPolyReq *req;
167    register long nbytes;
168    int		max_triangles;
169    int		n_this_time;
170    int		*buf, *pts;
171    int		gcid;
172    int		last;
173
174    max_triangles = (dpy->bufmax - dpy->buffer) / 28;
175    LockDisplay(dpy);
176    FlushGC(dpy, gc);
177    dpy->request += n_triangles;
178    pts = (int *) points;
179    gcid = gc->gid;
180    last = shape | (mode << 8);
181    while (n_triangles)
182    {
183	if ((n_this_time = max_triangles) > n_triangles)
184	    n_this_time = n_triangles;
185	n_triangles -= n_this_time;
186	GetReqExtra(FillPoly,
187	    (SIZEOF(xFillPolyReq) + 12) * n_this_time - SIZEOF(xFillPolyReq), req);
188	--dpy->request;
189
190	buf = req;
191        while (n_this_time--)
192	{
193	    buf[0] = X_FillPoly | (7 << 16);
194	    buf[1] = d;
195	    buf[2] = gcid;
196	    buf[3] = last;
197	    buf[4] = pts[0];
198	    buf[5] = pts[1];
199	    buf[6] = pts[2];
200	    buf += 7;
201	    pts += 3;
202	}
203    }
204    dpy->last_req = &_dummy_request;
205    UnlockDisplay(dpy);
206    SyncHandle();
207}
208
209void
210DoTriangles(XParms xp, Parms p, int64_t reps)
211{
212    int     i, j;
213    XPoint  *curPoint;
214
215    for (i = 0; i != reps; i++) {
216        XPolyTriangle (xp->d, xp->w, pgc, points, p->objects, Convex,
217			 CoordModeOrigin);
218        if (pgc == xp->bggc)
219            pgc = xp->fggc;
220        else
221            pgc = xp->bggc;
222	CheckAbort ();
223    }
224}
225#endif
226
227void
228EndTriangles(XParms xp, Parms p)
229{
230    free(points);
231}
232
233