Exposed StaticModelGroup to script. Ported HugeObjectCount example group mode switching to script versions.

This commit is contained in:
Lasse Öörni 2013-09-19 22:44:06 +00:00
Родитель 6e58119be9
Коммит 1cd73e46fd
13 изменённых файлов: 246 добавлений и 47 удалений

Просмотреть файл

@ -3,6 +3,7 @@
-- - Creating a scene with 250 x 250 simple objects; -- - Creating a scene with 250 x 250 simple objects;
-- - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :); -- - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :);
-- - Allowing examination of performance hotspots in the rendering code; -- - Allowing examination of performance hotspots in the rendering code;
-- - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
require "LuaScripts/Utilities/Sample" require "LuaScripts/Utilities/Sample"
@ -12,6 +13,7 @@ local boxNodes = {}
local yaw = 0.0 local yaw = 0.0
local pitch = 0.0 local pitch = 0.0
local animate = false local animate = false
local useGroups = false
local context = GetContext() local context = GetContext()
@ -38,7 +40,12 @@ function Start()
end end
function CreateScene() function CreateScene()
if scene_ == nil then
scene_ = Scene(context) scene_ = Scene(context)
else
scene_:Clear()
boxNodes = {}
end
-- Create the Octree component to the scene so that drawable objects can be rendered. Use default volume -- Create the Octree component to the scene so that drawable objects can be rendered. Use default volume
-- (-1000, -1000, -1000) to (1000, 1000, 1000) -- (-1000, -1000, -1000) to (1000, 1000, 1000)
@ -54,12 +61,15 @@ function CreateScene()
-- Create a directional light -- Create a directional light
local lightNode = scene_:CreateChild("DirectionalLight") local lightNode = scene_:CreateChild("DirectionalLight")
lightNode.direction = Vector3(0.5, -1.0, 0.5) -- The direction vector does not need to be normalized lightNode.direction = Vector3(-0.6, -1.0, -0.8) -- The direction vector does not need to be normalized
local light = lightNode:CreateComponent("Light") local light = lightNode:CreateComponent("Light")
light.lightType = LIGHT_DIRECTIONAL light.lightType = LIGHT_DIRECTIONAL
if not useGroups then
light.color = Color(0.7, 0.35, 0.0) light.color = Color(0.7, 0.35, 0.0)
-- Create box StaticModels in the scene -- Create individual box StaticModels in the scene
for y = -125, 125 do for y = -125, 125 do
for x = -125, 125 do for x = -125, 125 do
local boxNode = scene_:CreateChild("Box") local boxNode = scene_:CreateChild("Box")
@ -70,19 +80,48 @@ function CreateScene()
table.insert(boxNodes, boxNode) table.insert(boxNodes, boxNode)
end end
end end
else
light.color = Color(0.6, 0.6, 0.6);
light.specularIntensity = 1.5;
-- Create the camera -- Create StaticModelGroups in the scene
cameraNode = scene_:CreateChild("Camera") local lastGroup = nil
for y = -125, 125 do
for x = -125, 125 do
-- Create new group if no group yet, or the group has already "enough" objects. The tradeoff is between culling
-- accuracy and the amount of CPU processing needed for all the objects. Note that the group's own transform
-- does not matter, and it does not render anything if instance nodes are not added to it
if lastGroup == nil or lastGroup.numInstanceNodes >= 25 * 25 then
local boxGroupNode = scene_:CreateChild("BoxGroup")
lastGroup = boxGroupNode:CreateComponent("StaticModelGroup")
lastGroup.model = cache:GetResource("Model", "Models/Box.mdl")
end
local boxNode = scene_:CreateChild("Box");
boxNode.position = Vector3(x * 0.3, 0.0, y * 0.3)
boxNode:SetScale(0.25)
table.insert(boxNodes, boxNode)
lastGroup:AddInstanceNode(boxNode);
end
end
end
-- Create the camera. Create it outside the scene so that we can clear the whole scene without affecting it
if cameraNode == nil then
cameraNode = Node(context)
cameraNode.position = Vector3(0.0, 10.0, -100.0) cameraNode.position = Vector3(0.0, 10.0, -100.0)
local camera = cameraNode:CreateComponent("Camera") local camera = cameraNode:CreateComponent("Camera")
camera.farClip = 300.0 camera.farClip = 300.0
end end
end
function CreateInstructions() function CreateInstructions()
-- Construct new Text object, set string to display and font to use -- Construct new Text object, set string to display and font to use
local instructionText = ui.root:CreateChild("Text") local instructionText = ui.root:CreateChild("Text")
instructionText:SetText("Use WASD keys and mouse to move\n".. instructionText:SetText("Use WASD keys and mouse to move\n"..
"Space to toggle animation") "Space to toggle animation\n"..
"G to toggle object group optimization")
instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15) instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
-- The text has multiple rows. Center them in relation to each other -- The text has multiple rows. Center them in relation to each other
instructionText.textAlignment = HA_CENTER instructionText.textAlignment = HA_CENTER
@ -157,6 +196,12 @@ function HandleUpdate(eventType, eventData)
animate = not animate animate = not animate
end end
-- Toggle grouped / ungrouped mode
if input:GetKeyPress(KEY_G) then
useGroups = not useGroups
CreateScene()
end
-- Move the camera, scale movement with time step -- Move the camera, scale movement with time step
MoveCamera(timeStep) MoveCamera(timeStep)

Просмотреть файл

@ -3,6 +3,7 @@
// - Creating a scene with 250 x 250 simple objects; // - Creating a scene with 250 x 250 simple objects;
// - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :) // - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :)
// - Allowing examination of performance hotspots in the rendering code; // - Allowing examination of performance hotspots in the rendering code;
// - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
#include "Scripts/Utilities/Sample.as" #include "Scripts/Utilities/Sample.as"
@ -12,6 +13,7 @@ Array<Node@> boxNodes;
float yaw = 0.0f; float yaw = 0.0f;
float pitch = 0.0f; float pitch = 0.0f;
bool animate = false; bool animate = false;
bool useGroups = false;
void Start() void Start()
{ {
@ -33,7 +35,13 @@ void Start()
void CreateScene() void CreateScene()
{ {
if (scene_ is null)
scene_ = Scene(); scene_ = Scene();
else
{
scene_.Clear();
boxNodes.Clear();
}
// Create the Octree component to the scene so that drawable objects can be rendered. Use default volume // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume
// (-1000, -1000, -1000) to (1000, 1000, 1000) // (-1000, -1000, -1000) to (1000, 1000, 1000)
@ -49,12 +57,15 @@ void CreateScene()
// Create a directional light // Create a directional light
Node@ lightNode = scene_.CreateChild("DirectionalLight"); Node@ lightNode = scene_.CreateChild("DirectionalLight");
lightNode.direction = Vector3(0.5f, -1.0f, 0.5f); // The direction vector does not need to be normalized lightNode.direction = Vector3(-0.6f, -1.0f, -0.8f); // The direction vector does not need to be normalized
Light@ light = lightNode.CreateComponent("Light"); Light@ light = lightNode.CreateComponent("Light");
light.lightType = LIGHT_DIRECTIONAL; light.lightType = LIGHT_DIRECTIONAL;
if (!useGroups)
{
light.color = Color(0.7f, 0.35f, 0.0f); light.color = Color(0.7f, 0.35f, 0.0f);
// Create box StaticModels in the scene // Create individual box StaticModels in the scene
for (int y = -125; y < 125; ++y) for (int y = -125; y < 125; ++y)
{ {
for (int x = -125; x < 125; ++x) for (int x = -125; x < 125; ++x)
@ -67,13 +78,47 @@ void CreateScene()
boxNodes.Push(boxNode); boxNodes.Push(boxNode);
} }
} }
}
else
{
light.color = Color(0.6f, 0.6f, 0.6f);
light.specularIntensity = 1.5f;
// Create the camera // Create StaticModelGroups in the scene
cameraNode = scene_.CreateChild("Camera"); StaticModelGroup@ lastGroup;
for (int y = -125; y < 125; ++y)
{
for (int x = -125; x < 125; ++x)
{
// Create new group if no group yet, or the group has already "enough" objects. The tradeoff is between culling
// accuracy and the amount of CPU processing needed for all the objects. Note that the group's own transform
// does not matter, and it does not render anything if instance nodes are not added to it
if (lastGroup is null || lastGroup.numInstanceNodes >= 25 * 25)
{
Node@ boxGroupNode = scene_.CreateChild("BoxGroup");
lastGroup = boxGroupNode.CreateComponent("StaticModelGroup");
lastGroup.model = cache.GetResource("Model", "Models/Box.mdl");
}
Node@ boxNode = scene_.CreateChild("Box");
boxNode.position = Vector3(x * 0.3f, 0.0f, y * 0.3f);
boxNode.SetScale(0.25f);
boxNodes.Push(boxNode);
lastGroup.AddInstanceNode(boxNode);
}
}
}
// Create the camera. Create it outside the scene so that we can clear the whole scene without affecting it
if (cameraNode is null)
{
cameraNode = Node("Camera");
cameraNode.position = Vector3(0.0f, 10.0f, -100.0f); cameraNode.position = Vector3(0.0f, 10.0f, -100.0f);
Camera@ camera = cameraNode.CreateComponent("Camera"); Camera@ camera = cameraNode.CreateComponent("Camera");
camera.farClip = 300.0f; camera.farClip = 300.0f;
} }
}
void CreateInstructions() void CreateInstructions()
{ {
@ -81,7 +126,8 @@ void CreateInstructions()
Text@ instructionText = ui.root.CreateChild("Text"); Text@ instructionText = ui.root.CreateChild("Text");
instructionText.text = instructionText.text =
"Use WASD keys and mouse to move\n" "Use WASD keys and mouse to move\n"
"Space to toggle animation"; "Space to toggle animation\n"
"G to toggle object group optimization";
instructionText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15); instructionText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15);
// The text has multiple rows. Center them in relation to each other // The text has multiple rows. Center them in relation to each other
instructionText.textAlignment = HA_CENTER; instructionText.textAlignment = HA_CENTER;
@ -155,6 +201,13 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
if (input.keyPress[KEY_SPACE]) if (input.keyPress[KEY_SPACE])
animate = !animate; animate = !animate;
// Toggle grouped / ungrouped mode
if (input.keyPress['G'])
{
useGroups = !useGroups;
CreateScene();
}
// Move the camera, scale movement with time step // Move the camera, scale movement with time step
MoveCamera(timeStep); MoveCamera(timeStep);

Просмотреть файл

@ -1982,6 +1982,18 @@ Properties:<br>
- unsigned numGeometries (readonly) - unsigned numGeometries (readonly)
- unsigned occlusionLodLevel - unsigned occlusionLodLevel
StaticModelGroup : StaticModel
Methods:<br>
- void AddInstanceNode(Node* node)
- void RemoveInstanceNode(Node* node);
- void RemoveAllInstanceNodes()
- unsigned GetNumInstanceNodes() const
- Node* GetInstanceNode(unsigned index) const
Properties:<br>
- unsigned numInstanceNodes (readonly)
Pass : RefCounted Pass : RefCounted
Methods:<br> Methods:<br>

Просмотреть файл

@ -2436,6 +2436,66 @@ Properties:<br>
- uint occlusionLodLevel - uint occlusionLodLevel
StaticModelGroup
Methods:<br>
- void SendEvent(const String&, VariantMap& arg1 = VariantMap ( ))
- bool Load(File@, bool arg1 = false)
- bool Save(File@) const
- bool LoadXML(const XMLElement&, bool arg1 = false)
- bool SaveXML(XMLElement&) const
- void ApplyAttributes()
- bool SetAttribute(const String&, const Variant&)
- void ResetToDefault()
- void RemoveInstanceDefault()
- Variant GetAttribute(const String&) const
- Variant GetAttributeDefault(const String&) const
- void Remove()
- void MarkNetworkUpdate() const
- void DrawDebugGeometry(DebugRenderer@, bool)
- void AddInstanceNode(Node@)
- void RemoveInstanceNode(Node@)
- void RemoveAllInstanceNodes()
Properties:<br>
- int refs (readonly)
- int weakRefs (readonly)
- ShortStringHash type (readonly)
- String typeName (readonly)
- String category (readonly)
- uint numAttributes (readonly)
- Variant[] attributes
- Variant[] attributeDefaults (readonly)
- AttributeInfo[] attributeInfos (readonly)
- bool temporary
- bool enabled
- bool enabledEffective (readonly)
- uint id (readonly)
- Node@ node (readonly)
- bool inView (readonly)
- bool castShadows
- bool occluder
- bool occludee
- float drawDistance
- float shadowDistance
- float lodBias
- uint viewMask
- uint lightMask
- uint shadowMask
- uint zoneMask
- uint maxLights
- BoundingBox boundingBox (readonly)
- BoundingBox worldBoundingBox (readonly)
- Model@ model
- Material@ material (writeonly)
- Material@[] materials
- uint numGeometries (readonly)
- Zone@ zone (readonly)
- uint occlusionLodLevel
- uint numInstanceNodes (readonly)
- Node@[] instanceNodes (readonly)
Skybox Skybox
Methods:<br> Methods:<br>

Просмотреть файл

@ -38,6 +38,7 @@
#include "RenderPath.h" #include "RenderPath.h"
#include "Scene.h" #include "Scene.h"
#include "SmoothedTransform.h" #include "SmoothedTransform.h"
#include "StaticModelGroup.h"
#include "Technique.h" #include "Technique.h"
#include "Terrain.h" #include "Terrain.h"
#include "TerrainPatch.h" #include "TerrainPatch.h"
@ -817,6 +818,18 @@ static void RegisterStaticModel(asIScriptEngine* engine)
engine->RegisterObjectMethod("StaticModel", "uint get_occlusionLodLevel() const", asMETHOD(StaticModel, GetOcclusionLodLevel), asCALL_THISCALL); engine->RegisterObjectMethod("StaticModel", "uint get_occlusionLodLevel() const", asMETHOD(StaticModel, GetOcclusionLodLevel), asCALL_THISCALL);
} }
static void RegisterStaticModelGroup(asIScriptEngine* engine)
{
RegisterStaticModel<StaticModelGroup>(engine, "StaticModelGroup", true);
engine->RegisterObjectMethod("StaticModelGroup", "void set_occlusionLodLevel(uint) const", asMETHOD(StaticModelGroup, SetOcclusionLodLevel), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "uint get_occlusionLodLevel() const", asMETHOD(StaticModelGroup, GetOcclusionLodLevel), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void AddInstanceNode(Node@+)", asMETHOD(StaticModelGroup, AddInstanceNode), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void RemoveInstanceNode(Node@+)", asMETHOD(StaticModelGroup, RemoveInstanceNode), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void RemoveAllInstanceNodes()", asMETHOD(StaticModelGroup, RemoveAllInstanceNodes), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "uint get_numInstanceNodes() const", asMETHOD(StaticModelGroup, GetNumInstanceNodes), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "Node@+ get_instanceNodes(uint) const", asMETHOD(StaticModelGroup, GetInstanceNode), asCALL_THISCALL);
}
static void RegisterSkybox(asIScriptEngine* engine) static void RegisterSkybox(asIScriptEngine* engine)
{ {
RegisterStaticModel<Skybox>(engine, "Skybox", true); RegisterStaticModel<Skybox>(engine, "Skybox", true);
@ -1438,6 +1451,7 @@ void RegisterGraphicsAPI(asIScriptEngine* engine)
RegisterLight(engine); RegisterLight(engine);
RegisterZone(engine); RegisterZone(engine);
RegisterStaticModel(engine); RegisterStaticModel(engine);
RegisterStaticModelGroup(engine);
RegisterSkybox(engine); RegisterSkybox(engine);
RegisterAnimatedModel(engine); RegisterAnimatedModel(engine);
RegisterAnimationController(engine); RegisterAnimationController(engine);

Просмотреть файл

@ -0,0 +1,13 @@
$#include "StaticModelGroup.h"
class StaticModelGroup : public StaticModel
{
void AddInstanceNode(Node* node);
void RemoveInstanceNode(Node* node);
void RemoveAllInstanceNodes();
unsigned GetNumInstanceNodes() const;
Node* GetInstanceNode(unsigned index) const;
tolua_readonly tolua_property__get_set unsigned numInstanceNodes;
};

Просмотреть файл

@ -21,6 +21,7 @@ $pfile "Graphics/RenderSurface.pkg"
$pfile "Graphics/Skeleton.pkg" $pfile "Graphics/Skeleton.pkg"
$pfile "Graphics/Skybox.pkg" $pfile "Graphics/Skybox.pkg"
$pfile "Graphics/StaticModel.pkg" $pfile "Graphics/StaticModel.pkg"
$pfile "Graphics/StaticModelGroup.pkg"
$pfile "Graphics/Technique.pkg" $pfile "Graphics/Technique.pkg"
$pfile "Graphics/Terrain.pkg" $pfile "Graphics/Terrain.pkg"
$pfile "Graphics/TerrainPatch.pkg" $pfile "Graphics/TerrainPatch.pkg"

Просмотреть файл

@ -170,7 +170,7 @@ void HugeObjectCount::CreateInstructions()
instructionText->SetText( instructionText->SetText(
"Use WASD keys and mouse to move\n" "Use WASD keys and mouse to move\n"
"Space to toggle animation\n" "Space to toggle animation\n"
"G to toggle object group optimization\n" "G to toggle object group optimization"
); );
instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15); instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);
// The text has multiple rows. Center them in relation to each other // The text has multiple rows. Center them in relation to each other

Просмотреть файл

@ -38,6 +38,7 @@ class Scene;
/// - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :) /// - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :)
/// - Allowing examination of performance hotspots in the rendering code; /// - Allowing examination of performance hotspots in the rendering code;
/// - Using the profiler to measure the time taken to animate the scene; /// - Using the profiler to measure the time taken to animate the scene;
/// - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
class HugeObjectCount : public Sample class HugeObjectCount : public Sample
{ {
OBJECT(HugeObjectCount); OBJECT(HugeObjectCount);