1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25
26 /*
27 * $Id: rmstats.c,v 1.7 2005/06/06 02:04:29 wes Exp $
28 * Version: $Name: OpenRM-1-6-0-2-RC2 $
29 * $Revision: 1.7 $
30 * $Log: rmstats.c,v $
31 * Revision 1.7 2005/06/06 02:04:29 wes
32 * Lots of small additions to clean up compiler warnings.
33 *
34 * Revision 1.6 2005/02/19 16:22:50 wes
35 * Distro sync and consolidation.
36 *
37 * Revision 1.5 2005/01/23 17:00:22 wes
38 * Copyright updated to 2005.
39 *
40 * Revision 1.4 2004/01/16 16:48:35 wes
41 * Updated copyright line for 2004.
42 *
43 * Revision 1.3 2003/11/05 15:31:06 wes
44 * Updated to use new rmTime() routines introduced in 1.5.1.
45 *
46 * Revision 1.2 2003/02/02 02:07:16 wes
47 * Updated copyright to 2003.
48 *
49 * Revision 1.1.1.1 2003/01/28 02:15:23 wes
50 * Manual rebuild of rm150 repository.
51 *
52 * Revision 1.4 2003/01/16 22:21:17 wes
53 * Updated all source files to reflect new organization of header files:
54 * all header files formerly located in include/rmaux, include/rmi, include/rmv
55 * are now located in include/rm.
56 *
57 * Revision 1.3 2002/04/30 19:33:49 wes
58 * Updated copyright dates.
59 *
60 * Revision 1.2 2001/06/03 20:50:31 wes
61 * No significant differences.
62 *
63 * Revision 1.1 2001/03/31 17:29:14 wes
64 * Initial entry.
65 *
66 */
67
68 #include <rm/rm.h>
69 #include "rmprivat.h"
70 #include "rmstats.h"
71
72 static RMstats ss;
73
74 void
statsNodeFunc(RMnode * n,const RMstate * state,void * clientData)75 statsNodeFunc(RMnode *n,
76 const RMstate *state,
77 void *clientData)
78 {
79 RMstats *s = (RMstats *)clientData;
80 s->nNodes += 1;
81
82 /* in the future, we may want to use information in the RMstate */
83 state = NULL; /* foil compiler warning */
84
85 if (n->nprims != 0)
86 {
87 int i;
88 s->nPrims += n->nprims;
89 for (i=0;i<n->nprims;i++)
90 {
91 RMprimitive *p;
92 int nverts, vstride, vveclen;
93 RMvertex3D *v=NULL;
94
95 p = (RMprimitive *)(n->prims[i]);
96
97 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
98 switch (p->type)
99 {
100 /* code to count up stuff depending upon prim type */
101 case RM_LINES:
102 s->nVectors += (nverts/2);
103 break;
104 case RM_LINE_STRIP:
105 s->nVectors += (nverts - 1);
106 break;
107 case RM_TRIANGLES:
108 s->nTriangles += (nverts/3);
109 break;
110 case RM_TRIANGLE_STRIP:
111 s->nTriangles += (nverts-2);
112 break;
113 case RM_TRIANGLE_FAN:
114 s->nTriangles += (nverts-2);
115 break;
116
117 case RM_QUADMESH:
118 {
119 int *dims;
120 private_rmGetBlobData(BLOB_QMESHDIMS_INDEX, p, NULL, NULL, (void *)&dims, NULL);
121 s->nQuads += ((dims[0]-1) * (dims[1]-1));
122 }
123 break;
124 case RM_POINTS:
125 s->nPoints += (nverts);
126 break;
127
128 case RM_INDEXED_TFAN:
129 break;
130
131 case RM_POLYS:
132 break;
133
134 case RM_SPHERES:
135 {
136 /* spheres are made from disjoint triangles */
137 int modelFlag = rmPrimitiveGetModelFlag(p);
138 if (modelFlag == RM_SPHERES_8)
139 s->nTriangles += (nverts * 8);
140 else if (modelFlag == RM_SPHERES_32)
141 s->nTriangles += (nverts * 32);
142 else if (modelFlag == RM_SPHERES_128)
143 s->nTriangles += (nverts * 128);
144 else if (modelFlag == RM_SPHERES_512)
145 s->nTriangles += (nverts * 512);
146 }
147 break;
148
149 case RM_BOX3D:
150 s->nQuads = (nverts/2 * 6);
151 break;
152
153 case RM_BOX3D_WIRE:
154 break;
155
156 case RM_CONES:
157 {
158 /* cones are built from tstrips. the bottom of the
159 cone is built from a t-fan. 2 verts per cone. */
160
161 int modelFlag = rmPrimitiveGetModelFlag(p);
162
163 if (modelFlag == RM_CONES_4)
164 s->nTriangles += (nverts/2 * 8);
165 else if (modelFlag == RM_CONES_8)
166 s->nTriangles += (nverts/2 * 16);
167 else if (modelFlag == RM_CONES_12)
168 s->nTriangles += (nverts/2 * 24);
169 else if (modelFlag == RM_CONES_16)
170 s->nTriangles += (nverts/2 * 32);
171 else if (modelFlag == RM_CONES_32)
172 s->nTriangles += (nverts/2 * 64);
173 else if (modelFlag == RM_CONES_64)
174 s->nTriangles += (nverts/2 * 128);
175 else if (modelFlag == RM_CONES_128)
176 s->nTriangles += (nverts/2 * 256);
177 }
178 break;
179
180 case RM_CYLINDERS:
181 {
182 /* cylinders are built from tstrips. 2 verts per cylinder*/
183
184 int modelFlag = rmPrimitiveGetModelFlag(p);
185
186 if (modelFlag == RM_CYLINDERS_4)
187 s->nTriangles += (nverts/2 * 8);
188 else if (modelFlag == RM_CYLINDERS_8)
189 s->nTriangles += (nverts/2 * 16);
190 else if (modelFlag == RM_CYLINDERS_12)
191 s->nTriangles += (nverts/2 * 24);
192 else if (modelFlag == RM_CYLINDERS_16)
193 s->nTriangles += (nverts/2 * 32);
194 else if (modelFlag == RM_CYLINDERS_32)
195 s->nTriangles += (nverts/2 * 64);
196 else if (modelFlag == RM_CYLINDERS_64)
197 s->nTriangles += (nverts/2 * 128);
198 else if (modelFlag == RM_CYLINDERS_128)
199 s->nTriangles += (nverts/2 * 256);
200 }
201 break;
202
203 case RM_OCTMESH:
204 break;
205
206 case RM_TEXT:
207 break;
208
209 case RM_INDEXED_TEXT:
210 break;
211
212 case RM_QUADS:
213 s->nQuads += (nverts/4);
214 break;
215
216 case RM_MARKERS2D:
217 break;
218
219 case RM_CIRCLE2D:
220 break;
221
222 case RM_BOX2D:
223 break;
224
225 case RM_ELLIPSE2D:
226 break;
227
228 case RM_SPRITE:
229 break;
230
231 case RM_BITMAP:
232 break;
233
234 case RM_INDEXED_BITMAP:
235 break;
236
237 case RM_USERDEFINED_PRIM:
238 default:
239 break;
240 }
241 }
242 }
243 }
244
245 RMenum
rmStatsComputeDemography(RMnode * r)246 rmStatsComputeDemography (RMnode *r)
247 {
248 memset(&ss, 0,sizeof(RMstats));
249
250 /* count things in scene graph */
251 rmSceneGraphWalk(NULL, r, statsNodeFunc, (void *)&ss);
252 return(RM_CHILL);
253 }
254
255 RMenum
rmStatsStartTime(void)256 rmStatsStartTime(void)
257 {
258 /* initialize time entries in static RMstats structure */
259 rmTimeCurrent(&ss.renderStageTime[0]);
260 return(RM_CHILL);
261 }
262
263 RMenum
rmStatsEndTime(void)264 rmStatsEndTime(void)
265 {
266 /* make sure all rendering has been completed. note that glFinish()
267 will block execution until all rendering has been complete. It is
268 an expensive operation that will slow down applications. Use calls
269 to rmStatsEndTime sparingly!! */
270 /* glFinish(); */
271
272 /* get end times */
273 rmTimeCurrent(&ss.renderStageTime[1]);
274 return(RM_CHILL);
275 }
276
277 RMenum
rmStatsPrint(void)278 rmStatsPrint(void)
279 {
280 char buf1[256], buf2[256];
281 float msec;
282
283 memset(buf1,0,256);
284 memset(buf2,0,256);
285
286 #if 0
287 printf(" rmStatsPrint start=(%ld,%ld) end=(%ld,%ld) \n",ss.renderStageTime[0].sec, ss.renderStageTime[0].usec, ss.renderStageTime[1].sec, ss.renderStageTime[1].usec);
288 #endif
289
290 msec = rmTimeDifferenceMS(&(ss.renderStageTime[0]), &(ss.renderStageTime[1]));
291
292 /* print count of scene graph demography */
293 sprintf(buf1,"nodes\tprims\ttris\tquads\tvectors\ttex\tpbytes\tnpoints\ttime(ms)\n");
294 sprintf(buf2,"%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%g\n",ss.nNodes, ss.nPrims, ss.nTriangles, ss.nQuads, ss.nVectors, ss.nTextures, ss.nPixelBytes, ss.nPoints, msec);
295 /* print elapsed time */
296 fprintf(stderr,"%s", buf1);
297 fprintf(stderr,"%s", buf2);
298 return(RM_CHILL);
299 }
300
301 /* EOF */
302