mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Use indexed drawing and stackalloc in StandardEnvRenderer.
This commit is contained in:
parent
1590664f68
commit
0fe78fdf3b
@ -45,6 +45,7 @@ namespace ClassicalSharp {
|
||||
public PickedPos SelectedPos = new PickedPos();
|
||||
public ModelCache ModelCache;
|
||||
internal string skinServer, chatInInputBuffer;
|
||||
internal int defaultIb;
|
||||
public bool CanUseThirdPersonCamera = true;
|
||||
FpsScreen fpsScreen;
|
||||
|
||||
@ -119,6 +120,7 @@ namespace ClassicalSharp {
|
||||
#else
|
||||
Graphics = new Direct3D9Api( this );
|
||||
#endif
|
||||
defaultIb = Graphics.MakeDefaultIb();
|
||||
ModelCache = new ModelCache( this );
|
||||
AsyncDownloader = new AsyncDownloader( skinServer );
|
||||
PrintGraphicsInfo();
|
||||
@ -186,6 +188,7 @@ namespace ClassicalSharp {
|
||||
|
||||
protected override void OnRenderFrame( FrameEventArgs e ) {
|
||||
Graphics.BeginFrame( this );
|
||||
Graphics.BindIb( defaultIb );
|
||||
accumulator += e.Time;
|
||||
imageCheckAccumulator += e.Time;
|
||||
ticksAccumulator += e.Time;
|
||||
@ -278,6 +281,7 @@ namespace ClassicalSharp {
|
||||
if( writer != null ) {
|
||||
writer.Close();
|
||||
}
|
||||
Graphics.DeleteIb( defaultIb );
|
||||
Graphics.Dispose();
|
||||
Utils2D.Dispose();
|
||||
base.Dispose();
|
||||
|
@ -128,6 +128,9 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
|
||||
public abstract void DrawIndexedVb( DrawMode mode, int indicesCount, int startVertex, int startIndex );
|
||||
|
||||
/// <summary> Optimised version of DrawIndexedVb for VertexFormat.Pos3fTex2fCol4b </summary>
|
||||
//public abstract void DrawIndexedVb( DrawMode mode, int indicesCount, int startVertex, int startIndex );
|
||||
|
||||
protected static int[] strideSizes = { 20, 16, 24 };
|
||||
|
||||
public abstract void SetMatrixMode( MatrixType mode );
|
||||
@ -221,6 +224,25 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
DepthTest = true;
|
||||
AlphaBlending = false;
|
||||
}
|
||||
|
||||
public unsafe int MakeDefaultIb() {
|
||||
const int maxIndices = 65536 / 4 * 6;
|
||||
int element = 0;
|
||||
ushort* indices = stackalloc ushort[maxIndices];
|
||||
IntPtr ptr = (IntPtr)indices;
|
||||
|
||||
for( int i = 0; i < maxIndices; i += 6 ) {
|
||||
*indices++ = (ushort)( element + 0 );
|
||||
*indices++ = (ushort)( element + 1 );
|
||||
*indices++ = (ushort)( element + 2 );
|
||||
|
||||
*indices++ = (ushort)( element + 2 );
|
||||
*indices++ = (ushort)( element + 3 );
|
||||
*indices++ = (ushort)( element + 0 );
|
||||
element += 4;
|
||||
}
|
||||
return CreateIb( ptr, maxIndices );
|
||||
}
|
||||
}
|
||||
|
||||
public enum VertexFormat {
|
||||
|
@ -280,7 +280,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
GL.BindBufferARB( BufferTarget.ElementArrayBuffer, ib );
|
||||
}
|
||||
|
||||
const DrawElementsType indexType = DrawElementsType.UnsignedShort;
|
||||
const DrawElementsType indexType = DrawElementsType.UnsignedShort;
|
||||
public override void DrawIndexedVb( DrawMode mode, int indicesCount, int startVertex, int startIndex ) {
|
||||
int offset = startVertex * VertexPos3fTex2fCol4b.Size;
|
||||
GL.VertexPointer( 3, PointerType.Float, 24, new IntPtr( offset ) );
|
||||
|
@ -5,7 +5,7 @@ using ClassicalSharp.GraphicsAPI;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
public sealed class MapEnvRenderer : IDisposable {
|
||||
public unsafe sealed class MapEnvRenderer : IDisposable {
|
||||
|
||||
public Map Map;
|
||||
public Game Window;
|
||||
@ -16,9 +16,9 @@ namespace ClassicalSharp {
|
||||
Map = Window.Map;
|
||||
}
|
||||
|
||||
int sidesVboId = -1, edgesVboId = -1;
|
||||
int sidesVb = -1, edgesVb = -1;
|
||||
int edgeTexId, sideTexId;
|
||||
int sidesVertices, edgesVertices, index;
|
||||
int sidesIndices, edgesIndices;
|
||||
static readonly FastColour sidesCol = new FastColour( 128, 128, 128 ), edgesCol = FastColour.White;
|
||||
bool legacy = false;
|
||||
|
||||
@ -41,18 +41,20 @@ namespace ClassicalSharp {
|
||||
}
|
||||
|
||||
public void Render( double deltaTime ) {
|
||||
if( sidesVboId == -1 || edgesVboId == -1 ) return;
|
||||
if( sidesVb == -1 || edgesVb == -1 ) return;
|
||||
Graphics.Texturing = true;
|
||||
Graphics.BindTexture( sideTexId );
|
||||
Graphics.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
|
||||
Graphics.DrawVb( DrawMode.Triangles, sidesVboId, 0, sidesVertices );
|
||||
Graphics.BindVb( sidesVb );
|
||||
Graphics.DrawIndexedVb( DrawMode.Triangles, sidesIndices, 0, 0 );
|
||||
|
||||
// Do not draw water when we cannot see it.
|
||||
// Fixes 'depth bleeding through' issues with 16 bit depth buffers on large maps.
|
||||
if( Window.LocalPlayer.EyePosition.Y >= 0 ) {
|
||||
Graphics.AlphaBlending = true;
|
||||
Graphics.BindTexture( edgeTexId );
|
||||
Graphics.DrawVb( DrawMode.Triangles, edgesVboId, 0, edgesVertices );
|
||||
Graphics.BindVb( edgesVb );
|
||||
Graphics.DrawIndexedVb( DrawMode.Triangles, edgesIndices, 0, 0 );
|
||||
Graphics.AlphaBlending = false;
|
||||
}
|
||||
Graphics.Texturing = false;
|
||||
@ -67,22 +69,23 @@ namespace ClassicalSharp {
|
||||
|
||||
Graphics.DeleteTexture( ref edgeTexId );
|
||||
Graphics.DeleteTexture( ref sideTexId );
|
||||
Graphics.DeleteVb( sidesVboId );
|
||||
Graphics.DeleteVb( edgesVboId );
|
||||
sidesVboId = edgesVboId = -1;
|
||||
Graphics.DeleteVb( sidesVb );
|
||||
Graphics.DeleteVb( edgesVb );
|
||||
sidesVb = edgesVb = -1;
|
||||
}
|
||||
|
||||
void OnNewMap( object sender, EventArgs e ) {
|
||||
Graphics.DeleteVb( sidesVboId );
|
||||
Graphics.DeleteVb( edgesVboId );
|
||||
sidesVboId = edgesVboId = -1;
|
||||
Graphics.DeleteVb( sidesVb );
|
||||
Graphics.DeleteVb( edgesVb );
|
||||
sidesVb = edgesVb = -1;
|
||||
MakeTexture( ref edgeTexId, ref lastEdgeTexLoc, Map.EdgeBlock );
|
||||
MakeTexture( ref sideTexId, ref lastSideTexLoc, Map.SidesBlock );
|
||||
}
|
||||
|
||||
void OnNewMapLoaded( object sender, EventArgs e ) {
|
||||
RebuildSides();
|
||||
RebuildEdges();
|
||||
CalculateRects( Window.ViewDistance );
|
||||
RebuildSides( Map.GroundHeight, legacy ? 128 : 65536 );
|
||||
RebuildEdges( Map.WaterHeight, legacy ? 128 : 65536 );
|
||||
}
|
||||
|
||||
void EnvVariableChanged( object sender, EnvVariableEventArgs e ) {
|
||||
@ -103,112 +106,50 @@ namespace ClassicalSharp {
|
||||
|
||||
void ResetSidesAndEdges( object sender, EventArgs e ) {
|
||||
if( Window.Map.IsNotLoaded ) return;
|
||||
RebuildSides();
|
||||
RebuildEdges();
|
||||
Graphics.DeleteVb( sidesVb );
|
||||
Graphics.DeleteVb( edgesVb );
|
||||
CalculateRects( Window.ViewDistance );
|
||||
RebuildSides( Map.GroundHeight, legacy ? 128 : 65536 );
|
||||
RebuildEdges( Map.WaterHeight, legacy ? 128 : 65536 );
|
||||
}
|
||||
|
||||
void RebuildSides() {
|
||||
index = 0;
|
||||
Graphics.DeleteVb( sidesVboId );
|
||||
if( legacy ) {
|
||||
RebuildSidesLegacy( Map.GroundHeight );
|
||||
} else {
|
||||
RebuildSidesModern( Map.GroundHeight );
|
||||
void RebuildSides( int groundLevel, int axisSize ) {
|
||||
sidesIndices = 0;
|
||||
foreach( Rectangle rec in rects ) {
|
||||
sidesIndices += Utils.CountIndices( rec.Width, rec.Height, axisSize ); // YPlanes outside
|
||||
}
|
||||
}
|
||||
|
||||
void RebuildEdges() {
|
||||
index = 0;
|
||||
Graphics.DeleteVb( edgesVboId );
|
||||
if( legacy ) {
|
||||
RebuildEdgesLegacy( Map.WaterHeight );
|
||||
} else {
|
||||
RebuildEdgesModern( Map.WaterHeight );
|
||||
}
|
||||
}
|
||||
|
||||
// |-----------|
|
||||
// | 2 |
|
||||
// |---*****---|
|
||||
// | 3 *Map* 4 |
|
||||
// | * * |
|
||||
// |---*****---|
|
||||
// | 1 |
|
||||
// |-----------|
|
||||
IEnumerable<Rectangle> OutsideMap( int extent ) {
|
||||
yield return new Rectangle( -extent, -extent, extent + Map.Width + extent, extent );
|
||||
yield return new Rectangle( -extent, Map.Length, extent + Map.Width + extent, extent );
|
||||
yield return new Rectangle( -extent, 0, extent, Map.Length );
|
||||
yield return new Rectangle( Map.Width, 0, extent, Map.Length );
|
||||
}
|
||||
|
||||
#region Modern
|
||||
|
||||
void RebuildSidesModern( int groundLevel ) {
|
||||
sidesVertices = 5 * 6 + 4 * 6;
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[sidesVertices];
|
||||
sidesIndices += Utils.CountIndices( Map.Width, Map.Length, axisSize ); // YPlane beneath map
|
||||
sidesIndices += 2 * Utils.CountIndices( Map.Width, groundLevel, axisSize ); // ZPlanes
|
||||
sidesIndices += 2 * Utils.CountIndices( Map.Length, groundLevel, axisSize ); // XPlanes
|
||||
VertexPos3fTex2fCol4b* vertices = stackalloc VertexPos3fTex2fCol4b[sidesIndices / 6 * 4];
|
||||
IntPtr ptr = (IntPtr)vertices;
|
||||
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
DrawYPlane( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, groundLevel, sidesCol, vertices );
|
||||
foreach( Rectangle rec in rects ) {
|
||||
DrawY( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, groundLevel, axisSize, sidesCol, ref vertices );
|
||||
}
|
||||
DrawYPlane( 0, 0, Map.Width, Map.Length, 0, sidesCol, vertices );
|
||||
DrawZPlane( 0, 0, Map.Width, 0, groundLevel, sidesCol, vertices );
|
||||
DrawZPlane( Map.Length, 0, Map.Width, 0, groundLevel, sidesCol, vertices );
|
||||
DrawXPlane( 0, 0, Map.Length, 0, groundLevel, sidesCol, vertices );
|
||||
DrawXPlane( Map.Width, 0, Map.Length, 0, groundLevel, sidesCol, vertices );
|
||||
sidesVboId = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
DrawY( 0, 0, Map.Width, Map.Length, 0, axisSize, sidesCol, ref vertices );
|
||||
DrawZ( 0, 0, Map.Width, 0, groundLevel, axisSize, sidesCol, ref vertices );
|
||||
DrawZ( Map.Length, 0, Map.Width, 0, groundLevel, axisSize, sidesCol, ref vertices );
|
||||
DrawX( 0, 0, Map.Length, 0, groundLevel, axisSize, sidesCol, ref vertices );
|
||||
DrawX( Map.Width, 0, Map.Length, 0, groundLevel, axisSize, sidesCol, ref vertices );
|
||||
sidesVb = Graphics.CreateVb( ptr, VertexFormat.Pos3fTex2fCol4b, sidesIndices / 6 * 4 );
|
||||
}
|
||||
|
||||
void RebuildEdgesModern( int waterLevel ) {
|
||||
edgesVertices = 4 * 6;
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[edgesVertices];
|
||||
void RebuildEdges( int waterLevel, int axisSize ) {
|
||||
edgesIndices = 0;
|
||||
foreach( Rectangle rec in rects ) {
|
||||
edgesIndices += Utils.CountIndices( rec.Width, rec.Height, axisSize ); // YPlanes outside
|
||||
}
|
||||
VertexPos3fTex2fCol4b* vertices = stackalloc VertexPos3fTex2fCol4b[edgesIndices / 6 * 4];
|
||||
IntPtr ptr = (IntPtr)vertices;
|
||||
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
DrawYPlane( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, waterLevel, edgesCol, vertices );
|
||||
foreach( Rectangle rec in rects ) {
|
||||
DrawY( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, waterLevel, axisSize, edgesCol, ref vertices );
|
||||
}
|
||||
edgesVboId = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
edgesVb = Graphics.CreateVb( ptr, VertexFormat.Pos3fTex2fCol4b, edgesIndices / 6 * 4 );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Legacy
|
||||
|
||||
void RebuildSidesLegacy( int groundLevel ) {
|
||||
sidesVertices = 0;
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
sidesVertices += Utils.CountVertices( rec.Width, rec.Height, axisSize ); // YPlanes outside
|
||||
}
|
||||
sidesVertices += Utils.CountVertices( Map.Width, Map.Length, axisSize ); // YPlane beneath map
|
||||
sidesVertices += Utils.CountVertices( Map.Width, groundLevel, axisSize ) * 2; // ZPlanes
|
||||
sidesVertices += Utils.CountVertices( Map.Length, groundLevel, axisSize ) * 2; // XPlanes
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[sidesVertices];
|
||||
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
DrawYPlaneParts( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, groundLevel, sidesCol, vertices );
|
||||
}
|
||||
DrawYPlaneParts( 0, 0, Map.Width, Map.Length, 0, sidesCol, vertices );
|
||||
DrawZPlaneParts( 0, 0, Map.Width, 0, groundLevel, sidesCol, vertices );
|
||||
DrawZPlaneParts( Map.Length, 0, Map.Width, 0, groundLevel, sidesCol, vertices );
|
||||
DrawXPlaneParts( 0, 0, Map.Length, 0, groundLevel, sidesCol, vertices );
|
||||
DrawXPlaneParts( Map.Width, 0, Map.Length, 0, groundLevel, sidesCol, vertices );
|
||||
sidesVboId = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
}
|
||||
|
||||
void RebuildEdgesLegacy( int waterLevel ) {
|
||||
edgesVertices = 0;
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
edgesVertices += Utils.CountVertices( rec.Width, rec.Height, axisSize ); // YPlanes outside
|
||||
}
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[edgesVertices];
|
||||
|
||||
foreach( Rectangle rec in OutsideMap( Window.ViewDistance ) ) {
|
||||
DrawYPlaneParts( rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, waterLevel, edgesCol, vertices );
|
||||
}
|
||||
edgesVboId = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
}
|
||||
|
||||
const int axisSize = 128;
|
||||
void DrawXPlaneParts( int x, int z1, int z2, int y1, int y2, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
void DrawX( int x, int z1, int z2, int y1, int y2, int axisSize, FastColour col, ref VertexPos3fTex2fCol4b* vertices ) {
|
||||
int endZ = z2, endY = y2, startY = y1;
|
||||
for( ; z1 < endZ; z1 += axisSize ) {
|
||||
z2 = z1 + axisSize;
|
||||
@ -217,12 +158,17 @@ namespace ClassicalSharp {
|
||||
for( ; y1 < endY; y1 += axisSize ) {
|
||||
y2 = y1 + axisSize;
|
||||
if( y2 > endY ) y2 = endY;
|
||||
DrawXPlane( x, z1, z2, y1, y2, col, vertices );
|
||||
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, z2 - z1, y2 - y1 );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x, y1, z1, rec.U1, rec.V1, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x, y2, z1, rec.U1, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x, y2, z2, rec.U2, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x, y1, z2, rec.U2, rec.V1, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawZPlaneParts( int z, int x1, int x2, int y1, int y2, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
void DrawZ( int z, int x1, int x2, int y1, int y2, int axisSize, FastColour col, ref VertexPos3fTex2fCol4b* vertices ) {
|
||||
int endX = x2, endY = y2, startY = y1;
|
||||
for( ; x1 < endX; x1 += axisSize ) {
|
||||
x2 = x1 + axisSize;
|
||||
@ -231,12 +177,17 @@ namespace ClassicalSharp {
|
||||
for( ; y1 < endY; y1 += axisSize ) {
|
||||
y2 = y1 + axisSize;
|
||||
if( y2 > endY ) y2 = endY;
|
||||
DrawZPlane( z, x1, x2, y1, y2, col, vertices );
|
||||
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, x2 - x1, y2 - y1 );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y1, z, rec.U1, rec.V1, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y2, z, rec.U1, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y2, z, rec.U2, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y1, z, rec.U2, rec.V1, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawYPlaneParts( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
void DrawY( int x1, int z1, int x2, int z2, int y, int axisSize, FastColour col, ref VertexPos3fTex2fCol4b* vertices ) {
|
||||
int endX = x2, endZ = z2, startZ = z1;
|
||||
for( ; x1 < endX; x1 += axisSize ) {
|
||||
x2 = x1 + axisSize;
|
||||
@ -245,12 +196,24 @@ namespace ClassicalSharp {
|
||||
for( ; z1 < endZ; z1 += axisSize ) {
|
||||
z2 = z1 + axisSize;
|
||||
if( z2 > endZ ) z2 = endZ;
|
||||
DrawYPlane( x1, z1, x2, z2, y, col, vertices );
|
||||
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, x2 - x1, z2 - z1 );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y, z1, rec.U1, rec.V1, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y, z2, rec.U1, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y, z2, rec.U2, rec.V2, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y, z1, rec.U2, rec.V1, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
Rectangle[] rects = new Rectangle[4];
|
||||
void CalculateRects( int extent ) {
|
||||
rects[0] = new Rectangle( -extent, -extent, extent + Map.Width + extent, extent );
|
||||
rects[1] = new Rectangle( -extent, Map.Length, extent + Map.Width + extent, extent );
|
||||
|
||||
rects[2] = new Rectangle( -extent, 0, extent, Map.Length );
|
||||
rects[3] = new Rectangle( Map.Width, 0, extent, Map.Length );
|
||||
}
|
||||
|
||||
int lastEdgeTexLoc, lastSideTexLoc;
|
||||
void MakeTexture( ref int texId, ref int lastTexLoc, Block block ) {
|
||||
@ -261,38 +224,5 @@ namespace ClassicalSharp {
|
||||
texId = Window.TerrainAtlas.LoadTextureElement( texLoc );
|
||||
}
|
||||
}
|
||||
|
||||
void DrawXPlane( int x, int z1, int z2, int y1, int y2, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, z2 - z1, y2 - y1 );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y1, z1, rec.U1, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y2, z1, rec.U1, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y2, z2, rec.U2, rec.V2, col );
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y2, z2, rec.U2, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y1, z2, rec.U2, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x, y1, z1, rec.U1, rec.V1, col );
|
||||
}
|
||||
|
||||
void DrawYPlane( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, x2 - x1, z2 - z1 );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, rec.U1, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z2, rec.U1, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, rec.U2, rec.V2, col );
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, rec.U2, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z1, rec.U2, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, rec.U1, rec.V1, col );
|
||||
}
|
||||
|
||||
void DrawZPlane( int z, int x1, int x2, int y1, int y2, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
TextureRectangle rec = new TextureRectangle( 0, 0, x2 - x1, y2 - y1 );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y1, z, rec.U1, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y2, z, rec.U1, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y2, z, rec.U2, rec.V2, col );
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y2, z, rec.U2, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y1, z, rec.U2, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y1, z, rec.U1, rec.V1, col );
|
||||
}
|
||||
}
|
||||
}
|
@ -56,7 +56,6 @@ namespace ClassicalSharp {
|
||||
game.OnNewMapLoaded -= OnNewMapLoaded;
|
||||
game.EnvVariableChanged -= EnvVariableChanged;
|
||||
builder.Dispose();
|
||||
api.DeleteIb( chunkIb );
|
||||
}
|
||||
|
||||
public void Refresh() {
|
||||
@ -188,14 +187,10 @@ namespace ClassicalSharp {
|
||||
public void Render( double deltaTime ) {
|
||||
if( chunks == null ) return;
|
||||
UpdateSortOrder();
|
||||
UpdateChunks();
|
||||
if( chunkIb == -1 )
|
||||
MakeIndices();
|
||||
UpdateChunks();
|
||||
|
||||
api.BindIb( chunkIb );
|
||||
RenderNormal();
|
||||
game.MapEnvRenderer.Render( deltaTime );
|
||||
api.BindIb( chunkIb );
|
||||
RenderTranslucent();
|
||||
}
|
||||
|
||||
@ -274,25 +269,6 @@ namespace ClassicalSharp {
|
||||
api.Texturing = false;
|
||||
}
|
||||
|
||||
int chunkIb = -1;
|
||||
unsafe void MakeIndices() {
|
||||
int element = 0;
|
||||
ushort* indices = stackalloc ushort[maxIndices];
|
||||
IntPtr ptr = (IntPtr)indices;
|
||||
|
||||
for( int i = 0; i < maxIndices; i += 6 ) {
|
||||
*indices++ = (ushort)( element + 0 );
|
||||
*indices++ = (ushort)( element + 1 );
|
||||
*indices++ = (ushort)( element + 2 );
|
||||
|
||||
*indices++ = (ushort)( element + 2 );
|
||||
*indices++ = (ushort)( element + 3 );
|
||||
*indices++ = (ushort)( element + 0 );
|
||||
element += 4;
|
||||
}
|
||||
chunkIb = api.CreateIb( ptr, maxIndices );
|
||||
}
|
||||
|
||||
// Render translucent(liquid) blocks. These 'blend' into other blocks.
|
||||
void RenderTranslucent() {
|
||||
// First fill depth buffer
|
||||
|
@ -5,17 +5,16 @@ using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Renderers {
|
||||
|
||||
public class StandardEnvRenderer : EnvRenderer {
|
||||
public unsafe class StandardEnvRenderer : EnvRenderer {
|
||||
|
||||
public StandardEnvRenderer( Game window ) {
|
||||
Window = window;
|
||||
Map = Window.Map;
|
||||
}
|
||||
|
||||
int cloudTexture = -1, cloudsVbo = -1, cloudsVertices;
|
||||
int skyOffset = 10, skyVbo = -1, skyVertices;
|
||||
int index;
|
||||
public float CloudsSpeed = 1f;
|
||||
int cloudTexture = -1, cloudsVb = -1, cloudsIndices;
|
||||
int skyOffset = 10, skyVb = -1, skyIndices;
|
||||
public float CloudsSpeed = 1;
|
||||
bool legacy;
|
||||
|
||||
public void SetUseLegacyMode( bool legacy ) {
|
||||
@ -25,12 +24,13 @@ namespace ClassicalSharp.Renderers {
|
||||
}
|
||||
|
||||
public override void Render( double deltaTime ) {
|
||||
if( skyVbo == -1 || cloudsVbo == -1 ) return;
|
||||
if( skyVb == -1 || cloudsVb == -1 ) return;
|
||||
|
||||
Vector3 pos = Window.LocalPlayer.EyePosition;
|
||||
if( pos.Y < Map.Height + skyOffset ) {
|
||||
Graphics.BeginVbBatch( VertexFormat.Pos3fCol4b );
|
||||
Graphics.DrawVb( DrawMode.Triangles, skyVbo, 0, skyVertices );
|
||||
Graphics.BindVb( skyVb );
|
||||
Graphics.DrawIndexedVb( DrawMode.Triangles, skyIndices, 0, 0 );
|
||||
}
|
||||
RenderClouds( deltaTime );
|
||||
ResetFog();
|
||||
@ -55,9 +55,9 @@ namespace ClassicalSharp.Renderers {
|
||||
|
||||
public override void OnNewMap( object sender, EventArgs e ) {
|
||||
Graphics.Fog = false;
|
||||
Graphics.DeleteVb( skyVbo );
|
||||
Graphics.DeleteVb( cloudsVbo );
|
||||
skyVbo = cloudsVbo = -1;
|
||||
Graphics.DeleteVb( skyVb );
|
||||
Graphics.DeleteVb( cloudsVb );
|
||||
skyVb = cloudsVb = -1;
|
||||
}
|
||||
|
||||
public override void OnNewMapLoaded( object sender, EventArgs e ) {
|
||||
@ -82,8 +82,8 @@ namespace ClassicalSharp.Renderers {
|
||||
public override void Dispose() {
|
||||
base.Dispose();
|
||||
Window.ViewDistanceChanged -= ResetAllEnv;
|
||||
Graphics.DeleteVb( skyVbo );
|
||||
Graphics.DeleteVb( cloudsVbo );
|
||||
Graphics.DeleteVb( skyVb );
|
||||
Graphics.DeleteVb( cloudsVb );
|
||||
Graphics.DeleteTexture( ref cloudTexture );
|
||||
}
|
||||
|
||||
@ -99,7 +99,8 @@ namespace ClassicalSharp.Renderers {
|
||||
Graphics.Texturing = true;
|
||||
Graphics.BindTexture( cloudTexture );
|
||||
Graphics.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
|
||||
Graphics.DrawVb( DrawMode.Triangles, cloudsVbo, 0, cloudsVertices );
|
||||
Graphics.BindVb( cloudsVb );
|
||||
Graphics.DrawIndexedVb( DrawMode.Triangles, cloudsIndices, 0, 0 );
|
||||
Graphics.AlphaTest = false;
|
||||
Graphics.Texturing = false;
|
||||
|
||||
@ -147,114 +148,72 @@ namespace ClassicalSharp.Renderers {
|
||||
|
||||
void ResetClouds() {
|
||||
if( Map.IsNotLoaded ) return;
|
||||
index = 0;
|
||||
Graphics.DeleteVb( cloudsVbo );
|
||||
int extent = Window.ViewDistance;
|
||||
|
||||
if( legacy ) {
|
||||
ResetCloudsLegacy( Map.Height + 2, -extent, -extent, Map.Width + extent, Map.Length + extent );
|
||||
} else {
|
||||
ResetCloudsModern( Map.Height + 2, -extent, -extent, Map.Width + extent, Map.Length + extent );
|
||||
}
|
||||
Graphics.DeleteVb( cloudsVb );
|
||||
ResetClouds( Window.ViewDistance, legacy ? 128 : 65536 );
|
||||
}
|
||||
|
||||
void ResetSky() {
|
||||
if( Map.IsNotLoaded ) return;
|
||||
index = 0;
|
||||
Graphics.DeleteVb( skyVbo );
|
||||
int extent = Window.ViewDistance;
|
||||
Graphics.DeleteVb( skyVb );
|
||||
ResetSky( Window.ViewDistance, legacy ? 128 : 65536 );
|
||||
}
|
||||
|
||||
void ResetClouds( int extent, int axisSize ) {
|
||||
int x1 = -extent, x2 = Map.Width + extent;
|
||||
int z1 = -extent, z2 = Map.Length + extent;
|
||||
cloudsIndices = Utils.CountIndices( x2 - x1, z2 - z1, axisSize );
|
||||
|
||||
if( legacy ) {
|
||||
ResetSkyLegacy( Map.Height + skyOffset, -extent, -extent, Map.Width + extent, Map.Length + extent );
|
||||
} else {
|
||||
ResetSkyModern( Map.Height + skyOffset, -extent, -extent, Map.Width + extent, Map.Length + extent );
|
||||
}
|
||||
VertexPos3fTex2fCol4b* vertices = stackalloc VertexPos3fTex2fCol4b[cloudsIndices / 6 * 4];
|
||||
DrawCloudsY( x1, z1, x2, z2, Map.Height + 2, axisSize, Map.CloudsCol, vertices );
|
||||
cloudsVb = Graphics.CreateVb( (IntPtr)vertices, VertexFormat.Pos3fTex2fCol4b, cloudsIndices / 6 * 4 );
|
||||
}
|
||||
|
||||
#region Modern
|
||||
|
||||
void ResetCloudsModern( int y, int x1, int z1, int x2, int z2 ) {
|
||||
cloudsVertices = 6;
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[cloudsVertices];
|
||||
DrawCloudsYPlane( x1, z1, x2, z2, y, Map.CloudsCol, vertices );
|
||||
cloudsVbo = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
void ResetSky( int extent, int axisSize ) {
|
||||
int x1 = -extent, x2 = Map.Width + extent;
|
||||
int z1 = -extent, z2 = Map.Length + extent;
|
||||
skyIndices = Utils.CountIndices( x2 - x1, z2 - z1, axisSize );
|
||||
|
||||
VertexPos3fCol4b* vertices = stackalloc VertexPos3fCol4b[skyIndices / 6 * 4];
|
||||
DrawSkyY( x1, z1, x2, z2, Map.Height + skyOffset, axisSize, Map.SkyCol, vertices );
|
||||
skyVb = Graphics.CreateVb( (IntPtr)vertices, VertexFormat.Pos3fCol4b, skyIndices / 6 * 4 );
|
||||
}
|
||||
|
||||
void ResetSkyModern( int y, int x1, int z1, int x2, int z2 ) {
|
||||
skyVertices = 6;
|
||||
VertexPos3fCol4b[] vertices = new VertexPos3fCol4b[skyVertices];
|
||||
DrawSkyYPlane( x1, z1, x2, z2, y, Map.SkyCol, vertices );
|
||||
skyVbo = Graphics.CreateVb( vertices, VertexFormat.Pos3fCol4b );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Legacy
|
||||
|
||||
void ResetCloudsLegacy( int y, int x1, int z1, int x2, int z2 ) {
|
||||
cloudsVertices = Utils.CountVertices( x2 - x1, z2 - z1, 128 );
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[cloudsVertices];
|
||||
DrawCloudsYPlaneParts( x1, z1, x2, z2, y, Map.CloudsCol, vertices );
|
||||
cloudsVbo = Graphics.CreateVb( vertices, VertexFormat.Pos3fTex2fCol4b );
|
||||
}
|
||||
|
||||
void ResetSkyLegacy( int y, int x1, int z1, int x2, int z2 ) {
|
||||
skyVertices = Utils.CountVertices( x2 - x1, z2 - z1, 128 );
|
||||
VertexPos3fCol4b[] vertices = new VertexPos3fCol4b[skyVertices];
|
||||
DrawSkyYPlaneParts( x1, z1, x2, z2, y, Map.SkyCol, vertices );
|
||||
skyVbo = Graphics.CreateVb( vertices, VertexFormat.Pos3fCol4b );
|
||||
}
|
||||
|
||||
void DrawSkyYPlaneParts( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fCol4b[] vertices ) {
|
||||
void DrawSkyY( int x1, int z1, int x2, int z2, int y, int axisSize, FastColour col, VertexPos3fCol4b* vertices ) {
|
||||
int endX = x2, endZ = z2, startZ = z1;
|
||||
|
||||
for( ; x1 < endX; x1 += 128 ) {
|
||||
x2 = x1 + 128;
|
||||
for( ; x1 < endX; x1 += axisSize ) {
|
||||
x2 = x1 + axisSize;
|
||||
if( x2 > endX ) x2 = endX;
|
||||
z1 = startZ;
|
||||
for( ; z1 < endZ; z1 += 128 ) {
|
||||
z2 = z1 + 128;
|
||||
for( ; z1 < endZ; z1 += axisSize ) {
|
||||
z2 = z1 + axisSize;
|
||||
if( z2 > endZ ) z2 = endZ;
|
||||
DrawSkyYPlane( x1, z1, x2, z2, y, col, vertices );
|
||||
|
||||
*vertices++ = new VertexPos3fCol4b( x1, y, z1, col );
|
||||
*vertices++ = new VertexPos3fCol4b( x1, y, z2, col );
|
||||
*vertices++ = new VertexPos3fCol4b( x2, y, z2, col );
|
||||
*vertices++ = new VertexPos3fCol4b( x2, y, z1, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCloudsYPlaneParts( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
void DrawCloudsY( int x1, int z1, int x2, int z2, int y, int axisSize, FastColour col, VertexPos3fTex2fCol4b* vertices ) {
|
||||
int endX = x2, endZ = z2, startZ = z1;
|
||||
|
||||
for( ; x1 < endX; x1 += 128 ) {
|
||||
x2 = x1 + 128;
|
||||
for( ; x1 < endX; x1 += axisSize ) {
|
||||
x2 = x1 + axisSize;
|
||||
if( x2 > endX ) x2 = endX;
|
||||
z1 = startZ;
|
||||
for( ; z1 < endZ; z1 += 128 ) {
|
||||
z2 = z1 + 128;
|
||||
for( ; z1 < endZ; z1 += axisSize ) {
|
||||
z2 = z1 + axisSize;
|
||||
if( z2 > endZ ) z2 = endZ;
|
||||
DrawCloudsYPlane( x1, z1, x2, z2, y, col, vertices );
|
||||
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y, z1, x1 / 2048f, z1 / 2048f, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x1, y, z2, x1 / 2048f, z2 / 2048f, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y, z2, x2 / 2048f, z2 / 2048f, col );
|
||||
*vertices++ = new VertexPos3fTex2fCol4b( x2, y, z1, x2 / 2048f, z1 / 2048f, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
void DrawCloudsYPlane( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fTex2fCol4b[] vertices ) {
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, x1 / 2048f, z1 / 2048f, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z2, x1 / 2048f, z2 / 2048f, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, x2 / 2048f, z2 / 2048f, col );
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, x2 / 2048f, z2 / 2048f, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z1, x2 / 2048f, z1 / 2048f, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, x1 / 2048f, z1 / 2048f, col );
|
||||
}
|
||||
|
||||
void DrawSkyYPlane( int x1, int z1, int x2, int z2, int y, FastColour col, VertexPos3fCol4b[] vertices ) {
|
||||
vertices[index++] = new VertexPos3fCol4b( x1, y, z1, col );
|
||||
vertices[index++] = new VertexPos3fCol4b( x1, y, z2, col );
|
||||
vertices[index++] = new VertexPos3fCol4b( x2, y, z2, col );
|
||||
|
||||
vertices[index++] = new VertexPos3fCol4b( x2, y, z2, col );
|
||||
vertices[index++] = new VertexPos3fCol4b( x2, y, z1, col );
|
||||
vertices[index++] = new VertexPos3fCol4b( x1, y, z1, col );
|
||||
}
|
||||
}
|
||||
}
|
@ -206,7 +206,7 @@ namespace ClassicalSharp {
|
||||
return a + ( b - a ) * t;
|
||||
}
|
||||
|
||||
internal static int CountVertices( int axis1Len, int axis2Len, int axisSize ) {
|
||||
internal static int CountIndices( int axis1Len, int axis2Len, int axisSize ) {
|
||||
int cellsAxis1 = axis1Len / axisSize + ( axis1Len % axisSize != 0 ? 1 : 0 );
|
||||
int cellsAxis2 = axis2Len / axisSize + ( axis2Len % axisSize != 0 ? 1 : 0 );
|
||||
return cellsAxis1 * cellsAxis2 * 6;
|
||||
|
Loading…
x
Reference in New Issue
Block a user