private void Allocate() { if (vertexBuffer == null || vertexBuffer.IsDisposed) { vertexBuffer = new DynamicVertexBuffer(graphicsDevice, typeof(VertexPositionColorTexture), 8192, BufferUsage.WriteOnly); vertexBufferPosition = 0; vertexBuffer.ContentLost += delegate { vertexBufferPosition = 0; }; } if (indexBuffer != null && !indexBuffer.IsDisposed) { return; } if (fallbackIndexData == null) { fallbackIndexData = new short[12288]; for (int i = 0; i < 2048; i++) { fallbackIndexData[i * 6] = (short)(i * 4); fallbackIndexData[i * 6 + 1] = (short)(i * 4 + 1); fallbackIndexData[i * 6 + 2] = (short)(i * 4 + 2); fallbackIndexData[i * 6 + 3] = (short)(i * 4); fallbackIndexData[i * 6 + 4] = (short)(i * 4 + 2); fallbackIndexData[i * 6 + 5] = (short)(i * 4 + 3); } } indexBuffer = new DynamicIndexBuffer(graphicsDevice, typeof(short), 12288, BufferUsage.WriteOnly); indexBuffer.SetData(fallbackIndexData); indexBuffer.ContentLost += delegate { indexBuffer.SetData(fallbackIndexData); }; }
/// <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 static void LoadContent() { _iboQuad = new DynamicIndexBuffer(Device, IndexElementSize.SixteenBits, MAX_QUADS * 6, BufferUsage.WriteOnly); _iboQuad.SetData(QuadIndices, 0, MAX_QUADS * 6); _iboFan = new DynamicIndexBuffer(Device, IndexElementSize.SixteenBits, MAX_QUADS * 3, BufferUsage.WriteOnly); _iboFan.SetData(FanIndices, 0, MAX_QUADS * 3); }
/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // Compute camera matrices. Matrix View = Matrix.CreateLookAt(eye, at, up); Matrix Projection = Matrix.CreatePerspectiveFieldOfView(fov, GraphicsDevice.Viewport.AspectRatio, zNear, zFar); cubeRotation += (0.0025f) * (float)gameTime.ElapsedGameTime.TotalMilliseconds; Matrix World = Matrix.CreateRotationY(cubeRotation); // TODO: Add your drawing code here vertexBuffer.SetData(cube, 0, 8, SetDataOptions.Discard); indexBuffer.SetData(cubeIndices, 0, 36, SetDataOptions.Discard); GraphicsDevice device = basicEffect.GraphicsDevice; device.SetVertexBuffer(vertexBuffer); device.Indices = indexBuffer; basicEffect.View = View; basicEffect.Projection = Projection; basicEffect.World = World; foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { pass.Apply(); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 36); } base.Draw(gameTime); }
private void SetUpBuffers() { v_buffer = new DynamicVertexBuffer(Game.device, VertexPositionTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); i_buffer = new DynamicIndexBuffer(Game.device, typeof(int), indices.Length, BufferUsage.WriteOnly); v_buffer.SetData(vertices); i_buffer.SetData(indices); }
public void BeginRender(Vertex[] vertexBuffer, int[] indexBuffer, int vertexCount, int indexCount) { EnsureBufferSize(vertexCount, indexCount); _vertexBuffer.SetData(vertexBuffer, 0, vertexCount); _indexBuffer.SetData(indexBuffer, 0, indexCount); GraphicsDevice.SetVertexBuffer(_vertexBuffer); GraphicsDevice.Indices = _indexBuffer; }
/// <summary> /// Draws vertices from vertex buffer and empties it. /// </summary> private static void DrawVertices() { BasicEffect.View = CurrentTransformMatrix; __drawcalls += 1; if (_vertices.Count > 0) { BasicEffect.Texture = _currentTexture; BasicEffect.TextureEnabled = (_currentTexture != null); PrimitiveType type; int prCount; if (_currentPipelineMode == PipelineMode.OutlinePrimitives) { type = PrimitiveType.LineList; prCount = _indices.Count / 2; } else { type = PrimitiveType.TriangleList; prCount = _indices.Count / 3; } // Passing primitive data to the buffers. _vertexBuffer.SetData(_vertices.ToArray(), 0, _vertices.Count, SetDataOptions.None); _indexBuffer.SetData(_indices.ToArray(), 0, _indices.Count); // Passing primitive data to the buffers. if (_rasterizer != null) { Device.RasterizerState = _rasterizer; } if (_sampler != null) { Device.SamplerStates[0] = _sampler; } Device.ScissorRectangle = _scissorRectangle; foreach (EffectPass pass in BasicEffect.CurrentTechnique.Passes) { pass.Apply(); Device.DrawIndexedPrimitives(type, 0, 0, prCount); } _vertices.Clear(); _indices.Clear(); } }
void AllocateBuffers() { if (vertexBuffer == null || vertexBuffer.IsDisposed == true) { vertexBuffer = new DynamicVertexBuffer(graphicsDevice, typeof(GlyphVertex), vertexBufferSize, BufferUsage.WriteOnly); vertexBufferPosition = 0; } if (indexBuffer == null || indexBuffer.IsDisposed == true) { indexBuffer = new DynamicIndexBuffer(graphicsDevice, typeof(short), indexBufferSize, BufferUsage.WriteOnly); indexBuffer.SetData <short>(CreateIndexData()); } }
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); } }
public GUIRenderer(IGUIMapper mapper, Matrix renderMatrix /*, CollisionObject colObj*/) { this.mapper = mapper; this.renderMatrix = renderMatrix; //this.colObj = colObj; guiTexture = new Texture2D(State.Device, mapper.GUIWidth, mapper.GUIHeight, false, mapper.TextureFormat); texCoords = new VertexPositionTexture[4]; // Calculate the GUI positions where it will rendered in the 3D world Matrix texPos = Matrix.Identity; width = guiTexture.Width * mapper.DrawingScaleFactor.X / 2; height = guiTexture.Height * mapper.DrawingScaleFactor.Y / 2; texCoords[0].Position = new Vector3(-width, height, 0); texCoords[0].TextureCoordinate = new Vector2(0, 1); texCoords[1].Position = new Vector3(width, -height, 0); texCoords[1].TextureCoordinate = new Vector2(1, 0); texCoords[2].Position = new Vector3(-width, -height, 0); texCoords[2].TextureCoordinate = new Vector2(0, 0); texCoords[3].Position = new Vector3(width, height, 0); texCoords[3].TextureCoordinate = new Vector2(1, 1); vb = new DynamicVertexBuffer(State.Device, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.WriteOnly); vb.SetData(texCoords); short[] indices = new short[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 3; indices[4] = 1; indices[5] = 0; ib = new DynamicIndexBuffer(State.Device, typeof(short), 6, BufferUsage.WriteOnly); ib.SetData(indices); textureData = mapper.GUITexture; //colObj = GoblinSetting.UICollisionWorld.Add2Dto3DGUI(new Vector2(width * 2, height * 2), // renderMatrix, mapper.GetGUIName()); }
protected override unsafe void SetBuffers(byte[] vertices, ushort[] indices, int indicesCount, int vertexCount) { if (vertexCount == 0) { return; } var result = new VertexPositionColorTexture[vertexCount]; fixed(VertexPositionColorTexture *vx = &result[0]) { var b = (byte *)vx; for (int i = 0; i < vertexCount * sizeof(VertexPositionColorTexture); i++) { *(b + i) = vertices[i]; } } for (var i = 0; i < vertexCount; i++) { var c = result[i].Color; result[i].Color = new Color(c.B, c.G, c.R, c.A); } if (_vertexBuffer.VertexCount < result.Length) { // Resize vertex buffer if data doesnt fit _vertexBuffer = new DynamicVertexBuffer(_device, VertexPositionColorTexture.VertexDeclaration, result.Length * 2, BufferUsage.WriteOnly); } _vertexBuffer.SetData(result); if (_indexBuffer.IndexCount < indicesCount) { // Resize index buffer if data doesnt fit _indexBuffer = new DynamicIndexBuffer(_device, typeof(ushort), indicesCount * 2, BufferUsage.WriteOnly); } _indexBuffer.SetData(indices, 0, indicesCount); }
protected override void LoadContent() { device = graphics.GraphicsDevice; basicEffect = new BasicEffect(device, null); cCross = new CoordCross(device); grassTexture = Content.Load <Texture2D>("grass"); Texture2D heightMap = Content.Load <Texture2D>("heightmap"); heightData = LoadHeightData(heightMap); myVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements); VertexPositionNormalTexture[] terrainVertices = CreateTerrainVertices(); int[] terrainIndices = CreateTerrainIndices(); terrainVertices = GenerateNormalsForTriangleStrip(terrainVertices, terrainIndices); terrainVertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.SizeInBytes * terrainVertices.Length, BufferUsage.WriteOnly); terrainVertexBuffer.SetData(terrainVertices); int terrainSize = 1024; Triangle leftTriangle = new Triangle(null, new Vector2(0, 0), new Vector2(terrainSize, 0), new Vector2(0, terrainSize), heightData); Triangle rightTriangle = new Triangle(null, new Vector2(terrainSize, terrainSize), new Vector2(0, terrainSize), new Vector2(terrainSize, 0), heightData); leftTriangle.AddNeighs(null, null, rightTriangle); rightTriangle.AddNeighs(null, null, leftTriangle); triangleList = new List <Triangle>(); triangleList.Add(leftTriangle); triangleList.Add(rightTriangle); indicesList = new List <int>(); foreach (Triangle t in triangleList) { t.AddIndices(ref indicesList); } dynTerrainIndexBuffer = new DynamicIndexBuffer(device, typeof(int), indicesList.Count, BufferUsage.WriteOnly); dynTerrainIndexBuffer.SetData(indicesList.ToArray(), 0, indicesList.Count, SetDataOptions.Discard); dynTerrainIndexBuffer.ContentLost += new EventHandler(dynIndexBuffer_ContentLost); orthoView = Matrix.CreateLookAt(new Vector3(terrainSize / 2, 100, -terrainSize / 2), new Vector3(terrainSize / 2, 0, -terrainSize / 2), Vector3.Forward); orthoProj = Matrix.CreateOrthographic(terrainSize, terrainSize, 1, 1000); }
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; } } }
protected override void LoadModel(GraphicFactory factory, out BatchInformation[][] BatchInformations, out TextureInformation[][] TextureInformation) { vertexBufferS = factory.CreateDynamicVertexBuffer(VertexPositionTexture.VertexDeclaration, vertices.Count(), BufferUsage.None); vertexBufferS.SetData(vertices); int noVertices = vertices.Count(); int noTriangles = indices.Count() / 3; indexBufferS = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, indices.Count(), BufferUsage.None); indexBufferS.SetData(indices); BatchInformations = new BatchInformation[1][]; BatchInformation[] b = new BatchInformation[1]; b[0] = new BatchInformation(0, noVertices, noTriangles, 0, 0, VertexPositionTexture.VertexDeclaration, VertexPositionTexture.VertexDeclaration.VertexStride, BatchType.INDEXED); b[0].VertexBuffer = vertexBufferS; b[0].IndexBuffer = indexBufferS; BatchInformations[0] = b; TextureInformation = new TextureInformation[1][]; TextureInformation[0] = new TextureInformation[1]; TextureInformation[0][0] = new TextureInformation(false, factory); TextureInformation[0][0].SetTexture(diffuseName, TextureType.DIFFUSE); }
// Draw any queued objects and reset our line buffers private void FlushDrawing() { if (IndexCount > 0) { vertexBuffer.SetData(Vertices, 0, VertexCount, SetDataOptions.Discard); indexBuffer.SetData(Indices, 0, IndexCount, SetDataOptions.Discard); GraphicsDevice device = basicEffect.GraphicsDevice; device.SetVertexBuffer(vertexBuffer); device.Indices = indexBuffer; foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { pass.Apply(); device.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, VertexCount, 0, IndexCount / 2); } device.SetVertexBuffer(null); device.Indices = null; } IndexCount = 0; VertexCount = 0; }
// ------------------------------------------------------------------- // CreateTex : coords = [x,y,width,height] // ------------------------------------------------------------------- public void CreateTex(int[] coords, Texture2D texture) { // Texture coords float left = ((float)coords[0]) / texture.Width; float top = ((float)coords[1]) / texture.Height; float bot = ((float)(coords[1] + coords[3])) / texture.Height; float right = ((float)(coords[0] + coords[2])) / texture.Width; // Adjust in order to limit risk of textures flood float width = left + right; float height = top + bot; int coef = 10000; left += width / coef; right -= width / coef; top += height / coef; bot -= height / coef; // Vertex Position and Texture Vertices = new VertexPositionTexture[] { new VertexPositionTexture(WANOK.VERTICESFLOOR[0], new Vector2(left, top)), new VertexPositionTexture(WANOK.VERTICESFLOOR[1], new Vector2(right, top)), new VertexPositionTexture(WANOK.VERTICESFLOOR[2], new Vector2(right, bot)), new VertexPositionTexture(WANOK.VERTICESFLOOR[3], new Vector2(left, bot)) }; // Vertex Indexes Indexes = new int[] { 0, 1, 2, 0, 2, 3 }; // Update buffers VB.SetData(Vertices); IB.SetData(Indexes); }
/// <summary> /// Ends line drawing and resores render states. /// </summary> public void End() { if (_indexCount > 0) { _vertexBuffer.SetData(_vertices, 0, _vertexCount, SetDataOptions.Discard); _indexBuffer.SetData(_indices, 0, _indexCount, SetDataOptions.Discard); GraphicsDevice graphicsDevice = _basicEffect.GraphicsDevice; graphicsDevice.SetVertexBuffer(_vertexBuffer); graphicsDevice.Indices = _indexBuffer; foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, _vertexCount, 0, _indexCount / 2); } graphicsDevice.SetVertexBuffer(null); graphicsDevice.Indices = null; } _indexCount = 0; _vertexCount = 0; }
protected override void AddDataNative <VertexType>(Chunk textureChunk, VertexType[] vertexData, short[] indices, int numberOfVertices, int numberOfIndices) { nativeDevice.SetVertexBuffer(null); nativeVertexBuffer.SetData(totalVertexOffsetInBytes, vertexData, 0, numberOfVertices, vertexSize, currentDataHint); if (!UsesIndexBuffer) { currentDataHint = SetDataOptions.Discard; return; } nativeDevice.Indices = null; if (indices == null) { indices = ComputeIndices(textureChunk.NumberOfVertices, numberOfVertices); } else if (textureChunk.FirstVertexOffsetInBytes > 0) { indices = RemapIndices(indices, numberOfIndices); } nativeIndexBuffer.SetData(totalIndexOffsetInBytes, indices, 0, numberOfIndices, currentDataHint); currentDataHint = SetDataOptions.Discard; }
private void RenderFilledItems(GraphicsDevice graphicsDevice, ref Matrix world, ref Matrix view, ref Matrix projection) { if (_batchFilledItems.Count == 0) { return; } if (_vertexBuffer == null || _vertexBuffer.VertexCount < _filledVerticesCount) { _vertexBuffer = new DynamicVertexBuffer(graphicsDevice, VertexPositionColorTexture.VertexDeclaration, _filledVerticesCount, BufferUsage.WriteOnly); } if (_indexBuffer == null || _indexBuffer.IndexCount < _filledIndicesCount) { _indexBuffer = new DynamicIndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, _filledIndicesCount, BufferUsage.WriteOnly); } int vertexId = 0, indexId = 0; int[] indices = new int[_filledIndicesCount]; VertexPositionColorTexture[] vertices = new VertexPositionColorTexture[_filledVerticesCount]; foreach (PrimitiveBatchItem batchItem in _batchFilledItems) { System.Array.Copy(batchItem.VertexData, 0, vertices, vertexId, batchItem.VertexData.Length); for (int i = 0; i < batchItem.IndexData.Length; i++) { indices[indexId + i] = vertexId + batchItem.IndexData[i]; } vertexId += batchItem.VertexData.Length; indexId += batchItem.IndexData.Length; } _vertexBuffer.SetData( vertices, 0, vertices.Length, SetDataOptions.Discard ); _indexBuffer.SetData( indices, 0, indices.Length, SetDataOptions.Discard ); BasicShader shader = Shader as BasicShader; // transformations shader.World = world; shader.View = view; shader.Projection = projection; shader.DiffuseColor = Color.White; shader.Alpha = 1f; shader.TextureEnabled = false; graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.None; foreach (object pass in shader) { graphicsDevice.Indices = _indexBuffer; graphicsDevice.SetVertexBuffer(_vertexBuffer); graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertexBuffer.VertexCount, 0, indexId / 3); } shader.ResetParameters(); #if DEBUG TotalFilledDrawCalls++; #endif }
private void CreateVerticies() { Indexes = new ushort[36]; FlippedIndexes = new ushort[36]; Vertices = new ExtendedVertex[NumVertices]; // Calculate the position of the vertices on the top face. Vector3 topLeftFront = new Vector3(0.0f, Height, 0.0f); Vector3 topLeftBack = new Vector3(0.0f, Height, 1.0f); Vector3 topRightFront = new Vector3(Width, Height, 0.0f); Vector3 topRightBack = new Vector3(Width, Height, 1.0f); // Calculate the position of the vertices on the bottom face. Vector3 btmLeftFront = new Vector3(0.0f, 0.0f, 0.0f); Vector3 btmLeftBack = new Vector3(0.0f, 0.0f, 1.0f); Vector3 btmRightFront = new Vector3(Width, 0.0f, 0.0f); Vector3 btmRightBack = new Vector3(Width, 0.0f, 1.0f); // Normal vectors for each face (needed for lighting / display) // Add the vertices for the FRONT face. Vertices[0] = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[0], UVs.Bounds[0]); Vertices[1] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[1], UVs.Bounds[0]); Vertices[2] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[2], UVs.Bounds[0]); Vertices[3] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[3], UVs.Bounds[0]); /* * 0 . . . 3 * . . . * . . . * . . . * 1 . . . 2 */ Indexes[0] = 0; Indexes[1] = 1; Indexes[2] = 3; Indexes[3] = 3; Indexes[4] = 1; Indexes[5] = 2; /* * 0 . . . 3 * . . . * . . . * . . . * 1 . . . 2 */ FlippedIndexes[0] = 0; FlippedIndexes[1] = 1; FlippedIndexes[2] = 2; FlippedIndexes[3] = 3; FlippedIndexes[4] = 0; FlippedIndexes[5] = 2; // Add the vertices for the BACK face. Vertices[4] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[4], UVs.Bounds[1]); Vertices[5] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[5], UVs.Bounds[1]); Vertices[6] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[6], UVs.Bounds[1]); Vertices[7] = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[7], UVs.Bounds[1]); /* * 4 . . . 7 * . . . * . . . * . . . * 5 . . . 6 */ Indexes[6] = 4; Indexes[7] = 5; Indexes[8] = 7; Indexes[9] = 7; Indexes[10] = 5; Indexes[11] = 6; /* * 4 . . . 7 * . . . * . . . * . . . * 5 . . . 6 */ FlippedIndexes[6] = 4; FlippedIndexes[7] = 5; FlippedIndexes[8] = 6; FlippedIndexes[9] = 6; FlippedIndexes[10] = 7; FlippedIndexes[11] = 4; // Add the vertices for the TOP face. Vertices[8] = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[8], UVs.Bounds[2]); Vertices[9] = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[9], UVs.Bounds[2]); Vertices[10] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[10], UVs.Bounds[2]); Vertices[11] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[11], UVs.Bounds[2]); /* * 8 . . .11 * . . . * . . . * . . . * 9 . . . 10 */ Indexes[12] = 8; Indexes[13] = 9; Indexes[14] = 11; Indexes[15] = 10; Indexes[16] = 11; Indexes[17] = 9; /* * 8 . . .11 * . . . * . . . * . . . * 9 . . .10 */ FlippedIndexes[12] = 8; FlippedIndexes[13] = 10; FlippedIndexes[14] = 11; FlippedIndexes[15] = 10; FlippedIndexes[16] = 8; FlippedIndexes[17] = 9; // Add the vertices for the BOTTOM face. Vertices[12] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[12], UVs.Bounds[3]); Vertices[13] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[13], UVs.Bounds[3]); Vertices[14] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[14], UVs.Bounds[3]); Vertices[15] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[15], UVs.Bounds[3]); /* * 12. . .15 * . . . * . . . * . . . * 13. . .14 */ Indexes[18] = 12; Indexes[19] = 13; Indexes[20] = 15; Indexes[21] = 15; Indexes[22] = 13; Indexes[23] = 14; /* * 12. . .15 * . . . * . . . * . . . * 13. . .14 */ FlippedIndexes[18] = 12; FlippedIndexes[19] = 13; FlippedIndexes[20] = 14; FlippedIndexes[21] = 15; FlippedIndexes[22] = 12; FlippedIndexes[23] = 14; // Add the vertices for the LEFT face. Vertices[16] = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[16], UVs.Bounds[4]); Vertices[17] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[17], UVs.Bounds[4]); Vertices[18] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[18], UVs.Bounds[4]); Vertices[19] = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[19], UVs.Bounds[4]); /* * 16. . .19 * . . . * . . . * . . . * 17. . .18 */ Indexes[24] = 16; Indexes[25] = 17; Indexes[26] = 19; Indexes[27] = 18; Indexes[28] = 19; Indexes[29] = 17; /* * 16. . .19 * . . . * . . . * . . . * 17. . .18 */ FlippedIndexes[24] = 16; FlippedIndexes[25] = 17; FlippedIndexes[26] = 18; FlippedIndexes[27] = 18; FlippedIndexes[28] = 19; FlippedIndexes[29] = 16; // Add the vertices for the RIGHT face. Vertices[20] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[20], UVs.Bounds[5]); Vertices[21] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[21], UVs.Bounds[5]); Vertices[22] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[22], UVs.Bounds[5]); Vertices[23] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[23], UVs.Bounds[5]); /* * 20. . .23 * . . . * . . . * . . . * 21. . .22 */ Indexes[30] = 20; Indexes[31] = 21; Indexes[32] = 23; Indexes[33] = 23; Indexes[34] = 21; Indexes[35] = 22; /* * 20. . .23 * . . . * . . . * . . . * 21. . .22 */ FlippedIndexes[30] = 20; FlippedIndexes[31] = 21; FlippedIndexes[32] = 22; FlippedIndexes[33] = 23; FlippedIndexes[34] = 20; FlippedIndexes[35] = 22; try { IndexBuffer = new DynamicIndexBuffer(GameState.Game.GraphicsDevice, typeof(ushort), Indexes.Length, BufferUsage.WriteOnly); IndexBuffer.SetData(Indexes); } catch (Exception exception) { IndexBuffer = null; } Faces = new List <FaceDescriptor> { new FaceDescriptor { Face = BoxFace.Top, VertexCount = 4, IndexCount = 6, IndexOffset = 12, VertexOffset = 8 }, new FaceDescriptor { Face = BoxFace.Bottom, VertexCount = 4, IndexCount = 6, IndexOffset = 18, VertexOffset = 12 }, new FaceDescriptor { Face = BoxFace.Left, VertexCount = 4, IndexCount = 6, IndexOffset = 24, VertexOffset = 16 }, new FaceDescriptor { Face = BoxFace.Right, VertexCount = 4, IndexCount = 6, IndexOffset = 30, VertexOffset = 20 }, new FaceDescriptor { Face = BoxFace.Front, VertexCount = 4, IndexCount = 6, IndexOffset = 0, VertexOffset = 0 }, new FaceDescriptor { Face = BoxFace.Back, VertexCount = 4, IndexCount = 6, IndexOffset = 6, VertexOffset = 4 }, }; }
// SpriteManager public SpriteManager() { #if !RELEASE RasterizerState_WireFrame = new RasterizerState(); RasterizerState_WireFrame.FillMode = FillMode.WireFrame; #endif GraphicsDevice = _UI.Game.GraphicsDevice; PresentationParameters pp = GraphicsDevice.PresentationParameters; BackBufferSize = new Vector2(pp.BackBufferWidth, pp.BackBufferHeight); SpriteCountMax = _UI.Settings.Sprite_Count; Sprites = new Sprite[SpriteCountMax]; SpriteCount = 0; CurrentSprite = 0; HasBatched = new bool[_UI.Settings.Sprite_RenderPassCount]; TopLayer = _UI.Settings.Sprite_LayerCount - 1; RenderPassLayerSprites = new List <List <int>[]>(_UI.Settings.Sprite_RenderPassCount); RenderPass3dMask = _UI.Settings.Sprite_RenderPass3dMask; for (int i = 0; i < _UI.Settings.Sprite_RenderPassCount; ++i) { List <int>[] layerSprites = new List <int> [_UI.Settings.Sprite_LayerCount]; for (int j = 0; j < layerSprites.Length; ++j) { layerSprites[j] = new List <int>(); } RenderPassLayerSprites.Add(layerSprites); } PreMatrixPool = new Matrix[_UI.Settings.Sprite_PreMatrixCount]; PreMatrixCount = 0; PostMatrixPool = new Matrix[_UI.Settings.Sprite_PostMatrixCount]; PostMatrixCount = 0; Matrix identity = Matrix.Identity; // reserve identity StorePreMatrix(ref identity); StorePostMatrix(ref identity); RenderStatePool = new object[_UI.Settings.Sprite_RenderStateCount]; RenderStateCount = 0; // default renderstates StoreRenderState(DepthStencilState.None); StoreRenderState(RasterizerState.CullNone); RenderStateStack_Blend = new Stack <int>(_UI.Settings.Sprite_RenderStateStackCount); RenderStateStack_DepthStencil = new Stack <int>(_UI.Settings.Sprite_RenderStateStackCount); RenderStateStack_Rasterizer = new Stack <int>(_UI.Settings.Sprite_RenderStateStackCount); VertexCorners = new Vector2[VertexCount] { new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), }; VertexCornersFlipped = new Vector2[VertexCount] { new Vector2(0.0f, 1.0f), new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f), new Vector2(0.0f, 0.0f), }; VertexOffsetAligned = new Vector2[(int)E_Align.Count] { new Vector2(0.0f, 0.0f), // None new Vector2(0.0f, 0.0f), // TopLeft new Vector2(0.5f, 0.0f), // TopCentre new Vector2(1.0f, 0.0f), // TopRight new Vector2(0.0f, 0.5f), // MiddleLeft new Vector2(0.5f, 0.5f), // MiddleCentre new Vector2(1.0f, 0.5f), // MiddleRight new Vector2(0.0f, 1.0f), // BottomLeft new Vector2(0.5f, 1.0f), // BottomCentre new Vector2(1.0f, 1.0f), // BottomRight }; VertexOffsetAlignedFlipped = new Vector2[(int)E_Align.Count] { new Vector2(0.0f, 1.0f), // None new Vector2(0.0f, 1.0f), // TopLeft new Vector2(0.5f, 1.0f), // TopCentre new Vector2(1.0f, 1.0f), // TopRight new Vector2(0.0f, 0.5f), // MiddleLeft new Vector2(0.5f, 0.5f), // MiddleCentre new Vector2(1.0f, 0.5f), // MiddleRight new Vector2(0.0f, 0.0f), // BottomLeft new Vector2(0.5f, 0.0f), // BottomCentre new Vector2(1.0f, 0.0f), // BottomRight }; VertexCornersAligned = new Vector3[(int)E_Align.Count][]; for (int i = 0; i < VertexCornersAligned.Length; ++i) { VertexCornersAligned[i] = new Vector3[VertexCount]; } VertexCornersAlignedFlipped = new Vector3[(int)E_Align.Count][]; for (int i = 0; i < VertexCornersAlignedFlipped.Length; ++i) { VertexCornersAlignedFlipped[i] = new Vector3[VertexCount]; } for (int i = 0; i < (int)E_Align.Count; ++i) { for (int j = 0; j < VertexCount; ++j) { VertexCornersAligned[i][j] = new Vector3(VertexCorners[j] - VertexOffsetAligned[i], 0.0f); VertexCornersAlignedFlipped[i][j] = new Vector3(VertexCornersFlipped[j] - VertexOffsetAlignedFlipped[i], 0.0f); } } TransformMatrix2D = Matrix.CreateTranslation(-0.5f, -0.5f, 0.0f) * Matrix.CreateOrthographicOffCenter(0.0f, pp.BackBufferWidth, pp.BackBufferHeight, 0.0f, -1500.0f, 1500.0f); TransformMatrix = TransformMatrix2D; // default RenderPassTransformMatrix = new Matrix[_UI.Settings.Sprite_RenderPassCount]; for (int i = 0; i < RenderPassTransformMatrix.Length; ++i) { RenderPassTransformMatrix[i] = Matrix.Identity; } AutoTransformIndex = 0; AutoTransformOffset = new Vector3(); VertexData = new VertexSprite[VertexCount * SpriteCountMax]; VertexPosition = 0; DynamicVB = new DynamicVertexBuffer(GraphicsDevice, VertexSprite.VertexDeclaration, SpriteCountMax * VertexCount, BufferUsage.WriteOnly); #if WINDOWS DynamicVB.ContentLost += ((sender, e) => { VertexPosition = 0; }); #endif short primitiveCount = 0; short[] dataIB = new short[SpriteCountMax * IndexCount]; for (int i = 0; i < dataIB.Length;) { short offset = (short)(primitiveCount * VertexCount); dataIB[i++] = (short)(0 + offset); dataIB[i++] = (short)(1 + offset); dataIB[i++] = (short)(2 + offset); dataIB[i++] = (short)(2 + offset); dataIB[i++] = (short)(3 + offset); dataIB[i++] = (short)(0 + offset); ++primitiveCount; } DynamicIB = new DynamicIndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, SpriteCountMax * IndexCount, BufferUsage.WriteOnly); DynamicIB.SetData(dataIB); #if WINDOWS DataIB = dataIB; DynamicIB.ContentLost += ((sender, e) => { DynamicIB.SetData(DataIB); }); #endif }
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()); }
public override void UpdateGeometry(GraphicsDevice device) { rand = new Random(Seed); List <Branch> branches = new List <Branch>(); List <Leaf> leaves = new List <Leaf>(); float step = .4f; float max = step + MathHelper.Clamp(1f - TimeLeft / TimeToMature, 0, 1) * (height - step); branches.Add(new Branch(Vector3.Zero, Matrix.CreateRotationX(MathHelper.PiOver2), step)); Vector3 last = new Vector3(0, step, 0); float h = step; while (h < max) { float y = Math.Min(max, h + step) - h; for (float i = 0; i < MathHelper.TwoPi;) { leaves.Add(new Leaf(last + new Vector3(0, step * (float)rand.NextDouble(), 0), Matrix.CreateRotationX((float)rand.NextDouble() * MathHelper.PiOver2 * .5f) * Matrix.CreateRotationY(i), .3f + (float)rand.NextDouble() * .3f)); i += .5f + (float)rand.NextDouble() * 2; } Branch b = new Branch(last, Matrix.CreateRotationX(MathHelper.PiOver2), y); branches.Add(b); last = b.End; h += y; } List <VertexPositionColorNormal> verts = new List <VertexPositionColorNormal>(); List <int> tris = new List <int>(); float r = .05f; int sides = 6; #region branch geometry foreach (Branch b in branches) { float x1 = b.Start.Y / max, x2 = b.End.Y / max; float r1 = r * MathHelper.Clamp(-(float)Math.Pow(x1, 7) + 1, 0, 1); float r2 = r * MathHelper.Clamp(-(float)Math.Pow(x2, 7) + 1, 0, 1); int bi = verts.Count; for (int s = 0; s < sides; s++) { Matrix m = b.Direction * Matrix.CreateRotationY((s / (float)sides) * MathHelper.TwoPi); verts.Add(new VertexPositionColorNormal(b.Start + m.Up * r1, Color.Green, m.Up)); verts.Add(new VertexPositionColorNormal(b.End + m.Up * r2, Color.Green, m.Up)); } // cap on final branch if (b.Equals(branches[branches.Count - 1])) { verts.Add(new VertexPositionColorNormal(b.End + b.Direction.Forward * .15f, Color.Green, b.Direction.Forward)); } for (int i = 0; i < sides * 2; i += 2) { int i0 = i, i1 = i + 1, i2 = (i + 2) % (sides * 2), i3 = (i + 3) % (sides * 2); tris.AddRange(new int[] { bi + i0, bi + i3, bi + i2, bi + i0, bi + i1, bi + i3 }); // cap on final branch if (b.Equals(branches[branches.Count - 1])) { tris.AddRange(new int[] { verts.Count - 1, bi + i3, bi + i1 }); } } } #endregion #region leaf generation foreach (Leaf l in leaves) { if (l.Position.Y < max * .75f) { float scale = MathHelper.Clamp(max / height, 0, 1); // do twice (top & bottom) for (int x = 0; x < 2; x++) { int bi = verts.Count; Matrix m = l.Direction; Vector3 p = l.Position; for (int i = 0; i < 3; i++) { float d = r; if (i == 0) { d *= .6f; } else if (i == 1) { d *= 1.1f; } if (x == 0) { verts.Add(new VertexPositionColorNormal(p + m.Left * d * scale, Color.Green, m.Up)); verts.Add(new VertexPositionColorNormal(p + m.Right * d * scale, Color.Green, m.Up)); } else { verts.Add(new VertexPositionColorNormal(p + m.Right * d * scale, Color.Green, m.Down)); verts.Add(new VertexPositionColorNormal(p + m.Left * d * scale, Color.Green, m.Down)); } m *= Matrix.CreateRotationX(l.Drop * .3333f * scale); p += m.Forward * 2 * r * scale; } if (x == 0) { verts.Add(new VertexPositionColorNormal(p + m.Forward * r * scale, Color.Green, m.Up)); } else { verts.Add(new VertexPositionColorNormal(p + m.Forward * r * scale, Color.Green, m.Down)); } tris.AddRange(new int[] { bi, bi + 2, bi + 1, bi + 1, bi + 2, bi + 3, bi + 2, bi + 4, bi + 3, bi + 3, bi + 4, bi + 5, bi + 4, bi + 6, bi + 5 }); } } } #endregion // set data //if (VBuffer == null) VBuffer = new DynamicVertexBuffer(device, typeof(VertexPositionColorNormal), verts.Count, BufferUsage.WriteOnly); VBuffer.SetData(verts.ToArray()); //if (IBuffer == null) IBuffer = new DynamicIndexBuffer(device, typeof(int), tris.Count, BufferUsage.WriteOnly); IBuffer.SetData(tris.ToArray()); }
public void SetIndices(short[] indices) { indexBuffer.SetData(0, indices, 0, indices.Length, SetDataOptions.Discard); }
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; }
public void Setup(int columns, int rows, Size tileSize) { if (Columns == columns && Rows == rows && TileSize == tileSize) { return; } Columns = columns; Rows = rows; TileSize = tileSize; Size = new Size(Columns, Rows) * tileSize; if (Columns == 0 || Rows == 0) { return; } VertexPositionColor[] vertices = new VertexPositionColor[(Columns + Rows) * 2]; int[] indices = new int[vertices.Length + 4]; if (_vertexBuffer == null || vertices.Length > _vertexBuffer.VertexCount) { _vertexBuffer = new DynamicVertexBuffer(Game.Instance.GraphicsDevice, VertexPositionColor.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); } if (_indexBuffer == null || indices.Length > _indexBuffer.IndexCount) { _indexBuffer = new DynamicIndexBuffer(Game.Instance.GraphicsDevice, IndexElementSize.ThirtyTwoBits, indices.Length, BufferUsage.WriteOnly); } // // Vertices layout: // //(n-4)--4----6--(n-3) // | | | | // | | | | // 0----+----+----1 // | | | | // | | | | // 2----+----+----3 // | | | | // | | | | //(n-1)--5----7--(n-2) // int id = 0; // vertex/index id for (int row = 1; row < Rows; row++, id += 2) { vertices[id] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(0f, row * TileSize.Height, 0f), Color.White); vertices[id + 1] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(Columns * TileSize.Width, row * TileSize.Height, 0f), Color.White); indices[id] = id; indices[id + 1] = id + 1; } for (int column = 1; column < Columns; column++, id += 2) { vertices[id] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(column * TileSize.Width, 0f, 0f), Color.White); vertices[id + 1] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(column * TileSize.Width, Rows * TileSize.Height, 0f), Color.White); indices[id] = id; indices[id + 1] = id + 1; } // top-left vertices[id] = new VertexPositionColor(Microsoft.Xna.Framework.Vector3.Zero, Color.White); // top-right vertices[id + 1] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(Columns * TileSize.Width, 0f, 0f), Color.White); // bottom-right vertices[id + 2] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(Columns * TileSize.Width, Rows * TileSize.Height, 0f), Color.White); // bottom-left vertices[id + 3] = new VertexPositionColor(new Microsoft.Xna.Framework.Vector3(0f, Rows * TileSize.Height, 0f), Color.White); // top border indices[id] = 0; indices[id + 1] = 1; // right border indices[id + 2] = 1; indices[id + 3] = 2; // bottom border indices[id + 4] = 2; indices[id + 5] = 3; // left border indices[id + 6] = 3; indices[id + 7] = 0; _usingVerticesCount = vertices.Length; _usingIndicesCount = indices.Length; _vertexBuffer.SetData(vertices, 0, vertices.Length, SetDataOptions.Discard); _indexBuffer.SetData(indices, 0, indices.Length, SetDataOptions.Discard); }
private void dynIndexBuffer_ContentLost(object sender, EventArgs e) { dynTerrainIndexBuffer.Dispose(); dynTerrainIndexBuffer.SetData(indicesList.ToArray(), 0, indicesList.Count, SetDataOptions.Discard); }
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); }