15669413 |
1 | // Copyright (c) 2017 OPEN CASCADE SAS |
2 | // |
3 | // This file is part of Open CASCADE Technology software library. |
4 | // |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
10 | // |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
13 | |
14 | #include <OpenGl_FrameStats.hxx> |
15 | |
16 | #include <OpenGl_GlCore20.hxx> |
17 | #include <OpenGl_View.hxx> |
18 | #include <OpenGl_Workspace.hxx> |
19 | |
20 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameStats, Standard_Transient) |
21 | |
22 | namespace |
23 | { |
24 | //! Format counter. |
25 | static std::ostream& formatCounter (std::ostream& theStream, |
26 | Standard_Integer theWidth, |
27 | const char* thePrefix, |
28 | Standard_Size theValue, |
29 | const char* thePostfix = NULL) |
30 | { |
31 | if (thePrefix != NULL) |
32 | { |
33 | theStream << thePrefix; |
34 | } |
35 | theStream << std::setfill(' ') << std::setw (theWidth); |
36 | if (theValue >= 1000000000) |
37 | { |
38 | Standard_Real aValM = Standard_Real(theValue) / 1000000000.0; |
39 | theStream << std::fixed << std::setprecision (1) << aValM << "G"; |
40 | } |
41 | else if (theValue >= 1000000) |
42 | { |
43 | Standard_Real aValM = Standard_Real(theValue) / 1000000.0; |
44 | theStream << std::fixed << std::setprecision (1) << aValM << "M"; |
45 | } |
46 | else if (theValue >= 1000) |
47 | { |
48 | Standard_Real aValK = Standard_Real(theValue) / 1000.0; |
49 | theStream << std::fixed << std::setprecision (1) << aValK << "k"; |
50 | } |
51 | else |
52 | { |
53 | theStream << theValue; |
54 | } |
55 | if (thePostfix != NULL) |
56 | { |
57 | theStream << thePostfix; |
58 | } |
59 | return theStream; |
60 | } |
61 | |
62 | //! Format memory counter. |
63 | static std::ostream& formatBytes (std::ostream& theStream, |
64 | Standard_Integer theWidth, |
65 | const char* thePrefix, |
66 | Standard_Size theValue, |
67 | const char* thePostfix = NULL) |
68 | { |
69 | if (thePrefix != NULL) |
70 | { |
71 | theStream << thePrefix; |
72 | } |
73 | theStream << std::setfill(' ') << std::setw (theWidth); |
74 | if (theValue >= 1024 * 1024 * 1024) |
75 | { |
76 | Standard_Real aValM = Standard_Real(theValue) / (1024.0 * 1024.0 * 1024.0); |
77 | theStream << std::fixed << std::setprecision (1) << aValM << " GiB"; |
78 | } |
79 | else if (theValue >= 1024 * 1024) |
80 | { |
81 | Standard_Real aValM = Standard_Real(theValue) / (1024.0 * 1024.0); |
82 | theStream << std::fixed << std::setprecision (1) << aValM << " MiB"; |
83 | } |
84 | else if (theValue >= 1024) |
85 | { |
86 | Standard_Real aValK = Standard_Real(theValue) / 1024.0; |
87 | theStream << std::fixed << std::setprecision (1) << aValK << " KiB"; |
88 | } |
89 | else |
90 | { |
91 | theStream << theValue; |
92 | } |
93 | if (thePostfix != NULL) |
94 | { |
95 | theStream << thePostfix; |
96 | } |
97 | return theStream; |
98 | } |
99 | |
100 | //! Return estimated data size. |
101 | static Standard_Size estimatedDataSize (const Handle(OpenGl_Resource)& theRes) |
102 | { |
103 | return !theRes.IsNull() ? theRes->EstimatedDataSize() : 0; |
104 | } |
105 | } |
106 | |
107 | // ======================================================================= |
108 | // function : OpenGl_FrameStats |
109 | // purpose : |
110 | // ======================================================================= |
111 | OpenGl_FrameStats::OpenGl_FrameStats() |
112 | : myFpsTimer (Standard_True), |
113 | myFrameStartTime (0.0), |
114 | myFrameDuration (0.0), |
115 | myFps (-1.0), |
116 | myFpsCpu (-1.0), |
117 | myUpdateInterval (1.0), |
118 | myFpsFrameCount (0), |
119 | myIsLongLineFormat (Standard_False) |
120 | { |
121 | memset (myCounters, 0, sizeof(myCounters)); |
122 | memset (myCountersTmp, 0, sizeof(myCountersTmp)); |
123 | } |
124 | |
125 | // ======================================================================= |
126 | // function : ~OpenGl_FrameStats |
127 | // purpose : |
128 | // ======================================================================= |
129 | OpenGl_FrameStats::~OpenGl_FrameStats() |
130 | { |
131 | // |
132 | } |
133 | |
134 | // ======================================================================= |
135 | // function : FormatStats |
136 | // purpose : |
137 | // ======================================================================= |
138 | TCollection_AsciiString OpenGl_FrameStats::FormatStats (Graphic3d_RenderingParams::PerfCounters theFlags) const |
139 | { |
140 | const Standard_Integer aValWidth = 5; |
141 | std::stringstream aBuf; |
142 | const Standard_Boolean isCompact = theFlags == Graphic3d_RenderingParams::PerfCounters_FrameRate; // only FPS is displayed |
143 | if (myIsLongLineFormat |
144 | && (theFlags & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0 |
145 | && (theFlags & Graphic3d_RenderingParams::PerfCounters_CPU) != 0) |
146 | { |
147 | aBuf << "FPS: " << std::setfill(' ') << std::setw (isCompact ? aValWidth : 9) << std::fixed << std::setprecision (1) << myFps |
148 | << " [CPU: " << std::setfill(' ') << std::setw (isCompact ? aValWidth : 10) << std::fixed << std::setprecision (1) << myFpsCpu << "]\n"; |
149 | } |
150 | else |
151 | { |
152 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0) |
153 | { |
154 | aBuf << "FPS: " << std::setfill(' ') << std::setw (isCompact ? aValWidth : aValWidth + 3) << std::fixed << std::setprecision (1) << myFps << "\n"; |
155 | } |
156 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_CPU) != 0) |
157 | { |
158 | aBuf << "CPU FPS: " << std::setfill(' ') << std::setw (isCompact ? aValWidth : aValWidth + 3) << std::fixed << std::setprecision (1) << myFpsCpu << "\n"; |
159 | } |
160 | } |
161 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Layers) != 0) |
162 | { |
163 | if (myIsLongLineFormat) |
164 | { |
165 | formatCounter (aBuf, aValWidth, "Layers: ", myCounters[Counter_NbLayers]); |
166 | if (HasCulledLayers()) |
167 | { |
168 | formatCounter (aBuf, aValWidth, " [rendered: ", myCounters[Counter_NbLayersNotCulled], "]"); |
169 | } |
170 | aBuf << "\n"; |
171 | } |
172 | else |
173 | { |
174 | formatCounter (aBuf, aValWidth + 3, "Layers: ", myCounters[Counter_NbLayers], "\n"); |
175 | } |
176 | } |
177 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Structures) != 0) |
178 | { |
179 | if (myIsLongLineFormat) |
180 | { |
181 | formatCounter (aBuf, aValWidth, "Structs: ", myCounters[Counter_NbStructs]); |
182 | if (HasCulledStructs()) |
183 | { |
184 | formatCounter (aBuf, aValWidth, " [rendered: ", myCounters[Counter_NbStructsNotCulled], "]"); |
185 | } |
186 | aBuf << "\n"; |
187 | } |
188 | else |
189 | { |
190 | formatCounter (aBuf, aValWidth + 3, "Structs: ", myCounters[Counter_NbStructs], "\n"); |
191 | } |
192 | } |
193 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Groups) != 0 |
194 | || (theFlags & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0 |
195 | || (theFlags & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0 |
196 | || (theFlags & Graphic3d_RenderingParams::PerfCounters_Points) != 0 |
197 | || (!myIsLongLineFormat |
198 | && ((theFlags & Graphic3d_RenderingParams::PerfCounters_Structures) != 0 |
199 | || (theFlags & Graphic3d_RenderingParams::PerfCounters_Layers) != 0))) |
200 | { |
201 | aBuf << "Rendered\n"; |
202 | } |
203 | if (!myIsLongLineFormat |
204 | && (theFlags & Graphic3d_RenderingParams::PerfCounters_Layers) != 0) |
205 | { |
206 | formatCounter (aBuf, aValWidth, " Layers: ", myCounters[Counter_NbLayersNotCulled], "\n"); |
207 | } |
208 | if (!myIsLongLineFormat |
209 | && (theFlags & Graphic3d_RenderingParams::PerfCounters_Structures) != 0) |
210 | { |
211 | formatCounter (aBuf, aValWidth, " Structs: ", myCounters[Counter_NbStructsNotCulled], "\n"); |
212 | } |
213 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Groups) != 0) |
214 | { |
215 | formatCounter (aBuf, aValWidth, " Groups: ", myCounters[Counter_NbGroupsNotCulled], "\n"); |
216 | } |
217 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0) |
218 | { |
219 | formatCounter (aBuf, aValWidth, " Arrays: ", myCounters[Counter_NbElemsNotCulled], "\n"); |
220 | formatCounter (aBuf, aValWidth, " [fill]: ", myCounters[Counter_NbElemsFillNotCulled], "\n"); |
221 | formatCounter (aBuf, aValWidth, " [line]: ", myCounters[Counter_NbElemsLineNotCulled], "\n"); |
222 | formatCounter (aBuf, aValWidth, " [point]: ", myCounters[Counter_NbElemsPointNotCulled], "\n"); |
223 | formatCounter (aBuf, aValWidth, " [text]: ", myCounters[Counter_NbElemsTextNotCulled], "\n"); |
224 | } |
225 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0) |
226 | { |
227 | formatCounter (aBuf, aValWidth, " Triangles: ", myCounters[Counter_NbTrianglesNotCulled], "\n"); |
228 | } |
229 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_Points) != 0) |
230 | { |
231 | formatCounter (aBuf, aValWidth, " Points: ", myCounters[Counter_NbPointsNotCulled], "\n"); |
232 | } |
233 | if ((theFlags & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0) |
234 | { |
235 | aBuf << "GPU Memory\n"; |
236 | formatBytes (aBuf, aValWidth, " Geometry: ", myCounters[Counter_EstimatedBytesGeom], "\n"); |
237 | formatBytes (aBuf, aValWidth, " Textures: ", myCounters[Counter_EstimatedBytesTextures], "\n"); |
238 | formatBytes (aBuf, aValWidth, " Frames: ", myCounters[Counter_EstimatedBytesFbos], "\n"); |
239 | } |
240 | return TCollection_AsciiString (aBuf.str().c_str()); |
241 | } |
242 | |
243 | // ======================================================================= |
244 | // function : FrameStart |
245 | // purpose : |
246 | // ======================================================================= |
247 | void OpenGl_FrameStats::FrameStart (const Handle(OpenGl_Workspace)& ) |
248 | { |
249 | memset (myCountersTmp, 0, sizeof(myCountersTmp)); |
250 | myFrameStartTime = myFpsTimer.ElapsedTime(); |
251 | if (!myFpsTimer.IsStarted()) |
252 | { |
253 | myFpsTimer.Reset(); |
254 | myFpsTimer.Start(); |
255 | myFpsFrameCount = 0; |
256 | } |
257 | } |
258 | |
259 | // ======================================================================= |
260 | // function : FrameEnd |
261 | // purpose : |
262 | // ======================================================================= |
263 | void OpenGl_FrameStats::FrameEnd (const Handle(OpenGl_Workspace)& theWorkspace) |
264 | { |
265 | const Graphic3d_RenderingParams::PerfCounters aBits = !theWorkspace.IsNull() |
266 | ? theWorkspace->View()->RenderingParams().CollectedStats |
267 | : Graphic3d_RenderingParams::PerfCounters_NONE; |
268 | const double aTime = myFpsTimer.ElapsedTime(); |
269 | myFrameDuration = aTime - myFrameStartTime; |
270 | ++myFpsFrameCount; |
271 | if (!theWorkspace.IsNull()) |
272 | { |
273 | myUpdateInterval = theWorkspace->View()->RenderingParams().StatsUpdateInterval; |
274 | } |
275 | |
276 | if (aTime < myUpdateInterval) |
277 | { |
278 | return; |
279 | } |
280 | |
281 | if (aTime > gp::Resolution()) |
282 | { |
283 | // update FPS |
284 | myFpsTimer.Stop(); |
285 | const double aCpuSec = myFpsTimer.UserTimeCPU(); |
286 | myFps = double(myFpsFrameCount) / aTime; |
287 | myFpsCpu = aCpuSec > gp::Resolution() |
288 | ? double(myFpsFrameCount) / aCpuSec |
289 | : -1.0; |
290 | myFpsTimer.Reset(); |
291 | myFpsTimer.Start(); |
292 | myFpsFrameCount = 0; |
293 | } |
294 | |
295 | // update structure counters |
296 | if (theWorkspace.IsNull()) |
297 | { |
298 | memcpy (myCounters, myCountersTmp, sizeof(myCounters)); |
299 | return; |
300 | } |
301 | |
302 | const Standard_Boolean toCountMem = (aBits & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0; |
303 | const Standard_Boolean toCountTris = (aBits & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0 |
304 | || (aBits & Graphic3d_RenderingParams::PerfCounters_Points) != 0; |
305 | const Standard_Boolean toCountElems = (aBits & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0 || toCountTris || toCountMem; |
306 | const Standard_Boolean toCountGroups = (aBits & Graphic3d_RenderingParams::PerfCounters_Groups) != 0 || toCountElems; |
5dc0517d |
307 | const Standard_Boolean toCountStructs = (aBits & Graphic3d_RenderingParams::PerfCounters_Structures) != 0 |
308 | || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0 || toCountGroups; |
309 | |
310 | myCountersTmp[Counter_NbLayers] = theWorkspace->View()->LayerList().Layers().Size(); |
311 | if (toCountStructs |
312 | || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0) |
15669413 |
313 | { |
5dc0517d |
314 | const Standard_Integer aViewId = theWorkspace->View()->Identification(); |
15669413 |
315 | for (OpenGl_SequenceOfLayers::Iterator aLayerIter (theWorkspace->View()->LayerList().Layers()); aLayerIter.More(); aLayerIter.Next()) |
316 | { |
317 | const Handle(OpenGl_Layer)& aLayer = aLayerIter.Value(); |
318 | if (!aLayer->IsCulled()) |
319 | { |
320 | ++myCountersTmp[Counter_NbLayersNotCulled]; |
321 | } |
322 | myCountersTmp[Counter_NbStructs] += aLayer->NbStructures(); |
323 | myCountersTmp[Counter_NbStructsNotCulled] += aLayer->NbStructuresNotCulled(); |
324 | if (toCountGroups) |
325 | { |
5dc0517d |
326 | updateStructures (aViewId, aLayer->CullableStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem); |
327 | updateStructures (aViewId, aLayer->CullableTrsfPersStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem); |
328 | updateStructures (aViewId, aLayer->NonCullableStructures(), toCountElems, toCountTris, toCountMem); |
15669413 |
329 | } |
330 | } |
331 | } |
332 | if (toCountMem |
333 | && !theWorkspace.IsNull()) |
334 | { |
335 | for (OpenGl_Context::OpenGl_ResourcesMap::Iterator aResIter (theWorkspace->GetGlContext()->SharedResources()); |
336 | aResIter.More(); aResIter.Next()) |
337 | { |
338 | myCountersTmp[Counter_EstimatedBytesTextures] += aResIter.Value()->EstimatedDataSize(); |
339 | } |
340 | |
341 | const OpenGl_View* aView = theWorkspace->View(); |
342 | { |
343 | Standard_Size& aMemFbos = myCountersTmp[Counter_EstimatedBytesFbos]; |
344 | // main FBOs |
345 | aMemFbos += estimatedDataSize (aView->myMainSceneFbos[0]); |
346 | aMemFbos += estimatedDataSize (aView->myMainSceneFbos[1]); |
347 | aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[0]); |
348 | aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[1]); |
349 | // OIT FBOs |
350 | aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[0]); |
351 | aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[1]); |
352 | aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[0]); |
353 | aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[1]); |
354 | // dump FBO |
355 | aMemFbos += estimatedDataSize (aView->myFBO); |
356 | // RayTracing FBO |
357 | aMemFbos += estimatedDataSize (aView->myOpenGlFBO); |
358 | aMemFbos += estimatedDataSize (aView->myOpenGlFBO2); |
359 | aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[0]); |
360 | aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[1]); |
361 | aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[0]); |
362 | aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[1]); |
363 | // also RayTracing |
364 | aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[0]); |
365 | aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[1]); |
366 | aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[0]); |
367 | aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[1]); |
368 | aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[0]); |
369 | aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[1]); |
370 | } |
371 | { |
372 | // Ray Tracing geometry |
373 | Standard_Size& aMemGeom = myCountersTmp[Counter_EstimatedBytesGeom]; |
374 | aMemGeom += estimatedDataSize (aView->mySceneNodeInfoTexture); |
375 | aMemGeom += estimatedDataSize (aView->mySceneMinPointTexture); |
376 | aMemGeom += estimatedDataSize (aView->mySceneMaxPointTexture); |
377 | aMemGeom += estimatedDataSize (aView->mySceneTransformTexture); |
378 | aMemGeom += estimatedDataSize (aView->myGeometryVertexTexture); |
379 | aMemGeom += estimatedDataSize (aView->myGeometryNormalTexture); |
380 | aMemGeom += estimatedDataSize (aView->myGeometryTexCrdTexture); |
381 | aMemGeom += estimatedDataSize (aView->myGeometryTriangTexture); |
382 | aMemGeom += estimatedDataSize (aView->myRaytraceMaterialTexture); |
383 | aMemGeom += estimatedDataSize (aView->myRaytraceLightSrcTexture); |
384 | } |
385 | } |
386 | memcpy (myCounters, myCountersTmp, sizeof(myCounters)); |
387 | } |
388 | |
389 | // ======================================================================= |
390 | // function : updateStructures |
391 | // purpose : |
392 | // ======================================================================= |
5dc0517d |
393 | void OpenGl_FrameStats::updateStructures (Standard_Integer theViewId, |
394 | const OpenGl_IndexedMapOfStructure& theStructures, |
15669413 |
395 | Standard_Boolean theToCountElems, |
396 | Standard_Boolean theToCountTris, |
397 | Standard_Boolean theToCountMem) |
398 | { |
399 | for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next()) |
400 | { |
401 | const OpenGl_Structure* aStruct = aStructIter.Value(); |
0de16e29 |
402 | const bool isStructHidden = aStruct->IsCulled() |
403 | || !aStruct->IsVisible (theViewId); |
404 | for (; aStruct != NULL; aStruct = aStruct->InstancedStructure()) |
15669413 |
405 | { |
0de16e29 |
406 | if (isStructHidden) |
15669413 |
407 | { |
0de16e29 |
408 | if (theToCountMem) |
15669413 |
409 | { |
0de16e29 |
410 | for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next()) |
15669413 |
411 | { |
0de16e29 |
412 | const OpenGl_Group* aGroup = aGroupIter.Value(); |
413 | for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next) |
15669413 |
414 | { |
0de16e29 |
415 | if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem)) |
416 | { |
417 | myCountersTmp[Counter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo()); |
418 | myCountersTmp[Counter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo()); |
419 | } |
15669413 |
420 | } |
421 | } |
422 | } |
0de16e29 |
423 | continue; |
15669413 |
424 | } |
15669413 |
425 | |
0de16e29 |
426 | myCountersTmp[Counter_NbGroupsNotCulled] += aStruct->Groups().Size(); |
427 | if (!theToCountElems) |
428 | { |
429 | continue; |
430 | } |
15669413 |
431 | |
0de16e29 |
432 | for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next()) |
15669413 |
433 | { |
0de16e29 |
434 | const OpenGl_Group* aGroup = aGroupIter.Value(); |
435 | for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next) |
15669413 |
436 | { |
0de16e29 |
437 | if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem)) |
15669413 |
438 | { |
0de16e29 |
439 | ++myCountersTmp[Counter_NbElemsNotCulled]; |
440 | if (theToCountMem) |
15669413 |
441 | { |
0de16e29 |
442 | myCountersTmp[Counter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo()); |
443 | myCountersTmp[Counter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo()); |
15669413 |
444 | } |
445 | |
0de16e29 |
446 | if (aPrim->IsFillDrawMode()) |
15669413 |
447 | { |
0de16e29 |
448 | ++myCountersTmp[Counter_NbElemsFillNotCulled]; |
449 | if (!theToCountTris) |
15669413 |
450 | { |
0de16e29 |
451 | continue; |
15669413 |
452 | } |
0de16e29 |
453 | |
454 | const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo(); |
455 | if (anAttribs.IsNull() |
456 | || !anAttribs->IsValid()) |
15669413 |
457 | { |
0de16e29 |
458 | continue; |
15669413 |
459 | } |
0de16e29 |
460 | |
461 | const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo(); |
462 | const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb(); |
463 | const Standard_Integer aNbBounds = !aPrim->Bounds().IsNull() ? aPrim->Bounds()->NbBounds : 1; |
464 | switch (aPrim->DrawMode()) |
15669413 |
465 | { |
0de16e29 |
466 | case GL_TRIANGLES: |
467 | { |
468 | myCountersTmp[Counter_NbTrianglesNotCulled] += aNbIndices / 3; |
469 | break; |
470 | } |
471 | case GL_TRIANGLE_STRIP: |
472 | case GL_TRIANGLE_FAN: |
473 | { |
474 | myCountersTmp[Counter_NbTrianglesNotCulled] += aNbIndices - 2 * aNbBounds; |
475 | break; |
476 | } |
477 | case GL_TRIANGLES_ADJACENCY: |
478 | { |
479 | myCountersTmp[Counter_NbTrianglesNotCulled] += aNbIndices / 6; |
480 | break; |
481 | } |
482 | case GL_TRIANGLE_STRIP_ADJACENCY: |
483 | { |
484 | myCountersTmp[Counter_NbTrianglesNotCulled] += aNbIndices - 4 * aNbBounds; |
485 | break; |
486 | } |
487 | #if !defined(GL_ES_VERSION_2_0) |
488 | case GL_QUADS: |
489 | { |
490 | myCountersTmp[Counter_NbTrianglesNotCulled] += aNbIndices / 2; |
491 | break; |
492 | } |
493 | case GL_QUAD_STRIP: |
494 | { |
495 | myCountersTmp[Counter_NbTrianglesNotCulled] += (aNbIndices / 2 - aNbBounds) * 2; |
496 | break; |
497 | } |
498 | #endif |
15669413 |
499 | } |
15669413 |
500 | } |
0de16e29 |
501 | else if (aPrim->DrawMode() == GL_POINTS) |
15669413 |
502 | { |
0de16e29 |
503 | ++myCountersTmp[Counter_NbElemsPointNotCulled]; |
504 | if (theToCountTris) |
15669413 |
505 | { |
0de16e29 |
506 | const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo(); |
507 | if (!anAttribs.IsNull() |
508 | && anAttribs->IsValid()) |
509 | { |
510 | const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo(); |
511 | const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb(); |
512 | myCountersTmp[Counter_NbPointsNotCulled] += aNbIndices; |
513 | } |
15669413 |
514 | } |
515 | } |
0de16e29 |
516 | else |
517 | { |
518 | ++myCountersTmp[Counter_NbElemsLineNotCulled]; |
519 | } |
15669413 |
520 | } |
0de16e29 |
521 | else if (const OpenGl_Text* aText = dynamic_cast<const OpenGl_Text*> (aNodeIter->elem)) |
15669413 |
522 | { |
0de16e29 |
523 | (void )aText; |
524 | ++myCountersTmp[Counter_NbElemsNotCulled]; |
525 | ++myCountersTmp[Counter_NbElemsTextNotCulled]; |
15669413 |
526 | } |
527 | } |
15669413 |
528 | } |
529 | } |
530 | } |
531 | } |