mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 01:55:19 -04:00
Simplify updating atlases, move TextureAtlas1D to TerrainAtlas1D.
This commit is contained in:
parent
f5a55c50b8
commit
f191885115
@ -152,7 +152,7 @@
|
|||||||
<Compile Include="Utils\Camera.cs" />
|
<Compile Include="Utils\Camera.cs" />
|
||||||
<Compile Include="Utils\FastBitmap.cs" />
|
<Compile Include="Utils\FastBitmap.cs" />
|
||||||
<Compile Include="Utils\FastColour.cs" />
|
<Compile Include="Utils\FastColour.cs" />
|
||||||
<Compile Include="Utils\TextureAtlas1D.cs" />
|
<Compile Include="Utils\TerrainAtlas1D.cs" />
|
||||||
<Compile Include="Utils\TerrainAtlas2D.cs" />
|
<Compile Include="Utils\TerrainAtlas2D.cs" />
|
||||||
<Compile Include="Utils\TextureRectangle.cs" />
|
<Compile Include="Utils\TextureRectangle.cs" />
|
||||||
<Compile Include="Utils\UnsafeString.cs" />
|
<Compile Include="Utils\UnsafeString.cs" />
|
||||||
|
22
Game/Game.cs
22
Game/Game.cs
@ -29,8 +29,7 @@ namespace ClassicalSharp {
|
|||||||
public BlockInfo BlockInfo;
|
public BlockInfo BlockInfo;
|
||||||
public double accumulator;
|
public double accumulator;
|
||||||
public TerrainAtlas2D TerrainAtlas;
|
public TerrainAtlas2D TerrainAtlas;
|
||||||
public TextureAtlas1D TerrainAtlas1D;
|
public TerrainAtlas1D TerrainAtlas1D;
|
||||||
public int[] TerrainAtlas1DTexIds;
|
|
||||||
public SkinType DefaultPlayerSkinType;
|
public SkinType DefaultPlayerSkinType;
|
||||||
public int ChunkUpdates;
|
public int ChunkUpdates;
|
||||||
|
|
||||||
@ -95,17 +94,10 @@ namespace ClassicalSharp {
|
|||||||
public int MouseSensitivity = 30;
|
public int MouseSensitivity = 30;
|
||||||
|
|
||||||
void LoadAtlas( Bitmap bmp ) {
|
void LoadAtlas( Bitmap bmp ) {
|
||||||
// Cleanup old atlas if applicable.
|
TerrainAtlas1D.Dispose();
|
||||||
if( TerrainAtlas1DTexIds != null ) {
|
|
||||||
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
|
|
||||||
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerrainAtlas.GraphicsApi = Graphics;
|
|
||||||
TerrainAtlas.Dispose();
|
TerrainAtlas.Dispose();
|
||||||
TerrainAtlas.UpdateState( bmp );
|
TerrainAtlas.UpdateState( bmp );
|
||||||
int size = Math.Min( 2048, Graphics.MaxTextureDimensions );
|
TerrainAtlas1D.UpdateState( TerrainAtlas );
|
||||||
TerrainAtlas1DTexIds = TerrainAtlas1D.CreateFrom2DAtlas( Graphics, TerrainAtlas, size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeTerrainAtlas( Bitmap newAtlas ) {
|
public void ChangeTerrainAtlas( Bitmap newAtlas ) {
|
||||||
@ -127,8 +119,8 @@ namespace ClassicalSharp {
|
|||||||
AsyncDownloader = new AsyncDownloader( skinServer );
|
AsyncDownloader = new AsyncDownloader( skinServer );
|
||||||
PrintGraphicsInfo();
|
PrintGraphicsInfo();
|
||||||
Bitmap terrainBmp = new Bitmap( "terrain.png" );
|
Bitmap terrainBmp = new Bitmap( "terrain.png" );
|
||||||
TerrainAtlas1D = new TextureAtlas1D();
|
TerrainAtlas1D = new TerrainAtlas1D( Graphics );
|
||||||
TerrainAtlas = new TerrainAtlas2D();
|
TerrainAtlas = new TerrainAtlas2D( Graphics );
|
||||||
LoadAtlas( terrainBmp );
|
LoadAtlas( terrainBmp );
|
||||||
BlockInfo = new BlockInfo();
|
BlockInfo = new BlockInfo();
|
||||||
BlockInfo.Init();
|
BlockInfo.Init();
|
||||||
@ -284,9 +276,7 @@ namespace ClassicalSharp {
|
|||||||
fpsScreen.Dispose();
|
fpsScreen.Dispose();
|
||||||
SelectionManager.Dispose();
|
SelectionManager.Dispose();
|
||||||
TerrainAtlas.Dispose();
|
TerrainAtlas.Dispose();
|
||||||
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
|
TerrainAtlas1D.Dispose();
|
||||||
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
|
|
||||||
}
|
|
||||||
ModelCache.Dispose();
|
ModelCache.Dispose();
|
||||||
for( int i = 0; i < NetPlayers.Length; i++ ) {
|
for( int i = 0; i < NetPlayers.Length; i++ ) {
|
||||||
if( NetPlayers[i] != null ) {
|
if( NetPlayers[i] != null ) {
|
||||||
|
@ -6,12 +6,12 @@ namespace ClassicalSharp {
|
|||||||
public partial class ChunkMeshBuilder {
|
public partial class ChunkMeshBuilder {
|
||||||
|
|
||||||
DrawInfo1D[] drawInfoBuffer;
|
DrawInfo1D[] drawInfoBuffer;
|
||||||
TextureAtlas1D atlas;
|
TerrainAtlas1D atlas;
|
||||||
int arraysCount = 0;
|
int arraysCount = 0;
|
||||||
const int maxIndices = 65536;
|
const int maxIndices = 65536;
|
||||||
|
|
||||||
void TerrainAtlasChanged( object sender, EventArgs e ) {
|
void TerrainAtlasChanged( object sender, EventArgs e ) {
|
||||||
int newArraysCount = Window.TerrainAtlas1DTexIds.Length;
|
int newArraysCount = Window.TerrainAtlas1D.TexIds.Length;
|
||||||
if( arraysCount > 0 && arraysCount != newArraysCount ) {
|
if( arraysCount > 0 && arraysCount != newArraysCount ) {
|
||||||
Array.Resize( ref drawInfoBuffer, newArraysCount );
|
Array.Resize( ref drawInfoBuffer, newArraysCount );
|
||||||
for( int i = arraysCount; i < drawInfoBuffer.Length; i++ ) {
|
for( int i = arraysCount; i < drawInfoBuffer.Length; i++ ) {
|
||||||
@ -157,7 +157,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
void PreStretchTiles( int x1, int y1, int z1 ) {
|
void PreStretchTiles( int x1, int y1, int z1 ) {
|
||||||
invVerElementSize = Window.TerrainAtlas1D.invElementSize;
|
invVerElementSize = Window.TerrainAtlas1D.invElementSize;
|
||||||
arraysCount = Window.TerrainAtlas1DTexIds.Length;
|
arraysCount = Window.TerrainAtlas1D.TexIds.Length;
|
||||||
atlas = Window.TerrainAtlas1D;
|
atlas = Window.TerrainAtlas1D;
|
||||||
|
|
||||||
if( drawInfoBuffer == null ) {
|
if( drawInfoBuffer == null ) {
|
||||||
|
@ -50,7 +50,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public MapRenderer( Game window ) {
|
public MapRenderer( Game window ) {
|
||||||
Window = window;
|
Window = window;
|
||||||
_1Dcount = window.TerrainAtlas1DTexIds.Length;
|
_1Dcount = window.TerrainAtlas1D.TexIds.Length;
|
||||||
builder = new ChunkMeshBuilder( window );
|
builder = new ChunkMeshBuilder( window );
|
||||||
Graphics = window.Graphics;
|
Graphics = window.Graphics;
|
||||||
elementsPerBitmap = window.TerrainAtlas1D.elementsPerBitmap;
|
elementsPerBitmap = window.TerrainAtlas1D.elementsPerBitmap;
|
||||||
@ -83,7 +83,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TerrainAtlasChanged( object sender, EventArgs e ) {
|
void TerrainAtlasChanged( object sender, EventArgs e ) {
|
||||||
_1Dcount = Window.TerrainAtlas1DTexIds.Length;
|
_1Dcount = Window.TerrainAtlas1D.TexIds.Length;
|
||||||
bool fullResetRequired = elementsPerBitmap != Window.TerrainAtlas1D.elementsPerBitmap;
|
bool fullResetRequired = elementsPerBitmap != Window.TerrainAtlas1D.elementsPerBitmap;
|
||||||
if( fullResetRequired ) {
|
if( fullResetRequired ) {
|
||||||
Refresh();
|
Refresh();
|
||||||
@ -197,6 +197,7 @@ namespace ClassicalSharp {
|
|||||||
if( chunks == null ) return;
|
if( chunks == null ) return;
|
||||||
UpdateSortOrder();
|
UpdateSortOrder();
|
||||||
UpdateChunks();
|
UpdateChunks();
|
||||||
|
int[] texIds = Window.TerrainAtlas1D.TexIds;
|
||||||
|
|
||||||
// Render solid and fully transparent to fill depth buffer.
|
// Render solid and fully transparent to fill depth buffer.
|
||||||
// These blocks are treated as having an alpha value of either none or full.
|
// These blocks are treated as having an alpha value of either none or full.
|
||||||
@ -205,12 +206,12 @@ namespace ClassicalSharp {
|
|||||||
Graphics.AlphaTest = true;
|
Graphics.AlphaTest = true;
|
||||||
Graphics.FaceCulling = true;
|
Graphics.FaceCulling = true;
|
||||||
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
||||||
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
|
Graphics.Bind2DTexture( texIds[batch] );
|
||||||
RenderSolidBatch( batch );
|
RenderSolidBatch( batch );
|
||||||
}
|
}
|
||||||
Graphics.FaceCulling = false;
|
Graphics.FaceCulling = false;
|
||||||
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
||||||
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
|
Graphics.Bind2DTexture( texIds[batch] );
|
||||||
RenderSpriteBatch( batch );
|
RenderSpriteBatch( batch );
|
||||||
}
|
}
|
||||||
Graphics.AlphaTest = false;
|
Graphics.AlphaTest = false;
|
||||||
@ -235,7 +236,7 @@ namespace ClassicalSharp {
|
|||||||
Graphics.Texturing = true;
|
Graphics.Texturing = true;
|
||||||
Graphics.ColourMask( true, true, true, true );
|
Graphics.ColourMask( true, true, true, true );
|
||||||
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
||||||
Graphics.Bind2DTexture( Window.TerrainAtlas1DTexIds[batch] );
|
Graphics.Bind2DTexture( texIds[batch] );
|
||||||
RenderTranslucentBatch( batch );
|
RenderTranslucentBatch( batch );
|
||||||
}
|
}
|
||||||
Graphics.DepthTestFunc( CompareFunc.Less );
|
Graphics.DepthTestFunc( CompareFunc.Less );
|
||||||
|
@ -4,11 +4,17 @@ using ClassicalSharp.GraphicsAPI;
|
|||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public class TextureAtlas1D {
|
public class TerrainAtlas1D : IDisposable {
|
||||||
|
|
||||||
int usedElementsPerAtlas1D;
|
int usedElementsPerAtlas1D;
|
||||||
internal int elementsPerBitmap;
|
internal int elementsPerBitmap;
|
||||||
public float invElementSize;
|
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 ) {
|
public TextureRectangle GetTexRec( int texId, int uCount, out int index ) {
|
||||||
index = texId / usedElementsPerAtlas1D;
|
index = texId / usedElementsPerAtlas1D;
|
||||||
@ -24,21 +30,22 @@ namespace ClassicalSharp {
|
|||||||
return texId % usedElementsPerAtlas1D;
|
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 verElements = maxVerSize / atlas2D.elementSize;
|
||||||
int totalElements = atlas2D.UsedRowsCount * TerrainAtlas2D.ElementsPerRow;
|
int totalElements = atlas2D.UsedRowsCount * TerrainAtlas2D.ElementsPerRow;
|
||||||
int elemSize = atlas2D.elementSize;
|
int elemSize = atlas2D.elementSize;
|
||||||
|
|
||||||
int atlasesCount = totalElements / verElements + ( totalElements % verElements != 0 ? 1 : 0 );
|
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 atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.elementSize );
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int[] texIds = new int[atlasesCount];
|
TexIds = new int[atlasesCount];
|
||||||
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, usedElementsPerAtlas1D );
|
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, usedElementsPerAtlas1D );
|
||||||
|
|
||||||
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true ) ) {
|
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 );
|
Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight );
|
||||||
using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
|
using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
|
||||||
for( int y_1D = 0; y_1D < usedElementsPerAtlas1D; y_1D++ ) {
|
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 );
|
Utils.MovePortion( x * elemSize, y * elemSize, 0, y_1D * elemSize, atlas, dst, elemSize );
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
texIds[i] = graphics.LoadTexture( dst );
|
TexIds[i] = graphics.LoadTexture( dst );
|
||||||
}
|
}
|
||||||
atlas1d.Dispose();
|
atlas1d.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elementsPerBitmap = atlas1DHeight / atlas2D.elementSize;
|
elementsPerBitmap = atlas1DHeight / atlas2D.elementSize;
|
||||||
invElementSize = 1f / elementsPerBitmap;
|
invElementSize = 1f / elementsPerBitmap;
|
||||||
return texIds;
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
if( TexIds != null ) {
|
||||||
|
for( int i = 0; i < TexIds.Length; i++ ) {
|
||||||
|
graphics.DeleteTexture( ref TexIds[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,15 +20,19 @@ namespace ClassicalSharp {
|
|||||||
public readonly int UsedRowsCount = 5;
|
public readonly int UsedRowsCount = 5;
|
||||||
public Bitmap AtlasBitmap;
|
public Bitmap AtlasBitmap;
|
||||||
public int elementSize;
|
public int elementSize;
|
||||||
public IGraphicsApi GraphicsApi;
|
|
||||||
public int TexId;
|
public int TexId;
|
||||||
|
IGraphicsApi graphics;
|
||||||
|
|
||||||
|
public TerrainAtlas2D( IGraphicsApi graphics ) {
|
||||||
|
this.graphics = graphics;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateState( Bitmap bmp ) {
|
public void UpdateState( Bitmap bmp ) {
|
||||||
AtlasBitmap = bmp;
|
AtlasBitmap = bmp;
|
||||||
elementSize = bmp.Width >> 4;
|
elementSize = bmp.Width >> 4;
|
||||||
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
|
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
|
||||||
MakeOptimisedTexture( fastBmp );
|
MakeOptimisedTexture( fastBmp );
|
||||||
TexId = GraphicsApi.LoadTexture( fastBmp );
|
TexId = graphics.LoadTexture( fastBmp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +43,7 @@ namespace ClassicalSharp {
|
|||||||
using( Bitmap bmp = new Bitmap( elementSize, elementSize ) ) {
|
using( Bitmap bmp = new Bitmap( elementSize, elementSize ) ) {
|
||||||
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
|
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
|
||||||
Utils.MovePortion( x * elementSize, y * elementSize, 0, 0, atlas, dst, elementSize );
|
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 ) {
|
if( AtlasBitmap != null ) {
|
||||||
AtlasBitmap.Dispose();
|
AtlasBitmap.Dispose();
|
||||||
}
|
}
|
||||||
GraphicsApi.DeleteTexture( ref TexId );
|
graphics.DeleteTexture( ref TexId );
|
||||||
}
|
}
|
||||||
|
|
||||||
static ushort[] rowFlags = { 0xFFFF, 0xFFEE, 0xFFE0, 0xFFE0, 0xFFFF, 0xFA00 };
|
static ushort[] rowFlags = { 0xFFFF, 0xFFEE, 0xFFE0, 0xFFE0, 0xFFFF, 0xFA00 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user