// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Threading/Task.h"
#include "MaterialInfo.h"
struct MaterialParamsLink;
class GPUContext;
class GPUTextureView;
class RenderBuffers;
class SceneRenderTask;
struct RenderView;
struct RenderContext;
struct DrawCall;
///
/// Interface for material objects.
///
class FLAXENGINE_API IMaterial
{
public:
///
/// Gets the material info, structure which describes material surface.
///
/// The constant reference to the material descriptor.
virtual const MaterialInfo& GetInfo() const = 0;
///
/// Determines whether material is a surface shader.
///
/// true if material is surface shader; otherwise, false.
FORCE_INLINE bool IsSurface() const
{
return GetInfo().Domain == MaterialDomain::Surface;
}
///
/// Determines whether material is a post fx.
///
/// true if material is post fx; otherwise, false.
FORCE_INLINE bool IsPostFx() const
{
return GetInfo().Domain == MaterialDomain::PostProcess;
}
///
/// Determines whether material is a decal.
///
/// true if material is decal; otherwise, false.
FORCE_INLINE bool IsDecal() const
{
return GetInfo().Domain == MaterialDomain::Decal;
}
///
/// Determines whether material is a GUI shader.
///
/// true if material is GUI shader; otherwise, false.
FORCE_INLINE bool IsGUI() const
{
return GetInfo().Domain == MaterialDomain::GUI;
}
///
/// Determines whether material is a terrain shader.
///
/// true if material is terrain shader; otherwise, false.
FORCE_INLINE bool IsTerrain() const
{
return GetInfo().Domain == MaterialDomain::Terrain;
}
///
/// Determines whether material is a particle shader.
///
/// true if material is particle shader; otherwise, false.
FORCE_INLINE bool IsParticle() const
{
return GetInfo().Domain == MaterialDomain::Particle;
}
///
/// Checks if material needs vertex color vertex buffer data for rendering.
///
/// True if mesh renderer have to provide vertex color buffer to render that material
FORCE_INLINE bool RequireVertexColor() const
{
return (GetInfo().UsageFlags & MaterialUsageFlags::UseVertexColor) != 0;
}
///
/// Checks if material supports dithered LOD transitions.
///
/// True if material supports dithered LOD transitions, otherwise false.
FORCE_INLINE bool IsDitheredLODTransition() const
{
return (GetInfo().FeaturesFlags & MaterialFeaturesFlags::DitheredLODTransition) != 0;
}
///
/// Returns true if material is ready for rendering.
///
/// True if can render that material
virtual bool IsReady() const = 0;
///
/// Gets the mask of render passes supported by this material.
///
/// The drw passes supported by this material.
virtual DrawPass GetDrawModes() const
{
return DrawPass::None;
}
///
/// Returns true if material can use lightmaps (this includes lightmaps offline baking and sampling at runtime).
///
/// True if can use lightmaps, otherwise false
virtual bool CanUseLightmap() const
{
return false;
}
///
/// Returns true if material can use draw calls instancing.
///
/// True if can use instancing, otherwise false.
virtual bool CanUseInstancing() const
{
return false;
}
public:
///
/// Settings for the material binding to the graphics pipeline.
///
struct BindParameters
{
GPUContext* GPUContext;
const RenderContext& RenderContext;
const DrawCall* FirstDrawCall;
int32 DrawCallsCount;
MaterialParamsLink* ParamsLink = nullptr;
void* CustomData = nullptr;
///
/// The input scene color. It's optional and used in forward/postFx rendering.
///
GPUTextureView* Input = nullptr;
BindParameters(::GPUContext* context, const ::RenderContext& renderContext)
: GPUContext(context)
, RenderContext(renderContext)
, FirstDrawCall(nullptr)
, DrawCallsCount(0)
{
}
BindParameters(::GPUContext* context, const ::RenderContext& renderContext, const DrawCall& drawCall)
: GPUContext(context)
, RenderContext(renderContext)
, FirstDrawCall(&drawCall)
, DrawCallsCount(1)
{
}
BindParameters(::GPUContext* context, const ::RenderContext& renderContext, const DrawCall* firstDrawCall, int32 drawCallsCount)
: GPUContext(context)
, RenderContext(renderContext)
, FirstDrawCall(firstDrawCall)
, DrawCallsCount(drawCallsCount)
{
}
};
///
/// Binds the material state to the GPU pipeline. Should be called before the draw command.
///
/// The material bind settings.
virtual void Bind(BindParameters& params) = 0;
};