Exemplo n.º 1
0
        private IBuffer GetGlBuffer(ref IBuffer glBuffer, BufferTarget target, int offset)
        {
            if (!dirty)
            {
                return(glBuffer);
            }
            var nonDynamic        = rawDataResource.Volatility != ResourceVolatility.Volatile;
            var resourcePtr       = rawDataResource.Map();
            var resourceOffsetPtr = resourcePtr + offset;
            var glBufferSize      = rawDataResource.Size - offset;

            if (glBuffer == null || glBuffer.SizeInBytes != glBufferSize)
            {
                glBuffer?.Dispose();
                var usage = nonDynamic
                    ? BufferUsageHint.StaticDraw
                    : BufferUsageHint.DynamicDraw;
                // todo: target for index buffer
                glBuffer = infra.GlContext.Create.Buffer(target, glBufferSize, usage, resourceOffsetPtr);
            }
            else if (nonDynamic)
            {
                glBuffer.SetData(resourceOffsetPtr);
            }
            else
            {
                var bufferPtr = glBuffer.Map(0, glBufferSize, MapAccess.Write | MapAccess.InvalidateBuffer);
                PtrHelper.CopyBulk((byte *)bufferPtr, (byte *)resourceOffsetPtr, glBufferSize);
                glBuffer.Unmap();
            }
            rawDataResource.Unmap(false);
            dirty = false;
            return(glBuffer);
        }
        private unsafe void UpdateModel(float lerpAmount)
        {
            var pParticlePositions = (Vector3 *)particlesBuffer.Map();

            for (int i = 0; i < prevFrame.Particles.Length; i++)
            {
                var prevParticle = prevFrame.Particles[i];
                var nextParticle = nextFrame.Particles[i];
                if ((prevParticle - nextParticle).LengthSquared() < 1 && prevParticle != Vector3.Zero && nextParticle != Vector3.Zero)
                {
                    pParticlePositions[i] = Vector3.Lerp(prevParticle, nextParticle, lerpAmount);
                }
                else
                {
                    pParticlePositions[i] = nextParticle;
                }
            }
            particlesBuffer.Unmap(true);
        }
        private unsafe IFlexibleModel CreateModel(IntSize3 size, float cellSize, int numParticles)
        {
            // todo: add a 'IResourceSource.AttachResource(resource)' method
            var vertexPosElemInfo = new [] { new VertexElementInfo(CommonVertexSemantic.Position, 0, CommonFormat.R32G32B32_SFLOAT, 0, sizeof(Vector3)) };
            var resourcePack      = new ResourcePack(ResourceVolatility.Immutable);

            // Bounds
            var bounds         = new Vector3(size.Width * cellSize, size.Height * cellSize, size.Depth * cellSize);
            var boundsVertices = new[]
            {
                new Vector3(0, 0, 0),
                new Vector3(0, bounds.Y, 0),
                new Vector3(bounds.X, bounds.Y, 0),
                new Vector3(bounds.X, 0, 0),
                new Vector3(0, 0, bounds.Z),
                new Vector3(0, bounds.Y, bounds.Z),
                new Vector3(bounds.X, bounds.Y, bounds.Z),
                new Vector3(bounds.X, 0, bounds.Z),
            };
            var boundsIndices = new ushort[]
            {
                0, 1, 1, 2, 2, 3, 3, 0,
                4, 5, 5, 6, 6, 7, 7, 4,
                0, 4, 1, 5, 2, 6, 3, 7
            };
            RawDataResource boundsVertexBuffer;

            fixed(Vector3 *pBoundsVertexData = boundsVertices)
            boundsVertexBuffer = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pBoundsVertexData, boundsVertices.Length * sizeof(Vector3));

            resourcePack.AddSubresource("BoundsVertexBuffer", boundsVertexBuffer);
            RawDataResource boundsIndexBuffer;

            fixed(ushort *pBoundsIndices = boundsIndices)
            boundsIndexBuffer = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pBoundsIndices, boundsIndices.Length * sizeof(ushort));

            resourcePack.AddSubresource("BoundsIndexBuffer", boundsIndexBuffer);
            var boundsVertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable,
                                                             new [] { boundsVertexBuffer.AsSubrange(), boundsIndexBuffer.AsSubrange() },
                                                             vertexPosElemInfo,
                                                             new VertexIndicesInfo(1, CommonFormat.R16_UINT));

            resourcePack.AddSubresource("BoundsVertexSet", boundsVertexSet);
            var boundsModelPart = new FlexibleModelPart
            {
                VertexSetIndex    = 0,
                PrimitiveTopology = FlexibleModelPrimitiveTopology.LineList,
                ModelMaterialName = "BoundsMaterial",
                IndexCount        = boundsIndices.Length
            };

            // Particles
            particlesBuffer = new RawDataResource(ResourceVolatility.Volatile, numParticles * sizeof(Vector3));
            var pParticlePositions = (Vector3 *)particlesBuffer.Map();

            for (int i = 0; i < fluidSimulation.Particles.Length; i++)
            {
                pParticlePositions[i] = fluidSimulation.Particles[i].Position;
            }
            particlesBuffer.Unmap(true);
            resourcePack.AddSubresource("ParticlesBuffer", particlesBuffer);

            var particlesVertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable,
                                                                new [] { particlesBuffer.AsSubrange() },
                                                                vertexPosElemInfo,
                                                                null);

            resourcePack.AddSubresource("ParticlesVertexSet", particlesVertexSet);

            var particlesModelPart = new FlexibleModelPart
            {
                VertexSetIndex    = 1,
                PrimitiveTopology = FlexibleModelPrimitiveTopology.PointList,
                ModelMaterialName = "ParticlesMaterial",
                IndexCount        = numParticles
            };

            var resultModel = new FlexibleModel(ResourceVolatility.Immutable,
                                                new [] { boundsVertexSet, particlesVertexSet },
                                                new [] { boundsModelPart, particlesModelPart },
                                                new Sphere(bounds / 2, bounds.Length() / 2));

            resourcePack.AddSubresource("Model", resultModel);
            return(resultModel);
        }