Show F4 stats in pages

animationblending
elsid 2 months ago
parent 359600db83
commit 9a24e77d3f
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -965,17 +965,17 @@ void OMW::Engine::go()
}
// 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());
mViewer->addEventHandler(resourceshandler);
osg::ref_ptr<Resource::StatsHandler> resourcesHandler = new Resource::StatsHandler(stats.is_open(), *mVFS);
mViewer->addEventHandler(resourcesHandler);
if (stats.is_open())
Resource::CollectStatistics(mViewer);
Resource::collectStatistics(*mViewer);
// Start the game
if (!mSaveGameFile.empty())

@ -2,7 +2,11 @@
#include <algorithm>
#include <iomanip>
#include <span>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <osg/PolygonMode>
@ -18,143 +22,207 @@
namespace Resource
{
static bool collectStatRendering = false;
static bool collectStatCameraObjects = false;
static bool collectStatViewerObjects = false;
static bool collectStatResource = false;
static bool collectStatGPU = false;
static bool collectStatEvent = false;
static bool collectStatFrameRate = false;
static bool collectStatUpdate = false;
static bool collectStatEngine = false;
static const VFS::Path::Normalized sFontName("Fonts/DejaVuLGCSansMono.ttf");
static void setupStatCollection()
namespace
{
const char* envList = getenv("OPENMW_OSG_STATS_LIST");
if (envList == nullptr)
return;
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");
bool collectStatRendering = false;
bool collectStatCameraObjects = false;
bool collectStatViewerObjects = false;
bool collectStatResource = false;
bool collectStatGPU = false;
bool collectStatEvent = false;
bool collectStatFrameRate = false;
bool collectStatUpdate = false;
bool collectStatEngine = false;
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",
};
void setupStatCollection()
{
const char* envList = getenv("OPENMW_OSG_STATS_LIST");
if (envList == nullptr)
return;
std::string_view kwList(envList);
std::string_view kwList(envList);
auto kwBegin = kwList.begin();
auto kwBegin = kwList.begin();
while (kwBegin != kwList.end())
{
auto kwEnd = std::find(kwBegin, kwList.end(), ';');
const auto kw = kwList.substr(std::distance(kwList.begin(), kwBegin), std::distance(kwBegin, kwEnd));
if (kw == "gpu")
collectStatGPU = true;
else if (kw == "event")
collectStatEvent = true;
else if (kw == "frame_rate")
collectStatFrameRate = true;
else if (kw == "update")
collectStatUpdate = true;
else if (kw == "engine")
collectStatEngine = true;
else if (kw == "rendering")
collectStatRendering = true;
else if (kw == "cameraobjects")
collectStatCameraObjects = true;
else if (kw == "viewerobjects")
collectStatViewerObjects = true;
else if (kw == "resource")
collectStatResource = true;
else if (kw == "times")
while (kwBegin != kwList.end())
{
collectStatGPU = true;
collectStatEvent = true;
collectStatFrameRate = true;
collectStatUpdate = true;
collectStatEngine = true;
collectStatRendering = true;
}
auto kwEnd = std::find(kwBegin, kwList.end(), ';');
const auto kw = kwList.substr(std::distance(kwList.begin(), kwBegin), std::distance(kwBegin, kwEnd));
if (kw == "gpu")
collectStatGPU = true;
else if (kw == "event")
collectStatEvent = true;
else if (kw == "frame_rate")
collectStatFrameRate = true;
else if (kw == "update")
collectStatUpdate = true;
else if (kw == "engine")
collectStatEngine = true;
else if (kw == "rendering")
collectStatRendering = true;
else if (kw == "cameraobjects")
collectStatCameraObjects = true;
else if (kw == "viewerobjects")
collectStatViewerObjects = true;
else if (kw == "resource")
collectStatResource = true;
else if (kw == "times")
{
collectStatGPU = true;
collectStatEvent = true;
collectStatFrameRate = true;
collectStatUpdate = true;
collectStatEngine = true;
collectStatRendering = true;
}
if (kwEnd == kwList.end())
break;
if (kwEnd == kwList.end())
break;
kwBegin = std::next(kwEnd);
kwBegin = std::next(kwEnd);
}
}
}
class SetFontVisitor : public osg::NodeVisitor
{
public:
SetFontVisitor(osgText::Font* font)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mFont(font)
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;
}
void apply(osg::Drawable& node) override
osg::ref_ptr<osgText::Font> getMonoFont(const VFS::Manager& vfs)
{
if (osgText::Text* text = dynamic_cast<osgText::Text*>(&node))
if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs.exists(fontName))
{
text->setFont(mFont);
const Files::IStreamPtr streamPtr = vfs.get(fontName);
return osgText::readRefFontStream(*streamPtr);
}
}
private:
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;
}
return nullptr;
}
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;
_camera->getOrCreateStateSet()->setGlobalDefaults();
_camera->setRenderer(new osgViewer::Renderer(_camera.get()));
_camera->setProjectionResizePolicy(osg::Camera::FIXED);
class SetFontVisitor : public osg::NodeVisitor
{
public:
SetFontVisitor(osgText::Font* font)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mFont(font)
{
}
_resourceStatsChildNum = 0;
void apply(osg::Drawable& node) override
{
if (osgText::Text* text = dynamic_cast<osgText::Text*>(&node))
{
text->setFont(mFont);
}
}
_textFont = getMonoFont(vfs);
private:
osgText::Font* mFont;
};
}
Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs)
: _offlineCollect(offlineCollect)
, _initFonts(false)
Profiler::Profiler(bool offlineCollect, const VFS::Manager& vfs)
: mOfflineCollect(offlineCollect)
, mTextFont(getMonoFont(vfs))
{
_characterSize = 18;
_characterSize = characterSize;
_font.clear();
_textFont = getMonoFont(vfs);
setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3);
setupStatCollection();
}
void Profiler::setUpFonts()
{
if (_textFont != nullptr)
if (mTextFont != nullptr)
{
SetFontVisitor visitor(_textFont);
SetFontVisitor visitor(mTextFont);
_switch->accept(visitor);
}
_initFonts = true;
mInitFonts = true;
}
bool Profiler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
@ -162,24 +230,44 @@ namespace Resource
osgViewer::ViewerBase* viewer = nullptr;
bool handled = StatsHandler::handle(ea, aa);
if (_initialized && !_initFonts)
if (_initialized && !mInitFonts)
setUpFonts();
auto* view = dynamic_cast<osgViewer::View*>(&aa);
if (view)
viewer = view->getViewerBase();
if (viewer)
if (viewer != nullptr)
{
// Add/remove openmw stats to the osd as necessary
viewer->getViewerStats()->collectStats("engine", _statsType >= StatsHandler::StatsType::VIEWER_STATS);
if (_offlineCollect)
CollectStatistics(viewer);
if (mOfflineCollect)
collectStatistics(*viewer);
}
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)
{
if (ea.getHandled())
@ -189,18 +277,21 @@ namespace Resource
{
case (osgGA::GUIEventAdapter::KEYDOWN):
{
if (ea.getKey() == _key)
if (ea.getKey() == statsHandlerKey)
{
osgViewer::View* myview = dynamic_cast<osgViewer::View*>(&aa);
if (!myview)
osgViewer::View* const view = dynamic_cast<osgViewer::View*>(&aa);
if (view == nullptr)
return false;
osgViewer::ViewerBase* viewer = myview->getViewerBase();
osgViewer::ViewerBase* const viewer = view->getViewerBase();
toggle(viewer);
if (viewer == nullptr)
return false;
if (_offlineCollect)
CollectStatistics(viewer);
toggle(*viewer);
if (mOfflineCollect)
collectStatistics(*viewer);
aa.requestRedraw();
return true;
@ -223,66 +314,69 @@ namespace Resource
if (width <= 0 || height <= 0)
return;
_camera->setViewport(0, 0, width, height);
if (fabs(height * _statsWidth) <= fabs(width * _statsHeight))
mCamera->setViewport(0, 0, width, height);
if (std::abs(height * statsWidth) <= std::abs(width * statsHeight))
{
_camera->setProjectionMatrix(
osg::Matrix::ortho2D(_statsWidth - width * _statsHeight / height, _statsWidth, 0.0, _statsHeight));
mCamera->setProjectionMatrix(
osg::Matrix::ortho2D(statsWidth - width * statsHeight / height, statsWidth, 0.0, statsHeight));
}
else
{
_camera->setProjectionMatrix(
osg::Matrix::ortho2D(0.0, _statsWidth, _statsHeight - height * _statsWidth / width, _statsHeight));
mCamera->setProjectionMatrix(
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);
setUpScene(viewer);
mInitialized = true;
}
_statsType = !_statsType;
if (!_statsType)
if (mPage == mSwitch->getNumChildren())
{
_camera->setNodeMask(0);
_switch->setAllChildrenOff();
mPage = 0;
mCamera->setNodeMask(0);
mSwitch->setAllChildrenOff();
viewer->getViewerStats()->collectStats("resource", false);
viewer.getViewerStats()->collectStats("resource", false);
}
else
{
_camera->setNodeMask(0xffffffff);
_switch->setSingleChildOn(_resourceStatsChildNum);
mCamera->setNodeMask(0xffffffff);
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
osg::GraphicsContext* context = dynamic_cast<osgViewer::GraphicsWindow*>(_camera->getGraphicsContext());
osg::GraphicsContext* context = dynamic_cast<osgViewer::GraphicsWindow*>(mCamera->getGraphicsContext());
if (!context)
{
osgViewer::Viewer::Windows windows;
viewer->getWindows(windows);
viewer.getWindows(windows);
if (!windows.empty())
context = windows.front();
else
{
// No GraphicsWindows were found, so let's try to find a GraphicsContext
context = _camera->getGraphicsContext();
context = mCamera->getGraphicsContext();
if (!context)
{
osgViewer::Viewer::Contexts contexts;
viewer->getContexts(contexts);
viewer.getContexts(contexts);
if (contexts.empty())
return;
@ -292,241 +386,151 @@ 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);
_camera->setViewMatrix(osg::Matrix::identity());
mCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
mCamera->setViewMatrix(osg::Matrix::identity());
setWindowSize(context->getTraits()->width, context->getTraits()->height);
// only clear the depth buffer
_camera->setClearMask(0);
_camera->setAllowEventFocus(false);
_camera->setRenderer(new osgViewer::Renderer(_camera.get()));
mCamera->setClearMask(0);
mCamera->setAllowEventFocus(false);
_initialized = true;
mCamera->setRenderer(new osgViewer::Renderer(mCamera.get()));
}
osg::Geometry* createBackgroundRectangle(
const osg::Vec3& pos, const float width, const float height, osg::Vec4& color)
namespace
{
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
{
public:
ResourceStatsTextDrawCallback(osg::Stats* stats, const std::vector<std::string>& statNames)
: mStats(stats)
, mStatNames(statNames)
class ResourceStatsTextDrawCallback : public osg::Drawable::DrawCallback
{
}
public:
explicit ResourceStatsTextDrawCallback(osg::Stats* stats, std::span<const std::string> statNames)
: mStats(stats)
, mStatNames(statNames)
{
}
void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const override
{
if (!mStats)
return;
void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const override
{
if (mStats == nullptr)
return;
osgText::Text* text = (osgText::Text*)(drawable);
osgText::Text* text = (osgText::Text*)(drawable);
std::ostringstream viewStr;
viewStr.setf(std::ios::left, std::ios::adjustfield);
viewStr.width(14);
// Used fixed formatting, as scientific will switch to "...e+.." notation for
// large numbers of vertices/drawables/etc.
viewStr.setf(std::ios::fixed);
viewStr.precision(0);
std::ostringstream viewStr;
viewStr.setf(std::ios::left, std::ios::adjustfield);
viewStr.width(14);
// Used fixed formatting, as scientific will switch to "...e+.." notation for
// large numbers of vertices/drawables/etc.
viewStr.setf(std::ios::fixed);
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())
{
if (statName.empty())
viewStr << std::endl;
else
for (const std::string& statName : mStatNames)
{
double value = 0.0;
if (mStats->getAttribute(frameNumber, statName, value))
viewStr << std::setw(8) << value << std::endl;
if (statName.empty())
viewStr << std::endl;
else
viewStr << std::setw(8) << "." << std::endl;
{
double value = 0.0;
if (mStats->getAttribute(frameNumber, statName, value))
viewStr << std::setw(8) << value << std::endl;
else
viewStr << std::setw(8) << "." << std::endl;
}
}
}
text->setText(viewStr.str());
text->setText(viewStr.str());
text->drawImplementation(renderInfo);
}
text->drawImplementation(renderInfo);
}
osg::ref_ptr<osg::Stats> mStats;
std::reference_wrapper<const std::vector<std::string>> mStatNames;
};
private:
osg::ref_ptr<osg::Stats> mStats;
std::span<const std::string> mStatNames;
};
}
void StatsHandler::setUpScene(osgViewer::ViewerBase* viewer)
void StatsHandler::setUpScene(osgViewer::ViewerBase& viewer)
{
_switch = new osg::Switch;
_camera->addChild(_switch);
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
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);
const auto longest = std::max_element(allStatNames.begin(), allStatNames.end(),
[](const std::string& lhs, const std::string& rhs) { return lhs.size() < rhs.size(); });
const std::size_t longestSize = longest->size();
const float statNamesWidth = longestSize * characterSize * 0.6 + 2 * backgroundMargin;
const float statTextWidth = 7 * characterSize + 2 * backgroundMargin;
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::Group* group = new osg::Group;
osg::ref_ptr<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 float statNamesWidth = 13 * _characterSize + 2 * backgroundMargin;
const float statTextWidth = 7 * _characterSize + 2 * backgroundMargin;
const float statHeight = statNames.size() * _characterSize + 2 * backgroundMargin;
osg::Vec3 pos(_statsWidth - statNamesWidth - backgroundSpacing - statTextWidth, statHeight, 0.0f);
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(
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, _characterSize + backgroundMargin, 0),
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, backgroundMargin + characterSize, 0),
statNamesWidth, statHeight, backgroundColor));
osg::ref_ptr<osgText::Text> staticText = new osgText::Text;
group->addChild(staticText.get());
staticText->setColor(staticTextColor);
staticText->setCharacterSize(_characterSize);
staticText->setCharacterSize(characterSize);
staticText->setPosition(pos);
std::ostringstream viewStr;
viewStr.clear();
viewStr.setf(std::ios::left, std::ios::adjustfield);
viewStr.width(longest->size());
for (const auto& statName : statNames)
{
viewStr.width(longestSize);
for (const std::string& statName : currentStatNames)
viewStr << statName << std::endl;
}
staticText->setText(viewStr.str());
pos.x() += statNamesWidth + backgroundSpacing;
group->addChild(
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, _characterSize + backgroundMargin, 0),
createBackgroundRectangle(pos + osg::Vec3(-backgroundMargin, backgroundMargin + characterSize, 0),
statTextWidth, statHeight, backgroundColor));
osg::ref_ptr<osgText::Text> statsText = new osgText::Text;
group->addChild(statsText.get());
statsText->setColor(dynamicTextColor);
statsText->setCharacterSize(_characterSize);
statsText->setCharacterSize(characterSize);
statsText->setPosition(pos);
statsText->setText("");
statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer->getViewerStats(), statNames));
statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer.getViewerStats(), currentStatNames));
if (_textFont)
if (mTextFont != nullptr)
{
staticText->setFont(_textFont);
statsText->setFont(_textFont);
staticText->setFont(mTextFont);
statsText->setFont(mTextFont);
}
mSwitch->addChild(group, false);
}
}
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;
viewer->getCameras(cameras);
viewer.getCameras(cameras);
for (auto* camera : cameras)
{
if (collectStatGPU)
@ -537,17 +541,16 @@ namespace Resource
camera->getStats()->collectStats("scene", true);
}
if (collectStatEvent)
viewer->getViewerStats()->collectStats("event", true);
viewer.getViewerStats()->collectStats("event", true);
if (collectStatFrameRate)
viewer->getViewerStats()->collectStats("frame_rate", true);
viewer.getViewerStats()->collectStats("frame_rate", true);
if (collectStatUpdate)
viewer->getViewerStats()->collectStats("update", true);
viewer.getViewerStats()->collectStats("update", true);
if (collectStatResource)
viewer->getViewerStats()->collectStats("resource", true);
viewer.getViewerStats()->collectStats("resource", true);
if (collectStatViewerObjects)
viewer->getViewerStats()->collectStats("scene", true);
viewer.getViewerStats()->collectStats("scene", true);
if (collectStatEngine)
viewer->getViewerStats()->collectStats("engine", true);
viewer.getViewerStats()->collectStats("engine", true);
}
}

@ -28,57 +28,46 @@ namespace Resource
class Profiler : public osgViewer::StatsHandler
{
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;
private:
void setUpFonts();
bool _offlineCollect;
bool _initFonts;
osg::ref_ptr<osgText::Font> _textFont;
bool mInitFonts = false;
bool mOfflineCollect;
osg::ref_ptr<osgText::Font> mTextFont;
};
class StatsHandler : public osgGA::GUIEventHandler
{
public:
StatsHandler(bool offlineCollect, VFS::Manager* vfs);
void setKey(int key) { _key = key; }
int getKey() const { return _key; }
explicit StatsHandler(bool offlineCollect, const VFS::Manager& vfs);
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.*/
void getUsage(osg::ApplicationUsage& usage) const override;
private:
osg::ref_ptr<osg::Switch> _switch;
int _key;
osg::ref_ptr<osg::Camera> _camera;
bool _initialized;
bool _statsType;
bool _offlineCollect;
unsigned mPage = 0;
bool mInitialized = false;
bool mOfflineCollect;
osg::ref_ptr<osg::Switch> mSwitch;
osg::ref_ptr<osg::Camera> mCamera;
osg::ref_ptr<osgText::Font> mTextFont;
float _statsWidth;
float _statsHeight;
void setWindowSize(int w, int h);
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

Loading…
Cancel
Save