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