This commit is contained in:
UnknownShadow200 2018-06-01 19:33:44 +10:00
parent 3a8c3d1f99
commit ca5d0899fd
39 changed files with 289 additions and 328 deletions

View File

@ -45,9 +45,6 @@ namespace ClassicalSharp {
} }
public void DrawBatch(BlockID block, float size, float x, float y) { public void DrawBatch(BlockID block, float size, float x, float y) {
drawer.tilesPerAtlas1D = TerrainAtlas1D.TilesPerAtlas;
drawer.invVerTileSize = TerrainAtlas1D.invTileSize;
bool bright = BlockInfo.FullBright[block]; bool bright = BlockInfo.FullBright[block];
if (BlockInfo.Draw[block] == DrawType.Gas) return; if (BlockInfo.Draw[block] == DrawType.Gas) return;
@ -94,7 +91,7 @@ namespace ClassicalSharp {
int GetTex(BlockID block, int side) { int GetTex(BlockID block, int side) {
int texLoc = BlockInfo.GetTextureLoc(block, side); int texLoc = BlockInfo.GetTextureLoc(block, side);
texIndex = texLoc / TerrainAtlas1D.TilesPerAtlas; texIndex = texLoc / Atlas1D.TilesPerAtlas;
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
return texLoc; return texLoc;
@ -103,7 +100,7 @@ namespace ClassicalSharp {
static Vector3 pos = Vector3.Zero; static Vector3 pos = Vector3.Zero;
void SpriteZQuad(BlockID block, bool firstPart) { void SpriteZQuad(BlockID block, bool firstPart) {
int texLoc = BlockInfo.GetTextureLoc(block, Side.Right); int texLoc = BlockInfo.GetTextureLoc(block, Side.Right);
TextureRec rec = TerrainAtlas1D.GetTexRec(texLoc, 1, out texIndex); TextureRec rec = Atlas1D.GetTexRec(texLoc, 1, out texIndex);
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
VertexP3fT2fC4b v = default(VertexP3fT2fC4b); VertexP3fT2fC4b v = default(VertexP3fT2fC4b);
@ -127,7 +124,7 @@ namespace ClassicalSharp {
void SpriteXQuad(BlockID block, bool firstPart) { void SpriteXQuad(BlockID block, bool firstPart) {
int texLoc = BlockInfo.GetTextureLoc(block, Side.Right); int texLoc = BlockInfo.GetTextureLoc(block, Side.Right);
TextureRec rec = TerrainAtlas1D.GetTexRec(texLoc, 1, out texIndex); TextureRec rec = Atlas1D.GetTexRec(texLoc, 1, out texIndex);
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
VertexP3fT2fC4b v = default(VertexP3fT2fC4b); VertexP3fT2fC4b v = default(VertexP3fT2fC4b);
@ -152,7 +149,7 @@ namespace ClassicalSharp {
int lastTexIndex, texIndex; int lastTexIndex, texIndex;
void Flush() { void Flush() {
if (lastTexIndex != -1) { if (lastTexIndex != -1) {
game.Graphics.BindTexture(TerrainAtlas1D.TexIds[lastTexIndex]); game.Graphics.BindTexture(Atlas1D.TexIds[lastTexIndex]);
game.Graphics.UpdateDynamicVb_IndexedTris(vb, vertices, index); game.Graphics.UpdateDynamicVb_IndexedTris(vb, vertices, index);
} }

View File

@ -76,7 +76,7 @@ namespace ClassicalSharp.Gui.Screens {
const int chExtent = 16, chWeight = 2; const int chExtent = 16, chWeight = 2;
static TextureRec chRec = new TextureRec(0, 0, 15/256f, 15/256f); static TextureRec chRec = new TextureRec(0, 0, 15/256f, 15/256f);
void DrawCrosshairs() { void DrawCrosshairs() {
if (game.Gui.IconsTex <= 0) return; if (game.Gui.IconsTex == 0) return;
int cenX = game.Width / 2, cenY = game.Height / 2; int cenX = game.Width / 2, cenY = game.Height / 2;
int extent = (int)(chExtent * game.Scale(game.Height / 480f)); int extent = (int)(chExtent * game.Scale(game.Height / 480f));

View File

@ -132,7 +132,7 @@ namespace ClassicalSharp.Gui.Screens {
int texLoc = BlockInfo.GetTextureLoc(Block.Dirt, Side.Top); int texLoc = BlockInfo.GetTextureLoc(Block.Dirt, Side.Top);
Texture tex = new Texture(0, 0, 0, game.Width, 64, Texture tex = new Texture(0, 0, 0, game.Width, 64,
TerrainAtlas1D.GetTexRec(texLoc, 1, out atlasIndex)); Atlas1D.GetTexRec(texLoc, 1, out atlasIndex));
tex.U2 = (float)game.Width / 64; tex.U2 = (float)game.Width / 64;
bool bound = false; bool bound = false;
@ -150,7 +150,7 @@ namespace ClassicalSharp.Gui.Screens {
if (index == 0) return; if (index == 0) return;
if (!bound) { if (!bound) {
bound = true; bound = true;
game.Graphics.BindTexture(TerrainAtlas1D.TexIds[atlasIndex]); game.Graphics.BindTexture(Atlas1D.TexIds[atlasIndex]);
} }
ModelCache cache = game.ModelCache; ModelCache cache = game.ModelCache;

View File

@ -12,7 +12,7 @@ namespace ClassicalSharp.Gui.Screens {
TextAtlas idAtlas; TextAtlas idAtlas;
public TexIdsOverlay(Game game) : base(game) { widgets = new Widget[1]; } public TexIdsOverlay(Game game) : base(game) { widgets = new Widget[1]; }
const int verticesCount = TerrainAtlas2D.TilesPerRow * TerrainAtlas2D.RowsCount * 4; const int verticesCount = Atlas2D.TilesPerRow * Atlas2D.MaxRowsCount * 4;
static VertexP3fT2fC4b[] vertices; static VertexP3fT2fC4b[] vertices;
int dynamicVb; int dynamicVb;
int xOffset, yOffset, tileSize; int xOffset, yOffset, tileSize;
@ -46,26 +46,26 @@ namespace ClassicalSharp.Gui.Screens {
idAtlas = new TextAtlas(game, 16); idAtlas = new TextAtlas(game, 16);
idAtlas.Pack("0123456789", textFont, "f"); idAtlas.Pack("0123456789", textFont, "f");
tileSize = game.Height / TerrainAtlas2D.RowsCount; tileSize = game.Height / Atlas2D.RowsCount;
tileSize = (tileSize / 8) * 8; tileSize = (tileSize / 8) * 8;
Utils.Clamp(ref tileSize, 8, 40); Utils.Clamp(ref tileSize, 8, 40);
xOffset = CalcPos(Anchor.Centre, 0, tileSize * TerrainAtlas2D.TilesPerRow, game.Width); xOffset = CalcPos(Anchor.Centre, 0, tileSize * Atlas2D.TilesPerRow, game.Width);
yOffset = CalcPos(Anchor.Centre, 0, tileSize * TerrainAtlas2D.RowsCount, game.Height); yOffset = CalcPos(Anchor.Centre, 0, tileSize * Atlas2D.RowsCount, game.Height);
widgets[0] = TextWidget.Create(game, "Texture ID reference sheet", titleFont) widgets[0] = TextWidget.Create(game, "Texture ID reference sheet", titleFont)
.SetLocation(Anchor.Centre, Anchor.Min, 0, yOffset - 30); .SetLocation(Anchor.Centre, Anchor.Min, 0, yOffset - 30);
} }
void RenderTerrain() { void RenderTerrain() {
int elementsPerAtlas = TerrainAtlas1D.TilesPerAtlas; int elementsPerAtlas = Atlas1D.TilesPerAtlas;
for (int i = 0; i < TerrainAtlas2D.TilesPerRow * TerrainAtlas2D.RowsCount;) { for (int i = 0; i < Atlas2D.TilesPerRow * Atlas2D.RowsCount;) {
int index = 0, texIdx = i / elementsPerAtlas, ignored; int index = 0, texIdx = i / elementsPerAtlas, ignored;
for (int j = 0; j < elementsPerAtlas; j++) { for (int j = 0; j < elementsPerAtlas; j++) {
TextureRec rec = TerrainAtlas1D.GetTexRec(i + j, 1, out ignored); TextureRec rec = Atlas1D.GetTexRec(i + j, 1, out ignored);
int x = (i + j) % TerrainAtlas2D.TilesPerRow; int x = (i + j) % Atlas2D.TilesPerRow;
int y = (i + j) / TerrainAtlas2D.TilesPerRow; int y = (i + j) / Atlas2D.TilesPerRow;
Texture tex = new Texture(0, xOffset + x * tileSize, yOffset + y * tileSize, Texture tex = new Texture(0, xOffset + x * tileSize, yOffset + y * tileSize,
tileSize, tileSize, rec); tileSize, tileSize, rec);
@ -73,7 +73,7 @@ namespace ClassicalSharp.Gui.Screens {
} }
i += elementsPerAtlas; i += elementsPerAtlas;
game.Graphics.BindTexture(TerrainAtlas1D.TexIds[texIdx]); game.Graphics.BindTexture(Atlas1D.TexIds[texIdx]);
game.Graphics.UpdateDynamicVb_IndexedTris(dynamicVb, vertices, index); game.Graphics.UpdateDynamicVb_IndexedTris(dynamicVb, vertices, index);
} }
} }
@ -83,10 +83,10 @@ namespace ClassicalSharp.Gui.Screens {
int index = 0; int index = 0;
idAtlas.tex.Y = (short)(yOffset + (tileSize - idAtlas.tex.Height)); idAtlas.tex.Y = (short)(yOffset + (tileSize - idAtlas.tex.Height));
for (int y = 0; y < TerrainAtlas2D.RowsCount; y++) { for (int y = 0; y < Atlas2D.RowsCount; y++) {
for (int x = 0; x < TerrainAtlas2D.TilesPerRow; x++) { for (int x = 0; x < Atlas2D.TilesPerRow; x++) {
idAtlas.curX = xOffset + tileSize * x + textOffset; idAtlas.curX = xOffset + tileSize * x + textOffset;
int id = x + y * TerrainAtlas2D.TilesPerRow; int id = x + y * Atlas2D.TilesPerRow;
idAtlas.AddInt(id, vertices, ref index); idAtlas.AddInt(id, vertices, ref index);
} }
idAtlas.tex.Y += (short)tileSize; idAtlas.tex.Y += (short)tileSize;

View File

@ -184,7 +184,7 @@ namespace ClassicalSharp.Gui.Widgets {
tex = MakeTexture(index, text); tex = MakeTexture(index, text);
lines[index] = text; lines[index] = text;
} else { } else {
tex = new Texture(-1, 0, 0, 0, 0, 0, 0); tex = default(Texture);
tex.Height = (ushort)(PlaceholderHeight[index] ? defaultHeight : 0); tex.Height = (ushort)(PlaceholderHeight[index] ? defaultHeight : 0);
lines[index] = null; lines[index] = null;
} }

View File

@ -70,7 +70,7 @@ namespace ClassicalSharp.Gui.Widgets {
public override void Init() { public override void Init() {
int numLines = UsedLines; int numLines = UsedLines;
if (numLines > 1) { if (numLines > 1) {
Text.WordWrap(game.Drawer2D, lines, numLines, MaxCharsPerLine); Text.WordWrap(lines, numLines, MaxCharsPerLine);
} else { } else {
lines[0] = Text.ToString(); lines[0] = Text.ToString();
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using OpenTK; using OpenTK;
using ClassicalSharp; using ClassicalSharp;
using ClassicalSharp.Textures;
using BlockID = System.UInt16; using BlockID = System.UInt16;
namespace ClassicalSharp { namespace ClassicalSharp {
@ -42,7 +43,7 @@ namespace ClassicalSharp {
} }
internal static void RecalculateSpriteBB() { internal static void RecalculateSpriteBB() {
using (FastBitmap fastBmp = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) { using (FastBitmap fastBmp = new FastBitmap(Atlas2D.Atlas, true, true)) {
for (int i = 0; i < Count; i++) { for (int i = 0; i < Count; i++) {
if (Draw[i] != DrawType.Sprite) continue; if (Draw[i] != DrawType.Sprite) continue;
RecalculateBB((BlockID)i, fastBmp); RecalculateBB((BlockID)i, fastBmp);

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using ClassicalSharp.Blocks; using ClassicalSharp.Blocks;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
using TexLoc = System.UInt16;
namespace ClassicalSharp { namespace ClassicalSharp {
@ -63,11 +64,12 @@ namespace ClassicalSharp {
public static bool[] IsLiquid, BlocksLight, FullBright; public static bool[] IsLiquid, BlocksLight, FullBright;
public static bool[] CanPlace, CanDelete, Tinted, FullOpaque; public static bool[] CanPlace, CanDelete, Tinted, FullOpaque;
public static byte[] Collide, ExtendedCollide, textures, hidden; public static byte[] Collide, ExtendedCollide, hidden;
public static byte[] LightOffset, Draw, SpriteOffset, CanStretch; public static byte[] LightOffset, Draw, SpriteOffset, CanStretch;
public static byte[] DigSounds, StepSounds; public static byte[] DigSounds, StepSounds;
public static string[] Name; public static string[] Name;
public static float[] FogDensity, SpeedMultiplier; public static float[] FogDensity, SpeedMultiplier;
public static TexLoc[] textures;
public static FastColour[] FogColour; public static FastColour[] FogColour;
public static Vector3[] MinBB, MaxBB, RenderMinBB, RenderMaxBB; public static Vector3[] MinBB, MaxBB, RenderMinBB, RenderMaxBB;
static uint[] DefinedCustomBlocks; static uint[] DefinedCustomBlocks;
@ -83,7 +85,7 @@ namespace ClassicalSharp {
FullOpaque = new bool[count]; FullOpaque = new bool[count];
Collide = new byte[count]; Collide = new byte[count];
ExtendedCollide = new byte[count]; ExtendedCollide = new byte[count];
textures = new byte[count * Side.Sides]; textures = new TexLoc[count * Side.Sides];
hidden = new byte[count * count]; hidden = new byte[count * count];
LightOffset = new byte[count]; LightOffset = new byte[count];
Draw = new byte[count]; Draw = new byte[count];
@ -267,15 +269,15 @@ namespace ClassicalSharp {
} }
internal static void SetSide(byte textureId, BlockID blockId) { internal static void SetSide(TexLoc texLoc, BlockID blockId) {
textures[blockId * Side.Sides + Side.Left] = textureId; textures[blockId * Side.Sides + Side.Left] = texLoc;
textures[blockId * Side.Sides + Side.Right] = textureId; textures[blockId * Side.Sides + Side.Right] = texLoc;
textures[blockId * Side.Sides + Side.Front] = textureId; textures[blockId * Side.Sides + Side.Front] = texLoc;
textures[blockId * Side.Sides + Side.Back] = textureId; textures[blockId * Side.Sides + Side.Back] = texLoc;
} }
internal static void SetTex(byte textureId, int face, BlockID blockId) { internal static void SetTex(TexLoc texLoc, int face, BlockID blockId) {
textures[blockId * Side.Sides + face] = textureId; textures[blockId * Side.Sides + face] = texLoc;
} }
public static int GetTextureLoc(BlockID block, int face) { public static int GetTextureLoc(BlockID block, int face) {

View File

@ -47,7 +47,7 @@
<StartAction>Project</StartAction> <StartAction>Project</StartAction>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug_D3D' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug_D3D' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<OutputPath>..\output\debug\</OutputPath> <OutputPath>..\output\debug\</OutputPath>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType> <DebugType>Full</DebugType>
@ -56,6 +56,7 @@
<DefineConstants>DEBUG;TRACE;USE_DX;</DefineConstants> <DefineConstants>DEBUG;TRACE;USE_DX;</DefineConstants>
<StartAction>Project</StartAction> <StartAction>Project</StartAction>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath> <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<StartArguments>unk aa 127.0.0.1 25566</StartArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release_D3D' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release_D3D' ">
<OutputPath>..\output\release\</OutputPath> <OutputPath>..\output\release\</OutputPath>
@ -282,8 +283,7 @@
<Compile Include="TexturePack\LiquidAnimations.cs" /> <Compile Include="TexturePack\LiquidAnimations.cs" />
<Compile Include="TexturePack\Side.cs" /> <Compile Include="TexturePack\Side.cs" />
<Compile Include="TexturePack\TextureCache.cs" /> <Compile Include="TexturePack\TextureCache.cs" />
<Compile Include="TexturePack\TerrainAtlas1D.cs" /> <Compile Include="TexturePack\TerrainAtlas.cs" />
<Compile Include="TexturePack\TerrainAtlas2D.cs" />
<Compile Include="TexturePack\TexturePack.cs" /> <Compile Include="TexturePack\TexturePack.cs" />
<Compile Include="TexturePack\ZipReader.cs" /> <Compile Include="TexturePack\ZipReader.cs" />
<Compile Include="Utils\Camera.cs" /> <Compile Include="Utils\Camera.cs" />

View File

@ -187,9 +187,9 @@ namespace ClassicalSharp.Entities {
} }
internal static bool boundShadowTex = false; internal static bool boundShadowTex = false;
internal static int shadowTex = -1; internal static int shadowTex = 0;
static void CheckShadowTexture(IGraphicsApi gfx) { static void CheckShadowTexture(IGraphicsApi gfx) {
if (shadowTex != -1) return; if (shadowTex != 0) return;
const int size = 128, half = size / 2; const int size = 128, half = size / 2;
using (Bitmap bmp = Platform.CreateBmp(size, size)) using (Bitmap bmp = Platform.CreateBmp(size, size))
using (FastBitmap fastBmp = new FastBitmap(bmp, true, false)) using (FastBitmap fastBmp = new FastBitmap(bmp, true, false))

View File

@ -33,7 +33,7 @@ namespace ClassicalSharp.Entities {
/// <summary> Returns the size of the model that is used for collision detection. </summary> /// <summary> Returns the size of the model that is used for collision detection. </summary>
public Vector3 Size; public Vector3 Size;
public int TextureId = -1, MobTextureId = -1; public int TextureId, MobTextureId;
public short Health = 10; public short Health = 10;
public Vector3 Position; public Vector3 Position;
@ -130,7 +130,7 @@ namespace ClassicalSharp.Entities {
Model = game.ModelCache.Get(ModelName); Model = game.ModelCache.Get(ModelName);
ParseScale(scale); ParseScale(scale);
MobTextureId = -1; MobTextureId = 0;
Model.RecalcProperties(this); Model.RecalcProperties(this);
UpdateModelBounds(); UpdateModelBounds();

View File

@ -82,7 +82,7 @@ namespace ClassicalSharp.Model {
void Flush() { void Flush() {
if (lastTexIndex != -1) { if (lastTexIndex != -1) {
game.Graphics.BindTexture(TerrainAtlas1D.TexIds[lastTexIndex]); game.Graphics.BindTexture(Atlas1D.TexIds[lastTexIndex]);
UpdateVB(); UpdateVB();
} }
@ -103,9 +103,6 @@ namespace ClassicalSharp.Model {
SpriteXQuad(true, false); SpriteXQuad(true, false);
SpriteXQuad(true, true); SpriteXQuad(true, true);
} else { } else {
drawer.tilesPerAtlas1D = TerrainAtlas1D.TilesPerAtlas;
drawer.invVerTileSize = TerrainAtlas1D.invTileSize;
drawer.minBB = BlockInfo.MinBB[block]; drawer.minBB.Y = 1 - drawer.minBB.Y; drawer.minBB = BlockInfo.MinBB[block]; drawer.minBB.Y = 1 - drawer.minBB.Y;
drawer.maxBB = BlockInfo.MaxBB[block]; drawer.maxBB.Y = 1 - drawer.maxBB.Y; drawer.maxBB = BlockInfo.MaxBB[block]; drawer.maxBB.Y = 1 - drawer.maxBB.Y;
@ -128,7 +125,7 @@ namespace ClassicalSharp.Model {
int GetTex(int side) { int GetTex(int side) {
int texLoc = BlockInfo.GetTextureLoc(block, side); int texLoc = BlockInfo.GetTextureLoc(block, side);
texIndex = texLoc / TerrainAtlas1D.TilesPerAtlas; texIndex = texLoc / Atlas1D.TilesPerAtlas;
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
return texLoc; return texLoc;
@ -136,7 +133,7 @@ namespace ClassicalSharp.Model {
void SpriteZQuad(bool firstPart, bool mirror) { void SpriteZQuad(bool firstPart, bool mirror) {
int texLoc = BlockInfo.GetTextureLoc(block, Side.Back); int texLoc = BlockInfo.GetTextureLoc(block, Side.Back);
TextureRec rec = TerrainAtlas1D.GetTexRec(texLoc, 1, out texIndex); TextureRec rec = Atlas1D.GetTexRec(texLoc, 1, out texIndex);
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
int col = cols[0]; int col = cols[0];
@ -161,7 +158,7 @@ namespace ClassicalSharp.Model {
void SpriteXQuad(bool firstPart, bool mirror) { void SpriteXQuad(bool firstPart, bool mirror) {
int texLoc = BlockInfo.GetTextureLoc(block, Side.Right); int texLoc = BlockInfo.GetTextureLoc(block, Side.Right);
TextureRec rec = TerrainAtlas1D.GetTexRec(texLoc, 1, out texIndex); TextureRec rec = Atlas1D.GetTexRec(texLoc, 1, out texIndex);
if (lastTexIndex != texIndex) Flush(); if (lastTexIndex != texIndex) Flush();
int col = cols[0]; int col = cols[0];

View File

@ -30,7 +30,7 @@ namespace ClassicalSharp.Model {
public override AABB PickingBounds { get { return pickingBounds; } } public override AABB PickingBounds { get { return pickingBounds; } }
public override void DrawModel(Entity p) { public override void DrawModel(Entity p) {
int texId = p.TextureId <= 0 ? cache.HumanoidTexId : p.TextureId; int texId = p.TextureId == 0 ? cache.HumanoidTexId : p.TextureId;
} }
internal void ReadSetupPacket() { internal void ReadSetupPacket() {

View File

@ -139,7 +139,7 @@ namespace ClassicalSharp.Model {
bool _64x64 = p.SkinType != SkinType.Type64x32; bool _64x64 = p.SkinType != SkinType.Type64x32;
// only apply when using humanoid skins // only apply when using humanoid skins
_64x64 &= UsesHumanSkin || p.MobTextureId > 0; _64x64 &= UsesHumanSkin || p.MobTextureId != 0;
uScale = p.uScale * 0.015625f; uScale = p.uScale * 0.015625f;
vScale = p.vScale * (_64x64 ? 0.015625f : 0.03125f); vScale = p.vScale * (_64x64 ? 0.015625f : 0.03125f);
@ -184,7 +184,7 @@ namespace ClassicalSharp.Model {
protected int GetTexture(Entity entity) { protected int GetTexture(Entity entity) {
int pTex = UsesHumanSkin ? entity.TextureId : entity.MobTextureId; int pTex = UsesHumanSkin ? entity.TextureId : entity.MobTextureId;
return pTex > 0 ? pTex : game.ModelCache.Textures[texIndex].TexID; return pTex != 0 ? pTex : game.ModelCache.Textures[texIndex].TexID;
} }

View File

@ -33,6 +33,7 @@ namespace ClassicalSharp.Entities {
} }
public override void ContextLost() { public override void ContextLost() {
if (nameTex.ID < 0) return;
game.Graphics.DeleteTexture(ref nameTex.ID); game.Graphics.DeleteTexture(ref nameTex.ID);
} }
@ -178,7 +179,7 @@ namespace ClassicalSharp.Entities {
void ApplySkin(Player src) { void ApplySkin(Player src) {
TextureId = src.TextureId; TextureId = src.TextureId;
MobTextureId = -1; MobTextureId = 0;
SkinType = src.SkinType; SkinType = src.SkinType;
uScale = src.uScale; vScale = src.vScale; uScale = src.uScale; vScale = src.vScale;
@ -188,8 +189,8 @@ namespace ClassicalSharp.Entities {
internal void ResetSkin() { internal void ResetSkin() {
uScale = 1; vScale = 1; uScale = 1; vScale = 1;
MobTextureId = -1; MobTextureId = 0;
TextureId = -1; TextureId = 0;
SkinType = game.DefaultPlayerSkinType; SkinType = game.DefaultPlayerSkinType;
} }

View File

@ -83,8 +83,8 @@ namespace ClassicalSharp {
Drawer2D.BlackTextShadows = Options.GetBool(OptionsKey.BlackText, false); Drawer2D.BlackTextShadows = Options.GetBool(OptionsKey.BlackText, false);
Graphics.Mipmaps = Options.GetBool(OptionsKey.Mipmaps, false); Graphics.Mipmaps = Options.GetBool(OptionsKey.Mipmaps, false);
TerrainAtlas1D.game = this; Atlas1D.game = this;
TerrainAtlas2D.game = this; Atlas2D.game = this;
Animations = new Animations(); Components.Add(Animations); Animations = new Animations(); Components.Add(Animations);
Inventory = new Inventory(); Components.Add(Inventory); Inventory = new Inventory(); Components.Add(Inventory);
Inventory.Map = new BlockID[BlockInfo.Count]; Inventory.Map = new BlockID[BlockInfo.Count];

View File

@ -40,17 +40,17 @@ namespace ClassicalSharp {
public bool ChangeTerrainAtlas(Bitmap atlas) { public bool ChangeTerrainAtlas(Bitmap atlas) {
if (!ValidateBitmap("terrain.png", atlas)) return false; if (!ValidateBitmap("terrain.png", atlas)) return false;
if (atlas.Width != atlas.Height) { if (atlas.Width != atlas.Height && (atlas.Width * 2 != atlas.Height)) {
Chat.Add("&cUnable to use terrain.png from the texture pack."); Chat.Add("&cUnable to use terrain.png from the texture pack.");
Chat.Add("&c Its width is not the same as its height."); Chat.Add("&c Its width is not the same as its height.");
return false; return false;
} }
if (Graphics.LostContext) return false; if (Graphics.LostContext) return false;
TerrainAtlas1D.Dispose(); Atlas1D.Dispose();
TerrainAtlas2D.Dispose(); Atlas2D.Dispose();
TerrainAtlas2D.UpdateState(atlas); Atlas2D.UpdateState(atlas);
TerrainAtlas1D.UpdateState(); Atlas1D.UpdateState();
Events.RaiseTerrainAtlasChanged(); Events.RaiseTerrainAtlasChanged();
return true; return true;
@ -170,7 +170,7 @@ namespace ClassicalSharp {
Entity[] entities = Entities.List; Entity[] entities = Entities.List;
for (int i = 0; i < EntityList.MaxCount; i++) { for (int i = 0; i < EntityList.MaxCount; i++) {
if (entities[i] == null || entities[i].TextureId != -1) continue; if (entities[i] == null || entities[i].TextureId != 0) continue;
entities[i].SkinType = DefaultPlayerSkinType; entities[i].SkinType = DefaultPlayerSkinType;
} }
} }
@ -393,8 +393,8 @@ namespace ClassicalSharp {
public void Dispose() { public void Dispose() {
ChunkUpdater.Dispose(); ChunkUpdater.Dispose();
TerrainAtlas2D.Dispose(); Atlas2D.Dispose();
TerrainAtlas1D.Dispose(); Atlas1D.Dispose();
ModelCache.Dispose(); ModelCache.Dispose();
Entities.Dispose(); Entities.Dispose();
WorldEvents.OnNewMap -= OnNewMapCore; WorldEvents.OnNewMap -= OnNewMapCore;

View File

@ -524,14 +524,14 @@ namespace ClassicalSharp.GraphicsAPI {
} }
static void Delete<T>(T[] array, ref int id) where T : class, IDisposable { static void Delete<T>(T[] array, ref int id) where T : class, IDisposable {
if (id <= 0 || id >= array.Length) return; if (id == 0 || id >= array.Length) return;
T value = array[id]; T value = array[id];
if (value != null) { if (value != null) {
value.Dispose(); value.Dispose();
} }
array[id] = null; array[id] = null;
id = -1; id = 0;
} }
public override void Dispose() { public override void Dispose() {

View File

@ -232,9 +232,9 @@ namespace ClassicalSharp.GraphicsAPI {
} }
public override void DeleteTexture(ref int texId) { public override void DeleteTexture(ref int texId) {
if (texId <= 0) return; if (texId == 0) return;
int id = texId; GL.DeleteTextures(1, &id); int id = texId; GL.DeleteTextures(1, &id);
texId = -1; texId = 0;
} }
public override void EnableMipmaps() { } public override void EnableMipmaps() { }
@ -334,8 +334,8 @@ namespace ClassicalSharp.GraphicsAPI {
#endif #endif
public override void DeleteVb(ref int vb) { public override void DeleteVb(ref int vb) {
if (vb <= 0) return; if (vb == 0) return;
int id = vb; vb = -1; int id = vb; vb = 0;
#if !GL11 #if !GL11
GL.DeleteBuffers(1, &id); GL.DeleteBuffers(1, &id);
#else #else
@ -345,8 +345,8 @@ namespace ClassicalSharp.GraphicsAPI {
public override void DeleteIb(ref int ib) { public override void DeleteIb(ref int ib) {
#if !GL11 #if !GL11
if (ib <= 0) return; if (ib == 0) return;
int id = ib; ib = -1; int id = ib; ib = 0;
GL.DeleteBuffers(1, &id); GL.DeleteBuffers(1, &id);
#else #else
return; return;

View File

@ -146,10 +146,10 @@ namespace ClassicalSharp.GraphicsAPI {
} }
public override void DeleteTexture(ref int texId) { public override void DeleteTexture(ref int texId) {
if (texId <= 0) return; if (texId == 0) return;
int id = texId; int id = texId;
GL.DeleteTextures(1, &id); GL.DeleteTextures(1, &id);
texId = -1; texId = 0;
} }
#endregion #endregion
@ -192,15 +192,15 @@ namespace ClassicalSharp.GraphicsAPI {
} }
public override void DeleteVb(ref int vb) { public override void DeleteVb(ref int vb) {
if (vb <= 0) return; if (vb == 0) return;
int id = vb; GL.DeleteBuffers(1, &id); int id = vb; GL.DeleteBuffers(1, &id);
vb = -1; vb = 0;
} }
public override void DeleteIb(ref int ib) { public override void DeleteIb(ref int ib) {
if (ib <= 0) return; if (ib == 0) return;
int id = ib; GL.DeleteBuffers(1, &id); int id = ib; GL.DeleteBuffers(1, &id);
ib = -1; ib = 0;
} }
VertexFormat batchFormat = (VertexFormat)999; VertexFormat batchFormat = (VertexFormat)999;

View File

@ -2,6 +2,7 @@
using System; using System;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Map; using ClassicalSharp.Map;
using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
@ -124,13 +125,13 @@ namespace ClassicalSharp {
void DrawLeftFace(int count) { void DrawLeftFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Left]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Left];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Left) & 1; int offset = (lightFlags >> Side.Left) & 1;
float u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f/16f; float u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f/16f;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];
@ -166,13 +167,13 @@ namespace ClassicalSharp {
void DrawRightFace(int count) { void DrawRightFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Right]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Right];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Right) & 1; int offset = (lightFlags >> Side.Right) & 1;
float u1 = (count - minBB.Z), u2 = (1 - maxBB.Z) * 15.99f/16f; float u1 = (count - minBB.Z), u2 = (1 - maxBB.Z) * 15.99f/16f;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];
@ -208,13 +209,13 @@ namespace ClassicalSharp {
void DrawFrontFace(int count) { void DrawFrontFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Front]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Front];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Front) & 1; int offset = (lightFlags >> Side.Front) & 1;
float u1 = (count - minBB.X), u2 = (1 - maxBB.X) * 15.99f/16f; float u1 = (count - minBB.X), u2 = (1 - maxBB.X) * 15.99f/16f;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];
@ -250,13 +251,13 @@ namespace ClassicalSharp {
void DrawBackFace(int count) { void DrawBackFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Back]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Back];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Back) & 1; int offset = (lightFlags >> Side.Back) & 1;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];
@ -292,13 +293,13 @@ namespace ClassicalSharp {
void DrawBottomFace(int count) { void DrawBottomFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Bottom]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Bottom];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Bottom) & 1; int offset = (lightFlags >> Side.Bottom) & 1;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
float v1 = vOrigin + minBB.Z * invVerTileSize; float v1 = vOrigin + minBB.Z * Atlas1D.invTileSize;
float v2 = vOrigin + maxBB.Z * invVerTileSize * 15.99f/16f; float v2 = vOrigin + maxBB.Z * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];
@ -334,13 +335,13 @@ namespace ClassicalSharp {
void DrawTopFace(int count) { void DrawTopFace(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Top]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Top];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
int offset = (lightFlags >> Side.Top) & 1; int offset = (lightFlags >> Side.Top) & 1;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
float v1 = vOrigin + minBB.Z * invVerTileSize; float v1 = vOrigin + minBB.Z * Atlas1D.invTileSize;
float v2 = vOrigin + maxBB.Z * invVerTileSize * 15.99f/16f; float v2 = vOrigin + maxBB.Z * Atlas1D.invTileSize * 15.99f/16f;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int F = bitFlags[cIndex]; int F = bitFlags[cIndex];

View File

@ -24,10 +24,8 @@ namespace ClassicalSharp {
protected const int chunkSize2 = 16 * 16, extChunkSize2 = 18 * 18; protected const int chunkSize2 = 16 * 16, extChunkSize2 = 18 * 18;
protected const int chunkSize3 = 16 * 16 * 16, extChunkSize3 = 18 * 18 * 18; protected const int chunkSize3 = 16 * 16 * 16, extChunkSize3 = 18 * 18 * 18;
public void Init(Game game) { public void Init(Game game) { this.game = game; }
this.game = game; public void Dispose() { }
game.Events.TerrainAtlasChanged += TerrainAtlasChanged;
}
protected internal int width, length, height, sidesLevel, edgeLevel; protected internal int width, length, height, sidesLevel, edgeLevel;
protected int maxX, maxY, maxZ, chunkEndX, chunkEndZ; protected int maxX, maxY, maxZ, chunkEndX, chunkEndZ;

View File

@ -1,16 +1,13 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System; using System;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
namespace ClassicalSharp { namespace ClassicalSharp {
/// <summary> Draws the vertices for a cuboid region. </summary> /// <summary> Draws the vertices for a cuboid region. </summary>
public sealed class CuboidDrawer { public sealed class CuboidDrawer {
public int tilesPerAtlas1D;
public float invVerTileSize;
/// <summary> Whether a colour tinting effect should be applied to all faces. </summary> /// <summary> Whether a colour tinting effect should be applied to all faces. </summary>
public bool Tinted; public bool Tinted;
@ -19,14 +16,15 @@ namespace ClassicalSharp {
public Vector3 minBB, maxBB; public Vector3 minBB, maxBB;
public float x1, y1, z1, x2, y2, z2; public float x1, y1, z1, x2, y2, z2;
const float uv2Scale = 15.99f/16f;
/// <summary> Draws the left face of the given cuboid region. </summary> /// <summary> Draws the left face of the given cuboid region. </summary>
public void Left(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Left(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f/16f; float u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * uv2Scale;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.X = x1; v.Colour = col; VertexP3fT2fC4b v; v.X = x1; v.Colour = col;
@ -38,10 +36,10 @@ namespace ClassicalSharp {
/// <summary> Draws the right face of the given cuboid region. </summary> /// <summary> Draws the right face of the given cuboid region. </summary>
public void Right(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Right(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = (count - minBB.Z), u2 = (1 - maxBB.Z) * 15.99f/16f; float u1 = (count - minBB.Z), u2 = (1 - maxBB.Z) * uv2Scale;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.X = x2; v.Colour = col; VertexP3fT2fC4b v; v.X = x2; v.Colour = col;
@ -53,10 +51,10 @@ namespace ClassicalSharp {
/// <summary> Draws the front face of the given cuboid region. </summary> /// <summary> Draws the front face of the given cuboid region. </summary>
public void Front(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Front(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = (count - minBB.X), u2 = (1 - maxBB.X) * 15.99f/16f; float u1 = (count - minBB.X), u2 = (1 - maxBB.X) * uv2Scale;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.Z = z1; v.Colour = col; VertexP3fT2fC4b v; v.Z = z1; v.Colour = col;
@ -68,10 +66,10 @@ namespace ClassicalSharp {
/// <summary> Draws the back face of the given cuboid region. </summary> /// <summary> Draws the back face of the given cuboid region. </summary>
public void Back(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Back(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * uv2Scale;
float v1 = vOrigin + maxBB.Y * invVerTileSize; float v1 = vOrigin + maxBB.Y * Atlas1D.invTileSize;
float v2 = vOrigin + minBB.Y * invVerTileSize * 15.99f/16f; float v2 = vOrigin + minBB.Y * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.Z = z2; v.Colour = col; VertexP3fT2fC4b v; v.Z = z2; v.Colour = col;
@ -83,10 +81,10 @@ namespace ClassicalSharp {
/// <summary> Draws the bottom face of the given cuboid region. </summary> /// <summary> Draws the bottom face of the given cuboid region. </summary>
public void Bottom(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Bottom(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * uv2Scale;
float v1 = vOrigin + minBB.Z * invVerTileSize; float v1 = vOrigin + minBB.Z * Atlas1D.invTileSize;
float v2 = vOrigin + maxBB.Z * invVerTileSize * 15.99f/16f; float v2 = vOrigin + maxBB.Z * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.Y = y1; v.Colour = col; VertexP3fT2fC4b v; v.Y = y1; v.Colour = col;
@ -98,10 +96,10 @@ namespace ClassicalSharp {
/// <summary> Draws the top face of the given cuboid region. </summary> /// <summary> Draws the top face of the given cuboid region. </summary>
public void Top(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) { public void Top(int count, int col, int texLoc, VertexP3fT2fC4b[] vertices, ref int index) {
float vOrigin = (texLoc % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texLoc % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f; float u1 = minBB.X, u2 = (count - 1) + maxBB.X * uv2Scale;
float v1 = vOrigin + minBB.Z * invVerTileSize; float v1 = vOrigin + minBB.Z * Atlas1D.invTileSize;
float v2 = vOrigin + maxBB.Z * invVerTileSize * 15.99f/16f; float v2 = vOrigin + maxBB.Z * Atlas1D.invTileSize * uv2Scale;
if (Tinted) col = TintBlock(col); if (Tinted) col = TintBlock(col);
VertexP3fT2fC4b v; v.Y = y2; v.Colour = col; VertexP3fT2fC4b v; v.Y = y2; v.Colour = col;

View File

@ -2,6 +2,7 @@
using System; using System;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Map; using ClassicalSharp.Map;
using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
@ -88,13 +89,7 @@ namespace ClassicalSharp {
} }
return 0; return 0;
} }
protected override void PreStretchTiles(int x1, int y1, int z1) {
base.PreStretchTiles(x1, y1, z1);
drawer.invVerTileSize = invVerTileSize;
drawer.tilesPerAtlas1D = tilesPerAtlas1D;
}
protected override void RenderTile(int index) { protected override void RenderTile(int index) {
if (BlockInfo.Draw[curBlock] == DrawType.Sprite) { if (BlockInfo.Draw[curBlock] == DrawType.Sprite) {
this.fullBright = BlockInfo.FullBright[curBlock]; this.fullBright = BlockInfo.FullBright[curBlock];
@ -126,7 +121,7 @@ namespace ClassicalSharp {
if (leftCount != 0) { if (leftCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Left]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Left];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Left) & 1; int offset = (lightFlags >> Side.Left) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
@ -137,7 +132,7 @@ namespace ClassicalSharp {
if (rightCount != 0) { if (rightCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Right]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Right];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Right) & 1; int offset = (lightFlags >> Side.Right) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
@ -148,7 +143,7 @@ namespace ClassicalSharp {
if (frontCount != 0) { if (frontCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Front]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Front];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Front) & 1; int offset = (lightFlags >> Side.Front) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
@ -159,7 +154,7 @@ namespace ClassicalSharp {
if (backCount != 0) { if (backCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Back]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Back];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Back) & 1; int offset = (lightFlags >> Side.Back) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
@ -170,7 +165,7 @@ namespace ClassicalSharp {
if (bottomCount != 0) { if (bottomCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Bottom]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Bottom];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Bottom) & 1; int offset = (lightFlags >> Side.Bottom) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
@ -180,7 +175,7 @@ namespace ClassicalSharp {
if (topCount != 0) { if (topCount != 0) {
int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Top]; int texLoc = BlockInfo.textures[curBlock * Side.Sides + Side.Top];
int i = texLoc / tilesPerAtlas1D; int i = texLoc / Atlas1D.TilesPerAtlas;
int offset = (lightFlags >> Side.Top) & 1; int offset = (lightFlags >> Side.Top) & 1;
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i]; DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];

View File

@ -13,26 +13,6 @@ namespace ClassicalSharp {
protected DrawInfo[] normalParts, translucentParts; protected DrawInfo[] normalParts, translucentParts;
protected int arraysCount = 0; protected int arraysCount = 0;
protected bool fullBright, tinted; protected bool fullBright, tinted;
protected float invVerTileSize;
protected int tilesPerAtlas1D;
void TerrainAtlasChanged(object sender, EventArgs e) {
int newArraysCount = TerrainAtlas1D.TexIds.Length;
if (arraysCount == newArraysCount) return;
arraysCount = newArraysCount;
Array.Resize(ref normalParts, arraysCount);
Array.Resize(ref translucentParts, arraysCount);
for (int i = 0; i < normalParts.Length; i++) {
if (normalParts[i] != null) continue;
normalParts[i] = new DrawInfo();
translucentParts[i] = new DrawInfo();
}
}
public void Dispose() {
game.Events.TerrainAtlasChanged -= TerrainAtlasChanged;
}
protected class DrawInfo { protected class DrawInfo {
public int[] vIndex = new int[6], vCount = new int[6]; public int[] vIndex = new int[6], vCount = new int[6];
@ -69,13 +49,12 @@ namespace ClassicalSharp {
protected abstract void RenderTile(int index); protected abstract void RenderTile(int index);
protected virtual void PreStretchTiles(int x1, int y1, int z1) { protected virtual void PreStretchTiles(int x1, int y1, int z1) {
invVerTileSize = TerrainAtlas1D.invTileSize; arraysCount = Math.Max(Atlas1D.AtlasesCount, game.MapRenderer._1DUsed); // TODO: hacky workaround fix
tilesPerAtlas1D = TerrainAtlas1D.TilesPerAtlas;
arraysCount = TerrainAtlas1D.TexIds.Length;
if (normalParts == null) { if (normalParts == null || normalParts.Length < arraysCount) {
normalParts = new DrawInfo[arraysCount]; normalParts = new DrawInfo[arraysCount];
translucentParts = new DrawInfo[arraysCount]; translucentParts = new DrawInfo[arraysCount];
for (int i = 0; i < normalParts.Length; i++) { for (int i = 0; i < normalParts.Length; i++) {
normalParts[i] = new DrawInfo(); normalParts[i] = new DrawInfo();
translucentParts[i] = new DrawInfo(); translucentParts[i] = new DrawInfo();
@ -113,13 +92,13 @@ namespace ClassicalSharp {
} }
void AddSpriteVertices(BlockID block) { void AddSpriteVertices(BlockID block) {
int i = TerrainAtlas1D.Get1DIndex(BlockInfo.GetTextureLoc(block, Side.Left)); int i = Atlas1D.Get1DIndex(BlockInfo.GetTextureLoc(block, Side.Left));
DrawInfo part = normalParts[i]; DrawInfo part = normalParts[i];
part.spriteCount += 4 * 4; part.spriteCount += 4 * 4;
} }
void AddVertices(BlockID block, int face) { void AddVertices(BlockID block, int face) {
int i = TerrainAtlas1D.Get1DIndex(BlockInfo.GetTextureLoc(block, face)); int i = Atlas1D.Get1DIndex(BlockInfo.GetTextureLoc(block, face));
DrawInfo part = BlockInfo.Draw[block] == DrawType.Translucent ? translucentParts[i] : normalParts[i]; DrawInfo part = BlockInfo.Draw[block] == DrawType.Translucent ? translucentParts[i] : normalParts[i];
part.vCount[face] += 4; part.vCount[face] += 4;
} }
@ -127,13 +106,13 @@ namespace ClassicalSharp {
static JavaRandom spriteRng = new JavaRandom(0); static JavaRandom spriteRng = new JavaRandom(0);
protected virtual void DrawSprite(int count) { protected virtual void DrawSprite(int count) {
int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Right]; int texId = BlockInfo.textures[curBlock * Side.Sides + Side.Right];
int i = texId / tilesPerAtlas1D; int i = texId / Atlas1D.TilesPerAtlas;
float vOrigin = (texId % tilesPerAtlas1D) * invVerTileSize; float vOrigin = (texId % Atlas1D.TilesPerAtlas) * Atlas1D.invTileSize;
float x1 = X + 2.50f/16, y1 = Y, z1 = Z + 2.50f/16; float x1 = X + 2.50f/16, y1 = Y, z1 = Z + 2.50f/16;
float x2 = X + 13.5f/16, y2 = Y + 1, z2 = Z + 13.5f/16; float x2 = X + 13.5f/16, y2 = Y + 1, z2 = Z + 13.5f/16;
const float u1 = 0, u2 = 15.99f/16f; const float u1 = 0, u2 = 15.99f/16f;
float v1 = vOrigin, v2 = vOrigin + invVerTileSize * 15.99f/16f; float v1 = vOrigin, v2 = vOrigin + Atlas1D.invTileSize * 15.99f/16f;
byte offsetType = BlockInfo.SpriteOffset[curBlock]; byte offsetType = BlockInfo.SpriteOffset[curBlock];
if (offsetType >= 6 && offsetType <= 7) { if (offsetType >= 6 && offsetType <= 7) {

View File

@ -9,7 +9,7 @@ namespace ClassicalSharp.Network {
internal int ServerExtensionsCount; internal int ServerExtensionsCount;
internal bool sendHeldBlock, useMessageTypes; internal bool sendHeldBlock, useMessageTypes;
internal int envMapVer = 2, blockDefsExtVer = 2; internal int envMapVer = 2, blockDefsExtVer = 2;
internal bool needD3Fix, extEntityPos, twoWayPing, blockPerms, fastMap; internal bool needD3Fix, extEntityPos, twoWayPing, blockPerms, fastMap, extTexs;
public Game game; public Game game;
public void Reset() { public void Reset() {
@ -17,6 +17,7 @@ namespace ClassicalSharp.Network {
sendHeldBlock = false; useMessageTypes = false; sendHeldBlock = false; useMessageTypes = false;
envMapVer = 2; blockDefsExtVer = 2; envMapVer = 2; blockDefsExtVer = 2;
needD3Fix = false; extEntityPos = false; twoWayPing = false; fastMap = false; needD3Fix = false; extEntityPos = false; twoWayPing = false; fastMap = false;
extTexs = false;
game.SupportsCPEBlocks = false; game.SupportsCPEBlocks = false;
} }
@ -60,6 +61,10 @@ namespace ClassicalSharp.Network {
} else if (ext == "FastMap") { } else if (ext == "FastMap") {
net.packetSizes[Opcode.LevelInit] += 4; net.packetSizes[Opcode.LevelInit] += 4;
fastMap = true; fastMap = true;
} else if (ext == "ExtendedTextures") {
net.packetSizes[Opcode.CpeDefineBlock] += 3;
net.packetSizes[Opcode.CpeDefineBlockExt] += 6;
extTexs = true;
} }
#if !ONLY_8BIT #if !ONLY_8BIT
else if (ext == "ExtendedBlocks") { else if (ext == "ExtendedBlocks") {
@ -91,6 +96,7 @@ namespace ClassicalSharp.Network {
"EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages", "EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages",
"BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect", "BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect",
"EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap", "EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap",
"ExtendedTextures",
#if !ONLY_8BIT #if !ONLY_8BIT
"ExtendedBlocks", "ExtendedBlocks",
#endif #endif

View File

@ -1,7 +1,9 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System; using System;
using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
using TexLoc = System.UInt16;
namespace ClassicalSharp.Network.Protocols { namespace ClassicalSharp.Network.Protocols {
@ -15,7 +17,7 @@ namespace ClassicalSharp.Network.Protocols {
net.Set(Opcode.CpeDefineBlock, HandleDefineBlock, 80); net.Set(Opcode.CpeDefineBlock, HandleDefineBlock, 80);
net.Set(Opcode.CpeUndefineBlock, HandleRemoveBlockDefinition, 2); net.Set(Opcode.CpeUndefineBlock, HandleRemoveBlockDefinition, 2);
net.Set(Opcode.CpeDefineBlockExt, HandleDefineBlockExt, 85); net.Set(Opcode.CpeDefineBlockExt, HandleDefineBlockExt, 85);
} }
public override void Tick() { } public override void Tick() { }
internal void HandleDefineBlock() { internal void HandleDefineBlock() {
@ -29,7 +31,7 @@ namespace ClassicalSharp.Network.Protocols {
HandleDefineBlockCommonEnd(reader, shape, block); HandleDefineBlockCommonEnd(reader, shape, block);
// Update sprite BoundingBox if necessary // Update sprite BoundingBox if necessary
if (BlockInfo.Draw[block] == DrawType.Sprite) { if (BlockInfo.Draw[block] == DrawType.Sprite) {
using (FastBitmap dst = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) using (FastBitmap dst = new FastBitmap(Atlas2D.Atlas, true, true))
BlockInfo.RecalculateBB(block, dst); BlockInfo.RecalculateBB(block, dst);
} }
} }
@ -76,6 +78,13 @@ namespace ClassicalSharp.Network.Protocols {
HandleDefineBlockCommonEnd(reader, 1, block); HandleDefineBlockCommonEnd(reader, 1, block);
} }
TexLoc ReadTex(NetReader reader) {
if (!net.cpeData.extTexs) return reader.ReadUInt8();
const int maxTexCount = Atlas2D.TilesPerRow * Atlas2D.MaxRowsCount;
return (TexLoc)(reader.ReadUInt16() % maxTexCount);
}
BlockID HandleDefineBlockCommonStart(NetReader reader, bool uniqueSideTexs) { BlockID HandleDefineBlockCommonStart(NetReader reader, bool uniqueSideTexs) {
BlockID block = reader.ReadBlock(); BlockID block = reader.ReadBlock();
bool didBlockLight = BlockInfo.BlocksLight[block]; bool didBlockLight = BlockInfo.BlocksLight[block];
@ -85,23 +94,23 @@ namespace ClassicalSharp.Network.Protocols {
BlockInfo.SetCollide(block, reader.ReadUInt8()); BlockInfo.SetCollide(block, reader.ReadUInt8());
BlockInfo.SpeedMultiplier[block] = (float)Math.Pow(2, (reader.ReadUInt8() - 128) / 64f); BlockInfo.SpeedMultiplier[block] = (float)Math.Pow(2, (reader.ReadUInt8() - 128) / 64f);
BlockInfo.SetTex(reader.ReadUInt8(), Side.Top, block); BlockInfo.SetTex(ReadTex(reader), Side.Top, block);
if (uniqueSideTexs) { if (uniqueSideTexs) {
BlockInfo.SetTex(reader.ReadUInt8(), Side.Left, block); BlockInfo.SetTex(ReadTex(reader), Side.Left, block);
BlockInfo.SetTex(reader.ReadUInt8(), Side.Right, block); BlockInfo.SetTex(ReadTex(reader), Side.Right, block);
BlockInfo.SetTex(reader.ReadUInt8(), Side.Front, block); BlockInfo.SetTex(ReadTex(reader), Side.Front, block);
BlockInfo.SetTex(reader.ReadUInt8(), Side.Back, block); BlockInfo.SetTex(ReadTex(reader), Side.Back, block);
} else { } else {
BlockInfo.SetSide(reader.ReadUInt8(), block); BlockInfo.SetSide(ReadTex(reader), block);
} }
BlockInfo.SetTex(reader.ReadUInt8(), Side.Bottom, block); BlockInfo.SetTex(ReadTex(reader), Side.Bottom, block);
BlockInfo.BlocksLight[block] = reader.ReadUInt8() == 0; BlockInfo.BlocksLight[block] = reader.ReadUInt8() == 0;
OnBlockUpdated(block, didBlockLight); OnBlockUpdated(block, didBlockLight);
byte sound = reader.ReadUInt8(); byte sound = reader.ReadUInt8();
BlockInfo.StepSounds[block] = sound; BlockInfo.StepSounds[block] = sound;
BlockInfo.DigSounds[block] = sound; BlockInfo.DigSounds[block] = sound;
if (sound == SoundType.Glass) BlockInfo.StepSounds[block] = SoundType.Stone; if (sound == SoundType.Glass) BlockInfo.StepSounds[block] = SoundType.Stone;
BlockInfo.FullBright[block] = reader.ReadUInt8() != 0; BlockInfo.FullBright[block] = reader.ReadUInt8() != 0;

View File

@ -5,6 +5,7 @@ using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Map; using ClassicalSharp.Map;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
using TexLoc = System.UInt16;
namespace ClassicalSharp.Particles { namespace ClassicalSharp.Particles {
@ -141,7 +142,7 @@ namespace ClassicalSharp.Particles {
public sealed class TerrainParticle : Particle { public sealed class TerrainParticle : Particle {
internal TextureRec rec; internal TextureRec rec;
internal byte texLoc; internal TexLoc texLoc;
internal BlockID block; internal BlockID block;
public bool Tick(Game game, double delta) { public bool Tick(Game game, double delta) {

View File

@ -5,6 +5,7 @@ using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Textures; using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
using TexLoc = System.UInt16;
namespace ClassicalSharp.Particles { namespace ClassicalSharp.Particles {
@ -14,7 +15,8 @@ namespace ClassicalSharp.Particles {
TerrainParticle[] terrainParticles = new TerrainParticle[maxParticles]; TerrainParticle[] terrainParticles = new TerrainParticle[maxParticles];
RainParticle[] rainParticles = new RainParticle[maxParticles]; RainParticle[] rainParticles = new RainParticle[maxParticles];
int terrainCount, rainCount; int terrainCount, rainCount;
int[] terrain1DCount, terrain1DIndices; int[] terrain1DCount = new int[Atlas1D.MaxAtlases];
int[] terrain1DIndices = new int[Atlas1D.MaxAtlases];
Game game; Game game;
Random rnd = new Random(); Random rnd = new Random();
@ -23,7 +25,6 @@ namespace ClassicalSharp.Particles {
void IGameComponent.Init(Game game) { void IGameComponent.Init(Game game) {
this.game = game; this.game = game;
game.Events.TerrainAtlasChanged += TerrainAtlasChanged;
game.UserEvents.BlockChanged += BreakBlockEffect; game.UserEvents.BlockChanged += BreakBlockEffect;
game.Events.TextureChanged += TextureChanged; game.Events.TextureChanged += TextureChanged;
@ -36,11 +37,6 @@ namespace ClassicalSharp.Particles {
void IGameComponent.Reset(Game game) { rainCount = 0; terrainCount = 0; } void IGameComponent.Reset(Game game) { rainCount = 0; terrainCount = 0; }
void IGameComponent.OnNewMap(Game game) { rainCount = 0; terrainCount = 0; } void IGameComponent.OnNewMap(Game game) { rainCount = 0; terrainCount = 0; }
void IGameComponent.OnNewMapLoaded(Game game) { } void IGameComponent.OnNewMapLoaded(Game game) { }
void TerrainAtlasChanged(object sender, EventArgs e) {
terrain1DCount = new int[TerrainAtlas1D.TexIds.Length];
terrain1DIndices = new int[TerrainAtlas1D.TexIds.Length];
}
void TextureChanged(object sender, TextureEventArgs e) { void TextureChanged(object sender, TextureEventArgs e) {
if (e.Name == "particles.png") if (e.Name == "particles.png")
@ -72,7 +68,7 @@ namespace ClassicalSharp.Particles {
Update1DCounts(particles, elems); Update1DCounts(particles, elems);
for (int i = 0; i < elems; i++) { for (int i = 0; i < elems; i++) {
int index = TerrainAtlas1D.Get1DIndex(particles[i].texLoc); int index = Atlas1D.Get1DIndex(particles[i].texLoc);
particles[i].Render(game, t, vertices, ref terrain1DIndices[index]); particles[i].Render(game, t, vertices, ref terrain1DIndices[index]);
} }
int drawCount = Math.Min(count, maxParticles * 4); int drawCount = Math.Min(count, maxParticles * 4);
@ -81,11 +77,11 @@ namespace ClassicalSharp.Particles {
fixed (VertexP3fT2fC4b* ptr = vertices) { fixed (VertexP3fT2fC4b* ptr = vertices) {
gfx.SetDynamicVbData(vb, (IntPtr)ptr, drawCount); gfx.SetDynamicVbData(vb, (IntPtr)ptr, drawCount);
int offset = 0; int offset = 0;
for (int i = 0; i < terrain1DCount.Length; i++) { for (int i = 0; i < Atlas1D.AtlasesCount; i++) {
int partCount = terrain1DCount[i]; int partCount = terrain1DCount[i];
if (partCount == 0) continue; if (partCount == 0) continue;
gfx.BindTexture(TerrainAtlas1D.TexIds[i]); gfx.BindTexture(Atlas1D.TexIds[i]);
gfx.DrawVb_IndexedTris(partCount, offset); gfx.DrawVb_IndexedTris(partCount, offset);
offset += partCount; offset += partCount;
} }
@ -93,15 +89,15 @@ namespace ClassicalSharp.Particles {
} }
void Update1DCounts(TerrainParticle[] particles, int elems) { void Update1DCounts(TerrainParticle[] particles, int elems) {
for (int i = 0; i < terrain1DCount.Length; i++) { for (int i = 0; i < Atlas1D.MaxAtlases; i++) {
terrain1DCount[i] = 0; terrain1DCount[i] = 0;
terrain1DIndices[i] = 0; terrain1DIndices[i] = 0;
} }
for (int i = 0; i < elems; i++) { for (int i = 0; i < elems; i++) {
int index = TerrainAtlas1D.Get1DIndex(particles[i].texLoc); int index = Atlas1D.Get1DIndex(particles[i].texLoc);
terrain1DCount[index] += 4; terrain1DCount[index] += 4;
} }
for (int i = 1; i < terrain1DCount.Length; i++) { for (int i = 1; i < Atlas1D.AtlasesCount; i++) {
terrain1DIndices[i] = terrain1DIndices[i - 1] + terrain1DCount[i - 1]; terrain1DIndices[i] = terrain1DIndices[i - 1] + terrain1DCount[i - 1];
} }
} }
@ -169,8 +165,8 @@ namespace ClassicalSharp.Particles {
Vector3 worldPos = new Vector3(position.X, position.Y, position.Z); Vector3 worldPos = new Vector3(position.X, position.Y, position.Z);
int texLoc = BlockInfo.GetTextureLoc(block, Side.Left), texIndex = 0; int texLoc = BlockInfo.GetTextureLoc(block, Side.Left), texIndex = 0;
TextureRec baseRec = TerrainAtlas1D.GetTexRec(texLoc, 1, out texIndex); TextureRec baseRec = Atlas1D.GetTexRec(texLoc, 1, out texIndex);
float uScale = (1/16f), vScale = (1/16f) * TerrainAtlas1D.invTileSize; float uScale = (1/16f), vScale = (1/16f) * Atlas1D.invTileSize;
Vector3 minBB = BlockInfo.MinBB[block]; Vector3 minBB = BlockInfo.MinBB[block];
Vector3 maxBB = BlockInfo.MaxBB[block]; Vector3 maxBB = BlockInfo.MaxBB[block];
@ -211,7 +207,7 @@ namespace ClassicalSharp.Particles {
p.ResetState(worldPos + cell, velocity, life); p.ResetState(worldPos + cell, velocity, life);
p.rec = rec; p.rec = rec;
p.texLoc = (byte)texLoc; p.texLoc = (TexLoc)texLoc;
p.block = block; p.block = block;
int type = rnd.Next(0, 30); int type = rnd.Next(0, 30);
p.Size = (byte)(type >= 28 ? 12 : (type >= 25 ? 10 : 8)); p.Size = (byte)(type >= 28 ? 12 : (type >= 25 ? 10 : 8));
@ -267,7 +263,6 @@ namespace ClassicalSharp.Particles {
void IDisposable.Dispose() { void IDisposable.Dispose() {
game.Graphics.DeleteTexture(ref ParticlesTexId); game.Graphics.DeleteTexture(ref ParticlesTexId);
game.UserEvents.BlockChanged -= BreakBlockEffect; game.UserEvents.BlockChanged -= BreakBlockEffect;
game.Events.TerrainAtlasChanged -= TerrainAtlasChanged;
game.Events.TextureChanged -= TextureChanged; game.Events.TextureChanged -= TextureChanged;
ContextLost(); ContextLost();

View File

@ -83,8 +83,7 @@ namespace ClassicalSharp.Renderers {
ResetChunkCache(); ResetChunkCache();
} }
renderer.normalPartsCount = new int[TerrainAtlas1D.TexIds.Length]; ResetPartsCounts();
renderer.translucentPartsCount = new int[TerrainAtlas1D.TexIds.Length];
} }
void RefreshBorders(int clipLevel) { void RefreshBorders(int clipLevel) {
@ -115,21 +114,18 @@ namespace ClassicalSharp.Renderers {
} }
void TerrainAtlasChanged(object sender, EventArgs e) { void TerrainAtlasChanged(object sender, EventArgs e) {
if (renderer._1DUsed == -1) { if (renderer._1DUsed != -1) {
renderer.normalPartsCount = new int[TerrainAtlas1D.TexIds.Length]; bool refreshRequired = elementsPerBitmap != Atlas1D.TilesPerAtlas;
renderer.translucentPartsCount = new int[TerrainAtlas1D.TexIds.Length];
} else {
bool refreshRequired = elementsPerBitmap != TerrainAtlas1D.TilesPerAtlas;
if (refreshRequired) Refresh(); if (refreshRequired) Refresh();
} }
renderer._1DUsed = TerrainAtlas1D.UsedAtlasesCount(); renderer._1DUsed = Atlas1D.UsedAtlasesCount();
elementsPerBitmap = TerrainAtlas1D.TilesPerAtlas; elementsPerBitmap = Atlas1D.TilesPerAtlas;
ResetUsedFlags(); ResetUsedFlags();
} }
void BlockDefinitionChanged(object sender, EventArgs e) { void BlockDefinitionChanged(object sender, EventArgs e) {
renderer._1DUsed = TerrainAtlas1D.UsedAtlasesCount(); renderer._1DUsed = Atlas1D.UsedAtlasesCount();
ResetUsedFlags(); ResetUsedFlags();
Refresh(); Refresh();
} }
@ -143,30 +139,25 @@ namespace ClassicalSharp.Renderers {
} }
void ResetUsedFlags() { void ResetUsedFlags() {
int count = renderer._1DUsed; for (int i = 0; i < Atlas1D.MaxAtlases; i++) {
bool[] used = renderer.usedTranslucent;
if (used == null || count > used.Length) {
renderer.usedTranslucent = new bool[count];
renderer.usedNormal = new bool[count];
renderer.pendingTranslucent = new bool[count];
renderer.pendingNormal = new bool[count];
}
for (int i = 0; i < count; i++) {
renderer.pendingTranslucent[i] = true; renderer.pendingTranslucent[i] = true;
renderer.usedTranslucent[i] = false; renderer.usedTranslucent[i] = false;
renderer.pendingNormal[i] = true; renderer.pendingNormal[i] = true;
renderer.usedNormal[i] = false; renderer.usedNormal[i] = false;
}
}
void ResetPartsCounts() {
for (int i = 0; i < Atlas1D.MaxAtlases; i++) {
renderer.normalPartsCount[i] = 0;
renderer.translucentPartsCount[i] = 0;
} }
} }
void OnNewMap(object sender, EventArgs e) { void OnNewMap(object sender, EventArgs e) {
game.ChunkUpdates = 0; game.ChunkUpdates = 0;
ClearChunkCache(); ClearChunkCache();
for (int i = 0; i < renderer.normalPartsCount.Length; i++) { ResetPartsCounts();
renderer.normalPartsCount[i] = 0;
renderer.translucentPartsCount[i] = 0;
}
renderer.chunks = null; renderer.chunks = null;
renderer.unsortedChunks = null; renderer.unsortedChunks = null;
@ -218,11 +209,11 @@ namespace ClassicalSharp.Renderers {
void ClearChunkCache() { void ClearChunkCache() {
if (renderer.chunks == null) return; if (renderer.chunks == null) return;
for (int i = 0; i < renderer.chunks.Length; i++) for (int i = 0; i < renderer.chunks.Length; i++) {
DeleteChunk(renderer.chunks[i]); DeleteChunk(renderer.chunks[i]);
}
renderer.normalPartsCount = new int[TerrainAtlas1D.TexIds.Length]; ResetPartsCounts();
renderer.translucentPartsCount = new int[TerrainAtlas1D.TexIds.Length];
} }
void DeleteChunk(ChunkInfo info) { void DeleteChunk(ChunkInfo info) {

View File

@ -11,7 +11,7 @@ namespace ClassicalSharp.Renderers {
public unsafe sealed class EnvRenderer : IGameComponent { public unsafe sealed class EnvRenderer : IGameComponent {
int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices, cloudsTex; int cloudsVb, cloudVertices, skyVb, skyVertices, cloudsTex;
World map; World map;
Game game; Game game;
internal bool legacy, minimal; internal bool legacy, minimal;
@ -59,7 +59,7 @@ namespace ClassicalSharp.Renderers {
public void Render(double deltaTime) { public void Render(double deltaTime) {
if (minimal) { RenderMinimal(deltaTime); return; } if (minimal) { RenderMinimal(deltaTime); return; }
if (skyVb == -1 || cloudsVb == -1) return; if (skyVb == 0 || cloudsVb == 0) return;
if (!game.SkyboxRenderer.ShouldRender) { if (!game.SkyboxRenderer.ShouldRender) {
RenderSky(deltaTime); RenderSky(deltaTime);

View File

@ -5,6 +5,7 @@ using System.Drawing;
using ClassicalSharp.Events; using ClassicalSharp.Events;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Map; using ClassicalSharp.Map;
using ClassicalSharp.Textures;
using OpenTK; using OpenTK;
using BlockID = System.UInt16; using BlockID = System.UInt16;
@ -15,7 +16,7 @@ namespace ClassicalSharp.Renderers {
World map; World map;
Game game; Game game;
int sidesVb = -1, edgesVb = -1; int sidesVb, edgesVb;
int edgeTexId, sideTexId; int edgeTexId, sideTexId;
int sidesVertices, edgesVertices; int sidesVertices, edgesVertices;
internal bool legacy; internal bool legacy;
@ -38,7 +39,7 @@ namespace ClassicalSharp.Renderers {
} }
public void RenderSides(double delta) { public void RenderSides(double delta) {
if (sidesVb == -1) return; if (sidesVb == 0) return;
BlockID block = game.World.Env.SidesBlock; BlockID block = game.World.Env.SidesBlock;
IGraphicsApi gfx = game.Graphics; IGraphicsApi gfx = game.Graphics;
@ -57,7 +58,7 @@ namespace ClassicalSharp.Renderers {
} }
public void RenderEdges(double delta) { public void RenderEdges(double delta) {
if (edgesVb == -1) return; if (edgesVb == 0) return;
BlockID block = game.World.Env.EdgeBlock; BlockID block = game.World.Env.EdgeBlock;
IGraphicsApi gfx = game.Graphics; IGraphicsApi gfx = game.Graphics;
@ -319,7 +320,7 @@ namespace ClassicalSharp.Renderers {
lastTexLoc = texLoc; lastTexLoc = texLoc;
game.Graphics.DeleteTexture(ref id); game.Graphics.DeleteTexture(ref id);
id = TerrainAtlas2D.LoadTile(texLoc); id = Atlas2D.LoadTile(texLoc);
} }
} }
} }

View File

@ -9,7 +9,7 @@ namespace ClassicalSharp.Renderers {
public sealed class SkyboxRenderer : IGameComponent { public sealed class SkyboxRenderer : IGameComponent {
int tex, vb = -1; int tex, vb;
Game game; Game game;
const int count = 6 * 4; const int count = 6 * 4;
@ -62,7 +62,7 @@ namespace ClassicalSharp.Renderers {
} }
public void Render(double deltaTime) { public void Render(double deltaTime) {
if (vb == -1) return; if (vb == 0) return;
game.Graphics.DepthWrite = false; game.Graphics.DepthWrite = false;
game.Graphics.Texturing = true; game.Graphics.Texturing = true;
game.Graphics.BindTexture(tex); game.Graphics.BindTexture(tex);

View File

@ -54,11 +54,15 @@ namespace ClassicalSharp.Renderers {
internal int _1DUsed = -1, chunksX, chunksY, chunksZ; internal int _1DUsed = -1, chunksX, chunksY, chunksZ;
internal int renderCount = 0; internal int renderCount = 0;
internal ChunkInfo[] chunks, renderChunks, unsortedChunks; internal ChunkInfo[] chunks, renderChunks, unsortedChunks;
internal bool[] usedTranslucent, usedNormal;
internal bool[] pendingTranslucent, pendingNormal;
internal int[] normalPartsCount, translucentPartsCount;
bool inTranslucent = false; bool inTranslucent = false;
internal bool[] usedTranslucent = new bool[Atlas1D.MaxAtlases];
internal bool[] usedNormal = new bool[Atlas1D.MaxAtlases];
internal bool[] pendingTranslucent = new bool[Atlas1D.MaxAtlases];
internal bool[] pendingNormal = new bool[Atlas1D.MaxAtlases];
internal int[] normalPartsCount = new int[Atlas1D.MaxAtlases];
internal int[] translucentPartsCount = new int[Atlas1D.MaxAtlases];
public MapRenderer(Game game) { public MapRenderer(Game game) {
this.game = game; this.game = game;
} }
@ -86,7 +90,7 @@ namespace ClassicalSharp.Renderers {
if (chunks == null) return; if (chunks == null) return;
IGraphicsApi gfx = game.Graphics; IGraphicsApi gfx = game.Graphics;
int[] texIds = TerrainAtlas1D.TexIds; int[] texIds = Atlas1D.TexIds;
gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b);
gfx.Texturing = true; gfx.Texturing = true;
gfx.AlphaTest = true; gfx.AlphaTest = true;
@ -137,7 +141,7 @@ namespace ClassicalSharp.Renderers {
gfx.ColourWriteMask(true, true, true, true); gfx.ColourWriteMask(true, true, true, true);
gfx.DepthWrite = false; // we already calculated depth values in depth pass gfx.DepthWrite = false; // we already calculated depth values in depth pass
int[] texIds = TerrainAtlas1D.TexIds; int[] texIds = Atlas1D.TexIds;
gfx.EnableMipmaps(); gfx.EnableMipmaps();
for (int batch = 0; batch < _1DUsed; batch++) { for (int batch = 0; batch < _1DUsed; batch++) {
if (translucentPartsCount[batch] <= 0) continue; if (translucentPartsCount[batch] <= 0) continue;

View File

@ -55,11 +55,11 @@ namespace ClassicalSharp.Textures {
/// <summary> Runs through all animations and if necessary updates the terrain atlas. </summary> /// <summary> Runs through all animations and if necessary updates the terrain atlas. </summary>
public void Tick(ScheduledTask task) { public void Tick(ScheduledTask task) {
if (useLavaAnim) { if (useLavaAnim) {
int size = Math.Min(TerrainAtlas2D.TileSize, 64); int size = Math.Min(Atlas2D.TileSize, 64);
DrawAnimation(null, 30, size); DrawAnimation(null, 30, size);
} }
if (useWaterAnim) { if (useWaterAnim) {
int size = Math.Min(TerrainAtlas2D.TileSize, 64); int size = Math.Min(Atlas2D.TileSize, 64);
DrawAnimation(null, 14, size); DrawAnimation(null, 14, size);
} }
@ -154,8 +154,8 @@ namespace ClassicalSharp.Textures {
} }
unsafe void DrawAnimationCore(AnimationData data, int texId, int size, byte* temp) { unsafe void DrawAnimationCore(AnimationData data, int texId, int size, byte* temp) {
int index = TerrainAtlas1D.Get1DIndex(texId); int index = Atlas1D.Get1DIndex(texId);
int rowNum = TerrainAtlas1D.Get1DRowId(texId); int rowNum = Atlas1D.Get1DRowId(texId);
animPart.SetData(size, size, size * 4, (IntPtr)temp, false); animPart.SetData(size, size, size * 4, (IntPtr)temp, false);
if (data == null) { if (data == null) {
@ -169,8 +169,8 @@ namespace ClassicalSharp.Textures {
data.FrameY, 0, 0, animsBuffer, animPart, size); data.FrameY, 0, 0, animsBuffer, animPart, size);
} }
int y = rowNum * TerrainAtlas2D.TileSize; int y = rowNum * Atlas2D.TileSize;
game.Graphics.UpdateTexturePart(TerrainAtlas1D.TexIds[index], 0, y, animPart, game.Graphics.Mipmaps); game.Graphics.UpdateTexturePart(Atlas1D.TexIds[index], 0, y, animPart, game.Graphics.Mipmaps);
} }
bool IsDefaultZip() { bool IsDefaultZip() {
@ -209,7 +209,7 @@ namespace ClassicalSharp.Textures {
const string terrainFormat = "&cAnimation frames for tile ({0}, {1}) are bigger than the size of a tile in terrain.png"; const string terrainFormat = "&cAnimation frames for tile ({0}, {1}) are bigger than the size of a tile in terrain.png";
void ValidateAnimations() { void ValidateAnimations() {
validated = true; validated = true;
int elemSize = TerrainAtlas2D.TileSize; int elemSize = Atlas2D.TileSize;
for (int i = animations.Count - 1; i >= 0; i--) { for (int i = animations.Count - 1; i >= 0; i--) {
AnimationData a = animations[i]; AnimationData a = animations[i];
if (a.FrameSize > elemSize) { if (a.FrameSize > elemSize) {

View File

@ -8,12 +8,46 @@ using Android.Graphics;
namespace ClassicalSharp.Textures { namespace ClassicalSharp.Textures {
/// <summary> Represents a 2D packed texture atlas that has been converted into an array of 1D atlases. </summary> /// <summary> Represents a 2D packed texture atlas, specifically for terrain.png. </summary>
public static class TerrainAtlas1D { public static class Atlas2D {
public static int TilesPerAtlas; public const int TilesPerRow = 16, MaxRowsCount = 32;
public static float invTileSize; public static Bitmap Atlas;
public static int[] TexIds; public static int TileSize, RowsCount;
internal static Game game; internal static Game game;
public static void UpdateState(Bitmap bmp) {
Atlas = bmp;
TileSize = bmp.Width / TilesPerRow;
RowsCount = bmp.Height / TilesPerRow;
BlockInfo.RecalculateSpriteBB();
}
public static int LoadTile(int texLoc) {
int size = TileSize;
using (FastBitmap atlas = new FastBitmap(Atlas, true, true))
using (Bitmap bmp = Platform.CreateBmp(size, size))
using (FastBitmap dst = new FastBitmap(bmp, true, false))
{
int x = texLoc % TilesPerRow, y = texLoc / TilesPerRow;
y %= RowsCount;
FastBitmap.MovePortion(x * size, y * size, 0, 0, atlas, dst, size);
return game.Graphics.CreateTexture(dst, false, game.Graphics.Mipmaps);
}
}
public static void Dispose() {
if (Atlas != null) Atlas.Dispose();
}
}
/// <summary> Represents a 2D packed texture atlas that has been converted into an array of 1D atlases. </summary>
public static class Atlas1D {
public static int TilesPerAtlas, AtlasesCount;
public static float invTileSize;
internal static Game game;
public const int MaxAtlases = Atlas2D.MaxRowsCount * Atlas2D.TilesPerRow;
public static int[] TexIds = new int[MaxAtlases];
public static TextureRec GetTexRec(int texLoc, int uCount, out int index) { public static TextureRec GetTexRec(int texLoc, int uCount, out int index) {
index = texLoc / TilesPerAtlas; index = texLoc / TilesPerAtlas;
@ -30,38 +64,33 @@ namespace ClassicalSharp.Textures {
public static int Get1DRowId(int texLoc) { return texLoc % TilesPerAtlas; } public static int Get1DRowId(int texLoc) { return texLoc % TilesPerAtlas; }
public static void UpdateState() { public static void UpdateState() {
int tileSize = TerrainAtlas2D.TileSize; int tileSize = Atlas2D.TileSize;
int maxTiles = Atlas2D.RowsCount * Atlas2D.TilesPerRow;
int maxAtlasHeight = Math.Min(4096, game.Graphics.MaxTextureDimensions); int maxAtlasHeight = Math.Min(4096, game.Graphics.MaxTextureDimensions);
int maxTilesPerAtlas = maxAtlasHeight / tileSize; int maxTilesPerAtlas = maxAtlasHeight / tileSize;
const int maxTiles = TerrainAtlas2D.RowsCount * TerrainAtlas2D.TilesPerRow;
TilesPerAtlas = Math.Min(maxTilesPerAtlas, maxTiles); TilesPerAtlas = Math.Min(maxTilesPerAtlas, maxTiles);
int atlasesCount = Utils.CeilDiv(maxTiles, TilesPerAtlas); AtlasesCount = Utils.CeilDiv(maxTiles, TilesPerAtlas);
int atlasHeight = TilesPerAtlas * tileSize;
invTileSize = 1f / TilesPerAtlas; invTileSize = 1f / TilesPerAtlas;
Convert2DTo1D(atlasesCount, atlasHeight);
}
static void Convert2DTo1D(int atlasesCount, int atlas1DHeight) {
TexIds = new int[atlasesCount];
Utils.LogDebug("Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, TilesPerAtlas);
int index = 0;
using (FastBitmap atlas = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) { Utils.LogDebug("Loaded new atlas: {0} bmps, {1} per bmp", AtlasesCount, TilesPerAtlas);
for (int i = 0; i < TexIds.Length; i++) int index = 0, atlasHeight = TilesPerAtlas * tileSize;
Make1DTexture(i, atlas, atlas1DHeight, ref index);
using (FastBitmap atlas = new FastBitmap(Atlas2D.Atlas, true, true)) {
for (int i = 0; i < AtlasesCount; i++) {
Make1DTexture(i, atlas, atlasHeight, ref index);
}
} }
} }
static void Make1DTexture(int i, FastBitmap atlas, int atlas1DHeight, ref int index) { static void Make1DTexture(int i, FastBitmap atlas, int atlas1DHeight, ref int index) {
int tileSize = TerrainAtlas2D.TileSize; int tileSize = Atlas2D.TileSize;
using (Bitmap atlas1d = Platform.CreateBmp(tileSize, atlas1DHeight)) using (Bitmap atlas1d = Platform.CreateBmp(tileSize, atlas1DHeight))
using (FastBitmap dst = new FastBitmap(atlas1d, true, false)) using (FastBitmap dst = new FastBitmap(atlas1d, true, false))
{ {
for (int index1D = 0; index1D < TilesPerAtlas; index1D++) { for (int index1D = 0; index1D < TilesPerAtlas; index1D++) {
int atlasX = (index % TerrainAtlas2D.TilesPerRow) * tileSize; int atlasX = (index % Atlas2D.TilesPerRow) * tileSize;
int atlasY = (index / TerrainAtlas2D.TilesPerRow) * tileSize; int atlasY = (index / Atlas2D.TilesPerRow) * tileSize;
FastBitmap.MovePortion(atlasX, atlasY, FastBitmap.MovePortion(atlasX, atlasY,
0, index1D * tileSize, atlas, dst, tileSize); 0, index1D * tileSize, atlas, dst, tileSize);
@ -75,14 +104,14 @@ namespace ClassicalSharp.Textures {
int maxTexLoc = 0; int maxTexLoc = 0;
for (int i = 0; i < BlockInfo.textures.Length; i++) { for (int i = 0; i < BlockInfo.textures.Length; i++) {
maxTexLoc = Math.Max(maxTexLoc, BlockInfo.textures[i]); maxTexLoc = Math.Max(maxTexLoc, BlockInfo.textures[i]);
} }
return Get1DIndex(maxTexLoc) + 1; return Get1DIndex(maxTexLoc) + 1;
} }
public static void Dispose() { public static void Dispose() {
if (TexIds == null) return; if (TexIds == null) return;
for (int i = 0; i < TexIds.Length; i++) { for (int i = 0; i < AtlasesCount; i++) {
game.Graphics.DeleteTexture(ref TexIds[i]); game.Graphics.DeleteTexture(ref TexIds[i]);
} }
} }

View File

@ -1,44 +0,0 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using System.Drawing;
using ClassicalSharp.GraphicsAPI;
#if ANDROID
using Android.Graphics;
#endif
namespace ClassicalSharp {
/// <summary> Represents a 2D packed texture atlas, specifically for terrain.png. </summary>
public static class TerrainAtlas2D {
public const int TilesPerRow = 16, RowsCount = 16;
public static Bitmap Atlas;
public static int TileSize;
internal static Game game;
/// <summary> Updates the underlying atlas bitmap, fields, and texture. </summary>
public static void UpdateState(Bitmap bmp) {
Atlas = bmp;
TileSize = bmp.Width / TilesPerRow;
BlockInfo.RecalculateSpriteBB();
}
/// <summary> Creates a new texture that contains the tile at the specified index. </summary>
public static int LoadTile(int index) {
int size = TileSize;
using (FastBitmap atlas = new FastBitmap(Atlas, true, true))
using (Bitmap bmp = Platform.CreateBmp(size, size))
using (FastBitmap dst = new FastBitmap(bmp, true, false))
{
int x = index % TilesPerRow, y = index / TilesPerRow;
FastBitmap.MovePortion(x * size, y * size, 0, 0, atlas, dst, size);
return game.Graphics.CreateTexture(dst, false, game.Graphics.Mipmaps);
}
}
/// <summary> Disposes of the underlying atlas bitmap and texture. </summary>
public static void Dispose() {
if (Atlas != null) Atlas.Dispose();
}
}
}

View File

@ -116,7 +116,7 @@ namespace ClassicalSharp {
return new String(tmp, 0, len); return new String(tmp, 0, len);
} }
public void WordWrap(IDrawer2D drawer, string[] lines, int numLines, int lineLen) { public void WordWrap(string[] lines, int numLines, int lineLen) {
for (int i = 0; i < numLines; i++) { lines[i] = null; } for (int i = 0; i < numLines; i++) { lines[i] = null; }
int lineStart = 0, lineEnd; int lineStart = 0, lineEnd;

View File

@ -50,8 +50,8 @@ namespace OpenTK {
/// <exception cref="System.ArgumentOutOfRangeException">If width or height is less than 1.</exception> /// <exception cref="System.ArgumentOutOfRangeException">If width or height is less than 1.</exception>
/// <exception cref="System.ArgumentNullException">If mode or device is null.</exception> /// <exception cref="System.ArgumentNullException">If mode or device is null.</exception>
public NativeWindow(int width, int height, string title, GraphicsMode mode, DisplayDevice device) public NativeWindow(int width, int height, string title, GraphicsMode mode, DisplayDevice device)
: this(device.Bounds.Left + (device.Bounds.Width - width) / 2, : this(device.Bounds.Left + (device.Bounds.Width - width) / 2,
device.Bounds.Top + (device.Bounds.Height - height) / 2, device.Bounds.Top + (device.Bounds.Height - height) / 2,
width, height, title, mode, device) { } width, height, title, mode, device) { }
public NativeWindow(int width, int height, string title, GameWindowFlags flags, GraphicsMode mode, DisplayDevice device) : this(width, height, title, mode, device) {} public NativeWindow(int width, int height, string title, GameWindowFlags flags, GraphicsMode mode, DisplayDevice device) : this(width, height, title, mode, device) {}