More work on occlusion culling (still doesn't work properly in same cases), fix issues with HoldThis packet, fixes #100.

This commit is contained in:
UnknownShadow200 2015-10-13 16:59:21 +11:00
parent dd23cc8a47
commit b39d2764bc
8 changed files with 90 additions and 64 deletions

View File

@ -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();

View File

@ -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;
}

View File

@ -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() {

View File

@ -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 ) {

View File

@ -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.

View File

@ -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;

View File

@ -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;
}
}

View File

@ -74,6 +74,7 @@ namespace OpenTK.Graphics.OpenGL {
TexSubImage2DAddress = GetAddress( "glTexSubImage2D" );
VertexPointerAddress = GetAddress( "glVertexPointer" );
ViewportAddress = GetAddress( "glViewport" );
PolygonModeAddress = GetAddress( "glPolygonMode" );
}
public static void UseArbVboAddresses() {