mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
Add more methods for android, add platform class to abstract away some platform differences.
This commit is contained in:
parent
99bd040d2f
commit
101cbc5f06
@ -3,6 +3,7 @@ using System;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using Android.Graphics;
|
||||
using Android.Graphics.Drawables;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
@ -11,7 +12,7 @@ namespace ClassicalSharp {
|
||||
Bitmap measuringBmp;
|
||||
Canvas measuringC;
|
||||
|
||||
public GdiPlusDrawer2D( IGraphicsApi graphics ) {
|
||||
public CanvasDrawer2D( IGraphicsApi graphics ) {
|
||||
this.graphics = graphics;
|
||||
measuringBmp = Bitmap.CreateBitmap( 1, 1, Bitmap.Config.Argb8888 );
|
||||
measuringC = new Canvas( measuringBmp );
|
@ -21,6 +21,8 @@ namespace ClassicalSharp {
|
||||
c = new Canvas( bmp );
|
||||
curBmp = bmp;
|
||||
}
|
||||
|
||||
public override Bitmap ConvertTo32Bpp( Bitmap src ) { return src; }
|
||||
|
||||
public override void DrawRect( FastColour colour, int x, int y, int width, int height ) {
|
||||
RectF rec = new RectF( x, y, x + width, y + height );
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
#if !ANDROID
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
@ -119,3 +120,4 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
#if !ANDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
@ -102,3 +103,4 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
@ -140,7 +143,7 @@ namespace ClassicalSharp {
|
||||
|
||||
/// <summary> Creates a power-of-2 sized bitmap larger or equal to to the given size. </summary>
|
||||
public static Bitmap CreatePow2Bitmap( Size size ) {
|
||||
return new Bitmap( Utils.NextPowerOf2( size.Width ), Utils.NextPowerOf2( size.Height ) );
|
||||
return Platform.CreateBmp( Utils.NextPowerOf2( size.Width ), Utils.NextPowerOf2( size.Height ) );
|
||||
}
|
||||
|
||||
protected List<TextPart> parts = new List<TextPart>( 64 );
|
||||
|
143
ClassicalSharp/2D/Drawing/IsometricBlockDrawer.cs
Normal file
143
ClassicalSharp/2D/Drawing/IsometricBlockDrawer.cs
Normal file
@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using ClassicalSharp.Model;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
public static class IsometricBlockDrawer {
|
||||
|
||||
static BlockInfo info;
|
||||
static ModelCache cache;
|
||||
static TerrainAtlas2D atlas;
|
||||
static int index;
|
||||
static float scale;
|
||||
static Vector3 minBB, maxBB;
|
||||
const float invElemSize = TerrainAtlas2D.invElementSize;
|
||||
static bool fullBright;
|
||||
|
||||
static FastColour colNormal, colXSide, colZSide, colYBottom;
|
||||
static float cosX, sinX, cosY, sinY;
|
||||
static IsometricBlockDrawer() {
|
||||
colNormal = FastColour.White;
|
||||
FastColour.GetShaded( colNormal, ref colXSide, ref colZSide, ref colYBottom );
|
||||
|
||||
cosX = (float)Math.Cos( 26.565f * Utils.Deg2Rad );
|
||||
sinX = (float)Math.Sin( 26.565f * Utils.Deg2Rad );
|
||||
cosY = (float)Math.Cos( -45f * Utils.Deg2Rad );
|
||||
sinY = (float)Math.Sin( -45f * Utils.Deg2Rad );
|
||||
}
|
||||
|
||||
public static void Draw( Game game, byte block, float size, float x, float y ) {
|
||||
info = game.BlockInfo;
|
||||
cache = game.ModelCache;
|
||||
atlas = game.TerrainAtlas;
|
||||
minBB = info.MinBB[block];
|
||||
maxBB = info.MaxBB[block];
|
||||
fullBright = info.FullBright[block];
|
||||
if( info.IsSprite[block] ) {
|
||||
minBB = Vector3.Zero; maxBB = Vector3.One;
|
||||
}
|
||||
if( info.IsAir[block] ) return;
|
||||
index = 0;
|
||||
|
||||
// isometric coords size: cosY * -scale - sinY * scale
|
||||
// we need to divide by (2 * cosY), as the calling function expects size to be in pixels.
|
||||
scale = size / (2 * cosY);
|
||||
// screen to isometric coords (cos(-x) = cos(x), sin(-x) = -sin(x))
|
||||
pos.X = x; pos.Y = y; pos.Z = 0;
|
||||
pos = Utils.RotateY( Utils.RotateX( pos, cosX, -sinX ), cosY, -sinY );
|
||||
|
||||
if( info.IsSprite[block] ) {
|
||||
XQuad( block, 0f, TileSide.Right );
|
||||
ZQuad( block, 0f, TileSide.Back );
|
||||
} else {
|
||||
XQuad( block, Make( maxBB.X ), TileSide.Left );
|
||||
ZQuad( block, Make( minBB.Z ), TileSide.Back );
|
||||
YQuad( block, Make( maxBB.Y ), TileSide.Top );
|
||||
}
|
||||
|
||||
for( int i = 0; i < index; i++ )
|
||||
TransformVertex( ref cache.vertices[i] );
|
||||
game.Graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, cache.vb,
|
||||
cache.vertices, index, index * 6 / 4 );
|
||||
}
|
||||
|
||||
static void TransformVertex( ref VertexPos3fTex2fCol4b vertex ) {
|
||||
Vector3 p = new Vector3( vertex.X, vertex.Y, vertex.Z );
|
||||
//p = Utils.RotateY( p - pos, time ) + pos;
|
||||
// See comment in IGraphicsApi.Draw2DTexture()
|
||||
p.X -= 0.5f; p.Y -= 0.5f;
|
||||
p = Utils.RotateX( Utils.RotateY( p, cosY, sinY ), cosX, sinX );
|
||||
vertex.X = p.X; vertex.Y = p.Y; vertex.Z = p.Z;
|
||||
}
|
||||
|
||||
static Vector3 pos = Vector3.Zero;
|
||||
static void YQuad( byte block, float y, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = colNormal;
|
||||
float uOrigin = rec.U1, vOrigin = rec.V1;
|
||||
|
||||
rec.U1 = uOrigin + minBB.Z * invElemSize;
|
||||
rec.U2 = uOrigin + maxBB.Z * invElemSize * 15.99f/16f;
|
||||
rec.V1 = vOrigin + minBB.X * invElemSize;
|
||||
rec.V2 = vOrigin + maxBB.X * invElemSize * 15.99f/16f;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( minBB.X ), pos.Y + y,
|
||||
pos.Z + Make( minBB.Z ), rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( minBB.X ), pos.Y + y,
|
||||
pos.Z + Make( maxBB.Z ), rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( maxBB.X ), pos.Y + y,
|
||||
pos.Z + Make( maxBB.Z ), rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( maxBB.X ), pos.Y + y,
|
||||
pos.Z + Make( minBB.Z ), rec.U2, rec.V1, col );
|
||||
}
|
||||
|
||||
static void ZQuad( byte block, float z, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = fullBright ? colNormal : colZSide;
|
||||
float uOrigin = rec.U1, vOrigin = rec.V1;
|
||||
|
||||
rec.U1 = uOrigin + minBB.X * invElemSize;
|
||||
rec.U2 = uOrigin + maxBB.X * invElemSize * 15.99f/16f;
|
||||
rec.V1 = vOrigin + (1 - maxBB.Y) * invElemSize;
|
||||
rec.V2 = vOrigin + (1 - minBB.Y) * invElemSize;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( minBB.X ), pos.Y + Make( minBB.Y ),
|
||||
pos.Z + z, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( minBB.X ), pos.Y + Make( maxBB.Y ),
|
||||
pos.Z + z, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( maxBB.X ), pos.Y + Make( maxBB.Y ),
|
||||
pos.Z + z, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + Make( maxBB.X ), pos.Y + Make( minBB.Y ),
|
||||
pos.Z + z, rec.U1, rec.V2, col );
|
||||
}
|
||||
|
||||
static float Make( float value ) {
|
||||
return scale - (scale * value * 2);
|
||||
}
|
||||
|
||||
static void XQuad( byte block, float x, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = fullBright ? colNormal : colXSide;
|
||||
float uOrigin = rec.U1, vOrigin = rec.V1;
|
||||
|
||||
rec.U1 = uOrigin + minBB.Z * invElemSize;
|
||||
rec.U2 = uOrigin + maxBB.Z * invElemSize * 15.99f/16f;
|
||||
rec.V1 = vOrigin + (1 - maxBB.Y) * invElemSize;
|
||||
rec.V2 = vOrigin + (1 - minBB.Y) * invElemSize * 15.99f/16f;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + Make( minBB.Y ),
|
||||
pos.Z + Make( minBB.Z ), rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + Make( maxBB.Y ),
|
||||
pos.Z + Make( minBB.Z ), rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + Make( maxBB.Y ),
|
||||
pos.Z + Make( maxBB.Z ), rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + Make( minBB.Y ),
|
||||
pos.Z + Make( maxBB.Z ), rec.U1, rec.V2, col );
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
using Java.Nio;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
@ -38,6 +42,24 @@ namespace ClassicalSharp {
|
||||
return format == PixelFormat.Format32bppRgb || format == PixelFormat.Format32bppArgb;
|
||||
}
|
||||
|
||||
/// <summary> Returns a pointer to the start of the y'th scanline. </summary>
|
||||
public int* GetRowPtr( int y ) {
|
||||
return (int*)(scan0Byte + (y * Stride));
|
||||
}
|
||||
|
||||
public 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() { UnlockBits(); }
|
||||
|
||||
#if !ANDROID
|
||||
public void LockBits() {
|
||||
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
|
||||
if( data != null ) return;
|
||||
@ -55,33 +77,43 @@ namespace ClassicalSharp {
|
||||
Height = data.Height;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
UnlockBits();
|
||||
public void UnlockBits() {
|
||||
if( Bitmap == null || data == null )
|
||||
return;
|
||||
Bitmap.UnlockBits( data );
|
||||
data = null;
|
||||
scan0Byte = (byte*)IntPtr.Zero;
|
||||
Scan0 = IntPtr.Zero;
|
||||
Width = Height = Stride = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
public void LockBits() {
|
||||
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
|
||||
if( data != null ) return;
|
||||
|
||||
data = ByteBuffer.AllocateDirect( Bitmap.Width * Bitmap.Height * 4 );
|
||||
Bitmap.CopyPixelsToBuffer( data );
|
||||
scan0Byte = (byte*)data.GetDirectBufferAddress();
|
||||
Scan0 = data.GetDirectBufferAddress();
|
||||
Stride = Bitmap.Width * 4;
|
||||
Width = Bitmap.Width;
|
||||
Height = Bitmap.Height;
|
||||
}
|
||||
|
||||
public void UnlockBits() {
|
||||
if( Bitmap != null && data != null ) {
|
||||
Bitmap.UnlockBits( data );
|
||||
data = null;
|
||||
scan0Byte = (byte*)IntPtr.Zero;
|
||||
Scan0 = IntPtr.Zero;
|
||||
Width = Height = Stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns a pointer to the start of the y'th scanline. </summary>
|
||||
public int* GetRowPtr( int y ) {
|
||||
return (int*)(scan0Byte + (y * Stride));
|
||||
}
|
||||
|
||||
public 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];
|
||||
}
|
||||
}
|
||||
if( Bitmap == null || data == null )
|
||||
return;
|
||||
data.Rewind();
|
||||
Bitmap.CopyPixelsFromBuffer( data ); // TODO: Only if not readonly
|
||||
data.Dispose();
|
||||
|
||||
data = null;
|
||||
scan0Byte = (byte*)IntPtr.Zero;
|
||||
Scan0 = IntPtr.Zero;
|
||||
Width = Height = Stride = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
using System;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using ClassicalSharp.Model;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
public static class IsometricBlockDrawer {
|
||||
|
||||
static BlockInfo info;
|
||||
static ModelCache cache;
|
||||
static TerrainAtlas2D atlas;
|
||||
static float blockHeight;
|
||||
static int index;
|
||||
static float scale;
|
||||
static Vector3 minBB, maxBB;
|
||||
|
||||
static FastColour colNormal, colXSide, colZSide, colYBottom;
|
||||
static float cosX, sinX, cosY, sinY;
|
||||
static IsometricBlockDrawer() {
|
||||
colNormal = FastColour.White;
|
||||
FastColour.GetShaded( colNormal, ref colXSide, ref colZSide, ref colYBottom );
|
||||
|
||||
cosX = (float)Math.Cos( 26.565f * Utils.Deg2Rad );
|
||||
sinX = (float)Math.Sin( 26.565f * Utils.Deg2Rad );
|
||||
cosY = (float)Math.Cos( -45f * Utils.Deg2Rad );
|
||||
sinY = (float)Math.Sin( -45f * Utils.Deg2Rad );
|
||||
}
|
||||
|
||||
public static void Draw( Game game, byte block, float size, float x, float y ) {
|
||||
info = game.BlockInfo;
|
||||
cache = game.ModelCache;
|
||||
atlas = game.TerrainAtlas;
|
||||
minBB = info.MinBB[block];
|
||||
maxBB = info.MaxBB[block];
|
||||
blockHeight = info.Height[block];
|
||||
index = 0;
|
||||
// isometric coords size: cosY * -scale - sinY * scale
|
||||
// we need to divide by (2 * cosY), as the calling function expects size to be in pixels.
|
||||
scale = size / (2 * cosY);
|
||||
|
||||
// screen to isometric coords (cos(-x) = cos(x), sin(-x) = -sin(x))
|
||||
pos.X = x; pos.Y = y; pos.Z = 0;
|
||||
pos = Utils.RotateY( Utils.RotateX( pos, cosX, -sinX ), cosY, -sinY );
|
||||
|
||||
if( info.IsSprite[block] ) {
|
||||
XQuad( block, 0f, TileSide.Right );
|
||||
ZQuad( block, 0f, TileSide.Back );
|
||||
} else {
|
||||
XQuad( block, scale, TileSide.Left );
|
||||
ZQuad( block, -scale, TileSide.Back );
|
||||
YQuad( block, Y( maxBB.Y ), TileSide.Top );
|
||||
}
|
||||
|
||||
for( int i = 0; i < index; i++ )
|
||||
TransformVertex( ref cache.vertices[i] );
|
||||
game.Graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, cache.vb,
|
||||
cache.vertices, index, index * 6 / 4 );
|
||||
}
|
||||
|
||||
static void TransformVertex( ref VertexPos3fTex2fCol4b vertex ) {
|
||||
Vector3 p = new Vector3( vertex.X, vertex.Y, vertex.Z );
|
||||
//p = Utils.RotateY( p - pos, time ) + pos;
|
||||
// See comment in IGraphicsApi.Draw2DTexture()
|
||||
p.X -= 0.5f; p.Y -= 0.5f;
|
||||
p = Utils.RotateX( Utils.RotateY( p, cosY, sinY ), cosX, sinX );
|
||||
vertex.X = p.X; vertex.Y = p.Y; vertex.Z = p.Z;
|
||||
}
|
||||
|
||||
static Vector3 pos = Vector3.Zero;
|
||||
static void YQuad( byte block, float y, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = colNormal;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y - y,
|
||||
pos.Z - scale, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y - y,
|
||||
pos.Z + scale, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y - y,
|
||||
pos.Z + scale, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y - y,
|
||||
pos.Z - scale, rec.U2, rec.V1, col );
|
||||
}
|
||||
|
||||
static void ZQuad( byte block, float z, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = colZSide;
|
||||
|
||||
float vOrigin = rec.V1;
|
||||
rec.V1 = vOrigin + minBB.Y * TerrainAtlas2D.invElementSize;
|
||||
rec.V2 = vOrigin + maxBB.Y * TerrainAtlas2D.invElementSize;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + Y( minBB.Y ),
|
||||
pos.Z - z, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + Y( maxBB.Y ),
|
||||
pos.Z - z, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + Y( maxBB.Y ),
|
||||
pos.Z - z, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + Y( minBB.Y ),
|
||||
pos.Z - z, rec.U2, rec.V1, col );
|
||||
}
|
||||
|
||||
static float Y( float value ) {
|
||||
return (scale * value * 2) - scale;
|
||||
}
|
||||
|
||||
static void XQuad( byte block, float x, int side ) {
|
||||
int texId = info.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
FastColour col = colXSide;
|
||||
|
||||
float vOrigin = rec.V1;
|
||||
rec.V1 = vOrigin + minBB.Y * TerrainAtlas2D.invElementSize;
|
||||
rec.V2 = vOrigin + maxBB.Y * TerrainAtlas2D.invElementSize;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - x, pos.Y + Y( minBB.Y ),
|
||||
pos.Z - scale , rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - x, pos.Y + Y( maxBB.Y ),
|
||||
pos.Z - scale, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - x, pos.Y + Y( maxBB.Y ),
|
||||
pos.Z + scale, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - x, pos.Y + Y( minBB.Y ),
|
||||
pos.Z + scale, rec.U2, rec.V1, col );
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
@ -1,84 +0,0 @@
|
||||
#if ANDROID
|
||||
using System;
|
||||
using Android.Graphics;
|
||||
using Java.Nio;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public FastBitmap( int width, int height, int stride, IntPtr scan0 ) {
|
||||
Width = width;
|
||||
Height = height;
|
||||
Stride = stride;
|
||||
Scan0 = scan0;
|
||||
scan0Byte = (byte*)scan0;
|
||||
}
|
||||
|
||||
public Bitmap Bitmap;
|
||||
ByteBuffer data;
|
||||
byte* scan0Byte;
|
||||
|
||||
public bool IsLocked {
|
||||
get { return data != null; }
|
||||
}
|
||||
|
||||
public IntPtr Scan0;
|
||||
public int Stride;
|
||||
public int Width, Height;
|
||||
|
||||
public void LockBits() {
|
||||
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
|
||||
if( data != null ) return;
|
||||
|
||||
data = ByteBuffer.AllocateDirect( Bitmap.Width * Bitmap.Height * 4 );
|
||||
Bitmap.CopyPixelsToBuffer( data );
|
||||
scan0Byte = (byte*)data.GetDirectBufferAddress();
|
||||
Scan0 = data.GetDirectBufferAddress();
|
||||
Stride = Bitmap.Width * 4;
|
||||
Width = Bitmap.Width;
|
||||
Height = Bitmap.Height;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
UnlockBits();
|
||||
}
|
||||
|
||||
public void UnlockBits() {
|
||||
if( Bitmap != null && data != null ) {
|
||||
data.Rewind();
|
||||
Bitmap.CopyPixelsFromBuffer( data ); // TODO: Only if not readonly
|
||||
data.Dispose();
|
||||
|
||||
data = null;
|
||||
scan0Byte = (byte*)IntPtr.Zero;
|
||||
Scan0 = IntPtr.Zero;
|
||||
Width = Height = Stride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns a pointer to the start of the y'th scanline. </summary>
|
||||
public int* GetRowPtr( int y ) {
|
||||
return (int*)(scan0Byte + (y * Stride));
|
||||
}
|
||||
|
||||
public 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,221 +0,0 @@
|
||||
#if ANDROID
|
||||
using System;
|
||||
|
||||
namespace System.Drawing {
|
||||
|
||||
public struct Rectangle {
|
||||
|
||||
public static readonly Rectangle Empty = default(Rectangle);
|
||||
public int X, Y;
|
||||
public int Width, Height;
|
||||
|
||||
public Point Location {
|
||||
get { return new Point( X, Y ); }
|
||||
set { X = value.X; Y = value.Y; }
|
||||
}
|
||||
|
||||
public Size Size {
|
||||
get { return new Size( Width, Height ); }
|
||||
set { Width = value.Width; Height = value.Height; }
|
||||
}
|
||||
|
||||
public int Left {
|
||||
get { return X; }
|
||||
}
|
||||
|
||||
public int Top {
|
||||
get { return Y; }
|
||||
}
|
||||
|
||||
public int Right {
|
||||
get { return X + Width; }
|
||||
}
|
||||
|
||||
public int Bottom {
|
||||
get { return Y + Height; }
|
||||
}
|
||||
|
||||
public bool IsEmpty {
|
||||
get { return Height == 0 && Width == 0 && X == 0 && Y == 0; }
|
||||
}
|
||||
|
||||
public Rectangle( int x, int y, int width, int height ) {
|
||||
X = x; Y = y;
|
||||
Width = width; Height = height;
|
||||
}
|
||||
|
||||
public Rectangle( Point loc, Size size ) {
|
||||
X = loc.X; Y = loc.Y;
|
||||
Width = size.Width; Height = size.Height;
|
||||
}
|
||||
|
||||
public static Rectangle FromLTRB( int left, int top, int right, int bottom ) {
|
||||
return new Rectangle( left, top, right - left, bottom - top );
|
||||
}
|
||||
|
||||
public override bool Equals( object obj ) {
|
||||
return (obj is Rectangle) && Equals( (Rectangle)obj );
|
||||
}
|
||||
|
||||
public bool Equals( Rectangle other ) {
|
||||
return X == other.X && Y == other.Y && Width == other.Width && Height == other.Height;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return 1000000007 * X + 1000000009 * Y +
|
||||
1000000021 * Width + 1000000033 * Height;
|
||||
}
|
||||
|
||||
public static bool operator == ( Rectangle lhs, Rectangle rhs ) {
|
||||
return lhs.Equals( rhs );
|
||||
}
|
||||
|
||||
public static bool operator != ( Rectangle lhs, Rectangle rhs ) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public bool Contains(int x, int y) {
|
||||
return X <= x && x < X + Width && Y <= y && y < Y + Height;
|
||||
}
|
||||
|
||||
public bool Contains( Point pt ) {
|
||||
return Contains( pt.X, pt.Y );
|
||||
}
|
||||
|
||||
public bool Contains( Rectangle rect ) {
|
||||
return X <= rect.X && rect.X + rect.Width <= X + Width && Y <= rect.Y && rect.Y + rect.Height <= Y + Height;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return X + ", " + Y + " : " + Width + "," + Height;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Size {
|
||||
|
||||
public static readonly Size Empty = default(Size);
|
||||
public int Width, Height;
|
||||
|
||||
public bool IsEmpty {
|
||||
get { return Width == 0 && Height == 0; }
|
||||
}
|
||||
|
||||
public Size( Point point ) {
|
||||
Width = point.X; Height = point.Y;
|
||||
}
|
||||
|
||||
public Size( int width, int height ) {
|
||||
Width = width; Height = height;
|
||||
}
|
||||
|
||||
public static Size Ceiling( SizeF value ) {
|
||||
return new Size( (int)Math.Ceiling( value.Width ), (int)Math.Ceiling( value.Height ) );
|
||||
}
|
||||
|
||||
public override bool Equals( object obj ) {
|
||||
return (obj is Size) && Equals( (Size)obj );
|
||||
}
|
||||
|
||||
public bool Equals( Size other ) {
|
||||
return Width == other.Width && Height == other.Height;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return 1000000007 * Width + 1000000009 * Height;
|
||||
}
|
||||
|
||||
public static bool operator == ( Size lhs, Size rhs ) {
|
||||
return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
|
||||
}
|
||||
|
||||
public static bool operator != ( Size lhs, Size rhs ) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Width + "," + Height;
|
||||
}
|
||||
}
|
||||
|
||||
public struct SizeF {
|
||||
|
||||
public static readonly SizeF Empty = default(SizeF);
|
||||
public float Width, Height;
|
||||
|
||||
public bool IsEmpty {
|
||||
get { return Width == 0 && Height == 0; }
|
||||
}
|
||||
|
||||
public SizeF( float width, float height ) {
|
||||
Width = width; Height = height;
|
||||
}
|
||||
|
||||
public override bool Equals( object obj ) {
|
||||
return (obj is SizeF) && Equals( (SizeF)obj );
|
||||
}
|
||||
|
||||
public bool Equals( SizeF other ) {
|
||||
return Width == other.Width && Height == other.Height;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return 1000000007 * Width.GetHashCode() +
|
||||
1000000009 * Height.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator == ( SizeF lhs, SizeF rhs ) {
|
||||
return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
|
||||
}
|
||||
|
||||
public static bool operator != ( SizeF lhs, SizeF rhs ) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Width + "," + Height;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Point {
|
||||
|
||||
public static readonly Point Empty = default(Point);
|
||||
public int X, Y;
|
||||
|
||||
public bool IsEmpty {
|
||||
get { return X == 0 && Y == 0; }
|
||||
}
|
||||
|
||||
public Point( Size size ) {
|
||||
X = size.Width; Y = size.Height;
|
||||
}
|
||||
|
||||
public Point( int x, int y ) {
|
||||
X = x; Y = y;
|
||||
}
|
||||
|
||||
public override bool Equals( object obj ) {
|
||||
return (obj is Point) && Equals( (Point)obj );
|
||||
}
|
||||
|
||||
public bool Equals( Point other ) {
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return 1000000007 * X + 1000000009 * Y;
|
||||
}
|
||||
|
||||
public static bool operator == ( Point lhs, Point rhs ) {
|
||||
return lhs.X == rhs.X && lhs.Y == rhs.Y;
|
||||
}
|
||||
|
||||
public static bool operator != ( Point lhs, Point rhs ) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return X + "," + Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -78,6 +78,8 @@
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="2D\Drawing\CanvasDrawer2D.cs" />
|
||||
<Compile Include="2D\Drawing\CanvasDrawer2D.Text.cs" />
|
||||
<Compile Include="2D\Drawing\GdiPlusDrawer2D.Text.cs" />
|
||||
<Compile Include="2D\Drawing\IDrawer2D.TextMC.cs" />
|
||||
<Compile Include="2D\GuiElement.cs" />
|
||||
@ -130,12 +132,6 @@
|
||||
<Compile Include="2D\Widgets\PlayerListWidget.cs" />
|
||||
<Compile Include="2D\Widgets\TextWidget.cs" />
|
||||
<Compile Include="2D\Widgets\Widget.cs" />
|
||||
<Compile Include="Android\CanvasDrawer2D.cs" />
|
||||
<Compile Include="Android\CanvasDrawer2D.Text.cs" />
|
||||
<Compile Include="Android\FastBitmap.cs" />
|
||||
<Compile Include="Android\Font.cs" />
|
||||
<Compile Include="Android\Minimal.cs" />
|
||||
<Compile Include="Android\OpenGLESApi.cs" />
|
||||
<Compile Include="Audio\AudioPlayer.cs" />
|
||||
<Compile Include="Audio\AudioPlayer.Sounds.cs" />
|
||||
<Compile Include="Audio\Soundboard.cs" />
|
||||
@ -161,6 +157,7 @@
|
||||
<Compile Include="Generator\Noise.cs" />
|
||||
<Compile Include="Generator\NotchyGenerator.cs" />
|
||||
<Compile Include="Generator\NotchyGenerator.Utils.cs" />
|
||||
<Compile Include="GraphicsAPI\OpenGLESApi.cs" />
|
||||
<Compile Include="Particles\CollidableParticle.cs" />
|
||||
<Compile Include="Particles\Particle.cs" />
|
||||
<Compile Include="Particles\ParticleManager.cs" />
|
||||
@ -225,6 +222,8 @@
|
||||
<Compile Include="Physics\IntersectionUtils.cs" />
|
||||
<Compile Include="Physics\PickedPos.cs" />
|
||||
<Compile Include="Physics\Picking.cs" />
|
||||
<Compile Include="Platform\Font.cs" />
|
||||
<Compile Include="Platform\Platform.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Rendering\BlockHandRenderer.cs" />
|
||||
@ -286,7 +285,7 @@
|
||||
<Folder Include="Blocks" />
|
||||
<Folder Include="Events" />
|
||||
<Folder Include="Generator" />
|
||||
<Folder Include="Android" />
|
||||
<Folder Include="Platform" />
|
||||
<Folder Include="Particles" />
|
||||
<Folder Include="GraphicsAPI" />
|
||||
<Folder Include="Entities" />
|
||||
|
@ -3,6 +3,9 @@ using System.Drawing;
|
||||
using ClassicalSharp.Model;
|
||||
using ClassicalSharp.Network;
|
||||
using OpenTK;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
@ -15,6 +15,9 @@ using ClassicalSharp.TexturePack;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
@ -279,7 +282,7 @@ namespace ClassicalSharp {
|
||||
string timestamp = DateTime.Now.ToString( "dd-MM-yyyy-HH-mm-ss" );
|
||||
string file = "screenshot_" + timestamp + ".png";
|
||||
path = Path.Combine( "screenshots", file );
|
||||
Graphics.TakeScreenshot( path, ClientSize );
|
||||
Graphics.TakeScreenshot( path, ClientSize.Width, ClientSize.Height );
|
||||
Chat.Add( "&eTaken screenshot as: " + file );
|
||||
screenshotRequested = false;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#if USE_DX
|
||||
#if USE_DX && !ANDROID
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
@ -562,14 +562,14 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
};
|
||||
}
|
||||
|
||||
public override void TakeScreenshot( string output, Size size ) {
|
||||
public override void TakeScreenshot( string output, int width, int height ) {
|
||||
using( Surface backbuffer = device.GetBackBuffer( 0, 0, BackBufferType.Mono ),
|
||||
tempSurface = device.CreateOffscreenPlainSurface( size.Width, size.Height, Format.X8R8G8B8, Pool.SystemMemory ) ) {
|
||||
tempSurface = device.CreateOffscreenPlainSurface( width, height, Format.X8R8G8B8, Pool.SystemMemory ) ) {
|
||||
// For DX 8 use IDirect3DDevice8::CreateImageSurface
|
||||
device.GetRenderTargetData( backbuffer, tempSurface );
|
||||
LockedRectangle rect = tempSurface.LockRectangle( LockFlags.ReadOnly | LockFlags.NoDirtyUpdate );
|
||||
|
||||
using( Bitmap bmp = new Bitmap( size.Width, size.Height, size.Width * 4,
|
||||
using( Bitmap bmp = new Bitmap( width, height, width * sizeof(int),
|
||||
PixelFormat.Format32bppRgb, rect.DataPointer ) ) {
|
||||
bmp.Save( output, ImageFormat.Png );
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
public abstract void PopMatrix();
|
||||
|
||||
/// <summary> Outputs a .png screenshot of the backbuffer to the specified file. </summary>
|
||||
public abstract void TakeScreenshot( string output, Size size );
|
||||
public abstract void TakeScreenshot( string output, int width, int height );
|
||||
|
||||
protected abstract void MakeApiInfo();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#if !USE_DX
|
||||
#if !USE_DX && !ANDROID
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
@ -405,11 +405,10 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
}
|
||||
|
||||
// Based on http://www.opentk.com/doc/graphics/save-opengl-rendering-to-disk
|
||||
public override void TakeScreenshot( string output, Size size ) {
|
||||
using( Bitmap bmp = new Bitmap( size.Width, size.Height, BmpPixelFormat.Format32bppRgb ) ) { // ignore alpha component
|
||||
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
|
||||
GL.ReadPixels( 0, 0, size.Width, size.Height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0 );
|
||||
}
|
||||
public override void TakeScreenshot( string output, int width, int height ) {
|
||||
using( Bitmap bmp = new Bitmap( width, height, BmpPixelFormat.Format32bppRgb ) ) { // ignore alpha component
|
||||
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) )
|
||||
GL.ReadPixels( 0, 0, width, height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0 );
|
||||
bmp.RotateFlip( RotateFlipType.RotateNoneFlipY );
|
||||
bmp.Save( output, ImageFormat.Png );
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
public unsafe class OpenGLESApi : IGraphicsApi {
|
||||
|
||||
All[] modeMappings;
|
||||
public OpenGLApi() {
|
||||
public OpenGLESApi() {
|
||||
InitFields();
|
||||
int texDims;
|
||||
GL.GetInteger( All.MaxTextureSize, &texDims );
|
@ -196,7 +196,7 @@ namespace ClassicalSharp.Network {
|
||||
object DownloadContent( Request request, HttpWebResponse response ) {
|
||||
if( request.Type == RequestType.Bitmap ) {
|
||||
MemoryStream data = DownloadBytes( response );
|
||||
return new Bitmap( data );
|
||||
return Platform.ReadBmp( data );
|
||||
} else if( request.Type == RequestType.String ) {
|
||||
MemoryStream data = DownloadBytes( response );
|
||||
byte[] rawBuffer = data.GetBuffer();
|
||||
|
38
ClassicalSharp/Platform/Platform.cs
Normal file
38
ClassicalSharp/Platform/Platform.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#else
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
public static class Platform {
|
||||
|
||||
public static Bitmap CreateBmp( int width, int height ) {
|
||||
#if !ANDROID
|
||||
return new Bitmap( width, height );
|
||||
#else
|
||||
return Bitmap.CreateBitmap( width, height, Bitmap.Config.Argb8888 );
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Bitmap ReadBmp( Stream src ) {
|
||||
#if !ANDROID
|
||||
return new Bitmap( src );
|
||||
#else
|
||||
return BitmapFactory.DecodeStream( src );
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void WriteBmp( Bitmap bmp, Stream dst ) {
|
||||
#if !ANDROID
|
||||
bmp.Save( dst, ImageFormat.Png );
|
||||
#else
|
||||
bmp.Compress( Bitmap.CompressFormat.Png, 100, dst );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp.TexturePack {
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
@ -3,6 +3,9 @@ using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp.TexturePack {
|
||||
|
||||
@ -63,7 +66,8 @@ namespace ClassicalSharp.TexturePack {
|
||||
if( !Directory.Exists( basePath ) )
|
||||
Directory.CreateDirectory( basePath );
|
||||
|
||||
bmp.Save( path, ImageFormat.Png );
|
||||
using( FileStream fs = File.Create( path ) )
|
||||
Platform.WriteBmp( bmp, fs );
|
||||
} catch( IOException ex ) {
|
||||
ErrorHandler.LogError( "Cache.AddToCache", ex );
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace ClassicalSharp.TexturePack {
|
||||
IGraphicsApi api = game.Graphics;
|
||||
switch( filename ) {
|
||||
case "terrain.png":
|
||||
game.ChangeTerrainAtlas( new Bitmap( stream ) ); break;
|
||||
game.ChangeTerrainAtlas( Platform.ReadBmp( stream ) ); break;
|
||||
case "mob/chicken.png":
|
||||
case "chicken.png":
|
||||
UpdateTexture( ref cache.ChickenTexId, stream, false ); break;
|
||||
@ -79,7 +79,7 @@ namespace ClassicalSharp.TexturePack {
|
||||
UpdateTexture( ref game.GuiClassicTexId, stream, false ); break;
|
||||
case "animations.png":
|
||||
case "animation.png":
|
||||
game.Animations.SetAtlas( new Bitmap( stream ) ); break;
|
||||
game.Animations.SetAtlas( Platform.ReadBmp( stream ) ); break;
|
||||
case "animations.txt":
|
||||
case "animation.txt":
|
||||
StreamReader reader = new StreamReader( stream );
|
||||
@ -95,14 +95,14 @@ namespace ClassicalSharp.TexturePack {
|
||||
}
|
||||
|
||||
void SetFontBitmap( Game game, Stream stream ) {
|
||||
Bitmap bmp = new Bitmap( stream );
|
||||
Bitmap bmp = Platform.ReadBmp( stream );
|
||||
game.Drawer2D.SetFontBitmap( bmp );
|
||||
game.Events.RaiseChatFontChanged();
|
||||
}
|
||||
|
||||
void UpdateTexture( ref int texId, Stream stream, bool setSkinType ) {
|
||||
game.Graphics.DeleteTexture( ref texId );
|
||||
using( Bitmap bmp = new Bitmap( stream ) ) {
|
||||
using( Bitmap bmp = Platform.ReadBmp( stream ) ) {
|
||||
if( setSkinType )
|
||||
game.DefaultPlayerSkinType = Utils.GetSkinType( bmp );
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
using System.Drawing;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
#if ANDROID
|
||||
using Android.Graphics;
|
||||
#endif
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user