Created
April 22, 2020 16:52
-
-
Save hajimehoshi/5795179c9c64a3c4e66235882f728692 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: Apache-2.0 | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Input; | |
using System; | |
using System.IO; | |
using Go2DotNet.Example.Ebiten.AutoGen; | |
namespace Go2DotNet.Example.Ebiten | |
{ | |
// Operation must sync with driver.Operation. | |
enum Operation | |
{ | |
Zero, | |
One, | |
SrcAlpha, | |
DstAlpha, | |
OneMinusSrcAlpha, | |
OneMinusDstAlpha, | |
} | |
public class GoGame : Game | |
{ | |
private GraphicsDeviceManager graphics; | |
private IInvokable onUpdate; | |
private IInvokable onDraw; | |
private VertexBuffer vertexBuffer; | |
private IndexBuffer indexBuffer; | |
private Effect effect; | |
public GoGame(IInvokable onUpdate, IInvokable onDraw) | |
{ | |
this.onUpdate = onUpdate; | |
this.onDraw = onDraw; | |
this.graphics = new GraphicsDeviceManager(this); | |
this.graphics.PreferredBackBufferWidth = 640; | |
this.graphics.PreferredBackBufferHeight = 480; | |
this.Content.RootDirectory = "Content"; | |
this.IsMouseVisible = true; | |
} | |
protected override void LoadContent() | |
{ | |
VertexElement[] elements = new VertexElement[] | |
{ | |
new VertexElement(sizeof(float)*0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0), | |
new VertexElement(sizeof(float)*2, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), | |
new VertexElement(sizeof(float)*4, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1), | |
new VertexElement(sizeof(float)*8, VertexElementFormat.Vector4, VertexElementUsage.Color, 0), | |
}; | |
this.vertexBuffer = new DynamicVertexBuffer( | |
this.GraphicsDevice, new VertexDeclaration(elements), 65536, BufferUsage.None); | |
this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer); | |
this.indexBuffer = new DynamicIndexBuffer( | |
this.GraphicsDevice, IndexElementSize.SixteenBits, 65536, BufferUsage.None); | |
this.GraphicsDevice.Indices = this.indexBuffer; | |
byte[] bytecode = File.ReadAllBytes("Content/test.mgfxo"); | |
this.effect = new Effect(this.GraphicsDevice, bytecode); | |
this.GraphicsDevice.RasterizerState = new RasterizerState() | |
{ | |
CullMode = CullMode.None, | |
}; | |
base.LoadContent(); | |
} | |
internal void SetDestination(RenderTarget2D renderTarget2D, int viewportWidth, int viewportHeight) | |
{ | |
this.GraphicsDevice.SetRenderTarget(renderTarget2D); | |
this.GraphicsDevice.Viewport = new Viewport(0, 0, viewportWidth, viewportHeight); | |
this.effect.Parameters["ViewportSize"].SetValue(new Vector2(viewportWidth, viewportHeight)); | |
} | |
internal void SetSource(Texture2D texture2D) | |
{ | |
this.effect.Parameters["Texture"].SetValue(texture2D); | |
} | |
internal void SetVertices(byte[] vertices, byte[] indices) | |
{ | |
this.vertexBuffer.SetData(vertices, 0, vertices.Length); | |
this.indexBuffer.SetData(indices, 0, indices.Length); | |
} | |
protected override void Update(GameTime gameTime) | |
{ | |
this.onUpdate.Invoke(null); | |
base.Update(gameTime); | |
} | |
protected override void Draw(GameTime gameTime) | |
{ | |
this.onDraw.Invoke(null); | |
base.Draw(gameTime); | |
} | |
internal void DrawTriangles(int indexLen, int indexOffset, Blend blendSrc, Blend blendDst) | |
{ | |
this.GraphicsDevice.BlendState = new BlendState() | |
{ | |
AlphaSourceBlend = blendSrc, | |
ColorSourceBlend = blendSrc, | |
AlphaDestinationBlend = blendDst, | |
ColorDestinationBlend = blendDst, | |
}; | |
foreach (EffectPass pass in this.effect.CurrentTechnique.Passes) | |
{ | |
pass.Apply(); | |
this.GraphicsDevice.DrawIndexedPrimitives( | |
PrimitiveType.TriangleList, 0, indexOffset, indexLen / 3); | |
} | |
} | |
} | |
// This methods are called from Go world. They must not have overloads. | |
class GameGoBinding | |
{ | |
private static Blend ToBlend(Operation operation) | |
{ | |
switch (operation) | |
{ | |
case Operation.Zero: | |
return Blend.Zero; | |
case Operation.One: | |
return Blend.One; | |
case Operation.SrcAlpha: | |
return Blend.SourceAlpha; | |
case Operation.DstAlpha: | |
return Blend.DestinationAlpha; | |
case Operation.OneMinusSrcAlpha: | |
return Blend.InverseSourceAlpha; | |
case Operation.OneMinusDstAlpha: | |
return Blend.InverseDestinationAlpha; | |
} | |
throw new ArgumentOutOfRangeException("operation", operation, ""); | |
} | |
private GoGame game; | |
private GameGoBinding(IInvokable onUpdate, IInvokable onDraw) | |
{ | |
this.game = new GoGame(onUpdate, onDraw); | |
} | |
private void Run() | |
{ | |
try | |
{ | |
this.game.Run(); | |
} | |
finally | |
{ | |
this.game.Dispose(); | |
} | |
} | |
private RenderTarget2D NewRenderTarget2D(double width, double height) | |
{ | |
return new RenderTarget2D(this.game.GraphicsDevice, (int)width, (int)height); | |
} | |
private void Dispose(Texture2D texture2D) | |
{ | |
texture2D.Dispose(); | |
} | |
private void ReplacePixels(RenderTarget2D renderTarget2D, byte[] pixels, double x, double y, double width, double height) | |
{ | |
var rect = new Rectangle((int)x, (int)y, (int)width, (int)height); | |
renderTarget2D.SetData(0, rect, pixels, 0, pixels.Length); | |
} | |
private byte[] Pixels(Texture2D texture2D, double width, double height) | |
{ | |
Rectangle rect = new Rectangle(0, 0, (int)width, (int)height); | |
byte[] data = new byte[4*(int)width*(int)height]; | |
texture2D.GetData(0, rect, data, 0, data.Length); | |
return data; | |
} | |
private void SetDestination(RenderTarget2D renderTarget2D, double viewportWidth, double viewportHeight) | |
{ | |
this.game.SetDestination(renderTarget2D, (int)viewportWidth, (int)viewportHeight); | |
} | |
private void SetSource(Texture2D texture2D) | |
{ | |
this.game.SetSource(texture2D); | |
} | |
private void SetVertices(byte[] vertices, byte[] indices) | |
{ | |
this.game.SetVertices(vertices, indices); | |
} | |
private void Draw(double indexLen, double indexOffset, double operationSrc, double operationDst) | |
{ | |
this.game.DrawTriangles((int)indexLen, (int)indexOffset, ToBlend((Operation)operationSrc), ToBlend((Operation)operationDst)); | |
} | |
private bool IsKeyPressed(string driverKey) | |
{ | |
Keys key; | |
switch (driverKey) | |
{ | |
case "KeyDown": | |
key = Keys.Down; | |
break; | |
case "KeyLeft": | |
key = Keys.Left; | |
break; | |
case "KeySpace": | |
key = Keys.Space; | |
break; | |
case "KeyRight": | |
key = Keys.Right; | |
break; | |
case "KeyUp": | |
key = Keys.Up; | |
break; | |
default: | |
return false; | |
} | |
return Keyboard.GetState().IsKeyDown(key); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment