Initial work on new client gui.

This commit is contained in:
UnknownShadow200 2015-09-24 09:51:55 +10:00
parent a9681a15c6
commit 938cb13182
9 changed files with 235 additions and 177 deletions

View file

@ -0,0 +1,77 @@
using System;
using System.Drawing;
using OpenTK.Input;
namespace ClassicalSharp {
public class NewPauseScreen : Screen {
public NewPauseScreen( Game game ) : base( game ) {
}
ButtonWidget[] buttons;
public override void Render( double delta ) {
//graphicsApi.Draw2DQuad( 0, 0, game.Width, game.Height, new FastColour( 255, 255, 255, 100 ) );
graphicsApi.Texturing = true;
for( int i = 0; i < buttons.Length; i++ )
buttons[i].Render( delta );
graphicsApi.Texturing = false;
}
Font titleFont;
public override void Init() {
titleFont = new Font( "Arial", 16, FontStyle.Bold );
buttons = new ButtonWidget[] {
Make( 0, -50, "Options", Docking.Centre, g => { } ),
Make( 0, 0, "Environment settings",Docking.Centre, g => { } ),
Make( 0, 50, "Key mappings", Docking.Centre, g => { } ),
Make( 0, 55, "Back to game", Docking.BottomOrRight, g => g.SetNewScreen( new NormalScreen( g ) ) ),
Make( 0, 5, "Exit", Docking.BottomOrRight, g => g.Exit() ),
};
}
ButtonWidget Make( int x, int y, string text, Docking vDocking, Action<Game> onClick ) {
return ButtonWidget.Create( game, x, y, 240, 35, text, Docking.Centre, vDocking, titleFont, onClick );
}
public override void Dispose() {
titleFont.Dispose();
for( int i = 0; i < buttons.Length; i++ )
buttons[i].Dispose();
}
public override void OnResize( int oldWidth, int oldHeight, int width, int height ) {
for( int i = 0; i < buttons.Length; i++ )
buttons[i].OnResize( oldWidth, oldHeight, width, height );
}
public override bool HandlesAllInput {
get { return true; }
}
public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
if( button != MouseButton.Left ) return false;
for( int i = 0; i < buttons.Length; i++ ) {
ButtonWidget widget = buttons[i];
if( widget.ContainsPoint( mouseX, mouseY ) ) {
widget.OnClick( game );
return true;
}
}
return false;
}
public override bool HandlesMouseMove( int mouseX, int mouseY ) {
for( int i = 0; i < buttons.Length; i++ )
buttons[i].Active = false;
for( int i = 0; i < buttons.Length; i++ ) {
ButtonWidget widget = buttons[i];
if( widget.ContainsPoint( mouseX, mouseY ) ) {
widget.Active = true;
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace ClassicalSharp {
public sealed class ButtonWidget : Widget {
public ButtonWidget( Game game, Font font ) : base( game ) {
this.font = font;
}
public static ButtonWidget Create( Game game, int x, int y, int width, int height, string text, Docking horizontal,
Docking vertical, Font font, Action<Game> onClick ) {
ButtonWidget widget = new ButtonWidget( game, font );
widget.Init();
widget.HorizontalDocking = horizontal;
widget.VerticalDocking = vertical;
widget.XOffset = x;
widget.YOffset = y;
widget.DesiredMaxWidth = width;
widget.DesiredMaxHeight = height;
widget.SetText( text );
widget.OnClick = onClick;
return widget;
}
Texture texture;
public int XOffset = 0, YOffset = 0;
public int DesiredMaxWidth, DesiredMaxHeight;
int defaultHeight;
readonly Font font;
public override void Init() {
defaultHeight = Utils2D.MeasureSize( "I", font, true ).Height;
Height = defaultHeight;
}
static FastColour boxCol = new FastColour( 169, 143, 192 ), shadowCol = new FastColour( 97, 81, 110 );
//static FastColour boxCol = new FastColour( 29, 126, 192 ), shadowCol = new FastColour( 16, 72, 109 );
public void SetText( string text ) {
graphicsApi.DeleteTexture( ref texture );
if( String.IsNullOrEmpty( text ) ) {
texture = new Texture();
Height = defaultHeight;
} else {
MakeTexture( text );
X = texture.X1 = CalcOffset( game.Width, texture.Width, XOffset, HorizontalDocking );
Y = texture.Y1 = CalcOffset( game.Height, texture.Height, YOffset, VerticalDocking );
Height = texture.Height;
}
Width = texture.Width;
}
public override void Render( double delta ) {
if( texture.IsValid ) {
FastColour col = Active ? FastColour.White : new FastColour( 200, 200, 200 );
graphicsApi.BindTexture( texture.ID );
graphicsApi.Draw2DTexture( ref texture, col );
}
}
public override void Dispose() {
graphicsApi.DeleteTexture( ref texture );
}
public override void MoveTo( int newX, int newY ) {
int deltaX = newX - X;
int deltaY = newY - Y;
texture.X1 += deltaX;
texture.Y1 += deltaY;
X = newX;
Y = newY;
}
public Action<Game> OnClick;
public bool Active;
void MakeTexture( string text ) {
DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true );
Size size = Utils2D.MeasureSize( text, font, true );
int xOffset = Math.Max( size.Width, DesiredMaxWidth ) - size.Width;
size.Width = Math.Max( size.Width, DesiredMaxWidth );
int yOffset = Math.Max( size.Height, DesiredMaxHeight ) - size.Height;
size.Height = Math.Max( size.Height, DesiredMaxHeight );
Size baseSize = size;
const int borderSize = 3; // 1 px for base border, 2 px for shadow, 1 px for offset text
size.Width += borderSize; size.Height += borderSize;
using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) {
using( Graphics g = Graphics.FromImage( bmp ) ) {
args.SkipPartsCheck = true;
g.SmoothingMode = SmoothingMode.HighQuality;
// Draw shadow rectangle
GraphicsPath path = MakePath( 1.3f, baseSize.Width, baseSize.Height );
using( Brush brush = new SolidBrush( shadowCol ) )
g.FillPath( brush, path );
path.Dispose();
// Draw base rectangle
path = MakePath( 0, baseSize.Width, baseSize.Height );
using( Brush brush = new SolidBrush( boxCol ) )
g.FillPath( brush, path );
path.Dispose();
Utils2D.DrawText( g, font, ref args, 1 + xOffset / 2, 1 + yOffset / 2 );
}
texture = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, 0 );
}
}
GraphicsPath MakePath( float offset, float width, float height ) {
GraphicsPath path = new GraphicsPath();
float x1 = offset, y1 = offset;
float x2 = offset + width, y2 = offset + height;
const float r = 3, dia = r * 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 );
path.AddLine( x2, y1 + r, x2, y2 - r );
path.AddArc( x2 - dia, y2 - dia, dia, dia, 0, 90 );
path.AddLine( x1 + r, y2, x2 - r, y2 );
path.AddArc( x1, y2 - dia, dia, dia, 90, 90 );
path.AddLine( x1, y1 + r, x1, y2 - r );
path.CloseAllFigures();
return path;
}
}
}

View file

@ -1,111 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace ClassicalSharp {
public sealed class OptionsWidget : Widget {
public OptionsWidget( Game game, Font font ) : base( game ) {
this.font = font;
}
public static OptionsWidget Create( Game game, int x, int y, string text, Docking horizontal, Docking vertical, Font font ) {
OptionsWidget widget = new OptionsWidget( game, font );
widget.Init();
widget.HorizontalDocking = horizontal;
widget.VerticalDocking = vertical;
widget.XOffset = x;
widget.YOffset = y;
widget.SetText( text );
return widget;
}
Texture texture;
public int XOffset = 0, YOffset = 0;
int defaultHeight;
readonly Font font;
public override void Init() {
defaultHeight = Utils2D.MeasureSize( "I", font, true ).Height;
Height = defaultHeight;
}
static readonly FastColour boxColour = new FastColour( 169, 143, 192 );
static readonly FastColour shadowCol = new FastColour( 97, 81, 110 );
public void SetText( string text ) {
graphicsApi.DeleteTexture( ref texture );
if( String.IsNullOrEmpty( text ) ) {
texture = new Texture();
Height = defaultHeight;
} else {
DrawTextArgs args = new DrawTextArgs( graphicsApi, text, true );
Size size = Utils2D.MeasureSize( text, font, true );
Size baseSize = size;
const int borderSize = 3; // 1 px for base border, 2 px for shadow, 1 px for offset text
size.Width += borderSize; size.Height += borderSize;
using( Bitmap bmp = Utils2D.CreatePow2Bitmap( size ) ) {
using( Graphics g = Graphics.FromImage( bmp ) ) {
args.SkipPartsCheck = true;
g.SmoothingMode = SmoothingMode.HighQuality;
// Draw shadow rectangle
GraphicsPath path = MakePath( 1.3f, baseSize.Width, baseSize.Height );
using( Brush brush = new SolidBrush( shadowCol ) )
g.FillPath( brush, path );
path.Dispose();
// Draw base rectangle
path = MakePath( 0, baseSize.Width, baseSize.Height );
using( Brush brush = new SolidBrush( boxColour ) )
g.FillPath( brush, path );
path.Dispose();
Utils2D.DrawText( g, font, ref args, 1, 1 );
}
texture = Utils2D.Make2DTexture( graphicsApi, bmp, size, 0, 0 );
}
X = texture.X1 = CalcOffset( game.Width, texture.Width, XOffset, HorizontalDocking );
Y = texture.Y1 = CalcOffset( game.Height, texture.Height, YOffset, VerticalDocking );
Height = texture.Height;
}
Width = texture.Width;
}
GraphicsPath MakePath( float offset, float width, float height ) {
GraphicsPath path = new GraphicsPath();
float x1 = offset, y1 = offset;
float x2 = offset + width, y2 = offset + height;
const float r = 3, dia = r * 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 );
path.AddLine( x2, y1 + r, x2, y2 - r );
path.AddArc( x2 - dia, y2 - dia, dia, dia, 0, 90 );
path.AddLine( x1 + r, y2, x2 - r, y2 );
path.AddArc( x1, y2 - dia, dia, dia, 90, 90 );
path.AddLine( x1, y1 + r, x1, y2 - r );
path.CloseAllFigures();
return path;
}
public override void Render( double delta ) {
if( texture.IsValid ) {
texture.Render( graphicsApi );
}
}
public override void Dispose() {
graphicsApi.DeleteTexture( ref texture );
}
public override void MoveTo( int newX, int newY ) {
int deltaX = newX - X;
int deltaY = newY - Y;
texture.X1 += deltaX;
texture.Y1 += deltaY;
X = newX;
Y = newY;
}
}
}

View file

@ -71,6 +71,7 @@
<Compile Include="2D\Screens\ErrorScreen.cs" />
<Compile Include="2D\Screens\FpsScreen.cs" />
<Compile Include="2D\Screens\LoadingMapScreen.cs" />
<Compile Include="2D\Screens\NewPauseScreen.cs" />
<Compile Include="2D\Screens\NormalScreen.cs" />
<Compile Include="2D\Screens\PauseScreen.cs" />
<Compile Include="2D\Screens\Screen.cs" />
@ -79,7 +80,7 @@
<Compile Include="2D\Widgets\BlockHotbarWidget.cs" />
<Compile Include="2D\Widgets\ExtPlayerListWidget.cs" />
<Compile Include="2D\Widgets\NormalPlayerListWidget.cs" />
<Compile Include="2D\Widgets\OptionsWidget.cs" />
<Compile Include="2D\Widgets\ButtonWidget.cs" />
<Compile Include="2D\Widgets\PlayerListWidget.cs" />
<Compile Include="2D\Widgets\TextGroupWidget.cs" />
<Compile Include="2D\Widgets\TextInputWidget.cs" />

View file

@ -44,12 +44,13 @@ namespace ClassicalSharp {
Vector3 pos = Position;
pos.Y += Model.NameYOffset;
api.texVerts[0] = new VertexPos3fTex2f( Utils.RotateY( x1, y1, 0, cosA, sinA ) + pos, nameTex.U1, nameTex.V1 );
api.texVerts[1] = new VertexPos3fTex2f( Utils.RotateY( x2, y1, 0, cosA, sinA ) + pos, nameTex.U2, nameTex.V1 );
api.texVerts[2] = new VertexPos3fTex2f( Utils.RotateY( x2, y2, 0, cosA, sinA ) + pos, nameTex.U2, nameTex.V2 );
api.texVerts[3] = new VertexPos3fTex2f( Utils.RotateY( x1, y2, 0, cosA, sinA ) + pos, nameTex.U1, nameTex.V2 );
FastColour col = FastColour.White;
api.texVerts[0] = new VertexPos3fTex2fCol4b( Utils.RotateY( x1, y1, 0, cosA, sinA ) + pos, nameTex.U1, nameTex.V1, col );
api.texVerts[1] = new VertexPos3fTex2fCol4b( Utils.RotateY( x2, y1, 0, cosA, sinA ) + pos, nameTex.U2, nameTex.V1, col );
api.texVerts[2] = new VertexPos3fTex2fCol4b( Utils.RotateY( x2, y2, 0, cosA, sinA ) + pos, nameTex.U2, nameTex.V2, col );
api.texVerts[3] = new VertexPos3fTex2fCol4b( Utils.RotateY( x1, y2, 0, cosA, sinA ) + pos, nameTex.U1, nameTex.V2, col );
api.BeginVbBatch( VertexFormat.Pos3fTex2f );
api.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
api.DrawDynamicIndexedVb( DrawMode.Triangles, api.texVb, api.texVerts, 4, 6 );
api.Texturing = false;
api.AlphaTest = false;

View file

@ -579,7 +579,6 @@ namespace ClassicalSharp.GraphicsAPI {
Blend.DestinationAlpha, Blend.InverseDestinationAlpha,
};
formatMapping = new [] {
D3D.VertexFormat.Position | D3D.VertexFormat.Texture2,
D3D.VertexFormat.Position | D3D.VertexFormat.Diffuse,
D3D.VertexFormat.Position | D3D.VertexFormat.Texture2 | D3D.VertexFormat.Diffuse,
};
@ -603,10 +602,9 @@ namespace ClassicalSharp.GraphicsAPI {
blendFuncs[0] = Blend.Zero; blendFuncs[1] = Blend.One; blendFuncs[2] = Blend.SourceAlpha;
blendFuncs[3] = Blend.InverseSourceAlpha; blendFuncs[4] = Blend.DestinationAlpha;
blendFuncs[5] = Blend.InverseDestinationAlpha;
formatMapping = new D3D.VertexFormat[3];
formatMapping[0] = D3D.VertexFormat.Position | D3D.VertexFormat.Texture2;
formatMapping[1] = D3D.VertexFormat.Position | D3D.VertexFormat.Diffuse;
formatMapping[2] = D3D.VertexFormat.Position | D3D.VertexFormat.Texture2 | D3D.VertexFormat.Diffuse;
formatMapping = new D3D.VertexFormat[2];
formatMapping[0] = D3D.VertexFormat.Position | D3D.VertexFormat.Diffuse;
formatMapping[1] = D3D.VertexFormat.Position | D3D.VertexFormat.Texture2 | D3D.VertexFormat.Diffuse;
modes = new FogMode[3];
modes[0] = FogMode.Linear; modes[1] = FogMode.Exponential; modes[2] = FogMode.ExponentialSquared;
#endif

View file

@ -143,7 +143,7 @@ namespace ClassicalSharp.GraphicsAPI {
internal abstract void DrawIndexedVb_TrisT2fC4b( int indicesCount, int startIndex );
protected static int[] strideSizes = { 20, 16, 24 };
protected static int[] strideSizes = { 16, 24 };
public abstract void SetMatrixMode( MatrixType mode );
@ -180,7 +180,7 @@ namespace ClassicalSharp.GraphicsAPI {
protected void InitDynamicBuffers() {
quadVb = CreateDynamicVb( VertexFormat.Pos3fCol4b, 4 );
texVb = CreateDynamicVb( VertexFormat.Pos3fTex2f, 4 );
texVb = CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 4 );
}
public virtual void Dispose() {
@ -199,9 +199,9 @@ namespace ClassicalSharp.GraphicsAPI {
DrawDynamicIndexedVb( DrawMode.Triangles, quadVb, quadVerts, 4, 6 );
}
internal VertexPos3fTex2f[] texVerts = new VertexPos3fTex2f[4];
internal VertexPos3fTex2fCol4b[] texVerts = new VertexPos3fTex2fCol4b[4];
internal int texVb;
public virtual void Draw2DTexture( ref Texture tex ) {
public virtual void Draw2DTexture( ref Texture tex, FastColour col ) {
float x1 = tex.X1, y1 = tex.Y1, x2 = tex.X2, y2 = tex.Y2;
#if USE_DX
// NOTE: see "https://msdn.microsoft.com/en-us/library/windows/desktop/bb219690(v=vs.85).aspx",
@ -211,14 +211,18 @@ namespace ClassicalSharp.GraphicsAPI {
y1 -= 0.5f;
y2 -= 0.5f;
#endif
texVerts[0] = new VertexPos3fTex2f( x1, y1, 0, tex.U1, tex.V1 );
texVerts[1] = new VertexPos3fTex2f( x2, y1, 0, tex.U2, tex.V1 );
texVerts[2] = new VertexPos3fTex2f( x2, y2, 0, tex.U2, tex.V2 );
texVerts[3] = new VertexPos3fTex2f( x1, y2, 0, tex.U1, tex.V2 );
BeginVbBatch( VertexFormat.Pos3fTex2f );
texVerts[0] = new VertexPos3fTex2fCol4b( x1, y1, 0, tex.U1, tex.V1, col );
texVerts[1] = new VertexPos3fTex2fCol4b( x2, y1, 0, tex.U2, tex.V1, col );
texVerts[2] = new VertexPos3fTex2fCol4b( x2, y2, 0, tex.U2, tex.V2, col );
texVerts[3] = new VertexPos3fTex2fCol4b( x1, y2, 0, tex.U1, tex.V2, col );
BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
DrawDynamicIndexedVb( DrawMode.Triangles, texVb, texVerts, 4, 6 );
}
public void Draw2DTexture( ref Texture tex ) {
Draw2DTexture( ref tex, FastColour.White );
}
public void Mode2D( float width, float height ) {
SetMatrixMode( MatrixType.Projection );
PushMatrix();
@ -267,9 +271,8 @@ namespace ClassicalSharp.GraphicsAPI {
}
public enum VertexFormat {
Pos3fTex2f = 0,
Pos3fCol4b = 1,
Pos3fTex2fCol4b = 2,
Pos3fCol4b = 0,
Pos3fTex2fCol4b = 1,
}
public enum DrawMode {

View file

@ -29,9 +29,9 @@ namespace ClassicalSharp.GraphicsAPI {
base.InitDynamicBuffers();
setupBatchFuncCol4b = SetupVbPos3fCol4b;
setupBatchFuncTex2f = SetupVbPos3fTex2f;
setupBatchFuncTex2fCol4b = SetupVbPos3fTex2fCol4b;
GL.EnableClientState( ArrayCap.VertexArray );
GL.EnableClientState( ArrayCap.ColorArray );
}
public override bool AlphaTest {
@ -173,8 +173,7 @@ namespace ClassicalSharp.GraphicsAPI {
#endregion
#region Vertex/index buffers
Action setupBatchFunc;
Action setupBatchFuncTex2f, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b;
Action setupBatchFunc, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b;
public override int CreateDynamicVb( VertexFormat format, int maxVertices ) {
int id = GenAndBind( BufferTarget.ArrayBuffer );
@ -257,26 +256,15 @@ namespace ClassicalSharp.GraphicsAPI {
if( format == batchFormat ) return;
if( batchFormat == VertexFormat.Pos3fTex2fCol4b ) {
GL.DisableClientState( ArrayCap.ColorArray );
GL.DisableClientState( ArrayCap.TextureCoordArray );
} else if( batchFormat == VertexFormat.Pos3fTex2f ) {
GL.DisableClientState( ArrayCap.TextureCoordArray );
} else if( batchFormat == VertexFormat.Pos3fCol4b ) {
GL.DisableClientState( ArrayCap.ColorArray );
}
batchFormat = format;
if( format == VertexFormat.Pos3fTex2fCol4b ) {
GL.EnableClientState( ArrayCap.ColorArray );
GL.EnableClientState( ArrayCap.TextureCoordArray );
setupBatchFunc = setupBatchFuncTex2fCol4b;
batchStride = VertexPos3fTex2fCol4b.Size;
} else if( format == VertexFormat.Pos3fTex2f ) {
GL.EnableClientState( ArrayCap.TextureCoordArray );
setupBatchFunc = setupBatchFuncTex2f;
batchStride = VertexPos3fTex2f.Size;
} else if( format == VertexFormat.Pos3fCol4b ) {
GL.EnableClientState( ArrayCap.ColorArray );
} else {
setupBatchFunc = setupBatchFuncCol4b;
batchStride = VertexPos3fCol4b.Size;
}
@ -317,10 +305,6 @@ namespace ClassicalSharp.GraphicsAPI {
}
IntPtr zero = new IntPtr( 0 ), twelve = new IntPtr( 12 ), sixteen = new IntPtr( 16 );
void SetupVbPos3fTex2f() {
GL.VertexPointer( 3, PointerType.Float, VertexPos3fTex2f.Size, zero );
GL.TexCoordPointer( 2, PointerType.Float, VertexPos3fTex2f.Size, twelve );
}
void SetupVbPos3fCol4b() {
GL.VertexPointer( 3, PointerType.Float, VertexPos3fCol4b.Size, zero );

View file

@ -92,28 +92,4 @@ namespace ClassicalSharp {
return String.Format( "({0},{1},{2}) ({3},{4}) ({5},{6},{7},{8})", X, Y, Z, U, V, R, G, B, A );
}
}
/// <summary> 3 floats for position (X, Y, Z),<br/>
/// 2 floats for texture coordinates (U, V)</summary>
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public struct VertexPos3fTex2f {
public float X, Y, Z;
public float U, V;
public VertexPos3fTex2f( float x, float y, float z, float u, float v ) {
X = x; Y = y; Z = z;
U = u; V = v;
}
public VertexPos3fTex2f( Vector3 p, float u, float v ) {
X = p.X; Y = p.Y; Z = p.Z;
U = u; V = v;
}
public const int Size = 20; // (4 + 4 + 4) + (4 + 4)
public override string ToString() {
return String.Format( "({0},{1},{2}) ({3},{4})", X, Y, Z, U, V );
}
}
}