Exemplo n.º 1
0
 public JobInstance(JobTemplate <TData> parent, TData data)
 {
     this.parent = parent;
     this.data   = data;
     foreach (var taskTemplate in parent.tasksToRun)
     {
         this.tasksToRun.Add(new TaskInstance(this, taskTemplate));
     }
 }
Exemplo n.º 2
0
        void InitializeJobTemplate()
        {
            useSkirts = Debug.GetCVar("generation / use skirts", true);
            bool moveSkirtsOnGPU       = Debug.GetCVar("generation / move skirts on GPU", false);
            bool calculateNormalsOnGPU = Debug.GetCVar("generation / calculate normals on GPU", true);

            jobTemplate = new JobTemplate <Segment>();

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.CreateRendererAndBasicMesh();
            }, "vytvoření trojúhelníkových sítí a vykreslovací komponenty");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.RendererSurface.Mesh.EnsureIsOnGpu();
            }, "přesun trojúhelníkové sítě povrchu na grafickou kartu");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.RendererSea.Mesh.EnsureIsOnGpu();
            }, "přesun trojúhelníkové sítě moře na grafickou kartu");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                var surface = segment.RendererSurface.Mesh;

                var verticesStartIndexOffset = 0;
                var verticesCount            = surface.Vertices.Count;

                var range = segment.NoElevationRange;
                if (useSkirts)
                {
                    range = segment.NoElevationRangeModifiedForSkirts;
                }

                var uniforms = GenerateSurface.Uniforms;

                config.SetTo(uniforms);
                uniforms.Set("param_offsetFromPlanetCenter", segment.RendererSurface.Offset.ToVector3d());
                uniforms.Set("param_numberOfVerticesOnEdge", ChunkNumberOfVerticesOnEdge);
                uniforms.Set("param_cornerPositionA", range.a);
                uniforms.Set("param_cornerPositionB", range.b);
                uniforms.Set("param_cornerPositionC", range.c);
                uniforms.Set("param_indiciesCount", surface.TriangleIndicies.Count);
                uniforms.Set("param_verticesStartIndexOffset", verticesStartIndexOffset);

                GenerateSurface.Bind();

                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, surface.TriangleIndicies.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, surface.Vertices.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, surface.UVs.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, surface.VertexArray.GetVertexBuffer("biomes1").VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, surface.VertexArray.GetVertexBuffer("biomes2").VboHandle); MyGL.Check();
                GL.DispatchCompute(verticesCount, 1, 1); MyGL.Check();
            }, "vygenerování výšek trojúhelníkové sítě povrchu na grafické kartě");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.RendererSurface.Mesh.Vertices.DownloadDataFromGPU();
            }, "stáhnutí trojúhelníkové sítě povrchu z grafické karty do hlavní paměti počítače");

            jobTemplate.AddTask(segment =>
            {
                segment.RendererSurface.Mesh.RecalculateBounds();
                segment.CalculateRealVisibleRange();
            }, "vypočet obalového kvádru trojúhelníkových sítě povrchu");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                CalculateNormalsAndTangentsOnGPU(segment.RendererSurface.Mesh);
            }, "výpočet normál a tangent povrchu na grafické kartě");

            if (useSkirts)
            {
                /*
                 * if (false && moveSkirtsOnGPU) // TODO: move skirts on gpu
                 * {
                 *      var moveSkirts = Factory.GetShader("planet.moveSkirts.compute");
                 *      var uniforms = moveSkirts.Uniforms;
                 *
                 *      var ed = GetEdgeVerticesIndexes();
                 *      for (int i = 0; i < ed.Length; i++)
                 *      {
                 *              uniforms.Set("param_edgeVertexIndex[" + i + "]", ed[i]);
                 *      }
                 *
                 *      jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
                 *      {
                 *              var mesh = segment.RendererSurface.Mesh;
                 *              var moveAmount = -segment.NoElevationRange.CenterPos.Normalized().ToVector3() * (float)segment.NoElevationRange.ToBoundingSphere().radius / 10;
                 *
                 *
                 *              config.SetTo(uniforms);
                 *
                 *              uniforms.Set("param_moveAmount", moveAmount);
                 *
                 *              moveSkirts.Bind();
                 *
                 *              GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, mesh.Vertices.VboHandle); MyGL.Check();
                 *              GL.DispatchCompute(ed.Length, 1, 1); MyGL.Check();
                 *
                 *      }, "pokud jsou sukně zapnuty: posunutí vrcholú pro vytvoření sukní na grafické kartě");
                 * }
                 * else*/
                {
                    jobTemplate.AddTask(segment =>
                    {
                        var mesh       = segment.RendererSurface.Mesh;
                        var moveAmount = -segment.NoElevationRange.CenterPos.Normalized().ToVector3() * (float)segment.NoElevationRange.ToBoundingSphere().radius / 10;
                        foreach (var i in GetEdgeVerticesIndexes())
                        {
                            mesh.Vertices[i] += moveAmount;
                        }
                    }, "pokud jsou sukně zapnuty: posunutí vrcholú pro vytvoření sukní na centrální procesorové jednotce");

                    jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
                    {
                        var mesh = segment.RendererSurface.Mesh;
                        mesh.Vertices.UploadDataToGPU();
                    }, "pokud jsou sukně zapnuty: přesun upravené trojúhelníkové sítě zpět na grafickou kartu");
                }
            }

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                var mesh = segment.RendererSurface.Mesh;

                var verticesStartIndexOffset = 0;
                var verticesCount            = mesh.Vertices.Count;

                var range = segment.NoElevationRange;
                if (useSkirts)
                {
                    range = segment.NoElevationRangeModifiedForSkirts;
                }

                var uniforms = GenerateBiomes.Uniforms;

                config.SetTo(uniforms);
                uniforms.Set("param_offsetFromPlanetCenter", segment.RendererSurface.Offset.ToVector3d());
                uniforms.Set("param_numberOfVerticesOnEdge", ChunkNumberOfVerticesOnEdge);
                uniforms.Set("param_cornerPositionA", range.a);
                uniforms.Set("param_cornerPositionB", range.b);
                uniforms.Set("param_cornerPositionC", range.c);
                uniforms.Set("param_indiciesCount", mesh.TriangleIndicies.Count);
                uniforms.Set("param_verticesStartIndexOffset", verticesStartIndexOffset);

                GenerateBiomes.Bind();

                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, mesh.Vertices.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, mesh.Normals.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, mesh.UVs.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, mesh.TriangleIndicies.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, mesh.VertexArray.GetVertexBuffer("biomes1").VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 5, mesh.VertexArray.GetVertexBuffer("biomes2").VboHandle); MyGL.Check();
                GL.DispatchCompute(verticesCount, 1, 1); MyGL.Check();
            }, "vygenerování biomů na grafické kartě");


            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                var surface = segment.RendererSurface.Mesh;
                var sea     = segment.RendererSea.Mesh;

                var verticesStartIndexOffset = 0;
                var verticesCount            = surface.Vertices.Count;

                var range = segment.NoElevationRange;

                var uniforms = GenerateSea.Uniforms;

                config.SetTo(uniforms);
                uniforms.Set("param_offsetFromPlanetCenter", segment.RendererSurface.Offset.ToVector3d());
                uniforms.Set("param_numberOfVerticesOnEdge", ChunkNumberOfVerticesOnEdge);
                uniforms.Set("param_cornerPositionA", range.a);
                uniforms.Set("param_cornerPositionB", range.b);
                uniforms.Set("param_cornerPositionC", range.c);
                uniforms.Set("param_indiciesCount", surface.TriangleIndicies.Count);
                uniforms.Set("param_verticesStartIndexOffset", verticesStartIndexOffset);

                GenerateSea.Bind();

                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, sea.TriangleIndicies.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, sea.Vertices.VboHandle); MyGL.Check();
                GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, sea.UVs.VboHandle); MyGL.Check();
                GL.DispatchCompute(verticesCount, 1, 1); MyGL.Check();
            }, "upravení trojúhelníkové sítě moře na grafické kartě");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                CalculateNormalsAndTangentsOnGPU(segment.RendererSea.Mesh);
            }, "výpočet normál a tangent moře na grafické kartě");


            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.RendererSea.Mesh.Vertices.DownloadDataFromGPU();
            }, "stáhnutí trojúhelníkové sítě moře z grafické karty do hlavní paměti počítače");

            jobTemplate.AddTask(segment =>
            {
                segment.RendererSea.Mesh.RecalculateBounds();
            }, "vypočet obalového kvádru trojúhelníkových sítě moře");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                var range = segment.NoElevationRange;
                if (useSkirts)
                {
                    range = segment.NoElevationRangeModifiedForSkirts;
                }

                var uniforms = GenerateSurfaceNormalMap.Uniforms;

                config.SetTo(uniforms);
                uniforms.Set("param_offsetFromPlanetCenter", segment.RendererSurface.Offset.ToVector3d());
                uniforms.Set("param_numberOfVerticesOnEdge", ChunkNumberOfVerticesOnEdge);
                uniforms.Set("param_cornerPositionA", range.a);
                uniforms.Set("param_cornerPositionB", range.b);
                uniforms.Set("param_cornerPositionC", range.c);

                int texturingUnit = 0;

                var texture = segment.segmentNormalMap;

                uniforms.Set("param_segmentNormalMap", texturingUnit);
                GL.BindImageTexture(texturingUnit, texture.GetNativeTextureID(), 0, false, 0, TextureAccess.WriteOnly, SizedInternalFormat.Rgba8);
                texturingUnit++;

                GenerateSurfaceNormalMap.Bind();

                GL.DispatchCompute(texture.Width / 16, texture.Height / 16, 1); MyGL.Check();
            }, "vygenerování normálové povrchu mapy na grafické kartě");

            jobTemplate.AddTask(WhereToRun.GPUThread, segment =>
            {
                segment.segmentNormalMap.GenerateMipMaps();
            }, "vytvoření mipmap normálové povrchu mapy");

            ulong chunksGenerated = 0;

            jobTemplate.AddTask(segment =>
            {
                segment.NotifyGenerationDone();

                chunksGenerated++;
                Debug.AddValue("generation / total segments generated", chunksGenerated);
                Debug.AddValue("generation / total time spent generating", Neitri.FormatUtils.SecondsToString(jobTemplate.SecondsTaken));
                Debug.AddValue("generation / average time spent generating", Neitri.FormatUtils.SecondsToString(jobTemplate.AverageSeconds));
            }, "ukončení generování");
        }