private int MakeMesh() { Mesh m = new Mesh(); Vector3[] vertices = new Vector3[4]; Vector2[] uv = new Vector2[4]; int[] triangles = new int[6]; vertices[0] = new Vector3(0, 0); vertices[1] = new Vector3(0, Height); vertices[2] = new Vector3(Width, Height); vertices[3] = new Vector3(Width, 0); uv[0] = new Vector2(0, 0); uv[1] = new Vector2(0, 1); uv[2] = new Vector2(1, 1); uv[3] = new Vector2(1, 0); triangles[0] = 0; triangles[1] = 1; triangles[2] = 2; triangles[3] = 0; triangles[4] = 2; triangles[5] = 3; m.vertices = vertices; m.uv = uv; m.triangles = triangles; return(MaterialStore.GetInstance().AddMesh(m)); }
public static MaterialStore GetInstance() { if (instance == null) { instance = GameObject.FindObjectOfType <MaterialStore>(); } return(instance); }
public Material GetMaterial() { return(MaterialStore.GetInstance().GetMaterialById(_MaterialIndex)); }
// // // //END OF SPLIT MULTITHREADED CODE /// // // // // // //TODO Basically re-do this code once per different sprite tag, e.g once for User and once for Goblins, then we do 1 draw call per spritesheet protected override void OnUpdate() { //Get our entity reference EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; EntityQuery entityQuery = GetEntityQuery( typeof(SpriteSheetData)); //TODO Replace spritesheetdata with our tag? or seperate after we have them all by our identifer tags NativeArray <Entity> entitiesToDraw = entityQuery.ToEntityArray(Allocator.TempJob); Entity e = entitiesToDraw[ 0]; //Assume all entities share the shared data here (spritesheet cells, cell size, materials, etc. //Grab other shared data, DynamicBuffer <AnimationClip> animationClips = entityManager.GetBuffer <AnimationClip>(e); MaterialPropertyBlock shaderVariables = new MaterialPropertyBlock(); // //Per different Sprite // SpriteSheetData _spriteSheetData = entityManager.GetComponentData <SpriteSheetData>(e); //Get one per different sprite Vector2 _spriteSheetUVs = _spriteSheetData.GridUVs; MeshData _meshData = entityManager.GetSharedComponentData <MeshData>(e); // // End per different sprite (e.g we can re-use these values for each entity with a tag (.eg goblin) // EntityQuery query = GetEntityQuery(typeof(UniqueAnimationData), typeof(Translation)); NativeArray <UniqueAnimationData> uniqueAnimationDatas = query.ToComponentDataArray <UniqueAnimationData>(Allocator.TempJob); NativeQueue <RenderData> renderQueue1 = new NativeQueue <RenderData>(Allocator.TempJob); NativeQueue <RenderData> renderQueue2 = new NativeQueue <RenderData>(Allocator.TempJob); Camera camera = Camera.main; float3 cameraPos = camera.transform.position; float yBottom = cameraPos.y - camera.orthographicSize; float yTop1 = cameraPos.y + camera.orthographicSize; float yTop2 = cameraPos.y + 0f; CullAndSortJob cullAndSortJob = new CullAndSortJob() { YBottom = yBottom, YTop1 = yTop1, YTop2 = yTop2, nativeQueue_1 = renderQueue1.AsParallelWriter(), nativeQueue_2 = renderQueue2.AsParallelWriter(), spriteSheetUVs = _spriteSheetData.GridUVs }; JobHandle jobHandle = cullAndSortJob.Schedule(this); jobHandle.Complete(); NativeArray <JobHandle> jobHandles = new NativeArray <JobHandle>(2, Allocator.TempJob); NativeArray <RenderData> renderArray1 = new NativeArray <RenderData>(renderQueue1.Count, Allocator.TempJob); NativeArray <RenderData> renderArray2 = new NativeArray <RenderData>(renderQueue2.Count, Allocator.TempJob); RenderQueueToArrayJob renderQueueToArrayJob1 = new RenderQueueToArrayJob() { renderQueue1 = renderQueue1, renderArray = renderArray1 }; RenderQueueToArrayJob renderQueueToArrayJob2 = new RenderQueueToArrayJob() { renderQueue1 = renderQueue2, renderArray = renderArray2 }; jobHandles[0] = renderQueueToArrayJob1.Schedule(); jobHandles[1] = renderQueueToArrayJob2.Schedule(); JobHandle.CompleteAll(jobHandles); renderQueue1.Dispose(); renderQueue2.Dispose(); SortByPositionJob sortByPositionJob1 = new SortByPositionJob() { sortArray = renderArray1 }; SortByPositionJob sortByPositionJob2 = new SortByPositionJob() { sortArray = renderArray2 }; jobHandles[0] = sortByPositionJob1.Schedule(); jobHandles[1] = sortByPositionJob2.Schedule(); JobHandle.CompleteAll(jobHandles); int visibleEntityTotal = renderArray1.Length + renderArray2.Length; NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob); NativeArray <Vector4> uvArray = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob); FillArraysParralelJob fillArraysParralelJob1 = new FillArraysParralelJob() { nativeArray = renderArray1, matrixArray = matrixArray, uvArray = uvArray, startingIndex = 0 }; jobHandles[0] = fillArraysParralelJob1.Schedule(renderArray1.Length, 10); FillArraysParralelJob fillArraysParralelJob2 = new FillArraysParralelJob() { nativeArray = renderArray2, matrixArray = matrixArray, uvArray = uvArray, startingIndex = renderArray1.Length }; jobHandles[1] = fillArraysParralelJob2.Schedule(renderArray2.Length, 10); JobHandle.CompleteAll(jobHandles); int shaderPropertyId = Shader.PropertyToID("_MainTex_UV"); Mesh mesh = MaterialStore.GetInstance().GetMeshById(_meshData.GetMeshID()); int sliceCount = 1023; Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount]; Vector4[] uvInstancedArray = new Vector4[sliceCount]; for (int i = 0; i < uniqueAnimationDatas.Length; i += sliceCount) { int sliceSize = math.min(uniqueAnimationDatas.Length - i, sliceCount); NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize); NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize); shaderVariables.SetVectorArray(shaderPropertyId, uvInstancedArray); Graphics.DrawMeshInstanced( mesh, 0, _meshData.GetMaterial(), matrixInstancedArray, sliceSize, shaderVariables ); } matrixArray.Dispose(); uvArray.Dispose(); uniqueAnimationDatas.Dispose(); entitiesToDraw.Dispose(); jobHandles.Dispose(); renderArray1.Dispose(); renderArray2.Dispose(); }
public void Awake() { instance = this; }