2014-05-05 14:50:33 +08:00
|
|
|
|
/****************************************************************************
|
|
|
|
|
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
|
|
|
|
|
|
|
|
|
http://www.genesis-3d.com.cn
|
|
|
|
|
|
|
|
|
|
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 "stdneb.h"
|
|
|
|
|
#include "graphicfeature/components/mesh2drendercomponent.h"
|
|
|
|
|
#include "graphicfeature/graphicsfeatureprotocol.h"
|
|
|
|
|
#include "graphicfeature/components/screenmeshrenderobject.h"
|
|
|
|
|
#include "graphicfeature/components/apprenderable.h"
|
|
|
|
|
|
|
|
|
|
#include "resource/meshres.h"
|
|
|
|
|
#include "resource/resourceserver.h"
|
|
|
|
|
#include "appframework/actor.h"
|
|
|
|
|
#include "graphicfeature/components/cameracomponent.h"
|
|
|
|
|
|
|
|
|
|
#include "foundation/util/array.h"
|
|
|
|
|
#include "graphicsystem/GraphicSystem.h"
|
|
|
|
|
#include "rendersystem/base/IndexBuffer.h"
|
|
|
|
|
#include "rendersystem/base/VertexBuffer.h"
|
|
|
|
|
#include "rendersystem/base/VertexComponent.h"
|
|
|
|
|
#include "foundation/meshbuilder/parallelogrambuilder.h"
|
|
|
|
|
#include "foundation/meshbuilder/conebuilder.h"
|
|
|
|
|
#include "foundation/meshbuilder/boxbuilder.h"
|
|
|
|
|
|
|
|
|
|
namespace App
|
|
|
|
|
{
|
|
|
|
|
using namespace Resources;
|
|
|
|
|
using namespace Graphic;
|
|
|
|
|
using namespace RenderBase;
|
|
|
|
|
using namespace Math;
|
|
|
|
|
using namespace MeshBuilder;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const float R_Side = 1.0f;
|
|
|
|
|
|
|
|
|
|
static const float3 B_Center(0.0f,0.0f, 0.0f);
|
|
|
|
|
static const float B_Side = 1.0f;
|
|
|
|
|
|
|
|
|
|
static const int C_Tessellation = 12; //tessellation
|
|
|
|
|
static const float C_Radius = 0.5f;
|
|
|
|
|
static const float3 C_Center(0.0f,0.0f, 0.0f);
|
|
|
|
|
static const float C_TopHeight = 1.0f;
|
|
|
|
|
|
|
|
|
|
class _SimpleVertex
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
float3 position; //
|
|
|
|
|
float2 tex_uv;
|
|
|
|
|
float3 normal;
|
|
|
|
|
//Color32 color;
|
|
|
|
|
static const SizeT normal_bias_in_byte = sizeof(float3) + sizeof(float2);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class _SimpleVertex2
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
float3 position; //
|
|
|
|
|
float3 normal;
|
|
|
|
|
static const SizeT normal_bias_in_byte = sizeof(float3);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FillMode _FillModeToGSType(Mesh2dFillMode::_type mode)
|
|
|
|
|
{
|
|
|
|
|
FillMode pm = eFMSOLID;
|
|
|
|
|
switch(mode)
|
|
|
|
|
{
|
|
|
|
|
case Mesh2dFillMode::Point:
|
|
|
|
|
pm = eFMPOINT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Mesh2dFillMode::Line:
|
|
|
|
|
pm = eFMWIREFRAME;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return pm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Vertex>
|
|
|
|
|
inline void _setupVertexIndex(Graphic::VertexBufferData2& vbd2, SizeT vertex_count, Graphic::IndexBufferData2& ibd2, SizeT index_count)
|
|
|
|
|
{
|
|
|
|
|
vbd2.Setup(vertex_count, sizeof(Vertex), RenderBase::BufferData::Static, RenderBase::PrimitiveTopology::TriangleList, true);
|
|
|
|
|
ibd2.Setup(index_count, RenderBase::BufferData::Static, RenderBase::IndexBufferData::Int16, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__ImplementClass(App::Mesh2dRenderComponent, 'M2RC', App::RenderComponent );
|
|
|
|
|
|
|
|
|
|
const float4 Mesh2dRenderComponent::sDefaultColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
const float4 Mesh2dRenderComponent::sDefaultAmbient(0.6f,0.6f,0.6f,1.0f);
|
|
|
|
|
const float4 Mesh2dRenderComponent::sDefaultLightDiffuse(0.4f,0.4f,0.4f,1.0f);
|
|
|
|
|
const float4 Mesh2dRenderComponent::sDefaultLightDir(0.0f, 0.0f, -1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
const Resources::ResourceId Mesh2dRenderComponent::sDefaultShaderID = "sys:simple2d.shader";//sys:
|
|
|
|
|
const Resources::ResourceId Mesh2dRenderComponent::sDefaultMap = "sys:white.jpg";
|
|
|
|
|
const ShaderParamString Mesh2dRenderComponent::sColorName = "_color";
|
|
|
|
|
const ShaderParamString Mesh2dRenderComponent::sAmbientName = "_ambient";
|
|
|
|
|
const ShaderParamString Mesh2dRenderComponent::sLightDiffuseName = "_light_diffuse";
|
|
|
|
|
const ShaderParamString Mesh2dRenderComponent::sLightDirName = "_light_dir";
|
|
|
|
|
const ShaderParamString Mesh2dRenderComponent::sDiffuseMapName = "_diffuseMap";
|
|
|
|
|
|
|
|
|
|
Mesh2dRenderComponent::Mesh2dRenderComponent()
|
|
|
|
|
:mPrimHandle(NULL)
|
|
|
|
|
,mScreenObject()
|
|
|
|
|
,mTargetCamera(NULL)
|
|
|
|
|
,mMeshType(Mesh2dType::Unknown)
|
|
|
|
|
{
|
|
|
|
|
//empty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh2dRenderComponent::~Mesh2dRenderComponent()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void Mesh2dRenderComponent::SetupCallbacks()
|
|
|
|
|
{
|
|
|
|
|
mActor->RegisterComponentCallback(this, MoveAfter);
|
|
|
|
|
mActor->RegisterComponentCallback(this, BeginFrame);
|
|
|
|
|
Super::SetupCallbacks();
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void Mesh2dRenderComponent::SetupAcceptedMessages()
|
|
|
|
|
{
|
|
|
|
|
Super::SetupAcceptedMessages();
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void Mesh2dRenderComponent::HandleMessage(const GPtr<Messaging::Message>& msg)
|
|
|
|
|
{
|
|
|
|
|
n_assert(msg);
|
|
|
|
|
Super::HandleMessage(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::UpdateRenderLayer()
|
|
|
|
|
{
|
|
|
|
|
if (mScreenObject.isvalid())
|
|
|
|
|
{
|
|
|
|
|
mScreenObject->SetLayerID(mActor->GetLayerID());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::OnActivate()
|
2014-06-19 16:21:15 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_AttachRenderObject();
|
|
|
|
|
};
|
|
|
|
|
Super::OnActivate();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::OnDeactivate()
|
|
|
|
|
{
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
if (IsActive() && mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
Super::OnDeactivate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetVisible(bool bVis)
|
|
|
|
|
{
|
2014-06-19 16:21:15 +08:00
|
|
|
|
if ( bVis == mVisible )
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-05-05 14:50:33 +08:00
|
|
|
|
mVisible = bVis;
|
|
|
|
|
if (IsActive())
|
|
|
|
|
{
|
|
|
|
|
if (mVisible)
|
|
|
|
|
{
|
|
|
|
|
_AttachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
#ifdef __GENESIS_EDITOR__
|
|
|
|
|
void Mesh2dRenderComponent::SetEditorVisible(bool bVis)
|
|
|
|
|
{
|
|
|
|
|
Super::SetEditorVisible(bVis);
|
|
|
|
|
if (IsActive())
|
|
|
|
|
{
|
|
|
|
|
mScreenObject->SetEditorVisible(bVis);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-05-05 14:50:33 +08:00
|
|
|
|
void Mesh2dRenderComponent::SetTargetCamera(CameraComponent* camera)
|
|
|
|
|
{
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
if (IsActive() && mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
mTargetCamera = camera;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
|
2014-05-05 14:50:33 +08:00
|
|
|
|
if (IsActive() && mVisible)
|
|
|
|
|
{
|
|
|
|
|
_AttachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void Mesh2dRenderComponent::_OnMoveAfter()
|
|
|
|
|
{
|
|
|
|
|
if(mActor && mScreenObject.isvalid())
|
|
|
|
|
{
|
|
|
|
|
mScreenObject->SetTransform(mActor->GetWorldTransform());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_OnBeginFrame()
|
|
|
|
|
{
|
|
|
|
|
Super::_OnBeginFrame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_AttachRenderObject()
|
|
|
|
|
{
|
|
|
|
|
if (mScreenObject.isvalid())
|
|
|
|
|
{
|
|
|
|
|
if (mTargetCamera)
|
|
|
|
|
{
|
|
|
|
|
mScreenObject->AttachNoCull((mTargetCamera->GetCameraObject().get())->GetCameraScene());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
n_assert(mActor);
|
|
|
|
|
mScreenObject->AttachNoCull(mActor->GetRenderScene());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_DeattachRenderObject()
|
|
|
|
|
{
|
|
|
|
|
if (mScreenObject.isvalid())
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
mScreenObject->Detach();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_BuildRenderable(const _Mesh2dInfo& info, const GPtr<Resources::MeshRes>& meshRes, IndexT index)
|
|
|
|
|
{
|
|
|
|
|
SubMesh* subMesh = meshRes->GetSubMesh(index);
|
|
|
|
|
n_assert(subMesh);
|
|
|
|
|
RenderObjectType::RenderableType* renderable = mRenderableResUnitList[index].ResetRenderable<RenderObjectType::RenderableType>();
|
|
|
|
|
renderable->SetRenderInfo(
|
|
|
|
|
subMesh->firstVertex,
|
|
|
|
|
subMesh->numVertex,
|
|
|
|
|
subMesh->FirstIndex,
|
|
|
|
|
subMesh->numIndex);
|
|
|
|
|
renderable->GetMaterial()->SetRenderQueue(_getRenderQueue(info));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_BuildSimpleRenderable(const _Mesh2dInfo& info, SizeT vertexCount, SizeT indexCount)
|
|
|
|
|
{
|
|
|
|
|
RenderObjectType::RenderableType* renderable = mRenderableResUnitList[0].ResetRenderable<RenderObjectType::RenderableType>();
|
|
|
|
|
renderable->SetRenderInfo(
|
|
|
|
|
0,
|
|
|
|
|
vertexCount,
|
|
|
|
|
0,
|
|
|
|
|
indexCount);
|
|
|
|
|
|
|
|
|
|
renderable->GetMaterial()->SetRenderQueue(_getRenderQueue(info));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetActorTransform(GPtr<Actor>& actor, const Math::float2& pos, const Math::float3& scales)
|
|
|
|
|
{
|
|
|
|
|
n_assert(actor.isvalid());
|
|
|
|
|
matrix44 mat = matrix44::identity();
|
|
|
|
|
mat.mx[0][0] = scales.x();
|
|
|
|
|
mat.mx[1][1] = scales.y();
|
|
|
|
|
mat.mx[2][2] = scales.z();
|
|
|
|
|
|
|
|
|
|
mat.mx[0][3] = pos.x();
|
|
|
|
|
mat.mx[1][3] = -pos.y();
|
|
|
|
|
actor->SetTransform(mat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetActorTransform(GPtr<Actor>& actor, const Math::float2& pos, const Math::float3& scales, const Math::float4& axis, float angle)
|
|
|
|
|
{
|
|
|
|
|
n_assert(actor.isvalid());
|
|
|
|
|
|
|
|
|
|
matrix44 mat = matrix44::rotationaxis(axis, angle);
|
|
|
|
|
mat.scale(float4(scales.x(), scales.y(), scales.z(), 1.0f));
|
|
|
|
|
|
|
|
|
|
mat.mx[0][3] = pos.x();
|
|
|
|
|
mat.mx[1][3] = -pos.y();
|
|
|
|
|
mat.mx[2][3] = 0.0f;
|
|
|
|
|
mat.mx[3][3] = 1.0f;
|
|
|
|
|
actor->SetTransform(mat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::ChangeRenderInfo(int subMesh, const Mesh2dRenderInfo& info)
|
|
|
|
|
{
|
|
|
|
|
if (subMesh < mRenderableResUnitList.Size())
|
|
|
|
|
{
|
|
|
|
|
const Graphic::Renderable* renderable = mRenderableResUnitList[subMesh].GetRenderable();
|
|
|
|
|
GPtr<RenderBase::RenderStateDesc>& desc = renderable->GetMaterial()->GetTech()->GetDefaultPass()->GetRenderStateObject();
|
|
|
|
|
_setRenderState(desc, info, mMeshType);
|
|
|
|
|
|
|
|
|
|
renderable->GetMaterial()->SetRenderQueue(_getRenderQueue(info));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_resetRenderStateObj(const GPtr<Graphic::MaterialInstance>& material, const _Mesh2dInfo& info)
|
|
|
|
|
{
|
|
|
|
|
GPtr<RenderBase::RenderStateDesc>& desc = material->GetTech()->GetDefaultPass()->GetRenderStateObject();
|
|
|
|
|
_setRenderState(desc, info, mMeshType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_resetRenderStateObjs(const _Mesh2dInfo& info)
|
|
|
|
|
{
|
|
|
|
|
int index = 0;
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
const GPtr<Graphic::MaterialInstance>& material = GetMaterial(index);
|
|
|
|
|
if (material == Graphic::MaterialInstance::NullMaterial)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_resetRenderStateObj(material, info);
|
|
|
|
|
++index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::OnDestroy()
|
|
|
|
|
{
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
if (IsActive() && mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
mRenderableResUnitList.Clear();
|
|
|
|
|
if (NULL != mPrimHandle)
|
|
|
|
|
{
|
|
|
|
|
if (Mesh2dType::Custom != mMeshType)
|
|
|
|
|
{
|
|
|
|
|
GraphicSystem::Instance()->RemovePrimitive(mPrimHandle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mPrimHandle = RenderBase::PrimitiveHandle();
|
|
|
|
|
}
|
|
|
|
|
//mPrimGroup = NULL;
|
|
|
|
|
|
|
|
|
|
Super::OnDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetSimpleMesh(const _Mesh2dInfo& meshInfo)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (Mesh2dType::Custom == meshInfo.mMeshType)
|
|
|
|
|
{
|
|
|
|
|
_buildCustomMesh(meshInfo, sDefaultMap);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_buildSimpleMesh(meshInfo, sDefaultMap);
|
|
|
|
|
}
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>RenderObject
|
|
|
|
|
mScreenObject = ScreenMeshRenderObject::Create();
|
|
|
|
|
mScreenObject->SetOwner(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetMesh2dParam(
|
|
|
|
|
int index,
|
|
|
|
|
const Math::float4& color,
|
|
|
|
|
const Math::float4& ambient /* = sDefaultAmbient */,
|
|
|
|
|
const Math::float4& lightDiffuse /* = sDefaultLightDiffuse */,
|
|
|
|
|
const Math::float4& lightDir /* = sDefaultLightDir */)
|
|
|
|
|
{
|
|
|
|
|
//int index = 0;
|
|
|
|
|
int count = mRenderableResUnitList.Size();
|
|
|
|
|
if (index >= 0 && index < count)
|
|
|
|
|
{
|
|
|
|
|
float4 dir = -lightDir;
|
|
|
|
|
dir.set_w(0);
|
|
|
|
|
SetShaderConstantParam(index, sColorName, color);
|
|
|
|
|
SetShaderConstantParam(index, sAmbientName, ambient);
|
|
|
|
|
SetShaderConstantParam(index, sLightDiffuseName, lightDiffuse);
|
|
|
|
|
SetShaderConstantParam(index, sLightDirName, dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::SetSimpleMeshTex(const Resources::ResourceId& texID)
|
|
|
|
|
{
|
|
|
|
|
SetTexture(0, sDiffuseMapName, texID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_buildSimpleMesh(const _Mesh2dInfo& meshInfo, const Resources::ResourceId& texID)
|
|
|
|
|
{
|
|
|
|
|
n_assert(Mesh2dType::Custom != meshInfo.mMeshType);
|
|
|
|
|
OnDestroy();
|
|
|
|
|
SizeT vertexCount = 0;
|
|
|
|
|
SizeT indexCount = 0;
|
|
|
|
|
switch(meshInfo.mMeshType)
|
|
|
|
|
{
|
|
|
|
|
case Mesh2dType::Rectangle:
|
|
|
|
|
{
|
|
|
|
|
mPrimHandle = _createRectangle(meshInfo.mTransform, vertexCount, indexCount);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Mesh2dType::Box:
|
|
|
|
|
{
|
|
|
|
|
mPrimHandle = _createBox(meshInfo.mTransform, vertexCount, indexCount);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Mesh2dType::Cone:
|
|
|
|
|
{
|
|
|
|
|
ConeInfo* cone = (ConeInfo*)&meshInfo;
|
|
|
|
|
mPrimHandle = _createCone(cone->mTessellation, meshInfo.mTransform, vertexCount, indexCount);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
n_error("Unsupport Mesh2dType:%d", (int)meshInfo.mMeshType);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
mMeshType = meshInfo.mMeshType;
|
|
|
|
|
SetMaterialByShaderID(0, sDefaultShaderID, false);
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
if (IsActive() && mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// simple meshֻ<68><D6BB>һ<EFBFBD><D2BB>renderable<6C><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰһ<C7B0><D2BB>mesh<73>ж<EFBFBD><D0B6><EFBFBD>renderalbe<62><65><EFBFBD><EFBFBD>ôҪ<C3B4>Ѷ<EFBFBD><D1B6><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>
|
|
|
|
|
for(int i = mRenderableResUnitList.Size() - 1; i > 1; --i)
|
|
|
|
|
{
|
|
|
|
|
mRenderableResUnitList.EraseIndex(i);
|
|
|
|
|
}
|
|
|
|
|
_BuildSimpleRenderable(meshInfo, vertexCount, indexCount);
|
|
|
|
|
_resetRenderStateObjs(meshInfo);
|
|
|
|
|
SetTexture(0, sDiffuseMapName, texID, 1);
|
|
|
|
|
SetMesh2dParam(0, sDefaultColor, sDefaultAmbient, sDefaultLightDiffuse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_buildCustomMesh(const _Mesh2dInfo& meshInfo, const Resources::ResourceId& texID)
|
|
|
|
|
{
|
|
|
|
|
n_assert(Mesh2dType::Custom == meshInfo.mMeshType);
|
|
|
|
|
CustomInfo* custom = (CustomInfo*)&meshInfo;
|
|
|
|
|
OnDestroy();
|
|
|
|
|
|
|
|
|
|
mPrimitiveResInfo = ResourceManager::Instance()->CreatePrimitiveInfo(custom->mID ,0);
|
|
|
|
|
mMeshType = meshInfo.mMeshType;
|
|
|
|
|
//SetShaderID(0, sDefaultShaderID);
|
|
|
|
|
|
|
|
|
|
n_assert( GraphicSystem::HasInstance() );
|
2014-06-19 16:21:15 +08:00
|
|
|
|
|
|
|
|
|
if (IsActive() && mVisible)
|
2014-05-05 14:50:33 +08:00
|
|
|
|
{
|
|
|
|
|
_DeattachRenderObject();
|
|
|
|
|
}
|
|
|
|
|
mRenderableResUnitList.Clear();
|
|
|
|
|
|
|
|
|
|
const GPtr<MeshRes>& meshRes = mPrimitiveResInfo->GetRes().downcast<MeshRes>();
|
|
|
|
|
mPrimHandle = mPrimitiveResInfo->GetHandle();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>renderable
|
|
|
|
|
int sub_count = meshRes->GetSubMeshCount();
|
|
|
|
|
for ( IndexT index = 0; index < sub_count; ++index )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
SetMaterialByShaderID(index, sDefaultShaderID, false);
|
|
|
|
|
_BuildRenderable(meshInfo, meshRes, index);
|
|
|
|
|
SetMesh2dParam(index, sDefaultColor, sDefaultAmbient, sDefaultLightDiffuse);
|
|
|
|
|
}
|
|
|
|
|
_resetRenderStateObjs(meshInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PrimitiveHandle Mesh2dRenderComponent::_createRectangle(const Math::matrix44* transform, SizeT& vertexCount, SizeT& indexCount)
|
|
|
|
|
{
|
|
|
|
|
vertexCount = RECT_VERTEX_COUNT;
|
|
|
|
|
indexCount = RECT_INDICES_COUNT;
|
|
|
|
|
Graphic::VertexBufferData2 vbd2;
|
|
|
|
|
Graphic::IndexBufferData2 ibd2;
|
|
|
|
|
_setupVertexIndex<_SimpleVertex>(vbd2, RECT_VERTEX_COUNT, ibd2, RECT_INDICES_COUNT);
|
|
|
|
|
|
|
|
|
|
_SimpleVertex* vertices = vbd2.GetBufferPtr<_SimpleVertex>();//_SimpleVertex vertices[RECT_VERTEX_COUNT];
|
|
|
|
|
float hRS = R_Side * 0.5f;
|
|
|
|
|
float3 top(0.0f, hRS, 0.0f);
|
|
|
|
|
float3 right(hRS, 0.0f, 0.0f);
|
|
|
|
|
float3 center(0.0f, 0.0f, 0.0f);
|
|
|
|
|
MeshBuilder::ParallelogramBuilder::Set(vertices, top, right, center, 0, _SimpleVertex::normal_bias_in_byte);
|
|
|
|
|
|
|
|
|
|
//RectBuilder::SetPositions(vertices, sizeof(_SimpleVertex), R_Side, R_Side);
|
|
|
|
|
|
|
|
|
|
//RectBuilder::SetNormals(vertices, sizeof(_SimpleVertex), _SimpleVertex::normal_bias_in_byte);
|
|
|
|
|
|
|
|
|
|
if (transform)
|
|
|
|
|
{
|
|
|
|
|
MeshBuilder::TransformPositions(vertices, RECT_VERTEX_COUNT, sizeof(_SimpleVertex), 0, *transform);
|
|
|
|
|
MeshBuilder::TransformNormals(vertices, RECT_VERTEX_COUNT, sizeof(_SimpleVertex), _SimpleVertex::normal_bias_in_byte, *transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vertices[0].tex_uv = float2(0.0f, 0.0f);
|
|
|
|
|
vertices[1].tex_uv = float2(1.0f, 0.0f);
|
|
|
|
|
vertices[2].tex_uv = float2(0.0f, 1.0f);
|
|
|
|
|
vertices[3].tex_uv = float2(1.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort* indices = ibd2.GetBufferPtr<ushort>();//ushort indices[RECT_INDICES_COUNT];
|
|
|
|
|
ParallelogramBuilder::SetIndices(indices);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Util::Array<VertexComponent>& vertexComponents = vbd2.GetVertexComponents();//Util::Array<VertexComponent> vertexComponents;
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Position,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::TexCoord,0, RenderBase::VertexComponent::Float2));
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Normal,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
|
|
|
|
|
return Graphic::GraphicSystem::Instance()->CreatePrimitiveHandle(&vbd2, &ibd2);
|
|
|
|
|
//return _buildMeshInfo(vertices, vertexComponents,RECT_VERTEX_COUNT, indices, RECT_INDICES_COUNT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PrimitiveHandle Mesh2dRenderComponent::_createBox(const Math::matrix44* transform, SizeT& vertexCount, SizeT& indexCount)
|
|
|
|
|
{
|
|
|
|
|
vertexCount = BOX_VERTEX_COUNT;
|
|
|
|
|
indexCount = BOX_INDICES_COUNT;
|
|
|
|
|
Graphic::VertexBufferData2 vbd2;
|
|
|
|
|
Graphic::IndexBufferData2 ibd2;
|
|
|
|
|
_setupVertexIndex<_SimpleVertex2>(vbd2, BOX_VERTEX_COUNT, ibd2, BOX_INDICES_COUNT);
|
|
|
|
|
|
|
|
|
|
_SimpleVertex2* vertices = vbd2.GetBufferPtr<_SimpleVertex2>();//_SimpleVertex2 vertices[BOX_VERTEX_COUNT];
|
|
|
|
|
|
|
|
|
|
BoxBuilder::SetPositions(vertices, sizeof(_SimpleVertex2), 0, B_Side, B_Side, B_Side, B_Center);
|
|
|
|
|
BoxBuilder::SetNormals(vertices, sizeof(_SimpleVertex2), _SimpleVertex2::normal_bias_in_byte,
|
|
|
|
|
vertices, sizeof(_SimpleVertex2), 0);
|
|
|
|
|
|
|
|
|
|
if (transform)
|
|
|
|
|
{
|
|
|
|
|
MeshBuilder::TransformPositions(vertices, BOX_VERTEX_COUNT, sizeof(_SimpleVertex2), 0, *transform);
|
|
|
|
|
MeshBuilder::TransformNormals(vertices, BOX_VERTEX_COUNT, sizeof(_SimpleVertex2), _SimpleVertex2::normal_bias_in_byte, *transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ushort* indices = ibd2.GetBufferPtr<ushort>();//ushort indices[BOX_INDICES_COUNT];
|
|
|
|
|
BoxBuilder::SetIndices(indices);
|
|
|
|
|
|
|
|
|
|
Util::Array<VertexComponent>& vertexComponents = vbd2.GetVertexComponents();//static Util::Array<VertexComponent> vertexComponents;
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Position,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Normal,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
|
|
|
|
|
return Graphic::GraphicSystem::Instance()->CreatePrimitiveHandle(&vbd2, &ibd2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PrimitiveHandle Mesh2dRenderComponent::_createCone(int tessellation, const Math::matrix44* transform, SizeT& vertexCount, SizeT& indexCount)
|
|
|
|
|
{
|
|
|
|
|
int vertex_count = ConeBuilder::VertexCount(tessellation);
|
|
|
|
|
int index_count = ConeBuilder::IndexCount(tessellation);
|
|
|
|
|
vertexCount = vertex_count;
|
|
|
|
|
indexCount = index_count;
|
|
|
|
|
|
|
|
|
|
Graphic::VertexBufferData2 vbd2;
|
|
|
|
|
Graphic::IndexBufferData2 ibd2;
|
|
|
|
|
_setupVertexIndex<_SimpleVertex2>(vbd2, vertex_count, ibd2, index_count);
|
|
|
|
|
|
|
|
|
|
_SimpleVertex2* vertices = vbd2.GetBufferPtr<_SimpleVertex2>();//Util::FixedArray<_SimpleVertex2> vertices(vertex_count);
|
|
|
|
|
|
|
|
|
|
ConeBuilder::SetPositions(vertices, sizeof(_SimpleVertex2), 0, tessellation, C_Radius, C_TopHeight, C_Center);
|
|
|
|
|
ConeBuilder::SetNormals(vertices, sizeof(_SimpleVertex2), _SimpleVertex2::normal_bias_in_byte, tessellation,
|
|
|
|
|
vertices, sizeof(_SimpleVertex2), 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transform)
|
|
|
|
|
{
|
|
|
|
|
MeshBuilder::TransformPositions(vertices, vertex_count, sizeof(_SimpleVertex2), 0, *transform);
|
|
|
|
|
MeshBuilder::TransformNormals(vertices, vertex_count, sizeof(_SimpleVertex2), _SimpleVertex2::normal_bias_in_byte, *transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ushort* indices = ibd2.GetBufferPtr<ushort>();//Util::FixedArray<ushort> indices(index_count);
|
|
|
|
|
ConeBuilder::SetIndices(indices, tessellation);
|
|
|
|
|
Util::Array<VertexComponent>& vertexComponents = vbd2.GetVertexComponents();//Util::Array<VertexComponent> vertexComponents;
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Position,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
vertexComponents.Append(RenderBase::VertexComponent(RenderBase::VertexComponent::Normal,0, RenderBase::VertexComponent::Float3));
|
|
|
|
|
return Graphic::GraphicSystem::Instance()->CreatePrimitiveHandle(&vbd2, &ibd2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const SizeT Alpha_Mask = 2;
|
|
|
|
|
static const SizeT Add_Mask = 1;
|
|
|
|
|
static const SizeT NoZTest_Mask = 1<<2;
|
|
|
|
|
|
|
|
|
|
Graphic::RenderQueue Mesh2dRenderComponent::_getRenderQueue(const Mesh2dRenderInfo& info)
|
|
|
|
|
{
|
|
|
|
|
SizeT forSort = 0;
|
|
|
|
|
if (!info.mZTest)
|
|
|
|
|
{
|
|
|
|
|
forSort += NoZTest_Mask;
|
|
|
|
|
}
|
|
|
|
|
switch (info.mBlendMode)
|
|
|
|
|
{
|
|
|
|
|
case Mesh2dBlendMode::Alpha:
|
|
|
|
|
{
|
|
|
|
|
forSort += Alpha_Mask;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Mesh2dBlendMode::Add:
|
|
|
|
|
{
|
|
|
|
|
forSort += Add_Mask;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return Graphic::RenderQueue(Graphic::RenderQueue::eRQTScreen, forSort);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//struct Mesh2dRenderableSort : public std::binary_function<const GPtr<Renderable>&, const GPtr<Renderable>&, std::size_t>
|
|
|
|
|
//{
|
|
|
|
|
// bool operator() (const GPtr<Renderable>& lhs, const GPtr<Renderable>& rhs) const
|
|
|
|
|
// {
|
|
|
|
|
// const GPtr<Mesh2dRenderable>& l2d = lhs.downcast<Mesh2dRenderable>();
|
|
|
|
|
// const GPtr<Mesh2dRenderable>& r2d = rhs.downcast<Mesh2dRenderable>();
|
|
|
|
|
|
|
|
|
|
// return l2d->GetSort() < r2d->GetSort();
|
|
|
|
|
// }
|
|
|
|
|
//};
|
|
|
|
|
|
|
|
|
|
//void Mesh2dRenderComponent::_sortMesh2dRenderable()
|
|
|
|
|
//{
|
|
|
|
|
// GraphicSystem* gs = GraphicSystem::Instance();
|
|
|
|
|
// n_assert(gs);
|
|
|
|
|
// Util::Array<GPtr<Renderable>>& mesh2d_list = gs->GetRenderable2dList();
|
|
|
|
|
// Util::CustomSortArray<GPtr<Renderable>, Mesh2dRenderableSort>(mesh2d_list);
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_setBlendState(DeviceBlendState& state, Mesh2dBlendMode::_type mode)
|
|
|
|
|
{
|
|
|
|
|
switch(mode)
|
|
|
|
|
{
|
|
|
|
|
case Mesh2dBlendMode::Alpha:
|
|
|
|
|
{
|
|
|
|
|
state.m_alphaBlendEnable[0] = true;
|
|
|
|
|
state.m_srcBlendAlpha[0] = eBFSRCALPHA;
|
|
|
|
|
state.m_destBlendAlpha[0] = eBFINVSRCALPHA;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Mesh2dBlendMode::Add:
|
|
|
|
|
{
|
|
|
|
|
state.m_alphaBlendEnable[0] = true;
|
|
|
|
|
state.m_srcBlendAlpha[0] = eBFSRCALPHA;
|
|
|
|
|
state.m_destBlendAlpha[0] = eBFONE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Mesh2dBlendMode::Opacity:
|
|
|
|
|
{
|
|
|
|
|
state.m_alphaBlendEnable[0] = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Mesh2dRenderComponent::_setRenderState(GPtr<RenderBase::RenderStateDesc>& state, const Mesh2dRenderInfo& info, Mesh2dType::_type meshType)
|
|
|
|
|
{
|
|
|
|
|
DeviceRasterizerState rasterizerState = state->GetRasterizerState();
|
|
|
|
|
DeviceBlendState blendState = state->GetBlendState();
|
|
|
|
|
DeviceDepthAndStencilState depthState = state->GetDepthAndStencilState();
|
|
|
|
|
|
|
|
|
|
rasterizerState.m_fillMode = _FillModeToGSType(info.mFillMode);
|
|
|
|
|
_setBlendState(blendState, info.mBlendMode);
|
|
|
|
|
depthState.m_depthEnable = info.mZTest;
|
|
|
|
|
|
|
|
|
|
if (Mesh2dType::Rectangle == meshType || Mesh2dBlendMode::Add == info.mBlendMode)
|
|
|
|
|
{
|
|
|
|
|
rasterizerState.m_cullMode = RenderBase::eCMNONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state->SetRasterizerState(rasterizerState);
|
|
|
|
|
state->SetBlendState(blendState);
|
|
|
|
|
state->SetDepthAndStencilState(depthState);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|