mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Client now rescales non-power of two skins, fixes crashing and closes #177. (Thanks MarsBarsFood)
This commit is contained in:
parent
2bb67cd2f1
commit
544f80a2f5
@ -67,6 +67,12 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyRow( int srcY, int dstY, FastBitmap src, FastBitmap dst, int width ) {
|
||||
int* srcRow = src.GetRowPtr( srcY ), dstRow = dst.GetRowPtr( dstY);
|
||||
for( int x = 0; x < width; x++ )
|
||||
dstRow[x] = srcRow[x];
|
||||
}
|
||||
|
||||
public void Dispose() { UnlockBits(); }
|
||||
|
||||
#if !ANDROID
|
||||
|
@ -17,6 +17,7 @@ namespace ClassicalSharp.Entities {
|
||||
public SkinType SkinType;
|
||||
internal AnimatedComponent anim;
|
||||
internal ShadowComponent shadow;
|
||||
internal float uScale = 1, vScale = 1;
|
||||
|
||||
public Player( Game game ) : base( game ) {
|
||||
this.game = game;
|
||||
@ -81,6 +82,8 @@ namespace ClassicalSharp.Entities {
|
||||
game.Graphics.DeleteTexture( ref TextureId );
|
||||
if( !FastBitmap.CheckFormat( bmp.PixelFormat ) )
|
||||
game.Drawer2D.ConvertTo32Bpp( ref bmp );
|
||||
uScale = 1; vScale = 1;
|
||||
EnsurePow2( ref bmp );
|
||||
|
||||
try {
|
||||
SkinType = Utils.GetSkinType( bmp );
|
||||
@ -91,7 +94,7 @@ namespace ClassicalSharp.Entities {
|
||||
|
||||
// Custom mob textures.
|
||||
if( Utils.IsUrlPrefix( SkinName, 0 ) && item.TimeAdded > lastModelChange )
|
||||
MobTextureId = TextureId;
|
||||
MobTextureId = TextureId;
|
||||
} catch( NotSupportedException ) {
|
||||
ResetSkin( bmp );
|
||||
}
|
||||
@ -136,5 +139,24 @@ namespace ClassicalSharp.Entities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnsurePow2( ref Bitmap bmp ) {
|
||||
int width = Utils.NextPowerOf2( bmp.Width );
|
||||
int height = Utils.NextPowerOf2( bmp.Height );
|
||||
if( width == bmp.Width && height == bmp.Height ) return;
|
||||
|
||||
Bitmap scaled = Platform.CreateBmp( width, height );
|
||||
using( FastBitmap src = new FastBitmap( bmp, true, true ) )
|
||||
using( FastBitmap dst = new FastBitmap( scaled, true, false ) )
|
||||
{
|
||||
for( int y = 0; y < src.Height; y++ )
|
||||
FastBitmap.CopyRow( y, y, src, dst, src.Width );
|
||||
}
|
||||
|
||||
uScale = (float)bmp.Width / width;
|
||||
vScale = (float)bmp.Height / height;
|
||||
bmp.Dispose();
|
||||
bmp = scaled;
|
||||
}
|
||||
}
|
||||
}
|
@ -90,9 +90,12 @@ namespace ClassicalSharp.Model {
|
||||
graphics.AlphaTest = false;
|
||||
|
||||
SkinType skinType = p.SkinType;
|
||||
_64x64 = skinType != SkinType.Type64x32;
|
||||
bool _64x64 = skinType != SkinType.Type64x32;
|
||||
uScale = p.uScale / 64f;
|
||||
vScale = p.vScale / (_64x64 ? 64 : 32);
|
||||
ModelSet model = skinType == SkinType.Type64x64Slim ? SetSlim :
|
||||
(skinType == SkinType.Type64x64 ? Set64 : Set);
|
||||
|
||||
DrawHeadRotate( -p.PitchRadians, 0, 0, model.Head );
|
||||
DrawPart( model.Torso );
|
||||
|
||||
|
@ -47,15 +47,16 @@ namespace ClassicalSharp.Model {
|
||||
|
||||
protected Vector3 pos;
|
||||
protected float cosYaw, sinYaw, cosHead, sinHead;
|
||||
protected float uScale, vScale;
|
||||
|
||||
/// <summary> Renders the model based on the given entity's position and orientation. </summary>
|
||||
public void Render( Player p ) {
|
||||
index = 0;
|
||||
pos = p.Position;
|
||||
if( Bobbing )
|
||||
pos.Y += p.anim.bobYOffset;
|
||||
if( Bobbing ) pos.Y += p.anim.bobYOffset;
|
||||
World map = game.World;
|
||||
col = game.World.IsLit( Vector3I.Floor( p.EyePosition ) ) ? map.Sunlight : map.Shadowlight;
|
||||
uScale = 1 / 64f; vScale = 1 / 32f;
|
||||
|
||||
cols[0] = col;
|
||||
cols[1] = FastColour.Scale( col, FastColour.ShadeYBottom );
|
||||
@ -96,9 +97,7 @@ namespace ClassicalSharp.Model {
|
||||
return ModelBuilder.BuildRotatedBox( this, desc );
|
||||
}
|
||||
|
||||
protected bool _64x64 = false;
|
||||
protected void DrawPart( ModelPart part ) {
|
||||
float vScale = _64x64 ? 64f : 32f;
|
||||
for( int i = 0; i < part.Count; i++ ) {
|
||||
ModelVertex v = vertices[part.Offset + i];
|
||||
float t = cosYaw * v.X - sinYaw * v.Z; v.Z = sinYaw * v.X + cosYaw * v.Z; v.X = t; // Inlined RotY
|
||||
@ -110,10 +109,10 @@ namespace ClassicalSharp.Model {
|
||||
vertex.X = v.X; vertex.Y = v.Y; vertex.Z = v.Z;
|
||||
vertex.R = col.R; vertex.G = col.G; vertex.B = col.B; vertex.A = 255;
|
||||
|
||||
vertex.U = v.U / 64f; vertex.V = v.V / vScale;
|
||||
vertex.U = v.U * uScale; vertex.V = v.V * vScale;
|
||||
int quadI = i % 4;
|
||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f / vScale;
|
||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f / 64f;
|
||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f * vScale;
|
||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f * uScale;
|
||||
cache.vertices[index++] = vertex;
|
||||
}
|
||||
}
|
||||
@ -131,7 +130,6 @@ namespace ClassicalSharp.Model {
|
||||
float cosX = (float)Math.Cos( -angleX ), sinX = (float)Math.Sin( -angleX );
|
||||
float cosY = (float)Math.Cos( -angleY ), sinY = (float)Math.Sin( -angleY );
|
||||
float cosZ = (float)Math.Cos( -angleZ ), sinZ = (float)Math.Sin( -angleZ );
|
||||
float vScale = _64x64 ? 64f : 32f;
|
||||
|
||||
for( int i = 0; i < part.Count; i++ ) {
|
||||
ModelVertex v = vertices[part.Offset + i];
|
||||
@ -167,10 +165,10 @@ namespace ClassicalSharp.Model {
|
||||
vertex.X = v.X; vertex.Y = v.Y; vertex.Z = v.Z;
|
||||
vertex.R = col.R; vertex.G = col.G; vertex.B = col.B; vertex.A = 255;
|
||||
|
||||
vertex.U = v.U / 64f; vertex.V = v.V / vScale;
|
||||
vertex.U = v.U * uScale; vertex.V = v.V * vScale;
|
||||
int quadI = i % 4;
|
||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f / vScale;
|
||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f / 64f;
|
||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f * vScale;
|
||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f * vScale;
|
||||
cache.vertices[index++] = vertex;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user