diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index 2ae2ae520..1f22b23fe 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -234,11 +234,14 @@ namespace ClassicalSharp { } Graphics.Mode2D( Width, Height, EnvRenderer is StandardEnvRenderer ); + //OpenTK.Graphics.OpenGL.GL.PolygonMode( 0x0408, 0x1B02 ); fpsScreen.Render( e.Time ); if( activeScreen != null ) { activeScreen.Render( e.Time ); } Graphics.Mode3D( EnvRenderer is StandardEnvRenderer ); + //if( Keyboard[Key.F2] ) + // OpenTK.Graphics.OpenGL.GL.PolygonMode( 0x0408, 0x1B01 ); if( screenshotRequested ) TakeScreenshot(); diff --git a/ClassicalSharp/Game/Inventory.cs b/ClassicalSharp/Game/Inventory.cs index fc99ee82f..966ddb3d7 100644 --- a/ClassicalSharp/Game/Inventory.cs +++ b/ClassicalSharp/Game/Inventory.cs @@ -10,13 +10,13 @@ namespace ClassicalSharp { // and running on default .NET (https://bugzilla.xamarin.com/show_bug.cgi?id=572) #if !__MonoCS__ Hotbar = new Block[] { Block.Stone, Block.Cobblestone, Block.Brick, Block.Dirt, - Block.WoodenPlanks, Block.Wood, Block.Leaves, Block.Glass, Block.Slab }; + Block.WoodenPlanks, Block.Wood, Block.Leaves, Block.Grass, Block.Slab }; #else Hotbar = new Block[9]; Hotbar[0] = Block.Stone; Hotbar[1] = Block.Cobblestone; Hotbar[2] = Block.Brick; Hotbar[3] = Block.Dirt; Hotbar[4] = Block.WoodenPlanks; Hotbar[5] = Block.Wood; - Hotbar[6] = Block.Leaves; Hotbar[7] = Block.Glass; + Hotbar[6] = Block.Leaves; Hotbar[7] = Block.Grass; Hotbar[8] = Block.Slab; #endif } @@ -50,7 +50,10 @@ namespace ClassicalSharp { } for( int i = 0; i < Hotbar.Length; i++ ) { if( Hotbar[i] == value ) { - hotbarIndex = i; + Block held = Hotbar[hotbarIndex]; + Hotbar[hotbarIndex] = Hotbar[i]; + Hotbar[i] = held; + game.Events.RaiseHeldBlockChanged(); return; } diff --git a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs index c0a21f086..0db399768 100644 --- a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs +++ b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs @@ -255,7 +255,6 @@ namespace ClassicalSharp.GraphicsAPI { LoadIdentityMatrix(); AlphaBlending = true; if( setFog ) Fog = false; - //OpenTK.Graphics.OpenGL.GL.PolygonMode( 0x0408, 0x1B02 ); } protected virtual void LoadOrthoMatrix( float width, float height ) { @@ -272,7 +271,6 @@ namespace ClassicalSharp.GraphicsAPI { DepthTest = true; AlphaBlending = false; if( setFog ) Fog = true; - //OpenTK.Graphics.OpenGL.GL.PolygonMode( 0x0408, 0x1B01 ); } internal unsafe int MakeDefaultIb() { diff --git a/ClassicalSharp/Rendering/MapRenderer.Occlusion.cs b/ClassicalSharp/Rendering/MapRenderer.Occlusion.cs index e2b9cf3ca..371901c19 100644 --- a/ClassicalSharp/Rendering/MapRenderer.Occlusion.cs +++ b/ClassicalSharp/Rendering/MapRenderer.Occlusion.cs @@ -6,45 +6,53 @@ namespace ClassicalSharp { public partial class MapRenderer : IDisposable { - void SimpleOcclusionCulling() { // TODO: broken + void SimpleOcclusionCulling() { // TODO: still broken Vector3 p = game.LocalPlayer.EyePosition; - Vector3I chunkLoc = Vector3I.Floor( p ); - Utils.Clamp( ref chunkLoc.X, 0, game.Map.Width - 1 ); - Utils.Clamp( ref chunkLoc.Y, 0, game.Map.Height - 1 ); - Utils.Clamp( ref chunkLoc.Z, 0, game.Map.Length- 1 ); + Vector3I mapLoc = Vector3I.Floor( p ); + Utils.Clamp( ref mapLoc.X, 0, game.Map.Width - 1 ); + Utils.Clamp( ref mapLoc.Y, 0, game.Map.Height - 1 ); + Utils.Clamp( ref mapLoc.Z, 0, game.Map.Length- 1 ); - int cx = chunkLoc.X >> 4; - int cy = chunkLoc.Y >> 4; - int cz = chunkLoc.Z >> 4; + int cx = mapLoc.X >> 4; + int cy = mapLoc.Y >> 4; + int cz = mapLoc.Z >> 4; ChunkInfo chunkIn = unsortedChunks[cx + chunksX * (cy + cz * chunksY)]; - byte chunkInFlags = chunkIn.OcclusionFlags; + byte chunkInOcclusionFlags = chunkIn.OcclusionFlags; chunkIn.OcclusionFlags = 0; - ChunkQueue queue = new ChunkQueue( chunksX * chunksY * chunksZ ); for( int i = 0; i < chunks.Length; i++ ) { - chunks[i].Visited = false; - chunks[i].Occluded = false; - chunks[i].VisibilityFlags = 0; + ChunkInfo chunk = chunks[i]; + chunk.Visited = false; + chunk.Occluded = false; + chunk.OccludedFlags = chunk.OcclusionFlags; + chunk.DistanceFlags = 0; } chunkIn.Visited = true; + mapLoc = Vector3I.Floor( p ); + if( game.Map.IsValidPos( mapLoc ) ) { + chunkIn.DistanceFlags = flagX | flagY | flagZ; + } else { + chunkIn.OccludedFlags = chunkIn.OcclusionFlags = chunkInOcclusionFlags; + chunkIn.DistanceFlags |= (mapLoc.X < 0 || mapLoc.X >= game.Map.Width) ? flagX : (byte)0; + chunkIn.DistanceFlags |= (mapLoc.Y < 0 || mapLoc.Y >= game.Map.Height) ? flagY : (byte)0; + chunkIn.DistanceFlags |= (mapLoc.Z < 0 || mapLoc.Z >= game.Map.Length) ? flagZ : (byte)0; + } + QueueChunk( cx - 1, cy, cz, queue ); QueueChunk( cx + 1, cy, cz, queue ); QueueChunk( cx, cy - 1, cz, queue ); QueueChunk( cx, cy + 1, cz, queue ); QueueChunk( cx, cy, cz - 1, queue ); - QueueChunk( cx, cy, cz + 1, queue ); - - ProcessQueue( chunkIn, queue ); - chunkIn.OcclusionFlags = chunkInFlags; + QueueChunk( cx, cy, cz + 1, queue ); + ProcessQueue( chunkPos, queue ); + chunkIn.OcclusionFlags = chunkInOcclusionFlags; } - void ProcessQueue( ChunkInfo src, ChunkQueue queue ) { - Vector3I p = new Vector3I( src.CentreX, src.CentreY, src.CentreZ ); + void ProcessQueue( Vector3I p, ChunkQueue queue ) { while( queue.Size > 0 ) { - ChunkInfo chunk = queue.Dequeue(); - chunk.VisibilityFlags = chunk.OcclusionFlags; + ChunkInfo chunk = queue.Dequeue(); int x1 = chunk.CentreX - 8, x2 = chunk.CentreX + 8; int y1 = chunk.CentreY - 8, y2 = chunk.CentreY + 8; int z1 = chunk.CentreZ - 8, z2 = chunk.CentreZ + 8; @@ -82,19 +90,14 @@ namespace ClassicalSharp { distY = dx * dx + dxTop * dxTop + dz * dz; yOffset = 1; } - int distMin = Math.Min( distX, Math.Min( distY, distZ ) ); - bool occlude = true; - byte flags = 0; - if( distMin == distX ) - OccludeX( cx, cy, cz, xOffset, ref occlude, ref flags ); - if( distMin == distZ ) - OccludeZ( cx, cy, cz, zOffset, ref occlude, ref flags ); - if( distMin == distY ) - OccludeY( cx, cy, cz, yOffset, ref occlude, ref flags ); + chunk.Occluded = true; + int distMin = Math.Min( distX, Math.Min( distY, distZ ) ); + if( distMin == distX ) OccludeX( cx, cy, cz, xOffset, chunk ); + if( distMin == distZ ) OccludeZ( cx, cy, cz, zOffset, chunk ); + if( distMin == distY ) OccludeY( cx, cy, cz, yOffset, chunk ); - if( occlude ) - chunk.Occluded = true; - chunk.VisibilityFlags = (byte)( flags | chunk.OcclusionFlags ); + //Console.WriteLine( distMin + " , " + distX + " , " + distY + " , " + distZ ); + //Console.WriteLine( chunk.DistanceFlags + " : " + chunk.OccludedFlags + " : " + chunk.OcclusionFlags ); QueueChunk( cx - 1, cy, cz, queue ); QueueChunk( cx + 1, cy, cz, queue ); QueueChunk( cx, cy, cz - 1, queue ); @@ -104,45 +107,59 @@ namespace ClassicalSharp { } Console.WriteLine( "======================" ); } + const byte flagX = 1, flagZ = 2, flagY = 4; - void OccludeX( int cx, int cy, int cz, int xOffset, ref bool occlude, ref byte flags ) { + public void DebugPickedPos() { + if( game.SelectedPos.Valid ) { + Vector3I p = game.SelectedPos.BlockPos; + int cx = p.X >> 4; + int cy = p.Y >> 4; + int cz = p.Z >> 4; + ChunkInfo chunk = unsortedChunks[cx + chunksX * (cy + cz * chunksY)]; + //Console.WriteLine( chunk.DistanceFlags + " : " + chunk.OccludedFlags + " : " + chunk.OcclusionFlags + " , " + chunk.Occluded ); + } + } + + void OccludeX( int cx, int cy, int cz, int xOffset, ChunkInfo info ) { cx += xOffset; if( cx >= 0 && cx < chunksX ) { ChunkInfo neighbour = unsortedChunks[cx + chunksX * (cy + cz * chunksY)]; - if( (neighbour.VisibilityFlags & 1) == 0 ) - occlude = false; + if( (neighbour.OccludedFlags & neighbour.DistanceFlags) != neighbour.DistanceFlags ) + info.Occluded = false; else - flags |= 1; + info.OccludedFlags |= flagX; + } else { + info.Occluded = false; } + info.DistanceFlags |= flagX; } - void OccludeZ( int cx, int cy, int cz, int zOffset, ref bool occlude, ref byte flags ) { + void OccludeZ( int cx, int cy, int cz, int zOffset, ChunkInfo info ) { cz += zOffset; if( cz >= 0 && cz < chunksZ ) { ChunkInfo neighbour = unsortedChunks[cx + chunksX * (cy + cz * chunksY)]; - if( (neighbour.VisibilityFlags & 2) == 0 ) - occlude = false; + if( (neighbour.OccludedFlags & neighbour.DistanceFlags) != neighbour.DistanceFlags ) + info.Occluded = false; else - flags |= 2; + info.OccludedFlags |= flagZ; + } else { + info.Occluded = false; } + info.DistanceFlags |= flagZ; } - void OccludeY( int cx, int cy, int cz, int yOffset, ref bool occlude, ref byte flags ) { + void OccludeY( int cx, int cy, int cz, int yOffset, ChunkInfo info ) { cy += yOffset; - if( cy >= 0 && cy< chunksY ) { + if( cy >= 0 && cy < chunksY ) { ChunkInfo neighbour = unsortedChunks[cx + chunksX * (cy + cz * chunksY)]; - if( (neighbour.VisibilityFlags & 4) == 0 ) - occlude = false; + if( (neighbour.OccludedFlags & neighbour.DistanceFlags) != neighbour.DistanceFlags ) + info.Occluded = false; else - flags |= 4; + info.OccludedFlags |= flagY; + } else { + info.Occluded = false; } - } - - static float DistToRecSquared( Vector3 p, int x1, int y1, int z1, int x2, int y2, int z2 ) { - float dx = Math.Max( x1 - p.X, Math.Max( 0, p.X - x2 ) ); - float dy = Math.Max( y1 - p.Y, Math.Max( 0, p.Y - y2 ) ); - float dz = Math.Max( z1 - p.Z, Math.Max( 0, p.Z - z2 ) ); - return dx * dx + dy * dy + dz * dz; + info.DistanceFlags |= flagY; } void QueueChunk( int cx, int cy, int cz, ChunkQueue queue ) { diff --git a/ClassicalSharp/Rendering/MapRenderer.cs b/ClassicalSharp/Rendering/MapRenderer.cs index 7a39180f8..a12a3289c 100644 --- a/ClassicalSharp/Rendering/MapRenderer.cs +++ b/ClassicalSharp/Rendering/MapRenderer.cs @@ -14,7 +14,7 @@ namespace ClassicalSharp { public bool Visible = true, Occluded = false; public bool Visited = false, Empty = false; public bool DrawLeft, DrawRight, DrawFront, DrawBack, DrawBottom, DrawTop; - public byte OcclusionFlags, VisibilityFlags; + public byte OcclusionFlags, OccludedFlags, DistanceFlags; public ChunkPartInfo[] NormalParts; public ChunkPartInfo[] TranslucentParts; @@ -132,7 +132,7 @@ namespace ClassicalSharp { void DeleteChunk( ChunkInfo info ) { info.Empty = false; info.OcclusionFlags = 0; - info.VisibilityFlags = 0; + info.OccludedFlags = 0; DeleteData( ref info.NormalParts ); DeleteData( ref info.TranslucentParts ); } @@ -226,9 +226,9 @@ namespace ClassicalSharp { void UpdateSortOrder() { Player p = game.LocalPlayer; Vector3I newChunkPos = Vector3I.Floor( p.EyePosition ); - newChunkPos.X = ( newChunkPos.X & ~0x0F ) + 8; - newChunkPos.Y = ( newChunkPos.Y & ~0x0F ) + 8; - newChunkPos.Z = ( newChunkPos.Z & ~0x0F ) + 8; + newChunkPos.X = (newChunkPos.X & ~0x0F) + 8; + newChunkPos.Y = (newChunkPos.Y & ~0x0F) + 8; + newChunkPos.Z = (newChunkPos.Z & ~0x0F) + 8; if( newChunkPos == chunkPos ) return; chunkPos = newChunkPos; @@ -301,6 +301,7 @@ namespace ClassicalSharp { } api.AlphaTest = false; api.Texturing = false; + //DebugPickedPos(); } // Render translucent(liquid) blocks. These 'blend' into other blocks. diff --git a/OpenTK/GameWindow.cs b/OpenTK/GameWindow.cs index ba2b33d15..134c1faf2 100644 --- a/OpenTK/GameWindow.cs +++ b/OpenTK/GameWindow.cs @@ -74,7 +74,6 @@ namespace OpenTK IGraphicsContext glContext; bool isExiting = false; double render_period; - double target_render_period; // TODO: Implement these: double render_time; bool vsync; diff --git a/OpenTK/Graphics/OpenGL/GL.cs b/OpenTK/Graphics/OpenGL/GL.cs index 65131005d..044621bc9 100644 --- a/OpenTK/Graphics/OpenGL/GL.cs +++ b/OpenTK/Graphics/OpenGL/GL.cs @@ -196,5 +196,9 @@ namespace OpenTK.Graphics.OpenGL { public static void Viewport( int x, int y, int width, int height ) { Interop.Calli( x, y, width, height, ViewportAddress ); } static IntPtr ViewportAddress; + + public static void PolygonMode( int face, int mode ) { + Interop.Calli( face, mode, PolygonModeAddress ); + } static IntPtr PolygonModeAddress; } } \ No newline at end of file diff --git a/OpenTK/Graphics/OpenGL/GLHelper.cs b/OpenTK/Graphics/OpenGL/GLHelper.cs index 5ecb742a0..937635d0f 100644 --- a/OpenTK/Graphics/OpenGL/GLHelper.cs +++ b/OpenTK/Graphics/OpenGL/GLHelper.cs @@ -74,6 +74,7 @@ namespace OpenTK.Graphics.OpenGL { TexSubImage2DAddress = GetAddress( "glTexSubImage2D" ); VertexPointerAddress = GetAddress( "glVertexPointer" ); ViewportAddress = GetAddress( "glViewport" ); + PolygonModeAddress = GetAddress( "glPolygonMode" ); } public static void UseArbVboAddresses() {