Add a code profiler (stop-watch style).
- breaks MacOSX build for now (files need to be added there). - Interface still needs to be discussed, so maybe wait a few days before using this. - Not yet tested on Windows (will do that tomorrow) - No VS project files yet for the profiling example (will do that tomorrow) git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4791 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
c695a21f33
commit
1fa2ba2b61
|
@ -1,6 +1,7 @@
|
|||
--------------------------
|
||||
Changes in 1.9 (not yet released)
|
||||
|
||||
- Add a code profiler (stop-watch style)
|
||||
- Add override font to IGUITable
|
||||
- IGUITable can now disable the active column.
|
||||
- IGUIElement::getElementFromPoint now virtual
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# Makefile for Irrlicht Examples
|
||||
# It's usually sufficient to change just the target name and source file list
|
||||
# and be sure that CXX is set to a valid compiler
|
||||
|
||||
# Name of the executable created (.exe will be added automatically if necessary)
|
||||
Target := 30.Profiling
|
||||
# List of source files, separated by spaces
|
||||
Sources := main.cpp
|
||||
# Path to Irrlicht directory, should contain include/ and lib/
|
||||
IrrlichtHome := ../..
|
||||
# Path for the executable. Note that Irrlicht.dll should usually also be there for win32 systems
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
# preprocessor flags, e.g. defines and include paths
|
||||
USERCPPFLAGS =
|
||||
# compiler flags such as optimization flags
|
||||
USERCXXFLAGS = -O3 -ffast-math
|
||||
#USERCXXFLAGS = -g -Wall
|
||||
# linker flags such as additional libraries and link paths
|
||||
USERLDFLAGS =
|
||||
|
||||
####
|
||||
#no changes necessary below this line
|
||||
####
|
||||
|
||||
CPPFLAGS = -I$(IrrlichtHome)/include -I/usr/X11R6/include $(USERCPPFLAGS)
|
||||
CXXFLAGS = $(USERCXXFLAGS)
|
||||
LDFLAGS = $(USERLDFLAGS)
|
||||
|
||||
#default target is Linux
|
||||
all: all_linux
|
||||
|
||||
# target specific settings
|
||||
all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
|
||||
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 -lXcursor
|
||||
all_linux clean_linux: SYSTEM=Linux
|
||||
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
|
||||
all_win32 clean_win32 static_win32: SUF=.exe
|
||||
static_win32: CPPFLAGS += -D_IRR_STATIC_LIB_
|
||||
all_win32: LDFLAGS += -lopengl32 -lm
|
||||
static_win32: LDFLAGS += -lgdi32 -lwinspool -lcomdlg32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32
|
||||
# name of the binary - only valid for targets which set SYSTEM
|
||||
DESTPATH = $(BinPath)/$(Target)$(SUF)
|
||||
|
||||
all_linux all_win32 static_win32:
|
||||
$(warning Building...)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS)
|
||||
|
||||
clean: clean_linux clean_win32
|
||||
$(warning Cleaning...)
|
||||
|
||||
clean_linux clean_win32:
|
||||
@$(RM) $(DESTPATH)
|
||||
|
||||
.PHONY: all all_win32 static_win32 clean clean_linux clean_win32
|
||||
|
||||
#multilib handling
|
||||
ifeq ($(HOSTTYPE), x86_64)
|
||||
LIBSELECT=64
|
||||
endif
|
||||
#solaris real-time features
|
||||
ifeq ($(HOSTTYPE), sun4)
|
||||
LDFLAGS += -lrt
|
||||
endif
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="Irrlicht Example 30 Profiling" />
|
||||
<Option pch_mode="0" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Windows">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../../bin/Win32-gcc/Profiling" prefix_auto="0" extension_auto="1" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Option projectResourceIncludeDirsRelation="1" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add directory="../../lib/Win32-gcc" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../../bin/Linux/Profiling" prefix_auto="0" extension_auto="0" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="Xxf86vm" />
|
||||
<Add library="X11" />
|
||||
<Add library="GL" />
|
||||
<Add directory="../../lib/Linux" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<VirtualTargets>
|
||||
<Add alias="All" targets="Windows;Linux;" />
|
||||
</VirtualTargets>
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
<Add directory="../../include" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="Irrlicht" />
|
||||
</Linker>
|
||||
<Unit filename="main.cpp" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<debugger />
|
||||
<envvars />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
|
@ -0,0 +1,456 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
// Written by Michael Zeilfelder
|
||||
|
||||
/** Example 030 Profiling
|
||||
|
||||
Profiling is used to get runtime information about code code.
|
||||
|
||||
There exist several indepent profiling tools.
|
||||
Examples for free profilers are "gprof" for the GNU toolchain and "very sleepy"
|
||||
from codersnotes for Windows. Proprietary tools are for example "VTune" from
|
||||
Intel or "AMD APP Profiler". Those tools work by sampling the running
|
||||
application regularly to get statistic information about the called functions.
|
||||
The way to use them is to compile your application with special flags
|
||||
to include profiling information (some also work with debug information). They
|
||||
also might allow to profile only certain parts of the code, although
|
||||
most can't do that. The sampling is usually rather time-consuming which means
|
||||
the application will be very slow when collecting the profiling data. It's often
|
||||
useful to start with one of those tools to get an overview over the bottlenecks
|
||||
in your application. Those tools have the advantage that they don't need any
|
||||
modifications inside the code.
|
||||
|
||||
Once you need to dig deeper the Irrlicht profiler can help you. It works nearly
|
||||
like a stopwatch. You add start/stop blocks into the parts of your code which
|
||||
you need to check and the Irrlicht profiler will give you then the exact times
|
||||
of execution for those parts. And unlike general profiler tools you don't just
|
||||
get average information about the run-time but also worst-cases. Which tends
|
||||
to be information you really for a stable framerate. Also the Irrlicht profiler
|
||||
has a low overhead and affects only the areas which you want to time. So you
|
||||
can profile applications with nearly original speed.
|
||||
|
||||
Irrlicht itself has such profiling information, which is useful to figure out
|
||||
where the runtime inside the engine is spend. To get that profilng data you
|
||||
need to recompile Irrlicht with _IRR_COMPILE_WITH_PROFILING_ enabled as
|
||||
collecting profiling information is disabled by default for speed reasons.
|
||||
*/
|
||||
|
||||
/*
|
||||
It's usually a good idea to wrap all your profile code with a define.
|
||||
That way you don't have to worry too much about the runtime profiling
|
||||
itself takes. You can remove the profiling code completely when you release
|
||||
the software by removing a single define.Or sometimes you might want to
|
||||
have several such defines for different areas of your application code.
|
||||
*/
|
||||
#define ENABLE_MY_PROFILE // outcomment to remove the profiling code
|
||||
#ifdef ENABLE_MY_PROFILE
|
||||
// calls code X
|
||||
#define MY_PROFILE(X) X
|
||||
#else
|
||||
// removes the code for X in the pre-processor
|
||||
#define MY_PROFILE(X)
|
||||
#endif // IRR_PROFILE
|
||||
|
||||
#include <irrlicht.h>
|
||||
#include "driverChoice.h"
|
||||
|
||||
#ifdef _IRR_WINDOWS_
|
||||
#pragma comment(lib, "Irrlicht.lib")
|
||||
#endif
|
||||
|
||||
|
||||
using namespace irr;
|
||||
using namespace core;
|
||||
using namespace scene;
|
||||
using namespace video;
|
||||
using namespace io;
|
||||
using namespace gui;
|
||||
|
||||
/*
|
||||
We have the choice between working with fixed and with automatic profling id's.
|
||||
Here are some fixed ID's we will be using.
|
||||
*/
|
||||
enum EProfiles
|
||||
{
|
||||
EP_APP_TIME_ONCE,
|
||||
EP_APP_TIME_UPDATED,
|
||||
EP_SCOPE1,
|
||||
EP_SCOPE2,
|
||||
EP_DRAW_SCENE
|
||||
};
|
||||
|
||||
// For our example scenes
|
||||
enum EScenes
|
||||
{
|
||||
ES_NONE, // no scene set
|
||||
ES_CUBE,
|
||||
ES_QUAKE_MAP,
|
||||
ES_DWARVES,
|
||||
|
||||
ES_COUNT // counting how many scenes we have
|
||||
};
|
||||
|
||||
/*
|
||||
Controlling the profiling display is application specific behavior.
|
||||
We use function keys in our case and play around with all the parameters.
|
||||
In real applications you will likely only need something to make the
|
||||
profiling-display visible/invisible and switch pages while the parameters
|
||||
can be set to fixed values.
|
||||
*/
|
||||
class MyEventReceiver : public IEventReceiver
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
MyEventReceiver(ISceneManager * smgr) : GuiProfiler(0), IncludeOverview(true), ActiveScene(ES_NONE), SceneManager(smgr) {}
|
||||
|
||||
virtual bool OnEvent(const SEvent& event)
|
||||
{
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
if ( event.KeyInput.PressedDown )
|
||||
{
|
||||
/*
|
||||
Catching keys to control the profiling display and the profiler itself
|
||||
*/
|
||||
switch ( event.KeyInput.Key )
|
||||
{
|
||||
case KEY_F1:
|
||||
GuiProfiler->setVisible( !GuiProfiler->isVisible() );
|
||||
break;
|
||||
case KEY_F2:
|
||||
GuiProfiler->nextPage(IncludeOverview);
|
||||
break;
|
||||
case KEY_F3:
|
||||
GuiProfiler->previousPage(IncludeOverview);
|
||||
break;
|
||||
case KEY_F4:
|
||||
GuiProfiler->firstPage(IncludeOverview);
|
||||
break;
|
||||
case KEY_F5:
|
||||
IncludeOverview = !IncludeOverview;
|
||||
break;
|
||||
case KEY_F6:
|
||||
GuiProfiler->setIgnoreUncalled( !GuiProfiler->getIgnoreUncalled() );
|
||||
break;
|
||||
case KEY_F8:
|
||||
NextScene();
|
||||
break;
|
||||
case KEY_F9:
|
||||
{
|
||||
u32 index = 0;
|
||||
if ( getProfiler().findGroupIndex(index, L"group a") )
|
||||
{
|
||||
getProfiler().resetGroup(index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_F10:
|
||||
{
|
||||
u32 index = 0;
|
||||
if ( getProfiler().findDataIndex(index, L"scope 3") )
|
||||
{
|
||||
getProfiler().resetDataByIndex(index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEY_F11:
|
||||
getProfiler().resetAll();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Some example scenes so we have something to profile
|
||||
*/
|
||||
void NextScene()
|
||||
{
|
||||
SceneManager->clear();
|
||||
ActiveScene = (ActiveScene+1) % ES_COUNT;
|
||||
if ( ActiveScene == 0 )
|
||||
ActiveScene = ActiveScene+1;
|
||||
|
||||
switch ( ActiveScene )
|
||||
{
|
||||
case ES_CUBE:
|
||||
{
|
||||
/*
|
||||
Simple scene with cube and light.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p(L"cube", L"scenes");)
|
||||
|
||||
SceneManager->addCameraSceneNode (0, core::vector3df(0, 0, 0),
|
||||
core::vector3df(0, 0, 100),
|
||||
-1);
|
||||
|
||||
SceneManager->addCubeSceneNode (30.0f, 0, -1,
|
||||
core::vector3df(0, 20, 100),
|
||||
core::vector3df(45, 45, 45),
|
||||
core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
|
||||
SceneManager->addLightSceneNode(0, core::vector3df(0, 0, 0),
|
||||
video::SColorf(1.0f, 1.0f, 1.0f),
|
||||
100.0f);
|
||||
}
|
||||
break;
|
||||
case ES_QUAKE_MAP:
|
||||
{
|
||||
/*
|
||||
Our typical Irrlicht example quake map.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p(L"quake map", L"scenes");)
|
||||
|
||||
scene::IAnimatedMesh* mesh = SceneManager->getMesh("20kdm2.bsp");
|
||||
scene::ISceneNode* node = 0;
|
||||
|
||||
if (mesh)
|
||||
node = SceneManager->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
|
||||
if (node)
|
||||
node->setPosition(core::vector3df(-1300,-144,-1249));
|
||||
SceneManager->addCameraSceneNodeFPS();
|
||||
}
|
||||
break;
|
||||
case ES_DWARVES:
|
||||
{
|
||||
/*
|
||||
Stress-test Irrlicht a little bit by creating many objects.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p(L"dwarfes", L"scenes");)
|
||||
|
||||
scene::IAnimatedMesh* aniMesh = SceneManager->getMesh( "../../media/dwarf.x" );
|
||||
if (aniMesh)
|
||||
{
|
||||
scene::IMesh * mesh = aniMesh->getMesh (0);
|
||||
if ( !mesh )
|
||||
break;
|
||||
|
||||
/*
|
||||
You can never have too many dwarves. So let's make some.
|
||||
*/
|
||||
const int nodesX = 30;
|
||||
const int nodesY = 5;
|
||||
const int nodesZ = 30;
|
||||
|
||||
aabbox3df bbox = mesh->getBoundingBox();
|
||||
vector3df extent = bbox.getExtent();
|
||||
const f32 GAP = 10.f;
|
||||
f32 halfSizeX = 0.5f * (nodesX*extent.X + GAP*(nodesX-1));
|
||||
f32 halfSizeY = 0.5f * (nodesY*extent.Y + GAP*(nodesY-1));
|
||||
f32 halfSizeZ = 0.5f * (nodesZ*extent.Z + GAP*(nodesZ-1));
|
||||
|
||||
for ( int x = 0; x < nodesX; ++x )
|
||||
{
|
||||
irr::f32 gapX = x > 0 ? (x-1)*GAP : 0.f;
|
||||
irr::f32 posX = -halfSizeX + x*extent.X + gapX;
|
||||
for ( int y = 0; y < nodesY; ++y )
|
||||
{
|
||||
irr::f32 gapY = y > 0 ? (y-1)*GAP : 0.f;
|
||||
irr::f32 posY = -halfSizeY + y*extent.Y + gapY;
|
||||
for ( int z=0; z < nodesZ; ++z )
|
||||
{
|
||||
irr::f32 gapZ = z > 0 ? (z-1)*GAP : 0.f;
|
||||
irr::f32 posZ = -halfSizeZ + z*extent.Z + gapZ;
|
||||
scene::IMeshSceneNode * node = SceneManager->addMeshSceneNode (mesh, NULL, -1, vector3df(posX, posY, posZ) );
|
||||
node->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
irr::scene::ICameraSceneNode * camera = SceneManager->addCameraSceneNodeFPS(0, 20.f, 0.1f );
|
||||
camera->updateAbsolutePosition();
|
||||
camera->setTarget( vector3df(0,0,0) );
|
||||
camera->updateAbsolutePosition();
|
||||
camera->setPosition(irr::core::vector3df(halfSizeX+extent.X, halfSizeY+extent.Y, halfSizeZ+extent.Z));
|
||||
camera->updateAbsolutePosition();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IGUIProfiler * GuiProfiler;
|
||||
bool IncludeOverview;
|
||||
u32 ActiveScene;
|
||||
scene::ISceneManager* SceneManager;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
Setup, nothing special here.
|
||||
*/
|
||||
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
|
||||
if (driverType==video::EDT_COUNT)
|
||||
return 1;
|
||||
|
||||
IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
|
||||
if (device == 0)
|
||||
return 1; // could not create selected driver.
|
||||
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
IGUIEnvironment* env = device->getGUIEnvironment();
|
||||
scene::ISceneManager* smgr = device->getSceneManager();
|
||||
|
||||
/*
|
||||
A map we use for one of our test-scenes.
|
||||
*/
|
||||
device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
|
||||
|
||||
MyEventReceiver receiver(smgr);
|
||||
device->setEventReceiver(&receiver);
|
||||
receiver.NextScene();
|
||||
|
||||
/*
|
||||
Show some info about the controls used in this example
|
||||
*/
|
||||
IGUIStaticText * staticText = env->addStaticText(
|
||||
L"F1 to show/hide the profiling display\n"
|
||||
L"F2 to show the next page\n"
|
||||
L"F3 to show the previous page\n"
|
||||
L"F4 to show the first page\n"
|
||||
L"F5 to flip between including the group overview\n"
|
||||
L"F6 to flip between ignoring and showing uncalled data\n"
|
||||
L"F8 to change our scene\n"
|
||||
L"F9 to reset the \"group a\" data\n"
|
||||
L"F10 to reset the scope 3 data\n"
|
||||
L"F11 to reset all data\n"
|
||||
, recti(10,10, 250, 120), true, true, 0, -1, true);
|
||||
staticText->setWordWrap(false);
|
||||
|
||||
/*
|
||||
IGUIProfiler is can be used to show active profiling data at runtime.
|
||||
*/
|
||||
receiver.GuiProfiler = env->addProfilerDisplay(core::recti(40, 140, 600, 470));
|
||||
|
||||
/*
|
||||
Get a monospaced font - it's nicer when working with rows of numbers.
|
||||
*/
|
||||
IGUIFont* font = env->getFont("../../media/fontcourier.bmp");
|
||||
if (font)
|
||||
receiver.GuiProfiler->setOverrideFont(font);
|
||||
|
||||
|
||||
/*
|
||||
Adding ID's has to be done before the start/stop calls.
|
||||
This allows start/stop to be really fast and we still have nice information like
|
||||
names and groups.
|
||||
Groups are created automatically each time an ID with a new group-name is added.
|
||||
Groups exist to sort the display data in a nicer way.
|
||||
*/
|
||||
MY_PROFILE(
|
||||
getProfiler().add(EP_APP_TIME_ONCE, L"full time", L"group a");
|
||||
getProfiler().add(EP_APP_TIME_UPDATED, L"full time updated", L"group a");
|
||||
getProfiler().add(EP_SCOPE1, L"scope 1", L"group a");
|
||||
getProfiler().add(EP_DRAW_SCENE, L"draw scene", L"group a");
|
||||
)
|
||||
|
||||
/*
|
||||
Two timers which run the whole time. One will be continuosly updated the other won't.
|
||||
*/
|
||||
MY_PROFILE(getProfiler().start(EP_APP_TIME_ONCE);)
|
||||
MY_PROFILE(getProfiler().start(EP_APP_TIME_UPDATED);)
|
||||
|
||||
s32 lastFPS = -1;
|
||||
while(device->run() && driver)
|
||||
{
|
||||
if (device->isWindowActive())
|
||||
{
|
||||
/*
|
||||
For comparison show the FPS in the title bar
|
||||
*/
|
||||
s32 fps = driver->getFPS();
|
||||
if (lastFPS != fps)
|
||||
{
|
||||
core::stringw str = L"FPS: ";
|
||||
str += fps;
|
||||
device->setWindowCaption(str.c_str());
|
||||
lastFPS = fps;
|
||||
}
|
||||
|
||||
/*
|
||||
Times are only updated on stop() calls. So if we want a long-running timer
|
||||
to update we have to stop() and start() it in between.
|
||||
Note that this will also update the call-counter and is rarely needed.
|
||||
*/
|
||||
MY_PROFILE(getProfiler().stop(EP_APP_TIME_UPDATED);)
|
||||
MY_PROFILE(getProfiler().start(EP_APP_TIME_UPDATED);)
|
||||
|
||||
/*
|
||||
The following CProfileScope's will all do the same thing:
|
||||
they measure the time this loop takes. They call start()
|
||||
when the object is created and call stop() when it
|
||||
is destroyed.
|
||||
|
||||
The first one creates an ID on it's first call and will
|
||||
do constant string-comparisons for the name. It's
|
||||
the slowest, but most comfortable solution. Use it when you
|
||||
just need to run a quick check without the hassle of setting
|
||||
up id's.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p3(L"scope 3", L"group a");)
|
||||
|
||||
/*
|
||||
Second CProfileScope solution will create a data block on first
|
||||
call. So it's a little bit slower on the first run. But usually
|
||||
that's hardly noticable.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p2(EP_SCOPE2, L"scope 2", L"group a");)
|
||||
|
||||
/*
|
||||
Last CProfileScope solution is the fastest one. But you must add
|
||||
the id before you can use it like that.
|
||||
*/
|
||||
MY_PROFILE(CProfileScope p1(EP_SCOPE1));
|
||||
|
||||
driver->beginScene(true, true, SColor(0,200,200,200));
|
||||
|
||||
/*
|
||||
If you want to profile only some lines and not a complete scope
|
||||
then you have to work with start() and stop() calls.
|
||||
*/
|
||||
MY_PROFILE(getProfiler().start(EP_DRAW_SCENE);)
|
||||
smgr->drawAll();
|
||||
MY_PROFILE(getProfiler().stop(EP_DRAW_SCENE);)
|
||||
|
||||
/*
|
||||
If it doesn't matter if the profiler takes some time you can also
|
||||
be lazy and create id's automatically on the spot:
|
||||
*/
|
||||
MY_PROFILE(s32 pEnv = getProfiler().add(L"draw env", L"group a");)
|
||||
MY_PROFILE(getProfiler().start(pEnv);)
|
||||
env->drawAll();
|
||||
MY_PROFILE(getProfiler().stop(pEnv);)
|
||||
|
||||
driver->endScene();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Shutdown.
|
||||
*/
|
||||
device->drop();
|
||||
|
||||
/*
|
||||
The profiler is independent of an device - so we can still work with it.
|
||||
*/
|
||||
|
||||
MY_PROFILE(getProfiler().stop(EP_APP_TIME_UPDATED));
|
||||
MY_PROFILE(getProfiler().stop(EP_APP_TIME_ONCE));
|
||||
|
||||
/*
|
||||
Print a complete overview of the profiling data to the console.
|
||||
*/
|
||||
MY_PROFILE(core::stringw output);
|
||||
MY_PROFILE(getProfiler().printAll(output));
|
||||
MY_PROFILE(printf("%s", core::stringc(output).c_str() ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
**/
|
|
@ -2,7 +2,7 @@
|
|||
<CodeBlocks_workspace_file>
|
||||
<Workspace title="Build all examples">
|
||||
<Project filename="../source/Irrlicht/Irrlicht-gcc.cbp" />
|
||||
<Project filename="01.HelloWorld/HelloWorld.cbp" active="1" />
|
||||
<Project filename="01.HelloWorld/HelloWorld.cbp" />
|
||||
<Project filename="02.Quake3Map/Quake3Map.cbp" />
|
||||
<Project filename="03.CustomSceneNode/CustomSceneNode.cbp" />
|
||||
<Project filename="04.Movement/Movement.cbp" />
|
||||
|
@ -27,6 +27,7 @@
|
|||
<Project filename="24.CursorControl/CursorControl.cbp" />
|
||||
<Project filename="25.XmlHandling/XmlHandling.cbp" />
|
||||
<Project filename="26.OcclusionQuery/OcclusionQuery.cbp" />
|
||||
<Project filename="30.Profiling/Profiling.cbp" />
|
||||
<Project filename="Demo/demo.cbp" />
|
||||
<Project filename="../tools/GUIEditor/GUIEditor_gcc.cbp" />
|
||||
<Project filename="../tools/MeshConverter/MeshConverter.cbp" />
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
#ifndef __PROFILER_H_INCLUDED__
|
||||
#define __PROFILER_H_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#include "irrString.h"
|
||||
#include "irrArray.h"
|
||||
#include "ITimer.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
class ITimer;
|
||||
|
||||
//! Used to store the profile data (and also used for profile group data).
|
||||
struct SProfileData
|
||||
{
|
||||
friend class CProfiler;
|
||||
|
||||
SProfileData()
|
||||
{
|
||||
GroupIndex = 0;
|
||||
reset();
|
||||
}
|
||||
|
||||
bool operator<(const SProfileData& pd) const
|
||||
{
|
||||
return Id < pd.Id;
|
||||
}
|
||||
|
||||
bool operator==(const SProfileData& pd) const
|
||||
{
|
||||
return Id == pd.Id;
|
||||
}
|
||||
|
||||
u32 getGroupIndex() const
|
||||
{
|
||||
return GroupIndex;
|
||||
}
|
||||
|
||||
const core::stringw& getName() const
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
//! Each call to Profiler::stop for this data increases the counter by 1.
|
||||
u32 getCallsCounter() const
|
||||
{
|
||||
return CountCalls;
|
||||
}
|
||||
|
||||
//! Longest time any call from start/stop ever took for this id.
|
||||
u32 getLongestTime() const
|
||||
{
|
||||
return LongestTime;
|
||||
}
|
||||
|
||||
//! Time spend between start/stop
|
||||
s32 getTimeSum() const
|
||||
{
|
||||
return TimeSum;
|
||||
}
|
||||
|
||||
//! Convert the whole data into a string
|
||||
core::stringw getAsString() const;
|
||||
|
||||
//! Return a string which describes the columns returned by getAsString
|
||||
static core::stringw makeTitleString();
|
||||
|
||||
private:
|
||||
// just to be used for searching as it does no initialization besides id
|
||||
SProfileData(u32 id) : Id(id) {}
|
||||
|
||||
void reset();
|
||||
|
||||
s32 Id;
|
||||
u32 GroupIndex;
|
||||
core::stringw Name;
|
||||
|
||||
u32 CountCalls;
|
||||
u32 LongestTime;
|
||||
u32 TimeSum;
|
||||
|
||||
u32 LastTimeStarted;
|
||||
};
|
||||
|
||||
//! Code-profiler. Please check the example in the Irrlicht examples folder about how to use it.
|
||||
// Implementer notes:
|
||||
// The design is all about allowing to use the central start/stop mechanism with minimal time overhead.
|
||||
// This is why the class works without a virtual functions interface contrary to the usual Irrlicht design.
|
||||
// And also why it works with id's instead of strings in the start/stop functions even if it makes using
|
||||
// the class slightly harder.
|
||||
// The class comes without reference-counting because the profiler-instance is never released (TBD).
|
||||
// But it's _not_ a singleton (also TBD), life-time is only guaranteed after globals are intialized.
|
||||
class CProfiler
|
||||
{
|
||||
public:
|
||||
//! Constructor. You could use this to create a new profiler, but usually getProfiler() is used to access the global instance.
|
||||
CProfiler();
|
||||
|
||||
~CProfiler();
|
||||
|
||||
//! Add an id with given name and group which can be used for profiling with start/stop
|
||||
/** After calling this once you can start/stop profiling for the given id.
|
||||
\param id: Should be >= 0 as negative id's are reserved for Irrlicht. Also very large numbers (near INT_MAX) might
|
||||
have been added automatically by the other add function.
|
||||
\param name: Name for displaying profile data.
|
||||
\param groupName: Each id belongs into a group - this helps on displaying profile data. */
|
||||
void add(s32 id, const core::stringw &name, const core::stringw &groupName);
|
||||
|
||||
//! Add an automatically generated for the given name and group which can be used for profiling with start/stop.
|
||||
/** After calling this once you can start/stop profiling with the returned id.
|
||||
\param name: Name for displaying profile data.
|
||||
\param groupName: Each id belongs into a group - this helps on displaying profile data.
|
||||
\return Automatic id's start at INT_MAX and count down for each new id. If the name already has an id then that id will be returned. */
|
||||
s32 add(const core::stringw &name, const core::stringw &groupName);
|
||||
|
||||
//! Return the number of profile data blocks. There is one for each id.
|
||||
u32 getProfileDataCount() const
|
||||
{
|
||||
return ProfileDatas.size();
|
||||
}
|
||||
|
||||
//! Search for the index of the profile data by name
|
||||
/** \param result Receives the resulting data index when one was found.
|
||||
\param name String with name to search for
|
||||
\return true when found, false when not found */
|
||||
bool findDataIndex(u32 & result, const core::stringw &name) const;
|
||||
|
||||
//! Get the profile data
|
||||
/** \param index A value between 0 and getProfileDataCount()-1. Indices can change when new id's are added.*/
|
||||
const SProfileData& getProfileDataByIndex(u32 index) const
|
||||
{
|
||||
return ProfileDatas[index];
|
||||
}
|
||||
|
||||
//! Get the profile data
|
||||
/** \param id Same value as used in ::add
|
||||
\return Profile data for the given id or 0 when it does not exist. */
|
||||
const SProfileData* getProfileDataById(u32 id)
|
||||
{
|
||||
SProfileData data(id);
|
||||
s32 idx = ProfileDatas.binary_search(data);
|
||||
if ( idx >= 0 )
|
||||
return &ProfileDatas[idx];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//! Get the number of profile groups. Will be at least 1.
|
||||
/** NOTE: The first groups is always L"overview" which is an overview for all existing groups */
|
||||
u32 getGroupCount() const
|
||||
{
|
||||
return ProfileGroups.size();
|
||||
}
|
||||
|
||||
//! Get profile data for a group.
|
||||
/** NOTE: The first groups is always L"overview" which is an overview for all existing groups */
|
||||
const SProfileData& getGroupData(u32 index) const
|
||||
{
|
||||
return ProfileGroups[index];
|
||||
}
|
||||
|
||||
//! Find the group index by the group-name
|
||||
/** \param result Receives the resulting group index when one was found.
|
||||
\param name String with name to search for
|
||||
\return true when found, false when not found */
|
||||
bool findGroupIndex(u32 & result, const core::stringw &name) const;
|
||||
|
||||
|
||||
//! Start profile-timing for the given id
|
||||
/** NOTE: you have to add the id first with one of the ::add functions */
|
||||
inline void start(s32 id);
|
||||
|
||||
//! Stop profile-timing for the given id
|
||||
/** NOTE: timer must have been started first with the ::start function */
|
||||
inline void stop(s32 id);
|
||||
|
||||
//! Reset profile data for the given id
|
||||
void resetDataById(s32 id);
|
||||
|
||||
//! Reset profile data for the given index
|
||||
void resetDataByIndex(u32 index);
|
||||
|
||||
//! Reset profile data for a whole group
|
||||
void resetGroup(u32 index);
|
||||
|
||||
//! Reset all profile data
|
||||
/** NOTE: This is not deleting id's or groups, just resetting all timers to 0. */
|
||||
void resetAll();
|
||||
|
||||
//! Write all profile-data into a string
|
||||
/** \param result Receives the result string.
|
||||
\param includeOverview When true a group-overview is attached first
|
||||
\param suppressUncalled When true elements which got never called are not printed */
|
||||
void printAll(core::stringw &result, bool includeOverview=false,bool suppressUncalled=true) const;
|
||||
|
||||
//! Write the profile data of one group into a string
|
||||
/** \param result Receives the result string.
|
||||
\param groupIndex_ */
|
||||
void printGroup(core::stringw &result, u32 groupIndex, bool suppressUncalled) const;
|
||||
|
||||
protected:
|
||||
|
||||
u32 addGroup(const core::stringw &name);
|
||||
|
||||
private:
|
||||
ITimer * Timer; // I would prefer using os::Timer, but os.h is not in the public interface so far.
|
||||
s32 NextAutoId; // for giving out id's automatically
|
||||
core::array<SProfileData> ProfileDatas;
|
||||
core::array<SProfileData> ProfileGroups;
|
||||
};
|
||||
|
||||
void CProfiler::start(s32 id)
|
||||
{
|
||||
s32 idx = ProfileDatas.binary_search(SProfileData(id));
|
||||
if ( idx >= 0 && Timer )
|
||||
{
|
||||
ProfileDatas[idx].LastTimeStarted = Timer->getRealTime();
|
||||
}
|
||||
}
|
||||
|
||||
void CProfiler::stop(s32 id)
|
||||
{
|
||||
if ( Timer )
|
||||
{
|
||||
u32 timeNow = Timer->getRealTime();
|
||||
s32 idx = ProfileDatas.binary_search(SProfileData(id));
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
SProfileData &data = ProfileDatas[idx];
|
||||
if ( data.LastTimeStarted != 0 )
|
||||
{
|
||||
// update data for this id
|
||||
++data.CountCalls;
|
||||
u32 diffTime = timeNow - data.LastTimeStarted;
|
||||
data.TimeSum += diffTime;
|
||||
if ( diffTime > data.LongestTime )
|
||||
data.LongestTime = diffTime;
|
||||
data.LastTimeStarted = 0;
|
||||
|
||||
// update data of it's group
|
||||
SProfileData & group = ProfileGroups[data.GroupIndex];
|
||||
++group.CountCalls;
|
||||
group.TimeSum += diffTime;
|
||||
if ( diffTime > group.LongestTime )
|
||||
group.LongestTime = diffTime;
|
||||
group.LastTimeStarted = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Access the Irrlicht profiler object.
|
||||
/** Profiler is always accessible, except in destruction of global objects.
|
||||
If you want to get internal profiling information about the engine itself
|
||||
you will have to re-compile the engine with _IRR_COMPILE_WITH_PROFILING_ enabled.
|
||||
But you can use the profiler for profiling your own projects without that. */
|
||||
IRRLICHT_API CProfiler& IRRCALLCONV getProfiler();
|
||||
|
||||
//! Class where the objects profile their own life-time.
|
||||
/** This is a compfort wrapper around the CProfiler start/stop mechanism which is easier to use
|
||||
when you want to profile a scope. You only have to create an object and it will profile it's own lifetime
|
||||
for the given id. */
|
||||
class CProfileScope
|
||||
{
|
||||
public:
|
||||
//! Construct with an known id.
|
||||
/** This is the fastest scope constructor, but the id must have been added before.
|
||||
\param id Any id which you did add to the profiler before. */
|
||||
CProfileScope(s32 id)
|
||||
: Id(id), Profiler(getProfiler())
|
||||
{
|
||||
Profiler.start(Id);
|
||||
}
|
||||
|
||||
//! Object will create the given name, groupName combination for the id if it doesn't exist already
|
||||
/** \param id: Should be >= 0 as negative id's are reserved for Irrlicht. Also very large numbers (near INT_MAX) might
|
||||
have been created already by the autoamtic add function of ::CProfiler.
|
||||
\param name: Name for displaying profile data.
|
||||
\param groupName: Each id belongs into a group - this helps on displaying profile data. */
|
||||
CProfileScope(s32 id, const core::stringw &name, const core::stringw &groupName)
|
||||
: Id(id), Profiler(getProfiler())
|
||||
{
|
||||
Profiler.add(Id, name, groupName);
|
||||
Profiler.start(Id);
|
||||
}
|
||||
|
||||
//! Object will create an id for the given name, groupName combination if they don't exist already
|
||||
/** Slowest scope constructor, but usually still fine unless speed is very critical.
|
||||
\param name: Name for displaying profile data.
|
||||
\param groupName: Each id belongs into a group - this helps on displaying profile data. */
|
||||
CProfileScope(const core::stringw &name, const core::stringw &groupName)
|
||||
: Profiler(getProfiler())
|
||||
{
|
||||
Id = Profiler.add(name, groupName);
|
||||
Profiler.start(Id);
|
||||
}
|
||||
|
||||
~CProfileScope()
|
||||
{
|
||||
Profiler.stop(Id);
|
||||
}
|
||||
|
||||
protected:
|
||||
s32 Id;
|
||||
CProfiler& Profiler;
|
||||
};
|
||||
} // namespace irr
|
||||
|
||||
//! For internal engine use:
|
||||
//! Code inside IRR_PROFILE is only executed when _IRR_COMPILE_WITH_PROFILING_ is set
|
||||
//! This allows disabling all profiler code completely by changing that define.
|
||||
//! It's generally useful to wrap profiler-calls in application code with a similar macro.
|
||||
#ifdef _IRR_COMPILE_WITH_PROFILING_
|
||||
#define IRR_PROFILE(X) X
|
||||
#else
|
||||
#define IRR_PROFILE(X)
|
||||
#endif // IRR_PROFILE
|
||||
|
||||
#endif // __PROFILER_H_INCLUDED__
|
|
@ -91,6 +91,9 @@ enum EGUI_ELEMENT_TYPE
|
|||
//! The root of the GUI
|
||||
EGUIET_ROOT,
|
||||
|
||||
//! IGUIProfiler
|
||||
EGUIET_PROFILER,
|
||||
|
||||
//! Not an element, amount of elements in there
|
||||
EGUIET_COUNT,
|
||||
|
||||
|
@ -127,6 +130,7 @@ const c8* const GUIElementTypeNames[] =
|
|||
"window",
|
||||
"element",
|
||||
"root",
|
||||
"profiler",
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ class IGUIComboBox;
|
|||
class IGUIToolBar;
|
||||
class IGUIButton;
|
||||
class IGUIWindow;
|
||||
class IGUIProfiler;
|
||||
class IGUIElementFactory;
|
||||
|
||||
//! GUI Environment. Used as factory and manager of all other GUI elements.
|
||||
|
@ -540,6 +541,14 @@ public:
|
|||
virtual IGUITable* addTable(const core::rect<s32>& rectangle,
|
||||
IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) =0;
|
||||
|
||||
//! Adds an element to display the information from the Irrlicht profiler
|
||||
/** \param rectangle Rectangle specifying the borders of the element.
|
||||
\param parent Parent of the element. When 0 the environment itself will
|
||||
be the parent.
|
||||
\param id An identifier for the element. */
|
||||
virtual IGUIProfiler* addProfilerDisplay(const core::rect<s32>& rectangle,
|
||||
IGUIElement* parent=0, s32 id=-1) = 0;
|
||||
|
||||
//! Get the default element factory which can create all built-in elements
|
||||
/** \return Pointer to the factory.
|
||||
This pointer should not be dropped. See IReferenceCounted::drop() for
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef I_GUI_PROFILER_H_INCLUDED__
|
||||
#define I_GUI_PROFILER_H_INCLUDED__
|
||||
|
||||
#include "IGUIElement.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
class IGUIFont;
|
||||
|
||||
//! Element to display profiler information
|
||||
class IGUIProfiler : public IGUIElement
|
||||
{
|
||||
public:
|
||||
//! constructor
|
||||
IGUIProfiler(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
|
||||
: IGUIElement(EGUIET_PROFILER, environment, parent, id, rectangle)
|
||||
{}
|
||||
|
||||
//! Show first page of profile data
|
||||
/** \param includeOverview When true show the group-overview page, when false show the profile data of the first group */
|
||||
virtual void firstPage(bool includeOverview=true) = 0;
|
||||
|
||||
//! Show next page of profile data
|
||||
/** \param includeOverview Include the group-overview page */
|
||||
virtual void nextPage(bool includeOverview=true) = 0;
|
||||
|
||||
//! Show previous page of profile data
|
||||
/** \param includeOverview Include the group-overview page */
|
||||
virtual void previousPage(bool includeOverview=true) = 0;
|
||||
|
||||
//! Don't display stats for data which never got called
|
||||
virtual void setIgnoreUncalled(bool ignore) = 0;
|
||||
|
||||
//! Check if we display stats for data which never got called
|
||||
virtual bool getIgnoreUncalled() const = 0;
|
||||
|
||||
//! Sets another skin independent font.
|
||||
/** If this is set to zero, the button uses the font of the skin.
|
||||
\param font: New font to set. */
|
||||
virtual void setOverrideFont(IGUIFont* font=0) = 0;
|
||||
|
||||
//! Gets the override font (if any)
|
||||
/** \return The override font (may be 0) */
|
||||
virtual IGUIFont* getOverrideFont(void) const = 0;
|
||||
|
||||
//! Get the font which is used right now for drawing
|
||||
/** Currently this is the override font when one is set and the
|
||||
font of the active skin otherwise */
|
||||
virtual IGUIFont* getActiveFont() const = 0;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
|
@ -136,6 +136,15 @@
|
|||
#undef _IRR_COMPILE_WITH_LEAK_HUNTER_
|
||||
#endif
|
||||
|
||||
//! Enable profiling information in the engine
|
||||
/** NOTE: The profiler itself always exists and can be used by applications.
|
||||
This define is about the engine creating profile data
|
||||
while it runs and enabling it will slow down the engine. */
|
||||
//#define _IRR_COMPILE_WITH_PROFILING_
|
||||
#ifdef NO_IRR_COMPILE_WITH_PROFILING_
|
||||
#undef _IRR_COMPILE_WITH_PROFILING_
|
||||
#endif
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_DIRECT3D_8_ and _IRR_COMPILE_WITH_DIRECT3D_9_ to
|
||||
//! compile the Irrlicht engine with Direct3D8 and/or DIRECT3D9.
|
||||
/** If you only want to use the software device or opengl you can disable those defines.
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "CMeshBuffer.h"
|
||||
#include "coreutil.h"
|
||||
#include "CVertexBuffer.h"
|
||||
#include "CProfiler.h"
|
||||
#include "dimension2d.h"
|
||||
#include "ECullingTypes.h"
|
||||
#include "EDebugSceneTypes.h"
|
||||
|
@ -97,6 +98,7 @@
|
|||
#include "IGUIToolbar.h"
|
||||
#include "IGUIWindow.h"
|
||||
#include "IGUITreeView.h"
|
||||
#include "IGUIProfiler.h"
|
||||
#include "IImage.h"
|
||||
#include "IImageLoader.h"
|
||||
#include "IImageWriter.h"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "IGUIToolbar.h"
|
||||
#include "IGUIWindow.h"
|
||||
#include "IGUITreeView.h"
|
||||
#include "IGUIProfiler.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -96,6 +97,8 @@ IGUIElement* CDefaultGUIElementFactory::addGUIElement(EGUI_ELEMENT_TYPE type, IG
|
|||
return Environment->addSpinBox(L"0.0", core::rect<s32>(0,0,100,100), true, parent);
|
||||
case EGUIET_TREE_VIEW:
|
||||
return Environment->addTreeView(core::rect<s32>(0,0,100,100),parent);
|
||||
case EGUIET_PROFILER:
|
||||
return Environment->addProfilerDisplay(core::rect<s32>(0,0,100,100), parent);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "CGUIMenu.h"
|
||||
#include "CGUIToolBar.h"
|
||||
#include "CGUITable.h"
|
||||
#include "CGUIProfiler.h"
|
||||
|
||||
#include "CDefaultGUIElementFactory.h"
|
||||
#include "IWriteFile.h"
|
||||
|
@ -1127,6 +1128,13 @@ IGUITable* CGUIEnvironment::addTable(const core::rect<s32>& rectangle, IGUIEleme
|
|||
return b;
|
||||
}
|
||||
|
||||
//! Adds an element to display the information from the Irrlicht profiler
|
||||
IGUIProfiler* CGUIEnvironment::addProfilerDisplay(const core::rect<s32>& rectangle, IGUIElement* parent, s32 id)
|
||||
{
|
||||
CGUIProfiler* p = new CGUIProfiler(this, parent ? parent : this, id, rectangle);
|
||||
p->drop();
|
||||
return p;
|
||||
}
|
||||
|
||||
//! Adds an image element.
|
||||
IGUIImage* CGUIEnvironment::addImage(video::ITexture* image, core::position2d<s32> pos,
|
||||
|
|
|
@ -183,6 +183,10 @@ public:
|
|||
virtual IGUITable* addTable(const core::rect<s32>& rectangle,
|
||||
IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) _IRR_OVERRIDE_;
|
||||
|
||||
//! Adds an element to display the information from the Irrlicht profiler
|
||||
virtual IGUIProfiler* addProfilerDisplay(const core::rect<s32>& rectangle,
|
||||
IGUIElement* parent=0, s32 id=-1) _IRR_OVERRIDE_;
|
||||
|
||||
//! sets the focus to an element
|
||||
virtual bool setFocus(IGUIElement* element) _IRR_OVERRIDE_;
|
||||
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
// TODO: We should have more pages for groups that don't fit into the display area.
|
||||
// So additional to CurrentGroupIdx we would also have a current-page-for-current-group thing.
|
||||
// The interface doesn't have to be changed for that - just the implementation.
|
||||
|
||||
#include "CGUIProfiler.h"
|
||||
#ifdef _IRR_COMPILE_WITH_GUI_
|
||||
|
||||
#include "IGUITable.h"
|
||||
#include "IGUIEnvironment.h"
|
||||
#include "CProfiler.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
|
||||
//! constructor
|
||||
CGUIProfiler::CGUIProfiler(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
|
||||
: IGUIProfiler(environment, parent, id, rectangle)
|
||||
, DisplayTable(0), CurrentGroupIdx(0), IgnoreUncalled(false)
|
||||
{
|
||||
Profiler = &getProfiler();
|
||||
|
||||
core::recti r(0, 0, rectangle.getWidth(), rectangle.getHeight());
|
||||
|
||||
// Really just too lazy to code a complete new element for this.
|
||||
// If anyone can do this nicer he's welcome.
|
||||
DisplayTable = Environment->addTable(r, this, -1, true);
|
||||
DisplayTable->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
DisplayTable->setSubElement(true);
|
||||
rebuildColumns();
|
||||
}
|
||||
|
||||
void CGUIProfiler::fillRow(u32 rowIndex, const SProfileData& data, bool overviewTitle, bool groupTitle)
|
||||
{
|
||||
DisplayTable->setCellText(rowIndex, 0, data.getName());
|
||||
|
||||
if ( !overviewTitle )
|
||||
DisplayTable->setCellText(rowIndex, 1, core::stringw(data.getCallsCounter()));
|
||||
if ( data.getCallsCounter() > 0 )
|
||||
{
|
||||
DisplayTable->setCellText(rowIndex, 2, core::stringw(data.getTimeSum()));
|
||||
DisplayTable->setCellText(rowIndex, 3, core::stringw((u32)((f32)data.getTimeSum()/(f32)data.getCallsCounter())));
|
||||
DisplayTable->setCellText(rowIndex, 4, core::stringw(data.getLongestTime()));
|
||||
}
|
||||
|
||||
if ( overviewTitle || groupTitle )
|
||||
{
|
||||
const video::SColor titleColor(255, 0, 0, 255);
|
||||
DisplayTable->setCellColor(rowIndex, 0, titleColor);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIProfiler::rebuildColumns()
|
||||
{
|
||||
if ( DisplayTable )
|
||||
{
|
||||
DisplayTable->clear();
|
||||
DisplayTable->addColumn(L"name ");
|
||||
DisplayTable->addColumn(L"count calls");
|
||||
DisplayTable->addColumn(L"time(sum)");
|
||||
DisplayTable->addColumn(L"time(avg)");
|
||||
DisplayTable->addColumn(L"time(max) ");
|
||||
DisplayTable->setActiveColumn(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIProfiler::updateDisplay()
|
||||
{
|
||||
if ( DisplayTable )
|
||||
{
|
||||
DisplayTable->clearRows();
|
||||
|
||||
if ( CurrentGroupIdx < Profiler->getGroupCount() )
|
||||
{
|
||||
bool overview = CurrentGroupIdx == 0;
|
||||
u32 rowIndex = 0;
|
||||
const SProfileData& groupData = Profiler->getGroupData(CurrentGroupIdx);
|
||||
if ( overview || !IgnoreUncalled || groupData.getCallsCounter() > 0 )
|
||||
{
|
||||
rowIndex = DisplayTable->addRow(rowIndex);
|
||||
fillRow(rowIndex, groupData, overview, true);
|
||||
++rowIndex;
|
||||
}
|
||||
|
||||
// show overview over groups?
|
||||
if ( overview )
|
||||
{
|
||||
for ( u32 i=1; i<Profiler->getGroupCount(); ++i )
|
||||
{
|
||||
const SProfileData& groupData = Profiler->getGroupData(i);
|
||||
if ( !IgnoreUncalled || groupData.getCallsCounter() > 0 )
|
||||
{
|
||||
rowIndex = DisplayTable->addRow(rowIndex);
|
||||
fillRow(rowIndex, groupData, false, false);
|
||||
++rowIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
// show data for all elements in current group
|
||||
else
|
||||
{
|
||||
|
||||
for ( u32 i=0; i < Profiler->getProfileDataCount(); ++i )
|
||||
{
|
||||
const SProfileData& data = Profiler->getProfileDataByIndex(i);
|
||||
if ( data.getGroupIndex() == CurrentGroupIdx
|
||||
&& (!IgnoreUncalled || data.getCallsCounter() > 0) )
|
||||
{
|
||||
rowIndex = DisplayTable->addRow(rowIndex);
|
||||
fillRow(rowIndex, data, false, false);
|
||||
++rowIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIProfiler::draw()
|
||||
{
|
||||
if ( isVisible() )
|
||||
{
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
IGUIElement::draw();
|
||||
}
|
||||
|
||||
void CGUIProfiler::nextPage(bool includeOverview)
|
||||
{
|
||||
if ( ++CurrentGroupIdx >= Profiler->getGroupCount() )
|
||||
{
|
||||
if ( includeOverview )
|
||||
CurrentGroupIdx = 0;
|
||||
else
|
||||
CurrentGroupIdx = 1; // can be invalid
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIProfiler::previousPage(bool includeOverview)
|
||||
{
|
||||
if ( CurrentGroupIdx > 0 )
|
||||
--CurrentGroupIdx;
|
||||
else
|
||||
CurrentGroupIdx = Profiler->getGroupCount()-1;
|
||||
if ( CurrentGroupIdx == 0 && !includeOverview )
|
||||
{
|
||||
if ( Profiler->getGroupCount() )
|
||||
CurrentGroupIdx = Profiler->getGroupCount()-1;
|
||||
if ( CurrentGroupIdx == 0 )
|
||||
CurrentGroupIdx = 1; // invalid to avoid showing the overview
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIProfiler::firstPage(bool includeOverview)
|
||||
{
|
||||
if ( includeOverview )
|
||||
CurrentGroupIdx = 0;
|
||||
else
|
||||
CurrentGroupIdx = 1; // can be invalid
|
||||
}
|
||||
|
||||
|
||||
void CGUIProfiler::setIgnoreUncalled(bool ignore)
|
||||
{
|
||||
IgnoreUncalled = ignore;
|
||||
}
|
||||
|
||||
bool CGUIProfiler::getIgnoreUncalled() const
|
||||
{
|
||||
return IgnoreUncalled;
|
||||
}
|
||||
|
||||
//! Sets another skin independent font.
|
||||
void CGUIProfiler::setOverrideFont(IGUIFont* font)
|
||||
{
|
||||
if ( DisplayTable )
|
||||
{
|
||||
DisplayTable->setOverrideFont(font);
|
||||
rebuildColumns();
|
||||
}
|
||||
}
|
||||
|
||||
//! Gets the override font (if any)
|
||||
IGUIFont * CGUIProfiler::getOverrideFont() const
|
||||
{
|
||||
if ( DisplayTable )
|
||||
return DisplayTable->getOverrideFont();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Get the font which is used right now for drawing
|
||||
IGUIFont* CGUIProfiler::getActiveFont() const
|
||||
{
|
||||
if ( DisplayTable )
|
||||
return DisplayTable->getActiveFont();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_GUI_
|
|
@ -0,0 +1,79 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef C_GUI_PROFILER_H_INCLUDED__
|
||||
#define C_GUI_PROFILER_H_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#ifdef _IRR_COMPILE_WITH_GUI_
|
||||
|
||||
#include "IGUIProfiler.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
class CProfiler;
|
||||
struct SProfileData;
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class IGUITable;
|
||||
|
||||
//! Element to display profiler information
|
||||
class CGUIProfiler : public IGUIProfiler
|
||||
{
|
||||
public:
|
||||
//! constructor
|
||||
CGUIProfiler(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
|
||||
|
||||
//! Show first page of profile data
|
||||
virtual void firstPage(bool includeOverview) _IRR_OVERRIDE_;
|
||||
|
||||
//! Show next page of profile data
|
||||
virtual void nextPage(bool includeOverview) _IRR_OVERRIDE_;
|
||||
|
||||
//! Show previous page of profile data
|
||||
virtual void previousPage(bool includeOverview) _IRR_OVERRIDE_;
|
||||
|
||||
//! Don't display stats for data which never got called
|
||||
/** Default is false */
|
||||
virtual void setIgnoreUncalled(bool ignore) _IRR_OVERRIDE_;
|
||||
|
||||
//! Check if we display stats for data which never got called
|
||||
virtual bool getIgnoreUncalled() const _IRR_OVERRIDE_;
|
||||
|
||||
//! Sets another skin independent font.
|
||||
virtual void setOverrideFont(IGUIFont* font=0) _IRR_OVERRIDE_;
|
||||
|
||||
//! Gets the override font (if any)
|
||||
virtual IGUIFont* getOverrideFont() const _IRR_OVERRIDE_;
|
||||
|
||||
//! Get the font which is used right now for drawing
|
||||
virtual IGUIFont* getActiveFont() const _IRR_OVERRIDE_;
|
||||
|
||||
virtual IGUIElement* getElementFromPoint(const core::position2d<s32>& point) _IRR_OVERRIDE_
|
||||
{
|
||||
// This element should never get focus from mouse-clicks
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void draw() _IRR_OVERRIDE_;
|
||||
|
||||
protected:
|
||||
|
||||
void updateDisplay();
|
||||
void fillRow(u32 rowIndex, const SProfileData& data, bool overviewTitle, bool groupTitle);
|
||||
void rebuildColumns();
|
||||
|
||||
CProfiler * Profiler;
|
||||
irr::gui::IGUITable* DisplayTable;
|
||||
irr::u32 CurrentGroupIdx;
|
||||
bool IgnoreUncalled;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_GUI_
|
||||
|
||||
#endif // __C_GUI_IMAGE_H_INCLUDED__
|
|
@ -12,6 +12,8 @@
|
|||
#include "IMaterialRenderer.h"
|
||||
#include "os.h"
|
||||
#include "CShadowVolumeSceneNode.h"
|
||||
#include "EProfileIDs.h"
|
||||
#include "CProfiler.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -31,6 +33,16 @@ COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
|||
#ifdef _DEBUG
|
||||
setDebugName("COctreeSceneNode");
|
||||
#endif
|
||||
|
||||
IRR_PROFILE(
|
||||
static bool initProfile = false;
|
||||
if (!initProfile )
|
||||
{
|
||||
initProfile = true;
|
||||
getProfiler().add(EPID_OC_RENDER, L"render octnode", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_OC_CALCPOLYS, L"calc octnode", L"Irrlicht scene");
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,6 +101,7 @@ void COctreeSceneNode::OnRegisterSceneNode()
|
|||
//! renders the node.
|
||||
void COctreeSceneNode::render()
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psRender(EPID_OC_RENDER);)
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
if (VertexType == -1 || !driver)
|
||||
|
@ -122,10 +135,12 @@ void COctreeSceneNode::render()
|
|||
{
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
|
||||
if (BoxBased)
|
||||
StdOctree->calculatePolys(box);
|
||||
else
|
||||
StdOctree->calculatePolys(frust);
|
||||
IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
|
||||
|
||||
const Octree<video::S3DVertex>::SIndexData* d = StdOctree->getIndexData();
|
||||
|
||||
|
@ -170,10 +185,12 @@ void COctreeSceneNode::render()
|
|||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
|
||||
if (BoxBased)
|
||||
LightMapOctree->calculatePolys(box);
|
||||
else
|
||||
LightMapOctree->calculatePolys(frust);
|
||||
IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
|
||||
|
||||
const Octree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctree->getIndexData();
|
||||
|
||||
|
@ -236,10 +253,12 @@ void COctreeSceneNode::render()
|
|||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
IRR_PROFILE(getProfiler().start(EPID_OC_CALCPOLYS));
|
||||
if (BoxBased)
|
||||
TangentsOctree->calculatePolys(box);
|
||||
else
|
||||
TangentsOctree->calculatePolys(frust);
|
||||
IRR_PROFILE(getProfiler().stop(EPID_OC_CALCPOLYS));
|
||||
|
||||
const Octree<video::S3DVertexTangents>::SIndexData* d = TangentsOctree->getIndexData();
|
||||
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#include "CProfiler.h"
|
||||
#include "CTimer.h"
|
||||
#include <limits.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
IRRLICHT_API CProfiler& IRRCALLCONV getProfiler()
|
||||
{
|
||||
static CProfiler profiler;
|
||||
return profiler;
|
||||
}
|
||||
|
||||
|
||||
//! Convert the whole data into a string
|
||||
core::stringw SProfileData::getAsString() const
|
||||
{
|
||||
if ( CountCalls > 0 )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4996) // 'sprintf' was declared deprecated
|
||||
#endif
|
||||
// Can't use swprintf as it fails on some platforms (especially mobile platforms)
|
||||
// Can't use Irrlicht functions because we have no string formatting.
|
||||
char dummy[1023];
|
||||
sprintf(dummy, "%-15.15s%-12u%-12u%-12u%-12u",
|
||||
core::stringc(Name).c_str(), CountCalls, TimeSum,
|
||||
TimeSum / CountCalls, LongestTime);
|
||||
dummy[1022] = 0;
|
||||
|
||||
return core::stringw(dummy);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default :4996) // 'sprintf' was declared deprecated
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
//! Return a string which describes the columns returned by getAsString
|
||||
core::stringw SProfileData::makeTitleString()
|
||||
{
|
||||
return core::stringw("name calls time(sum) time(avg) time(max)");
|
||||
}
|
||||
|
||||
void SProfileData::reset()
|
||||
{
|
||||
CountCalls = 0;
|
||||
LongestTime = 0;
|
||||
TimeSum = 0;
|
||||
LastTimeStarted = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CProfiler::CProfiler()
|
||||
: Timer(0)
|
||||
, NextAutoId(INT_MAX)
|
||||
{
|
||||
Timer = new CTimer(true);
|
||||
|
||||
addGroup(L"overview");
|
||||
}
|
||||
|
||||
CProfiler::~CProfiler()
|
||||
{
|
||||
if ( Timer )
|
||||
Timer->drop();
|
||||
}
|
||||
|
||||
s32 CProfiler::add(const core::stringw &name, const core::stringw &groupName)
|
||||
{
|
||||
u32 index;
|
||||
if ( findDataIndex(index, name) )
|
||||
{
|
||||
add( ProfileDatas[index].Id, name, groupName );
|
||||
return ProfileDatas[index].Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 id = NextAutoId;
|
||||
--NextAutoId;
|
||||
add( id, name, groupName );
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
void CProfiler::add(s32 id, const core::stringw &name, const core::stringw &groupName)
|
||||
{
|
||||
u32 groupIdx;
|
||||
if ( !findGroupIndex(groupIdx, groupName) )
|
||||
{
|
||||
groupIdx = addGroup(groupName);
|
||||
}
|
||||
|
||||
SProfileData data(id);
|
||||
s32 idx = ProfileDatas.binary_search(data);
|
||||
if ( idx < 0 )
|
||||
{
|
||||
data.reset();
|
||||
data.GroupIndex = groupIdx;
|
||||
data.Name = name;
|
||||
|
||||
ProfileDatas.push_back(data);
|
||||
ProfileDatas.sort();
|
||||
}
|
||||
else
|
||||
{
|
||||
// only reset on group changes, otherwise we want to keep the data or coding CProfileScope would become tricky.
|
||||
if ( groupIdx != ProfileDatas[idx].GroupIndex )
|
||||
{
|
||||
resetDataByIndex((u32)idx);
|
||||
ProfileDatas[idx].GroupIndex = groupIdx;
|
||||
}
|
||||
ProfileDatas[idx].Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
u32 CProfiler::addGroup(const core::stringw &name)
|
||||
{
|
||||
SProfileData group;
|
||||
group.Id = -1; // Id for groups doesn't matter so far
|
||||
group.Name = name;
|
||||
ProfileGroups.push_back(group);
|
||||
return ProfileGroups.size()-1;
|
||||
}
|
||||
|
||||
bool CProfiler::findDataIndex(u32 & result, const core::stringw &name) const
|
||||
{
|
||||
for ( u32 i=0; i < ProfileDatas.size(); ++i )
|
||||
{
|
||||
if ( ProfileDatas[i].Name == name )
|
||||
{
|
||||
result = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CProfiler::findGroupIndex(u32 & result, const core::stringw &name) const
|
||||
{
|
||||
for ( u32 i=0; i < ProfileGroups.size(); ++i )
|
||||
{
|
||||
if ( ProfileGroups[i].Name == name )
|
||||
{
|
||||
result = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CProfiler::resetDataById(s32 id)
|
||||
{
|
||||
s32 idx = ProfileDatas.binary_search(SProfileData(id));
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
resetDataByIndex((u32)idx);
|
||||
}
|
||||
}
|
||||
|
||||
void CProfiler::resetDataByIndex(u32 index)
|
||||
{
|
||||
SProfileData &data = ProfileDatas[index];
|
||||
|
||||
SProfileData & group = ProfileGroups[data.GroupIndex];
|
||||
group.CountCalls -= data.CountCalls;
|
||||
group.TimeSum -= data.TimeSum;
|
||||
|
||||
data.reset();
|
||||
}
|
||||
|
||||
//! Reset profile data for a whole group
|
||||
void CProfiler::resetGroup(u32 index)
|
||||
{
|
||||
for ( u32 i=0; i<ProfileDatas.size(); ++i )
|
||||
{
|
||||
if ( ProfileDatas[i].GroupIndex == index )
|
||||
ProfileDatas[i].reset();
|
||||
}
|
||||
if ( index < ProfileGroups.size() )
|
||||
ProfileGroups[index].reset();
|
||||
}
|
||||
|
||||
void CProfiler::resetAll()
|
||||
{
|
||||
for ( u32 i=0; i<ProfileDatas.size(); ++i )
|
||||
{
|
||||
ProfileDatas[i].reset();
|
||||
}
|
||||
|
||||
for ( u32 i=0; i<ProfileGroups.size(); ++i )
|
||||
{
|
||||
ProfileGroups[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CProfiler::printAll(core::stringw &ostream, bool includeOverview, bool suppressUncalled) const
|
||||
{
|
||||
ostream += SProfileData::makeTitleString();
|
||||
ostream += L"\n";
|
||||
for ( u32 i=includeOverview ?0:1; i<ProfileGroups.size(); ++i )
|
||||
{
|
||||
printGroup( ostream, i, suppressUncalled );
|
||||
}
|
||||
}
|
||||
|
||||
void CProfiler::printGroup(core::stringw &ostream, u32 idxGroup, bool suppressUncalled) const
|
||||
{
|
||||
ostream += ProfileGroups[idxGroup].getAsString();
|
||||
ostream += L"\n";
|
||||
|
||||
// print overview for groups
|
||||
if ( idxGroup == 0 )
|
||||
{
|
||||
for ( u32 i=0; i<ProfileGroups.size(); ++i )
|
||||
{
|
||||
if ( !suppressUncalled || ProfileGroups[i].CountCalls > 0)
|
||||
{
|
||||
ostream += ProfileGroups[i].getAsString();
|
||||
ostream += L"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// print all data in a group
|
||||
else
|
||||
{
|
||||
for ( u32 i=0; i<ProfileDatas.size(); ++i )
|
||||
{
|
||||
if ( (!suppressUncalled || ProfileDatas[i].CountCalls > 0)
|
||||
&& ProfileDatas[i].GroupIndex == idxGroup )
|
||||
{
|
||||
ostream += ProfileDatas[i].getAsString();
|
||||
ostream += L"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace irr
|
|
@ -15,6 +15,8 @@
|
|||
#include "IReadFile.h"
|
||||
#include "IWriteFile.h"
|
||||
#include "ISceneLoader.h"
|
||||
#include "EProfileIDs.h"
|
||||
#include "CProfiler.h"
|
||||
|
||||
#include "os.h"
|
||||
|
||||
|
@ -308,6 +310,24 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
|
|||
ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this, CursorControl);
|
||||
registerSceneNodeAnimatorFactory(animatorFactory);
|
||||
animatorFactory->drop();
|
||||
|
||||
IRR_PROFILE(
|
||||
static bool initProfile = false;
|
||||
if (!initProfile )
|
||||
{
|
||||
initProfile = true;
|
||||
getProfiler().add(EPID_SM_DRAW_ALL, L"drawAll", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_ANIMATE, L"animate", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_CAMERAS, L"cameras", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_LIGHTS, L"lights", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_SKYBOXES, L"skyboxes", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_DEFAULT, L"defaultnodes", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_SHADOWS, L"shadows", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_TRANSPARENT, L"transp.nodes", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_RENDER_EFFECT, L"effectnodes", L"Irrlicht scene");
|
||||
getProfiler().add(EPID_SM_REGISTER, L"reg.render.node", L"Irrlicht scene");
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
@ -1228,6 +1248,7 @@ bool CSceneManager::isCulled(const ISceneNode* node) const
|
|||
//! registers a node for rendering it at a specific time.
|
||||
u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass)
|
||||
{
|
||||
IRR_PROFILE(CProfileScope p1(EPID_SM_REGISTER);)
|
||||
u32 taken = 0;
|
||||
|
||||
switch(pass)
|
||||
|
@ -1345,6 +1366,8 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE
|
|||
//! draws all scene nodes
|
||||
void CSceneManager::drawAll()
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psAll(EPID_SM_DRAW_ALL);)
|
||||
|
||||
if (!Driver)
|
||||
return;
|
||||
|
||||
|
@ -1370,18 +1393,22 @@ void CSceneManager::drawAll()
|
|||
Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT));
|
||||
|
||||
// do animations and other stuff.
|
||||
IRR_PROFILE(getProfiler().start(EPID_SM_ANIMATE));
|
||||
OnAnimate(os::Timer::getTime());
|
||||
IRR_PROFILE(getProfiler().stop(EPID_SM_ANIMATE));
|
||||
|
||||
/*!
|
||||
First Scene Node for prerendering should be the active camera
|
||||
consistent Camera is needed for culling
|
||||
*/
|
||||
IRR_PROFILE(getProfiler().start(EPID_SM_RENDER_CAMERAS));
|
||||
camWorldPos.set(0,0,0);
|
||||
if (ActiveCamera)
|
||||
{
|
||||
ActiveCamera->render();
|
||||
camWorldPos = ActiveCamera->getAbsolutePosition();
|
||||
}
|
||||
IRR_PROFILE(getProfiler().stop(EPID_SM_RENDER_CAMERAS));
|
||||
|
||||
// let all nodes register themselves
|
||||
OnRegisterSceneNode();
|
||||
|
@ -1391,6 +1418,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
//render camera scenes
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psCam(EPID_SM_RENDER_CAMERAS);)
|
||||
CurrentRenderPass = ESNRP_CAMERA;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1408,6 +1436,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
//render lights scenes
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psLights(EPID_SM_RENDER_LIGHTS);)
|
||||
CurrentRenderPass = ESNRP_LIGHT;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1452,6 +1481,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
// render skyboxes
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psSkyBox(EPID_SM_RENDER_SKYBOXES);)
|
||||
CurrentRenderPass = ESNRP_SKY_BOX;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1481,6 +1511,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
// render default objects
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psDefault(EPID_SM_RENDER_DEFAULT);)
|
||||
CurrentRenderPass = ESNRP_SOLID;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1514,6 +1545,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
// render shadows
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psShadow(EPID_SM_RENDER_SHADOWS);)
|
||||
CurrentRenderPass = ESNRP_SHADOW;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1546,6 +1578,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
// render transparent objects.
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psTrans(EPID_SM_RENDER_TRANSPARENT);)
|
||||
CurrentRenderPass = ESNRP_TRANSPARENT;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
@ -1579,6 +1612,7 @@ void CSceneManager::drawAll()
|
|||
|
||||
// render transparent effect objects.
|
||||
{
|
||||
IRR_PROFILE(CProfileScope psEffect(EPID_SM_RENDER_EFFECT);)
|
||||
CurrentRenderPass = ESNRP_TRANSPARENT_EFFECT;
|
||||
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef E_PROFILE_IDS_H_INCLUDED__
|
||||
#define E_PROFILE_IDS_H_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#include "limits.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
#ifdef _IRR_COMPILE_WITH_PROFILING_
|
||||
enum EPROFILE_ID
|
||||
{
|
||||
// We use negative ID's to avoid clashing with user application id's.
|
||||
EPID_FIRST = -INT_MAX, // not used
|
||||
|
||||
//! scenemanager.
|
||||
EPID_SM_DRAW_ALL,
|
||||
EPID_SM_ANIMATE,
|
||||
EPID_SM_RENDER_CAMERAS,
|
||||
EPID_SM_RENDER_LIGHTS,
|
||||
EPID_SM_RENDER_SKYBOXES,
|
||||
EPID_SM_RENDER_DEFAULT,
|
||||
EPID_SM_RENDER_SHADOWS,
|
||||
EPID_SM_RENDER_TRANSPARENT,
|
||||
EPID_SM_RENDER_EFFECT,
|
||||
EPID_SM_REGISTER,
|
||||
|
||||
//! octrees
|
||||
EPID_OC_RENDER,
|
||||
EPID_OC_CALCPOLYS
|
||||
};
|
||||
#endif
|
||||
} // end namespace irr
|
||||
|
||||
#endif // E_PROFILE_IDS_H_INCLUDED__
|
|
@ -414,6 +414,7 @@
|
|||
<Unit filename="../../include/CDynamicMeshBuffer.h" />
|
||||
<Unit filename="../../include/CIndexBuffer.h" />
|
||||
<Unit filename="../../include/CMeshBuffer.h" />
|
||||
<Unit filename="../../include/CProfiler.h" />
|
||||
<Unit filename="../../include/CVertexBuffer.h" />
|
||||
<Unit filename="../../include/EAttributes.h" />
|
||||
<Unit filename="../../include/ECullingTypes.h" />
|
||||
|
@ -470,6 +471,7 @@
|
|||
<Unit filename="../../include/IGUIInOutFader.h" />
|
||||
<Unit filename="../../include/IGUIListBox.h" />
|
||||
<Unit filename="../../include/IGUIMeshViewer.h" />
|
||||
<Unit filename="../../include/IGUIProfiler.h" />
|
||||
<Unit filename="../../include/IGUIScrollBar.h" />
|
||||
<Unit filename="../../include/IGUISkin.h" />
|
||||
<Unit filename="../../include/IGUISpinBox.h" />
|
||||
|
@ -713,6 +715,8 @@
|
|||
<Unit filename="CGUIMessageBox.h" />
|
||||
<Unit filename="CGUIModalScreen.cpp" />
|
||||
<Unit filename="CGUIModalScreen.h" />
|
||||
<Unit filename="CGUIProfiler.cpp" />
|
||||
<Unit filename="CGUIProfiler.h" />
|
||||
<Unit filename="CGUIScrollBar.cpp" />
|
||||
<Unit filename="CGUIScrollBar.h" />
|
||||
<Unit filename="CGUISkin.cpp" />
|
||||
|
@ -887,6 +891,7 @@
|
|||
<Unit filename="CParticleSphereEmitter.h" />
|
||||
<Unit filename="CParticleSystemSceneNode.cpp" />
|
||||
<Unit filename="CParticleSystemSceneNode.h" />
|
||||
<Unit filename="CProfiler.cpp" />
|
||||
<Unit filename="CQ3LevelMesh.cpp" />
|
||||
<Unit filename="CQ3LevelMesh.h" />
|
||||
<Unit filename="CQuake3ShaderSceneNode.cpp" />
|
||||
|
@ -1007,6 +1012,7 @@
|
|||
<Unit filename="CZBuffer.h" />
|
||||
<Unit filename="CZipReader.cpp" />
|
||||
<Unit filename="CZipReader.h" />
|
||||
<Unit filename="EProfileIDs.h" />
|
||||
<Unit filename="IAttribute.h" />
|
||||
<Unit filename="IBurningShader.cpp" />
|
||||
<Unit filename="IBurningShader.h" />
|
||||
|
|
|
@ -835,6 +835,7 @@
|
|||
<ClInclude Include="..\..\include\EMaterialFlags.h" />
|
||||
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h" />
|
||||
<ClInclude Include="..\..\include\IEventReceiver.h" />
|
||||
<ClInclude Include="..\..\include\CProfiler.h" />
|
||||
<ClInclude Include="..\..\include\ILogger.h" />
|
||||
<ClInclude Include="..\..\include\IOSOperator.h" />
|
||||
<ClInclude Include="..\..\include\IRandomizer.h" />
|
||||
|
@ -982,6 +983,7 @@
|
|||
<ClInclude Include="..\..\include\IGUIInOutFader.h" />
|
||||
<ClInclude Include="..\..\include\IGUIListBox.h" />
|
||||
<ClInclude Include="..\..\include\IGUIMeshViewer.h" />
|
||||
<ClInclude Include="..\..\include\IGUIProfiler.h" />
|
||||
<ClInclude Include="..\..\include\IGUIScrollBar.h" />
|
||||
<ClInclude Include="..\..\include\IGUISkin.h" />
|
||||
<ClInclude Include="..\..\include\IGUISpinBox.h" />
|
||||
|
@ -1149,6 +1151,7 @@
|
|||
<ClInclude Include="COSOperator.h" />
|
||||
<ClInclude Include="CTimer.h" />
|
||||
<ClInclude Include="os.h" />
|
||||
<ClInclude Include="EProfileIDs.h" />
|
||||
<ClInclude Include="lzma\LzmaDec.h" />
|
||||
<ClInclude Include="lzma\Types.h" />
|
||||
<ClInclude Include="zlib\crc32.h" />
|
||||
|
@ -1226,7 +1229,8 @@
|
|||
<ClInclude Include="CGUIMeshViewer.h" />
|
||||
<ClInclude Include="CGUIMessageBox.h" />
|
||||
<ClInclude Include="CGUIModalScreen.h" />
|
||||
<ClInclude Include="CGUIScrollBar.h" />
|
||||
<ClInclude Include="CGUIProfiler.h" />
|
||||
<ClInclude Include="CGUIScrollBar.h" />
|
||||
<ClInclude Include="CGUISkin.h" />
|
||||
<ClInclude Include="CGUISpinBox.h" />
|
||||
<ClInclude Include="CGUISpriteBank.h" />
|
||||
|
@ -1413,6 +1417,7 @@
|
|||
<ClCompile Include="Irrlicht.cpp" />
|
||||
<ClCompile Include="leakHunter.cpp" />
|
||||
<ClCompile Include="os.cpp" />
|
||||
<ClCompile Include="CProfiler.cpp" />
|
||||
<ClCompile Include="lzma\LzmaDec.c" />
|
||||
<ClCompile Include="zlib\adler32.c" />
|
||||
<ClCompile Include="zlib\compress.c" />
|
||||
|
@ -1542,7 +1547,8 @@
|
|||
<ClCompile Include="CGUIMeshViewer.cpp" />
|
||||
<ClCompile Include="CGUIMessageBox.cpp" />
|
||||
<ClCompile Include="CGUIModalScreen.cpp" />
|
||||
<ClCompile Include="CGUIScrollBar.cpp" />
|
||||
<ClCompile Include="CGUIProfiler.cpp" />
|
||||
<ClCompile Include="CGUIScrollBar.cpp" />
|
||||
<ClCompile Include="CGUISkin.cpp" />
|
||||
<ClCompile Include="CGUISpinBox.cpp" />
|
||||
<ClCompile Include="CGUISpriteBank.cpp" />
|
||||
|
|
|
@ -105,7 +105,10 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\IEventReceiver.h">
|
||||
<ClInclude Include="..\..\include\IEventReceiver.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\CProfiler.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\ILogger.h">
|
||||
|
@ -539,6 +542,9 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIMeshViewer.h">
|
||||
<Filter>include\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIProfiler.h">
|
||||
<Filter>include\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIScrollBar.h">
|
||||
<Filter>include\gui</Filter>
|
||||
|
@ -1022,6 +1028,9 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="os.h">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EProfileIDs.h">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lzma\LzmaDec.h">
|
||||
<Filter>Irrlicht\irr\extern</Filter>
|
||||
|
@ -1254,7 +1263,10 @@
|
|||
<ClInclude Include="CGUIModalScreen.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUIScrollBar.h">
|
||||
<ClInclude Include="CGUIProfiler.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUIScrollBar.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUISkin.h">
|
||||
|
@ -1822,6 +1834,9 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="os.cpp">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CProfiler.cpp">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="lzma\LzmaDec.c">
|
||||
<Filter>Irrlicht\irr\extern</Filter>
|
||||
|
@ -2210,7 +2225,10 @@
|
|||
<ClCompile Include="CGUIModalScreen.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUIScrollBar.cpp">
|
||||
<ClCompile Include="CGUIProfiler.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUIScrollBar.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUISkin.cpp">
|
||||
|
|
|
@ -842,6 +842,7 @@
|
|||
<ClInclude Include="..\..\include\EMaterialFlags.h" />
|
||||
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h" />
|
||||
<ClInclude Include="..\..\include\IEventReceiver.h" />
|
||||
<ClInclude Include="..\..\include\CProfiler.h" />
|
||||
<ClInclude Include="..\..\include\ILogger.h" />
|
||||
<ClInclude Include="..\..\include\IOSOperator.h" />
|
||||
<ClInclude Include="..\..\include\IRandomizer.h" />
|
||||
|
@ -989,6 +990,7 @@
|
|||
<ClInclude Include="..\..\include\IGUIInOutFader.h" />
|
||||
<ClInclude Include="..\..\include\IGUIListBox.h" />
|
||||
<ClInclude Include="..\..\include\IGUIMeshViewer.h" />
|
||||
<ClInclude Include="..\..\include\IGUIProfiler.h" />
|
||||
<ClInclude Include="..\..\include\IGUIScrollBar.h" />
|
||||
<ClInclude Include="..\..\include\IGUISkin.h" />
|
||||
<ClInclude Include="..\..\include\IGUISpinBox.h" />
|
||||
|
@ -1156,6 +1158,7 @@
|
|||
<ClInclude Include="COSOperator.h" />
|
||||
<ClInclude Include="CTimer.h" />
|
||||
<ClInclude Include="os.h" />
|
||||
<ClInclude Include="EProfileIDs.h" />
|
||||
<ClInclude Include="lzma\LzmaDec.h" />
|
||||
<ClInclude Include="lzma\Types.h" />
|
||||
<ClInclude Include="zlib\crc32.h" />
|
||||
|
@ -1233,7 +1236,8 @@
|
|||
<ClInclude Include="CGUIMeshViewer.h" />
|
||||
<ClInclude Include="CGUIMessageBox.h" />
|
||||
<ClInclude Include="CGUIModalScreen.h" />
|
||||
<ClInclude Include="CGUIScrollBar.h" />
|
||||
<ClInclude Include="CGUIProfiler.h" />
|
||||
<ClInclude Include="CGUIScrollBar.h" />
|
||||
<ClInclude Include="CGUISkin.h" />
|
||||
<ClInclude Include="CGUISpinBox.h" />
|
||||
<ClInclude Include="CGUISpriteBank.h" />
|
||||
|
@ -1419,6 +1423,7 @@
|
|||
<ClCompile Include="COSOperator.cpp" />
|
||||
<ClCompile Include="Irrlicht.cpp" />
|
||||
<ClCompile Include="os.cpp" />
|
||||
<ClCompile Include="CProfiler.cpp" />
|
||||
<ClCompile Include="leakHunter.cpp" />
|
||||
<ClCompile Include="lzma\LzmaDec.c" />
|
||||
<ClCompile Include="zlib\adler32.c" />
|
||||
|
@ -1549,7 +1554,8 @@
|
|||
<ClCompile Include="CGUIMeshViewer.cpp" />
|
||||
<ClCompile Include="CGUIMessageBox.cpp" />
|
||||
<ClCompile Include="CGUIModalScreen.cpp" />
|
||||
<ClCompile Include="CGUIScrollBar.cpp" />
|
||||
<ClCompile Include="CGUIProfiler.cpp" />
|
||||
<ClCompile Include="CGUIScrollBar.cpp" />
|
||||
<ClCompile Include="CGUISkin.cpp" />
|
||||
<ClCompile Include="CGUISpinBox.cpp" />
|
||||
<ClCompile Include="CGUISpriteBank.cpp" />
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\IEventReceiver.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\CProfiler.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\ILogger.h">
|
||||
<Filter>include</Filter>
|
||||
|
@ -542,6 +545,9 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIMeshViewer.h">
|
||||
<Filter>include\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIProfiler.h">
|
||||
<Filter>include\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\IGUIScrollBar.h">
|
||||
<Filter>include\gui</Filter>
|
||||
|
@ -1025,6 +1031,9 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="os.h">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EProfileIDs.h">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lzma\LzmaDec.h">
|
||||
<Filter>Irrlicht\irr\extern</Filter>
|
||||
|
@ -1257,7 +1266,10 @@
|
|||
<ClInclude Include="CGUIModalScreen.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUIScrollBar.h">
|
||||
<ClInclude Include="CGUIProfiler.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUIScrollBar.h">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CGUISkin.h">
|
||||
|
@ -1822,6 +1834,9 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="os.cpp">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CProfiler.cpp">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="leakHunter.cpp">
|
||||
<Filter>Irrlicht\irr</Filter>
|
||||
|
@ -2213,7 +2228,10 @@
|
|||
<ClCompile Include="CGUIModalScreen.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUIScrollBar.cpp">
|
||||
<ClCompile Include="CGUIProfiler.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUIScrollBar.cpp">
|
||||
<Filter>Irrlicht\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CGUISkin.cpp">
|
||||
|
|
|
@ -586,6 +586,10 @@
|
|||
RelativePath=".\..\..\include\IEventReceiver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\..\include\CProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\..\include\ILogger.h"
|
||||
>
|
||||
|
@ -1198,6 +1202,10 @@
|
|||
RelativePath=".\..\..\include\IGUIMeshViewer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\..\include\IGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\..\include\IGUIScrollBar.h"
|
||||
>
|
||||
|
@ -1391,6 +1399,14 @@
|
|||
RelativePath="CGUIModalScreen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIScrollBar.cpp"
|
||||
>
|
||||
|
@ -3001,6 +3017,14 @@
|
|||
RelativePath="os.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="EProfileIDs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="leakHunter.cpp"
|
||||
>
|
||||
|
|
|
@ -685,6 +685,10 @@
|
|||
RelativePath="..\..\include\IEventReceiver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\CProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\ILogger.h"
|
||||
>
|
||||
|
@ -1296,6 +1300,10 @@
|
|||
RelativePath="..\..\include\IGUIMeshViewer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIScrollBar.h"
|
||||
>
|
||||
|
@ -2728,6 +2736,14 @@
|
|||
RelativePath="os.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="EProfileIDs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="os.h"
|
||||
>
|
||||
|
@ -3592,6 +3608,14 @@
|
|||
RelativePath="CGUIModalScreen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIScrollBar.cpp"
|
||||
>
|
||||
|
|
|
@ -329,6 +329,10 @@
|
|||
RelativePath="..\..\include\IEventReceiver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\CProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\ILogger.h"
|
||||
>
|
||||
|
@ -848,6 +852,10 @@
|
|||
RelativePath="..\..\include\IGUIMeshViewer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIScrollBar.h"
|
||||
>
|
||||
|
@ -1033,6 +1041,14 @@
|
|||
RelativePath="CGUIModalScreen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIProfiler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CGUIScrollBar.cpp"
|
||||
>
|
||||
|
@ -2574,6 +2590,14 @@
|
|||
RelativePath="os.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CProfiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="EProfileIDs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="leakHunter.cpp"
|
||||
>
|
||||
|
|
|
@ -309,6 +309,9 @@
|
|||
<File
|
||||
RelativePath="..\..\include\IEventReceiver.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\CProfiler.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IFileArchive.h">
|
||||
</File>
|
||||
|
@ -372,6 +375,9 @@
|
|||
<File
|
||||
RelativePath="..\..\include\IGUIMeshViewer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIProfiler.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\IGUIScrollBar.h">
|
||||
</File>
|
||||
|
@ -1434,6 +1440,12 @@
|
|||
<File
|
||||
RelativePath=".\os.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CProfiler.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\EProfileIDs.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\leakHunter.cpp">
|
||||
</File>
|
||||
|
@ -1837,6 +1849,12 @@
|
|||
<File
|
||||
RelativePath=".\CGUIModalScreen.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIProfiler.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIProfiler.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CGUIScrollBar.cpp">
|
||||
</File>
|
||||
|
|
|
@ -44,8 +44,8 @@ IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CIm
|
|||
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)
|
||||
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o
|
||||
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CWADReader.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o lzma/LzmaDec.o
|
||||
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o leakHunter.o
|
||||
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o
|
||||
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o leakHunter.o CProfiler.o
|
||||
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o CGUIProfiler.o
|
||||
ZLIBOBJ = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o
|
||||
JPEGLIBOBJ = jpeglib/jcapimin.o jpeglib/jcapistd.o jpeglib/jccoefct.o jpeglib/jccolor.o jpeglib/jcdctmgr.o jpeglib/jchuff.o jpeglib/jcinit.o jpeglib/jcmainct.o jpeglib/jcmarker.o jpeglib/jcmaster.o jpeglib/jcomapi.o jpeglib/jcparam.o jpeglib/jcprepct.o jpeglib/jcsample.o jpeglib/jctrans.o jpeglib/jdapimin.o jpeglib/jdapistd.o jpeglib/jdatadst.o jpeglib/jdatasrc.o jpeglib/jdcoefct.o jpeglib/jdcolor.o jpeglib/jddctmgr.o jpeglib/jdhuff.o jpeglib/jdinput.o jpeglib/jdmainct.o jpeglib/jdmarker.o jpeglib/jdmaster.o jpeglib/jdmerge.o jpeglib/jdpostct.o jpeglib/jdsample.o jpeglib/jdtrans.o jpeglib/jerror.o jpeglib/jfdctflt.o jpeglib/jfdctfst.o jpeglib/jfdctint.o jpeglib/jidctflt.o jpeglib/jidctfst.o jpeglib/jidctint.o jpeglib/jmemmgr.o jpeglib/jmemnobs.o jpeglib/jquant1.o jpeglib/jquant2.o jpeglib/jutils.o jpeglib/jcarith.o jpeglib/jdarith.o jpeglib/jaricom.o
|
||||
LIBPNGOBJ = libpng/png.o libpng/pngerror.o libpng/pngget.o libpng/pngmem.o libpng/pngpread.o libpng/pngread.o libpng/pngrio.o libpng/pngrtran.o libpng/pngrutil.o libpng/pngset.o libpng/pngtrans.o libpng/pngwio.o libpng/pngwrite.o libpng/pngwtran.o libpng/pngwutil.o
|
||||
|
|
Loading…
Reference in New Issue