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