mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -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(); }
|
public void Dispose() { UnlockBits(); }
|
||||||
|
|
||||||
#if !ANDROID
|
#if !ANDROID
|
||||||
|
@ -17,6 +17,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
public SkinType SkinType;
|
public SkinType SkinType;
|
||||||
internal AnimatedComponent anim;
|
internal AnimatedComponent anim;
|
||||||
internal ShadowComponent shadow;
|
internal ShadowComponent shadow;
|
||||||
|
internal float uScale = 1, vScale = 1;
|
||||||
|
|
||||||
public Player( Game game ) : base( game ) {
|
public Player( Game game ) : base( game ) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
@ -81,6 +82,8 @@ namespace ClassicalSharp.Entities {
|
|||||||
game.Graphics.DeleteTexture( ref TextureId );
|
game.Graphics.DeleteTexture( ref TextureId );
|
||||||
if( !FastBitmap.CheckFormat( bmp.PixelFormat ) )
|
if( !FastBitmap.CheckFormat( bmp.PixelFormat ) )
|
||||||
game.Drawer2D.ConvertTo32Bpp( ref bmp );
|
game.Drawer2D.ConvertTo32Bpp( ref bmp );
|
||||||
|
uScale = 1; vScale = 1;
|
||||||
|
EnsurePow2( ref bmp );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SkinType = Utils.GetSkinType( bmp );
|
SkinType = Utils.GetSkinType( 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;
|
graphics.AlphaTest = false;
|
||||||
|
|
||||||
SkinType skinType = p.SkinType;
|
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 :
|
ModelSet model = skinType == SkinType.Type64x64Slim ? SetSlim :
|
||||||
(skinType == SkinType.Type64x64 ? Set64 : Set);
|
(skinType == SkinType.Type64x64 ? Set64 : Set);
|
||||||
|
|
||||||
DrawHeadRotate( -p.PitchRadians, 0, 0, model.Head );
|
DrawHeadRotate( -p.PitchRadians, 0, 0, model.Head );
|
||||||
DrawPart( model.Torso );
|
DrawPart( model.Torso );
|
||||||
|
|
||||||
|
@ -47,15 +47,16 @@ namespace ClassicalSharp.Model {
|
|||||||
|
|
||||||
protected Vector3 pos;
|
protected Vector3 pos;
|
||||||
protected float cosYaw, sinYaw, cosHead, sinHead;
|
protected float cosYaw, sinYaw, cosHead, sinHead;
|
||||||
|
protected float uScale, vScale;
|
||||||
|
|
||||||
/// <summary> Renders the model based on the given entity's position and orientation. </summary>
|
/// <summary> Renders the model based on the given entity's position and orientation. </summary>
|
||||||
public void Render( Player p ) {
|
public void Render( Player p ) {
|
||||||
index = 0;
|
index = 0;
|
||||||
pos = p.Position;
|
pos = p.Position;
|
||||||
if( Bobbing )
|
if( Bobbing ) pos.Y += p.anim.bobYOffset;
|
||||||
pos.Y += p.anim.bobYOffset;
|
|
||||||
World map = game.World;
|
World map = game.World;
|
||||||
col = game.World.IsLit( Vector3I.Floor( p.EyePosition ) ) ? map.Sunlight : map.Shadowlight;
|
col = game.World.IsLit( Vector3I.Floor( p.EyePosition ) ) ? map.Sunlight : map.Shadowlight;
|
||||||
|
uScale = 1 / 64f; vScale = 1 / 32f;
|
||||||
|
|
||||||
cols[0] = col;
|
cols[0] = col;
|
||||||
cols[1] = FastColour.Scale( col, FastColour.ShadeYBottom );
|
cols[1] = FastColour.Scale( col, FastColour.ShadeYBottom );
|
||||||
@ -96,9 +97,7 @@ namespace ClassicalSharp.Model {
|
|||||||
return ModelBuilder.BuildRotatedBox( this, desc );
|
return ModelBuilder.BuildRotatedBox( this, desc );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool _64x64 = false;
|
|
||||||
protected void DrawPart( ModelPart part ) {
|
protected void DrawPart( ModelPart part ) {
|
||||||
float vScale = _64x64 ? 64f : 32f;
|
|
||||||
for( int i = 0; i < part.Count; i++ ) {
|
for( int i = 0; i < part.Count; i++ ) {
|
||||||
ModelVertex v = vertices[part.Offset + 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
|
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.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.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;
|
int quadI = i % 4;
|
||||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f / vScale;
|
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f * vScale;
|
||||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f / 64f;
|
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f * uScale;
|
||||||
cache.vertices[index++] = vertex;
|
cache.vertices[index++] = vertex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +130,6 @@ namespace ClassicalSharp.Model {
|
|||||||
float cosX = (float)Math.Cos( -angleX ), sinX = (float)Math.Sin( -angleX );
|
float cosX = (float)Math.Cos( -angleX ), sinX = (float)Math.Sin( -angleX );
|
||||||
float cosY = (float)Math.Cos( -angleY ), sinY = (float)Math.Sin( -angleY );
|
float cosY = (float)Math.Cos( -angleY ), sinY = (float)Math.Sin( -angleY );
|
||||||
float cosZ = (float)Math.Cos( -angleZ ), sinZ = (float)Math.Sin( -angleZ );
|
float cosZ = (float)Math.Cos( -angleZ ), sinZ = (float)Math.Sin( -angleZ );
|
||||||
float vScale = _64x64 ? 64f : 32f;
|
|
||||||
|
|
||||||
for( int i = 0; i < part.Count; i++ ) {
|
for( int i = 0; i < part.Count; i++ ) {
|
||||||
ModelVertex v = vertices[part.Offset + 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.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.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;
|
int quadI = i % 4;
|
||||||
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f / vScale;
|
if( quadI == 0 || quadI == 3 ) vertex.V -= 0.01f * vScale;
|
||||||
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f / 64f;
|
if( quadI == 2 || quadI == 3 ) vertex.U -= 0.01f * vScale;
|
||||||
cache.vertices[index++] = vertex;
|
cache.vertices[index++] = vertex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user