6e8fbca745
match the genesis editor version 1.3.0.653.
342 lines
12 KiB
C++
342 lines
12 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 "VegetationRenderObject.h"
|
||
#include "vegetation/VegetationObejct.h"
|
||
#include "graphicsystem/Camera/RenderPipeline/RenderData.h"
|
||
#include "graphicsystem/Material/Material.h"
|
||
#include "graphicsystem/GraphicSystem.h"
|
||
#include "graphicsystem/Renderable/GraphicRenderer.h"
|
||
#include "graphicsystem/Material/materialinstance.h"
|
||
#include "shadercompiler/ShaderMarcro.h"
|
||
#include "graphicsystem/Vision/RenderScene.h"
|
||
namespace Vegetation
|
||
{
|
||
__ImplementClass(VegetationRenderObject,'VROB',Graphic::RenderObject)
|
||
|
||
using namespace Graphic;
|
||
VegetationRenderObject::VegetationRenderObject()
|
||
{
|
||
|
||
}
|
||
VegetationRenderObject::~VegetationRenderObject()
|
||
{
|
||
|
||
}
|
||
void VegetationRenderObject::AddToCollection(Graphic::RenderDataCollection* collection, const Graphic::RenderConfig* renderConfig)
|
||
{
|
||
const Graphic::RenderableResUnitArray& list = mOwner->GetResUnits();
|
||
Graphic::RenderableResUnitArray::Iterator begin = list.Begin();
|
||
Graphic::RenderableResUnitArray::Iterator end = list.End();
|
||
while(begin != end)
|
||
{
|
||
if (begin->Complete())
|
||
{
|
||
Graphic::Renderable* pRenderable = begin->GetRenderable();
|
||
SetShaderMask(pRenderable);
|
||
collection->Push(pRenderable);
|
||
}
|
||
++begin;
|
||
}
|
||
}
|
||
|
||
void VegetationRenderObject::Render(const Renderable* renderable, RenderPassType passType, const Material* customizedMaterial)
|
||
{
|
||
n_assert(renderable);
|
||
const RenderableType* grassRenderable = renderable->cast_fast<const RenderableType>();
|
||
switch(mOwner->GetRenderType())
|
||
{
|
||
case eRT_Grass:
|
||
_RenderGrass(grassRenderable, passType, customizedMaterial);
|
||
break;
|
||
case eRT_DetailMesh:
|
||
case eRT_Tree:
|
||
_RenderTree(grassRenderable, passType, customizedMaterial);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void VegetationRenderObject::_RenderTree(const RenderableType* renderable, RenderPassType passType, const Material* customizedMaterial)
|
||
{
|
||
// TODO : if renderable submesh is 0, render the bole, 1 is leaves pieces
|
||
|
||
if (mOwner->GetPrimHandle().IsValid())
|
||
{
|
||
GlobalMaterialParam* pGMP = Material::GetGlobalMaterialParams();
|
||
|
||
//TODO::
|
||
//camera cull
|
||
const Math::matrix44* camera = &(Graphic::GraphicSystem::Instance()->GetRenderingCamera()->GetTransform());
|
||
GPtr<Vegetation::VegeInstanceMap> pInstMap = mOwner->GetInstanceMap();
|
||
if ( !pInstMap.isvalid())
|
||
return;
|
||
|
||
Math::vector objscale = mOwner->GetScale();
|
||
Math::quaternion objrot = mOwner->GetRotation();
|
||
|
||
Math::scalar fCullDistance = mOwner->GetCullDistance();
|
||
|
||
SizeT nInstCount = pInstMap->GetInstanceCount();
|
||
for (SizeT i = 0; i < nInstCount; ++i)
|
||
{
|
||
INSTANCEDATA_POS* tmpInst = pInstMap->GetInstance(i);
|
||
|
||
Math::float4 _pos(tmpInst->pos.x(),tmpInst->pos.y(), tmpInst->pos.z(), 1);
|
||
|
||
Math::float4 fDistance = camera->get_position() - _pos;
|
||
|
||
// while in the visual range , draw a single Tree
|
||
if ( fDistance.length() < fCullDistance )
|
||
{
|
||
|
||
Math::quaternion _quat = Math::quaternion::rotationyawpitchroll( tmpInst->rotate.y() * N_PI / 180 , tmpInst->rotate.x()* N_PI / 180, tmpInst->rotate.z()* N_PI / 180);
|
||
_quat = Math::quaternion::multiply(_quat,objrot);
|
||
Math::float4 _scale = Math::float4(tmpInst->scale.x() * objscale.x(), tmpInst->scale.y()* objscale.y(), tmpInst->scale.z()* objscale.z(), 0);
|
||
Math::matrix44 _mat = Math::matrix44::transformation( _scale, _quat, _pos );
|
||
|
||
|
||
Math::float4 tempRegst = Math::float4(tmpInst->color, tmpInst->wave, 0, 0);
|
||
int startIndex = 13;
|
||
GraphicSystem::Instance()->SetVertexShaderConstantVectorF(startIndex, &tempRegst, 1);
|
||
|
||
const Graphic::Camera* pCamera = Graphic::GraphicSystem::Instance()->GetRenderingCamera();
|
||
|
||
Math::matrix44 mvp = Math::matrix44::multiply(pCamera->GetViewProjTransform(), _mat);
|
||
pGMP->SetMatrixParam(eGShaderMatMVP, mvp);
|
||
pGMP->SetMatrixParam(eGShaderMatM, _mat);
|
||
|
||
Math::matrix44 Inverse, InvTranspose;
|
||
Inverse = Math::matrix44::inverse(_mat);
|
||
InvTranspose = Math::matrix44::transpose(Inverse);
|
||
|
||
pGMP->SetMatrixParam(eGShaderMatInverseM,Inverse);
|
||
pGMP->SetMatrixParam(eGShaderMatInverseTransposeM,InvTranspose);
|
||
|
||
_Render(renderable, passType,//mat, passType,
|
||
mOwner->GetPrimHandle(),
|
||
renderable->GetFirstVertix(),
|
||
renderable->GetNumVertex(),
|
||
renderable->GetFirstIndex(),
|
||
renderable->GetNumIndex(),
|
||
customizedMaterial);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
void VegetationRenderObject::_RenderGrass(const RenderableType* renderable, Graphic::RenderPassType passType, const Graphic::Material* customizedMaterial)
|
||
{
|
||
|
||
if (mOwner->GetPrimHandle().IsValid())
|
||
{
|
||
GlobalMaterialParam* pGMP = Material::GetGlobalMaterialParams();
|
||
|
||
//TODO::
|
||
//camera cull
|
||
const Camera* renderingCamera = Graphic::GraphicSystem::Instance()->GetRenderingCamera();
|
||
const Math::matrix44* camera = &(renderingCamera->GetTransform());
|
||
Math::vector objscale = mOwner->GetScale();
|
||
Math::quaternion objrot = mOwner->GetRotation();
|
||
|
||
GPtr<Vegetation::VegeInstanceMap>& pInstMap = mOwner->GetInstanceMap();
|
||
|
||
if ( !pInstMap.isvalid())
|
||
return;
|
||
|
||
Math::scalar fCullDistance = mOwner->GetCullDistance();
|
||
|
||
if ( pInstMap->IsHWInstancing() )
|
||
{
|
||
n_assert(0);
|
||
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
SizeT nTotalCount = pInstMap->GetInstanceCount();
|
||
SizeT nVisualIndex = 0;
|
||
Util::Array<Math::matrix44> grassMatArray;
|
||
|
||
for (SizeT i = 0; i < nTotalCount; ++i)
|
||
{
|
||
|
||
INSTANCEDATA_POS* tmpInst = pInstMap->GetInstance(i);
|
||
|
||
Math::float4 _pos(tmpInst->pos.x(), tmpInst->pos.y(), tmpInst->pos.z(),1);
|
||
|
||
Math::float4 fDistance = camera->get_position() - _pos;
|
||
//max value 1000f, should be set outside
|
||
if ( fDistance.length() < fCullDistance )
|
||
{
|
||
Math::quaternion _quat = Math::quaternion::rotationyawpitchroll( tmpInst->rotate.y()* N_PI / 180 , tmpInst->rotate.x()* N_PI / 180, tmpInst->rotate.z()* N_PI / 180);
|
||
Math::float4 _scale = Math::float4(tmpInst->scale.x() , tmpInst->scale.y() , tmpInst->scale.z() , 0);
|
||
Math::matrix44 _mat = Math::matrix44::transformation( _scale, _quat, _pos );
|
||
|
||
if (customizedMaterial)
|
||
{
|
||
//TODO: while WireFrame mode : need to calculate the Matrix at here ,because the shader will has not the calculation step
|
||
const Graphic::Camera* pCamera = Graphic::GraphicSystem::Instance()->GetRenderingCamera();
|
||
Math::matrix44 mvp = Math::matrix44::multiply(pCamera->GetViewProjTransform(), _mat);
|
||
pGMP->SetMatrixParam(eGShaderMatMVP, mvp);
|
||
pGMP->SetMatrixParam(eGShaderMatM, _mat);
|
||
|
||
_Render(renderable, passType,
|
||
mOwner->GetPrimHandle(),
|
||
renderable->GetFirstVertix(),
|
||
renderable->GetNumVertex(),
|
||
renderable->GetFirstIndex(),
|
||
renderable->GetNumIndex(),
|
||
customizedMaterial);
|
||
}
|
||
else
|
||
{
|
||
float4 tfloat4 = _mat.getrow3();
|
||
tfloat4.x() = tmpInst->color;
|
||
tfloat4.y() = tmpInst->wave;
|
||
tfloat4.z() = _scale.y();
|
||
_mat.setrow3(tfloat4);
|
||
grassMatArray.Append(_mat);
|
||
}
|
||
++nVisualIndex;
|
||
}
|
||
|
||
}
|
||
|
||
if (customizedMaterial)
|
||
return;
|
||
|
||
bool meshRT = (eRT_DetailMesh == mOwner->GetRenderType());
|
||
SizeT vertLimitCount = pInstMap->GetVertLimitCount();
|
||
SizeT nremainingInst = nVisualIndex;
|
||
while ( nremainingInst > 0 )
|
||
{
|
||
SizeT nRenderIndicesCount = Math::n_min(nremainingInst, g_nNumBatchInstance);
|
||
if (meshRT)
|
||
nRenderIndicesCount = Math::n_min(nRenderIndicesCount, vertLimitCount);
|
||
|
||
|
||
SizeT nRenderVertInst = Math::n_min(nremainingInst, vertLimitCount);
|
||
nRenderVertInst = Math::n_min(nRenderVertInst, nRenderIndicesCount);
|
||
|
||
SizeT nbegin = nVisualIndex - nremainingInst;
|
||
|
||
//TODO : DrawPrimitive
|
||
if ( grassMatArray.Size() > 0 )
|
||
{
|
||
int startIndex = 0;
|
||
if (meshRT)
|
||
startIndex = 12;
|
||
else
|
||
startIndex = 12;
|
||
GraphicSystem::Instance()->SetVertexShaderConstantMatrixF(startIndex, &grassMatArray[nbegin], nRenderIndicesCount);
|
||
}
|
||
|
||
const Graphic::Camera* pCamera = Graphic::GraphicSystem::Instance()->GetRenderingCamera();
|
||
|
||
Math::matrix44 mvp = Math::matrix44::multiply(pCamera->GetViewProjTransform(), matrix44::identity());
|
||
pGMP->SetMatrixParam(eGShaderMatMVP, mvp);
|
||
|
||
pGMP->SetMatrixParam(eGShaderMatM, matrix44::identity());
|
||
|
||
_Render(renderable, passType,//mat, passType,
|
||
mOwner->GetPrimHandle(),
|
||
renderable->GetFirstVertix(),
|
||
nRenderVertInst * renderable->GetNumVertex(),
|
||
nbegin * renderable->GetNumIndex(),
|
||
nRenderIndicesCount * renderable->GetNumIndex(),
|
||
customizedMaterial);
|
||
nremainingInst -= nRenderIndicesCount;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
void VegetationRenderObject::_Render(const RenderableType* renderable, Graphic::RenderPassType passType, const RenderBase::PrimitiveHandle& handle,
|
||
IndexT firstVert, SizeT numVert, IndexT firstIndex, SizeT numIndex, const Graphic::Material* customizedMaterial)
|
||
{
|
||
const Graphic::Material* material = (NULL == customizedMaterial) ? renderable->GetMaterial() : customizedMaterial;
|
||
if (passType && material->GetTech()->IsTemplateTech())
|
||
{
|
||
|
||
GraphicRenderer::RenderForward(passType, renderable, handle, firstVert, numVert, firstIndex, numIndex, customizedMaterial);
|
||
}
|
||
else
|
||
{
|
||
GraphicRenderer::RenderForward(eForward, renderable, handle, firstVert, numVert, firstIndex, numIndex, customizedMaterial);
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void VegetationRenderObject::SetShaderMask(Graphic::Renderable* pRenderable)
|
||
{
|
||
const Graphic::MaterialInstance* material_instance = pRenderable->GetMaterial();
|
||
|
||
//<2F><><EFBFBD><EFBFBD>forward pass <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><>
|
||
const Util::Array< GPtr<Graphic::MaterialPass> >& passList = material_instance->GetTech()->GetPassList();
|
||
const GPtr<Graphic::MaterialPass>& pass = passList[Graphic::eForward - 1];
|
||
const GPtr<ShaderProgramCompiler::ShaderMarcro>& pMarcro = pass->GetShaderMarcro();
|
||
bool bTemplate = material_instance->GetTech()->IsTemplateTech();
|
||
|
||
pMarcro->Reset();
|
||
pRenderable->ResetShaderMask();
|
||
|
||
if (bTemplate)
|
||
{
|
||
|
||
if (this->IsUseLM() && this->IsLMHandleValid())
|
||
{
|
||
pMarcro->TurnOn(ShaderProgramCompiler::ShaderMarcro::m_sLightMap);
|
||
}
|
||
|
||
const Graphic::Light* pSunLight = m_pRenderScene->GetSunLight();
|
||
if (this->GetReceiveShadow() && pSunLight != NULL)
|
||
{
|
||
|
||
if (pSunLight->IsEnableShadow())
|
||
{
|
||
pMarcro->TurnOn(ShaderProgramCompiler::ShaderMarcro::m_sShadow);
|
||
}
|
||
|
||
}
|
||
|
||
if (m_pRenderScene->HasLight())
|
||
{
|
||
pMarcro->TurnOnLight();
|
||
}
|
||
|
||
if (m_pRenderScene->GetEnvironment()->fogColor.w() > 0.0f)
|
||
{
|
||
pMarcro->TurnOn(ShaderProgramCompiler::ShaderMarcro::m_sFog);
|
||
}
|
||
|
||
pRenderable->SetShaderMask(Graphic::eForward, pMarcro->GetShaderMask());
|
||
}
|
||
}
|
||
} |