/// <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; } } } }
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(); }
/// <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(); }
public void Dispose() { IsDisposed = true; vertexBuffer?.Dispose(); indexBuffer?.Dispose(); }
// ------------------------------------------------------------------- // DisposeBuffers // ------------------------------------------------------------------- public void DisposeBuffers(GraphicsDevice device) { device.SetVertexBuffer(null); device.Indices = null; VB.Dispose(); IB.Dispose(); }
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; } }
protected override void DisposeData() { if (vertexBuffer == null) { return; } vertexBuffer.Dispose(); indexBuffer.Dispose(); vertexBuffer = null; }
public void Dispose() { if (vertexBuffer != null) { vertexBuffer.Dispose(); } if (indexBuffer != null) { indexBuffer.Dispose(); } }
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(); } }
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; } } }
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); } }
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; }
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); }
/// <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(); } } }
protected virtual void Dispose(bool disposing) { if (disposing) { if (vertexBuffer != null) { vertexBuffer.Dispose(); } if (indexBuffer != null) { indexBuffer.Dispose(); } if (basicEffect != null) { basicEffect.Dispose(); } } }
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(); }
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()); }
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; }
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()); }
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); }
protected override void DisposeNative() { nativeVertexBuffer.Dispose(); nativeIndexBuffer.Dispose(); }
private void dynIndexBuffer_ContentLost(object sender, EventArgs e) { dynTerrainIndexBuffer.Dispose(); dynTerrainIndexBuffer.SetData(indicesList.ToArray(), 0, indicesList.Count, SetDataOptions.Discard); }