private unsafe void UpdateIndexBufferCPU(CCommandList cmd, Graphics.CGfxCamera Camera) { if (mCpuDrawIndexBuffer == null) { return; } CBMeshBatch cbMesh = new CBMeshBatch(); { var pPlanes = stackalloc Plane[6]; Camera.CullingFrustum.GetPlanes(pPlanes); CBMeshBatch *pCBuffer = &cbMesh; Plane * planesTar = (Plane *)pCBuffer; for (uint i = 0; i < 6; i++) { planesTar[i] = pPlanes[i]; } cbMesh.GpuDrivenCameraPosition = Camera.CullingFrustum.TipPos; BoundingBox box = new BoundingBox(); Camera.CullingFrustum.GetBoundBox(ref box); cbMesh.GpuDrivenFrustumMinPoint = box.Minimum; cbMesh.GpuDrivenFrustumMaxPoint = box.Maximum; cbMesh.MeshBatchVertexStride = (uint)AllVertices.Count; cbMesh.ClusterNumber = (uint)GpuClusters.Count; UpdateCBMeshbatch(cmd, Camera); } UInt32_3 tri = new UInt32_3(); mDrawIndices.Clear(); for (int i = 0; i < GpuClusters.Count; i++) { var cluster = GpuClusters[i]; var GpuDrivenCameraDirection = GpuClusters[i].BoundCenter - cbMesh.GpuDrivenCameraPosition; var cameraDirInBoundSpace = Vector3.TransposeTransformNormal(GpuDrivenCameraDirection, GpuInstanceDatas[(int)cluster.InstanceId].InvMatrix); if (FrustumCull(ref cluster, ref cbMesh) == false) { UInt64 visBits = 0; if (cameraDirInBoundSpace.X >= 0) { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NX]; } else { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_X]; } if (cameraDirInBoundSpace.Y >= 0) { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NY]; } else { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_Y]; } if (cameraDirInBoundSpace.Z >= 0) { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_NZ]; } else { visBits |= cluster.CubeFaces[(int)Cluster.GpuCluster.ECubeFace.CubeFace_Z]; } uint InstanceStartIndex = cbMesh.MeshBatchVertexStride * cluster.InstanceId; for (int j = 0; j < cluster.FaceCount; j++) { if (TestBit(visBits, j) == false) { continue; } int srcIndex = (int)(cluster.StartFaceIndex + j) * 3; tri.x = InstanceStartIndex + AllIndices[srcIndex]; tri.y = InstanceStartIndex + AllIndices[srcIndex + 1]; tri.z = InstanceStartIndex + AllIndices[srcIndex + 2]; mDrawIndices.Add(tri); } } } mDrawArgs.InstanceCount = 1; mDrawArgs.IndexCountPerInstance = (uint)mDrawIndices.Count * 3; uint size = (uint)(mDrawIndices.Count * sizeof(UInt32_3)); if (mCpuDrawIndexBuffer.Desc.ByteWidth > size) { mCpuDrawIndexBuffer.UpdateBuffData(cmd, mDrawIndices.GetBufferPtr(), size); } }
public void UpdateGeomMesh(CRenderContext rc, float halfWidth = 0.1F) { if (GeomMesh == null) { return; } CDrawPrimitiveDesc dpDesc = new CDrawPrimitiveDesc(); dpDesc.SetDefault(); if (UseGeometry) { mTempPosition.Clear(); mTempUV.Clear(); LinesGen.BuildGraph(mTempPosition, mTempUV, halfWidth); mTempNormal.Clear(); mTempNormal.SetGrowStep(mTempPosition.Count); for (int i = 0; i < mTempPosition.Count; i++) { //mTempNormal.Add(mTempPosition[i].CalcNormals()); unsafe { LinePosition tempNorm = new LinePosition(); var ptr = (LinePosition *)mTempPosition.UnsafeAddressAt(i).ToPointer(); ptr->CalcNormals(ref tempNorm); mTempNormal.Add(tempNorm); } } dpDesc.StartIndex = 0xFFFFFFFF; if (halfWidth == 0) { dpDesc.PrimitiveType = EPrimitiveType.EPT_LineList; dpDesc.NumPrimitives = (UInt32)(mTempPosition.Count * 3 * 3); } else { dpDesc.NumPrimitives = (UInt32)(mTempPosition.Count * 3 * 2); } GeomMesh.SetAtom(0, 0, ref dpDesc); unsafe { GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_Position, mTempPosition.GetBufferPtr(), (UInt32)(sizeof(LinePosition) * mTempPosition.Count), (UInt32)sizeof(Vector3), 0); GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_Normal, mTempNormal.GetBufferPtr(), (UInt32)(sizeof(LinePosition) * mTempNormal.Count), (UInt32)sizeof(Vector3), 0); GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_UV, mTempUV.GetBufferPtr(), (UInt32)(sizeof(LineUV) * mTempUV.Count), (UInt32)sizeof(Vector2), 0); } } else { mTempPosition.Clear(); mTempUV.Clear(); LinesGen.BuildGraph(mTempPosition, mTempUV, halfWidth); mTempNormal.Clear(); mTempNormal.SetGrowStep(mTempPosition.Count); for (int i = 0; i < mTempPosition.Count; i++) { //mTempNormal.Add(mTempPosition[i].CalcNormals()); unsafe { LinePosition tempNorm = new LinePosition(); var ptr = (LinePosition *)mTempPosition.UnsafeAddressAt(i).ToPointer(); ptr->CalcNormals(ref tempNorm); mTempNormal.Add(tempNorm); } } dpDesc.StartIndex = 0xFFFFFFFF; if (halfWidth == 0) { dpDesc.PrimitiveType = EPrimitiveType.EPT_LineList; dpDesc.NumPrimitives = (UInt32)(mTempPosition.Count * 3); } else { dpDesc.NumPrimitives = (UInt32)(mTempPosition.Count * 2); } GeomMesh.SetAtom(0, 0, ref dpDesc); unsafe { GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_Position, mTempPosition.GetBufferPtr(), (UInt32)(sizeof(LinePosition) * mTempPosition.Count), (UInt32)sizeof(Vector3), 0); GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_Normal, mTempNormal.GetBufferPtr(), (UInt32)(sizeof(LinePosition) * mTempNormal.Count), (UInt32)sizeof(Vector3), 0); GeomMesh.SetGeomtryMeshStream(rc, EVertexSteamType.VST_UV, mTempUV.GetBufferPtr(), (UInt32)(sizeof(LineUV) * mTempUV.Count), (UInt32)sizeof(Vector2), 0); } } GeomMesh.AABB = LinesGen.AABB; GeomMesh.GeometryMesh.Dirty = true; }