Convert MaterialCache2D to a component. [ci skip]
This commit is contained in:
parent
4a34818c25
commit
43147fbe1d
@ -32,7 +32,6 @@
|
||||
#include "Input.h"
|
||||
#include "InputEvents.h"
|
||||
#include "Log.h"
|
||||
#include "MaterialCache2D.h"
|
||||
#include "NavigationMesh.h"
|
||||
#include "Network.h"
|
||||
#include "PackageFile.h"
|
||||
@ -149,7 +148,6 @@ bool Engine::Initialize(const VariantMap& parameters)
|
||||
}
|
||||
|
||||
// 2D graphics library is dependent on 3D graphics library
|
||||
context_->RegisterSubsystem(new MaterialCache2D(context_));
|
||||
RegisterUrho2DLibrary(context_);
|
||||
|
||||
// Start logging
|
||||
@ -761,10 +759,6 @@ void Engine::HandleExitRequested(StringHash eventType, VariantMap& eventData)
|
||||
|
||||
void Engine::DoExit()
|
||||
{
|
||||
MaterialCache2D* materialCache = GetSubsystem<MaterialCache2D>();
|
||||
if (materialCache)
|
||||
materialCache->ReleaseAllMaterials();
|
||||
|
||||
Graphics* graphics = GetSubsystem<Graphics>();
|
||||
if (graphics)
|
||||
graphics->Close();
|
||||
|
@ -274,6 +274,22 @@ ResourceRef Drawable2D::GetMaterialAttr() const
|
||||
return GetResourceRef(material_, Material::GetTypeStatic());
|
||||
}
|
||||
|
||||
void Drawable2D::OnNodeSet(Node* node)
|
||||
{
|
||||
Drawable::OnNodeSet(node);
|
||||
|
||||
if (node)
|
||||
{
|
||||
node->AddListener(this);
|
||||
|
||||
Scene* scene = GetScene();
|
||||
if (scene)
|
||||
{
|
||||
materialCache_ = scene->GetOrCreateComponent<MaterialCache2D>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable2D::OnWorldBoundingBoxUpdate()
|
||||
{
|
||||
if (verticesDirty_)
|
||||
@ -298,8 +314,7 @@ void Drawable2D::UpdateMaterial()
|
||||
batches_[0].material_ = material_;
|
||||
else
|
||||
{
|
||||
MaterialCache2D* materialCache = GetSubsystem<MaterialCache2D>();
|
||||
defaultMaterial_ = materialCache->GetMaterial(GetTexture(), blendMode_);
|
||||
defaultMaterial_ = materialCache_->GetMaterial(GetTexture(), blendMode_);
|
||||
batches_[0].material_ = defaultMaterial_;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
namespace Urho3D
|
||||
{
|
||||
|
||||
class DrawableProxy2D;
|
||||
class MaterialCache2D;
|
||||
class VertexBuffer;
|
||||
|
||||
/// Pixel size (equal 0.01f).
|
||||
@ -98,6 +100,8 @@ public:
|
||||
ResourceRef GetMaterialAttr() const;
|
||||
|
||||
protected:
|
||||
/// Handle node being assigned.
|
||||
virtual void OnNodeSet(Node* node);
|
||||
/// Recalculate the world-space bounding box.
|
||||
virtual void OnWorldBoundingBoxUpdate();
|
||||
/// Update vertices.
|
||||
@ -128,7 +132,12 @@ protected:
|
||||
bool geometryDirty_;
|
||||
/// Material update pending flag.
|
||||
bool materialUpdatePending_;
|
||||
/// Default material.
|
||||
SharedPtr<Material> defaultMaterial_;
|
||||
/// Material cache.
|
||||
WeakPtr<MaterialCache2D> materialCache_;
|
||||
/// Drawable proxy.
|
||||
WeakPtr<DrawableProxy2D> drawableProxy_;
|
||||
};
|
||||
|
||||
inline bool CompareDrawable2Ds(Drawable2D* lhs, Drawable2D* rhs)
|
||||
|
193
Source/Engine/Urho2D/DrawableProxy2D.cpp
Normal file
193
Source/Engine/Urho2D/DrawableProxy2D.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
//
|
||||
// Copyright (c) 2008-2014 the Urho3D project.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#include "Precompiled.h"
|
||||
#include "Camera.h"
|
||||
#include "Context.h"
|
||||
#include "Drawable2D.h"
|
||||
#include "DrawableProxy2D.h"
|
||||
#include "Geometry.h"
|
||||
#include "Log.h"
|
||||
#include "Material.h"
|
||||
#include "Node.h"
|
||||
#include "VertexBuffer.h"
|
||||
#include "Sort.h"
|
||||
|
||||
#include "DebugNew.h"
|
||||
|
||||
namespace Urho3D
|
||||
{
|
||||
|
||||
DrawableProxy2D::DrawableProxy2D(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
vertexBuffer_(new VertexBuffer(context_)),
|
||||
orderDirty_(true)
|
||||
{
|
||||
}
|
||||
|
||||
DrawableProxy2D::~DrawableProxy2D()
|
||||
{
|
||||
}
|
||||
|
||||
void DrawableProxy2D::RegisterObject(Context* context)
|
||||
{
|
||||
context->RegisterFactory<DrawableProxy2D>();
|
||||
}
|
||||
|
||||
void DrawableProxy2D::UpdateBatches(const FrameInfo& frame)
|
||||
{
|
||||
unsigned count = materials_.Size();
|
||||
batches_.Resize(count);
|
||||
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
batches_[i].distance_ = 10.0f + (count - i) * 0.001f;
|
||||
batches_[i].material_ = materials_[i];
|
||||
batches_[i].geometry_ = geometries_[i];
|
||||
batches_[i].worldTransform_ = &Matrix3x4::IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableProxy2D::UpdateGeometry(const FrameInfo& frame)
|
||||
{
|
||||
materials_.Clear();
|
||||
|
||||
if (orderDirty_)
|
||||
{
|
||||
Sort(drawables_.Begin(), drawables_.End(), CompareDrawable2Ds);
|
||||
orderDirty_ = false;
|
||||
}
|
||||
|
||||
float timeStep = frame.timeStep_;
|
||||
|
||||
unsigned vertexCount = 0;
|
||||
for (unsigned i = 0; i < drawables_.Size(); ++i)
|
||||
vertexCount += drawables_[i]->GetVertices().Size();
|
||||
|
||||
if (vertexCount == 0)
|
||||
return;
|
||||
|
||||
vertexCount = vertexCount / 4 * 6;
|
||||
|
||||
vertexBuffer_->SetSize(vertexCount, MASK_VERTEX2D);
|
||||
Vertex2D* dest = reinterpret_cast<Vertex2D*>(vertexBuffer_->Lock(0, vertexCount, true));
|
||||
if (dest)
|
||||
{
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
Material* material = 0;
|
||||
|
||||
for (unsigned d = 0; d < drawables_.Size(); ++d)
|
||||
{
|
||||
Material* currMaterial = drawables_[d]->GetUsedMaterial();
|
||||
if (material != currMaterial)
|
||||
{
|
||||
if (material)
|
||||
{
|
||||
AddBatch(material, start, count);
|
||||
start += count;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
material = currMaterial;
|
||||
}
|
||||
|
||||
const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();
|
||||
for (unsigned i = 0; i < vertices.Size(); i += 4)
|
||||
{
|
||||
dest[0] = vertices[i + 0];
|
||||
dest[1] = vertices[i + 1];
|
||||
dest[2] = vertices[i + 2];
|
||||
|
||||
dest[3] = vertices[i + 0];
|
||||
dest[4] = vertices[i + 2];
|
||||
dest[5] = vertices[i + 3];
|
||||
dest += 6;
|
||||
}
|
||||
|
||||
count += vertices.Size() / 4 * 6;
|
||||
}
|
||||
|
||||
if (material)
|
||||
AddBatch(material, start, count);
|
||||
|
||||
vertexBuffer_->Unlock();
|
||||
}
|
||||
else
|
||||
LOGERROR("Failed to lock vertex buffer");
|
||||
}
|
||||
|
||||
UpdateGeometryType DrawableProxy2D::GetUpdateGeometryType()
|
||||
{
|
||||
return UPDATE_WORKER_THREAD;
|
||||
}
|
||||
|
||||
void DrawableProxy2D::AddDrawable(Drawable2D* drawable)
|
||||
{
|
||||
if (!drawable)
|
||||
return;
|
||||
|
||||
if (drawables_.Contains(drawable))
|
||||
return;
|
||||
|
||||
drawables_.Push(drawable);
|
||||
orderDirty_ = true;
|
||||
}
|
||||
|
||||
void DrawableProxy2D::RemoveDrawable(Drawable2D* drawable)
|
||||
{
|
||||
if (!drawable)
|
||||
return;
|
||||
|
||||
drawables_.Remove(drawable);
|
||||
orderDirty_ = true;
|
||||
}
|
||||
|
||||
void DrawableProxy2D::OnWorldBoundingBoxUpdate()
|
||||
{
|
||||
boundingBox_.Clear();
|
||||
|
||||
for (unsigned i = 0; i < drawables_.Size(); ++i)
|
||||
boundingBox_.Merge(drawables_[i]->GetWorldBoundingBox());
|
||||
|
||||
worldBoundingBox_ = boundingBox_;
|
||||
}
|
||||
|
||||
void DrawableProxy2D::AddBatch(Material* material, unsigned vertexStart, unsigned vertexCount)
|
||||
{
|
||||
if (!material)
|
||||
return;
|
||||
|
||||
materials_.Push(SharedPtr<Material>(material));
|
||||
|
||||
unsigned batchSize = materials_.Size();
|
||||
if (geometries_.Size() < batchSize)
|
||||
{
|
||||
SharedPtr<Geometry> geometry(new Geometry(context_));
|
||||
geometry->SetVertexBuffer(0, vertexBuffer_, MASK_VERTEX2D);
|
||||
geometries_.Push(geometry);
|
||||
}
|
||||
|
||||
geometries_[batchSize - 1]->SetDrawRange(TRIANGLE_LIST, 0, 0, vertexStart, vertexCount);
|
||||
}
|
||||
|
||||
}
|
78
Source/Engine/Urho2D/DrawableProxy2D.h
Normal file
78
Source/Engine/Urho2D/DrawableProxy2D.h
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright (c) 2008-2014 the Urho3D project.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Drawable.h"
|
||||
|
||||
namespace Urho3D
|
||||
{
|
||||
|
||||
class Drawable2D;
|
||||
class VertexBuffer;
|
||||
|
||||
/// Proxy for 2D visible components.
|
||||
class URHO3D_API DrawableProxy2D : public Drawable
|
||||
{
|
||||
OBJECT(DrawableProxy2D);
|
||||
|
||||
public:
|
||||
/// Construct.
|
||||
DrawableProxy2D(Context* context);
|
||||
/// Destruct.
|
||||
~DrawableProxy2D();
|
||||
/// Register object factory.
|
||||
static void RegisterObject(Context* context);
|
||||
|
||||
/// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
|
||||
virtual void UpdateBatches(const FrameInfo& frame);
|
||||
/// Prepare geometry for rendering. Called from a worker thread if possible (no GPU update.)
|
||||
virtual void UpdateGeometry(const FrameInfo& frame);
|
||||
/// Return whether a geometry update is necessary, and if it can happen in a worker thread.
|
||||
virtual UpdateGeometryType GetUpdateGeometryType();
|
||||
|
||||
/// Add drawable.
|
||||
void AddDrawable(Drawable2D* drawable);
|
||||
/// Remove drawable.
|
||||
void RemoveDrawable(Drawable2D* drawable);
|
||||
/// Mark order dirty.
|
||||
void MarkOrderDirty() { orderDirty_ = true; }
|
||||
|
||||
protected:
|
||||
/// Recalculate the world-space bounding box.
|
||||
virtual void OnWorldBoundingBoxUpdate();
|
||||
/// Add batch.
|
||||
void AddBatch(Material* material, unsigned vertexStart, unsigned vertexCount);
|
||||
|
||||
/// Vertex buffer.
|
||||
SharedPtr<VertexBuffer> vertexBuffer_;
|
||||
/// Materials.
|
||||
Vector<SharedPtr<Material> > materials_;
|
||||
/// Geometries.
|
||||
Vector<SharedPtr<Geometry> > geometries_;
|
||||
/// Drawables.
|
||||
PODVector<Drawable2D* > drawables_;
|
||||
/// Order dirty.
|
||||
bool orderDirty_;
|
||||
};
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ namespace Urho3D
|
||||
{
|
||||
|
||||
MaterialCache2D::MaterialCache2D(Context* context) :
|
||||
Object(context)
|
||||
Component(context)
|
||||
{
|
||||
}
|
||||
|
||||
@ -41,21 +41,9 @@ MaterialCache2D::~MaterialCache2D()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialCache2D::ReleaseAllMaterials()
|
||||
void MaterialCache2D::RegisterObject(Context* context)
|
||||
{
|
||||
materials_.Clear();
|
||||
}
|
||||
|
||||
void MaterialCache2D::ReleaseMaterial(Texture2D* texture)
|
||||
{
|
||||
materials_.Erase(texture);
|
||||
}
|
||||
|
||||
void MaterialCache2D::ReleaseMaterial(Texture2D* texture, BlendMode blendMode)
|
||||
{
|
||||
HashMap<Texture2D*, HashMap<int, SharedPtr<Material> > >::Iterator i = materials_.Find(texture);
|
||||
if (i != materials_.End())
|
||||
i->second_.Erase(blendMode);
|
||||
context->RegisterFactory<MaterialCache2D>();
|
||||
}
|
||||
|
||||
Material* MaterialCache2D::GetMaterial(Texture2D* texture, BlendMode blendMode)
|
||||
@ -82,7 +70,7 @@ Material* MaterialCache2D::GetMaterial(Texture2D* texture, BlendMode blendMode)
|
||||
Material* MaterialCache2D::CreateMaterial(Texture2D* texture, BlendMode blendMode)
|
||||
{
|
||||
Material* material = new Material(context_);
|
||||
|
||||
|
||||
Technique* tech = new Technique(context_);
|
||||
Pass* pass = tech->CreatePass(PASS_ALPHA);
|
||||
pass->SetBlendMode(blendMode);
|
||||
@ -92,7 +80,7 @@ Material* MaterialCache2D::CreateMaterial(Texture2D* texture, BlendMode blendMod
|
||||
|
||||
pass->SetPixelShader("Basic");
|
||||
pass->SetPixelShaderDefines("DIFFMAP VERTEXCOLOR");
|
||||
|
||||
|
||||
pass->SetDepthWrite(false);
|
||||
|
||||
material->SetTechnique(0, tech);
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Object.h"
|
||||
#include "Component.h"
|
||||
#include "GraphicsDefs.h"
|
||||
|
||||
namespace Urho3D
|
||||
@ -32,7 +32,7 @@ class Texture2D;
|
||||
class Material;
|
||||
|
||||
/// Material cache for 2D.
|
||||
class URHO3D_API MaterialCache2D : public Object
|
||||
class URHO3D_API MaterialCache2D : public Component
|
||||
{
|
||||
OBJECT(MaterialCache2D);
|
||||
|
||||
@ -41,13 +41,8 @@ public:
|
||||
MaterialCache2D(Context* context);
|
||||
/// Destruct.
|
||||
virtual ~MaterialCache2D();
|
||||
|
||||
/// Release all materials.
|
||||
void ReleaseAllMaterials();
|
||||
/// Release material by texture.
|
||||
void ReleaseMaterial(Texture2D* texture);
|
||||
/// Release material by texture and blend mode.
|
||||
void ReleaseMaterial(Texture2D* texture, BlendMode blendMode);
|
||||
/// Register object factory.
|
||||
static void RegisterObject(Context* context);
|
||||
|
||||
/// Return material by texture and blend mode.
|
||||
Material* GetMaterial(Texture2D* texture, BlendMode blendMode);
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "ConstraintWheel2D.h"
|
||||
#include "Context.h"
|
||||
#include "Drawable2D.h"
|
||||
#include "DrawableProxy2D.h"
|
||||
#include "MaterialCache2D.h"
|
||||
#include "ParticleEffect2D.h"
|
||||
#include "ParticleEmitter2D.h"
|
||||
#include "PhysicsWorld2D.h"
|
||||
@ -60,6 +62,9 @@ const char* URHO2D_CATEGORY = "Urho2D";
|
||||
|
||||
void RegisterUrho2DLibrary(Context* context)
|
||||
{
|
||||
MaterialCache2D::RegisterObject(context);
|
||||
DrawableProxy2D::RegisterObject(context);
|
||||
|
||||
// Must register objects from base to derived order
|
||||
Drawable2D::RegisterObject(context);
|
||||
StaticSprite2D::RegisterObject(context);
|
||||
|
Loading…
Reference in New Issue
Block a user