You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
279 lines
10 KiB
C++
279 lines
10 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
LandscapeRenderMobile.cpp: Landscape Rendering without using vertex texture fetch
|
|
=============================================================================*/
|
|
|
|
#include "Landscape.h"
|
|
#include "ShaderParameters.h"
|
|
#include "ShaderParameterUtils.h"
|
|
#include "LandscapeRender.h"
|
|
#include "LandscapeRenderMobile.h"
|
|
|
|
void FLandscapeVertexFactoryMobile::InitRHI()
|
|
{
|
|
// list of declaration items
|
|
FVertexDeclarationElementList Elements;
|
|
|
|
// position decls
|
|
Elements.Add(AccessStreamComponent(MobileData.PositionComponent,0));
|
|
|
|
if (MobileData.LODHeightsComponent.Num())
|
|
{
|
|
const int32 BaseAttribute = 1;
|
|
for(int32 Index = 0;Index < MobileData.LODHeightsComponent.Num();Index++)
|
|
{
|
|
Elements.Add(AccessStreamComponent(MobileData.LODHeightsComponent[Index], BaseAttribute + Index));
|
|
}
|
|
}
|
|
|
|
// create the actual device decls
|
|
InitDeclaration(Elements,FVertexFactory::DataType());
|
|
}
|
|
|
|
/** Shader parameters for use with FLandscapeVertexFactory */
|
|
class FLandscapeVertexFactoryMobileVertexShaderParameters : public FVertexFactoryShaderParameters
|
|
{
|
|
public:
|
|
/**
|
|
* Bind shader constants by name
|
|
* @param ParameterMap - mapping of named shader constants to indices
|
|
*/
|
|
virtual void Bind(const FShaderParameterMap& ParameterMap) override
|
|
{
|
|
LodValuesParameter.Bind(ParameterMap,TEXT("LodValues"));
|
|
NeighborSectionLodParameter.Bind(ParameterMap,TEXT("NeighborSectionLod"));
|
|
LodBiasParameter.Bind(ParameterMap,TEXT("LodBias"));
|
|
SectionLodsParameter.Bind(ParameterMap,TEXT("SectionLods"));
|
|
}
|
|
|
|
/**
|
|
* Serialize shader params to an archive
|
|
* @param Ar - archive to serialize to
|
|
*/
|
|
virtual void Serialize(FArchive& Ar) override
|
|
{
|
|
Ar << LodValuesParameter;
|
|
Ar << NeighborSectionLodParameter;
|
|
Ar << LodBiasParameter;
|
|
Ar << SectionLodsParameter;
|
|
}
|
|
/**
|
|
* Set any shader data specific to this vertex factory
|
|
*/
|
|
virtual void SetMesh(FRHICommandList& RHICmdList, FShader* VertexShader,const class FVertexFactory* VertexFactory,const class FSceneView& View,const struct FMeshBatchElement& BatchElement,uint32 DataFlags) const override
|
|
{
|
|
SCOPE_CYCLE_COUNTER(STAT_LandscapeVFDrawTime);
|
|
|
|
const FLandscapeBatchElementParams* BatchElementParams = (const FLandscapeBatchElementParams*)BatchElement.UserData;
|
|
check(BatchElementParams);
|
|
|
|
const FLandscapeComponentSceneProxyMobile* SceneProxy = (const FLandscapeComponentSceneProxyMobile*)BatchElementParams->SceneProxy;
|
|
SetUniformBufferParameter(RHICmdList, VertexShader->GetVertexShader(),VertexShader->GetUniformBufferParameter<FLandscapeUniformShaderParameters>(),*BatchElementParams->LandscapeUniformShaderParametersResource);
|
|
|
|
FVector CameraLocalPos3D = SceneProxy->WorldToLocal.TransformPosition(View.ViewMatrices.ViewOrigin);
|
|
FVector2D CameraLocalPos = FVector2D(CameraLocalPos3D.X, CameraLocalPos3D.Y);
|
|
|
|
if( LodBiasParameter.IsBound() )
|
|
{
|
|
FVector4 LodBias(
|
|
0.0f, // unused
|
|
0.0f, // unused
|
|
CameraLocalPos3D.X + SceneProxy->SectionBase.X,
|
|
CameraLocalPos3D.Y + SceneProxy->SectionBase.Y
|
|
);
|
|
SetShaderValue(RHICmdList, VertexShader->GetVertexShader(), LodBiasParameter, LodBias);
|
|
}
|
|
|
|
// Calculate LOD params
|
|
FVector4 fCurrentLODs;
|
|
FVector4 CurrentNeighborLODs[4];
|
|
|
|
if( BatchElementParams->SubX == -1 )
|
|
{
|
|
for( int32 SubY = 0; SubY < SceneProxy->NumSubsections; SubY++ )
|
|
{
|
|
for( int32 SubX = 0; SubX < SceneProxy->NumSubsections; SubX++ )
|
|
{
|
|
int32 SubIndex = SubX + 2 * SubY;
|
|
SceneProxy->CalcLODParamsForSubsection(View, CameraLocalPos, SubX, SubY, BatchElementParams->CurrentLOD, fCurrentLODs[SubIndex], CurrentNeighborLODs[SubIndex]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int32 SubIndex = BatchElementParams->SubX + 2 * BatchElementParams->SubY;
|
|
SceneProxy->CalcLODParamsForSubsection(View, CameraLocalPos, BatchElementParams->SubX, BatchElementParams->SubY, BatchElementParams->CurrentLOD, fCurrentLODs[SubIndex], CurrentNeighborLODs[SubIndex]);
|
|
}
|
|
|
|
if( SectionLodsParameter.IsBound() )
|
|
{
|
|
SetShaderValue(RHICmdList, VertexShader->GetVertexShader(), SectionLodsParameter, fCurrentLODs);
|
|
}
|
|
|
|
if( NeighborSectionLodParameter.IsBound() )
|
|
{
|
|
SetShaderValue(RHICmdList, VertexShader->GetVertexShader(), NeighborSectionLodParameter, CurrentNeighborLODs);
|
|
}
|
|
|
|
if( LodValuesParameter.IsBound() )
|
|
{
|
|
FVector4 LodValues(
|
|
0.0f, // this is the mesh's LOD, ES2 always uses the LOD0 mesh
|
|
0.0f, // unused
|
|
(float)SceneProxy->SubsectionSizeQuads,
|
|
1.f / (float)SceneProxy->SubsectionSizeQuads );
|
|
|
|
SetShaderValue(RHICmdList, VertexShader->GetVertexShader(),LodValuesParameter,LodValues);
|
|
}
|
|
}
|
|
protected:
|
|
FShaderParameter LodValuesParameter;
|
|
FShaderParameter NeighborSectionLodParameter;
|
|
FShaderParameter LodBiasParameter;
|
|
FShaderParameter SectionLodsParameter;
|
|
TShaderUniformBufferParameter<FLandscapeUniformShaderParameters> LandscapeShaderParameters;
|
|
};
|
|
|
|
/** Shader parameters for use with FLandscapeVertexFactory */
|
|
class FLandscapeVertexFactoryMobilePixelShaderParameters : public FLandscapeVertexFactoryPixelShaderParameters
|
|
{
|
|
public:
|
|
/**
|
|
* Bind shader constants by name
|
|
* @param ParameterMap - mapping of named shader constants to indices
|
|
*/
|
|
virtual void Bind(const FShaderParameterMap& ParameterMap) override
|
|
{
|
|
FLandscapeVertexFactoryPixelShaderParameters::Bind(ParameterMap);
|
|
BlendableLayerMaskParameter.Bind(ParameterMap, TEXT("BlendableLayerMask"));
|
|
}
|
|
|
|
/**
|
|
* Serialize shader params to an archive
|
|
* @param Ar - archive to serialize to
|
|
*/
|
|
virtual void Serialize(FArchive& Ar) override
|
|
{
|
|
FLandscapeVertexFactoryPixelShaderParameters::Serialize(Ar);
|
|
Ar << BlendableLayerMaskParameter;
|
|
}
|
|
/**
|
|
* Set any shader data specific to this vertex factory
|
|
*/
|
|
virtual void SetMesh(FRHICommandList& RHICmdList, FShader* PixelShader, const FVertexFactory* VertexFactory, const FSceneView& View, const FMeshBatchElement& BatchElement, uint32 DataFlags) const override
|
|
{
|
|
SCOPE_CYCLE_COUNTER(STAT_LandscapeVFDrawTime);
|
|
|
|
FLandscapeVertexFactoryPixelShaderParameters::SetMesh(RHICmdList, PixelShader, VertexFactory, View, BatchElement, DataFlags);
|
|
|
|
const FLandscapeBatchElementParams* BatchElementParams = (const FLandscapeBatchElementParams*)BatchElement.UserData;
|
|
check(BatchElementParams);
|
|
const FLandscapeComponentSceneProxyMobile* SceneProxy = (const FLandscapeComponentSceneProxyMobile*)BatchElementParams->SceneProxy;
|
|
|
|
if (BlendableLayerMaskParameter.IsBound())
|
|
{
|
|
FVector MaskVector;
|
|
MaskVector[0] = (SceneProxy->BlendableLayerMask & (1 << 0)) ? 1 : 0;
|
|
MaskVector[1] = (SceneProxy->BlendableLayerMask & (1 << 1)) ? 1 : 0;
|
|
MaskVector[2] = (SceneProxy->BlendableLayerMask & (1 << 2)) ? 1 : 0;
|
|
SetShaderValue(RHICmdList, PixelShader->GetPixelShader(), BlendableLayerMaskParameter, MaskVector);
|
|
}
|
|
}
|
|
protected:
|
|
FShaderParameter BlendableLayerMaskParameter;
|
|
};
|
|
|
|
FVertexFactoryShaderParameters* FLandscapeVertexFactoryMobile::ConstructShaderParameters(EShaderFrequency ShaderFrequency)
|
|
{
|
|
switch( ShaderFrequency )
|
|
{
|
|
case SF_Vertex:
|
|
return new FLandscapeVertexFactoryMobileVertexShaderParameters();
|
|
case SF_Pixel:
|
|
return new FLandscapeVertexFactoryMobilePixelShaderParameters();
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_VERTEX_FACTORY_TYPE(FLandscapeVertexFactoryMobile, "LandscapeVertexFactory", true, true, true, false, false);
|
|
|
|
/**
|
|
* Initialize the RHI for this rendering resource
|
|
*/
|
|
void FLandscapeVertexBufferMobile::InitRHI()
|
|
{
|
|
// create a static vertex buffer
|
|
FRHIResourceCreateInfo CreateInfo;
|
|
VertexBufferRHI = RHICreateVertexBuffer(DataSize, BUF_Static, CreateInfo);
|
|
void* VertexData = RHILockVertexBuffer(VertexBufferRHI, 0, DataSize, RLM_WriteOnly);
|
|
// Copy stored platform data
|
|
FMemory::Memcpy(VertexData, (uint8*)Data, DataSize);
|
|
RHIUnlockVertexBuffer(VertexBufferRHI);
|
|
}
|
|
|
|
FLandscapeComponentSceneProxyMobile::FLandscapeComponentSceneProxyMobile(ULandscapeComponent* InComponent, FLandscapeEditToolRenderData* InEditToolRenderData)
|
|
: FLandscapeComponentSceneProxy(InComponent, InEditToolRenderData)
|
|
{
|
|
check(InComponent && InComponent->PlatformData.HasValidPlatformData());
|
|
InComponent->PlatformData.GetUncompressedData(PlatformData);
|
|
|
|
#if WITH_EDITOR
|
|
InComponent->GeneratePlatformPixelData(false);
|
|
#endif
|
|
check(InComponent->MobileMaterialInterface);
|
|
check(InComponent->MobileWeightNormalmapTexture);
|
|
|
|
MaterialInterface = InComponent->MobileMaterialInterface;
|
|
|
|
WeightmapTextures.Empty(1);
|
|
WeightmapTextures.Add(InComponent->MobileWeightNormalmapTexture);
|
|
NormalmapTexture = InComponent->MobileWeightNormalmapTexture;
|
|
|
|
BlendableLayerMask = InComponent->MobileBlendableLayerMask;
|
|
}
|
|
|
|
FLandscapeComponentSceneProxyMobile::~FLandscapeComponentSceneProxyMobile()
|
|
{
|
|
if (VertexFactory)
|
|
{
|
|
delete VertexFactory;
|
|
VertexFactory = NULL;
|
|
}
|
|
}
|
|
|
|
void FLandscapeComponentSceneProxyMobile::CreateRenderThreadResources()
|
|
{
|
|
// Use only Index buffers
|
|
SharedBuffers = FLandscapeComponentSceneProxy::SharedBuffersMap.FindRef(SharedBuffersKey);
|
|
if( SharedBuffers == NULL )
|
|
{
|
|
SharedBuffers = new FLandscapeSharedBuffers(SharedBuffersKey, SubsectionSizeQuads, NumSubsections, GetScene().GetFeatureLevel(), false);
|
|
FLandscapeComponentSceneProxy::SharedBuffersMap.Add(SharedBuffersKey, SharedBuffers);
|
|
}
|
|
|
|
SharedBuffers->AddRef();
|
|
|
|
int32 VertexBufferSize = PlatformData.Num();
|
|
// Copy platform data into vertex buffer
|
|
VertexBuffer = new FLandscapeVertexBufferMobile(PlatformData.GetData(), VertexBufferSize);
|
|
|
|
FLandscapeVertexFactoryMobile* LandscapeVertexFactory = new FLandscapeVertexFactoryMobile();
|
|
LandscapeVertexFactory->MobileData.PositionComponent = FVertexStreamComponent(VertexBuffer, STRUCT_OFFSET(FLandscapeMobileVertex,Position), sizeof(FLandscapeMobileVertex), VET_UByte4N);
|
|
for( uint32 Index = 0; Index < LANDSCAPE_MAX_ES_LOD_COMP; ++Index )
|
|
{
|
|
LandscapeVertexFactory->MobileData.LODHeightsComponent.Add
|
|
(FVertexStreamComponent(VertexBuffer, STRUCT_OFFSET(FLandscapeMobileVertex,LODHeights) + sizeof(uint8) * 4 * Index, sizeof(FLandscapeMobileVertex), VET_UByte4N));
|
|
}
|
|
|
|
LandscapeVertexFactory->InitResource();
|
|
VertexFactory = LandscapeVertexFactory;
|
|
|
|
// Assign LandscapeUniformShaderParameters
|
|
LandscapeUniformShaderParameters.InitResource();
|
|
|
|
PlatformData.Empty();
|
|
}
|
|
|