ad5cd7b16a
match the genesis editor version 1.3.1.921.
704 lines
21 KiB
C++
704 lines
21 KiB
C++
/****************************************************************************
|
||
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()
|
||
{
|
||
|
||
if (mVisible)
|
||
{
|
||
_AttachRenderObject();
|
||
};
|
||
Super::OnActivate();
|
||
|
||
}
|
||
|
||
void Mesh2dRenderComponent::OnDeactivate()
|
||
{
|
||
|
||
if (IsActive() && mVisible)
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
Super::OnDeactivate();
|
||
}
|
||
|
||
void Mesh2dRenderComponent::SetVisible(bool bVis)
|
||
{
|
||
if ( bVis == mVisible )
|
||
{
|
||
return;
|
||
}
|
||
mVisible = bVis;
|
||
if (IsActive())
|
||
{
|
||
if (mVisible)
|
||
{
|
||
_AttachRenderObject();
|
||
}
|
||
else
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
}
|
||
}
|
||
|
||
#ifdef __GENESIS_EDITOR__
|
||
void Mesh2dRenderComponent::SetEditorVisible(bool bVis)
|
||
{
|
||
Super::SetEditorVisible(bVis);
|
||
if (IsActive())
|
||
{
|
||
mScreenObject->SetEditorVisible(bVis);
|
||
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void Mesh2dRenderComponent::SetTargetCamera(CameraComponent* camera)
|
||
{
|
||
|
||
if (IsActive() && mVisible)
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
mTargetCamera = camera;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>
|
||
|
||
|
||
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()
|
||
{
|
||
|
||
if (IsActive() && mVisible)
|
||
{
|
||
_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);
|
||
|
||
if (IsActive() && mVisible)
|
||
{
|
||
_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() );
|
||
|
||
if (IsActive() && mVisible)
|
||
{
|
||
_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);
|
||
}
|
||
|
||
}
|