Fix translucent blocks, fix clipboard crashing the client.

This commit is contained in:
UnknownShadow200 2015-09-30 13:49:37 +10:00
parent 9e9a739932
commit 0979c0597e
18 changed files with 223 additions and 44 deletions

View File

@ -3,10 +3,11 @@ using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp {
public sealed class GdiDrawer2D : IDrawer2D {
public sealed class GdiPlusDrawer2D : IDrawer2D {
StringFormat format;
Bitmap measuringBmp;
@ -15,8 +16,8 @@ namespace ClassicalSharp {
Graphics g;
public GdiDrawer2D( Game game ) {
graphics = game.Graphics;
public GdiPlusDrawer2D( IGraphicsApi graphics ) {
this.graphics = graphics;
format = StringFormat.GenericTypographic;
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
format.Trimming = StringTrimming.None;
@ -64,11 +65,11 @@ namespace ClassicalSharp {
g.DrawRectangle( pen, x, y, width, height );
}
public override void DrawRoundedRect( Color colour, float x, float y, float width, float height ) {
public override void DrawRoundedRect( Color colour, float radius, float x, float y, float width, float height ) {
GraphicsPath path = new GraphicsPath();
float x1 = x, y1 = y, x2 = x + width, y2 = y + height;
const float r = 3, dia = r * 2;
float r = radius, dia = radius * 2;
path.AddArc( x1, y1, dia, dia, 180, 90 );
path.AddLine( x1 + r, y1, x2 - r, y1 );
path.AddArc( x2 - dia, y1, dia, dia, 270, 90 );

View File

@ -19,7 +19,7 @@ namespace ClassicalSharp {
public abstract void DrawRectBounds( Color colour, float lineWidth, int x, int y, int width, int height );
public abstract void DrawRoundedRect( Color colour, float x, float y, float width, float height );
public abstract void DrawRoundedRect( Color colour, float radius, float x, float y, float width, float height );
/// <summary> Disposes of any resources used by this class that are associated with the underlying bitmap. </summary>
public abstract void Dispose();

View File

@ -230,7 +230,8 @@ namespace ClassicalSharp {
}
public override bool HandlesKeyDown( Key key ) {
if( key == game.Keys[KeyMapping.PauseOrExit] ) {
if( key == game.Keys[KeyMapping.PauseOrExit] ||
key == game.Keys[KeyMapping.OpenInventory] ) {
game.SetNewScreen( new NormalScreen( game ) );
}
return true;

View File

@ -66,7 +66,6 @@ namespace ClassicalSharp {
public override void Init() {
playerFont = new Font( "Arial", 12 );
chat = new ChatScreen( game );
chat.game = game;
const int blockSize = 32;
chat.ChatLogYOffset = blockSize + blockSize;
chat.ChatInputYOffset = blockSize + blockSize / 2;

View File

@ -6,7 +6,7 @@ namespace ClassicalSharp {
public abstract class Screen : IDisposable {
protected internal Game game;
protected Game game;
protected IGraphicsApi graphicsApi;
public Screen( Game game ) {

View File

@ -93,8 +93,8 @@ namespace ClassicalSharp {
using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
using( IDrawer2D drawer = game.Drawer2D ) {
drawer.SetBitmap( bmp );
drawer.DrawRoundedRect( shadowCol, 1.3f, 1.3f, baseSize.Width, baseSize.Height );
drawer.DrawRoundedRect( boxCol, 0, 0, baseSize.Width, baseSize.Height );
drawer.DrawRoundedRect( shadowCol, 3, 1.3f, 1.3f, baseSize.Width, baseSize.Height );
drawer.DrawRoundedRect( boxCol, 3, 0, 0, baseSize.Width, baseSize.Height );
DrawTextArgs args = new DrawTextArgs( text, true );
args.SkipPartsCheck = true;

View File

@ -221,6 +221,7 @@ namespace ClassicalSharp {
} else {
chatInputText.Append( caretPos, text );
caretPos += text.Length;
if( caretPos >= chatInputText.Length ) caretPos = -1;
}
Dispose();
Init();

View File

@ -66,7 +66,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="2D\Drawing\DrawTextArgs.cs" />
<Compile Include="2D\Drawing\GdiDrawer2D.cs" />
<Compile Include="2D\Drawing\GdiPlusDrawer2D.cs" />
<Compile Include="2D\Drawing\IDrawer2D.cs" />
<Compile Include="2D\Screens\BlockSelectScreen.cs" />
<Compile Include="2D\Screens\ChatScreen.cs" />

View File

@ -10,6 +10,7 @@ namespace ClassicalSharp {
protected IGraphicsApi api;
protected Texture nameTex;
protected internal int PlayerTextureId = -1, MobTextureId = -1;
internal bool RenderHat = true;
public override void Despawn() {
if( api == null ) return;

View File

@ -99,7 +99,7 @@ namespace ClassicalSharp {
Utils.LogWarning( "Unable to load options.txt" );
}
Keys = new KeyMap();
Drawer2D = new GdiDrawer2D( this );
Drawer2D = new GdiPlusDrawer2D( Graphics );
ViewDistance = Options.GetInt( "viewdist", 16, 8192, 512 );
defaultIb = Graphics.MakeDefaultIb();
ModelCache = new ModelCache( this );
@ -129,6 +129,8 @@ namespace ClassicalSharp {
} else {
Network = new NetworkProcessor( this );
}
Graphics.LostContextFunction = Network.Tick;
firstPersonCam = new FirstPersonCamera( this );
thirdPersonCam = new ThirdPersonCamera( this );
Camera = firstPersonCam;
@ -290,17 +292,14 @@ namespace ClassicalSharp {
Screen activeScreen;
public void SetNewScreen( Screen screen ) {
if( activeScreen != null ) {
if( activeScreen != null )
activeScreen.Dispose();
}
if( activeScreen != null && activeScreen.HandlesAllInput )
lastClick = DateTime.UtcNow;
activeScreen = screen;
if( screen != null ) {
screen.game = this;
if( screen != null )
screen.Init();
}
if( Network.UsingPlayerClick ) {
byte targetId = Players.GetClosetPlayer( this );
ButtonStateChanged( MouseButton.Left, false, targetId );

View File

@ -3,10 +3,10 @@ using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using OpenTK;
using SharpDX;
using SharpDX.Direct3D9;
using D3D = SharpDX.Direct3D9;
using Matrix4 = OpenTK.Matrix4;
using WinWindowInfo = OpenTK.Platform.Windows.WinWindowInfo;
namespace ClassicalSharp.GraphicsAPI {
@ -395,11 +395,11 @@ namespace ClassicalSharp.GraphicsAPI {
#endregion
public override void BeginFrame( Game game ) {
public override void BeginFrame( GameWindow game ) {
device.BeginScene();
}
public override void EndFrame( Game game ) {
public override void EndFrame( GameWindow game ) {
device.EndScene();
int code = device.Present();
if( code >= 0 ) return;
@ -417,22 +417,22 @@ namespace ClassicalSharp.GraphicsAPI {
RecreateDevice( game );
break;
}
game.Network.Tick( 1 / 20.0 );
LostContextFunction( 1 / 20.0 );
}
}
bool vsync = false;
public override void SetVSync( Game game, bool value ) {
public override void SetVSync( GameWindow game, bool value ) {
vsync = value;
game.VSync = value;
RecreateDevice( game );
}
public override void OnWindowResize( Game game ) {
public override void OnWindowResize( GameWindow game ) {
RecreateDevice( game );
}
void RecreateDevice( Game game ) {
void RecreateDevice( GameWindow game ) {
PresentParameters args = GetPresentArgs( game.Width, game.Height );
for( int i = 0; i < dynamicvBuffers.Length; i++ ) {
DynamicDataBuffer buffer = dynamicvBuffers[i];

View File

@ -172,13 +172,15 @@ namespace ClassicalSharp.GraphicsAPI {
Console.ResetColor();
}
public abstract void BeginFrame( Game game );
public abstract void BeginFrame( GameWindow game );
public abstract void EndFrame( Game game );
public abstract void EndFrame( GameWindow game );
public abstract void SetVSync( Game game, bool value );
public abstract void SetVSync( GameWindow game, bool value );
public abstract void OnWindowResize( Game game );
public abstract void OnWindowResize( GameWindow game );
public Action<double> LostContextFunction;
protected void InitDynamicBuffers() {
quadVb = CreateDynamicVb( VertexFormat.Pos3fCol4b, 4 );

View File

@ -353,14 +353,14 @@ namespace ClassicalSharp.GraphicsAPI {
#endregion
public override void BeginFrame( Game game ) {
public override void BeginFrame( GameWindow game ) {
}
public override void EndFrame( Game game ) {
public override void EndFrame( GameWindow game ) {
game.SwapBuffers();
}
public override void SetVSync( Game game, bool value ) {
public override void SetVSync( GameWindow game, bool value ) {
game.VSync = value;
}

View File

@ -89,12 +89,13 @@ namespace ClassicalSharp.Model {
DrawRotate( 0, 12/16f, 0, p.rightLegXRot, 0, 0, model.RightLeg );
DrawRotate( -6/16f, 22/16f, 0, p.leftArmXRot, 0, p.leftArmZRot, model.LeftArm );
DrawRotate( 6/16f, 22/16f, 0, p.rightArmXRot, 0, p.rightArmZRot, model.RightArm );
graphics.AlphaTest = true;
DrawRotate( 0, 23.5f/16f, 0, -p.PitchRadians, 0, 0, model.Hat );
if( p.RenderHat ) {
graphics.AlphaTest = true;
DrawRotate( 0, 23.5f/16f, 0, -p.PitchRadians, 0, 0, model.Hat );
}
}
class ModelSet {
class ModelSet {
public ModelPart Head, Torso, LeftLeg, RightLeg, LeftArm, RightArm, Hat;
}
}

View File

@ -21,7 +21,7 @@ namespace ClassicalSharp {
if( part.IndicesCount > maxIndices ) {
DrawBigPart( info, ref part );
} else {
DrawPart( info, ref part, true );
DrawPart( info, ref part );
}
if( part.spriteCount > 0 )
@ -37,7 +37,7 @@ namespace ClassicalSharp {
ChunkPartInfo part = info.TranslucentParts[batch];
if( part.IndicesCount == 0 ) continue;
DrawPart( info, ref part, false );
DrawTranslucentPart( info, ref part );
game.Vertices += part.IndicesCount;
}
}
@ -49,11 +49,11 @@ namespace ClassicalSharp {
ChunkPartInfo part = info.TranslucentParts[batch];
if( part.IndicesCount == 0 ) continue;
DrawPart( info, ref part, false );
DrawTranslucentPart( info, ref part );
}
}
void DrawPart( ChunkInfo info, ref ChunkPartInfo part, bool faceCulling ) {
void DrawPart( ChunkInfo info, ref ChunkPartInfo part ) {
api.BindVb( part.VbId );
bool drawLeft = info.DrawLeft && part.leftCount > 0;
bool drawRight = info.DrawRight && part.rightCount > 0;
@ -63,7 +63,7 @@ namespace ClassicalSharp {
bool drawBack = info.DrawBack && part.backCount > 0;
if( drawLeft && drawRight ) {
api.FaceCulling = faceCulling;
api.FaceCulling = true;
api.DrawIndexedVb_TrisT2fC4b( part.leftCount + part.rightCount, part.leftIndex );
api.FaceCulling = false;
} else if( drawLeft ) {
@ -73,7 +73,7 @@ namespace ClassicalSharp {
}
if( drawFront && drawBack ) {
api.FaceCulling = faceCulling;
api.FaceCulling = true;
api.DrawIndexedVb_TrisT2fC4b( part.frontCount + part.backCount, part.frontIndex );
api.FaceCulling = false;
} else if( drawFront ) {
@ -83,7 +83,7 @@ namespace ClassicalSharp {
}
if( drawBottom && drawTop ) {
api.FaceCulling = faceCulling;
api.FaceCulling = true;
api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount, part.bottomIndex );
api.FaceCulling = false;
} else if( drawBottom ) {
@ -93,6 +93,41 @@ namespace ClassicalSharp {
}
}
bool drawAllFaces = false;
void DrawTranslucentPart( ChunkInfo info, ref ChunkPartInfo part ) {
api.BindVb( part.VbId );
bool drawLeft = (drawAllFaces || info.DrawLeft) && part.leftCount > 0;
bool drawRight = (drawAllFaces || info.DrawRight) && part.rightCount > 0;
bool drawBottom = (drawAllFaces || info.DrawBottom) && part.bottomCount > 0;
bool drawTop = (drawAllFaces || info.DrawTop) && part.topCount > 0;
bool drawFront = (drawAllFaces || info.DrawFront) && part.frontCount > 0;
bool drawBack = (drawAllFaces || info.DrawBack) && part.backCount > 0;
if( drawLeft && drawRight ) {
api.DrawIndexedVb_TrisT2fC4b( part.leftCount + part.rightCount, part.leftIndex );
} else if( drawLeft ) {
api.DrawIndexedVb_TrisT2fC4b( part.leftCount, part.leftIndex );
} else if( drawRight ) {
api.DrawIndexedVb_TrisT2fC4b( part.rightCount, part.rightIndex );
}
if( drawFront && drawBack ) {
api.DrawIndexedVb_TrisT2fC4b( part.frontCount + part.backCount, part.frontIndex );
} else if( drawFront ) {
api.DrawIndexedVb_TrisT2fC4b( part.frontCount, part.frontIndex );
} else if( drawBack ) {
api.DrawIndexedVb_TrisT2fC4b( part.backCount, part.backIndex );
}
if( drawBottom && drawTop ) {
api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount, part.bottomIndex );
} else if( drawBottom ) {
api.DrawIndexedVb_TrisT2fC4b( part.bottomCount, part.bottomIndex );
} else if( drawTop ) {
api.DrawIndexedVb_TrisT2fC4b( part.topCount, part.topIndex );
}
}
void DrawBigPart( ChunkInfo info, ref ChunkPartInfo part ) {
api.BindVb( part.VbId );
bool drawLeft = info.DrawLeft && part.leftCount > 0;

View File

@ -275,6 +275,8 @@ namespace ClassicalSharp {
// Render translucent(liquid) blocks. These 'blend' into other blocks.
void RenderTranslucent() {
Block block = game.LocalPlayer.BlockAtHead;
drawAllFaces = block == Block.Water || block == Block.StillWater;
// First fill depth buffer
int[] texIds = game.TerrainAtlas1D.TexIds;
api.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );

View File

@ -3,7 +3,7 @@ using System.Reflection;
namespace ClassicalSharp {
internal sealed unsafe class StringBuffer {
public sealed unsafe class StringBuffer {
internal string value;
internal int capacity;

137
Launcher2/Game.cs Normal file
View File

@ -0,0 +1,137 @@
using System;
using ClassicalSharp;
using ClassicalSharp.GraphicsAPI;
using OpenTK;
using System.Drawing;
namespace Launcher2 {
public partial class Game : GameWindow {
public IGraphicsApi Graphics;
FpsScreen fpsScreen;
public IDrawer2D Drawer2D;
protected override void OnLoad( EventArgs e ) {
#if !USE_DX
//Graphics = new OpenGLApi();
#else
Graphics = new Direct3D9Api( this );
#endif
Graphics.SetVSync( this, true );
Graphics.DepthTest = true;
Graphics.DepthTestFunc( CompareFunc.LessEqual );
Graphics.AlphaBlendFunc( BlendFunc.SourceAlpha, BlendFunc.InvSourceAlpha );
Graphics.AlphaTestFunc( CompareFunc.Greater, 0.5f );
Title = Utils.AppName;
Width = width;
Height = height;
fpsScreen = new FpsScreen( Graphics );
fpsScreen.Init();
}
int width, height;
protected override void OnRenderFrame( FrameEventArgs e ) {
Graphics.BeginFrame( this );
Graphics.Clear();
Graphics.Mode2D( Width, Height );
fpsScreen.Render( e.Time );
if( activeScreen != null ) {
activeScreen.Render( e.Time );
}
Graphics.Mode3D();
Graphics.EndFrame( this );
}
protected override void OnResize( EventArgs e ) {
base.OnResize( e );
Graphics.OnWindowResize( this );
if( activeScreen != null ) {
activeScreen.OnResize( width, height, Width, Height );
}
width = Width;
height = Height;
}
Screen activeScreen;
public void SetNewScreen( Screen screen ) {
if( activeScreen != null ) {
activeScreen.Dispose();
}
activeScreen = screen;
if( screen != null ) {
screen.Init();
}
}
public override void Dispose() {
if( activeScreen != null ) {
activeScreen.Dispose();
}
Graphics.Dispose();
Drawer2D.DisposeInstance();
base.Dispose();
}
}
public class FpsScreen : Screen {
readonly Font font;
StringBuffer text;
public FpsScreen( IGraphicsApi gfx ) : base( gfx ) {
font = new Font( "Arial", 13 );
text = new StringBuffer( 96 );
}
TextWidget fpsTextWidget;
public override void Render( double delta ) {
UpdateFPS( delta );
if( game.HideGui ) return;
graphicsApi.Texturing = true;
fpsTextWidget.Render( delta );
graphicsApi.Texturing = false;
}
double accumulator, maxDelta;
int fpsCount;
unsafe void UpdateFPS( double delta ) {
fpsCount++;
maxDelta = Math.Max( maxDelta, delta );
accumulator += delta;
if( accumulator >= 1 ) {
fixed( char* ptr = text.value ) {
char* ptr2 = ptr;
text.Clear( ptr2 )
.Append( ref ptr2, "FPS: " ).AppendNum( ref ptr2, (int)( fpsCount / accumulator ) )
.Append( ref ptr2, " (min " ).AppendNum( ref ptr2, (int)( 1f / maxDelta ) )
.Append( ref ptr2, "), chunks/s: " ).AppendNum( ref ptr2, game.ChunkUpdates )
.Append( ref ptr2, ", vertices: " ).AppendNum( ref ptr2, game.Vertices );
}
string textString = text.GetString();
fpsTextWidget.SetText( textString );
maxDelta = 0;
accumulator = 0;
fpsCount = 0;
game.ChunkUpdates = 0;
}
}
public override void Init() {
fpsTextWidget = new TextWidget( game, font );
fpsTextWidget.Init();
fpsTextWidget.SetText( "FPS: no data yet" );
}
public override void Dispose() {
font.Dispose();
fpsTextWidget.Dispose();
}
}
}