Fix mipmaps with terrain.png less than 16x16, give arm model a collision size.

This commit is contained in:
UnknownShadow200 2017-08-28 08:51:40 +10:00
parent a31de85bea
commit e28d029e39
8 changed files with 55 additions and 35 deletions

View File

@ -82,8 +82,12 @@ namespace ClassicalSharp.Gui.Screens {
TexturePack.ExtractDefault(game); return;
}
TexturePack extractor = new TexturePack();
extractor.Extract(data, game);
if (url.Contains(".zip")) {
TexturePack extractor = new TexturePack();
extractor.Extract(data, game);
} else {
TexturePack.ExtractTerrainPng(game, data, url);
}
}
}

View File

@ -135,10 +135,10 @@ namespace ClassicalSharp.Model {
}
}
public override float NameYOffset { get { return 0; } }
public override float GetEyeY(Entity entity) { return 0; }
public override Vector3 CollisionSize { get { return default(Vector3); } }
public override AABB PickingBounds { get { return default(AABB); } }
public override float NameYOffset { get { return 0.5f; } }
public override float GetEyeY(Entity entity) { return 0.5f; }
public override Vector3 CollisionSize { get { return Vector3.One; } }
public override AABB PickingBounds { get { return new AABB(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f); } }
protected override void RenderParts(Entity p) {
HumanoidModel human = (HumanoidModel)game.ModelCache.Models[0].Instance;

View File

@ -169,13 +169,12 @@ namespace ClassicalSharp.GraphicsAPI {
protected override int CreateTexture(int width, int height, IntPtr scan0, bool managedPool, bool mipmaps) {
D3D.Texture texture = null;
int levels = mipmaps ? 5 : 1;
int levels = 1 + (mipmaps ? MipmapsLevels(width, height) : 0);
if (managedPool) {
texture = device.CreateTexture(width, height, levels, Usage.None, Format.A8R8G8B8, Pool.Managed);
texture.SetData(0, LockFlags.None, scan0, width * height * 4);
// TODO: FIX THIS MEMORY LEAK!!!!!
if (mipmaps) DoMipmaps(texture, width, height, scan0);
} else {
D3D.Texture sys = device.CreateTexture(width, height, levels, Usage.None, Format.A8R8G8B8, Pool.SystemMemory);
@ -190,7 +189,9 @@ namespace ClassicalSharp.GraphicsAPI {
unsafe void DoMipmaps(D3D.Texture texture, int width, int height, IntPtr scan0) {
IntPtr prev = scan0;
for (int lvl = 1; lvl <= 4; lvl++) {
int lvls = MipmapsLevels(width, height);
for (int lvl = 1; lvl <= lvls; lvl++) {
width /= 2; height /= 2;
int size = width * height * 4;
@ -202,6 +203,7 @@ namespace ClassicalSharp.GraphicsAPI {
prev = cur;
}
if (prev != scan0) Marshal.FreeHGlobal(prev);
}
public override void UpdateTexturePart(int texId, int texX, int texY, FastBitmap part) {

View File

@ -196,6 +196,12 @@ namespace ClassicalSharp.GraphicsAPI {
}
}
}
internal static int MipmapsLevels(int width, int height) {
int lvlsWidth = Utils.Log2(width), lvlsHeight = Utils.Log2(height);
int lvls = Math.Min(lvlsWidth, lvlsHeight);
return Math.Min(lvls, 4);
}
}
public enum VertexFormat {

View File

@ -169,7 +169,7 @@ namespace ClassicalSharp.GraphicsAPI {
if (mipmaps) {
GL.TexParameteri(TextureTarget.Texture2D, TextureParameterName.MinFilter, (int)TextureFilter.NearestMipmapLinear);
GL.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 4);
GL.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, MipmapsLevels(width, height));
} else {
GL.TexParameteri(TextureTarget.Texture2D, TextureParameterName.MinFilter, (int)TextureFilter.Nearest);
}
@ -183,7 +183,9 @@ namespace ClassicalSharp.GraphicsAPI {
unsafe void DoMipmaps(int texture, int width, int height, IntPtr scan0) {
IntPtr prev = scan0;
for (int lvl = 1; lvl <= 4; lvl++) {
int lvls = MipmapsLevels(width, height);
for (int lvl = 1; lvl <= lvls; lvl++) {
width /= 2; height /= 2;
int size = width * height * 4;
@ -196,6 +198,7 @@ namespace ClassicalSharp.GraphicsAPI {
prev = cur;
}
if (prev != scan0) Marshal.FreeHGlobal(prev);
}
public override void BindTexture(int texture) {

View File

@ -16,10 +16,7 @@ namespace ClassicalSharp {
potHeat = new float[size * size];
soupHeat = new float[size * size];
}
int shift = 0;
while (size > 1) { shift++; size >>= 1; }
return shift;
return Utils.Log2(size);
}
}

View File

@ -77,29 +77,31 @@ namespace ClassicalSharp.Textures {
}
static void ExtractCachedTerrainPng(Game game, string url) {
FileStream data = TextureCache.GetStream(url);
if (data == null) { // e.g. 404 errors
if (game.World.TextureUrl != null) ExtractDefault(game);
} else if (url != game.World.TextureUrl) {
// Must read into a MemoryStream, because stream duration must be lifetime of bitmap
// and we don't want to maintain a reference to the file
MemoryStream ms = ReadAllBytes(data);
Bitmap bmp = GetBitmap(game.Drawer2D, ms);
data.Dispose();
if (bmp != null) {
game.World.TextureUrl = url;
game.Events.RaiseTexturePackChanged();
if (game.ChangeTerrainAtlas(bmp)) return;
using (Stream data = TextureCache.GetStream(url)) {
if (data == null) { // e.g. 404 errors
if (game.World.TextureUrl != null) ExtractDefault(game);
} else if (url != game.World.TextureUrl) {
ExtractTerrainPng(game, data, url);
}
if (bmp != null) bmp.Dispose();
ms.Dispose();
} else {
data.Dispose();
}
}
internal static void ExtractTerrainPng(Game game, Stream data, string url) {
// Must read into a MemoryStream, because stream duration must be lifetime of bitmap
// and we don't want to maintain a reference to the file
MemoryStream ms = ReadAllBytes(data);
Bitmap bmp = GetBitmap(game.Drawer2D, ms);
if (bmp != null) {
game.World.TextureUrl = url;
game.Events.RaiseTexturePackChanged();
if (game.ChangeTerrainAtlas(bmp)) return;
}
if (bmp != null) bmp.Dispose();
ms.Dispose();
}
internal static void ExtractTexturePack(Game game, DownloadedItem item) {
if (item.Data == null) return;
game.World.TextureUrl = item.Url;
@ -140,7 +142,7 @@ namespace ClassicalSharp.Textures {
}
}
static MemoryStream ReadAllBytes(FileStream src) {
static MemoryStream ReadAllBytes(Stream src) {
MemoryStream dst = new MemoryStream((int)src.Length);
byte[] buffer = new byte[4096];
for (int i = 0; i < (int)src.Length; i += 4096) {

View File

@ -118,6 +118,12 @@ namespace ClassicalSharp {
public static float Lerp(float a, float b, float t) {
return a + (b - a) * t;
}
public static int Log2(int value) {
int shift = 0;
while (value > 1) { shift++; value >>= 1; }
return shift;
}
#if !LAUNCHER
// http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/