00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 /* 00027 00028 Although the code is original, many of the ideas for the profiler were borrowed from 00029 "Real-Time In-Game Profiling" by Steve Rabin which can be found in Game Programming 00030 Gems 1. 00031 00032 This code can easily be adapted to your own non-Ogre project. The only code that is 00033 Ogre-dependent is in the visualization/logging routines and the use of the Timer class. 00034 00035 Enjoy! 00036 00037 */ 00038 00039 #include "OgreProfiler.h" 00040 #include "OgreTimer.h" 00041 #include "OgreLogManager.h" 00042 #include "OgreStringConverter.h" 00043 #include "OgreOverlayManager.h" 00044 #include "OgreOverlay.h" 00045 #include "OgreGuiManager.h" 00046 #include "OgreGuiElement.h" 00047 #include "OgreGuiContainer.h" 00048 00049 namespace Ogre { 00050 //----------------------------------------------------------------------- 00051 // PROFILE DEFINITIONS 00052 //----------------------------------------------------------------------- 00053 Profile::Profile(const String& profileName) { 00054 00055 mName = profileName; 00056 00057 Ogre::Profiler::getSingleton().beginProfile(profileName); 00058 00059 } 00060 //----------------------------------------------------------------------- 00061 Profile::~Profile() { 00062 00063 Ogre::Profiler::getSingleton().endProfile(mName); 00064 00065 } 00066 //----------------------------------------------------------------------- 00067 00068 00069 //----------------------------------------------------------------------- 00070 // PROFILER DEFINITIONS 00071 //----------------------------------------------------------------------- 00072 template<> Profiler* Singleton<Profiler>::ms_Singleton = 0; 00073 //----------------------------------------------------------------------- 00074 Profiler::Profiler() { 00075 00076 // init some variables 00077 mTimer = 0; 00078 mTotalFrameTime = 0; 00079 mUpdateDisplayFrequency = 0; 00080 mCurrentFrame = 0; 00081 mEnabled = mNewEnableState = false; // the profiler starts out as disabled 00082 mEnableStateChangePending = false; 00083 mInitialized = false; 00084 maxProfiles = 50; 00085 00086 // by default the display will be updated every 10 frames 00087 mUpdateDisplayFrequency = 10; 00088 00089 } 00090 //----------------------------------------------------------------------- 00091 Profiler::~Profiler() { 00092 00093 if (!mProfileHistory.empty()) { 00094 // log the results of our profiling before we quit 00095 logResults(); 00096 } 00097 00098 // clear all our lists 00099 mProfiles.clear(); 00100 mProfileFrame.clear(); 00101 mProfileHistoryMap.clear(); 00102 mProfileHistory.clear(); 00103 mDisabledProfiles.clear(); 00104 mProfileBars.clear(); 00105 00106 } 00107 //----------------------------------------------------------------------- 00108 void Profiler::initialize() { 00109 00110 // init some gui characteristics 00111 mBarHeight = 10; //0.02; 00112 mGuiBorderWidth = 10; //0.02; 00113 mGuiHeight = 25; //0.05; 00114 mGuiWidth = 250; //0.15; 00115 mBarIndent = mGuiWidth; 00116 mBarLineWidth = 2; 00117 00118 // create a new overlay to hold our Profiler display 00119 mOverlay = (Overlay*)OverlayManager::getSingleton().create("Profiler"); 00120 mOverlay->setZOrder(500); 00121 00122 // this panel will be the main container for our profile bars 00123 mProfileGui = createContainer(); 00124 00125 GuiElement* element; 00126 00127 // we create the little "ticks" above the profiles 00128 for (uint k = 1; k < 10; ++k) { // we don't want a tick at 0% or 100% 00129 00130 if (k != 5) { // we don't want a tick at 50% 00131 element = createTextArea("ProfileKeyLine" + StringConverter::toString(k), 20, 10, 2, mGuiWidth * (1 + k * .1), 9, "|"); 00132 mProfileGui->addChild(element); 00133 } 00134 00135 } 00136 00137 // we create a 0% marker 00138 element = createTextArea("ProfileKey0", 50, 10, 2, mGuiWidth * 0.99, 9, "0%"); 00139 mProfileGui->addChild(element); 00140 00141 // we create a 50% marker 00142 element = createTextArea("ProfileyKey50", 50, 10, 2, mGuiWidth * 1.48, 9, "50%"); 00143 mProfileGui->addChild(element); 00144 00145 // we create a 100% marker 00146 element = createTextArea("ProfileKey100", 50, 10, 2, mGuiWidth * 1.98, 9, "100%"); 00147 mProfileGui->addChild(element); 00148 00149 // we create an initial pool of 50 profile bars 00150 for (uint i = 0; i < maxProfiles; ++i) { 00151 00152 // this is for the profile name and the number of times it was called in a frame 00153 element = createTextArea("profileText" + StringConverter::toString(i), 90, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, 14, "", false); 00154 mProfileGui->addChild(element); 00155 mProfileBars.push_back(element); 00156 00157 // this indicates the current frame time 00158 element = createPanel("currBar" + StringConverter::toString(i), 0, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, mBarIndent, "Core/ProfilerCurrent", false); 00159 mProfileGui->addChild(element); 00160 mProfileBars.push_back(element); 00161 00162 // this indicates the minimum frame time 00163 element = createPanel("minBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerMin", false); 00164 mProfileGui->addChild(element); 00165 mProfileBars.push_back(element); 00166 00167 // this indicates the maximum frame time 00168 element = createPanel("maxBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerMax", false); 00169 mProfileGui->addChild(element); 00170 mProfileBars.push_back(element); 00171 00172 // this indicates the average frame time 00173 element = createPanel("avgBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerAvg", false); 00174 mProfileGui->addChild(element); 00175 mProfileBars.push_back(element); 00176 00177 } 00178 00179 // throw everything all the GUI stuff into the overlay and display it 00180 mOverlay->add2D(mProfileGui); 00181 mOverlay->show(); 00182 00183 } 00184 //----------------------------------------------------------------------- 00185 void Profiler::setTimer(Timer* t) { 00186 00187 mTimer = t; 00188 00189 } 00190 //----------------------------------------------------------------------- 00191 Timer* Profiler::getTimer() { 00192 00193 assert(mTimer && "Timer not set!"); 00194 return mTimer; 00195 00196 } 00197 //----------------------------------------------------------------------- 00198 void Profiler::setEnabled(bool enabled) { 00199 00200 if (!mInitialized && enabled) { 00201 00202 // the user wants to enable the Profiler for the first time 00203 // so we initialize the GUI stuff 00204 initialize(); 00205 mInitialized = true; 00206 mEnabled = true; 00207 00208 } 00209 else { 00210 // We store this enable/disable request until the frame ends 00211 // (don't want to screw up any open profiles!) 00212 mEnableStateChangePending = true; 00213 mNewEnableState = enabled; 00214 } 00215 00216 } 00217 //----------------------------------------------------------------------- 00218 bool Profiler::getEnabled() const { 00219 00220 return mEnabled; 00221 00222 } 00223 //----------------------------------------------------------------------- 00224 void Profiler::disableProfile(const String& profileName) { 00225 00226 // make sure the profile isn't already disabled 00227 DisabledProfileMap::iterator iter; 00228 iter = mDisabledProfiles.find(profileName); 00229 00230 // make sure you don't disable a profile in the middle of that profile 00231 ProfileStack::iterator pIter; 00232 for (pIter = mProfiles.begin(); pIter != mProfiles.end(); ++pIter) { 00233 00234 if (profileName == (*pIter).name) 00235 break; 00236 00237 } 00238 00239 // if those two conditions are met, disable the profile 00240 if ( (iter == mDisabledProfiles.end()) && (pIter == mProfiles.end()) ) { 00241 00242 mDisabledProfiles.insert(std::pair<String, bool>(profileName, true)); 00243 00244 } 00245 00246 } 00247 //----------------------------------------------------------------------- 00248 void Profiler::enableProfile(const String& profileName) { 00249 00250 // make sure the profile is actually disabled 00251 DisabledProfileMap::iterator iter; 00252 iter = mDisabledProfiles.find(profileName); 00253 00254 // make sure you don't enable a profile in the middle of that profile 00255 ProfileStack::iterator pIter; 00256 for (pIter = mProfiles.begin(); pIter != mProfiles.end(); ++pIter) { 00257 00258 if (profileName == (*pIter).name) 00259 break; 00260 00261 } 00262 00263 // if those two conditions are met, enable the profile by removing it from 00264 // the disabled list 00265 if ( (iter != mDisabledProfiles.end()) && (pIter == mProfiles.end()) ) { 00266 00267 mDisabledProfiles.erase(iter); 00268 00269 } 00270 00271 } 00272 //----------------------------------------------------------------------- 00273 void Profiler::beginProfile(const String& profileName) { 00274 00275 // if the profiler is enabled 00276 if (!mEnabled) { 00277 00278 return; 00279 00280 } 00281 00282 // empty string is reserved for the root 00283 assert ((profileName != "") && ("Profile name can't be an empty string")); 00284 00285 ProfileStack::iterator iter; 00286 for (iter = mProfiles.begin(); iter != mProfiles.end(); ++iter) { 00287 00288 if ((*iter).name == profileName) { 00289 00290 break; 00291 00292 } 00293 00294 } 00295 00296 // make sure this profile isn't being used more than once 00297 assert ((iter == mProfiles.end()) && ("This profile name is already being used")); 00298 00299 // we only process this profile if isn't disabled 00300 DisabledProfileMap::iterator dIter; 00301 dIter = mDisabledProfiles.find(profileName); 00302 if ( dIter != mDisabledProfiles.end() ) { 00303 00304 return; 00305 00306 } 00307 00308 ProfileInstance p; 00309 00310 // this is the root, it has no parent 00311 if (mProfiles.empty()) { 00312 00313 p.parent = ""; 00314 00315 } 00316 // otherwise peek at the stack and use the top as the parent 00317 else { 00318 00319 ProfileInstance parent = mProfiles.back(); 00320 p.parent = parent.name; 00321 00322 } 00323 00324 // need a timer to profile! 00325 assert (mTimer && "Timer not set!"); 00326 00327 ProfileFrameList::iterator fIter; 00328 ProfileHistoryList::iterator hIter; 00329 00330 // we check to see if this profile has been called in the frame before 00331 for (fIter = mProfileFrame.begin(); fIter != mProfileFrame.end(); ++fIter) { 00332 00333 if ((*fIter).name == profileName) 00334 break; 00335 00336 } 00337 // if it hasn't been called before, set its position in the stack 00338 if (fIter == mProfileFrame.end()) { 00339 00340 ProfileFrame f; 00341 f.name = profileName; 00342 f.frameTime = 0; 00343 f.calls = 0; 00344 f.hierarchicalLvl = (uint) mProfiles.size(); 00345 mProfileFrame.push_back(f); 00346 00347 } 00348 00349 // we check to see if this profile has been called in the app before 00350 ProfileHistoryMap::iterator histMapIter; 00351 histMapIter = mProfileHistoryMap.find(profileName); 00352 00353 // if not we add a profile with just the name into the history 00354 if (histMapIter == mProfileHistoryMap.end()) { 00355 00356 ProfileHistory h; 00357 h.name = profileName; 00358 h.numCallsThisFrame = 0; 00359 h.totalTime = 0; 00360 h.totalCalls = 0; 00361 h.maxTime = 0; 00362 h.minTime = 1; 00363 h.hierarchicalLvl = p.hierarchicalLvl; 00364 h.currentTime = 0; 00365 00366 // we add this to the history 00367 hIter = mProfileHistory.insert(mProfileHistory.end(), h); 00368 00369 // for quick look-ups, we'll add it to the history map as well 00370 mProfileHistoryMap.insert(std::pair<String, ProfileHistoryList::iterator>(profileName, hIter)); 00371 00372 } 00373 00374 // add the stats to this profile and push it on the stack 00375 // we do this at the very end of the function to get the most 00376 // accurate timing results 00377 p.name = profileName; 00378 p.currTime = mTimer->getMicroseconds(); 00379 p.accum = 0; 00380 p.hierarchicalLvl = (uint) mProfiles.size(); 00381 mProfiles.push_back(p); 00382 00383 } 00384 //----------------------------------------------------------------------- 00385 void Profiler::endProfile(const String& profileName) { 00386 00387 // if the profiler is enabled 00388 if(!mEnabled) { 00389 00390 return; 00391 00392 } 00393 00394 // need a timer to profile! 00395 assert (mTimer && "Timer not set!"); 00396 00397 // get the end time of this profile 00398 // we do this as close the beginning of this function as possible 00399 // to get more accurate timing results 00400 ulong endTime = mTimer->getMicroseconds(); 00401 00402 // empty string is reserved for designating an empty parent 00403 assert ((profileName != "") && ("Profile name can't be an empty string")); 00404 00405 // we only process this profile if isn't disabled 00406 DisabledProfileMap::iterator dIter; 00407 dIter = mDisabledProfiles.find(profileName); 00408 if ( dIter != mDisabledProfiles.end() ) { 00409 00410 return; 00411 00412 } 00413 00414 // stack shouldnt be empty 00415 assert (!mProfiles.empty()); 00416 00417 // get the start of this profile 00418 ProfileInstance bProfile; 00419 bProfile = mProfiles.back(); 00420 mProfiles.pop_back(); 00421 00422 // calculate the elapsed time of this profile 00423 ulong timeElapsed = endTime - bProfile.currTime; 00424 00425 // update parent's accumalator if it isn't the root 00426 if (bProfile.parent != "") { 00427 00428 // find the parent 00429 ProfileStack::iterator iter; 00430 for(iter = mProfiles.begin(); iter != mProfiles.end(); ++iter) { 00431 00432 if ((*iter).name == bProfile.parent) 00433 break; 00434 00435 } 00436 00437 // the parent should be found 00438 assert(iter != mProfiles.end()); 00439 00440 // add this profile's time to the parent's accumlator 00441 (*iter).accum += timeElapsed; 00442 00443 } 00444 00445 // we find the profile in this frame 00446 ProfileFrameList::iterator iter; 00447 for (iter = mProfileFrame.begin(); iter != mProfileFrame.end(); ++iter) { 00448 00449 if ((*iter).name == bProfile.name) 00450 break; 00451 00452 } 00453 00454 // we subtract the time the children profiles took from this profile 00455 (*iter).frameTime += timeElapsed - bProfile.accum; 00456 (*iter).calls++; 00457 00458 // the stack is empty and all the profiles have been completed 00459 // we have reached the end of the frame so process the frame statistics 00460 if (mProfiles.empty()) { 00461 00462 // we know that the time elapsed of the main loop is the total time the frame took 00463 mTotalFrameTime = timeElapsed; 00464 00465 // we got all the information we need, so process the profiles 00466 // for this frame 00467 processFrameStats(); 00468 00469 // clear the frame stats for next frame 00470 mProfileFrame.clear(); 00471 00472 // we display everything to the screen 00473 displayResults(); 00474 00475 // if the profiler received a request to be enabled or disabled 00476 // we reached the end of the frame so we can safely do this 00477 if (mEnableStateChangePending) { 00478 00479 changeEnableState(); 00480 00481 } 00482 00483 } 00484 00485 } 00486 //----------------------------------------------------------------------- 00487 void Profiler::processFrameStats() { 00488 00489 ProfileFrameList::iterator frameIter; 00490 ProfileHistoryList::iterator historyIter; 00491 00492 // we set the number of times each profile was called per frame to 0 00493 // because not all profiles are called every frame 00494 for (historyIter = mProfileHistory.begin(); historyIter != mProfileHistory.end(); ++historyIter) { 00495 00496 (*historyIter).numCallsThisFrame = 0; 00497 00498 } 00499 00500 // iterate through each of the profiles processed during this frame 00501 for (frameIter = mProfileFrame.begin(); frameIter != mProfileFrame.end(); ++frameIter) { 00502 00503 String s = (*frameIter).name; 00504 00505 // use our map to find the appropriate profile in the history 00506 historyIter = (*mProfileHistoryMap.find(s)).second; 00507 00508 // extract the frame stats 00509 ulong frameTime = (*frameIter).frameTime; 00510 uint calls = (*frameIter).calls; 00511 uint lvl = (*frameIter).hierarchicalLvl; 00512 00513 // calculate what percentage of frame time this profile took 00514 Real framePercentage = (Real) frameTime / (Real) mTotalFrameTime; 00515 00516 // update the profile stats 00517 (*historyIter).currentTime = framePercentage; 00518 (*historyIter).totalTime += framePercentage; 00519 (*historyIter).totalCalls++; 00520 (*historyIter).numCallsThisFrame = calls; 00521 (*historyIter).hierarchicalLvl = lvl; 00522 00523 // if we find a new minimum for this profile, update it 00524 if ((framePercentage) < ((*historyIter).minTime)) { 00525 00526 (*historyIter).minTime = framePercentage; 00527 00528 } 00529 00530 // if we find a new maximum for this profile, update it 00531 if ((framePercentage) > ((*historyIter).maxTime)) { 00532 00533 (*historyIter).maxTime = framePercentage; 00534 00535 } 00536 00537 } 00538 00539 } 00540 //----------------------------------------------------------------------- 00541 void Profiler::displayResults() { 00542 00543 if (!mEnabled) { 00544 00545 return; 00546 00547 } 00548 00549 // if its time to update the display 00550 if (mCurrentFrame >= mUpdateDisplayFrequency) { 00551 00552 mCurrentFrame = 0; 00553 00554 ProfileHistoryList::iterator iter; 00555 ProfileBarList::iterator bIter; 00556 00557 GuiElement* g; 00558 00559 Real newGuiHeight = mGuiHeight; 00560 00561 int temp = 0; // dummy variable for weird Ogre issue 00562 00563 // go through each profile and display it 00564 for (iter = mProfileHistory.begin(), bIter = mProfileBars.begin(); 00565 iter != mProfileHistory.end() && bIter != mProfileBars.end(); 00566 ++iter, ++bIter) 00567 { 00568 00569 // display the profile's name and the number of times it was called in a frame 00570 g = *bIter; 00571 g->show(); 00572 g->setCaption((*iter).name + " (" + StringConverter::toString((*iter).numCallsThisFrame) + ")"); 00573 g->setLeft(10 + (*iter).hierarchicalLvl * 15); 00574 00575 // display the main bar that show the percentage of the frame time that this 00576 // profile has taken 00577 bIter++; 00578 g = *bIter; 00579 g->show(); 00580 // most of this junk has been set before, but we do this to get around a weird 00581 // Ogre gui issue (bug?) 00582 g->setMetricsMode(GMM_PIXELS); 00583 g->setHeight(mBarHeight); 00584 g->setWidth(((*iter).currentTime) * mGuiWidth); 00585 g->setLeft(mGuiWidth); 00586 g->setTop(mGuiBorderWidth + temp * mBarHeight * 2); 00587 00588 // display line to indicate the minimum frame time for this profile 00589 bIter++; 00590 g = *bIter; 00591 g->show(); 00592 g->setLeft(mBarIndent + (*iter).minTime * mGuiWidth); 00593 00594 // display line to indicate the maximum frame time for this profile 00595 bIter++; 00596 g = *bIter; 00597 g->show(); 00598 g->setLeft(mBarIndent + (*iter).maxTime * mGuiWidth); 00599 00600 // display line to indicate the average frame time for this profile 00601 bIter++; 00602 g = *bIter; 00603 g->show(); 00604 if ((*iter).totalCalls != 0) 00605 g->setLeft(mBarIndent + ((*iter).totalTime / (*iter).totalCalls) * mGuiWidth); 00606 else 00607 g->setLeft(mBarIndent); 00608 // we set the height of the display with respect to the number of profiles displayed 00609 newGuiHeight += mBarHeight * 2; 00610 00611 temp++; 00612 00613 } 00614 00615 // set the main display dimensions 00616 mProfileGui->setMetricsMode(GMM_PIXELS); 00617 mProfileGui->setHeight(newGuiHeight); 00618 mProfileGui->setWidth(mGuiWidth * 2 + 15); 00619 mProfileGui->setTop(5); 00620 mProfileGui->setLeft(5); 00621 00622 // we hide all the remaining pre-created bars 00623 for (; bIter != mProfileBars.end(); ++bIter) { 00624 00625 (*bIter)->hide(); 00626 00627 } 00628 00629 } 00630 00631 // not time to update the display yet 00632 else { 00633 00634 mCurrentFrame++; 00635 00636 } 00637 00638 } 00639 //----------------------------------------------------------------------- 00640 bool Profiler::watchForMax(const String& profileName) { 00641 00642 ProfileHistoryMap::iterator mapIter; 00643 ProfileHistoryList::iterator iter; 00644 00645 mapIter = mProfileHistoryMap.find(profileName); 00646 00647 // if we don't find the profile, return false 00648 if (mapIter == mProfileHistoryMap.end()) 00649 return false; 00650 00651 iter = (*mapIter).second; 00652 00653 return ((*iter).currentTime == (*iter).maxTime); 00654 00655 } 00656 //----------------------------------------------------------------------- 00657 bool Profiler::watchForMin(const String& profileName) { 00658 00659 ProfileHistoryMap::iterator mapIter; 00660 ProfileHistoryList::iterator iter; 00661 00662 mapIter = mProfileHistoryMap.find(profileName); 00663 00664 // if we don't find the profile, return false 00665 if (mapIter == mProfileHistoryMap.end()) 00666 return false; 00667 00668 iter = (*mapIter).second; 00669 00670 return ((*iter).currentTime == (*iter).minTime); 00671 00672 } 00673 //----------------------------------------------------------------------- 00674 bool Profiler::watchForLimit(const String& profileName, Real limit, bool greaterThan) { 00675 00676 ProfileHistoryMap::iterator mapIter; 00677 ProfileHistoryList::iterator iter; 00678 00679 mapIter = mProfileHistoryMap.find(profileName); 00680 00681 // if we don't find the profile, return false 00682 if (mapIter == mProfileHistoryMap.end()) 00683 return false; 00684 00685 iter = (*mapIter).second; 00686 00687 if (greaterThan) 00688 return ((*iter).currentTime > limit); 00689 else 00690 return ((*iter).currentTime < limit); 00691 00692 } 00693 //----------------------------------------------------------------------- 00694 void Profiler::logResults() { 00695 00696 ProfileHistoryList::iterator iter; 00697 00698 LogManager::getSingleton().logMessage("----------------------Profiler Results----------------------"); 00699 00700 for (iter = mProfileHistory.begin(); iter != mProfileHistory.end(); ++iter) { 00701 00702 // create an indent that represents the hierarchical order of the profile 00703 String indent = ""; 00704 for (uint i = 0; i < (*iter).hierarchicalLvl; ++i) { 00705 00706 indent = indent + " "; 00707 00708 } 00709 00710 LogManager::getSingleton().logMessage(indent + "Name " + (*iter).name + " | Min " + StringConverter::toString((*iter).minTime) + " | Max " + StringConverter::toString((*iter).maxTime) + " | Avg "+ StringConverter::toString((*iter).totalTime / (*iter).totalCalls)); 00711 00712 } 00713 00714 LogManager::getSingleton().logMessage("------------------------------------------------------------"); 00715 00716 } 00717 //----------------------------------------------------------------------- 00718 void Profiler::reset() { 00719 00720 ProfileHistoryList::iterator iter; 00721 for (iter = mProfileHistory.begin(); iter != mProfileHistory.end(); ++iter) { 00722 00723 (*iter).currentTime = (*iter).maxTime = (*iter).totalTime = 0; 00724 (*iter).numCallsThisFrame = (*iter).totalCalls = 0; 00725 00726 (*iter).minTime = 1; 00727 00728 } 00729 00730 } 00731 //----------------------------------------------------------------------- 00732 void Profiler::setUpdateDisplayFrequency(uint freq) { 00733 00734 mUpdateDisplayFrequency = freq; 00735 00736 } 00737 //----------------------------------------------------------------------- 00738 uint Profiler::getUpdateDisplayFrequency() const { 00739 00740 return mUpdateDisplayFrequency; 00741 00742 } 00743 //----------------------------------------------------------------------- 00744 void Profiler::changeEnableState() { 00745 00746 if (mNewEnableState) { 00747 00748 mOverlay->show(); 00749 00750 } 00751 else { 00752 00753 mOverlay->hide(); 00754 00755 } 00756 mEnabled = mNewEnableState; 00757 mEnableStateChangePending = false; 00758 00759 } 00760 //----------------------------------------------------------------------- 00761 GuiContainer* Profiler::createContainer() { 00762 00763 GuiContainer* container = (GuiContainer*) GuiManager::getSingleton().createGuiElement("BorderPanel", "profiler"); 00764 container->setMetricsMode(GMM_PIXELS); 00765 container->setMaterialName("Core/StatsBlockCenter"); 00766 container->setHeight(mGuiHeight); 00767 container->setWidth(mGuiWidth * 2 + 15); 00768 container->setParameter("border_size", "1 1 1 1"); 00769 container->setParameter("border_material", "Core/StatsBlockBorder"); 00770 container->setParameter("border_topleft_uv", "0.0000 1.0000 0.0039 0.9961"); 00771 container->setParameter("border_top_uv", "0.0039 1.0000 0.9961 0.9961"); 00772 container->setParameter("border_topright_uv", "0.9961 1.0000 1.0000 0.9961"); 00773 container->setParameter("border_left_uv","0.0000 0.9961 0.0039 0.0039"); 00774 container->setParameter("border_right_uv","0.9961 0.9961 1.0000 0.0039"); 00775 container->setParameter("border_bottomleft_uv","0.0000 0.0039 0.0039 0.0000"); 00776 container->setParameter("border_bottom_uv","0.0039 0.0039 0.9961 0.0000"); 00777 container->setParameter("border_bottomright_uv","0.9961 0.0039 1.0000 0.0000"); 00778 container->setLeft(5); 00779 container->setTop(5); 00780 00781 return container; 00782 00783 } 00784 //----------------------------------------------------------------------- 00785 GuiElement* Profiler::createTextArea(const String& name, Real width, Real height, Real top, Real left, 00786 uint fontSize, const String& caption, bool show) { 00787 00788 00789 GuiElement* textArea = GuiManager::getSingleton().createGuiElement("TextArea", name); 00790 textArea->setMetricsMode(GMM_PIXELS); 00791 textArea->setWidth(width); 00792 textArea->setHeight(height); 00793 textArea->setTop(top); 00794 textArea->setLeft(left); 00795 textArea->setParameter("font_name", "TrebuchetMSBold"); 00796 textArea->setParameter("char_height", StringConverter::toString(fontSize)); 00797 textArea->setCaption(caption); 00798 textArea->setParameter("colour_top", "1 1 1"); 00799 textArea->setParameter("colour_bottom", "1 1 1"); 00800 00801 if (show) { 00802 textArea->show(); 00803 } 00804 else { 00805 textArea->hide(); 00806 } 00807 00808 return textArea; 00809 00810 } 00811 //----------------------------------------------------------------------- 00812 GuiElement* Profiler::createPanel(const String& name, Real width, Real height, Real top, Real left, 00813 const String& materialName, bool show) { 00814 00815 GuiElement* panel = GuiManager::getSingleton().createGuiElement("Panel", name); 00816 panel->setMetricsMode(GMM_PIXELS); 00817 panel->setWidth(width); 00818 panel->setHeight(height); 00819 panel->setTop(top); 00820 panel->setLeft(left); 00821 panel->setMaterialName(materialName); 00822 00823 if (show) { 00824 panel->show(); 00825 } 00826 else { 00827 panel->hide(); 00828 } 00829 00830 return panel; 00831 00832 } 00833 //----------------------------------------------------------------------- 00834 Profiler& Profiler::getSingleton() { 00835 return Singleton<Profiler>::getSingleton(); 00836 } 00837 //----------------------------------------------------------------------- 00838 00839 }
Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:22 2004