Simplify updating atlases, move TextureAtlas1D to TerrainAtlas1D.

This commit is contained in:
UnknownShadow200 2015-05-27 19:47:09 +10:00
parent f5a55c50b8
commit f191885115
7 changed files with 50 additions and 41 deletions

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using OpenTK.Input;
using System;
using System.Collections.Generic;
using System.Drawing;
using OpenTK.Input;
namespace ClassicalSharp {

View File

@ -152,7 +152,7 @@
<Compile Include="Utils\Camera.cs" />
<Compile Include="Utils\FastBitmap.cs" />
<Compile Include="Utils\FastColour.cs" />
<Compile Include="Utils\TextureAtlas1D.cs" />
<Compile Include="Utils\TerrainAtlas1D.cs" />
<Compile Include="Utils\TerrainAtlas2D.cs" />
<Compile Include="Utils\TextureRectangle.cs" />
<Compile Include="Utils\UnsafeString.cs" />

View File

@ -29,8 +29,7 @@ namespace ClassicalSharp {
public BlockInfo BlockInfo;
public double accumulator;
public TerrainAtlas2D TerrainAtlas;
public TextureAtlas1D TerrainAtlas1D;
public int[] TerrainAtlas1DTexIds;
public TerrainAtlas1D TerrainAtlas1D;
public SkinType DefaultPlayerSkinType;
public int ChunkUpdates;
@ -95,17 +94,10 @@ namespace ClassicalSharp {
public int MouseSensitivity = 30;
void LoadAtlas( Bitmap bmp ) {
// Cleanup old atlas if applicable.
if( TerrainAtlas1DTexIds != null ) {
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}
}
TerrainAtlas.GraphicsApi = Graphics;
TerrainAtlas1D.Dispose();
TerrainAtlas.Dispose();
TerrainAtlas.UpdateState( bmp );
int size = Math.Min( 2048, Graphics.MaxTextureDimensions );
TerrainAtlas1DTexIds = TerrainAtlas1D.CreateFrom2DAtlas( Graphics, TerrainAtlas, size );
TerrainAtlas.UpdateState( bmp );
TerrainAtlas1D.UpdateState( TerrainAtlas );
}
public void ChangeTerrainAtlas( Bitmap newAtlas ) {
@ -127,8 +119,8 @@ namespace ClassicalSharp {
AsyncDownloader = new AsyncDownloader( skinServer );
PrintGraphicsInfo();
Bitmap terrainBmp = new Bitmap( "terrain.png" );
TerrainAtlas1D = new TextureAtlas1D();
TerrainAtlas = new TerrainAtlas2D();
TerrainAtlas1D = new TerrainAtlas1D( Graphics );
TerrainAtlas = new TerrainAtlas2D( Graphics );
LoadAtlas( terrainBmp );
BlockInfo = new BlockInfo();
BlockInfo.Init();
@ -284,9 +276,7 @@ namespace ClassicalSharp {
fpsScreen.Dispose();
SelectionManager.Dispose();
TerrainAtlas.Dispose();
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}
TerrainAtlas1D.Dispose();
ModelCache.Dispose();
for( int i = 0; i < NetPlayers.Length; i++ ) {
if( NetPlayers[i] != null ) {

View File

@ -6,12 +6,12 @@ namespace ClassicalSharp {
public partial class ChunkMeshBuilder {
DrawInfo1D[] drawInfoBuffer;
TextureAtlas1D atlas;
TerrainAtlas1D atlas;
int arraysCount = 0;
const int maxIndices = 65536;
void TerrainAtlasChanged( object sender, EventArgs e ) {
int newArraysCount = Window.TerrainAtlas1DTexIds.Length;
int newArraysCount = Window.TerrainAtlas1D.TexIds.Length;
if( arraysCount > 0 && arraysCount != newArraysCount ) {
Array.Resize( ref drawInfoBuffer, newArraysCount );
for( int i = arraysCount; i < drawInfoBuffer.Length; i++ ) {
@ -157,7 +157,7 @@ namespace ClassicalSharp {
void PreStretchTiles( int x1, int y1, int z1 ) {
invVerElementSize = Window.TerrainAtlas1D.invElementSize;
arraysCount = Window.TerrainAtlas1DTexIds.Length;
arraysCount = Window.TerrainAtlas1D.TexIds.Length;
atlas = Window.TerrainAtlas1D;
if( drawInfoBuffer == null ) {

View File

@ -50,7 +50,7 @@ namespace ClassicalSharp {
public MapRenderer( Game window ) {
Window = window;
_1Dcount = window.TerrainAtlas1DTexIds.Length;
_1Dcount = window.TerrainAtlas1D.TexIds.Length;
builder = new ChunkMeshBuilder( window );
Graphics = window.Graphics;
elementsPerBitmap = window.TerrainAtlas1D.elementsPerBitmap;
@ -83,7 +83,7 @@ namespace ClassicalSharp {
}
void TerrainAtlasChanged( object sender, EventArgs e ) {
_1Dcount = Window.TerrainAtlas1DTexIds.Length;
_1Dcount = Window.TerrainAtlas1D.TexIds.Length;
bool fullResetRequired = elementsPerBitmap != Window.TerrainAtlas1D.elementsPerBitmap;
if( fullResetRequired ) {
Refresh();
@ -197,6 +197,7 @@ namespace ClassicalSharp {
if( chunks == null ) return;
UpdateSortOrder();
UpdateChunks();
int[] texIds = Window.TerrainAtlas1D.TexIds;
// Render solid and fully transparent to fill depth buffer.
// These blocks are treated as having an alpha value of either none or full.
@ -205,12 +206,12 @@ namespace ClassicalSharp {
Graphics.AlphaTest = true;
Graphics.FaceCulling = true;
for( int batch = 0; batch < _1Dcount; batch++ ) {
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
Graphics.Bind2DTexture( texIds[batch] );
RenderSolidBatch( batch );
}
Graphics.FaceCulling = false;
for( int batch = 0; batch < _1Dcount; batch++ ) {
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
Graphics.Bind2DTexture( texIds[batch] );
RenderSpriteBatch( batch );
}
Graphics.AlphaTest = false;
@ -235,7 +236,7 @@ namespace ClassicalSharp {
Graphics.Texturing = true;
Graphics.ColourMask( true, true, true, true );
for( int batch = 0; batch < _1Dcount; batch++ ) {
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
Graphics.Bind2DTexture( texIds[batch] );
RenderTranslucentBatch( batch );
}
Graphics.DepthTestFunc( CompareFunc.Less );

View File

@ -4,11 +4,17 @@ using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp {
public class TextureAtlas1D {
public class TerrainAtlas1D : IDisposable {
int usedElementsPerAtlas1D;
internal int elementsPerBitmap;
public float invElementSize;
public int[] TexIds;
IGraphicsApi graphics;
public TerrainAtlas1D( IGraphicsApi graphics ) {
this.graphics = graphics;
}
public TextureRectangle GetTexRec( int texId, int uCount, out int index ) {
index = texId / usedElementsPerAtlas1D;
@ -24,21 +30,22 @@ namespace ClassicalSharp {
return texId % usedElementsPerAtlas1D;
}
public int[] CreateFrom2DAtlas( IGraphicsApi graphics, TerrainAtlas2D atlas2D, int maxVerSize ) {
public void UpdateState( TerrainAtlas2D atlas2D ) {
int maxVerSize = Math.Min( 2048, graphics.MaxTextureDimensions );
int verElements = maxVerSize / atlas2D.elementSize;
int totalElements = atlas2D.UsedRowsCount * TerrainAtlas2D.ElementsPerRow;
int elemSize = atlas2D.elementSize;
int atlasesCount = totalElements / verElements + ( totalElements % verElements != 0 ? 1 : 0 );
usedElementsPerAtlas1D = Math.Min( verElements, totalElements ); // in case verElements > totalElements
usedElementsPerAtlas1D = Math.Min( verElements, totalElements );
int atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.elementSize );
int index = 0;
int[] texIds = new int[atlasesCount];
TexIds = new int[atlasesCount];
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, usedElementsPerAtlas1D );
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true ) ) {
for( int i = 0; i < texIds.Length; i++ ) {
for( int i = 0; i < TexIds.Length; i++ ) {
Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight );
using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
for( int y_1D = 0; y_1D < usedElementsPerAtlas1D; y_1D++ ) {
@ -47,14 +54,21 @@ namespace ClassicalSharp {
Utils.MovePortion( x * elemSize, y * elemSize, 0, y_1D * elemSize, atlas, dst, elemSize );
index++;
}
texIds[i] = graphics.LoadTexture( dst );
TexIds[i] = graphics.LoadTexture( dst );
}
atlas1d.Dispose();
}
}
elementsPerBitmap = atlas1DHeight / atlas2D.elementSize;
invElementSize = 1f / elementsPerBitmap;
return texIds;
}
public void Dispose() {
if( TexIds != null ) {
for( int i = 0; i < TexIds.Length; i++ ) {
graphics.DeleteTexture( ref TexIds[i] );
}
}
}
}
}

View File

@ -20,15 +20,19 @@ namespace ClassicalSharp {
public readonly int UsedRowsCount = 5;
public Bitmap AtlasBitmap;
public int elementSize;
public IGraphicsApi GraphicsApi;
public int TexId;
IGraphicsApi graphics;
public TerrainAtlas2D( IGraphicsApi graphics ) {
this.graphics = graphics;
}
public void UpdateState( Bitmap bmp ) {
AtlasBitmap = bmp;
elementSize = bmp.Width >> 4;
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
MakeOptimisedTexture( fastBmp );
TexId = GraphicsApi.LoadTexture( fastBmp );
TexId = graphics.LoadTexture( fastBmp );
}
}
@ -39,7 +43,7 @@ namespace ClassicalSharp {
using( Bitmap bmp = new Bitmap( elementSize, elementSize ) ) {
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
Utils.MovePortion( x * elementSize, y * elementSize, 0, 0, atlas, dst, elementSize );
return GraphicsApi.LoadTexture( dst );
return graphics.LoadTexture( dst );
}
}
}
@ -55,7 +59,7 @@ namespace ClassicalSharp {
if( AtlasBitmap != null ) {
AtlasBitmap.Dispose();
}
GraphicsApi.DeleteTexture( ref TexId );
graphics.DeleteTexture( ref TexId );
}
static ushort[] rowFlags = { 0xFFFF, 0xFFEE, 0xFFE0, 0xFFE0, 0xFFFF, 0xFA00 };