98 lines
3.9 KiB
C#
98 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Assets.ThoMagic.Renderer
|
|
{
|
|
public class DrawCall
|
|
{
|
|
public readonly Mesh Mesh;
|
|
public readonly Material[] Materials;
|
|
public readonly RenderParams[] RenderParams;
|
|
private readonly Matrix4x4 _localToWorldMatrix;
|
|
private readonly uint baseIndirectArgsIndex;
|
|
private readonly int lodNr;
|
|
public DrawCall(
|
|
int lodNr,
|
|
Mesh mesh,
|
|
Material[] materials,
|
|
Matrix4x4 localToWorldMatrix,
|
|
uint baseIndirectArgsIndex,
|
|
List<GraphicsBuffer.IndirectDrawIndexedArgs> indirectDrawIndexedArgs,
|
|
in RenderParams renderParams)
|
|
{
|
|
if (mesh == null)
|
|
throw new ArgumentNullException(nameof(mesh));
|
|
if (materials == null)
|
|
throw new ArgumentNullException(nameof(materials));
|
|
if (materials.Length != mesh.subMeshCount)
|
|
throw new IndexOutOfRangeException(nameof(materials));
|
|
|
|
this.baseIndirectArgsIndex = baseIndirectArgsIndex;
|
|
_localToWorldMatrix = localToWorldMatrix;
|
|
Mesh = mesh;
|
|
Materials = materials;
|
|
RenderParams = new RenderParams[mesh.subMeshCount];
|
|
|
|
this.lodNr = lodNr;
|
|
|
|
for (int index = 0; index < mesh.subMeshCount; ++index)
|
|
{
|
|
RenderParams[index] = renderParams;
|
|
RenderParams[index].material = materials[index];
|
|
RenderParams[index].matProps = new MaterialPropertyBlock();
|
|
RenderParams[index].matProps.SetMatrix("trInstanceMatrix", _localToWorldMatrix);
|
|
RenderParams[index].matProps.SetInteger("trLodNr", lodNr + 1);
|
|
|
|
RenderParams[index].worldBounds = new Bounds(Vector3.zero, 1000f * Vector3.one);
|
|
|
|
indirectDrawIndexedArgs.Add(new GraphicsBuffer.IndirectDrawIndexedArgs
|
|
{
|
|
indexCountPerInstance = mesh.GetIndexCount(index),
|
|
baseVertexIndex = mesh.GetBaseVertex(index),
|
|
startIndex = mesh.GetIndexStart(index),
|
|
startInstance = 0,
|
|
instanceCount = 0
|
|
});
|
|
}
|
|
}
|
|
|
|
public virtual void SetInstances(ComputeBuffer instances, ComputeBuffer visibleIndexBuffer, ComputeBuffer metaBuffer)
|
|
{
|
|
for (int index = 0; index < this.RenderParams.Length; ++index)
|
|
{
|
|
RenderParams[index].matProps.SetBuffer("trInstances", instances);
|
|
RenderParams[index].matProps.SetBuffer("trPerCamVisibleIndexesBuffer", visibleIndexBuffer);
|
|
RenderParams[index].matProps.SetBuffer("trPerCamMeta", metaBuffer);
|
|
}
|
|
}
|
|
|
|
public virtual void Draw(Camera camera, ObjectData obj, GraphicsBuffer indirectDrawIndexedArgs)
|
|
{
|
|
if (Materials == null)
|
|
throw new ObjectDisposedException("Materials");
|
|
|
|
if (Mesh == null)
|
|
throw new ObjectDisposedException("Mesh");
|
|
|
|
var bounds = new Bounds(camera.transform.position, Vector3.one * 1000f);
|
|
|
|
for (int index = 0; index < RenderParams.Length; ++index)
|
|
{
|
|
var renderParam = RenderParams[index];
|
|
if (renderParam.material != null)
|
|
{
|
|
renderParam.camera = camera;
|
|
renderParam.worldBounds = bounds;
|
|
Graphics.RenderMeshIndirect(in renderParam, Mesh, indirectDrawIndexedArgs, 1, obj.indirectArgsPerSubmeshOffsets[(int)baseIndirectArgsIndex + index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal virtual void Dispose()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|