Ejemplo n.º 1
0
        private void Enqueue(ref DrawCallInfo call)
        {
            //if (Calls > 0 && call.TryMerge(ref _drawCalls[Calls - 1]))
            //{
            //    Merged++;
            //    return;
            //}

            if (Calls >= _drawCalls.Length)
            {
                Flush();
            }

            _drawCalls[Calls++] = call;
        }
Ejemplo n.º 2
0
        private void EnqueueBuiltGeometry(Texture2D texture, float depth)
        {
            if ((_vertexCount + _geometryBuilder.VertexCount > _vertices.Length) ||
                (_indexCount + _geometryBuilder.IndexCount > _indices.Length))
            {
                Flush();
            }
            var drawCall = new DrawCallInfo(texture, _geometryBuilder.PrimitiveType, _indexCount,
                                            _geometryBuilder.PrimitivesCount, depth);

            Array.Copy(_geometryBuilder.Vertices, 0, _vertices, _vertexCount, _geometryBuilder.VertexCount);
            _vertexCount += _geometryBuilder.VertexCount;
            Array.Copy(_geometryBuilder.Indices, 0, _indices, _indexCount, _geometryBuilder.IndexCount);
            _indexCount += _geometryBuilder.IndexCount;
            Enqueue(ref drawCall);
        }
Ejemplo n.º 3
0
        private unsafe void Push(Texture2D texture, SpriteVertex[] vertices, Techniques technique)
        {
            AddQuadrilateralIndices(_vertexCount);

            if (_vertexCount + VERTEX_COUNT > _vertices.Length || _indicesCount + INDEX_COUNT > _indices.Length)
            {
                Flush();
            }

            DrawCallInfo call = new DrawCallInfo(texture, technique, _indicesCount, PRIMITIVES_COUNT, 0);


            fixed(SpriteVertex *p = &_vertices[_vertexCount])
            {
                fixed(SpriteVertex *t = &vertices[0])
                {
                    SpriteVertex *ptr  = p;
                    SpriteVertex *tptr = t;

                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr   = *tptr;
                }
            }

            fixed(short *p = &_indices[_indicesCount])
            {
                fixed(short *t = &_geometryIndices[0])
                {
                    short *ptr  = p;
                    short *tptr = t;

                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr++ = *tptr++;
                    *ptr   = *tptr;
                }
            }

            _vertexCount  += VERTEX_COUNT;
            _indicesCount += INDEX_COUNT;

            Enqueue(ref call);
        }
Ejemplo n.º 4
0
        private void SortIndicesAndMerge()
        {
            Array.Sort(_drawCalls, 0, Calls);

            int newDrawCallCount = 0;
            int start            = _drawCalls[0].StartIndex;

            _drawCalls[0].StartIndex = 0;
            DrawCallInfo currentDrawCall = _drawCalls[0];

            _drawCalls[newDrawCallCount++] = _drawCalls[0];

            int drawCallIndexCount = currentDrawCall.PrimitiveCount * 3;

            Array.Copy(_indices, start, _sortedIndices, 0, drawCallIndexCount);
            int sortedIndexCount = drawCallIndexCount;

            for (int i = 1; i < Calls; i++)
            {
                currentDrawCall    = _drawCalls[i];
                drawCallIndexCount = currentDrawCall.PrimitiveCount * 3;
                Array.Copy(_indices, currentDrawCall.StartIndex, _sortedIndices, sortedIndexCount, drawCallIndexCount);

                sortedIndexCount += drawCallIndexCount;
                if (currentDrawCall.TryMerge(ref _drawCalls[newDrawCallCount - 1]))
                {
                    Merged++;
                    continue;
                }

                currentDrawCall.StartIndex     = sortedIndexCount - drawCallIndexCount;
                _drawCalls[newDrawCallCount++] = currentDrawCall;
            }


            Calls = newDrawCallCount;
        }
Ejemplo n.º 5
0
        private void InternalDraw()
        {
            if (Calls == 0)
            {
                return;
            }

            Techniques last = Techniques.None;

            for (int i = 0; i < Calls; i++)
            {
                ref DrawCallInfo call = ref _drawCalls[i];

                switch (call.Technique)
                {
                case Techniques.Hued:
                    if (last != call.Technique)
                    {
                        _effect.CurrentTechnique = _huesTechnique;
                        _effect.CurrentTechnique.Passes[0].Apply();
                    }
                    break;

                case Techniques.ShadowSet:
                    if (last != call.Technique)
                    {
                        _effect.CurrentTechnique = _shadowTechnique;
                        _effect.CurrentTechnique.Passes[0].Apply();
                    }
                    break;
                }

                last = call.Technique;

                DoDraw(ref call);
            }
Ejemplo n.º 6
0
 /// <summary>
 ///     Submits a draw operation to the <see cref="GraphicsDevice" /> using the specified <see cref="DrawCallInfo"/>.
 /// </summary>
 /// <param name="drawCall">The draw call information.</param>
 protected override void InvokeDrawCall(ref DrawCallInfo drawCall)
 {
     GraphicsDevice.DrawIndexedPrimitives(drawCall.PrimitiveType, 0, drawCall.StartIndex, drawCall.PrimitiveCount);
 }
Ejemplo n.º 7
0
        public static void Run()
        {
            using (var app = /*new VulkanApplication() */ new OpenGlApplication())
            {
                var win = app.CreateSimpleRenderWindow(samples: 8);

                // create CPU side array
                var indices = new int[] { 0, 1, 2, 0, 2, 3 };
                // wrap it into cpu buffer. ArrayBuffer is a CPU buffer (which will be uploaded on demand),
                // In contrast, BackendBuffer would be a buffer prepared for a specific backend.
                // both implement the IBuffer interface.
                var indexBuffer = (IBuffer) new ArrayBuffer(indices);

                // same applies for vertex data. Here we do not explicitly create an ArrayBuffer since
                // we use convinience functions which internally create the ArrayBuffer for us
                var vertices = new V3f[] {
                    new V3f(-1, -1, 0), new V3f(1, -1, 0), new V3f(1, 1, 0), new V3f(-1, 1, 0)
                };
                var colors = new C4b[] {
                    C4b.Green, C4b.Red, C4b.Blue, C4b.White
                };

                // In this low level API, we manually construct a drawCallInfo which essentially map
                // to the arguments of glDrawElements etc.
                var drawCallInfo = new DrawCallInfo()
                {
                    FaceVertexCount = 6,
                    InstanceCount   = 1, // DrawCallInfo is a struct and is initialized with zeros. make sure to set instanceCount to 1
                    FirstIndex      = 0,
                };

                // next we create a scene graph node which describes a simple scene which, when rendered
                // uses the supplied drawCallInfo to render geometry of type TriangleList (in constrast to points, linestrip etc)
                var drawNode = new Sg.RenderNode(drawCallInfo, IndexedGeometryMode.TriangleList);
                // the main principle is to use scene graph nodes as small building blocks to build together the
                // complete scene description - a bit like lego ;)
                // the same applies for applying geometry data. just like any other attribute (e.g. model trafos),
                // vertex data can be inherited along the edges in the scene graph. thus the scene graph would look like this
                //             VertexIndexApplicator   (applies index buffer to sub graph)
                //                 ^
                //                 |
                //              drawNode               (performs draw call using attributes inherited along scene graph edges)
                var sceneWithIndexBuffer =
                    new Sg.VertexIndexApplicator(
                        new BufferView(AValModule.constant(indexBuffer), typeof(int)),
                        drawNode
                        );

                // of course constructing scene graph nodes manually is tedious. therefore we use
                // convinience extension functions which can be chaned together, each
                // wrapping a node around the previously constructed scene graph
                var scene =
                    sceneWithIndexBuffer
                    .WithVertexAttribute("Positions", vertices)
                    // there are a lot such extension functions defined to conviniently work with scene graphs
                    .VertexAttribute(DefaultSemantic.Colors, colors)
                    // next, we apply the shaders (this way, the shader becomes the root node -> all children now use
                    // this so called effect (a pipeline shader which combines all shader stages into one object)
                    .WithEffects(new[] { Aardvark.Rendering.Effects.VertexColor.Effect });

                // next we use the aardvark scene graph compiler to construct a so called render task,
                // an optimized representation of the scene graph.
                var renderTask = app.Runtime.CompileRender(win.FramebufferSignature, scene);

                // next, we assign the rendertask to our render window.
                win.RenderTask = renderTask;

                win.Run();
            }
        }