예제 #1
0
        /// <summary>
        /// Resets the vertex buffer object from the verticies.
        /// <param Name="device">GPU to draw with.</param></summary>
        public virtual void ResetBuffer(GraphicsDevice device)
        {
            //if(DwarfGame.ExitGame)
            //{
            //    return;
            //}

            //lock (VertexLock)
            {
                if (VertexBuffer != null && !VertexBuffer.IsDisposed)
                {
                    VertexBuffer.Dispose();
                }
                VertexBuffer = null;

                if (IndexBuffer != null && !IndexBuffer.IsDisposed)
                {
                    IndexBuffer.Dispose();
                }
                IndexBuffer = null;

                if (IndexCount <= 0 && Indexes != null)
                {
                    IndexCount = Indexes.Length;
                }

                if (VertexCount <= 0 && Vertices != null)
                {
                    VertexCount = Vertices.Length;
                }

                if (Vertices != null)
                {
                    try
                    {
                        VertexBuffer = new DynamicVertexBuffer(device, ExtendedVertex.VertexDeclaration, Vertices.Length, BufferUsage.WriteOnly);
                        VertexBuffer.SetData(Vertices, 0, VertexCount);
                    }
                    catch (Exception exception)
                    {
                        Console.Out.WriteLine(exception.ToString());
                        VertexBuffer = null;
                    }
                }

                if (Indexes != null)
                {
                    try
                    {
                        IndexBuffer = new DynamicIndexBuffer(device, typeof(ushort), Indexes.Length, BufferUsage.None);
                        IndexBuffer.SetData(Indexes, 0, IndexCount);
                    }
                    catch (Exception exception)
                    {
                        Console.Out.WriteLine(exception.ToString());
                        IndexBuffer = null;
                    }
                }
            }
        }
예제 #2
0
        public void ContentLostResources()
        {
            // https://blogs.msdn.microsoft.com/shawnhar/2007/12/12/virtualizing-the-graphicsdevice-in-xna-game-studio-2-0/

            var rt  = new RenderTarget2D(gdm.GraphicsDevice, 5, 5);
            var vb  = new DynamicVertexBuffer(gd, VertexPositionColor.VertexDeclaration, 1, BufferUsage.None);
            var ib  = new DynamicIndexBuffer(gd, IndexElementSize.SixteenBits, 1, BufferUsage.None);
            var rtc = new RenderTargetCube(gd, 1, false, SurfaceFormat.Color, DepthFormat.Depth16);

            gd.Reset();

            Assert.IsTrue(rt.IsContentLost);
            Assert.IsFalse(rt.IsDisposed);

            Assert.IsTrue(vb.IsContentLost);
            Assert.IsFalse(vb.IsDisposed);

            Assert.IsTrue(ib.IsContentLost);
            Assert.IsFalse(ib.IsDisposed);

            Assert.IsTrue(rtc.IsContentLost);
            Assert.IsFalse(rtc.IsDisposed);

            rt.Dispose();
            vb.Dispose();
            ib.Dispose();
            rtc.Dispose();
        }
예제 #3
0
        /// <summary>
        /// Unload the elements used in the <c>OcTree</c>.
        /// </summary>
        public void Unload()
        {
            Stack <OcTreeNode> auxStack = new Stack <OcTreeNode>();

            auxStack.Push(RootNode);

            while (auxStack.Count != 0)
            {
                OcTreeNode node = auxStack.Pop();

                if (node.ChildList.Count == 0)
                {
                    node.Unload();
                }
                else
                {
                    for (int i = node.ChildList.Count - 1; i >= 0; i--)
                    {
                        auxStack.Push(node.ChildList[i]);
                    }
                }
            }

            _cubeVertexBuffer.Dispose();
            _cubeIndexBuffer.Dispose();
        }
예제 #4
0
        public void Dispose()
        {
            IsDisposed = true;

            vertexBuffer?.Dispose();
            indexBuffer?.Dispose();
        }
예제 #5
0
        // -------------------------------------------------------------------
        // DisposeBuffers
        // -------------------------------------------------------------------

        public void DisposeBuffers(GraphicsDevice device)
        {
            device.SetVertexBuffer(null);
            device.Indices = null;
            VB.Dispose();
            IB.Dispose();
        }
예제 #6
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing == true && isDisposed == false)
            {
                if (Disposing != null)
                {
                    Disposing(this, EventArgs.Empty);
                }

                if (vertexDeclaration != null)
                {
                    vertexDeclaration.Dispose();
                }
                if (vertexShader != null)
                {
                    vertexShader.Dispose();
                }
                if (pixelShader != null)
                {
                    pixelShader.Dispose();
                }
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }
                if (indexBuffer != null)
                {
                    indexBuffer.Dispose();
                }

                isDisposed = true;
            }
        }
예제 #7
0
 protected override void DisposeData()
 {
     if (vertexBuffer == null)
     {
         return;
     }
     vertexBuffer.Dispose();
     indexBuffer.Dispose();
     vertexBuffer = null;
 }
예제 #8
0
 public void Dispose()
 {
     if (vertexBuffer != null)
     {
         vertexBuffer.Dispose();
     }
     if (indexBuffer != null)
     {
         indexBuffer.Dispose();
     }
 }
예제 #9
0
 public void Dispose()
 {
     if (_vertexBuffer != null)
     {
         _vertexBuffer.Dispose();
     }
     if (_indexBuffer != null)
     {
         _indexBuffer.Dispose();
     }
 }
 public void Dispose()
 {
     if (ObstructionVertexBuffer != null)
     {
         ObstructionVertexBuffer.Dispose();
     }
     if (ObstructionIndexBuffer != null)
     {
         ObstructionIndexBuffer.Dispose();
     }
 }
예제 #11
0
        public void SetIndices(ushort[] indices, int indexCount)
        {
            if (indices == null)
            {
                throw new ArgumentNullException("indices");
            }
            if (indexCount < 0 || indices.Length < indexCount)
            {
                throw new ArgumentOutOfRangeException("vertexCount");
            }

            IndexCount     = indexCount;
            PrimitiveCount = indexCount / 3;

            if (indexCount != 0)
            {
                if (indexBuffer != null && indexBuffer.IndexCount != indexCount)
                {
                    indexBuffer.Dispose();
                    indexBuffer = null;
                }

                if (indexBuffer == null)
                {
                    indexBuffer = new DynamicIndexBuffer(
                        graphicsDevice, IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly);
                }

                indexBuffer.SetData(indices, 0, indexCount, SetDataOptions.Discard);
            }
            else
            {
                if (indexBuffer != null)
                {
                    indexBuffer.Dispose();
                    indexBuffer = null;
                }
            }
        }
예제 #12
0
        private void EnsureBufferSize(int vbs, int ibs)
        {
            if (_vertexBuffer == null || _vertexBuffer.VertexCount < vbs)
            {
                _vertexBuffer?.Dispose();
                _vertexBuffer = new DynamicVertexBuffer(GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, vbs, BufferUsage.WriteOnly);
            }

            if (_indexBuffer == null || _indexBuffer.IndexCount < ibs)
            {
                _indexBuffer?.Dispose();
                _indexBuffer = new DynamicIndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, ibs, BufferUsage.WriteOnly);
            }
        }
예제 #13
0
        private void CalculateBuffers()
        {
            if (fPoints.Count > 0)
            {
                fNumberOfParticles = fPoints.Count;
                fNumberOfVertices  = fPoints.Count * 4;
                fNumberOfIndices   = fPoints.Count * 6;
                VertexBillboardParticle[] vertices = new VertexBillboardParticle[fNumberOfVertices];
                short[] indices       = new short[fNumberOfIndices];
                int     verticeNumber = 0;
                int     indiceNumber  = 0;
                for (int i = 0; i < fNumberOfParticles; i++)
                {
                    MyPoint point             = fPoints[i];
                    int     verticeNumberBase = verticeNumber;
                    vertices[verticeNumber++] = new VertexBillboardParticle(point.Position, Vector2.Zero, point.Size, Color.White);
                    vertices[verticeNumber++] = new VertexBillboardParticle(point.Position, new Vector2(1, 0), point.Size, Color.White);
                    vertices[verticeNumber++] = new VertexBillboardParticle(point.Position, new Vector2(0, 1), point.Size, Color.White);
                    vertices[verticeNumber++] = new VertexBillboardParticle(point.Position, Vector2.One, point.Size, Color.White);
                    indices[indiceNumber++]   = (short)(0 + verticeNumberBase);
                    indices[indiceNumber++]   = (short)(1 + verticeNumberBase);
                    indices[indiceNumber++]   = (short)(2 + verticeNumberBase);
                    indices[indiceNumber++]   = (short)(1 + verticeNumberBase);
                    indices[indiceNumber++]   = (short)(3 + verticeNumberBase);
                    indices[indiceNumber++]   = (short)(2 + verticeNumberBase);
                }

                // 2020-04-01 Out of memory, which hasent happened before
                //fIndexBuffer = new DynamicIndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, fNumberOfIndices, BufferUsage.WriteOnly);
                //fIndexBuffer.SetData(indices);
                //fVertexBuffer = new DynamicVertexBuffer(GraphicsDevice, VertexBillboardParticle.VertexDeclaration, fNumberOfVertices, BufferUsage.WriteOnly);
                //fVertexBuffer.SetData(vertices);

                if (fIndexBuffer != null)
                {
                    fIndexBuffer.Dispose();
                }
                if (fVertexBuffer != null)
                {
                    fVertexBuffer.Dispose();
                }

                fIndexBuffer  = new DynamicIndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, fNumberOfIndices, BufferUsage.WriteOnly);
                fVertexBuffer = new DynamicVertexBuffer(GraphicsDevice, VertexBillboardParticle.VertexDeclaration, fNumberOfVertices, BufferUsage.WriteOnly);

                fIndexBuffer.SetData(indices);
                fVertexBuffer.SetData(vertices);
            }
        }
        /// <summary>
        /// Unload all the needed elements of the <c>DrawableModel</c>.
        /// </summary>
        public virtual void Unload()
        {
            _scale    = Vector3.Zero;
            _rotation = Vector3.Zero;
            _position = Vector3.Zero;

            _vertexBuffer.Dispose();
            _vertexBuffer = null;

            _indexBuffer.Dispose();
            _indexBuffer = null;

            _modelTransforms = null;

            _model = null;
        }
예제 #15
0
        public void Remove()
        {
            if (!lightSourceParams.Persistent)
            {
                LightSprite?.Remove();
                OverrideLightTexture?.Remove();
            }

            DeformableLightSprite?.Remove();
            DeformableLightSprite = null;

            lightVolumeBuffer?.Dispose();
            lightVolumeBuffer = null;

            lightVolumeIndexBuffer?.Dispose();
            lightVolumeIndexBuffer = null;

            GameMain.LightManager.RemoveLight(this);
        }
예제 #16
0
        /// <summary>
        /// Dispose of all those drawing tools.
        /// </summary>
        /// <param name="disposing">Tells whether we want to throw things away.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_vertexBuffer != null)
                {
                    _vertexBuffer.Dispose();
                }

                if (_indexBuffer != null)
                {
                    _indexBuffer.Dispose();
                }

                if (_basicEffect != null)
                {
                    _basicEffect.Dispose();
                }
            }
        }
예제 #17
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }

                if (indexBuffer != null)
                {
                    indexBuffer.Dispose();
                }

                if (basicEffect != null)
                {
                    basicEffect.Dispose();
                }
            }
        }
예제 #18
0
        public override void Dispose()
        {
            if (IsDisposed)
            {
                return;
            }

            if (_vertexBuffer != null && !_vertexBuffer.IsDisposed)
            {
                _vertexBuffer.Dispose();
            }

            if (_indexBuffer != null && !_indexBuffer.IsDisposed)
            {
                _indexBuffer.Dispose();
            }

            _vertexBuffer = null;
            _indexBuffer  = null;

            base.Dispose();
        }
예제 #19
0
        private void CalculateLightVertices(List <Vector2> rayCastHits)
        {
            List <VertexPositionTexture> vertices = new List <VertexPositionTexture>();

            Vector2 drawPos = position;

            if (ParentSub != null)
            {
                drawPos += ParentSub.DrawPosition;
            }

            float cosAngle = (float)Math.Cos(Rotation);
            float sinAngle = -(float)Math.Sin(Rotation);

            Vector2 uvOffset            = Vector2.Zero;
            Vector2 overrideTextureDims = Vector2.One;

            if (overrideLightTexture != null)
            {
                overrideTextureDims = new Vector2(overrideLightTexture.SourceRect.Width, overrideLightTexture.SourceRect.Height);
                uvOffset            = (overrideLightTexture.Origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
            }

            // Add a vertex for the center of the mesh
            vertices.Add(new VertexPositionTexture(new Vector3(position.X, position.Y, 0),
                                                   new Vector2(0.5f, 0.5f) + uvOffset));

            // Add all the other encounter points as vertices
            // storing their world position as UV coordinates
            foreach (Vector2 vertex in rayCastHits)
            {
                Vector2 rawDiff = vertex - drawPos;
                Vector2 diff    = rawDiff;
                diff /= range * 2.0f;
                if (overrideLightTexture != null)
                {
                    Vector2 originDiff = diff;

                    diff.X = originDiff.X * cosAngle - originDiff.Y * sinAngle;
                    diff.Y = originDiff.X * sinAngle + originDiff.Y * cosAngle;
                    diff  *= (overrideTextureDims / overrideLightTexture.size) * 2.0f;

                    diff += uvOffset;
                }

                vertices.Add(new VertexPositionTexture(new Vector3(position.X + rawDiff.X, position.Y + rawDiff.Y, 0),
                                                       new Vector2(0.5f, 0.5f) + diff));
            }

            // Compute the indices to form triangles
            List <short> indices = new List <short>();

            for (int i = 0; i < rayCastHits.Count - 1; i++)
            {
                indices.Add(0);
                indices.Add((short)((i + 2) % vertices.Count));
                indices.Add((short)((i + 1) % vertices.Count));
            }

            indices.Add(0);
            indices.Add((short)(1));
            indices.Add((short)(vertices.Count - 1));

            vertexCount = vertices.Count;
            indexCount  = indices.Count;

            //TODO: a better way to determine the size of the vertex buffer and handle changes in size?
            //now we just create a buffer for 64 verts and make it larger if needed
            if (lightVolumeBuffer == null)
            {
                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionTexture.VertexDeclaration, Math.Max(64, (int)(vertexCount * 1.5)), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), Math.Max(64 * 3, (int)(indexCount * 1.5)), BufferUsage.None);
            }
            else if (vertexCount > lightVolumeBuffer.VertexCount)
            {
                lightVolumeBuffer.Dispose();
                lightVolumeIndexBuffer.Dispose();

                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionTexture.VertexDeclaration, (int)(vertexCount * 1.5), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), (int)(indexCount * 1.5), BufferUsage.None);
            }

            lightVolumeBuffer.SetData <VertexPositionTexture>(vertices.ToArray());
            lightVolumeIndexBuffer.SetData <short>(indices.ToArray());
        }
예제 #20
0
        private void CalculateLightVertices(List <Vector2> rayCastHits)
        {
            vertexCount = rayCastHits.Count * 2 + 1;
            indexCount  = (rayCastHits.Count) * 9;

            //recreate arrays if they're too small or excessively large
            if (vertices == null || vertices.Length < vertexCount || vertices.Length > vertexCount * 3)
            {
                vertices = new VertexPositionColorTexture[vertexCount];
                indices  = new short[indexCount];
            }

            Vector2 drawPos = position;

            if (ParentSub != null)
            {
                drawPos += ParentSub.DrawPosition;
            }

            float cosAngle = (float)Math.Cos(Rotation);
            float sinAngle = -(float)Math.Sin(Rotation);

            Vector2 uvOffset            = Vector2.Zero;
            Vector2 overrideTextureDims = Vector2.One;

            if (OverrideLightTexture != null)
            {
                overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);

                Vector2 origin = OverrideLightTexture.Origin;
                if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
                {
                    origin.X = OverrideLightTexture.SourceRect.Width - origin.X;
                }
                if (LightSpriteEffect == SpriteEffects.FlipVertically)
                {
                    origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y;
                }
                uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
            }

            // Add a vertex for the center of the mesh
            vertices[0] = new VertexPositionColorTexture(new Vector3(position.X, position.Y, 0),
                                                         Color.White, GetUV(new Vector2(0.5f, 0.5f) + uvOffset, LightSpriteEffect));

            //hacky fix to exc excessively large light volumes (they used to be up to 4x the range of the light if there was nothing to block the rays).
            //might want to tweak the raycast logic in a way that this isn't necessary
            float     boundRadius = Range * 1.1f / (1.0f - Math.Max(Math.Abs(uvOffset.X), Math.Abs(uvOffset.Y)));
            Rectangle boundArea   = new Rectangle((int)(drawPos.X - boundRadius), (int)(drawPos.Y + boundRadius), (int)(boundRadius * 2), (int)(boundRadius * 2));

            for (int i = 0; i < rayCastHits.Count; i++)
            {
                if (MathUtils.GetLineRectangleIntersection(drawPos, rayCastHits[i], boundArea, out Vector2 intersection))
                {
                    rayCastHits[i] = intersection;
                }
            }

            // Add all the other encounter points as vertices
            // storing their world position as UV coordinates
            for (int i = 0; i < rayCastHits.Count; i++)
            {
                Vector2 vertex = rayCastHits[i];

                //we'll use the previous and next vertices to calculate the normals
                //of the two segments this vertex belongs to
                //so we can add new vertices based on these normals
                Vector2 prevVertex = rayCastHits[i > 0 ? i - 1 : rayCastHits.Count - 1];
                Vector2 nextVertex = rayCastHits[i < rayCastHits.Count - 1 ? i + 1 : 0];

                Vector2 rawDiff = vertex - drawPos;

                //calculate normal of first segment
                Vector2 nDiff1 = vertex - nextVertex;
                float   tx     = nDiff1.X; nDiff1.X = -nDiff1.Y; nDiff1.Y = tx;
                nDiff1 /= Math.Max(Math.Abs(nDiff1.X), Math.Abs(nDiff1.Y));
                //if the normal is pointing towards the light origin
                //rather than away from it, invert it
                if (Vector2.DistanceSquared(nDiff1, rawDiff) > Vector2.DistanceSquared(-nDiff1, rawDiff))
                {
                    nDiff1 = -nDiff1;
                }

                //calculate normal of second segment
                Vector2 nDiff2 = prevVertex - vertex;
                tx      = nDiff2.X; nDiff2.X = -nDiff2.Y; nDiff2.Y = tx;
                nDiff2 /= Math.Max(Math.Abs(nDiff2.X), Math.Abs(nDiff2.Y));
                //if the normal is pointing towards the light origin
                //rather than away from it, invert it
                if (Vector2.DistanceSquared(nDiff2, rawDiff) > Vector2.DistanceSquared(-nDiff2, rawDiff))
                {
                    nDiff2 = -nDiff2;
                }

                //add the normals together and use some magic numbers to create
                //a somewhat useful/good-looking blur
                Vector2 nDiff = nDiff1 + nDiff2;
                nDiff /= Math.Max(Math.Abs(nDiff.X), Math.Abs(nDiff.Y));
                nDiff *= 50.0f;

                Vector2 diff = rawDiff;
                diff /= Range * 2.0f;
                if (OverrideLightTexture != null)
                {
                    //calculate texture coordinates based on the light's rotation
                    Vector2 originDiff = diff;

                    diff.X = originDiff.X * cosAngle - originDiff.Y * sinAngle;
                    diff.Y = originDiff.X * sinAngle + originDiff.Y * cosAngle;
                    diff  *= (overrideTextureDims / OverrideLightTexture.size);// / (1.0f - Math.Max(Math.Abs(uvOffset.X), Math.Abs(uvOffset.Y)));
                    diff  += uvOffset;
                }

                //finally, create the vertices
                VertexPositionColorTexture fullVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X, position.Y + rawDiff.Y, 0),
                                                                                     Color.White, GetUV(new Vector2(0.5f, 0.5f) + diff, LightSpriteEffect));
                VertexPositionColorTexture fadeVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X + nDiff.X, position.Y + rawDiff.Y + nDiff.Y, 0),
                                                                                     Color.White * 0.0f, GetUV(new Vector2(0.5f, 0.5f) + diff, LightSpriteEffect));

                vertices[1 + i * 2]     = fullVert;
                vertices[1 + i * 2 + 1] = fadeVert;
            }

            // Compute the indices to form triangles
            for (int i = 0; i < rayCastHits.Count - 1; i++)
            {
                //main light body
                indices[i * 9]     = 0;
                indices[i * 9 + 1] = (short)((i * 2 + 3) % vertexCount);
                indices[i * 9 + 2] = (short)((i * 2 + 1) % vertexCount);

                //faded light
                indices[i * 9 + 3] = (short)((i * 2 + 1) % vertexCount);
                indices[i * 9 + 4] = (short)((i * 2 + 3) % vertexCount);
                indices[i * 9 + 5] = (short)((i * 2 + 4) % vertexCount);

                indices[i * 9 + 6] = (short)((i * 2 + 2) % vertexCount);
                indices[i * 9 + 7] = (short)((i * 2 + 1) % vertexCount);
                indices[i * 9 + 8] = (short)((i * 2 + 4) % vertexCount);
            }

            //main light body
            indices[(rayCastHits.Count - 1) * 9]     = 0;
            indices[(rayCastHits.Count - 1) * 9 + 1] = (short)(1);
            indices[(rayCastHits.Count - 1) * 9 + 2] = (short)(vertexCount - 2);

            //faded light
            indices[(rayCastHits.Count - 1) * 9 + 3] = (short)(1);
            indices[(rayCastHits.Count - 1) * 9 + 4] = (short)(vertexCount - 1);
            indices[(rayCastHits.Count - 1) * 9 + 5] = (short)(vertexCount - 2);

            indices[(rayCastHits.Count - 1) * 9 + 6] = (short)(1);
            indices[(rayCastHits.Count - 1) * 9 + 7] = (short)(2);
            indices[(rayCastHits.Count - 1) * 9 + 8] = (short)(vertexCount - 1);

            //TODO: a better way to determine the size of the vertex buffer and handle changes in size?
            //now we just create a buffer for 64 verts and make it larger if needed
            if (lightVolumeBuffer == null)
            {
                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, Math.Max(64, (int)(vertexCount * 1.5)), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), Math.Max(64 * 3, (int)(indexCount * 1.5)), BufferUsage.None);
            }
            else if (vertexCount > lightVolumeBuffer.VertexCount || indexCount > lightVolumeIndexBuffer.IndexCount)
            {
                lightVolumeBuffer.Dispose();
                lightVolumeIndexBuffer.Dispose();

                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, (int)(vertexCount * 1.5), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), (int)(indexCount * 1.5), BufferUsage.None);
            }

            lightVolumeBuffer.SetData <VertexPositionColorTexture>(vertices, 0, vertexCount);
            lightVolumeIndexBuffer.SetData <short>(indices, 0, indexCount);

            Vector2 GetUV(Vector2 vert, SpriteEffects effects)
            {
                if (effects == SpriteEffects.FlipHorizontally)
                {
                    vert.X = 1.0f - vert.X;
                }
                else if (effects == SpriteEffects.FlipVertically)
                {
                    vert.Y = 1.0f - vert.Y;
                }
                else if (effects == (SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically))
                {
                    vert.X = 1.0f - vert.X;
                    vert.Y = 1.0f - vert.Y;
                }
                vert.Y = 1.0f - vert.Y;
                return(vert);
            }

            translateVertices      = Vector2.Zero;
            rotateVertices         = 0.0f;
            prevCalculatedPosition = position;
            prevCalculatedRotation = rotation;
        }
예제 #21
0
        private void CalculateLightVertices(List <Vector2> rayCastHits)
        {
            List <VertexPositionColorTexture> vertices = new List <VertexPositionColorTexture>();

            Vector2 drawPos = position;

            if (ParentSub != null)
            {
                drawPos += ParentSub.DrawPosition;
            }

            float cosAngle = (float)Math.Cos(Rotation);
            float sinAngle = -(float)Math.Sin(Rotation);

            Vector2 uvOffset            = Vector2.Zero;
            Vector2 overrideTextureDims = Vector2.One;

            if (overrideLightTexture != null)
            {
                overrideTextureDims = new Vector2(overrideLightTexture.SourceRect.Width, overrideLightTexture.SourceRect.Height);
                uvOffset            = (overrideLightTexture.Origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
            }

            // Add a vertex for the center of the mesh
            vertices.Add(new VertexPositionColorTexture(new Vector3(position.X, position.Y, 0),
                                                        Color.White, new Vector2(0.5f, 0.5f) + uvOffset));

            // Add all the other encounter points as vertices
            // storing their world position as UV coordinates
            for (int i = 0; i < rayCastHits.Count; i++)
            {
                Vector2 vertex = rayCastHits[i];

                //we'll use the previous and next vertices to calculate the normals
                //of the two segments this vertex belongs to
                //so we can add new vertices based on these normals
                Vector2 prevVertex = rayCastHits[i > 0 ? i - 1 : rayCastHits.Count - 1];
                Vector2 nextVertex = rayCastHits[i < rayCastHits.Count - 1 ? i + 1 : 0];

                Vector2 rawDiff = vertex - drawPos;
                Vector2 diff    = rawDiff;
                diff /= range * 2.0f;
                if (overrideLightTexture != null)
                {
                    //calculate texture coordinates based on the light's rotation
                    Vector2 originDiff = diff;

                    diff.X = originDiff.X * cosAngle - originDiff.Y * sinAngle;
                    diff.Y = originDiff.X * sinAngle + originDiff.Y * cosAngle;
                    diff  *= (overrideTextureDims / overrideLightTexture.size) * 2.0f;

                    diff += uvOffset;
                }

                //calculate normal of first segment
                Vector2 nDiff1 = vertex - nextVertex;
                float   tx     = nDiff1.X; nDiff1.X = -nDiff1.Y; nDiff1.Y = tx;
                nDiff1 /= Math.Max(Math.Abs(nDiff1.X), Math.Abs(nDiff1.Y));
                //if the normal is pointing towards the light origin
                //rather than away from it, invert it
                if (Vector2.DistanceSquared(nDiff1, rawDiff) > Vector2.DistanceSquared(-nDiff1, rawDiff))
                {
                    nDiff1 = -nDiff1;
                }

                //calculate normal of second segment
                Vector2 nDiff2 = prevVertex - vertex;
                tx      = nDiff2.X; nDiff2.X = -nDiff2.Y; nDiff2.Y = tx;
                nDiff2 /= Math.Max(Math.Abs(nDiff2.X), Math.Abs(nDiff2.Y));
                //if the normal is pointing towards the light origin
                //rather than away from it, invert it
                if (Vector2.DistanceSquared(nDiff2, rawDiff) > Vector2.DistanceSquared(-nDiff2, rawDiff))
                {
                    nDiff2 = -nDiff2;
                }

                //add the normals together and use some magic numbers to create
                //a somewhat useful/good-looking blur
                Vector2 nDiff = nDiff1 + nDiff2;
                nDiff /= Math.Max(Math.Abs(nDiff.X), Math.Abs(nDiff.Y));
                nDiff *= 50.0f;

                //finally, create the vertices
                VertexPositionColorTexture fullVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X, position.Y + rawDiff.Y, 0),
                                                                                     Color.White, new Vector2(0.5f, 0.5f) + diff);
                VertexPositionColorTexture fadeVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X + nDiff.X, position.Y + rawDiff.Y + nDiff.Y, 0),
                                                                                     Color.White * 0.0f, new Vector2(0.5f, 0.5f) + diff);

                vertices.Add(fullVert);
                vertices.Add(fadeVert);
            }

            // Compute the indices to form triangles
            List <short> indices = new List <short>();

            for (int i = 0; i < rayCastHits.Count - 1; i++)
            {
                //main light body
                indices.Add(0);
                indices.Add((short)((i * 2 + 3) % vertices.Count));
                indices.Add((short)((i * 2 + 1) % vertices.Count));

                //faded light
                indices.Add((short)((i * 2 + 1) % vertices.Count));
                indices.Add((short)((i * 2 + 3) % vertices.Count));
                indices.Add((short)((i * 2 + 4) % vertices.Count));

                indices.Add((short)((i * 2 + 2) % vertices.Count));
                indices.Add((short)((i * 2 + 1) % vertices.Count));
                indices.Add((short)((i * 2 + 4) % vertices.Count));
            }

            //main light body
            indices.Add(0);
            indices.Add((short)(1));
            indices.Add((short)(vertices.Count - 2));

            //faded light
            indices.Add((short)(1));
            indices.Add((short)(vertices.Count - 1));
            indices.Add((short)(vertices.Count - 2));

            indices.Add((short)(1));
            indices.Add((short)(2));
            indices.Add((short)(vertices.Count - 1));

            vertexCount = vertices.Count;
            indexCount  = indices.Count;

            //TODO: a better way to determine the size of the vertex buffer and handle changes in size?
            //now we just create a buffer for 64 verts and make it larger if needed
            if (lightVolumeBuffer == null)
            {
                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, Math.Max(64, (int)(vertexCount * 1.5)), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), Math.Max(64 * 3, (int)(indexCount * 1.5)), BufferUsage.None);
            }
            else if (vertexCount > lightVolumeBuffer.VertexCount || indexCount > lightVolumeIndexBuffer.IndexCount)
            {
                lightVolumeBuffer.Dispose();
                lightVolumeIndexBuffer.Dispose();

                lightVolumeBuffer      = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, (int)(vertexCount * 1.5), BufferUsage.None);
                lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), (int)(indexCount * 1.5), BufferUsage.None);
            }

            lightVolumeBuffer.SetData <VertexPositionColorTexture>(vertices.ToArray());
            lightVolumeIndexBuffer.SetData <short>(indices.ToArray());
        }
예제 #22
0
        private void DrawBatch(DrawingContext context, ref PrimitiveGroupEntry entry, Material material)
        {
            if (entry.VertexCount <= 0 && entry.IndexCount <= 0)
            {
                return;
            }

            material.texture = entry.Texture;
            material.world   = entry.World.HasValue ? entry.World.Value * AbsoluteTransform : AbsoluteTransform;
            material.BeginApply(context);

#if !WINDOWS_PHONE
            if (entry.LineWidth > 0)
            {
                if (thickLineMaterial == null)
                {
                    thickLineMaterial = new ThickLineMaterial(graphics);
                }
                thickLineMaterial.Thickness = entry.LineWidth;
                thickLineMaterial.world     = material.world;
                thickLineMaterial.BeginApply(context);
            }
#endif

            var vertexBufferSize = vertexSegments[entry.Segment + 1] - vertexSegments[entry.Segment];
#if SILVERLIGHT
            if (vertexBuffer == null || vertexBuffer.VertexCount < vertexBufferSize)
#else
            if (vertexBuffer == null || vertexBuffer.VertexCount < vertexBufferSize || vertexBuffer.IsContentLost)
#endif
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }
                vertexBuffer = new DynamicVertexBuffer(graphics, typeof(VertexPositionColorNormalTexture), Math.Max(initialBufferCapacity, vertexBufferSize), BufferUsage.WriteOnly);
            }

            context.SetVertexBuffer(null, 0);
            vertexBuffer.SetData(vertexData, vertexSegments[entry.Segment], vertexBufferSize, SetDataOptions.Discard);

            // Previous segments are not used, so use SetDataOption.Discard to boost performance.
            context.SetVertexBuffer(vertexBuffer, 0);

            if (entry.IndexCount > 0)
            {
                var indexBufferSize = indexSegments[entry.Segment + 1] - indexSegments[entry.Segment];
#if SILVERLIGHT
                if (indexBuffer == null || indexBuffer.IndexCount < indexBufferSize)
#else
                if (indexBuffer == null || indexBuffer.IndexCount < indexBufferSize || indexBuffer.IsContentLost)
#endif
                {
                    if (indexBuffer != null)
                    {
                        indexBuffer.Dispose();
                    }
                    indexBuffer = new DynamicIndexBuffer(graphics, IndexElementSize.SixteenBits, Math.Max(initialBufferCapacity, indexBufferSize), BufferUsage.WriteOnly);
                }

                graphics.Indices = null;
                indexBuffer.SetData(indexData, indexSegments[entry.Segment], indexBufferSize, SetDataOptions.Discard);

                var primitiveCount = Helper.GetPrimitiveCount(entry.PrimitiveType, entry.IndexCount);
                graphics.Indices = indexBuffer;
                graphics.DrawIndexedPrimitives(entry.PrimitiveType, 0, entry.StartVertex, entry.VertexCount, entry.StartIndex, primitiveCount);
            }
            else
            {
                var primitiveCount = Helper.GetPrimitiveCount(entry.PrimitiveType, entry.VertexCount);
                graphics.DrawPrimitives(entry.PrimitiveType, entry.StartVertex, primitiveCount);
            }

            material.EndApply(context);
        }
예제 #23
0
 protected override void DisposeNative()
 {
     nativeVertexBuffer.Dispose();
     nativeIndexBuffer.Dispose();
 }
예제 #24
0
 private void dynIndexBuffer_ContentLost(object sender, EventArgs e)
 {
     dynTerrainIndexBuffer.Dispose();
     dynTerrainIndexBuffer.SetData(indicesList.ToArray(), 0, indicesList.Count, SetDataOptions.Discard);
 }