mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -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 ClassicalSharp.GraphicsAPI;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using Android.Graphics.Drawables;
|
using Android.Graphics.Drawables;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ namespace ClassicalSharp {
|
|||||||
Bitmap measuringBmp;
|
Bitmap measuringBmp;
|
||||||
Canvas measuringC;
|
Canvas measuringC;
|
||||||
|
|
||||||
public GdiPlusDrawer2D( IGraphicsApi graphics ) {
|
public CanvasDrawer2D( IGraphicsApi graphics ) {
|
||||||
this.graphics = graphics;
|
this.graphics = graphics;
|
||||||
measuringBmp = Bitmap.CreateBitmap( 1, 1, Bitmap.Config.Argb8888 );
|
measuringBmp = Bitmap.CreateBitmap( 1, 1, Bitmap.Config.Argb8888 );
|
||||||
measuringC = new Canvas( measuringBmp );
|
measuringC = new Canvas( measuringBmp );
|
@ -21,6 +21,8 @@ namespace ClassicalSharp {
|
|||||||
c = new Canvas( bmp );
|
c = new Canvas( bmp );
|
||||||
curBmp = 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 ) {
|
public override void DrawRect( FastColour colour, int x, int y, int width, int height ) {
|
||||||
RectF rec = new RectF( x, y, x + width, y + 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;
|
||||||
using System.Drawing.Text;
|
using System.Drawing.Text;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
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.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
@ -102,3 +103,4 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
@ -1,6 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
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>
|
/// <summary> Creates a power-of-2 sized bitmap larger or equal to to the given size. </summary>
|
||||||
public static Bitmap CreatePow2Bitmap( Size size ) {
|
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 );
|
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;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
using Java.Nio;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
@ -38,6 +42,24 @@ namespace ClassicalSharp {
|
|||||||
return format == PixelFormat.Format32bppRgb || format == PixelFormat.Format32bppArgb;
|
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() {
|
public void LockBits() {
|
||||||
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
|
if( Bitmap == null ) throw new InvalidOperationException( "Underlying bitmap is null." );
|
||||||
if( data != null ) return;
|
if( data != null ) return;
|
||||||
@ -55,33 +77,43 @@ namespace ClassicalSharp {
|
|||||||
Height = data.Height;
|
Height = data.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void UnlockBits() {
|
||||||
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() {
|
public void UnlockBits() {
|
||||||
if( Bitmap != null && data != null ) {
|
if( Bitmap == null || data == null )
|
||||||
Bitmap.UnlockBits( data );
|
return;
|
||||||
data = null;
|
data.Rewind();
|
||||||
scan0Byte = (byte*)IntPtr.Zero;
|
Bitmap.CopyPixelsFromBuffer( data ); // TODO: Only if not readonly
|
||||||
Scan0 = IntPtr.Zero;
|
data.Dispose();
|
||||||
Width = Height = Stride = 0;
|
|
||||||
}
|
data = null;
|
||||||
}
|
scan0Byte = (byte*)IntPtr.Zero;
|
||||||
|
Scan0 = IntPtr.Zero;
|
||||||
/// <summary> Returns a pointer to the start of the y'th scanline. </summary>
|
Width = Height = Stride = 0;
|
||||||
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,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;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
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" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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\GdiPlusDrawer2D.Text.cs" />
|
||||||
<Compile Include="2D\Drawing\IDrawer2D.TextMC.cs" />
|
<Compile Include="2D\Drawing\IDrawer2D.TextMC.cs" />
|
||||||
<Compile Include="2D\GuiElement.cs" />
|
<Compile Include="2D\GuiElement.cs" />
|
||||||
@ -130,12 +132,6 @@
|
|||||||
<Compile Include="2D\Widgets\PlayerListWidget.cs" />
|
<Compile Include="2D\Widgets\PlayerListWidget.cs" />
|
||||||
<Compile Include="2D\Widgets\TextWidget.cs" />
|
<Compile Include="2D\Widgets\TextWidget.cs" />
|
||||||
<Compile Include="2D\Widgets\Widget.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.cs" />
|
||||||
<Compile Include="Audio\AudioPlayer.Sounds.cs" />
|
<Compile Include="Audio\AudioPlayer.Sounds.cs" />
|
||||||
<Compile Include="Audio\Soundboard.cs" />
|
<Compile Include="Audio\Soundboard.cs" />
|
||||||
@ -161,6 +157,7 @@
|
|||||||
<Compile Include="Generator\Noise.cs" />
|
<Compile Include="Generator\Noise.cs" />
|
||||||
<Compile Include="Generator\NotchyGenerator.cs" />
|
<Compile Include="Generator\NotchyGenerator.cs" />
|
||||||
<Compile Include="Generator\NotchyGenerator.Utils.cs" />
|
<Compile Include="Generator\NotchyGenerator.Utils.cs" />
|
||||||
|
<Compile Include="GraphicsAPI\OpenGLESApi.cs" />
|
||||||
<Compile Include="Particles\CollidableParticle.cs" />
|
<Compile Include="Particles\CollidableParticle.cs" />
|
||||||
<Compile Include="Particles\Particle.cs" />
|
<Compile Include="Particles\Particle.cs" />
|
||||||
<Compile Include="Particles\ParticleManager.cs" />
|
<Compile Include="Particles\ParticleManager.cs" />
|
||||||
@ -225,6 +222,8 @@
|
|||||||
<Compile Include="Physics\IntersectionUtils.cs" />
|
<Compile Include="Physics\IntersectionUtils.cs" />
|
||||||
<Compile Include="Physics\PickedPos.cs" />
|
<Compile Include="Physics\PickedPos.cs" />
|
||||||
<Compile Include="Physics\Picking.cs" />
|
<Compile Include="Physics\Picking.cs" />
|
||||||
|
<Compile Include="Platform\Font.cs" />
|
||||||
|
<Compile Include="Platform\Platform.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Rendering\BlockHandRenderer.cs" />
|
<Compile Include="Rendering\BlockHandRenderer.cs" />
|
||||||
@ -286,7 +285,7 @@
|
|||||||
<Folder Include="Blocks" />
|
<Folder Include="Blocks" />
|
||||||
<Folder Include="Events" />
|
<Folder Include="Events" />
|
||||||
<Folder Include="Generator" />
|
<Folder Include="Generator" />
|
||||||
<Folder Include="Android" />
|
<Folder Include="Platform" />
|
||||||
<Folder Include="Particles" />
|
<Folder Include="Particles" />
|
||||||
<Folder Include="GraphicsAPI" />
|
<Folder Include="GraphicsAPI" />
|
||||||
<Folder Include="Entities" />
|
<Folder Include="Entities" />
|
||||||
|
@ -3,6 +3,9 @@ using System.Drawing;
|
|||||||
using ClassicalSharp.Model;
|
using ClassicalSharp.Model;
|
||||||
using ClassicalSharp.Network;
|
using ClassicalSharp.Network;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ using ClassicalSharp.TexturePack;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
@ -279,7 +282,7 @@ namespace ClassicalSharp {
|
|||||||
string timestamp = DateTime.Now.ToString( "dd-MM-yyyy-HH-mm-ss" );
|
string timestamp = DateTime.Now.ToString( "dd-MM-yyyy-HH-mm-ss" );
|
||||||
string file = "screenshot_" + timestamp + ".png";
|
string file = "screenshot_" + timestamp + ".png";
|
||||||
path = Path.Combine( "screenshots", file );
|
path = Path.Combine( "screenshots", file );
|
||||||
Graphics.TakeScreenshot( path, ClientSize );
|
Graphics.TakeScreenshot( path, ClientSize.Width, ClientSize.Height );
|
||||||
Chat.Add( "&eTaken screenshot as: " + file );
|
Chat.Add( "&eTaken screenshot as: " + file );
|
||||||
screenshotRequested = false;
|
screenshotRequested = false;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#if USE_DX
|
#if USE_DX && !ANDROID
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
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 ),
|
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
|
// For DX 8 use IDirect3DDevice8::CreateImageSurface
|
||||||
device.GetRenderTargetData( backbuffer, tempSurface );
|
device.GetRenderTargetData( backbuffer, tempSurface );
|
||||||
LockedRectangle rect = tempSurface.LockRectangle( LockFlags.ReadOnly | LockFlags.NoDirtyUpdate );
|
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 ) ) {
|
PixelFormat.Format32bppRgb, rect.DataPointer ) ) {
|
||||||
bmp.Save( output, ImageFormat.Png );
|
bmp.Save( output, ImageFormat.Png );
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
public abstract void PopMatrix();
|
public abstract void PopMatrix();
|
||||||
|
|
||||||
/// <summary> Outputs a .png screenshot of the backbuffer to the specified file. </summary>
|
/// <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();
|
protected abstract void MakeApiInfo();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#if !USE_DX
|
#if !USE_DX && !ANDROID
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
@ -405,11 +405,10 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Based on http://www.opentk.com/doc/graphics/save-opengl-rendering-to-disk
|
// Based on http://www.opentk.com/doc/graphics/save-opengl-rendering-to-disk
|
||||||
public override void TakeScreenshot( string output, Size size ) {
|
public override void TakeScreenshot( string output, int width, int height ) {
|
||||||
using( Bitmap bmp = new Bitmap( size.Width, size.Height, BmpPixelFormat.Format32bppRgb ) ) { // ignore alpha component
|
using( Bitmap bmp = new Bitmap( width, height, BmpPixelFormat.Format32bppRgb ) ) { // ignore alpha component
|
||||||
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
|
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) )
|
||||||
GL.ReadPixels( 0, 0, size.Width, size.Height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0 );
|
GL.ReadPixels( 0, 0, width, height, GlPixelFormat.Bgra, PixelType.UnsignedByte, fastBmp.Scan0 );
|
||||||
}
|
|
||||||
bmp.RotateFlip( RotateFlipType.RotateNoneFlipY );
|
bmp.RotateFlip( RotateFlipType.RotateNoneFlipY );
|
||||||
bmp.Save( output, ImageFormat.Png );
|
bmp.Save( output, ImageFormat.Png );
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
public unsafe class OpenGLESApi : IGraphicsApi {
|
public unsafe class OpenGLESApi : IGraphicsApi {
|
||||||
|
|
||||||
All[] modeMappings;
|
All[] modeMappings;
|
||||||
public OpenGLApi() {
|
public OpenGLESApi() {
|
||||||
InitFields();
|
InitFields();
|
||||||
int texDims;
|
int texDims;
|
||||||
GL.GetInteger( All.MaxTextureSize, &texDims );
|
GL.GetInteger( All.MaxTextureSize, &texDims );
|
@ -196,7 +196,7 @@ namespace ClassicalSharp.Network {
|
|||||||
object DownloadContent( Request request, HttpWebResponse response ) {
|
object DownloadContent( Request request, HttpWebResponse response ) {
|
||||||
if( request.Type == RequestType.Bitmap ) {
|
if( request.Type == RequestType.Bitmap ) {
|
||||||
MemoryStream data = DownloadBytes( response );
|
MemoryStream data = DownloadBytes( response );
|
||||||
return new Bitmap( data );
|
return Platform.ReadBmp( data );
|
||||||
} else if( request.Type == RequestType.String ) {
|
} else if( request.Type == RequestType.String ) {
|
||||||
MemoryStream data = DownloadBytes( response );
|
MemoryStream data = DownloadBytes( response );
|
||||||
byte[] rawBuffer = data.GetBuffer();
|
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.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp.TexturePack {
|
namespace ClassicalSharp.TexturePack {
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using ClassicalSharp.GraphicsAPI;
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ using System.Drawing;
|
|||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp.TexturePack {
|
namespace ClassicalSharp.TexturePack {
|
||||||
|
|
||||||
@ -63,7 +66,8 @@ namespace ClassicalSharp.TexturePack {
|
|||||||
if( !Directory.Exists( basePath ) )
|
if( !Directory.Exists( basePath ) )
|
||||||
Directory.CreateDirectory( basePath );
|
Directory.CreateDirectory( basePath );
|
||||||
|
|
||||||
bmp.Save( path, ImageFormat.Png );
|
using( FileStream fs = File.Create( path ) )
|
||||||
|
Platform.WriteBmp( bmp, fs );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ErrorHandler.LogError( "Cache.AddToCache", ex );
|
ErrorHandler.LogError( "Cache.AddToCache", ex );
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace ClassicalSharp.TexturePack {
|
|||||||
IGraphicsApi api = game.Graphics;
|
IGraphicsApi api = game.Graphics;
|
||||||
switch( filename ) {
|
switch( filename ) {
|
||||||
case "terrain.png":
|
case "terrain.png":
|
||||||
game.ChangeTerrainAtlas( new Bitmap( stream ) ); break;
|
game.ChangeTerrainAtlas( Platform.ReadBmp( stream ) ); break;
|
||||||
case "mob/chicken.png":
|
case "mob/chicken.png":
|
||||||
case "chicken.png":
|
case "chicken.png":
|
||||||
UpdateTexture( ref cache.ChickenTexId, stream, false ); break;
|
UpdateTexture( ref cache.ChickenTexId, stream, false ); break;
|
||||||
@ -79,7 +79,7 @@ namespace ClassicalSharp.TexturePack {
|
|||||||
UpdateTexture( ref game.GuiClassicTexId, stream, false ); break;
|
UpdateTexture( ref game.GuiClassicTexId, stream, false ); break;
|
||||||
case "animations.png":
|
case "animations.png":
|
||||||
case "animation.png":
|
case "animation.png":
|
||||||
game.Animations.SetAtlas( new Bitmap( stream ) ); break;
|
game.Animations.SetAtlas( Platform.ReadBmp( stream ) ); break;
|
||||||
case "animations.txt":
|
case "animations.txt":
|
||||||
case "animation.txt":
|
case "animation.txt":
|
||||||
StreamReader reader = new StreamReader( stream );
|
StreamReader reader = new StreamReader( stream );
|
||||||
@ -95,14 +95,14 @@ namespace ClassicalSharp.TexturePack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetFontBitmap( Game game, Stream stream ) {
|
void SetFontBitmap( Game game, Stream stream ) {
|
||||||
Bitmap bmp = new Bitmap( stream );
|
Bitmap bmp = Platform.ReadBmp( stream );
|
||||||
game.Drawer2D.SetFontBitmap( bmp );
|
game.Drawer2D.SetFontBitmap( bmp );
|
||||||
game.Events.RaiseChatFontChanged();
|
game.Events.RaiseChatFontChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTexture( ref int texId, Stream stream, bool setSkinType ) {
|
void UpdateTexture( ref int texId, Stream stream, bool setSkinType ) {
|
||||||
game.Graphics.DeleteTexture( ref texId );
|
game.Graphics.DeleteTexture( ref texId );
|
||||||
using( Bitmap bmp = new Bitmap( stream ) ) {
|
using( Bitmap bmp = Platform.ReadBmp( stream ) ) {
|
||||||
if( setSkinType )
|
if( setSkinType )
|
||||||
game.DefaultPlayerSkinType = Utils.GetSkinType( bmp );
|
game.DefaultPlayerSkinType = Utils.GetSkinType( bmp );
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user