2016-03-26 13:51:42 +11:00
|
|
|
|
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
|
|
|
using System;
|
2016-03-27 09:33:51 +11:00
|
|
|
|
using ClassicalSharp.Entities;
|
|
|
|
|
using ClassicalSharp.Events;
|
2016-05-13 19:49:39 +10:00
|
|
|
|
using ClassicalSharp.Map;
|
2014-12-17 14:47:17 +11:00
|
|
|
|
using ClassicalSharp.GraphicsAPI;
|
|
|
|
|
using OpenTK;
|
|
|
|
|
|
2016-03-27 09:33:51 +11:00
|
|
|
|
namespace ClassicalSharp.Renderers {
|
2015-05-01 06:43:17 +10:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public class ChunkInfo {
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public ushort CentreX, CentreY, CentreZ;
|
|
|
|
|
public bool Visible = true, Empty = false;
|
|
|
|
|
public bool DrawLeft, DrawRight, DrawFront, DrawBack, DrawBottom, DrawTop;
|
|
|
|
|
#if OCCLUSION
|
|
|
|
|
public bool Visited = false, Occluded = false;
|
|
|
|
|
public byte OcclusionFlags, OccludedFlags, DistanceFlags;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public ChunkPartInfo[] NormalParts;
|
|
|
|
|
public ChunkPartInfo[] TranslucentParts;
|
|
|
|
|
|
|
|
|
|
public ChunkInfo( int x, int y, int z ) {
|
|
|
|
|
CentreX = (ushort)(x + 8);
|
|
|
|
|
CentreY = (ushort)(y + 8);
|
|
|
|
|
CentreZ = (ushort)(z + 8);
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
2016-05-01 22:01:11 +10:00
|
|
|
|
|
|
|
|
|
public void Reset( int x, int y, int z ) {
|
|
|
|
|
CentreX = (ushort)(x + 8);
|
|
|
|
|
CentreY = (ushort)(y + 8);
|
|
|
|
|
CentreZ = (ushort)(z + 8);
|
|
|
|
|
|
|
|
|
|
Visible = true; Empty = false;
|
|
|
|
|
DrawLeft = false; DrawRight = false; DrawFront = false;
|
|
|
|
|
DrawBack = false; DrawBottom = false; DrawTop = false;
|
|
|
|
|
}
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public partial class MapRenderer : IDisposable {
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2015-08-03 17:25:42 +10:00
|
|
|
|
Game game;
|
|
|
|
|
IGraphicsApi api;
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2016-05-13 19:49:39 +10:00
|
|
|
|
internal int _1DUsed = -1;
|
2016-06-28 13:29:42 +10:00
|
|
|
|
internal int renderCount = 0;
|
|
|
|
|
internal ChunkInfo[] chunks, renderChunks, unsortedChunks;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
internal bool[] usedTranslucent, usedNormal;
|
|
|
|
|
internal bool[] pendingTranslucent, pendingNormal;
|
|
|
|
|
internal int[] totalUsed;
|
|
|
|
|
ChunkUpdater updater;
|
2016-05-13 19:49:39 +10:00
|
|
|
|
bool drawAllFaces = false, underWater = false;
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2015-10-01 18:10:22 +10:00
|
|
|
|
public MapRenderer( Game game ) {
|
|
|
|
|
this.game = game;
|
|
|
|
|
api = game.Graphics;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
updater = new ChunkUpdater( game, this );
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public void Dispose() { updater.Dispose(); }
|
2015-10-04 15:24:20 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public void Refresh() { updater.Refresh(); }
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public void RedrawBlock( int x, int y, int z, byte block, int oldHeight, int newHeight ) {
|
|
|
|
|
updater.RedrawBlock( x, y, z, block, oldHeight, newHeight );
|
2016-04-14 07:38:25 +10:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
public void Render( double deltaTime ) {
|
|
|
|
|
if( chunks == null ) return;
|
|
|
|
|
ChunkSorter.UpdateSortOrder( game, updater );
|
2016-06-08 13:54:46 +10:00
|
|
|
|
updater.UpdateChunks( deltaTime );
|
|
|
|
|
RenderNormalChunks( deltaTime );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RenderTranslucent( double deltaTime ) {
|
|
|
|
|
if( chunks == null ) return;
|
|
|
|
|
RenderTranslucentChunks( deltaTime );
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
|
2016-01-17 21:56:22 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
// Render solid and fully transparent to fill depth buffer.
|
|
|
|
|
// These blocks are treated as having an alpha value of either none or full.
|
2016-06-08 13:54:46 +10:00
|
|
|
|
void RenderNormalChunks( double deltaTime ) {
|
2016-04-20 08:41:22 +10:00
|
|
|
|
int[] texIds = game.TerrainAtlas1D.TexIds;
|
|
|
|
|
api.SetBatchFormat( VertexFormat.P3fT2fC4b );
|
|
|
|
|
api.Texturing = true;
|
|
|
|
|
api.AlphaTest = true;
|
2016-01-04 22:14:03 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
for( int batch = 0; batch < _1DUsed; batch++ ) {
|
|
|
|
|
if( totalUsed[batch] <= 0 ) continue;
|
|
|
|
|
if( pendingNormal[batch] || usedNormal[batch] ) {
|
|
|
|
|
api.BindTexture( texIds[batch] );
|
|
|
|
|
RenderNormalBatch( batch );
|
|
|
|
|
pendingNormal[batch] = false;
|
|
|
|
|
}
|
2016-01-04 22:14:03 +11:00
|
|
|
|
}
|
2016-05-13 19:49:39 +10:00
|
|
|
|
|
|
|
|
|
CheckWeather( deltaTime );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.AlphaTest = false;
|
|
|
|
|
api.Texturing = false;
|
|
|
|
|
#if DEBUG_OCCLUSION
|
|
|
|
|
DebugPickedPos();
|
2016-04-20 07:37:30 +10:00
|
|
|
|
#endif
|
2015-01-14 17:11:03 +11:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-13 19:49:39 +10:00
|
|
|
|
void CheckWeather( double deltaTime ) {
|
|
|
|
|
WorldEnv env = game.World.Env;
|
2016-05-11 17:50:32 +10:00
|
|
|
|
Vector3 pos = game.CurrentCameraPos;
|
|
|
|
|
Vector3I coords = Vector3I.Floor( pos );
|
2016-05-29 22:26:50 +10:00
|
|
|
|
|
2016-05-11 17:50:32 +10:00
|
|
|
|
byte block = game.World.SafeGetBlock( coords );
|
|
|
|
|
drawAllFaces = game.BlockInfo.IsTranslucent[block];
|
2016-05-29 22:26:50 +10:00
|
|
|
|
bool outside = !game.World.IsValidPos( Vector3I.Floor( pos ) );
|
|
|
|
|
underWater = drawAllFaces || (pos.Y < env.EdgeHeight && outside);
|
2016-05-13 19:49:39 +10:00
|
|
|
|
|
|
|
|
|
// If we are under water, render weather before to blend properly
|
|
|
|
|
if( !underWater || env.Weather == Weather.Sunny ) return;
|
|
|
|
|
api.AlphaBlending = true;
|
|
|
|
|
game.WeatherRenderer.Render( deltaTime );
|
|
|
|
|
api.AlphaBlending = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Render translucent(liquid) blocks. These 'blend' into other blocks.
|
2016-06-08 15:04:17 +10:00
|
|
|
|
void RenderTranslucentChunks( double deltaTime ) {
|
2016-04-20 08:41:22 +10:00
|
|
|
|
// First fill depth buffer
|
|
|
|
|
int[] texIds = game.TerrainAtlas1D.TexIds;
|
|
|
|
|
api.SetBatchFormat( VertexFormat.P3fT2fC4b );
|
|
|
|
|
api.Texturing = false;
|
|
|
|
|
api.AlphaBlending = false;
|
|
|
|
|
api.ColourWrite = false;
|
|
|
|
|
for( int batch = 0; batch < _1DUsed; batch++ ) {
|
|
|
|
|
if( totalUsed[batch] <= 0 ) continue;
|
|
|
|
|
if( pendingTranslucent[batch] || usedTranslucent[batch] ) {
|
|
|
|
|
RenderTranslucentBatchDepthPass( batch );
|
|
|
|
|
pendingTranslucent[batch] = false;
|
|
|
|
|
}
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
2015-10-01 18:10:22 +10:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
// Then actually draw the transluscent blocks
|
|
|
|
|
api.AlphaBlending = true;
|
|
|
|
|
api.Texturing = true;
|
|
|
|
|
api.ColourWrite = true;
|
|
|
|
|
api.DepthWrite = false; // we already calculated depth values in depth pass
|
2015-10-01 18:10:22 +10:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
for( int batch = 0; batch < _1DUsed; batch++ ) {
|
|
|
|
|
if( totalUsed[batch] <= 0 ) continue;
|
|
|
|
|
if( !usedTranslucent[batch] ) continue;
|
|
|
|
|
api.BindTexture( texIds[batch] );
|
|
|
|
|
RenderTranslucentBatch( batch );
|
|
|
|
|
}
|
2016-05-13 19:49:39 +10:00
|
|
|
|
|
2016-05-29 22:26:50 +10:00
|
|
|
|
api.DepthWrite = true;
|
2016-05-13 19:49:39 +10:00
|
|
|
|
// If we weren't under water, render weather after to blend properly
|
|
|
|
|
if( !underWater && game.World.Env.Weather != Weather.Sunny ) {
|
|
|
|
|
api.AlphaTest = true;
|
|
|
|
|
game.WeatherRenderer.Render( deltaTime );
|
|
|
|
|
api.AlphaTest = false;
|
|
|
|
|
}
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.AlphaBlending = false;
|
|
|
|
|
api.Texturing = false;
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
const DrawMode mode = DrawMode.Triangles;
|
|
|
|
|
const int maxVertex = 65536;
|
|
|
|
|
const int maxIndices = maxVertex / 4 * 6;
|
|
|
|
|
void RenderNormalBatch( int batch ) {
|
2016-06-28 13:29:42 +10:00
|
|
|
|
for( int i = 0; i < renderCount; i++ ) {
|
|
|
|
|
ChunkInfo info = renderChunks[i];
|
|
|
|
|
if( info.NormalParts == null ) continue;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
|
|
|
|
ChunkPartInfo part = info.NormalParts[batch];
|
|
|
|
|
if( part.IndicesCount == 0 ) continue;
|
|
|
|
|
usedNormal[batch] = true;
|
|
|
|
|
if( part.IndicesCount > maxIndices )
|
|
|
|
|
DrawBigPart( info, ref part );
|
|
|
|
|
else
|
2016-05-13 19:49:39 +10:00
|
|
|
|
DrawPart( info, ref part );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
2016-04-28 08:37:13 +10:00
|
|
|
|
if( part.SpriteCount > 0 ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
int count = part.SpriteCount / 4; // 4 per sprite
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = true;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
if( info.DrawRight || info.DrawFront ) {
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( count, 0 ); game.Vertices += count;
|
|
|
|
|
}
|
|
|
|
|
if( info.DrawLeft || info.DrawBack ) {
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( count, count ); game.Vertices += count;
|
|
|
|
|
}
|
|
|
|
|
if( info.DrawLeft || info.DrawFront ) {
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( count, count * 2 ); game.Vertices += count;
|
|
|
|
|
}
|
|
|
|
|
if( info.DrawRight || info.DrawBack ) {
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( count, count * 3 ); game.Vertices += count;
|
|
|
|
|
}
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
void RenderTranslucentBatch( int batch ) {
|
2016-06-28 13:29:42 +10:00
|
|
|
|
for( int i = 0; i < renderCount; i++ ) {
|
|
|
|
|
ChunkInfo info = renderChunks[i];
|
|
|
|
|
if( info.TranslucentParts == null ) continue;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
ChunkPartInfo part = info.TranslucentParts[batch];
|
2014-12-17 14:47:17 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
if( part.IndicesCount == 0 ) continue;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
DrawTranslucentPart( info, ref part, 1 );
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
void RenderTranslucentBatchDepthPass( int batch ) {
|
2016-06-28 13:29:42 +10:00
|
|
|
|
for( int i = 0; i < renderCount; i++ ) {
|
|
|
|
|
ChunkInfo info = renderChunks[i];
|
|
|
|
|
if( info.TranslucentParts == null ) continue;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
|
|
|
|
ChunkPartInfo part = info.TranslucentParts[batch];
|
|
|
|
|
if( part.IndicesCount == 0 ) continue;
|
|
|
|
|
usedTranslucent[batch] = true;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
DrawTranslucentPart( info, ref part, 0 );
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-01-14 17:11:03 +11:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
void DrawPart( ChunkInfo info, ref ChunkPartInfo part ) {
|
|
|
|
|
api.BindVb( part.VbId );
|
2016-04-28 08:37:13 +10:00
|
|
|
|
bool drawLeft = info.DrawLeft && part.LeftCount > 0;
|
|
|
|
|
bool drawRight = info.DrawRight && part.RightCount > 0;
|
|
|
|
|
bool drawBottom = info.DrawBottom && part.BottomCount > 0;
|
|
|
|
|
bool drawTop = info.DrawTop && part.TopCount > 0;
|
|
|
|
|
bool drawFront = info.DrawFront && part.FrontCount > 0;
|
|
|
|
|
bool drawBack = info.DrawBack && part.BackCount > 0;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
|
|
|
|
if( drawLeft && drawRight ) {
|
|
|
|
|
api.FaceCulling = true;
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount + part.RightCount, part.LeftIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.LeftCount + part.RightCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawLeft ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount, part.LeftIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.LeftCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawRight ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.RightCount, part.RightIndex );
|
|
|
|
|
game.Vertices += part.RightCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( drawFront && drawBack ) {
|
|
|
|
|
api.FaceCulling = true;
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount + part.BackCount, part.FrontIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.FrontCount + part.BackCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawFront ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount, part.FrontIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.FrontCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBack ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BackCount, part.BackIndex );
|
|
|
|
|
game.Vertices += part.BackCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
2015-08-03 17:25:42 +10:00
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
if( drawBottom && drawTop ) {
|
|
|
|
|
api.FaceCulling = true;
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount + part.TopCount, part.BottomIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.BottomCount + part.TopCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBottom ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount, part.BottomIndex );
|
|
|
|
|
game.Vertices += part.BottomCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawTop ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.TopCount, part.TopIndex );
|
|
|
|
|
game.Vertices += part.TopCount;
|
2016-04-13 17:40:09 +10:00
|
|
|
|
}
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
2016-04-13 17:40:09 +10:00
|
|
|
|
|
2016-06-15 21:39:51 +10:00
|
|
|
|
void DrawTranslucentPart( ChunkInfo info, ref ChunkPartInfo part, int m ) {
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.BindVb( part.VbId );
|
2016-04-28 08:37:13 +10:00
|
|
|
|
bool drawLeft = (drawAllFaces || info.DrawLeft) && part.LeftCount > 0;
|
|
|
|
|
bool drawRight = (drawAllFaces || info.DrawRight) && part.RightCount > 0;
|
|
|
|
|
bool drawBottom = (drawAllFaces || info.DrawBottom) && part.BottomCount > 0;
|
|
|
|
|
bool drawTop = (drawAllFaces || info.DrawTop) && part.TopCount > 0;
|
|
|
|
|
bool drawFront = (drawAllFaces || info.DrawFront) && part.FrontCount > 0;
|
|
|
|
|
bool drawBack = (drawAllFaces || info.DrawBack) && part.BackCount > 0;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
|
|
|
|
if( drawLeft && drawRight ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount + part.RightCount, part.LeftIndex );
|
|
|
|
|
game.Vertices += m * (part.LeftCount + part.RightCount);
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawLeft ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount, part.LeftIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * part.LeftCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawRight ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.RightCount, part.RightIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * part.RightCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( drawFront && drawBack ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount + part.BackCount, part.FrontIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * (part.FrontCount + part.BackCount);
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawFront ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount, part.FrontIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * part.FrontCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBack ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BackCount, part.BackIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * part.BackCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( drawBottom && drawTop ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount + part.TopCount, part.BottomIndex );
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += m * (part.BottomCount + part.TopCount);
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBottom ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount, part.BottomIndex );
|
|
|
|
|
game.Vertices += m * part.BottomCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawTop ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.TopCount, part.TopIndex );
|
|
|
|
|
game.Vertices += m * part.TopCount;
|
2016-04-13 17:40:09 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 08:41:22 +10:00
|
|
|
|
void DrawBigPart( ChunkInfo info, ref ChunkPartInfo part ) {
|
|
|
|
|
api.BindVb( part.VbId );
|
2016-04-28 08:37:13 +10:00
|
|
|
|
bool drawLeft = info.DrawLeft && part.LeftCount > 0;
|
|
|
|
|
bool drawRight = info.DrawRight && part.RightCount > 0;
|
|
|
|
|
bool drawBottom = info.DrawBottom && part.BottomCount > 0;
|
|
|
|
|
bool drawTop = info.DrawTop && part.TopCount > 0;
|
|
|
|
|
bool drawFront = info.DrawFront && part.FrontCount > 0;
|
|
|
|
|
bool drawBack = info.DrawBack && part.BackCount > 0;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
|
|
|
|
|
if( drawLeft && drawRight ) {
|
|
|
|
|
api.FaceCulling = true;
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount + part.RightCount, part.LeftIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.LeftCount + part.RightCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawLeft ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.LeftCount, part.LeftIndex );
|
|
|
|
|
game.Vertices += part.LeftCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawRight ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.RightCount, part.RightIndex );
|
|
|
|
|
game.Vertices += part.RightCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( drawFront && drawBack ) {
|
|
|
|
|
api.FaceCulling = true;
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount + part.BackCount, part.FrontIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.FrontCount + part.BackCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawFront ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.FrontCount, part.FrontIndex );
|
|
|
|
|
game.Vertices += part.FrontCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBack ) {
|
2016-06-15 21:39:51 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BackCount, part.BackIndex );
|
|
|
|
|
game.Vertices += part.BackCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Special handling for top and bottom as these can go over 65536 vertices and we need to adjust the indices in this case.
|
|
|
|
|
if( drawBottom && drawTop ) {
|
|
|
|
|
api.FaceCulling = true;
|
|
|
|
|
if( part.IndicesCount > maxIndices ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
int part1Count = maxIndices - part.BottomIndex;
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part1Count, part.BottomIndex );
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount + part.TopCount - part1Count, maxVertex, 0 );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount + part.TopCount, part.BottomIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
|
|
|
|
api.FaceCulling = false;
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.TopCount + part.BottomCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawBottom ) {
|
|
|
|
|
int part1Count;
|
|
|
|
|
if( part.IndicesCount > maxIndices &&
|
2016-05-13 19:49:39 +10:00
|
|
|
|
( part1Count = maxIndices - part.BottomIndex ) < part.BottomCount ) {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part1Count, part.BottomIndex );
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount - part1Count, maxVertex, 0 );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.BottomCount, part.BottomIndex );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
}
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.BottomCount;
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else if( drawTop ) {
|
|
|
|
|
int part1Count;
|
|
|
|
|
if( part.IndicesCount > maxIndices &&
|
2016-04-28 08:37:13 +10:00
|
|
|
|
( part1Count = maxIndices - part.TopIndex ) < part.TopCount ) {
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part1Count, part.TopIndex );
|
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.TopCount - part1Count, maxVertex, 0 );
|
2016-04-20 08:41:22 +10:00
|
|
|
|
} else {
|
2016-04-28 08:37:13 +10:00
|
|
|
|
api.DrawIndexedVb_TrisT2fC4b( part.TopCount, part.TopIndex );
|
2016-05-13 19:49:39 +10:00
|
|
|
|
}
|
2016-06-15 21:39:51 +10:00
|
|
|
|
game.Vertices += part.TopCount;
|
2016-04-13 17:40:09 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-17 14:47:17 +11:00
|
|
|
|
}
|
|
|
|
|
}
|