// Do not delete: Used to generate block icon texture for menu. public static Texture2D RenderIcons(GraphicsDevice device, Shader shader, ChunkManager chunks, int width, int height, int tileSize) { if (width == -1) { int sqrt = (int)(Math.Ceiling(Math.Sqrt(PrimitiveMap.Count))); width = MathFunctions.NearestPowerOf2(sqrt * tileSize); height = MathFunctions.NearestPowerOf2(sqrt * tileSize); } RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 16, RenderTargetUsage.PreserveContents); device.SetRenderTarget(toReturn); device.Clear(Color.Transparent); shader.SetIconTechnique(); shader.MainTexture = chunks.ChunkData.Tilemap; shader.SelfIlluminationEnabled = true; shader.SelfIlluminationTexture = chunks.ChunkData.IllumMap; shader.EnableShadows = false; shader.EnableLighting = false; shader.ClippingEnabled = false; shader.CameraPosition = new Vector3(-0.5f, 0.5f, 0.5f); shader.VertexColorTint = Color.White; shader.LightRampTint = Color.White; shader.SunlightGradient = chunks.ChunkData.SunMap; shader.AmbientOcclusionGradient = chunks.ChunkData.AmbientMap; shader.TorchlightGradient = chunks.ChunkData.TorchMap; Viewport oldview = device.Viewport; List <VoxelType> voxelsByType = Types.Select(type => type.Value).ToList(); voxelsByType.Sort((a, b) => a.ID < b.ID ? -1 : 1); int rows = height / tileSize; int cols = width / tileSize; device.ScissorRectangle = new Rectangle(0, 0, tileSize, tileSize); device.RasterizerState = RasterizerState.CullNone; device.DepthStencilState = DepthStencilState.Default; Vector3 half = Vector3.One * 0.5f; half = new Vector3(half.X, half.Y, half.Z); foreach (EffectPass pass in shader.CurrentTechnique.Passes) { foreach (var type in voxelsByType) { int row = type.ID / cols; int col = type.ID % cols; BoxPrimitive primitive = GetPrimitive(type); if (primitive == null) { continue; } if (type.HasTransitionTextures) { primitive = new BoxPrimitive(device, 1, 1, 1, type.TransitionTextures[new BoxTransition()]); } device.Viewport = new Viewport(col * tileSize, row * tileSize, tileSize, tileSize); Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(-1.2f, 1.0f, -1.5f), Vector3.Zero, Vector3.Up); Matrix projectionMatrix = Matrix.CreateOrthographic(1.5f, 1.5f, 0, 5); shader.View = viewMatrix; shader.Projection = projectionMatrix; shader.World = Matrix.CreateTranslation(-half); pass.Apply(); primitive.Render(device); } } device.Viewport = oldview; return((Texture2D)toReturn); }
public static Texture2D RenderIcons(GraphicsDevice device, Microsoft.Xna.Framework.Content.ContentManager Content, Gui.JsonTileSheet Sheet) { InitializeDefaultLibrary(device); var shader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); var sqrt = (int)(Math.Ceiling(Math.Sqrt(PrimitiveMap.Count))); var width = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth); var height = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth); RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 16, RenderTargetUsage.PreserveContents); device.SetRenderTarget(toReturn); device.Clear(Color.Transparent); shader.SetIconTechnique(); shader.MainTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); shader.SelfIlluminationEnabled = true; shader.SelfIlluminationTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_illumination); shader.EnableShadows = false; shader.EnableLighting = false; shader.ClippingEnabled = false; shader.CameraPosition = new Vector3(-0.5f, 0.5f, 0.5f); shader.VertexColorTint = Color.White; shader.LightRamp = Color.White; shader.SunlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.sungradient); shader.AmbientOcclusionGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.ambientgradient); shader.TorchlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.torchgradient); Viewport oldview = device.Viewport; int rows = height / Sheet.TileWidth; int cols = width / Sheet.TileWidth; device.ScissorRectangle = new Rectangle(0, 0, Sheet.TileWidth, Sheet.TileWidth); device.RasterizerState = RasterizerState.CullNone; device.DepthStencilState = DepthStencilState.Default; Vector3 half = Vector3.One * 0.5f; half = new Vector3(half.X, half.Y, half.Z); List <VoxelType> voxelsByType = Types.Select(type => type.Value).ToList(); voxelsByType.Sort((a, b) => a.ID < b.ID ? -1 : 1); foreach (EffectPass pass in shader.CurrentTechnique.Passes) { foreach (var type in voxelsByType) { int row = type.ID / cols; int col = type.ID % cols; BoxPrimitive primitive = GetPrimitive(type); if (primitive == null) { continue; } if (type.HasTransitionTextures) { primitive = new BoxPrimitive(device, 1, 1, 1, type.TransitionTextures[new BoxTransition()]); } device.Viewport = new Viewport(col * Sheet.TileWidth, row * Sheet.TileWidth, Sheet.TileWidth, Sheet.TileWidth); Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(-1.2f, 1.0f, -1.5f), Vector3.Zero, Vector3.Up); Matrix projectionMatrix = Matrix.CreateOrthographic(1.5f, 1.5f, 0, 5); shader.View = viewMatrix; shader.Projection = projectionMatrix; shader.World = Matrix.CreateTranslation(-half); shader.VertexColorTint = type.Tint; pass.Apply(); primitive.Render(device); } } device.Viewport = oldview; device.SetRenderTarget(null); return((Texture2D)toReturn); }
public static Texture2D RenderPatternIcons(GraphicsDevice device, Microsoft.Xna.Framework.Content.ContentManager Content, Gui.JsonTileSheet Sheet) { InitializeRailLibrary(); var shader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); var sqrt = (int)(Math.Ceiling(Math.Sqrt(RailPatterns.Count))); var width = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth); var fitHorizontal = width / Sheet.TileWidth; var rowCount = (int)Math.Ceiling((float)RailPatterns.Count / (float)fitHorizontal); var height = MathFunctions.NearestPowerOf2(rowCount * Sheet.TileHeight); RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 0, RenderTargetUsage.PreserveContents); var tileSheet = new SpriteSheet(ContentPaths.rail_tiles, 32); device.SetRenderTarget(toReturn); device.Clear(Color.Transparent); shader.SetTexturedTechnique(); shader.MainTexture = AssetManager.GetContentTexture(ContentPaths.rail_tiles); shader.SelfIlluminationEnabled = true; shader.SelfIlluminationTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_illumination); shader.EnableShadows = false; shader.EnableLighting = false; shader.ClippingEnabled = false; shader.CameraPosition = new Vector3(-0.5f, 0.5f, 0.5f); shader.VertexColorTint = Color.White; shader.LightRamp = Color.White; shader.SunlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.sungradient); shader.AmbientOcclusionGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.ambientgradient); shader.TorchlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.torchgradient); Viewport oldview = device.Viewport; int rows = height / Sheet.TileWidth; int cols = width / Sheet.TileWidth; device.ScissorRectangle = new Rectangle(0, 0, Sheet.TileWidth, Sheet.TileHeight); device.RasterizerState = RasterizerState.CullNone; device.DepthStencilState = DepthStencilState.Default; Vector3 half = Vector3.One * 0.5f; half = new Vector3(half.X, half.Y, half.Z); foreach (EffectPass pass in shader.CurrentTechnique.Passes) { int ID = 0; foreach (var type in RailPatterns) { int row = ID / cols; int col = ID % cols; var xboundsMin = 0; var xboundsMax = 0; var yboundsMin = 0; var yboundsMax = 0; var primitive = new RawPrimitive(); foreach (var piece in type.Pieces) { var rawPiece = Library.GetRailPiece(piece.RailPiece); var bounds = Vector4.Zero; var uvs = tileSheet.GenerateTileUVs(rawPiece.Tile, out bounds); primitive.AddQuad( Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)piece.Orientation) * Matrix.CreateTranslation(new Vector3(piece.Offset.X, 0.0f, piece.Offset.Y)), Color.White, Color.White, uvs, bounds); xboundsMin = Math.Min(xboundsMin, piece.Offset.X); xboundsMax = Math.Max(xboundsMax, piece.Offset.X); yboundsMin = Math.Min(yboundsMin, piece.Offset.Y); yboundsMax = Math.Max(yboundsMax, piece.Offset.Y); } float xSize = xboundsMax - xboundsMin + 1; float ySize = yboundsMax - yboundsMin + 1; var cameraPos = new Vector3(xboundsMin + (xSize / 2), 2.0f, yboundsMax + 1.0f); device.Viewport = new Viewport(col * Sheet.TileWidth, row * Sheet.TileHeight, Sheet.TileWidth, Sheet.TileHeight); shader.View = Matrix.CreateLookAt(cameraPos, new Vector3((xboundsMin + (xSize / 2)), 0.0f, yboundsMin), Vector3.UnitY); shader.Projection = Matrix.CreatePerspectiveFieldOfView(1.0f, 1.0f, 0.1f, 10); shader.World = Matrix.Identity; shader.CameraPosition = cameraPos; pass.Apply(); primitive.Render(device); ++ID; } } device.Viewport = oldview; device.SetRenderTarget(null); return((Texture2D)toReturn); }
// This will loop through the whole world and draw out all liquid primatives that are handed to the function. public static void InitializePrimativesFromChunk(VoxelChunk chunk, List <LiquidPrimitive> primitivesToInit) { LiquidPrimitive[] lps = new LiquidPrimitive[(int)LiquidType.Count]; if (!AddCaches(primitivesToInit, ref lps)) { return; } LiquidType curLiqType = LiquidType.None; LiquidPrimitive curPrimitive = null; ExtendedVertex[] curVertices = null; ushort[] curIndexes = null; int[] maxVertices = new int[lps.Length]; int[] maxIndexes = new int[lps.Length]; int maxVertex = 0; int maxIndex = 0; int totalFaces = 6; bool fogOfWar = GameSettings.Current.FogofWar; for (int globalY = chunk.Origin.Y; globalY < Math.Min(chunk.Manager.World.Renderer.PersistentSettings.MaxViewingLevel + 1, chunk.Origin.Y + VoxelConstants.ChunkSizeY); globalY++) { var y = globalY - chunk.Origin.Y; if (chunk.Data.LiquidPresent[y] == 0) { continue; } for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z)); if (fogOfWar && !voxel.IsExplored) { continue; } if (voxel.LiquidLevel > 0) { var liqType = voxel.LiquidType; // We need to see if we changed types and should change the data we are writing to. if (liqType != curLiqType) { LiquidPrimitive newPrimitive = lps[(int)liqType]; // We weren't passed a LiquidPrimitive object to work with for this type so we'll skip it. if (newPrimitive == null) { continue; } maxVertices[(int)curLiqType] = maxVertex; maxIndexes[(int)curLiqType] = maxIndex; curVertices = newPrimitive.Vertices; curIndexes = newPrimitive.Indexes; curLiqType = liqType; curPrimitive = newPrimitive; maxVertex = maxVertices[(int)liqType]; maxIndex = maxIndexes[(int)liqType]; } int facesToDraw = 0; for (int i = 0; i < totalFaces; i++) { BoxFace face = (BoxFace)i; // We won't draw the bottom face. This might be needed down the line if we add transparent tiles like glass. if (face == BoxFace.Bottom) { continue; } var delta = faceDeltas[(int)face]; // Pull the current neighbor DestinationVoxel based on the face it would be touching. var vox = VoxelHelpers.GetNeighbor(voxel, delta); if (vox.IsValid) { if (face == BoxFace.Top) { if (!(vox.LiquidLevel == 0 || y == (int)chunk.Manager.World.Renderer.PersistentSettings.MaxViewingLevel)) { cache.drawFace[(int)face] = false; continue; } } else { if (vox.LiquidLevel != 0 || !vox.IsEmpty) { cache.drawFace[(int)face] = false; continue; } } } else { cache.drawFace[(int)face] = false; continue; } cache.drawFace[(int)face] = true; facesToDraw++; } // There's no faces to draw on this voxel. Let's go to the next one. if (facesToDraw == 0) { continue; } // Now we check to see if we need to resize the current Vertex array. int vertexSizeIncrease = facesToDraw * 4; int indexSizeIncrease = facesToDraw * 6; lock (curPrimitive.VertexLock) { // Check vertex array size if (curVertices == null) { curVertices = new ExtendedVertex[256]; curPrimitive.Vertices = curVertices; } else if (curVertices.Length <= maxVertex + vertexSizeIncrease) { ExtendedVertex[] newVerts = new ExtendedVertex[MathFunctions.NearestPowerOf2(maxVertex + vertexSizeIncrease)]; curVertices.CopyTo(newVerts, 0); curVertices = newVerts; curPrimitive.Vertices = curVertices; } // Check index array size if (curIndexes == null) { curIndexes = new ushort[256]; curPrimitive.Indexes = curIndexes; } else if (curIndexes.Length <= maxIndex + indexSizeIncrease) { ushort[] newIdxs = new ushort[MathFunctions.NearestPowerOf2(maxIndex + indexSizeIncrease)]; curIndexes.CopyTo(newIdxs, 0); curIndexes = newIdxs; curPrimitive.Indexes = curIndexes; } } // Now we have a list of all the faces that will need to be drawn. Let's draw them. CreateWaterFaces(voxel, chunk, x, y, z, curVertices, curIndexes, maxVertex, maxIndex); // Finally increase the size so we can move on. maxVertex += vertexSizeIncrease; maxIndex += indexSizeIncrease; } } } } // The last thing we need to do is make sure we set the current primative's maxVertices to the right value. maxVertices[(int)curLiqType] = maxVertex; maxIndexes[(int)curLiqType] = maxIndex; // Now actually force the VertexBuffer to be recreated in each primative we worked with. for (int i = 0; i < lps.Length; i++) { LiquidPrimitive updatedPrimative = lps[i]; if (updatedPrimative == null) { continue; } maxVertex = maxVertices[i]; maxIndex = maxIndexes[i]; if (maxVertex > 0) { try { lock (updatedPrimative.VertexLock) { updatedPrimative.VertexCount = maxVertex; updatedPrimative.IndexCount = maxIndex; updatedPrimative.VertexBuffer = null; updatedPrimative.IndexBuffer = null; } } catch (global::System.Threading.AbandonedMutexException e) { Console.Error.WriteLine(e.Message); } } else { try { lock (updatedPrimative.VertexLock) { updatedPrimative.VertexBuffer = null; updatedPrimative.Vertices = null; updatedPrimative.IndexBuffer = null; updatedPrimative.Indexes = null; updatedPrimative.VertexCount = 0; updatedPrimative.IndexCount = 0; } } catch (global::System.Threading.AbandonedMutexException e) { Console.Error.WriteLine(e.Message); } } updatedPrimative.IsBuilding = false; } cache.inUse = false; cache = null; }