1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-02 04:36:39 +00:00

Show F4 stats in pages

This commit is contained in:
elsid 2024-03-17 19:01:11 +01:00
parent 359600db83
commit 9a24e77d3f
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
3 changed files with 344 additions and 352 deletions

View file

@ -965,17 +965,17 @@ void OMW::Engine::go()
} }
// Setup profiler // Setup profiler
osg::ref_ptr<Resource::Profiler> statshandler = new Resource::Profiler(stats.is_open(), mVFS.get()); osg::ref_ptr<Resource::Profiler> statsHandler = new Resource::Profiler(stats.is_open(), *mVFS);
initStatsHandler(*statshandler); initStatsHandler(*statsHandler);
mViewer->addEventHandler(statshandler); mViewer->addEventHandler(statsHandler);
osg::ref_ptr<Resource::StatsHandler> resourceshandler = new Resource::StatsHandler(stats.is_open(), mVFS.get()); osg::ref_ptr<Resource::StatsHandler> resourcesHandler = new Resource::StatsHandler(stats.is_open(), *mVFS);
mViewer->addEventHandler(resourceshandler); mViewer->addEventHandler(resourcesHandler);
if (stats.is_open()) if (stats.is_open())
Resource::CollectStatistics(mViewer); Resource::collectStatistics(*mViewer);
// Start the game // Start the game
if (!mSaveGameFile.empty()) if (!mSaveGameFile.empty())

View file

@ -2,7 +2,11 @@
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <span>
#include <sstream> #include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <osg/PolygonMode> #include <osg/PolygonMode>
@ -18,20 +22,72 @@
namespace Resource namespace Resource
{ {
namespace
{
constexpr float statsWidth = 1280.0f;
constexpr float statsHeight = 1024.0f;
constexpr float characterSize = 17.0f;
constexpr float backgroundMargin = 5;
constexpr float backgroundSpacing = 3;
constexpr float maxStatsHeight = 420.0f;
constexpr std::size_t pageSize
= static_cast<std::size_t>((maxStatsHeight - 2 * backgroundMargin) / characterSize);
constexpr int statsHandlerKey = osgGA::GUIEventAdapter::KEY_F4;
const VFS::Path::Normalized fontName("Fonts/DejaVuLGCSansMono.ttf");
static bool collectStatRendering = false; bool collectStatRendering = false;
static bool collectStatCameraObjects = false; bool collectStatCameraObjects = false;
static bool collectStatViewerObjects = false; bool collectStatViewerObjects = false;
static bool collectStatResource = false; bool collectStatResource = false;
static bool collectStatGPU = false; bool collectStatGPU = false;
static bool collectStatEvent = false; bool collectStatEvent = false;
static bool collectStatFrameRate = false; bool collectStatFrameRate = false;
static bool collectStatUpdate = false; bool collectStatUpdate = false;
static bool collectStatEngine = false; bool collectStatEngine = false;
static const VFS::Path::Normalized sFontName("Fonts/DejaVuLGCSansMono.ttf"); const std::vector<std::string> allStatNames = {
"FrameNumber",
"Compiling",
"WorkQueue",
"WorkThread",
"UnrefQueue",
"Texture",
"StateSet",
"Node",
"Shape",
"Shape Instance",
"Image",
"Nif",
"Keyframe",
"Groundcover Chunk",
"Object Chunk",
"Terrain Chunk",
"Terrain Texture",
"Land",
"Composite",
"Mechanics Actors",
"Mechanics Objects",
"Physics Actors",
"Physics Objects",
"Physics Projectiles",
"Physics HeightFields",
"Lua UsedMemory",
"NavMesh Jobs",
"NavMesh Waiting",
"NavMesh Pushed",
"NavMesh Processing",
"NavMesh DbJobs Write",
"NavMesh DbJobs Read",
"NavMesh DbCache Get",
"NavMesh DbCache Hit",
"NavMesh CacheSize",
"NavMesh UsedTiles",
"NavMesh CachedTiles",
"NavMesh Cache Get",
"NavMesh Cache Hit",
};
static void setupStatCollection() void setupStatCollection()
{ {
const char* envList = getenv("OPENMW_OSG_STATS_LIST"); const char* envList = getenv("OPENMW_OSG_STATS_LIST");
if (envList == nullptr) if (envList == nullptr)
@ -82,6 +138,49 @@ namespace Resource
} }
} }
osg::ref_ptr<osg::Geometry> createBackgroundRectangle(
const osg::Vec3& pos, const float width, const float height, const osg::Vec4& color)
{
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
geometry->setStateSet(stateSet);
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(pos.x(), pos.y(), 0));
vertices->push_back(osg::Vec3(pos.x(), pos.y() - height, 0));
vertices->push_back(osg::Vec3(pos.x() + width, pos.y() - height, 0));
vertices->push_back(osg::Vec3(pos.x() + width, pos.y(), 0));
geometry->setVertexArray(vertices);
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(color);
geometry->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::ref_ptr<osg::DrawElementsUShort> base
= new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_FAN, 0);
base->push_back(0);
base->push_back(1);
base->push_back(2);
base->push_back(3);
geometry->addPrimitiveSet(base);
return geometry;
}
osg::ref_ptr<osgText::Font> getMonoFont(const VFS::Manager& vfs)
{
if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs.exists(fontName))
{
const Files::IStreamPtr streamPtr = vfs.get(fontName);
return osgText::readRefFontStream(*streamPtr);
}
return nullptr;
}
class SetFontVisitor : public osg::NodeVisitor class SetFontVisitor : public osg::NodeVisitor
{ {
public: public:
@ -102,59 +201,28 @@ namespace Resource
private: private:
osgText::Font* mFont; osgText::Font* mFont;
}; };
osg::ref_ptr<osgText::Font> getMonoFont(VFS::Manager* vfs)
{
if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName))
{
Files::IStreamPtr streamPtr = vfs->get(sFontName);
return osgText::readRefFontStream(*streamPtr.get());
} }
return nullptr; Profiler::Profiler(bool offlineCollect, const VFS::Manager& vfs)
} : mOfflineCollect(offlineCollect)
, mTextFont(getMonoFont(vfs))
StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs)
: _key(osgGA::GUIEventAdapter::KEY_F4)
, _initialized(false)
, _statsType(false)
, _offlineCollect(offlineCollect)
, _statsWidth(1280.0f)
, _statsHeight(1024.0f)
, _characterSize(18.0f)
{ {
_camera = new osg::Camera; _characterSize = characterSize;
_camera->getOrCreateStateSet()->setGlobalDefaults();
_camera->setRenderer(new osgViewer::Renderer(_camera.get()));
_camera->setProjectionResizePolicy(osg::Camera::FIXED);
_resourceStatsChildNum = 0;
_textFont = getMonoFont(vfs);
}
Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs)
: _offlineCollect(offlineCollect)
, _initFonts(false)
{
_characterSize = 18;
_font.clear(); _font.clear();
_textFont = getMonoFont(vfs);
setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3); setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3);
setupStatCollection(); setupStatCollection();
} }
void Profiler::setUpFonts() void Profiler::setUpFonts()
{ {
if (_textFont != nullptr) if (mTextFont != nullptr)
{ {
SetFontVisitor visitor(_textFont); SetFontVisitor visitor(mTextFont);
_switch->accept(visitor); _switch->accept(visitor);
} }
_initFonts = true; mInitFonts = true;
} }
bool Profiler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) bool Profiler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
@ -162,24 +230,44 @@ namespace Resource
osgViewer::ViewerBase* viewer = nullptr; osgViewer::ViewerBase* viewer = nullptr;
bool handled = StatsHandler::handle(ea, aa); bool handled = StatsHandler::handle(ea, aa);
if (_initialized && !_initFonts) if (_initialized && !mInitFonts)
setUpFonts(); setUpFonts();
auto* view = dynamic_cast<osgViewer::View*>(&aa); auto* view = dynamic_cast<osgViewer::View*>(&aa);
if (view) if (view)
viewer = view->getViewerBase(); viewer = view->getViewerBase();
if (viewer) if (viewer != nullptr)
{ {
// Add/remove openmw stats to the osd as necessary // Add/remove openmw stats to the osd as necessary
viewer->getViewerStats()->collectStats("engine", _statsType >= StatsHandler::StatsType::VIEWER_STATS); viewer->getViewerStats()->collectStats("engine", _statsType >= StatsHandler::StatsType::VIEWER_STATS);
if (_offlineCollect) if (mOfflineCollect)
CollectStatistics(viewer); collectStatistics(*viewer);
} }
return handled; return handled;
} }
StatsHandler::StatsHandler(bool offlineCollect, const VFS::Manager& vfs)
: mOfflineCollect(offlineCollect)
, mSwitch(new osg::Switch)
, mCamera(new osg::Camera)
, mTextFont(getMonoFont(vfs))
{
osg::ref_ptr<osg::StateSet> stateset = mSwitch->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
#ifdef OSG_GL1_AVAILABLE
stateset->setAttribute(new osg::PolygonMode(), osg::StateAttribute::PROTECTED);
#endif
mCamera->getOrCreateStateSet()->setGlobalDefaults();
mCamera->setRenderer(new osgViewer::Renderer(mCamera.get()));
mCamera->setProjectionResizePolicy(osg::Camera::FIXED);
mCamera->addChild(mSwitch);
}
bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{ {
if (ea.getHandled()) if (ea.getHandled())
@ -189,18 +277,21 @@ namespace Resource
{ {
case (osgGA::GUIEventAdapter::KEYDOWN): case (osgGA::GUIEventAdapter::KEYDOWN):
{ {
if (ea.getKey() == _key) if (ea.getKey() == statsHandlerKey)
{ {
osgViewer::View* myview = dynamic_cast<osgViewer::View*>(&aa); osgViewer::View* const view = dynamic_cast<osgViewer::View*>(&aa);
if (!myview) if (view == nullptr)
return false; return false;
osgViewer::ViewerBase* viewer = myview->getViewerBase(); osgViewer::ViewerBase* const viewer = view->getViewerBase();
toggle(viewer); if (viewer == nullptr)
return false;
if (_offlineCollect) toggle(*viewer);
CollectStatistics(viewer);
if (mOfflineCollect)
collectStatistics(*viewer);
aa.requestRedraw(); aa.requestRedraw();
return true; return true;
@ -223,66 +314,69 @@ namespace Resource
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
return; return;
_camera->setViewport(0, 0, width, height); mCamera->setViewport(0, 0, width, height);
if (fabs(height * _statsWidth) <= fabs(width * _statsHeight)) if (std::abs(height * statsWidth) <= std::abs(width * statsHeight))
{ {
_camera->setProjectionMatrix( mCamera->setProjectionMatrix(
osg::Matrix::ortho2D(_statsWidth - width * _statsHeight / height, _statsWidth, 0.0, _statsHeight)); osg::Matrix::ortho2D(statsWidth - width * statsHeight / height, statsWidth, 0.0, statsHeight));
} }
else else
{ {
_camera->setProjectionMatrix( mCamera->setProjectionMatrix(
osg::Matrix::ortho2D(0.0, _statsWidth, _statsHeight - height * _statsWidth / width, _statsHeight)); osg::Matrix::ortho2D(0.0, statsWidth, statsHeight - height * statsWidth / width, statsHeight));
} }
} }
void StatsHandler::toggle(osgViewer::ViewerBase* viewer) void StatsHandler::toggle(osgViewer::ViewerBase& viewer)
{ {
if (!_initialized) if (!mInitialized)
{ {
setUpHUDCamera(viewer); setUpHUDCamera(viewer);
setUpScene(viewer); setUpScene(viewer);
mInitialized = true;
} }
_statsType = !_statsType; if (mPage == mSwitch->getNumChildren())
if (!_statsType)
{ {
_camera->setNodeMask(0); mPage = 0;
_switch->setAllChildrenOff();
viewer->getViewerStats()->collectStats("resource", false); mCamera->setNodeMask(0);
mSwitch->setAllChildrenOff();
viewer.getViewerStats()->collectStats("resource", false);
} }
else else
{ {
_camera->setNodeMask(0xffffffff); mCamera->setNodeMask(0xffffffff);
_switch->setSingleChildOn(_resourceStatsChildNum); mSwitch->setSingleChildOn(mPage);
viewer->getViewerStats()->collectStats("resource", true); viewer.getViewerStats()->collectStats("resource", true);
++mPage;
} }
} }
void StatsHandler::setUpHUDCamera(osgViewer::ViewerBase* viewer) void StatsHandler::setUpHUDCamera(osgViewer::ViewerBase& viewer)
{ {
// Try GraphicsWindow first so we're likely to get the main viewer window // Try GraphicsWindow first so we're likely to get the main viewer window
osg::GraphicsContext* context = dynamic_cast<osgViewer::GraphicsWindow*>(_camera->getGraphicsContext()); osg::GraphicsContext* context = dynamic_cast<osgViewer::GraphicsWindow*>(mCamera->getGraphicsContext());
if (!context) if (!context)
{ {
osgViewer::Viewer::Windows windows; osgViewer::Viewer::Windows windows;
viewer->getWindows(windows); viewer.getWindows(windows);
if (!windows.empty()) if (!windows.empty())
context = windows.front(); context = windows.front();
else else
{ {
// No GraphicsWindows were found, so let's try to find a GraphicsContext // No GraphicsWindows were found, so let's try to find a GraphicsContext
context = _camera->getGraphicsContext(); context = mCamera->getGraphicsContext();
if (!context) if (!context)
{ {
osgViewer::Viewer::Contexts contexts; osgViewer::Viewer::Contexts contexts;
viewer->getContexts(contexts); viewer.getContexts(contexts);
if (contexts.empty()) if (contexts.empty())
return; return;
@ -292,60 +386,27 @@ namespace Resource
} }
} }
_camera->setGraphicsContext(context); mCamera->setGraphicsContext(context);
_camera->setRenderOrder(osg::Camera::POST_RENDER, 11); mCamera->setRenderOrder(osg::Camera::POST_RENDER, 11);
_camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); mCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
_camera->setViewMatrix(osg::Matrix::identity()); mCamera->setViewMatrix(osg::Matrix::identity());
setWindowSize(context->getTraits()->width, context->getTraits()->height); setWindowSize(context->getTraits()->width, context->getTraits()->height);
// only clear the depth buffer // only clear the depth buffer
_camera->setClearMask(0); mCamera->setClearMask(0);
_camera->setAllowEventFocus(false); mCamera->setAllowEventFocus(false);
_camera->setRenderer(new osgViewer::Renderer(_camera.get())); mCamera->setRenderer(new osgViewer::Renderer(mCamera.get()));
_initialized = true;
} }
osg::Geometry* createBackgroundRectangle( namespace
const osg::Vec3& pos, const float width, const float height, osg::Vec4& color)
{ {
osg::StateSet* ss = new osg::StateSet;
osg::Geometry* geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setStateSet(ss);
osg::Vec3Array* vertices = new osg::Vec3Array;
geometry->setVertexArray(vertices);
vertices->push_back(osg::Vec3(pos.x(), pos.y(), 0));
vertices->push_back(osg::Vec3(pos.x(), pos.y() - height, 0));
vertices->push_back(osg::Vec3(pos.x() + width, pos.y() - height, 0));
vertices->push_back(osg::Vec3(pos.x() + width, pos.y(), 0));
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(color);
geometry->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::DrawElementsUShort* base = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_FAN, 0);
base->push_back(0);
base->push_back(1);
base->push_back(2);
base->push_back(3);
geometry->addPrimitiveSet(base);
return geometry;
}
class ResourceStatsTextDrawCallback : public osg::Drawable::DrawCallback class ResourceStatsTextDrawCallback : public osg::Drawable::DrawCallback
{ {
public: public:
ResourceStatsTextDrawCallback(osg::Stats* stats, const std::vector<std::string>& statNames) explicit ResourceStatsTextDrawCallback(osg::Stats* stats, std::span<const std::string> statNames)
: mStats(stats) : mStats(stats)
, mStatNames(statNames) , mStatNames(statNames)
{ {
@ -353,7 +414,7 @@ namespace Resource
void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const override void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const override
{ {
if (!mStats) if (mStats == nullptr)
return; return;
osgText::Text* text = (osgText::Text*)(drawable); osgText::Text* text = (osgText::Text*)(drawable);
@ -366,9 +427,9 @@ namespace Resource
viewStr.setf(std::ios::fixed); viewStr.setf(std::ios::fixed);
viewStr.precision(0); viewStr.precision(0);
unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber() - 1; const unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber() - 1;
for (const auto& statName : mStatNames.get()) for (const std::string& statName : mStatNames)
{ {
if (statName.empty()) if (statName.empty())
viewStr << std::endl; viewStr << std::endl;
@ -387,146 +448,89 @@ namespace Resource
text->drawImplementation(renderInfo); text->drawImplementation(renderInfo);
} }
private:
osg::ref_ptr<osg::Stats> mStats; osg::ref_ptr<osg::Stats> mStats;
std::reference_wrapper<const std::vector<std::string>> mStatNames; std::span<const std::string> mStatNames;
}; };
}
void StatsHandler::setUpScene(osgViewer::ViewerBase* viewer) void StatsHandler::setUpScene(osgViewer::ViewerBase& viewer)
{ {
_switch = new osg::Switch; const osg::Vec4 backgroundColor(0.0, 0.0, 0.0f, 0.3);
const osg::Vec4 staticTextColor(1.0, 1.0, 0.0f, 1.0);
const osg::Vec4 dynamicTextColor(1.0, 1.0, 1.0f, 1.0);
_camera->addChild(_switch); const auto longest = std::max_element(allStatNames.begin(), allStatNames.end(),
osg::StateSet* stateset = _switch->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
#ifdef OSG_GL1_AVAILABLE
stateset->setAttribute(new osg::PolygonMode(), osg::StateAttribute::PROTECTED);
#endif
osg::Vec4 backgroundColor(0.0, 0.0, 0.0f, 0.3);
osg::Vec4 staticTextColor(1.0, 1.0, 0.0f, 1.0);
osg::Vec4 dynamicTextColor(1.0, 1.0, 1.0f, 1.0);
float backgroundMargin = 5;
float backgroundSpacing = 3;
// resource stats
{
osg::Group* group = new osg::Group;
group->setCullingActive(false);
_resourceStatsChildNum = _switch->getNumChildren();
_switch->addChild(group, false);
static const std::vector<std::string> statNames({
"FrameNumber",
"",
"Compiling",
"WorkQueue",
"WorkThread",
"UnrefQueue",
"",
"Texture",
"StateSet",
"Node",
"Shape",
"Shape Instance",
"Image",
"Nif",
"Keyframe",
"",
"Groundcover Chunk",
"Object Chunk",
"Terrain Chunk",
"Terrain Texture",
"Land",
"Composite",
"",
"NavMesh Jobs",
"NavMesh Waiting",
"NavMesh Pushed",
"NavMesh Processing",
"NavMesh DbJobs Write",
"NavMesh DbJobs Read",
"NavMesh DbCache Get",
"NavMesh DbCache Hit",
"NavMesh CacheSize",
"NavMesh UsedTiles",
"NavMesh CachedTiles",
"NavMesh Cache Get",
"NavMesh Cache Hit",
"",
"Mechanics Actors",
"Mechanics Objects",
"",
"Physics Actors",
"Physics Objects",
"Physics Projectiles",
"Physics HeightFields",
"",
"Lua UsedMemory",
});
static const auto longest = std::max_element(statNames.begin(), statNames.end(),
[](const std::string& lhs, const std::string& rhs) { return lhs.size() < rhs.size(); }); [](const std::string& lhs, const std::string& rhs) { return lhs.size() < rhs.size(); });
const float statNamesWidth = 13 * _characterSize + 2 * backgroundMargin; const std::size_t longestSize = longest->size();
const float statTextWidth = 7 * _characterSize + 2 * backgroundMargin; const float statNamesWidth = longestSize * characterSize * 0.6 + 2 * backgroundMargin;
const float statHeight = statNames.size() * _characterSize + 2 * backgroundMargin; const float statTextWidth = 7 * characterSize + 2 * backgroundMargin;
osg::Vec3 pos(_statsWidth - statNamesWidth - backgroundSpacing - statTextWidth, statHeight, 0.0f); const float statHeight = pageSize * characterSize + 2 * backgroundMargin;
const float width = statNamesWidth + backgroundSpacing + statTextWidth;
for (std::size_t offset = 0; offset < allStatNames.size(); offset += pageSize)
{
osg::ref_ptr<osg::Group> group = new osg::Group;
group->setCullingActive(false);
const std::size_t count = std::min(allStatNames.size() - offset, pageSize);
std::span<const std::string> currentStatNames(allStatNames.data() + offset, count);
osg::Vec3 pos(statsWidth - width, statHeight - characterSize, 0.0f);
group->addChild( group->addChild(
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, _characterSize + backgroundMargin, 0), createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, backgroundMargin + characterSize, 0),
statNamesWidth, statHeight, backgroundColor)); statNamesWidth, statHeight, backgroundColor));
osg::ref_ptr<osgText::Text> staticText = new osgText::Text; osg::ref_ptr<osgText::Text> staticText = new osgText::Text;
group->addChild(staticText.get()); group->addChild(staticText.get());
staticText->setColor(staticTextColor); staticText->setColor(staticTextColor);
staticText->setCharacterSize(_characterSize); staticText->setCharacterSize(characterSize);
staticText->setPosition(pos); staticText->setPosition(pos);
std::ostringstream viewStr; std::ostringstream viewStr;
viewStr.clear(); viewStr.clear();
viewStr.setf(std::ios::left, std::ios::adjustfield); viewStr.setf(std::ios::left, std::ios::adjustfield);
viewStr.width(longest->size()); viewStr.width(longestSize);
for (const auto& statName : statNames) for (const std::string& statName : currentStatNames)
{
viewStr << statName << std::endl; viewStr << statName << std::endl;
}
staticText->setText(viewStr.str()); staticText->setText(viewStr.str());
pos.x() += statNamesWidth + backgroundSpacing; pos.x() += statNamesWidth + backgroundSpacing;
group->addChild( group->addChild(
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, _characterSize + backgroundMargin, 0), createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, backgroundMargin + characterSize, 0),
statTextWidth, statHeight, backgroundColor)); statTextWidth, statHeight, backgroundColor));
osg::ref_ptr<osgText::Text> statsText = new osgText::Text; osg::ref_ptr<osgText::Text> statsText = new osgText::Text;
group->addChild(statsText.get()); group->addChild(statsText.get());
statsText->setColor(dynamicTextColor); statsText->setColor(dynamicTextColor);
statsText->setCharacterSize(_characterSize); statsText->setCharacterSize(characterSize);
statsText->setPosition(pos); statsText->setPosition(pos);
statsText->setText(""); statsText->setText("");
statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer->getViewerStats(), statNames)); statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer.getViewerStats(), currentStatNames));
if (_textFont) if (mTextFont != nullptr)
{ {
staticText->setFont(_textFont); staticText->setFont(mTextFont);
statsText->setFont(_textFont); statsText->setFont(mTextFont);
} }
mSwitch->addChild(group, false);
} }
} }
void StatsHandler::getUsage(osg::ApplicationUsage& usage) const void StatsHandler::getUsage(osg::ApplicationUsage& usage) const
{ {
usage.addKeyboardMouseBinding(_key, "On screen resource usage stats."); usage.addKeyboardMouseBinding(statsHandlerKey, "On screen resource usage stats.");
} }
void CollectStatistics(osgViewer::ViewerBase* viewer) void collectStatistics(osgViewer::ViewerBase& viewer)
{ {
osgViewer::Viewer::Cameras cameras; osgViewer::Viewer::Cameras cameras;
viewer->getCameras(cameras); viewer.getCameras(cameras);
for (auto* camera : cameras) for (auto* camera : cameras)
{ {
if (collectStatGPU) if (collectStatGPU)
@ -537,17 +541,16 @@ namespace Resource
camera->getStats()->collectStats("scene", true); camera->getStats()->collectStats("scene", true);
} }
if (collectStatEvent) if (collectStatEvent)
viewer->getViewerStats()->collectStats("event", true); viewer.getViewerStats()->collectStats("event", true);
if (collectStatFrameRate) if (collectStatFrameRate)
viewer->getViewerStats()->collectStats("frame_rate", true); viewer.getViewerStats()->collectStats("frame_rate", true);
if (collectStatUpdate) if (collectStatUpdate)
viewer->getViewerStats()->collectStats("update", true); viewer.getViewerStats()->collectStats("update", true);
if (collectStatResource) if (collectStatResource)
viewer->getViewerStats()->collectStats("resource", true); viewer.getViewerStats()->collectStats("resource", true);
if (collectStatViewerObjects) if (collectStatViewerObjects)
viewer->getViewerStats()->collectStats("scene", true); viewer.getViewerStats()->collectStats("scene", true);
if (collectStatEngine) if (collectStatEngine)
viewer->getViewerStats()->collectStats("engine", true); viewer.getViewerStats()->collectStats("engine", true);
} }
} }

View file

@ -28,57 +28,46 @@ namespace Resource
class Profiler : public osgViewer::StatsHandler class Profiler : public osgViewer::StatsHandler
{ {
public: public:
Profiler(bool offlineCollect, VFS::Manager* vfs); explicit Profiler(bool offlineCollect, const VFS::Manager& vfs);
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override; bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override;
private: private:
void setUpFonts(); void setUpFonts();
bool _offlineCollect; bool mInitFonts = false;
bool _initFonts; bool mOfflineCollect;
osg::ref_ptr<osgText::Font> _textFont; osg::ref_ptr<osgText::Font> mTextFont;
}; };
class StatsHandler : public osgGA::GUIEventHandler class StatsHandler : public osgGA::GUIEventHandler
{ {
public: public:
StatsHandler(bool offlineCollect, VFS::Manager* vfs); explicit StatsHandler(bool offlineCollect, const VFS::Manager& vfs);
void setKey(int key) { _key = key; }
int getKey() const { return _key; }
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override; bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override;
void setWindowSize(int w, int h);
void toggle(osgViewer::ViewerBase* viewer);
void setUpHUDCamera(osgViewer::ViewerBase* viewer);
void setUpScene(osgViewer::ViewerBase* viewer);
/** Get the keyboard and mouse usage of this manipulator.*/ /** Get the keyboard and mouse usage of this manipulator.*/
void getUsage(osg::ApplicationUsage& usage) const override; void getUsage(osg::ApplicationUsage& usage) const override;
private: private:
osg::ref_ptr<osg::Switch> _switch; unsigned mPage = 0;
int _key; bool mInitialized = false;
osg::ref_ptr<osg::Camera> _camera; bool mOfflineCollect;
bool _initialized; osg::ref_ptr<osg::Switch> mSwitch;
bool _statsType; osg::ref_ptr<osg::Camera> mCamera;
bool _offlineCollect; osg::ref_ptr<osgText::Font> mTextFont;
float _statsWidth; void setWindowSize(int w, int h);
float _statsHeight;
float _characterSize; void toggle(osgViewer::ViewerBase& viewer);
int _resourceStatsChildNum; void setUpHUDCamera(osgViewer::ViewerBase& viewer);
osg::ref_ptr<osgText::Font> _textFont; void setUpScene(osgViewer::ViewerBase& viewer);
}; };
void CollectStatistics(osgViewer::ViewerBase* viewer); void collectStatistics(osgViewer::ViewerBase& viewer);
} }
#endif #endif