Block break particles should account for block height, more work on rain particles.

This commit is contained in:
UnknownShadow200 2015-11-22 23:58:10 +11:00
parent e198ef367f
commit 0defe3b66c
12 changed files with 108 additions and 57 deletions

View File

@ -81,11 +81,13 @@ namespace ClassicalSharp {
public override void Init() { public override void Init() {
int fontSize = (int)(12 * game.GuiScale() * game.ChatScale); int fontSize = (int)(12 * game.GuiScale() * game.ChatScale);
Utils.Clamp( ref fontSize, 8, 60 ); Utils.Clamp( ref fontSize, 8, 60 );
chatFont = new Font( "Arial", fontSize ); chatFont = new Font( "Arial", fontSize );
chatInputFont = new Font( "Arial", fontSize, FontStyle.Bold ); chatInputFont = new Font( "Arial", fontSize, FontStyle.Bold );
chatUnderlineFont = new Font( "Arial", fontSize, FontStyle.Underline ); chatUnderlineFont = new Font( "Arial", fontSize, FontStyle.Underline );
announcementFont = new Font( "Arial", 14 );
fontSize = (int)(14 * game.GuiScale());
Utils.Clamp( ref fontSize, 8, 60 );
announcementFont = new Font( "Arial", fontSize );
blockSize = (int)(40 * game.GuiScale()); blockSize = (int)(40 * game.GuiScale());
textInput = new TextInputWidget( game, chatFont, chatInputFont ); textInput = new TextInputWidget( game, chatFont, chatInputFont );

View File

@ -3,7 +3,7 @@ using OpenTK;
namespace ClassicalSharp.Particles { namespace ClassicalSharp.Particles {
public abstract class Particle : IDisposable { public abstract class Particle {
public Vector3 Position; public Vector3 Position;
public Vector3 Velocity; public Vector3 Velocity;
@ -13,8 +13,6 @@ namespace ClassicalSharp.Particles {
public abstract void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ); public abstract void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index );
public abstract void Dispose();
public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) { public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) {
this.game = game; this.game = game;
Position = lastPos = nextPos = pos; Position = lastPos = nextPos = pos;

View File

@ -7,54 +7,71 @@ namespace ClassicalSharp.Particles {
public class ParticleManager : IDisposable { public class ParticleManager : IDisposable {
List<Particle> particles = new List<Particle>(); public int ParticlesTexId;
List<Particle> terrainParticles = new List<Particle>();
List<Particle> rainParticles = new List<Particle>();
Game game; Game game;
IGraphicsApi graphics; Random rnd;
int vb; int vb;
public ParticleManager( Game game ) { public ParticleManager( Game game ) {
this.game = game; this.game = game;
graphics = game.Graphics; rnd = new Random();
vb = graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 1000 ); vb = game.Graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 1000 );
} }
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[0]; VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[0];
public void Render( double delta, float t ) { public void Render( double delta, float t ) {
if( particles.Count == 0 ) return; if( terrainParticles.Count == 0 && rainParticles.Count == 0 ) return;
IGraphicsApi graphics = game.Graphics;
int count = particles.Count * 4;
if( count > vertices.Length ) {
vertices = new VertexPos3fTex2fCol4b[count];
}
int index = 0;
for( int i = 0; i < particles.Count; i++ ) {
particles[i].Render( delta, t, vertices, ref index );
}
graphics.Texturing = true; graphics.Texturing = true;
graphics.BindTexture( game.TerrainAtlas.TexId );
graphics.AlphaTest = true; graphics.AlphaTest = true;
count = Math.Min( count, 1000 );
graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b ); graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b );
int count = RenderParticles( terrainParticles, delta, t );
if( count > 0 ) {
graphics.BindTexture( game.TerrainAtlas.TexId );
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 ); graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 );
}
count = 0;//RenderParticles( rainParticles, delta, t );
if( count > 0 ) {
graphics.BindTexture( ParticlesTexId );
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 );
}
graphics.AlphaTest = false; graphics.AlphaTest = false;
graphics.Texturing = false; graphics.Texturing = false;
} }
int RenderParticles( List<Particle> particles, double delta, float t ) {
int count = particles.Count * 4;
if( count > vertices.Length )
vertices = new VertexPos3fTex2fCol4b[count];
int index = 0;
for( int i = 0; i < particles.Count; i++ )
particles[i].Render( delta, t, vertices, ref index );
return Math.Min( count, 1000 );
}
public void Tick( double delta ) { public void Tick( double delta ) {
TickParticles( terrainParticles, delta );
//TickParticles( rainParticles, delta );
}
void TickParticles( List<Particle> particles, double delta ) {
for( int i = 0; i < particles.Count; i++ ) { for( int i = 0; i < particles.Count; i++ ) {
Particle particle = particles[i]; Particle particle = particles[i];
if( particle.Tick( delta ) ) { if( particle.Tick( delta ) ) {
particles.RemoveAt( i ); particles.RemoveAt( i );
i--; i--;
particle.Dispose();
} }
} }
} }
public void Dispose() { public void Dispose() {
graphics.DeleteDynamicVb( vb ); game.Graphics.DeleteDynamicVb( vb );
game.Graphics.DeleteTexture( ref ParticlesTexId );
} }
public void BreakBlockEffect( Vector3I position, byte block ) { public void BreakBlockEffect( Vector3I position, byte block ) {
@ -62,30 +79,50 @@ namespace ClassicalSharp.Particles {
int texLoc = game.BlockInfo.GetTextureLoc( block, TileSide.Left ); int texLoc = game.BlockInfo.GetTextureLoc( block, TileSide.Left );
TextureRec rec = game.TerrainAtlas.GetTexRec( texLoc ); TextureRec rec = game.TerrainAtlas.GetTexRec( texLoc );
float invSize = TerrainAtlas2D.invElementSize; const float invSize = TerrainAtlas2D.invElementSize;
int cellsCountX = (int)( 0.25f / invSize ); const int cellsCount = (int)((1/4f) / invSize);
int cellsCountY = (int)( 0.25f / invSize ); const float elemSize = invSize / 4f;
float elementXSize = invSize * 0.25f; float blockHeight = game.BlockInfo.Height[block];
float elementYSize = invSize * 0.25f;
Random rnd = new Random();
for( int i = 0; i < 25; i++ ) { for( int i = 0; i < 25; i++ ) {
double velX = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/; double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4]
double velZ = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/; double velZ = rnd.NextDouble() * 0.8 - 0.4;
double velY = ( rnd.NextDouble() + 0.25 ) * game.BlockInfo.Height[block]; double velY = rnd.NextDouble() + 0.2;
Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ ); Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ );
double xOffset = rnd.NextDouble() - 0.125;
double yOffset = rnd.NextDouble() - 0.125; double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5]
double zOffset = rnd.NextDouble() - 0.125; double yOffset = (rnd.NextDouble() - 0.125) * blockHeight;
Vector3 pos = startPos + new Vector3( (float)xOffset, (float)yOffset, (float)zOffset ); double zOffset = rnd.NextDouble() - 0.5;
Vector3 pos = startPos + new Vector3( 0.5f + (float)xOffset,
(float)yOffset, 0.5f + (float)zOffset );
TextureRec particleRec = rec; TextureRec particleRec = rec;
particleRec.U1 = (float)( rec.U1 + rnd.Next( 0, cellsCountX ) * elementXSize ); particleRec.U1 = rec.U1 + rnd.Next( 0, cellsCount ) * elemSize;
particleRec.V1 = (float)( rec.V1 + rnd.Next( 0, cellsCountY ) * elementYSize ); particleRec.V1 = rec.V1 + rnd.Next( 0, cellsCount ) * elemSize;
particleRec.U2 = particleRec.U1 + elementXSize; particleRec.U2 = particleRec.U1 + elemSize;
particleRec.V2 = particleRec.V1 + elementYSize; particleRec.V2 = particleRec.V1 + elemSize;
double life = 1.5 - rnd.NextDouble(); double life = 1.5 - rnd.NextDouble();
particles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) ); terrainParticles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) );
}
}
public void AddRainParticle( Vector3 pos ) {
Vector3 startPos = pos;
for( int i = 0; i < 5; i++ ) {
double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4]
double velZ = rnd.NextDouble() * 0.8 - 0.4;
double velY = rnd.NextDouble() + 0.2;
Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ );
double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5]
double yOffset = rnd.NextDouble() - 0.125;
double zOffset = rnd.NextDouble() - 0.5;
pos = startPos + new Vector3( 0.5f + (float)xOffset,
(float)yOffset, 0.5f + (float)zOffset );
double life = 1.5 - rnd.NextDouble();
rainParticles.Add( new RainParticle( game, pos, velocity, life ) );
} }
} }
} }

View File

@ -24,8 +24,5 @@ namespace ClassicalSharp.Particles {
vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col );
vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col );
} }
public override void Dispose() {
}
} }
} }

View File

@ -25,8 +25,5 @@ namespace ClassicalSharp.Particles {
vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col );
vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col );
} }
public override void Dispose() {
}
} }
} }

View File

@ -82,7 +82,7 @@ namespace ClassicalSharp {
last = now; last = now;
if( writer != null ) { if( writer != null ) {
string data = text;//Utils.StripColours( text ); string data = Utils.StripColours( text );
string entry = now.ToString( "[yyyy-MM-dd HH:mm:ss] " ) + data; string entry = now.ToString( "[yyyy-MM-dd HH:mm:ss] " ) + data;
writer.WriteLine( entry ); writer.WriteLine( entry );
} }

View File

@ -126,6 +126,7 @@ namespace ClassicalSharp {
ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 ); ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 );
InputHandler = new InputHandler( this ); InputHandler = new InputHandler( this );
Chat = new ChatLog( this ); Chat = new ChatLog( this );
ParticleManager = new ParticleManager( this );
HudScale = Options.GetFloat( OptionsKey.HudScale, 0.25f, 5f, 1f ); HudScale = Options.GetFloat( OptionsKey.HudScale, 0.25f, 5f, 1f );
ChatScale = Options.GetFloat( OptionsKey.ChatScale, 0.35f, 5f, 1f ); ChatScale = Options.GetFloat( OptionsKey.ChatScale, 0.35f, 5f, 1f );
defaultIb = Graphics.MakeDefaultIb(); defaultIb = Graphics.MakeDefaultIb();
@ -173,7 +174,6 @@ namespace ClassicalSharp {
CommandManager = new CommandManager(); CommandManager = new CommandManager();
CommandManager.Init( this ); CommandManager.Init( this );
SelectionManager = new SelectionManager( this ); SelectionManager = new SelectionManager( this );
ParticleManager = new ParticleManager( this );
WeatherRenderer = new WeatherRenderer( this ); WeatherRenderer = new WeatherRenderer( this );
WeatherRenderer.Init(); WeatherRenderer.Init();
BlockHandRenderer = new BlockHandRenderer( this ); BlockHandRenderer = new BlockHandRenderer( this );

View File

@ -23,6 +23,7 @@ namespace ClassicalSharp {
float vOffset; float vOffset;
const int extent = 4; const int extent = 4;
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * (extent * 2 + 1) * (extent * 2 + 1)]; VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * (extent * 2 + 1) * (extent * 2 + 1)];
double rainAcc;
public void Render( double deltaTime ) { public void Render( double deltaTime ) {
Weather weather = map.Weather; Weather weather = map.Weather;
@ -33,6 +34,7 @@ namespace ClassicalSharp {
Vector3I pos = Vector3I.Floor( game.LocalPlayer.Position ); Vector3I pos = Vector3I.Floor( game.LocalPlayer.Position );
float speed = weather == Weather.Rainy ? 1f : 0.25f; float speed = weather == Weather.Rainy ? 1f : 0.25f;
vOffset = -(float)game.accumulator * speed; vOffset = -(float)game.accumulator * speed;
rainAcc += deltaTime;
int index = 0; int index = 0;
graphics.AlphaBlending = true; graphics.AlphaBlending = true;
@ -44,10 +46,14 @@ namespace ClassicalSharp {
float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY; float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY;
if( height <= 0 ) continue; if( height <= 0 ) continue;
//if( rainAcc >= 3 )
// game.ParticleManager.AddRainParticle( new Vector3( pos.X + dx, rainY, pos.Z + dz ) );
col.A = (byte)Math.Max( 0, AlphaAt( dx * dx + dz * dz ) ); col.A = (byte)Math.Max( 0, AlphaAt( dx * dx + dz * dz ) );
MakeRainForSquare( pos.X + dx, rainY, height, pos.Z + dz, col, ref index ); MakeRainForSquare( pos.X + dx, rainY, height, pos.Z + dz, col, ref index );
} }
} }
if( rainAcc >= 3 )
rainAcc = 0;
// fixes crashing on nVidia cards in OpenGL builds. // fixes crashing on nVidia cards in OpenGL builds.
if( index > 0 ) { if( index > 0 ) {

View File

@ -78,6 +78,9 @@ namespace ClassicalSharp.TexturePack {
StreamReader reader = new StreamReader( stream ); StreamReader reader = new StreamReader( stream );
game.Animations.ReadAnimationsDescription( reader ); game.Animations.ReadAnimationsDescription( reader );
break; break;
case "particles.png":
UpdateTexture( ref game.ParticleManager.ParticlesTexId,
stream, false ); break;
case "default.png": case "default.png":
SetFontBitmap( game, stream ); SetFontBitmap( game, stream );
break; break;

View File

@ -40,6 +40,17 @@ namespace Launcher2 {
protected override void OnRemovedChar() { FilterList(); } protected override void OnRemovedChar() { FilterList(); }
protected override void KeyDown( object sender, KeyboardKeyEventArgs e ) {
if( e.Key == Key.Enter ) {
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
if( table.Count == 1 )
widgets[3].Text = table.usedEntries[0].Hash;
ConnectToServer( 0, 0 );
} else {
base.KeyDown( sender, e );
}
}
void FilterList() { void FilterList() {
if( lastInput == widgets[1] ) { if( lastInput == widgets[1] ) {
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex]; LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];

View File

@ -24,7 +24,7 @@ namespace Launcher2 {
game.Window.Keyboard.KeyRepeat = true; game.Window.Keyboard.KeyRepeat = true;
} }
protected void KeyDown( object sender, KeyboardKeyEventArgs e ) { protected virtual void KeyDown( object sender, KeyboardKeyEventArgs e ) {
if( lastInput != null && e.Key == Key.BackSpace ) { if( lastInput != null && e.Key == Key.BackSpace ) {
if( lastInput.RemoveChar() ) { if( lastInput.RemoveChar() ) {
RedrawLastInput(); RedrawLastInput();

View File

@ -15,7 +15,7 @@ namespace Launcher2 {
public Action<string> SelectedChanged; public Action<string> SelectedChanged;
public string SelectedHash; public string SelectedHash;
TableEntry[] entries, usedEntries; internal TableEntry[] entries, usedEntries;
internal List<ServerListEntry> servers; internal List<ServerListEntry> servers;
public void SetEntries( List<ServerListEntry> servers ) { public void SetEntries( List<ServerListEntry> servers ) {
entries = new TableEntry[servers.Count]; entries = new TableEntry[servers.Count];
@ -56,7 +56,7 @@ namespace Launcher2 {
public int[] ColumnWidths = { 280, 80, 80 }; public int[] ColumnWidths = { 280, 80, 80 };
public int[] DesiredColumnWidths = { 280, 80, 80 }; public int[] DesiredColumnWidths = { 280, 80, 80 };
struct TableEntry { internal struct TableEntry {
public string Hash, Name, Players, Uptime; public string Hash, Name, Players, Uptime;
public int Y, Height; public int Y, Height;
} }