Specify whether the FastBitmap instance is readonly or not. (Mainly for android)

This commit is contained in:
UnknownShadow200 2016-01-21 21:19:23 +11:00
parent be005c791f
commit 0f87b7feb5
11 changed files with 60 additions and 53 deletions

View File

@ -71,7 +71,7 @@ namespace ClassicalSharp {
if( !args.SkipPartsCheck )
GetTextParts( args.Text );
using( FastBitmap fastBmp = new FastBitmap( curBmp, true ) )
using( FastBitmap fastBmp = new FastBitmap( curBmp, true, false ) )
DrawBitmapTextImpl( fastBmp, ref args, x, y );
}

View File

@ -18,7 +18,7 @@ namespace ClassicalSharp {
public void SetFontBitmap( Bitmap bmp ) {
FontBitmap = bmp;
boxSize = FontBitmap.Width / 16;
fontPixels = new FastBitmap( FontBitmap, true );
fontPixels = new FastBitmap( FontBitmap, true, true );
CalculateTextWidths();
}

View File

@ -11,22 +11,28 @@ namespace ClassicalSharp {
/// <summary> Wrapper around a bitmap that allows extremely fast manipulation of 32bpp images. </summary>
public unsafe class FastBitmap : IDisposable {
public FastBitmap( Bitmap bmp, bool lockBits ) {
Bitmap = bmp;
if( lockBits ) {
LockBits();
}
[Obsolete( "You should always specify whether the bitmap is readonly or not." )]
public FastBitmap( Bitmap bmp, bool lockBits ) : this( bmp, lockBits, false ) {
}
public FastBitmap( int width, int height, int stride, IntPtr scan0 ) {
public FastBitmap( Bitmap bmp, bool lockBits, bool readOnly ) {
Bitmap = bmp;
if( lockBits )
LockBits();
ReadOnly = readOnly;
}
public FastBitmap( int width, int height, int stride, IntPtr scan0, bool readOnly ) {
Width = width;
Height = height;
Stride = stride;
Scan0 = scan0;
scan0Byte = (byte*)scan0;
ReadOnly = readOnly;
}
public Bitmap Bitmap;
public bool ReadOnly;
BitmapData data;
byte* scan0Byte;
@ -51,15 +57,15 @@ namespace ClassicalSharp {
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++ ) {
for( int x = 0; x < size; x++ )
dstRow[dstX + x] = srcRow[srcX + x];
}
}
}
public void Dispose() { UnlockBits(); }
#if !ANDROID
public void LockBits() {
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
if( data != null ) return;
@ -70,8 +76,8 @@ namespace ClassicalSharp {
Rectangle rec = new Rectangle( 0, 0, Bitmap.Width, Bitmap.Height );
data = Bitmap.LockBits( rec, ImageLockMode.ReadWrite, format );
scan0Byte = (byte*)data.Scan0;
Scan0 = data.Scan0;
scan0Byte = (byte*)Scan0;
Stride = data.Stride;
Width = data.Width;
Height = data.Height;
@ -95,8 +101,8 @@ namespace ClassicalSharp {
data = ByteBuffer.AllocateDirect( Bitmap.Width * Bitmap.Height * 4 );
Bitmap.CopyPixelsToBuffer( data );
scan0Byte = (byte*)data.GetDirectBufferAddress();
Scan0 = data.GetDirectBufferAddress();
scan0Byte = (byte*)Scan0;
Stride = Bitmap.Width * 4;
Width = Bitmap.Width;
Height = Bitmap.Height;
@ -106,7 +112,8 @@ namespace ClassicalSharp {
if( Bitmap == null || data == null )
return;
data.Rewind();
Bitmap.CopyPixelsFromBuffer( data ); // TODO: Only if not readonly
if( !ReadOnly )
Bitmap.CopyPixelsFromBuffer( data );
data.Dispose();
data = null;

View File

@ -45,10 +45,12 @@ namespace ClassicalSharp {
internal void RecalculateBB( int block, FastBitmap fastBmp ) {
int elemSize = fastBmp.Width / 16;
int texId = GetTextureLoc( (byte)block, TileSide.Top );
float topY = GetSpriteBB_TopY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
float bottomY = GetSpriteBB_BottomY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
float leftX = GetSpriteBB_LeftX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
float rightX = GetSpriteBB_RightX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
int texX = texId & 0x0F, texY = texId >> 4;
float topY = GetSpriteBB_TopY( elemSize, texX, texY, fastBmp );
float bottomY = GetSpriteBB_BottomY( elemSize, texX, texY, fastBmp );
float leftX = GetSpriteBB_LeftX( elemSize, texX, texY, fastBmp );
float rightX = GetSpriteBB_RightX( elemSize, texX, texY, fastBmp );
MinBB[block] = Utils.RotateY( leftX - 0.5f, bottomY, 0, angle ) + centre;
MaxBB[block] = Utils.RotateY( rightX - 0.5f, topY, 0, angle ) + centre;

View File

@ -87,7 +87,7 @@ namespace ClassicalSharp {
}
unsafe static void ClearHat( Bitmap bmp, SkinType skinType ) {
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
using( FastBitmap fastBmp = new FastBitmap( bmp, true, false ) ) {
int sizeX = (bmp.Width / 64) * 32;
int yScale = skinType == SkinType.Type64x32 ? 32 : 64;
int sizeY = (bmp.Height / yScale) * 16;

View File

@ -363,14 +363,14 @@ namespace ClassicalSharp.GraphicsAPI {
#endregion
public override void BeginFrame( GameWindow game ) {
public override void BeginFrame( Game game ) {
}
public override void EndFrame( GameWindow game ) {
game.SwapBuffers();
public override void EndFrame( Game game ) {
game.window.SwapBuffers();
}
public override void SetVSync( GameWindow game, bool value ) {
public override void SetVSync( Game game, bool value ) {
game.VSync = value;
}
@ -414,7 +414,7 @@ namespace ClassicalSharp.GraphicsAPI {
}
}
public override void OnWindowResize( GameWindow game ) {
public override void OnWindowResize( Game game ) {
GL.Viewport( 0, 0, game.Width, game.Height );
}

View File

@ -412,10 +412,8 @@ namespace ClassicalSharp {
HandleCpeDefineBlockCommonEnd( block );
// Update sprite BoundingBox if necessary
if( info.IsSprite[block] ) {
using( FastBitmap fastBmp =
new FastBitmap( game.TerrainAtlas.AtlasBitmap, true ) ) {
info.RecalculateBB( block, fastBmp );
}
using( FastBitmap dst = new FastBitmap( game.TerrainAtlas.AtlasBitmap, true, true ) )
info.RecalculateBB( block, dst );
}
}

View File

@ -40,6 +40,8 @@ namespace ClassicalSharp {
void Run();
void SwapBuffers();
void Exit();
event EventHandler<KeyPressEventArgs> KeyPress;

View File

@ -28,7 +28,7 @@ namespace ClassicalSharp.TexturePack {
public void SetAtlas( Bitmap bmp ) {
Dispose();
this.bmp = bmp;
fastBmp = new FastBitmap( bmp, true );
fastBmp = new FastBitmap( bmp, true, true );
}
/// <summary> Runs through all animations and if necessary updates the terrain atlas. </summary>
@ -102,7 +102,7 @@ namespace ClassicalSharp.TexturePack {
int size = data.FrameSize;
byte* temp = stackalloc byte[size * size * 4];
FastBitmap part = new FastBitmap( size, size, size * 4, (IntPtr)temp );
FastBitmap part = new FastBitmap( size, size, size * 4, (IntPtr)temp, false );
FastBitmap.MovePortion( data.FrameX + data.CurrentState * size, data.FrameY, 0, 0, fastBmp, part, size );
api.UpdateTexturePart( atlas.TexIds[index], 0, rowNum * game.TerrainAtlas.elementSize, part );
}

View File

@ -54,7 +54,7 @@ namespace ClassicalSharp {
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, elementsPerAtlas1D );
int index = 0;
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true ) ) {
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true, true ) ) {
for( int i = 0; i < TexIds.Length; i++ )
Make1DTexture( i, atlas, atlas2D, atlas1DHeight, ref index );
}
@ -62,15 +62,15 @@ namespace ClassicalSharp {
void Make1DTexture( int i, FastBitmap atlas, TerrainAtlas2D atlas2D, int atlas1DHeight, ref int index ) {
int elemSize = atlas2D.elementSize;
using( Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight ) ) {
using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
for( int index1D = 0; index1D < elementsPerAtlas1D; index1D++ ) {
FastBitmap.MovePortion( (index & 0x0F) * elemSize, (index >> 4) * elemSize,
0, index1D * elemSize, atlas, dst, elemSize );
index++;
}
TexIds[i] = graphics.CreateTexture( dst );
using( Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight ) )
using( FastBitmap dst = new FastBitmap( atlas1d, true, false ) )
{
for( int index1D = 0; index1D < elementsPerAtlas1D; index1D++ ) {
FastBitmap.MovePortion( (index & 0x0F) * elemSize, (index >> 4) * elemSize,
0, index1D * elemSize, atlas, dst, elemSize );
index++;
}
TexIds[i] = graphics.CreateTexture( dst );
}
}

View File

@ -43,7 +43,7 @@ namespace ClassicalSharp {
AtlasBitmap = bmp;
elementSize = bmp.Width >> 4;
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
using( FastBitmap fastBmp = new FastBitmap( bmp, true, true ) ) {
info.RecalculateSpriteBB( fastBmp );
TexId = graphics.CreateTexture( fastBmp );
}
@ -52,15 +52,13 @@ namespace ClassicalSharp {
/// <summary> Creates a new texture that contains the tile at the specified index. </summary>
public int LoadTextureElement( int index ) {
int size = elementSize;
using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
using( Bitmap bmp = new Bitmap( size, size ) ) {
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
FastBitmap.MovePortion( (index & 0x0F) * size, (index >> 4) *
size, 0, 0, atlas, dst, size );
return graphics.CreateTexture( dst );
}
}
using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true, true ) )
using( Bitmap bmp = new Bitmap( size, size ) )
using( FastBitmap dst = new FastBitmap( bmp, true, false ) )
{
FastBitmap.MovePortion( (index & 0x0F) * size, (index >> 4) *
size, 0, 0, atlas, dst, size );
return graphics.CreateTexture( dst );
}
}