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

@ -80,12 +80,14 @@ namespace ClassicalSharp {
Font chatFont, chatInputFont, chatUnderlineFont, announcementFont;
public override void Init() {
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 );
chatInputFont = new Font( "Arial", fontSize, FontStyle.Bold );
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());
textInput = new TextInputWidget( game, chatFont, chatInputFont );

View File

@ -3,7 +3,7 @@ using OpenTK;
namespace ClassicalSharp.Particles {
public abstract class Particle : IDisposable {
public abstract class Particle {
public Vector3 Position;
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 Dispose();
public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) {
this.game = game;
Position = lastPos = nextPos = pos;

View File

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

View File

@ -82,7 +82,7 @@ namespace ClassicalSharp {
last = now;
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;
writer.WriteLine( entry );
}

View File

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

View File

@ -23,6 +23,7 @@ namespace ClassicalSharp {
float vOffset;
const int extent = 4;
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * (extent * 2 + 1) * (extent * 2 + 1)];
double rainAcc;
public void Render( double deltaTime ) {
Weather weather = map.Weather;
@ -33,6 +34,7 @@ namespace ClassicalSharp {
Vector3I pos = Vector3I.Floor( game.LocalPlayer.Position );
float speed = weather == Weather.Rainy ? 1f : 0.25f;
vOffset = -(float)game.accumulator * speed;
rainAcc += deltaTime;
int index = 0;
graphics.AlphaBlending = true;
@ -44,10 +46,14 @@ namespace ClassicalSharp {
float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY;
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 ) );
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.
if( index > 0 ) {

View File

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

View File

@ -40,6 +40,17 @@ namespace Launcher2 {
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() {
if( lastInput == widgets[1] ) {
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];

View File

@ -24,7 +24,7 @@ namespace Launcher2 {
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.RemoveChar() ) {
RedrawLastInput();

View File

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