fix conflicts

This commit is contained in:
Alli
2010-02-18 13:49:30 +13:00
16 changed files with 482 additions and 263 deletions

6
.gitignore vendored
View File

@@ -25,3 +25,9 @@ log.txt
# backup files by various editors # backup files by various editors
*~ *~
# dependency DLLs (different for every platform!)
cg.dll
cgGL.dll
glfw.dll
/OpenRa.Gl.dll

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
namespace OpenRa.FileFormats.Graphics
{
[AttributeUsage( AttributeTargets.Assembly )]
public class RendererAttribute : Attribute
{
public readonly Type Type;
public RendererAttribute( Type graphicsDeviceType )
{
if( !typeof( IGraphicsDevice ).IsAssignableFrom( graphicsDeviceType ) )
throw new InvalidOperationException( "Incorrect type in RendererAttribute" );
Type = graphicsDeviceType;
}
}
public interface IGraphicsDevice
{
IVertexBuffer<T> CreateVertexBuffer<T>( int length ) where T : struct;
IIndexBuffer CreateIndexBuffer( int length );
ITexture CreateTexture( Bitmap bitmap );
IShader CreateShader( Stream stream );
Size WindowSize { get; }
void Begin();
void End();
void Clear( Color color );
void Present();
void DrawIndexedPrimitives( PrimitiveType type, Range<int> vertexRange, Range<int> indexRange );
void DrawIndexedPrimitives( PrimitiveType type, int vertexPool, int numPrimitives );
void EnableScissor( int left, int top, int width, int height );
void DisableScissor();
}
public interface IVertexBuffer<T>
{
void Bind();
void SetData( T[] vertices );
}
public interface IIndexBuffer
{
void Bind();
void SetData( ushort[] indices );
}
public interface IShader
{
void SetValue( string name, float x, float y );
void SetValue( string param, ITexture texture );
void Commit();
void Render( Action a );
}
public interface ITexture
{
void SetData( Bitmap bitmap );
}
public enum PrimitiveType
{
PointList,
LineList,
TriangleList,
}
public struct Range<T>
{
public readonly T Start, End;
public Range( T start, T end ) { Start = start; End = end; }
}
}

View File

@@ -59,6 +59,7 @@
<Compile Include="Format2.cs" /> <Compile Include="Format2.cs" />
<Compile Include="Format40.cs" /> <Compile Include="Format40.cs" />
<Compile Include="Format80.cs" /> <Compile Include="Format80.cs" />
<Compile Include="Graphics\IGraphicsDevice.cs" />
<Compile Include="IniFile.cs" /> <Compile Include="IniFile.cs" />
<Compile Include="int2.cs" /> <Compile Include="int2.cs" />
<Compile Include="IPaletteRemap.cs" /> <Compile Include="IPaletteRemap.cs" />

View File

@@ -30,6 +30,8 @@ using OpenRa.Network;
using OpenRa.Support; using OpenRa.Support;
using OpenRa.Traits; using OpenRa.Traits;
using Timer = OpenRa.Support.Timer; using Timer = OpenRa.Support.Timer;
using System.Runtime.InteropServices;
using System.IO;
namespace OpenRa namespace OpenRa
{ {
@@ -285,7 +287,7 @@ namespace OpenRa
return sp; return sp;
} }
internal static void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e, Keys ModifierKeys) public static void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e, Keys ModifierKeys)
{ {
int sync = Game.world.SyncHash(); int sync = Game.world.SyncHash();
@@ -302,7 +304,7 @@ namespace OpenRa
throw new InvalidOperationException( "Desync in DispatchMouseInput" ); throw new InvalidOperationException( "Desync in DispatchMouseInput" );
} }
internal static void HandleKeyDown( KeyEventArgs e ) public static void HandleKeyDown( KeyEventArgs e )
{ {
int sync = Game.world.SyncHash(); int sync = Game.world.SyncHash();
@@ -315,7 +317,7 @@ namespace OpenRa
throw new InvalidOperationException( "Desync in OnKeyDown" ); throw new InvalidOperationException( "Desync in OnKeyDown" );
} }
internal static void HandleKeyPress( KeyPressEventArgs e ) public static void HandleKeyPress( KeyPressEventArgs e )
{ {
int sync = Game.world.SyncHash(); int sync = Game.world.SyncHash();
@@ -327,5 +329,81 @@ namespace OpenRa
if( sync != Game.world.SyncHash() ) if( sync != Game.world.SyncHash() )
throw new InvalidOperationException( "Desync in OnKeyPress" ); throw new InvalidOperationException( "Desync in OnKeyPress" );
} }
static Size GetResolution(Settings settings)
{
var desktopResolution = Screen.PrimaryScreen.Bounds.Size;
if (Game.Settings.Width > 0 && Game.Settings.Height > 0)
{
desktopResolution.Width = Game.Settings.Width;
desktopResolution.Height = Game.Settings.Height;
}
return new Size(
desktopResolution.Width,
desktopResolution.Height);
}
[DllImport("user32")]
static extern int ShowCursor([MarshalAs(UnmanagedType.Bool)] bool visible);
public static void PreInit(Settings settings)
{
while (!File.Exists("redalert.mix"))
{
var current = Directory.GetCurrentDirectory();
if (Directory.GetDirectoryRoot(current) == current)
throw new InvalidOperationException("Unable to load MIX files.");
Directory.SetCurrentDirectory("..");
}
LoadUserSettings(settings);
Game.LobbyInfo.GlobalSettings.Mods = Game.Settings.InitialMods;
// Load the default mod to access required files
Game.LoadModPackages(new Manifest(Game.LobbyInfo.GlobalSettings.Mods));
UiOverlay.ShowUnitDebug = Game.Settings.UnitDebug;
WorldRenderer.ShowUnitPaths = Game.Settings.PathDebug;
Renderer.SheetSize = Game.Settings.SheetSize;
bool windowed = !Game.Settings.Fullscreen;
var resolution = GetResolution(settings);
renderer = new Renderer(resolution, windowed);
resolution = renderer.Resolution;
var controller = new Controller(() => (Modifiers)(int)0/*ModifierKeys*/); /* a bit of insane input routing */
Game.Initialize(Game.Settings.Map, renderer, new int2(resolution), Game.Settings.Player, controller);
ShowCursor(false);
Game.ResetTimer();
}
static void LoadUserSettings(Settings settings)
{
Game.Settings = new UserSettings();
var settingsFile = settings.GetValue("settings", "settings.ini");
FileSystem.Mount("./");
if (FileSystem.Exists(settingsFile))
FieldLoader.Load(Game.Settings,
new IniFile(FileSystem.Open(settingsFile)).GetSection("Settings"));
FileSystem.UnmountAll();
}
static bool quit;
internal static void Run()
{
while (!quit)
{
Game.Tick();
Application.DoEvents();
}
}
public static void Exit()
{
quit = true;
}
} }
} }

View File

@@ -19,15 +19,15 @@
#endregion #endregion
using System.Drawing; using System.Drawing;
using OpenRa.GlRenderer; using OpenRa.FileFormats.Graphics;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
class LineRenderer class LineRenderer
{ {
Renderer renderer; Renderer renderer;
VertexBuffer<Vertex> vertexBuffer; IVertexBuffer<Vertex> vertexBuffer;
IndexBuffer indexBuffer; /* kindof a waste of space, but the GPU likes indexing, oh well */ IIndexBuffer indexBuffer; /* kindof a waste of space, but the GPU likes indexing, oh well */
const int linesPerBatch = 1024; const int linesPerBatch = 1024;
@@ -39,8 +39,8 @@ namespace OpenRa.Graphics
public LineRenderer( Renderer renderer ) public LineRenderer( Renderer renderer )
{ {
this.renderer = renderer; this.renderer = renderer;
vertexBuffer = new VertexBuffer<Vertex>( renderer.Device, vertices.Length, Vertex.Format ); vertexBuffer = renderer.Device.CreateVertexBuffer<Vertex>(vertices.Length );
indexBuffer = new IndexBuffer( renderer.Device, indices.Length ); indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length );
} }
public void Flush() public void Flush()

View File

@@ -18,12 +18,15 @@
*/ */
#endregion #endregion
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Text; using System.Drawing.Text;
using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.GlRenderer; using OpenRa.FileFormats.Graphics;
using OpenRa.Support; using OpenRa.Support;
using System.IO;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
@@ -31,14 +34,14 @@ namespace OpenRa.Graphics
{ {
internal static int SheetSize; internal static int SheetSize;
readonly GraphicsDevice device; readonly IGraphicsDevice device;
public Shader SpriteShader { get; private set; } /* note: shared shader params */ public IShader SpriteShader { get; private set; } /* note: shared shader params */
public Shader LineShader { get; private set; } public IShader LineShader { get; private set; }
public Shader RgbaSpriteShader { get; private set; } public IShader RgbaSpriteShader { get; private set; }
public Shader WorldSpriteShader { get; private set; } public IShader WorldSpriteShader { get; private set; }
public Texture PaletteTexture; public ITexture PaletteTexture;
readonly Font fDebug, fTitle; readonly Font fDebug, fTitle;
@@ -46,19 +49,16 @@ namespace OpenRa.Graphics
SpriteRenderer rgbaRenderer; SpriteRenderer rgbaRenderer;
Sprite textSprite; Sprite textSprite;
public Renderer(Control control, Size resolution, bool windowed) public Size Resolution { get { return device.WindowSize; } }
{
control.ClientSize = resolution;
device = new GraphicsDevice(control, resolution.Width, resolution.Height, windowed, false);
SpriteShader = new Shader(device, FileSystem.Open("world-shp.fx")); public Renderer(Size resolution, bool windowed)
SpriteShader.Quality = ShaderQuality.Low; {
LineShader = new Shader(device, FileSystem.Open("line.fx")); device = CreateDevice( Assembly.LoadFile( Path.GetFullPath( "OpenRa.Gl.dll" ) ), resolution.Width, resolution.Height, windowed, false );
LineShader.Quality = ShaderQuality.High;
RgbaSpriteShader = new Shader(device, FileSystem.Open("chrome-rgba.fx")); SpriteShader = device.CreateShader(FileSystem.Open("world-shp.fx"));
RgbaSpriteShader.Quality = ShaderQuality.High; LineShader = device.CreateShader(FileSystem.Open("line.fx"));
WorldSpriteShader = new Shader(device, FileSystem.Open("chrome-shp.fx")); RgbaSpriteShader = device.CreateShader(FileSystem.Open("chrome-rgba.fx"));
WorldSpriteShader.Quality = ShaderQuality.High; WorldSpriteShader = device.CreateShader(FileSystem.Open("chrome-shp.fx"));
fDebug = new Font("Tahoma", 10, FontStyle.Regular); fDebug = new Font("Tahoma", 10, FontStyle.Regular);
fTitle = new Font("Tahoma", 10, FontStyle.Bold); fTitle = new Font("Tahoma", 10, FontStyle.Bold);
@@ -67,6 +67,16 @@ namespace OpenRa.Graphics
textSprite = new Sprite(textSheet, new Rectangle(0, 0, 256, 256), TextureChannel.Alpha); textSprite = new Sprite(textSheet, new Rectangle(0, 0, 256, 256), TextureChannel.Alpha);
} }
IGraphicsDevice CreateDevice( Assembly rendererDll, int width, int height, bool fullscreen, bool vsync )
{
foreach( RendererAttribute r in rendererDll.GetCustomAttributes( typeof( RendererAttribute ), false ) )
{
return (IGraphicsDevice)r.Type.GetConstructor( new Type[] { typeof( int ), typeof( int ), typeof( bool ), typeof( bool ) } )
.Invoke( new object[] { width, height, fullscreen, vsync } );
}
throw new NotImplementedException();
}
Bitmap RenderTextToBitmap(string s, Font f, Color c) Bitmap RenderTextToBitmap(string s, Font f, Color c)
{ {
Bitmap b = new Bitmap(256, 256); Bitmap b = new Bitmap(256, 256);
@@ -86,7 +96,7 @@ namespace OpenRa.Graphics
return new int2(g.MeasureString(s, f).ToSize()); return new int2(g.MeasureString(s, f).ToSize());
} }
public GraphicsDevice Device { get { return device; } } public IGraphicsDevice Device { get { return device; } }
public void BeginFrame(float2 r1, float2 r2, float2 scroll) public void BeginFrame(float2 r1, float2 r2, float2 scroll)
{ {
@@ -99,7 +109,7 @@ namespace OpenRa.Graphics
SetShaderParams( WorldSpriteShader, r1, r2, scroll ); SetShaderParams( WorldSpriteShader, r1, r2, scroll );
} }
private void SetShaderParams( Shader s, float2 r1, float2 r2, float2 scroll ) private void SetShaderParams( IShader s, float2 r1, float2 r2, float2 scroll )
{ {
s.SetValue( "Palette", PaletteTexture ); s.SetValue( "Palette", PaletteTexture );
s.SetValue( "Scroll", scroll.X, scroll.Y ); s.SetValue( "Scroll", scroll.X, scroll.Y );
@@ -114,8 +124,8 @@ namespace OpenRa.Graphics
device.Present(); device.Present();
} }
public void DrawBatch<T>(VertexBuffer<T> vertices, IndexBuffer indices, public void DrawBatch<T>(IVertexBuffer<T> vertices, IIndexBuffer indices,
Range<int> vertexRange, Range<int> indexRange, Texture texture, PrimitiveType type, Shader shader) Range<int> vertexRange, Range<int> indexRange, ITexture texture, PrimitiveType type, IShader shader)
where T : struct where T : struct
{ {
shader.SetValue("DiffuseTexture", texture); shader.SetValue("DiffuseTexture", texture);
@@ -129,8 +139,8 @@ namespace OpenRa.Graphics
PerfHistory.Increment("batches", 1); PerfHistory.Increment("batches", 1);
} }
public void DrawBatch<T>(VertexBuffer<T> vertices, IndexBuffer indices, public void DrawBatch<T>(IVertexBuffer<T> vertices, IIndexBuffer indices,
int vertexPool, int numPrimitives, Texture texture, PrimitiveType type) int vertexPool, int numPrimitives, ITexture texture, PrimitiveType type)
where T : struct where T : struct
{ {
SpriteShader.SetValue("DiffuseTexture", texture); SpriteShader.SetValue("DiffuseTexture", texture);

View File

@@ -20,7 +20,7 @@
using System.Drawing; using System.Drawing;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.GlRenderer; using OpenRa.FileFormats.Graphics;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
@@ -29,7 +29,7 @@ namespace OpenRa.Graphics
readonly Renderer renderer; readonly Renderer renderer;
protected readonly Bitmap bitmap; protected readonly Bitmap bitmap;
Texture texture; ITexture texture;
internal Sheet(Renderer renderer, Size size) internal Sheet(Renderer renderer, Size size)
{ {
@@ -45,10 +45,10 @@ namespace OpenRa.Graphics
void Resolve() void Resolve()
{ {
texture = new Texture(renderer.Device, bitmap); texture = renderer.Device.CreateTexture(bitmap);
} }
public Texture Texture public ITexture Texture
{ {
get get
{ {

View File

@@ -18,16 +18,16 @@
*/ */
#endregion #endregion
using OpenRa.GlRenderer; using OpenRa.FileFormats.Graphics;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
class SpriteRenderer class SpriteRenderer
{ {
VertexBuffer<Vertex> vertexBuffer; IVertexBuffer<Vertex> vertexBuffer;
IndexBuffer indexBuffer; IIndexBuffer indexBuffer;
Renderer renderer; Renderer renderer;
Shader shader; IShader shader;
const int spritesPerBatch = 1024; const int spritesPerBatch = 1024;
@@ -35,18 +35,15 @@ namespace OpenRa.Graphics
ushort[] indices = new ushort[6 * spritesPerBatch]; ushort[] indices = new ushort[6 * spritesPerBatch];
Sheet currentSheet = null; Sheet currentSheet = null;
int sprites = 0; int sprites = 0;
ShaderQuality quality;
int nv = 0, ni = 0; int nv = 0, ni = 0;
public SpriteRenderer(Renderer renderer, bool allowAlpha, Shader shader) public SpriteRenderer(Renderer renderer, bool allowAlpha, IShader shader)
{ {
this.renderer = renderer; this.renderer = renderer;
this.shader = shader; this.shader = shader;
vertexBuffer = new VertexBuffer<Vertex>(renderer.Device, vertices.Length, Vertex.Format); vertexBuffer = renderer.Device.CreateVertexBuffer<Vertex>( vertices.Length );
indexBuffer = new IndexBuffer(renderer.Device, indices.Length); indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length );
quality = allowAlpha ? ShaderQuality.High : ShaderQuality.Low;
} }
public SpriteRenderer(Renderer renderer, bool allowAlpha) public SpriteRenderer(Renderer renderer, bool allowAlpha)
@@ -56,7 +53,6 @@ namespace OpenRa.Graphics
{ {
if (sprites > 0) if (sprites > 0)
{ {
shader.Quality = quality;
shader.SetValue( "DiffuseTexture", currentSheet.Texture ); shader.SetValue( "DiffuseTexture", currentSheet.Texture );
shader.Render(() => shader.Render(() =>
{ {

View File

@@ -20,14 +20,14 @@
using System.Drawing; using System.Drawing;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.GlRenderer; using OpenRa.FileFormats.Graphics;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
class TerrainRenderer class TerrainRenderer
{ {
VertexBuffer<Vertex> vertexBuffer; IVertexBuffer<Vertex> vertexBuffer;
IndexBuffer indexBuffer; IIndexBuffer indexBuffer;
Sheet terrainSheet; Sheet terrainSheet;
Renderer renderer; Renderer renderer;
@@ -62,10 +62,10 @@ namespace OpenRa.Graphics
terrainSheet = tileMapping[map.MapTiles[map.XOffset, map.YOffset]].sheet; terrainSheet = tileMapping[map.MapTiles[map.XOffset, map.YOffset]].sheet;
vertexBuffer = new VertexBuffer<Vertex>( renderer.Device, vertices.Length, Vertex.Format ); vertexBuffer = renderer.Device.CreateVertexBuffer<Vertex>( vertices.Length );
vertexBuffer.SetData( vertices ); vertexBuffer.SetData( vertices );
indexBuffer = new IndexBuffer( renderer.Device, indices.Length ); indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length );
indexBuffer.SetData( indices ); indexBuffer.SetData( indices );
overlayRenderer = new OverlayRenderer( renderer, map ); overlayRenderer = new OverlayRenderer( renderer, map );
@@ -97,7 +97,6 @@ namespace OpenRa.Graphics
firstRow = r.Bottom - map.YOffset; firstRow = r.Bottom - map.YOffset;
} }
renderer.SpriteShader.Quality = ShaderQuality.Low;
renderer.SpriteShader.SetValue( "DiffuseTexture", terrainSheet.Texture ); renderer.SpriteShader.SetValue( "DiffuseTexture", terrainSheet.Texture );
renderer.SpriteShader.Render(() => renderer.SpriteShader.Render(() =>
renderer.DrawBatch(vertexBuffer, indexBuffer, renderer.DrawBatch(vertexBuffer, indexBuffer,

View File

@@ -19,7 +19,6 @@
#endregion #endregion
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using OpenRa.GlRenderer;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
@@ -35,7 +34,5 @@ namespace OpenRa.Graphics
this.u = uv.X; this.v = uv.Y; this.u = uv.X; this.v = uv.Y;
this.p = pc.X; this.c = pc.Y; this.p = pc.X; this.c = pc.Y;
} }
public const VertexFormat Format = VertexFormat.Position | VertexFormat.Texture2;
} }
} }

View File

@@ -29,128 +29,129 @@ using OpenRa.Graphics;
namespace OpenRa namespace OpenRa
{ {
class MainWindow : Form //class MainWindow : Form
{ //{
readonly Renderer renderer; // readonly Renderer renderer;
static Size GetResolution(Settings settings) // static Size GetResolution(Settings settings)
{ // {
var desktopResolution = Screen.PrimaryScreen.Bounds.Size; // var desktopResolution = Screen.PrimaryScreen.Bounds.Size;
if (Game.Settings.Width > 0 && Game.Settings.Height > 0) // if (Game.Settings.Width > 0 && Game.Settings.Height > 0)
{ // {
desktopResolution.Width = Game.Settings.Width; // desktopResolution.Width = Game.Settings.Width;
desktopResolution.Height = Game.Settings.Height; // desktopResolution.Height = Game.Settings.Height;
} // }
return new Size( // return new Size(
desktopResolution.Width, // desktopResolution.Width,
desktopResolution.Height); // desktopResolution.Height);
} // }
[DllImport("user32")] // [DllImport("user32")]
static extern int ShowCursor([MarshalAs(UnmanagedType.Bool)] bool visible); // static extern int ShowCursor([MarshalAs(UnmanagedType.Bool)] bool visible);
public MainWindow(Settings settings) // public MainWindow(Settings settings)
{ // {
//Icon = Resources1.OpenRA; // Icon = Resources1.OpenRA;
FormBorderStyle = FormBorderStyle.None; // FormBorderStyle = FormBorderStyle.None;
BackColor = Color.Black; // BackColor = Color.Black;
StartPosition = FormStartPosition.Manual; // StartPosition = FormStartPosition.Manual;
Location = Point.Empty; // Location = Point.Empty;
Visible = true; // Visible = true;
>>>>>>> origin/glfw:OpenRa.Game/MainWindow.cs
while (!File.Exists("redalert.mix")) // while (!File.Exists("redalert.mix"))
{ // {
var current = Directory.GetCurrentDirectory(); // var current = Directory.GetCurrentDirectory();
if (Directory.GetDirectoryRoot(current) == current) // if (Directory.GetDirectoryRoot(current) == current)
throw new InvalidOperationException("Unable to load MIX files."); // throw new InvalidOperationException("Unable to load MIX files.");
Directory.SetCurrentDirectory(".."); // Directory.SetCurrentDirectory("..");
} // }
LoadUserSettings(settings); // LoadUserSettings(settings);
Game.LobbyInfo.GlobalSettings.Mods = Game.Settings.InitialMods; // Game.LobbyInfo.GlobalSettings.Mods = Game.Settings.InitialMods;
// Load the default mod to access required files // // Load the default mod to access required files
Game.LoadModPackages(new Manifest(Game.LobbyInfo.GlobalSettings.Mods)); // Game.LoadModPackages(new Manifest(Game.LobbyInfo.GlobalSettings.Mods));
UiOverlay.ShowUnitDebug = Game.Settings.UnitDebug; // UiOverlay.ShowUnitDebug = Game.Settings.UnitDebug;
WorldRenderer.ShowUnitPaths = Game.Settings.PathDebug; // WorldRenderer.ShowUnitPaths = Game.Settings.PathDebug;
Renderer.SheetSize = Game.Settings.SheetSize; // Renderer.SheetSize = Game.Settings.SheetSize;
bool windowed = !Game.Settings.Fullscreen; // bool windowed = !Game.Settings.Fullscreen;
renderer = new Renderer(this, GetResolution(settings), windowed); // renderer = new Renderer(this, GetResolution(settings), windowed);
var controller = new Controller(() => (Modifiers)(int)ModifierKeys); /* a bit of insane input routing */ // var controller = new Controller(() => (Modifiers)(int)ModifierKeys); /* a bit of insane input routing */
Game.Initialize(Game.Settings.Map, renderer, new int2(ClientSize), Game.Settings.Player, controller); // Game.Initialize(Game.Settings.Map, renderer, new int2(ClientSize), Game.Settings.Player, controller);
ShowCursor(false); // ShowCursor(false);
Game.ResetTimer(); // Game.ResetTimer();
} // }
static void LoadUserSettings(Settings settings) // static void LoadUserSettings(Settings settings)
{ // {
Game.Settings = new UserSettings(); // Game.Settings = new UserSettings();
var settingsFile = settings.GetValue("settings", "settings.ini"); // var settingsFile = settings.GetValue("settings", "settings.ini");
FileSystem.Mount("./"); // FileSystem.Mount("./");
if (FileSystem.Exists(settingsFile)) // if (FileSystem.Exists(settingsFile))
FieldLoader.Load(Game.Settings, // FieldLoader.Load(Game.Settings,
new IniFile(FileSystem.Open(settingsFile)).GetSection("Settings")); // new IniFile(FileSystem.Open(settingsFile)).GetSection("Settings"));
FileSystem.UnmountAll(); // FileSystem.UnmountAll();
} // }
internal void Run() // internal void Run()
{ // {
while (Created && Visible) // while (Created && Visible)
{ // {
Game.Tick(); // Game.Tick();
Application.DoEvents(); // Application.DoEvents();
} // }
} // }
int2 lastPos; // int2 lastPos;
protected override void OnMouseDown(MouseEventArgs e) // protected override void OnMouseDown(MouseEventArgs e)
{ // {
base.OnMouseDown(e); // base.OnMouseDown(e);
lastPos = new int2(e.Location); // lastPos = new int2(e.Location);
Game.DispatchMouseInput(MouseInputEvent.Down, e, ModifierKeys); // Game.DispatchMouseInput(MouseInputEvent.Down, e, ModifierKeys);
} // }
protected override void OnMouseMove(MouseEventArgs e) // protected override void OnMouseMove(MouseEventArgs e)
{ // {
base.OnMouseMove(e); // base.OnMouseMove(e);
if (e.Button == MouseButtons.Middle || e.Button == (MouseButtons.Left | MouseButtons.Right)) // if (e.Button == MouseButtons.Middle || e.Button == (MouseButtons.Left | MouseButtons.Right))
{ // {
int2 p = new int2(e.Location); // int2 p = new int2(e.Location);
Game.viewport.Scroll(lastPos - p); // Game.viewport.Scroll(lastPos - p);
lastPos = p; // lastPos = p;
} // }
Game.DispatchMouseInput(MouseInputEvent.Move, e, ModifierKeys); // Game.DispatchMouseInput(MouseInputEvent.Move, e, ModifierKeys);
} // }
protected override void OnMouseUp(MouseEventArgs e) // protected override void OnMouseUp(MouseEventArgs e)
{ // {
base.OnMouseUp(e); // base.OnMouseUp(e);
Game.DispatchMouseInput(MouseInputEvent.Up, e, ModifierKeys); // Game.DispatchMouseInput(MouseInputEvent.Up, e, ModifierKeys);
} // }
protected override void OnKeyDown(KeyEventArgs e) // protected override void OnKeyDown(KeyEventArgs e)
{ // {
base.OnKeyDown(e); // base.OnKeyDown(e);
Game.HandleKeyDown( e ); // Game.HandleKeyDown( e );
} // }
protected override void OnKeyPress(KeyPressEventArgs e) // protected override void OnKeyPress(KeyPressEventArgs e)
{ // {
base.OnKeyPress(e); // base.OnKeyPress(e);
Game.HandleKeyPress( e ); // Game.HandleKeyPress( e );
} // }
} //}
[Flags] [Flags]
public enum MouseButton public enum MouseButton

View File

@@ -166,7 +166,6 @@
<Compile Include="Graphics\SheetBuilder.cs" /> <Compile Include="Graphics\SheetBuilder.cs" />
<Compile Include="Graphics\HardwarePalette.cs" /> <Compile Include="Graphics\HardwarePalette.cs" />
<Compile Include="MainWindow.cs"> <Compile Include="MainWindow.cs">
<SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="Support\Program.cs" /> <Compile Include="Support\Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
@@ -272,10 +271,6 @@
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project> <Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRa.FileFormats</Name> <Name>OpenRa.FileFormats</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\OpenRa.Gl\OpenRa.Gl.csproj">
<Project>{67CF1A10-C5F6-48FA-B1A7-FE83BE4CE2CC}</Project>
<Name>OpenRa.Gl</Name>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">

View File

@@ -47,7 +47,8 @@ namespace OpenRa
static void Run( string[] args ) static void Run( string[] args )
{ {
new MainWindow( new Settings( args ) ).Run(); Game.PreInit( new Settings( args ) );
Game.Run();
} }
} }
} }

View File

@@ -23,7 +23,7 @@ using System.Text.RegularExpressions;
namespace OpenRa namespace OpenRa
{ {
class Settings public class Settings
{ {
Dictionary<string, string> settings = new Dictionary<string, string>(); Dictionary<string, string> settings = new Dictionary<string, string>();

View File

@@ -27,61 +27,88 @@ using System.Windows.Forms;
using Tao.Cg; using Tao.Cg;
using Tao.OpenGl; using Tao.OpenGl;
using Tao.Platform.Windows; using Tao.Platform.Windows;
using OpenRa.FileFormats.Graphics;
using Tao.Glfw;
[assembly: Renderer( typeof( OpenRa.GlRenderer.GraphicsDevice ))]
namespace OpenRa.GlRenderer namespace OpenRa.GlRenderer
{ {
public class GraphicsDevice public class GraphicsDevice : IGraphicsDevice
{ {
Size windowSize; Size windowSize;
Graphics g;
internal IntPtr dc;
internal IntPtr rc;
internal IntPtr cgContext; internal IntPtr cgContext;
internal int vertexProfile, fragmentProfile; internal int vertexProfile, fragmentProfile;
public static void CheckGlError() readonly Glfw.GLFWmousebuttonfun mouseButtonCallback;
readonly Glfw.GLFWmouseposfun mousePositionCallback;
readonly Glfw.GLFWwindowclosefun windowCloseCallback;
int mouseX, mouseY;
public Size WindowSize { get { return windowSize; } }
internal static void CheckGlError()
{ {
var n = Gl.glGetError(); var n = Gl.glGetError();
if (n != Gl.GL_NO_ERROR) if (n != Gl.GL_NO_ERROR)
throw new InvalidOperationException("GL Error"); throw new InvalidOperationException("GL Error");
} }
public GraphicsDevice(Control control, int width, int height, bool fullscreen, bool vsync) public GraphicsDevice( int width, int height, bool fullscreen, bool vsync )
{ {
Glfw.glfwInit();
Glfw.glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, /*fullscreen ? Glfw.GLFW_FULLSCREEN : */Glfw.GLFW_WINDOW);
bool initDone = false;
var lastButtonBits = (MouseButtons)0;
Glfw.glfwSetMouseButtonCallback( mouseButtonCallback = ( button, action ) =>
{
var b = button == Glfw.GLFW_MOUSE_BUTTON_1 ? MouseButtons.Left
: button == Glfw.GLFW_MOUSE_BUTTON_2 ? MouseButtons.Right
: button == Glfw.GLFW_MOUSE_BUTTON_3 ? MouseButtons.Middle
: 0;
Game.DispatchMouseInput( action == Glfw.GLFW_PRESS ? MouseInputEvent.Down : MouseInputEvent.Up,
new MouseEventArgs( b, action == Glfw.GLFW_PRESS ? 1 : 0, mouseX, mouseY, 0 ), 0 );
if (action == Glfw.GLFW_PRESS) lastButtonBits |= b;
else lastButtonBits &= ~b;
if (action != Glfw.GLFW_PRESS && action != Glfw.GLFW_RELEASE)
throw new InvalidOperationException();
} );
Glfw.glfwSetMousePosCallback(mousePositionCallback = (x, y) =>
{
mouseX = x;
mouseY = y;
if (initDone)
Game.DispatchMouseInput(MouseInputEvent.Move, new MouseEventArgs(lastButtonBits, 0, x, y, 0), 0);
});
Glfw.glfwSetWindowCloseCallback( windowCloseCallback = () =>
{
Game.Exit();
Glfw.glfwIconifyWindow();
return Gl.GL_TRUE;
} );
CheckGlError();
Glfw.glfwGetWindowSize(out width, out height);
windowSize = new Size( width, height ); windowSize = new Size( width, height );
g = control.CreateGraphics();
dc = g.GetHdc();
var pfd = new Gdi.PIXELFORMATDESCRIPTOR
{
nSize = (short)Marshal.SizeOf(typeof(Gdi.PIXELFORMATDESCRIPTOR)),
nVersion = 1,
dwFlags = Gdi.PFD_SUPPORT_OPENGL | Gdi.PFD_DRAW_TO_BITMAP | Gdi.PFD_DOUBLEBUFFER,
iPixelType = Gdi.PFD_TYPE_RGBA,
cColorBits = 24,
iLayerType = Gdi.PFD_MAIN_PLANE
};
var iFormat = Gdi.ChoosePixelFormat(dc, ref pfd);
Gdi.SetPixelFormat(dc, iFormat, ref pfd);
rc = Wgl.wglCreateContext(dc);
if (rc == IntPtr.Zero)
throw new InvalidOperationException("can't create wglcontext");
Wgl.wglMakeCurrent(dc, rc);
cgContext = Cg.cgCreateContext(); cgContext = Cg.cgCreateContext();
Cg.cgSetErrorCallback(CgErrorCallback); Cg.cgSetErrorCallback( CgErrorCallback );
CgGl.cgGLRegisterStates(cgContext); CgGl.cgGLRegisterStates( cgContext );
CgGl.cgGLSetManageTextureParameters(cgContext, true); CgGl.cgGLSetManageTextureParameters( cgContext, true );
vertexProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_VERTEX); vertexProfile = CgGl.cgGLGetLatestProfile( CgGl.CG_GL_VERTEX );
fragmentProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_FRAGMENT); fragmentProfile = CgGl.cgGLGetLatestProfile( CgGl.CG_GL_FRAGMENT );
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); Gl.glEnableClientState( Gl.GL_VERTEX_ARRAY );
CheckGlError(); CheckGlError();
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY); Gl.glEnableClientState( Gl.GL_TEXTURE_COORD_ARRAY );
CheckGlError(); CheckGlError();
initDone = true;
} }
static Cg.CGerrorCallbackFuncDelegate CgErrorCallback = () => static Cg.CGerrorCallbackFuncDelegate CgErrorCallback = () =>
@@ -121,22 +148,34 @@ namespace OpenRa.GlRenderer
public void Present() public void Present()
{ {
Wgl.wglSwapBuffers(dc); Glfw.glfwSwapBuffers();
Glfw.glfwPollEvents();
CheckGlError(); CheckGlError();
} }
public void DrawIndexedPrimitives(PrimitiveType pt, Range<int> vertices, Range<int> indices) public void DrawIndexedPrimitives( PrimitiveType pt, Range<int> vertices, Range<int> indices )
{ {
Gl.glDrawElements( (int)pt, indices.End - indices.Start, Gl.GL_UNSIGNED_SHORT, new IntPtr( indices.Start * 2 ) ); Gl.glDrawElements( ModeFromPrimitiveType( pt ), indices.End - indices.Start, Gl.GL_UNSIGNED_SHORT, new IntPtr( indices.Start * 2 ) );
CheckGlError(); CheckGlError();
} }
public void DrawIndexedPrimitives(PrimitiveType pt, int numVerts, int numPrimitives) public void DrawIndexedPrimitives( PrimitiveType pt, int numVerts, int numPrimitives )
{ {
Gl.glDrawElements((int)pt, numPrimitives * IndicesPerPrimitive( pt ), Gl.GL_UNSIGNED_SHORT, IntPtr.Zero); Gl.glDrawElements( ModeFromPrimitiveType( pt ), numPrimitives * IndicesPerPrimitive( pt ), Gl.GL_UNSIGNED_SHORT, IntPtr.Zero );
CheckGlError(); CheckGlError();
} }
static int ModeFromPrimitiveType( PrimitiveType pt )
{
switch( pt )
{
case PrimitiveType.PointList: return Gl.GL_POINTS;
case PrimitiveType.LineList: return Gl.GL_LINES;
case PrimitiveType.TriangleList: return Gl.GL_TRIANGLES;
}
throw new NotImplementedException();
}
static int IndicesPerPrimitive( PrimitiveType pt ) static int IndicesPerPrimitive( PrimitiveType pt )
{ {
switch( pt ) switch( pt )
@@ -147,19 +186,39 @@ namespace OpenRa.GlRenderer
} }
throw new NotImplementedException(); throw new NotImplementedException();
} }
}
public struct Range<T> #region IGraphicsDevice Members
public IVertexBuffer<T> CreateVertexBuffer<T>( int size )
where T : struct
{ {
public readonly T Start, End; return new VertexBuffer<T>( this, size );
public Range(T start, T end) { Start = start; End = end; }
} }
public class VertexBuffer<T> where T : struct public IIndexBuffer CreateIndexBuffer( int size )
{
return new IndexBuffer( this, size );
}
public ITexture CreateTexture( Bitmap bitmap )
{
return new Texture( this, bitmap );
}
public IShader CreateShader( Stream stream )
{
return new Shader( this, stream );
}
#endregion
}
public class VertexBuffer<T> : IVertexBuffer<T>, IDisposable
where T : struct
{ {
int buffer; int buffer;
public VertexBuffer(GraphicsDevice dev, int size, VertexFormat fmt) public VertexBuffer(GraphicsDevice dev, int size)
{ {
Gl.glGenBuffers(1, out buffer); Gl.glGenBuffers(1, out buffer);
GraphicsDevice.CheckGlError(); GraphicsDevice.CheckGlError();
@@ -196,7 +255,7 @@ namespace OpenRa.GlRenderer
//~VertexBuffer() { Dispose(); } //~VertexBuffer() { Dispose(); }
} }
public class IndexBuffer : IDisposable public class IndexBuffer : IIndexBuffer, IDisposable
{ {
int buffer; int buffer;
@@ -233,11 +292,10 @@ namespace OpenRa.GlRenderer
//~IndexBuffer() { Dispose(); } //~IndexBuffer() { Dispose(); }
} }
public class Shader public class Shader : IShader
{ {
IntPtr effect; IntPtr effect;
IntPtr highTechnique; IntPtr technique;
IntPtr lowTechnique;
GraphicsDevice dev; GraphicsDevice dev;
public Shader(GraphicsDevice dev, Stream s) public Shader(GraphicsDevice dev, Stream s)
@@ -256,31 +314,22 @@ namespace OpenRa.GlRenderer
string.Format("Cg compile failed ({0}):\n{1}", err, results)); string.Format("Cg compile failed ({0}):\n{1}", err, results));
} }
lowTechnique = Cg.cgGetNamedTechnique(effect, "low_quality"); technique = Cg.cgGetFirstTechnique( effect );
highTechnique = Cg.cgGetNamedTechnique(effect, "high_quality"); if( technique == IntPtr.Zero )
throw new InvalidOperationException("No techniques");
if (lowTechnique != IntPtr.Zero && 0 == Cg.cgValidateTechnique(lowTechnique)) while( Cg.cgValidateTechnique( technique ) == 0 )
lowTechnique = IntPtr.Zero; {
if (highTechnique != IntPtr.Zero && 0 == Cg.cgValidateTechnique(highTechnique)) technique = Cg.cgGetNextTechnique( technique );
highTechnique = IntPtr.Zero; if( technique == IntPtr.Zero )
if (highTechnique == IntPtr.Zero && lowTechnique == IntPtr.Zero)
throw new InvalidOperationException("No valid techniques"); throw new InvalidOperationException("No valid techniques");
if( highTechnique == IntPtr.Zero )
highTechnique = lowTechnique;
if( lowTechnique == IntPtr.Zero )
lowTechnique = highTechnique;
} }
}
public ShaderQuality Quality { get; set; }
public void Render(Action a) public void Render(Action a)
{ {
CgGl.cgGLEnableProfile(dev.vertexProfile); CgGl.cgGLEnableProfile(dev.vertexProfile);
CgGl.cgGLEnableProfile(dev.fragmentProfile); CgGl.cgGLEnableProfile(dev.fragmentProfile);
var technique = Quality == ShaderQuality.High ? highTechnique : lowTechnique;
var pass = Cg.cgGetFirstPass(technique); var pass = Cg.cgGetFirstPass(technique);
while (pass != IntPtr.Zero) while (pass != IntPtr.Zero)
{ {
@@ -294,8 +343,9 @@ namespace OpenRa.GlRenderer
CgGl.cgGLDisableProfile(dev.vertexProfile); CgGl.cgGLDisableProfile(dev.vertexProfile);
} }
public void SetValue(string name, Texture texture) public void SetValue(string name, ITexture t)
{ {
var texture = (Texture)t;
var param = Cg.cgGetNamedEffectParameter( effect, name ); var param = Cg.cgGetNamedEffectParameter( effect, name );
if( param != IntPtr.Zero && texture != null ) if( param != IntPtr.Zero && texture != null )
CgGl.cgGLSetupSampler( param, texture.texture ); CgGl.cgGLSetupSampler( param, texture.texture );
@@ -311,7 +361,7 @@ namespace OpenRa.GlRenderer
public void Commit() { } public void Commit() { }
} }
public class Texture public class Texture : ITexture
{ {
internal int texture; internal int texture;
@@ -343,15 +393,4 @@ namespace OpenRa.GlRenderer
bitmap.UnlockBits(bits); bitmap.UnlockBits(bits);
} }
} }
[Flags]
public enum VertexFormat { Position, Texture2 }
public enum ShaderQuality { Low, High }
public enum PrimitiveType
{
PointList = Gl.GL_POINTS,
LineList = Gl.GL_LINES,
TriangleList = Gl.GL_TRIANGLES
}
} }

View File

@@ -48,6 +48,7 @@
<Reference Include="Tao.Cg, Version=2.0.0.0, Culture=neutral, PublicKeyToken=52fa5aba625fe731, processorArchitecture=MSIL"> <Reference Include="Tao.Cg, Version=2.0.0.0, Culture=neutral, PublicKeyToken=52fa5aba625fe731, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
</Reference> </Reference>
<Reference Include="Tao.Glfw, Version=2.6.0.0, Culture=neutral, PublicKeyToken=2bb092b6587e4402, processorArchitecture=MSIL" />
<Reference Include="Tao.OpenGl, Version=2.1.0.12, Culture=neutral, PublicKeyToken=1ca010269a4501ef, processorArchitecture=MSIL"> <Reference Include="Tao.OpenGl, Version=2.1.0.12, Culture=neutral, PublicKeyToken=1ca010269a4501ef, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
</Reference> </Reference>
@@ -59,6 +60,16 @@
<Compile Include="GraphicsDevice.cs" /> <Compile Include="GraphicsDevice.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRa.FileFormats\OpenRa.FileFormats.csproj">
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRa.FileFormats</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRa.Game\OpenRa.Game.csproj">
<Project>{0DFB103F-2962-400F-8C6D-E2C28CCBA633}</Project>
<Name>OpenRa.Game</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
@@ -67,4 +78,7 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
<PropertyGroup>
<PostBuildEvent>copy "$(TargetPath)" "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
</Project> </Project>