Initial block in hand model. No left/right click animations yet though.

This commit is contained in:
UnknownShadow200 2015-11-16 10:48:51 +11:00
parent fe2353c11d
commit 83af1b5a2d
6 changed files with 128 additions and 27 deletions

View File

@ -196,6 +196,7 @@
<Compile Include="Physics\Picking.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Rendering\BlockHandRenderer.cs" />
<Compile Include="Rendering\EnvRenderer.cs" />
<Compile Include="Rendering\MapRenderer.Occlusion.cs" />
<Compile Include="Rendering\MapRenderer.Rendering.cs" />

View File

@ -56,6 +56,7 @@ namespace ClassicalSharp {
public Events Events = new Events();
public InputHandler InputHandler;
public ChatLog Chat;
public BlockHandRenderer BlockHandRenderer;
public IPAddress IPAddress;
public string Username;
@ -172,6 +173,8 @@ namespace ClassicalSharp {
ParticleManager = new ParticleManager( this );
WeatherRenderer = new WeatherRenderer( this );
WeatherRenderer.Init();
BlockHandRenderer = new BlockHandRenderer( this );
BlockHandRenderer.Init();
bool vsync = Options.GetBool( OptionsKey.VSync, true );
Graphics.SetVSync( this, vsync );
@ -257,10 +260,12 @@ namespace ClassicalSharp {
bool middle = IsMousePressed( MouseButton.Middle );
bool right = IsMousePressed( MouseButton.Right );
InputHandler.PickBlocks( true, left, middle, right );
BlockHandRenderer.Render( e.Time );
} else {
SelectedPos.SetAsInvalid();
}
Graphics.Mode2D( Width, Height, EnvRenderer is StandardEnvRenderer );
fpsScreen.Render( e.Time );
if( activeScreen == null || !activeScreen.HidesHud )

View File

@ -1,5 +1,6 @@
using System;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model {
@ -25,11 +26,18 @@ namespace ClassicalSharp.Model {
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -0.5f, 0f, -0.5f, 0.5f, blockHeight, 0.5f ); }
get { return new BoundingBox( -scale, 0f, -scale, scale, blockHeight, scale ); }
}
protected override void DrawPlayerModel( Player p ) {
block = Byte.Parse( p.ModelName );
// TODO: using 'is' is ugly, but means we can avoid creating
// a string every single time held block changes.
if( p is FakePlayer ) {
col = FastColour.Scale( FastColour.White, 0.8f );
block = ((FakePlayer)p).Block;
} else {
block = Byte.Parse( p.ModelName );
}
if( block == 0 ) {
blockHeight = 1;
return;
@ -41,21 +49,28 @@ namespace ClassicalSharp.Model {
BlockInfo = game.BlockInfo;
if( BlockInfo.IsSprite[block] ) {
XQuad( 0f, TileSide.Right, false );
ZQuad( 0f, TileSide.Back, false );
float offset = TerrainAtlas2D.invElementSize / 2;
XQuad( 0f, TileSide.Right, -scale, 0, 0, -offset, false );
ZQuad( 0f, TileSide.Back, 0, scale, offset, 0, false );
XQuad( 0f, TileSide.Right, 0, scale, offset, 0, false );
ZQuad( 0f, TileSide.Back, -scale, 0, 0, -offset, false );
} else {
YQuad( blockHeight, TileSide.Top );
XQuad( -0.5f, TileSide.Right, false );
XQuad( 0.5f, TileSide.Left, true );
ZQuad( -0.5f, TileSide.Front, true );
ZQuad( 0.5f, TileSide.Back, false );
YQuad( 0f, TileSide.Bottom );
XQuad( scale, TileSide.Left, -scale, scale, 0, 0, true );
ZQuad( -scale, TileSide.Front, -scale, scale, 0, 0, true );
ZQuad( scale, TileSide.Back, -scale, scale, 0, 0, true );
YQuad( blockHeight, TileSide.Top );
XQuad( -scale, TileSide.Right, -scale, scale, 0, 0, true );
}
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4 );
}
float blockHeight;
TerrainAtlas2D atlas;
BlockInfo BlockInfo;
float scale = 0.5f;
public override void Dispose() {
}
@ -64,36 +79,45 @@ namespace ClassicalSharp.Model {
int texId = BlockInfo.GetTextureLoc( block, side );
TextureRec rec = atlas.GetAdjTexRec( texId );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + -0.5f, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + y, pos.Z + -0.5f, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + y, pos.Z + 0.5f, rec.U2, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + 0.5f, rec.U1, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + y, pos.Z - scale, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + y, pos.Z - scale, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + y, pos.Z + scale, rec.U2, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + y, pos.Z + scale, rec.U1, rec.V2, col );
}
void ZQuad( float z, int side, bool swapU ) {
void ZQuad( float z, int side, float x1, float x2,
float u1Offset, float u2Offset, bool swapU ) {
int texId = BlockInfo.GetTextureLoc( block, side );
TextureRec rec = atlas.GetAdjTexRec( texId );
if( blockHeight != 1 )
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
if( swapU ) rec.SwapU();
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + 0f, pos.Z + z, rec.U1, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + blockHeight, pos.Z + z, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + blockHeight, pos.Z + z, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + 0f, pos.Z + z, rec.U2, rec.V2, col );
// need to break into two quads when drawing a sprite model in hand.
if( swapU ) rec.SwapU();
rec.U1 += u1Offset;
rec.U2 += u2Offset;
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x1, pos.Y + 0f, pos.Z + z, rec.U1, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x1, pos.Y + blockHeight, pos.Z + z, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x2, pos.Y + blockHeight, pos.Z + z, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x2, pos.Y + 0f, pos.Z + z, rec.U2, rec.V2, col );
}
void XQuad( float x, int side, bool swapU ) {
void XQuad( float x, int side, float z1, float z2,
float u1Offset, float u2Offset, bool swapU ) {
int texId = BlockInfo.GetTextureLoc( block, side );
TextureRec rec = atlas.GetAdjTexRec( texId );
if( blockHeight != 1 )
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
if( swapU ) rec.SwapU();
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + -0.5f, rec.U1, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + -0.5f, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + 0.5f, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + 0.5f, rec.U2, rec.V2, col );
if( swapU ) rec.SwapU();
rec.U1 += u1Offset;
rec.U2 += u2Offset;
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + z1, rec.U1, rec.V2, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + z1, rec.U1, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + z2, rec.U2, rec.V1, col );
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + z2, rec.U2, rec.V2, col );
}
}
}

View File

@ -0,0 +1,71 @@
using System;
using ClassicalSharp.Model;
using OpenTK;
namespace ClassicalSharp.Renderers {
public class BlockHandRenderer : IDisposable {
Game game;
BlockModel block;
FakePlayer fakePlayer;
public BlockHandRenderer( Game window ) {
this.game = window;
}
public void Init() {
block = new BlockModel( game );
fakePlayer = new FakePlayer( game );
SetupMatrices();
}
public void Render( double delta ) {
game.Graphics.Texturing = true;
game.Graphics.DepthTest = false;
game.Graphics.AlphaTest = true;
byte type = (byte)game.Inventory.HeldBlock;
if( game.BlockInfo.IsSprite[type] )
game.Graphics.LoadMatrix( ref spriteMat );
else
game.Graphics.LoadMatrix( ref normalMat );
fakePlayer.Block = type;
block.RenderModel( fakePlayer );
game.Graphics.LoadMatrix( ref game.View );
game.Graphics.Texturing = false;
game.Graphics.DepthTest = true;
game.Graphics.AlphaTest = false;
}
Matrix4 normalMat, spriteMat;
void SetupMatrices() {
Matrix4 m = Matrix4.Identity;
m = m * Matrix4.Scale( 0.6f );
m = m * Matrix4.RotateY( 45 * Utils.Deg2Rad );
normalMat = m * Matrix4.Translate( 0.85f, -1.35f, -1.5f );
spriteMat = m * Matrix4.Translate( 0.85f, -1.05f, -1.5f );
}
public void Dispose() {
}
}
internal class FakePlayer : Player {
public FakePlayer( Game game ) : base( game ) {
}
public byte Block;
public override void SetLocation( LocationUpdate update, bool interpolate ) { }
public override void Tick( double delta ) { }
public override void RenderModel( double deltaTime, float t ) { }
public override void RenderName() { }
}
}

View File

@ -4,7 +4,7 @@ using OpenTK;
namespace ClassicalSharp.Renderers {
public class PickingRenderer {
public class PickingRenderer : IDisposable {
IGraphicsApi graphics;
BlockInfo info;

View File

@ -1,4 +1,4 @@
ClassicalSharp is a custom Minecraft Classic client written in C# that works on both Windows, Linux and OSX.
ClassicalSharp is a custom Minecraft Classic client written in C# that works on Windows, Linux and OSX.
**It is not affiliated with (or supported by) Mojang AB, Minecraft, or Microsoft in any way.**
![screenshot_n](https://cloud.githubusercontent.com/assets/6509348/10800494/288b4f00-7e06-11e5-8344-5df33625cc8b.png)