public static void Render( GraphicsDevice Device, Shader Effect, OrbitCamera Camera, DesignationDrawer DesignationDrawer, DesignationSet Designations, WorldManager World) { lock (renderLock) { Drawer3D.Effect = Effect; Drawer3D.Camera = Camera; var colorModulation = Math.Abs(Math.Sin(DwarfTime.LastTime.TotalGameTime.TotalSeconds * 2.0f)); DesignationDrawer.DrawHilites( World, Designations, _addBox, (pos, type) => { Effect.MainTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); Effect.LightRamp = Color.White; // Todo: Alpha pulse Effect.VertexColorTint = new Color(0.1f, 0.9f, 1.0f, 1.0f); var prevTechnique = Effect.CurrentTechnique; Effect.CurrentTechnique = Effect.Techniques[Shader.Technique.Stipple]; var pos_distorted = pos + Vector3.Up * 0.15f + VertexNoise.GetNoiseVectorFromRepeatingTexture(pos + Vector3.One * 0.5f); Effect.World = Matrix.CreateTranslation(pos_distorted); foreach (EffectPass pass in Effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(type).Render(Device); } Effect.LightRamp = Color.White; Effect.VertexColorTint = Color.White; Effect.World = Matrix.Identity; Effect.CurrentTechnique = prevTechnique; }); foreach (var box in Boxes) { _addBox(box.RealBox.Min, box.RealBox.Max - box.RealBox.Min, box.Color, box.Thickness, box.Warp); } foreach (var segment in Segments) { _addLineSegment(segment.A, segment.B, segment.Color, segment.Thickness, false); } _flush(); Boxes.Clear(); Segments.Clear(); } }
public void Render(DwarfTime gameTime, GraphicsDevice graphics, Shader effect) { DepthStencilState state = graphics.DepthStencilState; graphics.DepthStencilState = DepthStencilState.DepthRead; float t = (float)gameTime.TotalGameTime.TotalSeconds; float st = (float)Math.Sin(t * 4) * 0.5f + 0.5f; effect.MainTexture = World.ChunkManager.ChunkData.Tilemap; effect.LightRampTint = Color.White; effect.VertexColorTint = new Color(0.1f, 0.9f, 1.0f, 0.5f * st + 0.45f); foreach (WallBuilder put in Designations) { //Drawer3D.DrawBox(put.Vox.GetBoundingBox(), Color.LightBlue, st * 0.01f + 0.05f); effect.World = Matrix.CreateTranslation(put.Vox.Position); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(put.Type.Name).Render(graphics); } } if (Selected == null) { Selected = new List <Voxel>(); } if (CurrentVoxelType == null) { Selected.Clear(); } effect.VertexColorTint = verified ? new Color(0.0f, 1.0f, 0.0f, 0.5f * st + 0.45f) : new Color(1.0f, 0.0f, 0.0f, 0.5f * st + 0.45f); foreach (Voxel voxel in Selected) { effect.World = Matrix.CreateTranslation(voxel.Position); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(CurrentVoxelType).Render(graphics); } } effect.LightRampTint = Color.White; effect.VertexColorTint = Color.White; effect.World = Matrix.Identity; graphics.DepthStencilState = state; }
public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time) { DepthStencilState state = graphics.DepthStencilState; graphics.DepthStencilState = DepthStencilState.DepthRead; Effect = Player.World.DefaultShader; float t = (float)time.TotalGameTime.TotalSeconds; float st = (float)Math.Sin(t * 4) * 0.5f + 0.5f; Effect.MainTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); Effect.LightRamp = Color.White; Effect.VertexColorTint = new Color(0.1f, 0.9f, 1.0f, 0.25f * st + 0.4f); Effect.SetTexturedTechnique(); if (Selected == null) { Selected = new List <VoxelHandle>(); } if (CurrentVoxelType == 0) { Selected.Clear(); } Effect.VertexColorTint = new Color(0.0f, 1.0f, 0.0f, 0.25f * st + 0.4f); Vector3 offset = Player.World.Master.VoxSelector.SelectionType == VoxelSelectionType.SelectEmpty ? Vector3.Zero : Vector3.Up * 0.15f; if (Mouse.GetState().LeftButton == ButtonState.Pressed) { foreach (var voxel in Selected) { Effect.World = Matrix.CreateTranslation(voxel.WorldPosition + offset); foreach (EffectPass pass in Effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(CurrentVoxelType).Render(graphics); } } } Effect.LightRamp = Color.White; Effect.VertexColorTint = Color.White; Effect.World = Matrix.Identity; graphics.DepthStencilState = state; }
private static void BuildVoxelGeometry( RawPrimitive Into, int X, int Y, int Z, VoxelChunk Chunk, BoxPrimitive BedrockModel, Cache Cache) { var v = new VoxelHandle(Chunk, new LocalVoxelCoordinate(X, Y, Z)); if ((v.IsExplored && v.IsEmpty) || !v.IsVisible) { return; } var primitive = VoxelLibrary.GetPrimitive(v.Type); if (v.IsExplored && primitive == null) { return; } if (primitive == null) { primitive = BedrockModel; } var tint = v.Type.Tint; var uvs = primitive.UVs; if (v.Type.HasTransitionTextures && v.IsExplored) { uvs = ComputeTransitionTexture(new VoxelHandle(v.Chunk.Manager.ChunkData, v.Coordinate)); } BuildVoxelTopFaceGeometry(Into, Chunk, Cache, primitive, v, uvs, 0); for (int i = 1; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, primitive, v, tint, uvs, i); } }
private static BoxPrimitive.BoxTextureCoords ComputeTransitionTexture(VoxelHandle V) { var type = V.Type; var primitive = VoxelLibrary.GetPrimitive(type); if (!type.HasTransitionTextures && primitive != null) { return(primitive.UVs); } else if (primitive == null) { return(null); } else { var transition = ComputeTransitions(V.Chunk.Manager.ChunkData, V, type); return(type.TransitionTextures[transition]); } }
public void Render(DwarfTime gameTime, GraphicsDevice graphics, Effect effect) { float t = (float)gameTime.TotalGameTime.TotalSeconds; float st = (float)Math.Sin(t * 4) * 0.5f + 0.5f; effect.Parameters["xTexture"].SetValue(BlockTextures); effect.Parameters["xTint"].SetValue(new Vector4(1.0f, 1.0f, 2.0f, 0.5f * st + 0.45f)); //Matrix oldWorld = effect.Parameters["xWorld"].GetValueMatrix(); foreach (WallBuilder put in Designations) { Drawer3D.DrawBox(put.Vox.GetBoundingBox(), Color.LightBlue, st * 0.01f + 0.05f); effect.Parameters["xWorld"].SetValue(Matrix.CreateTranslation(put.Vox.Position)); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(put.Type.Name).Render(graphics); } } effect.Parameters["xTint"].SetValue(new Vector4(1.0f, 1.0f, 1.0f, 1.0f)); effect.Parameters["xWorld"].SetValue(Matrix.Identity); }
public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics) { if (chunk == null) { return; } rebuildMutex.WaitOne(); if (isRebuilding) { rebuildMutex.ReleaseMutex(); return; } isRebuilding = true; rebuildMutex.ReleaseMutex(); accumulatedVertices.Clear(); accumulatedIndices.Clear(); faceExists.Clear(); drawFace.Clear(); Voxel v = chunk.MakeVoxel(0, 0, 0); Voxel voxelOnFace = chunk.MakeVoxel(0, 0, 0); Voxel[] manhattanNeighbors = new Voxel[4]; for (int x = 0; x < chunk.SizeX; x++) { for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++) { for (int z = 0; z < chunk.SizeZ; z++) { v.GridPosition = new Vector3(x, y, z); if (v.IsEmpty || !v.IsVisible) { continue; } BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type); if (primitive == null) { continue; } BoxPrimitive.BoxTextureCoords uvs = primitive.UVs; if (v.Type.HasTransitionTextures) { uvs = v.ComputeTransitionTexture(manhattanNeighbors); } Voxel worldVoxel = new Voxel(); for (int i = 0; i < 6; i++) { BoxFace face = (BoxFace)i; Vector3 delta = FaceDeltas[face]; faceExists[face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); drawFace[face] = true; if (faceExists[face]) { voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); drawFace[face] = voxelOnFace.IsEmpty || !voxelOnFace.IsVisible || (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, voxelOnFace.RampType, v.RampType)); } else { bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel); drawFace[face] = !success || worldVoxel.IsEmpty || !worldVoxel.IsVisible || (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, worldVoxel.RampType, v.RampType)); } } for (int i = 0; i < 6; i++) { BoxFace face = (BoxFace)i; if (!drawFace[face]) { continue; } int faceIndex = 0; int faceCount = 0; int vertexIndex = 0; int vertexCount = 0; primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount); Vector2 texScale = uvs.Scales[i]; int indexOffset = accumulatedVertices.Count; for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++) { ExtendedVertex vert = primitive.Vertices[vertOffset + vertexIndex]; VoxelVertex bestKey = VoxelChunk.GetNearestDelta(vert.Position); Color color = v.Chunk.Data.GetColor(x, y, z, bestKey); Vector3 offset = Vector3.Zero; Vector2 texOffset = Vector2.Zero; if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType)) { offset = new Vector3(0, -v.Type.RampSize, 0); if (face != BoxFace.Top && face != BoxFace.Bottom) { texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y)); } } ExtendedVertex newVertex = new ExtendedVertex((vert.Position + v.Position + VertexNoise.GetNoiseVectorFromRepeatingTexture(vert.Position + v.Position) + offset), color, uvs.Uvs[vertOffset + vertexIndex] + texOffset, uvs.Bounds[faceIndex / 6]); accumulatedVertices.Add(newVertex); } for (int idx = faceIndex; idx < faceCount + faceIndex; idx++) { int vertexOffset = primitive.Indices[idx]; accumulatedIndices.Add((short)(indexOffset + (vertexOffset - primitive.Indices[faceIndex]))); } } } } } Vertices = new ExtendedVertex[accumulatedVertices.Count]; accumulatedVertices.CopyTo(Vertices); IndexBuffer = new IndexBuffer(graphics, typeof(short), accumulatedIndices.Count, BufferUsage.WriteOnly); IndexBuffer.SetData(accumulatedIndices.ToArray()); ResetBuffer(graphics); isRebuilding = false; //chunk.PrimitiveMutex.WaitOne(); chunk.NewPrimitive = this; chunk.NewPrimitiveReceived = true; //chunk.PrimitiveMutex.ReleaseMutex(); }
public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics) { if (chunk == null) { return; } rebuildMutex.WaitOne(); if (isRebuilding) { rebuildMutex.ReleaseMutex(); return; } isRebuilding = true; rebuildMutex.ReleaseMutex(); int[] ambientValues = new int[4]; int maxIndex = 0; int maxVertex = 0; Voxel v = chunk.MakeVoxel(0, 0, 0); Voxel voxelOnFace = chunk.MakeVoxel(0, 0, 0); Voxel[] manhattanNeighbors = new Voxel[4]; BoxPrimitive bedrockModel = VoxelLibrary.GetPrimitive("Bedrock"); Voxel worldVoxel = new Voxel(); if (Vertices == null) { Vertices = new ExtendedVertex[1024]; } if (Indexes == null) { Indexes = new ushort[512]; } for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++) { for (int x = 0; x < chunk.SizeX; x++) { for (int z = 0; z < chunk.SizeZ; z++) { v.GridPosition = new Vector3(x, y, z); if ((v.IsExplored && v.IsEmpty) || !v.IsVisible) { continue; } BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type); if (v.IsExplored && primitive == null) { continue; } if (!v.IsExplored) { primitive = bedrockModel; } Color tint = v.Type.Tint; BoxPrimitive.BoxTextureCoords uvs = primitive.UVs; if (v.Type.HasTransitionTextures && v.IsExplored) { uvs = v.ComputeTransitionTexture(manhattanNeighbors); } for (int i = 0; i < 6; i++) { BoxFace face = (BoxFace)i; Vector3 delta = FaceDeltas[(int)face]; faceExists[(int)face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); drawFace[(int)face] = true; if (faceExists[(int)face]) { voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z); drawFace[(int)face] = (voxelOnFace.IsExplored && voxelOnFace.IsEmpty) || !voxelOnFace.IsVisible || (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, voxelOnFace.RampType, v.RampType)); } else { bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel); drawFace[(int)face] = !success || (worldVoxel.IsExplored && worldVoxel.IsEmpty) || !worldVoxel.IsVisible || (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, worldVoxel.RampType, v.RampType)); } } for (int i = 0; i < 6; i++) { BoxFace face = (BoxFace)i; if (!drawFace[(int)face]) { continue; } int faceIndex = 0; int faceCount = 0; int vertexIndex = 0; int vertexCount = 0; primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount); Vector2 texScale = uvs.Scales[i]; int indexOffset = maxVertex; for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++) { ExtendedVertex vert = primitive.Vertices[vertOffset + vertexIndex]; VoxelVertex bestKey = primitive.Deltas[vertOffset + vertexIndex]; Color color = v.Chunk.Data.GetColor(x, y, z, bestKey); ambientValues[vertOffset] = color.G; Vector3 offset = Vector3.Zero; Vector2 texOffset = Vector2.Zero; if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType)) { offset = new Vector3(0, -v.Type.RampSize, 0); if (face != BoxFace.Top && face != BoxFace.Bottom) { texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y)); } } if (maxVertex >= Vertices.Length) { ExtendedVertex[] newVertices = new ExtendedVertex[Vertices.Length * 2]; Vertices.CopyTo(newVertices, 0); Vertices = newVertices; } Vertices[maxVertex] = new ExtendedVertex(vert.Position + v.Position + VertexNoise.GetNoiseVectorFromRepeatingTexture( vert.Position + v.Position) + offset, color, tint, uvs.Uvs[vertOffset + vertexIndex] + texOffset, uvs.Bounds[faceIndex / 6]); maxVertex++; } bool flippedQuad = ambientValues[0] + ambientValues[2] > ambientValues[1] + ambientValues[3]; for (int idx = faceIndex; idx < faceCount + faceIndex; idx++) { if (maxIndex >= Indexes.Length) { ushort[] indexes = new ushort[Indexes.Length * 2]; Indexes.CopyTo(indexes, 0); Indexes = indexes; } ushort vertexOffset = flippedQuad ? primitive.FlippedIndexes[idx] : primitive.Indexes[idx]; ushort vertexOffset0 = flippedQuad? primitive.FlippedIndexes[faceIndex] : primitive.Indexes[faceIndex]; Indexes[maxIndex] = (ushort)((int)indexOffset + (int)((int)vertexOffset - (int)vertexOffset0)); maxIndex++; } } } } } MaxIndex = maxIndex; MaxVertex = maxVertex; GenerateLightmap(chunk.Manager.ChunkData.Tilemap.Bounds); isRebuilding = false; //chunk.PrimitiveMutex.WaitOne(); chunk.NewPrimitive = this; chunk.NewPrimitiveReceived = true; //chunk.PrimitiveMutex.ReleaseMutex(); }
public void InitializeFromChunk(VoxelChunk chunk) { if (chunk == null) { return; } BoxPrimitive bedrockModel = VoxelLibrary.GetPrimitive("Bedrock"); var sliceStack = new List <RawPrimitive>(); var cache = new Cache(); for (var y = 0; y < chunk.Manager.ChunkData.MaxViewingLevel; ++y) { RawPrimitive sliceGeometry = null; lock (chunk.Data.SliceCache) { var cachedSlice = chunk.Data.SliceCache[y]; if (chunk.Data.VoxelsPresentInSlice[y] == 0) { cache.Clear(); if (cachedSlice != null) { chunk.Data.SliceCache[y] = null; } continue; } if (cachedSlice != null) { cache.Clear(); sliceStack.Add(cachedSlice); if (GameSettings.Default.GrassMotes) { chunk.RebuildMoteLayerIfNull(y); } continue; } sliceGeometry = new RawPrimitive { Vertices = new ExtendedVertex[128], Indexes = new short[128] }; chunk.Data.SliceCache[y] = sliceGeometry; } if (GameSettings.Default.CalculateRamps) { UpdateCornerRamps(chunk, y); UpdateNeighborEdgeRamps(chunk, y); } if (GameSettings.Default.GrassMotes) { chunk.RebuildMoteLayer(y); } BuildSliceGeometry(chunk, bedrockModel, cache, y, sliceGeometry); sliceStack.Add(sliceGeometry); } var combinedGeometry = RawPrimitive.Concat(sliceStack); Vertices = combinedGeometry.Vertices; VertexCount = combinedGeometry.VertexCount; Indexes = combinedGeometry.Indexes.Select(s => (ushort)s).ToArray(); IndexCount = combinedGeometry.IndexCount; chunk.PrimitiveMutex.WaitOne(); chunk.NewPrimitive = this; chunk.NewPrimitiveReceived = true; chunk.PrimitiveMutex.ReleaseMutex(); }