diff --git a/2D/Screens/BlockSelectScreen.cs b/2D/Screens/BlockSelectScreen.cs
index 7f550b040..de43f0e70 100644
--- a/2D/Screens/BlockSelectScreen.cs
+++ b/2D/Screens/BlockSelectScreen.cs
@@ -31,7 +31,7 @@ namespace ClassicalSharp {
public override void Render( double delta ) {
GraphicsApi.Texturing = true;
- GraphicsApi.Bind2DTexture( Window.TerrainAtlasTexId );
+ GraphicsApi.Bind2DTexture( Window.TerrainAtlas.TexId );
for( int i = 0; i < blocksTable.Length; i++ ) {
Texture texture = blocksTable[i].Texture;
@@ -146,7 +146,7 @@ namespace ClassicalSharp {
float height = Window.BlockInfo.BlockHeight( (byte)block );
int blockY = y;
if( height != 1 ) {
- rec.V1 = rec.V1 + Window.TerrainAtlas.invVerElementSize * height;
+ rec.V1 = rec.V1 + TerrainAtlas2D.invElementSize * height;
verSize = (int)( blockSize * height );
blockY = y + blockSize - verSize;
}
diff --git a/2D/Widgets/BlockHotbarWidget.cs b/2D/Widgets/BlockHotbarWidget.cs
index 3394c75d2..3aec2a91e 100644
--- a/2D/Widgets/BlockHotbarWidget.cs
+++ b/2D/Widgets/BlockHotbarWidget.cs
@@ -50,7 +50,7 @@ namespace ClassicalSharp {
public override void Render( double delta ) {
GraphicsApi.Texturing = true;
// TODO: Maybe redesign this so we don't have to bind the whole atlas. Not cheap.
- GraphicsApi.Bind2DTexture( Window.TerrainAtlasTexId );
+ GraphicsApi.Bind2DTexture( Window.TerrainAtlas.TexId );
int selectedX = 0;
for( int i = 0; i < barTextures.Length; i++ ) {
barTextures[i].RenderNoBind( GraphicsApi );
@@ -83,7 +83,7 @@ namespace ClassicalSharp {
float height = Window.BlockInfo.BlockHeight( (byte)block );
int blockY = y;
if( height != 1 ) {
- rec.V1 = rec.V1 + Window.TerrainAtlas.invVerElementSize * height;
+ rec.V1 = rec.V1 + TerrainAtlas2D.invElementSize * height;
verSize = (int)( blockSize * height );
blockY = y + blockSize - verSize;
}
diff --git a/Blocks/BlockInfo.Optimised.cs b/Blocks/BlockInfo.Optimised.cs
index 4d3a7356d..37f88ff2c 100644
--- a/Blocks/BlockInfo.Optimised.cs
+++ b/Blocks/BlockInfo.Optimised.cs
@@ -131,46 +131,5 @@ namespace ClassicalSharp {
public int GetOptimTextureLoc( byte block, int face ) {
return optimTextures[block * 6 + face];
}
-
- static ushort[] RowFlags = new ushort[] {
- 0xFFFF, // y y y y y y y y y y y y y y y y
- 0xFFEE, // y y y y y y y y y y y n y y y n
- 0xFFE0, // y y y y y y y y y y y n n n n n
- 0xFFE0, // y y y y y y y y y y y n n n n n
- 0xFFFF, // y y y y y y y y y y y y y y y y
- 0xFA00, // y y y y y n y n n n n n n n n n
- };
-
- public static void MakeOptimisedTexture( FastBitmap atlas ) {
- int tileSize = atlas.Width / 16;
- int srcIndex = 0, destIndex = 0;
-
- for( int y = 0; y < 6; y++ ) {
- int flags = RowFlags[y];
- for( int x = 0; x < 16; x++ ) {
- bool isUsed = ( flags & 1 << ( 15 - x ) ) != 0;
- if( isUsed && srcIndex != destIndex ) {
- int srcX = x * tileSize;
- int srcY = y * tileSize;
- int destX = ( destIndex & 0x0F ) * tileSize;
- int destY = ( destIndex >> 4 ) * tileSize;
- MovePortion( srcX, srcY, destX, destY, atlas, tileSize );
- }
-
- srcIndex++;
- if( isUsed ) destIndex++;
- }
- }
- }
-
- unsafe static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, int size ) {
- for( int y = 0; y < size; y++ ) {
- int* srcRow = src.GetRowPtr( srcY + y );
- int* dstRow = src.GetRowPtr( dstY + y );
- for( int x = 0; x < size; x++ ) {
- dstRow[dstX + x] = srcRow[srcX + x];
- }
- }
- }
}
}
\ No newline at end of file
diff --git a/ClassicalSharp.csproj b/ClassicalSharp.csproj
index 122719d7e..9d48a3981 100644
--- a/ClassicalSharp.csproj
+++ b/ClassicalSharp.csproj
@@ -153,9 +153,11 @@
-
+
+
+
diff --git a/Entities/ParticleManager.cs b/Entities/ParticleManager.cs
index a7157fecb..53e6d2a8f 100644
--- a/Entities/ParticleManager.cs
+++ b/Entities/ParticleManager.cs
@@ -30,7 +30,7 @@ namespace ClassicalSharp.Particles {
}
Graphics.Texturing = true;
- Graphics.Bind2DTexture( Window.TerrainAtlasTexId );
+ Graphics.Bind2DTexture( Window.TerrainAtlas.TexId );
Graphics.AlphaTest = true;
Graphics.DrawVertices( DrawMode.Triangles, vertices, count );
Graphics.AlphaTest = false;
@@ -54,8 +54,8 @@ namespace ClassicalSharp.Particles {
int texLoc = Window.BlockInfo.GetOptimTextureLoc( block, TileSide.Left );
TextureRectangle rec = Window.TerrainAtlas.GetTexRec( texLoc );
- float invHorSize = Window.TerrainAtlas.invHorElementSize;
- float invVerSize = Window.TerrainAtlas.invVerElementSize;
+ float invHorSize = TerrainAtlas2D.invElementSize;
+ float invVerSize = TerrainAtlas2D.invElementSize;
int cellsCountX = (int)( 0.25f / invHorSize );
int cellsCountY = (int)( 0.25f / invVerSize );
float elementXSize = invHorSize * 0.25f;
diff --git a/Game/Game.cs b/Game/Game.cs
index cbf0df2d3..b42c86da2 100644
--- a/Game/Game.cs
+++ b/Game/Game.cs
@@ -28,8 +28,7 @@ namespace ClassicalSharp {
Camera firstPersonCam, thirdPersonCam;
public BlockInfo BlockInfo;
public double accumulator;
- public TextureAtlas2D TerrainAtlas;
- public int TerrainAtlasTexId = -1;
+ public TerrainAtlas2D TerrainAtlas;
public TextureAtlas1D TerrainAtlas1D;
public int[] TerrainAtlas1DTexIds;
public SkinType DefaultPlayerSkinType;
@@ -97,21 +96,14 @@ namespace ClassicalSharp {
void LoadAtlas( Bitmap bmp ) {
// Cleanup old atlas if applicable.
- Graphics.DeleteTexture( ref TerrainAtlasTexId );
if( TerrainAtlas1DTexIds != null ) {
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}
}
- if( TerrainAtlas != null ) {
- TerrainAtlas.AtlasBitmap.Dispose();
- }
-
- TerrainAtlas = new TextureAtlas2D( Graphics, bmp, 16, 16, 5 );
- using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
- BlockInfo.MakeOptimisedTexture( fastBmp );
- TerrainAtlasTexId = Graphics.LoadTexture( fastBmp );
- }
+ TerrainAtlas.GraphicsApi = Graphics;
+ TerrainAtlas.Dispose();
+ TerrainAtlas.UpdateState( bmp );
int size = Math.Min( 2048, Graphics.MaxTextureDimensions );
TerrainAtlas1DTexIds = TerrainAtlas1D.CreateFrom2DAtlas( Graphics, TerrainAtlas, size );
}
@@ -136,6 +128,7 @@ namespace ClassicalSharp {
PrintGraphicsInfo();
Bitmap terrainBmp = new Bitmap( "terrain.png" );
TerrainAtlas1D = new TextureAtlas1D();
+ TerrainAtlas = new TerrainAtlas2D();
LoadAtlas( terrainBmp );
BlockInfo = new BlockInfo();
BlockInfo.Init();
@@ -290,7 +283,7 @@ namespace ClassicalSharp {
SetNewScreen( null );
fpsScreen.Dispose();
SelectionManager.Dispose();
- Graphics.DeleteTexture( ref TerrainAtlasTexId );
+ TerrainAtlas.Dispose();
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}
diff --git a/Map/ChunkMeshBuilderTex2Col4.cs b/Map/ChunkMeshBuilderTex2Col4.cs
index 8e18fb36c..bd3a023fb 100644
--- a/Map/ChunkMeshBuilderTex2Col4.cs
+++ b/Map/ChunkMeshBuilderTex2Col4.cs
@@ -201,8 +201,7 @@ namespace ClassicalSharp {
void DrawTopFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Top );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -221,8 +220,7 @@ namespace ClassicalSharp {
void DrawBottomFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Bottom );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y - 1, Z, ref map.SunlightYBottom, ref map.ShadowlightYBottom );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -241,8 +239,7 @@ namespace ClassicalSharp {
void DrawBackFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Back );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X, Y, Z + 1, ref map.SunlightZSide, ref map.ShadowlightZSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -264,8 +261,7 @@ namespace ClassicalSharp {
void DrawFrontFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Front );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X, Y, Z - 1, ref map.SunlightZSide, ref map.ShadowlightZSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -287,8 +283,7 @@ namespace ClassicalSharp {
void DrawLeftFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Left );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X - 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -310,8 +305,7 @@ namespace ClassicalSharp {
void DrawRightFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X + 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@@ -333,8 +327,7 @@ namespace ClassicalSharp {
void DrawSprite( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right );
int drawInfoIndex;
- TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
- rec.U2 = count;
+ TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
diff --git a/Model/BlockModel.cs b/Model/BlockModel.cs
index c11bd4808..1087b2615 100644
--- a/Model/BlockModel.cs
+++ b/Model/BlockModel.cs
@@ -26,7 +26,7 @@ namespace ClassicalSharp.Model {
return;
}
- graphics.Bind2DTexture( window.TerrainAtlasTexId );
+ graphics.Bind2DTexture( window.TerrainAtlas.TexId );
blockHeight = window.BlockInfo.BlockHeight( block );
atlas = window.TerrainAtlas;
BlockInfo = window.BlockInfo;
@@ -46,7 +46,7 @@ namespace ClassicalSharp.Model {
}
}
float blockHeight;
- TextureAtlas2D atlas;
+ TerrainAtlas2D atlas;
BlockInfo BlockInfo;
public override void Dispose() {
@@ -69,7 +69,7 @@ namespace ClassicalSharp.Model {
int texId = BlockInfo.GetOptimTextureLoc( block, side );
TextureRectangle rec = atlas.GetTexRec( texId );
if( blockHeight != 1 ) {
- rec.V2 = rec.V1 + blockHeight * atlas.invVerElementSize;
+ rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
}
if( swapU ) rec.SwapU();
@@ -86,7 +86,7 @@ namespace ClassicalSharp.Model {
int texId = BlockInfo.GetOptimTextureLoc( block, side );
TextureRectangle rec = atlas.GetTexRec( texId );
if( blockHeight != 1 ) {
- rec.V2 = rec.V1 + blockHeight * atlas.invVerElementSize;
+ rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
}
if( swapU ) rec.SwapU();
diff --git a/Utils/TerrainAtlas2D.cs b/Utils/TerrainAtlas2D.cs
new file mode 100644
index 000000000..570fe1523
--- /dev/null
+++ b/Utils/TerrainAtlas2D.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Drawing;
+using ClassicalSharp.GraphicsAPI;
+
+namespace ClassicalSharp {
+
+ public static class TileSide {
+ public const int Left = 0;
+ public const int Right = 1;
+ public const int Front = 2;
+ public const int Back = 3;
+ public const int Bottom = 4;
+ public const int Top = 5;
+ }
+
+ public class TerrainAtlas2D : IDisposable {
+
+ public const int ElementsPerRow = 16, RowsCount = 16;
+ public const float invElementSize = 0.0625f;
+ public readonly int UsedRowsCount = 5;
+ public Bitmap AtlasBitmap;
+ public int elementSize;
+ public IGraphicsApi GraphicsApi;
+ public int TexId;
+
+ public void UpdateState( Bitmap bmp ) {
+ AtlasBitmap = bmp;
+ elementSize = bmp.Width >> 4;
+ using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
+ MakeOptimisedTexture( fastBmp );
+ TexId = GraphicsApi.LoadTexture( fastBmp );
+ }
+ }
+
+ public int LoadTextureElement( int index ) {
+ int x = index & 0x0F;
+ int y = index >> 4;
+ using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
+ Bitmap bmp = new Bitmap( elementSize, elementSize );
+ using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
+ Utils.MovePortion( x * elementSize, y * elementSize, 0, 0, atlas, dst, elementSize );
+ return GraphicsApi.LoadTexture( dst );
+ }
+ }
+ }
+
+ public TextureRectangle GetTexRec( int index ) {
+ int x = index & 0x0F;
+ int y = index >> 4;
+ return new TextureRectangle( x * invElementSize, y * invElementSize, invElementSize, invElementSize );
+ }
+
+ public void Dispose() {
+ if( AtlasBitmap != null ) {
+ AtlasBitmap.Dispose();
+ }
+ GraphicsApi.DeleteTexture( ref TexId );
+ }
+
+ static ushort[] rowFlags = { 0xFFFF, 0xFFEE, 0xFFE0, 0xFFE0, 0xFFFF, 0xFA00 };
+ void MakeOptimisedTexture( FastBitmap atlas ) {
+ int srcIndex = 0, destIndex = 0;
+
+ for( int y = 0; y < 6; y++ ) {
+ int flags = rowFlags[y];
+ for( int x = 0; x < ElementsPerRow; x++ ) {
+ bool isUsed = ( flags & 1 << ( 15 - x ) ) != 0;
+ if( isUsed && srcIndex != destIndex ) {
+ int dstX = ( destIndex & 0x0F ) * elementSize;
+ int dstY = ( destIndex >> 4 ) * elementSize;
+ Utils.MovePortion( x * elementSize, y * elementSize, dstX, dstY, atlas, atlas, elementSize );
+ }
+
+ srcIndex++;
+ if( isUsed ) destIndex++;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Utils/TextureAtlas1D.cs b/Utils/TextureAtlas1D.cs
index c14f5483e..2b28a86d4 100644
--- a/Utils/TextureAtlas1D.cs
+++ b/Utils/TextureAtlas1D.cs
@@ -10,10 +10,10 @@ namespace ClassicalSharp {
internal int elementsPerBitmap;
public float invElementSize;
- public TextureRectangle GetTexRec( int texId, out int index ) {
+ public TextureRectangle GetTexRec( int texId, int uCount, out int index ) {
index = texId / usedElementsPerAtlas1D;
int y = texId % usedElementsPerAtlas1D;
- return new TextureRectangle( 0, y * invElementSize, 1, invElementSize );
+ return new TextureRectangle( 0, y * invElementSize, uCount, invElementSize );
}
public int Get1DIndex( int texId ) {
@@ -24,34 +24,35 @@ namespace ClassicalSharp {
return texId % usedElementsPerAtlas1D;
}
- public int[] CreateFrom2DAtlas( IGraphicsApi graphics, TextureAtlas2D atlas2D, int maxVerSize ) {
- int verElements = maxVerSize / atlas2D.verElementSize;
- int totalElements = atlas2D.UsedRowsCount * atlas2D.ElementsPerRow;
+ public int[] CreateFrom2DAtlas( IGraphicsApi graphics, TerrainAtlas2D atlas2D, int maxVerSize ) {
+ int verElements = maxVerSize / atlas2D.elementSize;
+ int totalElements = atlas2D.UsedRowsCount * TerrainAtlas2D.ElementsPerRow;
+ int elemSize = atlas2D.elementSize;
int atlasesCount = totalElements / verElements + ( totalElements % verElements != 0 ? 1 : 0 );
usedElementsPerAtlas1D = Math.Min( verElements, totalElements ); // in case verElements > totalElements
- int atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.verElementSize );
+ int atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.elementSize );
int index = 0;
- int x = 0, y = 0;
int[] texIds = new int[atlasesCount];
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, usedElementsPerAtlas1D );
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true ) ) {
for( int i = 0; i < texIds.Length; i++ ) {
- Bitmap atlas1d = new Bitmap( atlas2D.horElementSize, atlas1DHeight );
- using( FastBitmap dest = new FastBitmap( atlas1d, true ) ) {
- for( int j = 0; j < usedElementsPerAtlas1D; j++ ) {
- atlas2D.GetCoords( index, ref x, ref y );
- atlas2D.CopyPortion( x, y, 0, j * atlas2D.verElementSize, atlas, dest );
+ Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight );
+ using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
+ for( int y_1D = 0; y_1D < usedElementsPerAtlas1D; y_1D++ ) {
+ int x = index & 0x0F;
+ int y = index >> 4;
+ Utils.MovePortion( x * elemSize, y * elemSize, 0, y_1D * elemSize, atlas, dst, elemSize );
index++;
}
- texIds[i] = graphics.LoadTexture( dest );
+ texIds[i] = graphics.LoadTexture( dst );
}
atlas1d.Dispose();
}
}
- elementsPerBitmap = atlas1DHeight / atlas2D.verElementSize;
+ elementsPerBitmap = atlas1DHeight / atlas2D.elementSize;
invElementSize = 1f / elementsPerBitmap;
return texIds;
}
diff --git a/Utils/TextureAtlas2D.cs b/Utils/TextureAtlas2D.cs
deleted file mode 100644
index 281ef3ab3..000000000
--- a/Utils/TextureAtlas2D.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-using System;
-using System.Drawing;
-using ClassicalSharp.GraphicsAPI;
-
-namespace ClassicalSharp {
-
- public struct TextureRectangle {
- public float U1, V1, U2, V2;
-
- public TextureRectangle( float u, float v, float uWidth, float vHeight ) {
- U1 = u;
- V1 = v;
- U2 = u + uWidth;
- V2 = v + vHeight;
- }
-
- public static TextureRectangle FromPoints( float u1, float u2, float v1, float v2 ) {
- TextureRectangle rec;
- rec.U1 = u1;
- rec.U2 = u2;
- rec.V1 = v1;
- rec.V2 = v2;
- return rec;
- }
-
- public override string ToString() {
- return String.Format( "{0}, {1} : {2}, {3}", U1, V1, U2, V2 );
- }
-
- internal void SwapU() {
- float u2 = U2;
- U2 = U1;
- U1 = u2;
- }
- }
-
- public static class TileSide {
- public const int Left = 0;
- public const int Right = 1;
- public const int Front = 2;
- public const int Back = 3;
- public const int Bottom = 4;
- public const int Top = 5;
- }
-
- public class TextureAtlas2D : IDisposable {
-
- public int ElementsPerRow;
- public int RowsCount;
- public int UsedRowsCount;
- public Bitmap AtlasBitmap;
- public int horElementSize, verElementSize;
- public float invHorElementSize, invVerElementSize;
- public IGraphicsApi GraphicsApi;
-
- public TextureAtlas2D( IGraphicsApi graphics, string path, int elementsPerRow, int rows, int usedRows ) {
- Bitmap bmp = new Bitmap( path );
- GraphicsApi = graphics;
- Init( bmp, elementsPerRow, rows, usedRows );
- }
-
- public TextureAtlas2D( IGraphicsApi graphics, Bitmap bmp, int elementsPerRow, int rows, int usedRows ) {
- GraphicsApi = graphics;
- Init( bmp, elementsPerRow, rows, usedRows );
- }
-
- void Init( Bitmap bmp, int elementsPerRow, int rows, int usedRows ) {
- AtlasBitmap = bmp;
- ElementsPerRow = elementsPerRow;
- RowsCount = rows;
- horElementSize = bmp.Width / ElementsPerRow;
- verElementSize = bmp.Height / RowsCount;
- UsedRowsCount = usedRows;
- invHorElementSize = (float)horElementSize / bmp.Width;
- invVerElementSize = (float)verElementSize / bmp.Height;
- }
-
- public int LoadTextureElement( int x, int y ) {
- using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
- Bitmap bmp = new Bitmap( horElementSize, verElementSize );
- using( FastBitmap dest = new FastBitmap( bmp, true ) ) {
- CopyPortion( x, y, 0, 0, atlas, dest );
- return GraphicsApi.LoadTexture( dest );
- }
- }
- }
-
- public int LoadTextureElement( int index ) {
- int x = 0, y = 0;
- GetCoords( index, ref x, ref y );
- return LoadTextureElement( x, y );
- }
-
- public TextureRectangle GetTexRec( int x, int y ) {
- return new TextureRectangle( x * invHorElementSize, y * invVerElementSize,
- invHorElementSize, invVerElementSize );
- }
-
- public TextureRectangle GetTexRec( int index ) {
- int x = 0, y = 0;
- GetCoords( index, ref x, ref y );
- return GetTexRec( x, y );
- }
-
- internal void GetCoords( int id, ref int x, ref int y ) {
- x = id % ElementsPerRow;
- y = id / ElementsPerRow;
- }
-
- internal unsafe void CopyPortion( int tileX, int tileY, int dstX, int dstY, FastBitmap atlas, FastBitmap dst ) {
- int atlasX = tileX * horElementSize;
- int atlasY = tileY * verElementSize;
- for( int y = 0; y < verElementSize; y++ ) {
- int* srcRow = atlas.GetRowPtr( atlasY + y );
- int* dstRow = dst.GetRowPtr( dstY + y );
- for( int x = 0; x < horElementSize; x++ ) {
- dstRow[dstX + x] = srcRow[atlasX + x];
- }
- }
- }
-
- public void Dispose() {
- if( AtlasBitmap != null ) {
- AtlasBitmap.Dispose();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Utils/TextureRectangle.cs b/Utils/TextureRectangle.cs
new file mode 100644
index 000000000..7320799fb
--- /dev/null
+++ b/Utils/TextureRectangle.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace ClassicalSharp {
+
+ public struct TextureRectangle {
+ public float U1, V1, U2, V2;
+
+ public TextureRectangle( float u, float v, float uWidth, float vHeight ) {
+ U1 = u;
+ V1 = v;
+ U2 = u + uWidth;
+ V2 = v + vHeight;
+ }
+
+ public static TextureRectangle FromPoints( float u1, float u2, float v1, float v2 ) {
+ TextureRectangle rec;
+ rec.U1 = u1;
+ rec.U2 = u2;
+ rec.V1 = v1;
+ rec.V2 = v2;
+ return rec;
+ }
+
+ public override string ToString() {
+ return String.Format( "{0}, {1} : {2}, {3}", U1, V1, U2, V2 );
+ }
+
+ internal void SwapU() {
+ float u2 = U2;
+ U2 = U1;
+ U1 = u2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Utils/Utils.cs b/Utils/Utils.cs
index 420a61ecb..8b4baa0c8 100644
--- a/Utils/Utils.cs
+++ b/Utils/Utils.cs
@@ -1,9 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Text;
-using ClassicalSharp.GraphicsAPI;
-using OpenTK;
+using System;
+using System.Drawing;
+using System.Text;
+using OpenTK;
namespace ClassicalSharp {
@@ -230,118 +228,15 @@ namespace ClassicalSharp {
throw new NotSupportedException( "unsupported skin: " + bmp.Width + ", " + bmp.Height );
}
}
- }
-
- public struct Vector3I {
- public static Vector3I Zero = new Vector3I( 0, 0, 0 );
- public static Vector3I UnitX = new Vector3I( 1, 0, 0 );
- public static Vector3I UnitY = new Vector3I( 0, 1, 0 );
- public static Vector3I UnitZ = new Vector3I( 0, 0, 1 );
-
- public int X, Y, Z;
-
- public float Length {
- get { return (float)Math.Sqrt( X * X + Y * Y + Z + Z ); }
- }
-
- public int LengthSquared {
- get { return X * X + Y * Y + Z + Z; }
- }
-
- public Vector3 Normalise() {
- float len = Length;
- return new Vector3( X / len, Y / len, Z / len );
- }
-
- public Vector3I( int x, int y, int z ) {
- X = x;
- Y = y;
- Z = z;
- }
-
- public Vector3I( int value ) {
- X = value;
- Y = value;
- Z = value;
- }
-
- public static Vector3I operator + ( Vector3I left, Vector3I right ) {
- return new Vector3I( left.X + right.X, left.Y + right.Y, left.Z + right.Z );
- }
-
- public static Vector3I operator - ( Vector3I left, Vector3I right ) {
- return new Vector3I( left.X - right.X, left.Y - right.Y, left.Z - right.Z );
- }
-
- public static Vector3I operator - ( Vector3I left ) {
- return new Vector3I( -left.X, -left.Y, -left.Z );
- }
-
- public static explicit operator Vector3I( Vector3 value ) {
- return Truncate( value );
- }
-
- public static explicit operator Vector3( Vector3I value ) {
- return new Vector3( value.X, value.Y, value.Z );
- }
-
- public override bool Equals( object obj ) {
- return obj is Vector3I && Equals( (Vector3I)obj );
- }
-
- public bool Equals( Vector3I other ) {
- return X == other.X && Y == other.Y && Z == other.Z;
- }
-
- public override int GetHashCode(){
- int hashCode = 1000000007 * X;
- hashCode += 1000000009 * Y;
- hashCode += 1000000021 * Z;
- return hashCode;
- }
-
- public static bool operator == ( Vector3I lhs, Vector3I rhs ) {
- return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
- }
-
- public static bool operator != (Vector3I lhs, Vector3I rhs) {
- return !( lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z );
- }
-
- public static Vector3I Truncate( Vector3 vector ) {
- int x = (int)vector.X;
- int y = (int)vector.Y;
- int z = (int)vector.Z;
- return new Vector3I( x, y, z );
- }
-
- public static Vector3I Floor( Vector3 value ) {
- return new Vector3I( Utils.Floor( value.X ), Utils.Floor( value.Y ), Utils.Floor( value.Z ) );
- }
-
- public static Vector3I Floor( float x, float y, float z ) {
- return new Vector3I( Utils.Floor( x ), Utils.Floor( y ), Utils.Floor( z ) );
- }
-
- public static Vector3I Min( Vector3I p1, Vector3I p2 ) {
- return new Vector3I( Math.Min( p1.X, p2.X ), Math.Min( p1.Y, p2.Y ), Math.Min( p1.Z, p2.Z ) );
- }
-
- public static Vector3I Min( int x1, int y1, int z1, int x2, int y2, int z2 ) {
- return new Vector3I( Math.Min( x1, x2 ), Math.Min( y1, y2 ), Math.Min( z1, z2 ) );
- }
-
- public static Vector3I Max( Vector3I p1, Vector3I p2 ) {
- return new Vector3I( Math.Max( p1.X, p2.X ), Math.Max( p1.Y, p2.Y ), Math.Max( p1.Z, p2.Z ) );
- }
-
- public static Vector3I Max( int x1, int y1, int z1, int x2, int y2, int z2 ) {
- return new Vector3I( Math.Max( x1, x2 ), Math.Max( y1, y2 ), Math.Max( z1, z2 ) );
- }
-
- public override string ToString() {
- return X + "," + Y + "," + Z;
+ internal unsafe static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, FastBitmap dst, int size ) {
+ for( int y = 0; y < size; y++ ) {
+ int* srcRow = src.GetRowPtr( srcY + y );
+ int* dstRow = dst.GetRowPtr( dstY + y );
+ for( int x = 0; x < size; x++ ) {
+ dstRow[dstX + x] = srcRow[srcX + x];
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/Utils/Vector3I.cs b/Utils/Vector3I.cs
new file mode 100644
index 000000000..28aa1d619
--- /dev/null
+++ b/Utils/Vector3I.cs
@@ -0,0 +1,118 @@
+using System;
+using OpenTK;
+
+namespace ClassicalSharp {
+
+ public struct Vector3I {
+
+ public static Vector3I Zero = new Vector3I( 0, 0, 0 );
+ public static Vector3I UnitX = new Vector3I( 1, 0, 0 );
+ public static Vector3I UnitY = new Vector3I( 0, 1, 0 );
+ public static Vector3I UnitZ = new Vector3I( 0, 0, 1 );
+
+ public int X, Y, Z;
+
+ public float Length {
+ get { return (float)Math.Sqrt( X * X + Y * Y + Z + Z ); }
+ }
+
+ public int LengthSquared {
+ get { return X * X + Y * Y + Z + Z; }
+ }
+
+ public Vector3 Normalise() {
+ float len = Length;
+ return new Vector3( X / len, Y / len, Z / len );
+ }
+
+ public Vector3I( int x, int y, int z ) {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ public Vector3I( int value ) {
+ X = value;
+ Y = value;
+ Z = value;
+ }
+
+ public static Vector3I operator + ( Vector3I left, Vector3I right ) {
+ return new Vector3I( left.X + right.X, left.Y + right.Y, left.Z + right.Z );
+ }
+
+ public static Vector3I operator - ( Vector3I left, Vector3I right ) {
+ return new Vector3I( left.X - right.X, left.Y - right.Y, left.Z - right.Z );
+ }
+
+ public static Vector3I operator - ( Vector3I left ) {
+ return new Vector3I( -left.X, -left.Y, -left.Z );
+ }
+
+ public static explicit operator Vector3I( Vector3 value ) {
+ return Truncate( value );
+ }
+
+ public static explicit operator Vector3( Vector3I value ) {
+ return new Vector3( value.X, value.Y, value.Z );
+ }
+
+ public override bool Equals( object obj ) {
+ return obj is Vector3I && Equals( (Vector3I)obj );
+ }
+
+ public bool Equals( Vector3I other ) {
+ return X == other.X && Y == other.Y && Z == other.Z;
+ }
+
+ public override int GetHashCode(){
+ int hashCode = 1000000007 * X;
+ hashCode += 1000000009 * Y;
+ hashCode += 1000000021 * Z;
+ return hashCode;
+ }
+
+ public static bool operator == ( Vector3I lhs, Vector3I rhs ) {
+ return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
+ }
+
+ public static bool operator != (Vector3I lhs, Vector3I rhs) {
+ return !( lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z );
+ }
+
+ public static Vector3I Truncate( Vector3 vector ) {
+ int x = (int)vector.X;
+ int y = (int)vector.Y;
+ int z = (int)vector.Z;
+ return new Vector3I( x, y, z );
+ }
+
+ public static Vector3I Floor( Vector3 value ) {
+ return new Vector3I( Utils.Floor( value.X ), Utils.Floor( value.Y ), Utils.Floor( value.Z ) );
+ }
+
+ public static Vector3I Floor( float x, float y, float z ) {
+ return new Vector3I( Utils.Floor( x ), Utils.Floor( y ), Utils.Floor( z ) );
+ }
+
+ public static Vector3I Min( Vector3I p1, Vector3I p2 ) {
+ return new Vector3I( Math.Min( p1.X, p2.X ), Math.Min( p1.Y, p2.Y ), Math.Min( p1.Z, p2.Z ) );
+ }
+
+ public static Vector3I Min( int x1, int y1, int z1, int x2, int y2, int z2 ) {
+ return new Vector3I( Math.Min( x1, x2 ), Math.Min( y1, y2 ), Math.Min( z1, z2 ) );
+ }
+
+ public static Vector3I Max( Vector3I p1, Vector3I p2 ) {
+ return new Vector3I( Math.Max( p1.X, p2.X ), Math.Max( p1.Y, p2.Y ), Math.Max( p1.Z, p2.Z ) );
+ }
+
+ public static Vector3I Max( int x1, int y1, int z1, int x2, int y2, int z2 ) {
+ return new Vector3I( Math.Max( x1, x2 ), Math.Max( y1, y2 ), Math.Max( z1, z2 ) );
+ }
+
+ public override string ToString() {
+ return X + "," + Y + "," + Z;
+ }
+ }
+}
\ No newline at end of file