diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 852a553934..fa30c49956 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -203,6 +203,12 @@ FirmwaresConfigInfo.cs + + Form + + + DisplayConfig.cs + Component @@ -887,6 +893,9 @@ ControllerConfigPanel.cs + + DisplayConfig.cs + FirmwaresConfig.cs diff --git a/BizHawk.Client.EmuHawk/PresentationPanel.cs b/BizHawk.Client.EmuHawk/PresentationPanel.cs index 13b5f4e41d..9309b0c19d 100644 --- a/BizHawk.Client.EmuHawk/PresentationPanel.cs +++ b/BizHawk.Client.EmuHawk/PresentationPanel.cs @@ -26,14 +26,14 @@ namespace BizHawk.Client.EmuHawk { GL = GlobalWin.GL; - GraphicsControl = GL.CreateGraphicsControl(); - GraphicsControl.Control.Dock = DockStyle.Fill; - GraphicsControl.Control.BackColor = Color.Black; + GraphicsControl = new GraphicsControl(GL); + GraphicsControl.Dock = DockStyle.Fill; + GraphicsControl.BackColor = Color.Black; //pass through these events to the form. we might need a more scalable solution for mousedown etc. for zapper and whatnot. //http://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control (HTTRANSPARENT) - GraphicsControl.Control.MouseDoubleClick += (o, e) => HandleFullscreenToggle(o, e); - GraphicsControl.Control.MouseClick += (o, e) => GlobalWin.MainForm.MainForm_MouseClick(o, e); + GraphicsControl.MouseDoubleClick += (o, e) => HandleFullscreenToggle(o, e); + GraphicsControl.MouseClick += (o, e) => GlobalWin.MainForm.MainForm_MouseClick(o, e); } public void Dispose() @@ -47,8 +47,8 @@ namespace BizHawk.Client.EmuHawk private bool Vsync; - public Control Control { get { return GraphicsControl.Control; } } - public static implicit operator Control(PresentationPanel self) { return self.GraphicsControl.Control; } + public Control Control { get { return GraphicsControl; } } + public static implicit operator Control(PresentationPanel self) { return self.GraphicsControl; } private void HandleFullscreenToggle(object sender, MouseEventArgs e) { @@ -70,7 +70,7 @@ namespace BizHawk.Client.EmuHawk throw new InvalidOperationException("Not supported right now, sorry"); } - public Size NativeSize { get { return GraphicsControl.Control.ClientSize; } } + public Size NativeSize { get { return GraphicsControl.ClientSize; } } } diff --git a/BizHawk.Client.EmuHawk/RenderPanel.cs b/BizHawk.Client.EmuHawk/RenderPanel.cs deleted file mode 100644 index 3af8b88a11..0000000000 --- a/BizHawk.Client.EmuHawk/RenderPanel.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using System.Drawing; -using sd=System.Drawing; -using sysdrawingfont=System.Drawing.Font; -using sysdrawing2d=System.Drawing.Drawing2D; -using System.IO; -using System.Threading; -using System.Windows.Forms; -#if WINDOWS -using SlimDX; -#endif - -using BizHawk.Client.Common; -using BizHawk.Bizware.BizwareGL; - -namespace BizHawk.Client.EmuHawk -{ - /// - /// Handles the EmuHawk main presentation control - final display only. - /// Compositing, filters, etc., should be handled by DisplayManager - /// - public class PresentationPanel : IBlitter - { - public PresentationPanel() - { - GL = GlobalWin.GL; - - GraphicsControl = GL.CreateGraphicsControl(); - GraphicsControl.Control.Dock = DockStyle.Fill; - GraphicsControl.Control.BackColor = Color.Black; - - //prepare a renderer - Renderer = new GuiRenderer(GL); - - //pass through these events to the form. we might need a more scalable solution for mousedown etc. for zapper and whatnot. - //http://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control (HTTRANSPARENT) - GraphicsControl.Control.MouseDoubleClick += (o, e) => HandleFullscreenToggle(o, e); - GraphicsControl.Control.MouseClick += (o, e) => GlobalWin.MainForm.MainForm_MouseClick(o, e); - - using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt")) - using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png")) - TheOneFont = new StringRenderer(GL, xml, tex); - } - - public void Dispose() - { - //this hasnt been analyzed real well yet - Renderer.Dispose(); - GraphicsControl.Dispose(); - TheOneFont.Dispose(); - if (LastSurfaceTexture != null) - LastSurfaceTexture.Dispose(); - //gl shouldnt be disposed! it should be a global resource! probably managed elsewhere - } - - public Control Control { get { return GraphicsControl.Control; } } - public static implicit operator Control(PresentationPanel self) { return self.GraphicsControl.Control; } - StringRenderer TheOneFont; - public Bizware.BizwareGL.GraphicsControl GraphicsControl; - static Bizware.BizwareGL.IGL GL; - GuiRenderer Renderer; - Texture2d LastSurfaceTexture; - - private void HandleFullscreenToggle(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Left) - GlobalWin.MainForm.ToggleFullscreen(); - } - - class FontWrapper : IBlitterFont - { - public FontWrapper(StringRenderer font) - { - this.font = font; - } - - public readonly StringRenderer font; - } - - - void IBlitter.Open() - { - Renderer.Begin(GraphicsControl.Control.ClientSize.Width, GraphicsControl.Control.ClientSize.Height); - Renderer.SetBlendState(GL.BlendNormal); - ClipBounds = new sd.Rectangle(0, 0, NativeSize.Width, NativeSize.Height); - } - void IBlitter.Close() { - Renderer.End(); - } - IBlitterFont IBlitter.GetFontType(string fontType) { return new FontWrapper(TheOneFont); } - void IBlitter.DrawString(string s, IBlitterFont font, Color color, float x, float y) - { - var stringRenderer = ((FontWrapper)font).font; - Renderer.SetModulateColor(color); - stringRenderer.RenderString(Renderer, x, y, s); - Renderer.SetModulateColorWhite(); - } - SizeF IBlitter.MeasureString(string s, IBlitterFont font) - { - var stringRenderer = ((FontWrapper)font).font; - return stringRenderer.Measure(s); - } - public sd.Rectangle ClipBounds { get; set; } - - public bool Resized { get; set; } - - public void Clear(Color color) - { - GraphicsControl.Begin(); - } - - public sd.Point ScreenToScreen(sd.Point p) - { - p = GraphicsControl.Control.PointToClient(p); - sd.Point ret = new sd.Point(p.X * sw / GraphicsControl.Control.Width, - p.Y * sh / GraphicsControl.Control.Height); - return ret; - } - - public Size NativeSize { get { return GraphicsControl.Control.ClientSize; } } - - //the hell is this doing here? horrible - private bool VsyncRequested - { - get - { - if (Global.ForceNoThrottle) - return false; - return Global.Config.VSyncThrottle || Global.Config.VSync; - } - } - - public void RenderOverlay(DisplaySurface surface) - { - RenderExec(null, surface); - } - - public void Render(BitmapBuffer surface) - { - RenderExec(surface,null); - } - - private bool Vsync; - int sw=1, sh=1; - public void RenderExec(BitmapBuffer surface, DisplaySurface displaySurface) - { - GraphicsControl.Begin(); - - if (Resized || Vsync != VsyncRequested) - { - GraphicsControl.SetVsync(VsyncRequested); - } - - bool overlay = false; - if(displaySurface != null) - { - overlay = true; - displaySurface.ToBitmap(false); - surface = new BitmapBuffer(displaySurface.PeekBitmap(), new BitmapLoadOptions()); - } - - if (sw != surface.Width || sh != surface.Height || LastSurfaceTexture == null) - { - LastSurfaceTexture = GL.LoadTexture(surface); - } - else - { - GL.LoadTextureData(LastSurfaceTexture, surface); - } - - if(Global.Config.DispBlurry) - LastSurfaceTexture.SetFilterLinear(); - else - LastSurfaceTexture.SetFilterNearest(); - - - sw = surface.Width; - sh = surface.Height; - - Resized = false; - - // figure out scaling factor - float vw = (float)GraphicsControl.Control.Width; - float vh = (float)GraphicsControl.Control.Height; - float widthScale = vw / surface.Width; - float heightScale = vh / surface.Height; - float finalScale = Math.Min(widthScale, heightScale); - float dx = (int)((vw - finalScale * surface.Width)/2); - float dy = (int)((vh - finalScale * surface.Height)/2); - - if (!overlay) - { - GL.SetClearColor(Color.Black); //TODO GL - set from background color - GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit); - } - - Renderer.Begin(GraphicsControl.Control.ClientSize.Width, GraphicsControl.Control.ClientSize.Height); - if (overlay) - Renderer.SetBlendState(GL.BlendNormal); - else Renderer.SetBlendState(GL.BlendNone); - Renderer.Modelview.Translate(dx, dy); - Renderer.Modelview.Scale(finalScale); - Renderer.Draw(LastSurfaceTexture); - Renderer.End(); - - GraphicsControl.End(); - } - - public void Present() - { - GraphicsControl.Begin(); - GraphicsControl.SwapBuffers(); - GraphicsControl.End(); - } - - public void RenderOverlay(BitmapBuffer surface) - { - //TODO GL - draw transparent overlay - } - } - - public interface IBlitter - { - void Open(); - void Close(); - IBlitterFont GetFontType(string fontType); - void DrawString(string s, IBlitterFont font, Color color, float x, float y); - SizeF MeasureString(string s, IBlitterFont font); - sd.Rectangle ClipBounds { get; set; } - } - - public interface IBlitterFont { } - -} diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfig.Designer.cs b/BizHawk.Client.EmuHawk/config/DisplayConfig.Designer.cs new file mode 100644 index 0000000000..a2fc39835a --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/DisplayConfig.Designer.cs @@ -0,0 +1,278 @@ +namespace BizHawk.Client.EmuHawk.config +{ + partial class DisplayConfig + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.button1 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.listView2 = new System.Windows.Forms.ListView(); + this.label1 = new System.Windows.Forms.Label(); + this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.button2 = new System.Windows.Forms.Button(); + this.panel3 = new System.Windows.Forms.Panel(); + this.label2 = new System.Windows.Forms.Label(); + this.panel4 = new System.Windows.Forms.Panel(); + this.listView1 = new System.Windows.Forms.ListView(); + this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.tableLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.panel3.SuspendLayout(); + this.panel4.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.button3, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.panel1, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.panel2, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.panel3, 0, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(557, 433); + this.tableLayoutPanel1.TabIndex = 1; + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.button1.Location = new System.Drawing.Point(74, 3); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 2; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + // + // button3 + // + this.button3.Location = new System.Drawing.Point(3, 407); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(75, 23); + this.button3.TabIndex = 4; + this.button3.Text = "Defaults"; + this.button3.UseVisualStyleBackColor = true; + // + // listView2 + // + this.listView2.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader4}); + this.listView2.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView2.Location = new System.Drawing.Point(0, 13); + this.listView2.Name = "listView2"; + this.listView2.Size = new System.Drawing.Size(224, 385); + this.listView2.TabIndex = 5; + this.listView2.UseCompatibleStateImageBehavior = false; + this.listView2.View = System.Windows.Forms.View.Details; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(38, 13); + this.label1.TabIndex = 6; + this.label1.Text = "Library"; + // + // columnHeader4 + // + this.columnHeader4.Text = ""; + this.columnHeader4.Width = 101; + // + // panel1 + // + this.panel1.Controls.Add(this.listView2); + this.panel1.Controls.Add(this.label1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(330, 3); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(224, 398); + this.panel1.TabIndex = 7; + // + // panel2 + // + this.panel2.AutoSize = true; + this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel2.Controls.Add(this.button2); + this.panel2.Controls.Add(this.button1); + this.panel2.Location = new System.Drawing.Point(327, 404); + this.panel2.Margin = new System.Windows.Forms.Padding(0); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(230, 29); + this.panel2.TabIndex = 8; + // + // button2 + // + this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.button2.Location = new System.Drawing.Point(155, 3); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(75, 23); + this.button2.TabIndex = 3; + this.button2.Text = "Cancel"; + this.button2.UseVisualStyleBackColor = true; + // + // panel3 + // + this.panel3.Controls.Add(this.listView1); + this.panel3.Controls.Add(this.label2); + this.panel3.Controls.Add(this.panel4); + this.panel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel3.Location = new System.Drawing.Point(3, 3); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(321, 398); + this.panel3.TabIndex = 9; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Dock = System.Windows.Forms.DockStyle.Top; + this.label2.Location = new System.Drawing.Point(0, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(172, 13); + this.label2.TabIndex = 7; + this.label2.Text = "Current Layers/Filters Configuration"; + // + // panel4 + // + this.panel4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.panel4.Controls.Add(this.groupBox1); + this.panel4.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel4.Location = new System.Drawing.Point(0, 298); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(321, 100); + this.panel4.TabIndex = 4; + // + // listView1 + // + this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader1, + this.columnHeader2, + this.columnHeader3}); + this.listView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView1.Location = new System.Drawing.Point(0, 13); + this.listView1.Name = "listView1"; + this.listView1.Size = new System.Drawing.Size(321, 285); + this.listView1.TabIndex = 9; + this.listView1.UseCompatibleStateImageBehavior = false; + this.listView1.View = System.Windows.Forms.View.Details; + // + // columnHeader1 + // + this.columnHeader1.Text = "Input"; + this.columnHeader1.Width = 75; + // + // columnHeader2 + // + this.columnHeader2.Text = "Output"; + this.columnHeader2.Width = 85; + // + // columnHeader3 + // + this.columnHeader3.Text = "Description"; + this.columnHeader3.Width = 88; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Location = new System.Drawing.Point(6, 19); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(85, 17); + this.checkBox1.TabIndex = 0; + this.checkBox1.Text = "Bilinear Filter"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.checkBox1); + this.groupBox1.Location = new System.Drawing.Point(7, 3); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(200, 90); + this.groupBox1.TabIndex = 1; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Final Presentation:"; + // + // DisplayConfig + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(557, 433); + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "DisplayConfig"; + this.Text = "Display Configuration"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.panel2.ResumeLayout(false); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.panel4.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ListView listView2; + private System.Windows.Forms.ColumnHeader columnHeader4; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.ListView listView1; + private System.Windows.Forms.ColumnHeader columnHeader1; + private System.Windows.Forms.ColumnHeader columnHeader2; + private System.Windows.Forms.ColumnHeader columnHeader3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.CheckBox checkBox1; + + } +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfig.cs b/BizHawk.Client.EmuHawk/config/DisplayConfig.cs new file mode 100644 index 0000000000..fcc14c4f9c --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/DisplayConfig.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace BizHawk.Client.EmuHawk.config +{ + public partial class DisplayConfig : Form + { + public DisplayConfig() + { + InitializeComponent(); + } + } +} diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfig.resx b/BizHawk.Client.EmuHawk/config/DisplayConfig.resx new file mode 100644 index 0000000000..29dcb1b3a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/DisplayConfig.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj index bf8f6cb396..5f0a1ccb97 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj @@ -59,6 +59,9 @@ + + UserControl + diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/Enums.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/Enums.cs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/GraphicsControl_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/GraphicsControl_TK.cs new file mode 100644 index 0000000000..335b5f9cf0 --- /dev/null +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/GraphicsControl_TK.cs @@ -0,0 +1,61 @@ +using System; +using System.Reflection; +using System.Threading; +using System.IO; +using System.Collections.Generic; +using System.Windows.Forms; + +using BizHawk.Bizware.BizwareGL; + +using OpenTK; +using OpenTK.Graphics; +using OpenTK.Graphics.OpenGL; + +namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK +{ + class GLControlWrapper : GLControl, IGraphicsControl + { + //Note: In order to work around bugs in OpenTK which sometimes do things to a context without making that context active first... + //we are going to push and pop the context before doing stuff + + public GLControlWrapper(IGL_TK owner) + : base(GraphicsMode.Default, 2, 0, GraphicsContextFlags.Default) + { + Owner = owner; + GLControl = this; + } + + global::OpenTK.GLControl GLControl; + IGL_TK Owner; + + public Control Control { get { return this; } } + + + public void SetVsync(bool state) + { + //IGraphicsContext curr = global::OpenTK.Graphics.GraphicsContext.CurrentContext; + GLControl.MakeCurrent(); + GLControl.VSync = state; + //Owner.MakeContextCurrent(curr, Owner.NativeWindowsForContexts[curr]); + } + + public void Begin() + { + Owner.MakeContextCurrent(GLControl.Context, GLControl.WindowInfo); + } + + public void End() + { + //this slows things down too much + //Owner.MakeDefaultCurrent(); + } + + public new void SwapBuffers() + { + //IGraphicsContext curr = global::OpenTK.Graphics.GraphicsContext.CurrentContext; + base.MakeCurrent(); + base.SwapBuffers(); + //Owner.MakeContextCurrent(curr, Owner.NativeWindowsForContexts[curr]); + } + } +} \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs index 94cdf16af8..5dceced690 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs @@ -74,71 +74,16 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK GL.ClearColor(color); } - class GLControlWrapper : GraphicsControl + IGraphicsControl IGL.Internal_CreateGraphicsControl() { - //Note: In order to work around bugs in OpenTK which sometimes do things to a context without making that context active first... - //we are going to push and pop the context before doing stuff - - public GLControlWrapper(IGL_TK owner) - { - Owner = owner; - } - - IGL_TK Owner; - - public override swf.Control Control { get { return MyControl; } } - - public override void SetVsync(bool state) - { - //IGraphicsContext curr = global::OpenTK.Graphics.GraphicsContext.CurrentContext; - MyControl.MakeCurrent(); - MyControl.VSync = state; - //Owner.MakeContextCurrent(curr, Owner.NativeWindowsForContexts[curr]); - } - - public override void Begin() - { - Owner.MakeContextCurrent(MyControl.Context, MyControl.WindowInfo); - } - - public override void End() - { - //this slows things down too much - //Owner.MakeDefaultCurrent(); - } - - public override void SwapBuffers() - { - //IGraphicsContext curr = global::OpenTK.Graphics.GraphicsContext.CurrentContext; - MyControl.MakeCurrent(); - MyControl.SwapBuffers(); - //Owner.MakeContextCurrent(curr, Owner.NativeWindowsForContexts[curr]); - } - - public override void Dispose() - { - //TODO - what happens if this context was current? - MyControl.Dispose(); - MyControl = null; - } - - public GLControl MyControl; - } - - GraphicsControl IGL.CreateGraphicsControl() - { - var glc = new GLControl(GraphicsMode.Default, 2, 0, GraphicsContextFlags.Default); + var glc = new GLControlWrapper(this); glc.CreateControl(); //now the control's context will be current. annoying! fix it. MakeDefaultCurrent(); - GLControlWrapper wrapper = new GLControlWrapper(this); - wrapper.MyControl = glc; - //this might be important.. or it might not. it's ready, in case we need it - //glc.GetType().GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(glc, new object[] { System.Windows.Forms.ControlStyles.UserMouse, true }); - return wrapper; + return glc; } IntPtr IGL.GenTexture() { return new IntPtr(GL.GenTexture()); } @@ -376,6 +321,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK } } + void IGL.FreeRenderTarget(RenderTarget rt) + { + rt.Texture2d.Dispose(); + GL.DeleteFramebuffer(rt.Id.ToInt32()); + } + unsafe RenderTarget IGL.CreateRenderTarget(int w, int h) { //create a texture for it @@ -557,12 +508,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK } } - void MakeDefaultCurrent() + internal void MakeDefaultCurrent() { MakeContextCurrent(this.GraphicsContext, OffscreenNativeWindow.WindowInfo); } - void MakeContextCurrent(IGraphicsContext context, global::OpenTK.Platform.IWindowInfo windowInfo) + internal void MakeContextCurrent(IGraphicsContext context, global::OpenTK.Platform.IWindowInfo windowInfo) { //TODO - if we're churning through contexts quickly, this will sort of be a memory leak, since they'll be memoized forever in here //maybe make it a weakptr or something diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj index 2dbe80b1f8..be1485d191 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj @@ -57,15 +57,21 @@ - + + UserControl + + + + UserControl + diff --git a/Bizware/BizHawk.Bizware.BizwareGL/GraphicsControl.cs b/Bizware/BizHawk.Bizware.BizwareGL/GraphicsControl.cs index 85fe674841..6fa42b1722 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/GraphicsControl.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/GraphicsControl.cs @@ -1,52 +1,53 @@ using System; -using swf = System.Windows.Forms; +using System.Windows.Forms; namespace BizHawk.Bizware.BizwareGL { /// - /// Represents + /// a base class for deriving/wrapping from a IGraphicsControl. + /// This is to work around the annoyance that we cant inherit from a control whose type is unknown (it would be delivered by the selected BizwareGL driver) + /// and so we have to resort to composition and c# sucks and events suck. /// - public abstract class GraphicsControl : IDisposable + public class GraphicsControl : UserControl { - /// - /// Gets the control that this interface is wrapping - /// - public abstract swf.Control Control { get; } + public GraphicsControl(IGL owner) + { + SetStyle(ControlStyles.Opaque, true); + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.UserMouse, true); - public static implicit operator swf.Control(GraphicsControl ctrl) { return ctrl.Control; } + //in case we need it + //GLControl.GetType().GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(GLControl, new object[] { System.Windows.Forms.ControlStyles.UserMouse, true }); - /// - /// The width of the control - /// - public int Width { get { return Control.Width; } } - /// - /// The height of the control - /// - public int Height { get { return Control.Height; } } - - /// - /// Sets whether presentation operations on this control will vsync - /// - public abstract void SetVsync(bool state); + IGC = owner.Internal_CreateGraphicsControl(); + Managed = IGC as Control; + Managed.Dock = DockStyle.Fill; + Controls.Add(Managed); - /// - /// Swaps the buffers for this control - /// - public abstract void SwapBuffers(); + //pass through these events to the form. I tried really hard to find a better way, but there is none. + //(dont use HTTRANSPARENT, it isnt portable, I would assume) + Managed.MouseDoubleClick += (object sender, MouseEventArgs e) => OnMouseDoubleClick(e); + Managed.MouseClick += (object sender, MouseEventArgs e) => OnMouseClick(e); - /// - /// Makes this control current for rendering operations. - /// Note that at this time, the window size shouldnt change until End() or else something bad might happen - /// Please be aware that this might change the rendering context, meaning that some things you set without calling BeginControl/EndControl might not be affected - /// - public abstract void Begin(); + //the GraphicsControl is occupying all of our area. So we pretty much never get paint events ourselves. + //So lets capture its paint event and use it for ourselves (it doesnt know how to do anything, anyway) + Managed.Paint += new PaintEventHandler(GraphicsControl_Paint); + } - /// - /// Ends rendering on the specified control. - /// - public abstract void End(); + void GraphicsControl_Paint(object sender, PaintEventArgs e) + { + OnPaint(e); + } - public abstract void Dispose(); + IGraphicsControl IGC; + Control Managed; + + //public virtual Control Control { get { return Managed; } } //do we need this anymore? + public virtual void SetVsync(bool state) { IGC.SetVsync(state); } + public virtual void SwapBuffers() { IGC.SwapBuffers(); } + public virtual void Begin() { IGC.Begin(); } + public virtual void End() { IGC.End(); } } } \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs b/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs index b721ef7075..5b9d096cfb 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs @@ -17,10 +17,6 @@ namespace BizHawk.Bizware.BizwareGL /// public interface IGL : IDisposable { - /// - /// Returns an a control optimized for drawing onto the screen. - /// - GraphicsControl CreateGraphicsControl(); /// /// Clears the specified buffer parts @@ -113,6 +109,11 @@ namespace BizHawk.Bizware.BizwareGL /// void FreeTexture(IntPtr texHandle); + /// + /// frees the provided render target + /// + void FreeRenderTarget(RenderTarget rt); + /// /// Binds this texture as the current texture2d target for parameter-specification /// @@ -218,5 +219,7 @@ namespace BizHawk.Bizware.BizwareGL /// Binds a RenderTarget for current rendering /// void BindRenderTarget(RenderTarget rt); + + IGraphicsControl Internal_CreateGraphicsControl(); } } diff --git a/Bizware/BizHawk.Bizware.BizwareGL/IGraphicsControl.cs b/Bizware/BizHawk.Bizware.BizwareGL/IGraphicsControl.cs new file mode 100644 index 0000000000..881283e57d --- /dev/null +++ b/Bizware/BizHawk.Bizware.BizwareGL/IGraphicsControl.cs @@ -0,0 +1,32 @@ +using System; +using System.Windows.Forms; + +namespace BizHawk.Bizware.BizwareGL +{ + public interface IGraphicsControl : IDisposable + { + /// + /// Sets whether presentation operations on this control will vsync + /// + void SetVsync(bool state); + + /// + /// Swaps the buffers for this control + /// + void SwapBuffers(); + + /// + /// Makes this control current for rendering operations. + /// Note that at this time, the window size shouldnt change until End() or else something bad might happen + /// Please be aware that this might change the rendering context, meaning that some things you set without calling BeginControl/EndControl might not be affected + /// + void Begin(); + + /// + /// Ends rendering on the specified control. + /// + void End(); + } + + +} \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.BizwareGL/RenderTarget.cs b/Bizware/BizHawk.Bizware.BizwareGL/RenderTarget.cs index 2dc8736b04..ceac7215a9 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/RenderTarget.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/RenderTarget.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace BizHawk.Bizware.BizwareGL { - public class RenderTarget + public class RenderTarget : IDisposable { public RenderTarget(IGL owner, IntPtr handle, Texture2d tex) { @@ -25,5 +25,10 @@ namespace BizHawk.Bizware.BizwareGL { Owner.BindRenderTarget(this); } + + public void Dispose() + { + Owner.FreeRenderTarget(this); + } } } \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.BizwareGL/RetainedGraphicsControl.cs b/Bizware/BizHawk.Bizware.BizwareGL/RetainedGraphicsControl.cs new file mode 100644 index 0000000000..8a4acdc57e --- /dev/null +++ b/Bizware/BizHawk.Bizware.BizwareGL/RetainedGraphicsControl.cs @@ -0,0 +1,104 @@ +using System; +using System.Windows.Forms; +using System.Drawing; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using BizHawk.Bizware.BizwareGL; +using OpenTK.Graphics.OpenGL; + +namespace BizHawk.Bizware.Test +{ + /// + /// Adapts a GraphicsControl to gain the power of remembering what was drawn to it, and keeping it presented in response to Paint events + /// + public class RetainedGraphicsControl : GraphicsControl + { + public RetainedGraphicsControl(IGL gl) + : base(gl) + { + GL = gl; + GuiRenderer = new GuiRenderer(gl); + } + + /// + /// Control whether rendering goes into the retaining buffer (it's slower) or straight to the viewport. + /// This could be useful as a performance hack, or if someone was very clever, they could wait for a control to get deactivated, enable retaining, and render it one more time. + /// Of course, even better still is to be able to repaint viewports continually, but sometimes thats annoying. + /// + public bool Retain + { + get { return _retain; } + set + { + if (_retain && !value) + { + rt.Dispose(); + rt = null; + } + _retain = value; + } + } + bool _retain = true; + + IGL GL; + RenderTarget rt; + GuiRenderer GuiRenderer; + + public override void Begin() + { + base.Begin(); + + if (_retain) + { + //TODO - frugalize me + if (rt != null) + rt.Dispose(); + rt = GL.CreateRenderTarget(Width, Height); + rt.Bind(); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + //todo - check whether we're begun? + base.Begin(); + Draw(); + base.End(); + } + + void Draw() + { + if (rt == null) return; + GuiRenderer.Begin(Width, Height, true); + GuiRenderer.SetBlendState(GL.BlendNone); + GuiRenderer.Draw(rt.Texture2d); + GuiRenderer.End(); + base.SwapBuffers(); + } + + public override void SwapBuffers() + { + //if we're not retaining, then we havent been collecting into a framebuffer. just swap it + if (!_retain) + { + base.SwapBuffers(); + return; + } + + //if we're retaining, then we cant draw until we unbind! its semantically a bit odd, but we expect users to call SwapBuffers() before end, so we cant unbind in End() even thoug hit makes a bit more sense. + rt.Unbind(); + Draw(); + } + + public override void End() + { + if (_retain) + rt.Unbind(); + base.End(); + } + } + +} \ No newline at end of file diff --git a/Bizware/BizHawk.Bizware.Test/Program.cs b/Bizware/BizHawk.Bizware.Test/Program.cs index 098f1bcbeb..fc4021fe45 100644 --- a/Bizware/BizHawk.Bizware.Test/Program.cs +++ b/Bizware/BizHawk.Bizware.Test/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Windows.Forms; using System.Drawing; using System.Collections.Generic; using System.Linq; @@ -11,12 +12,11 @@ namespace BizHawk.Bizware.Test { class Program { + static unsafe void Main(string[] args) { BizHawk.Bizware.BizwareGL.IGL igl = new BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(); - - List testArts = new List(); ArtManager am = new ArtManager(igl); foreach (var name in typeof(Program).Assembly.GetManifestResourceNames()) @@ -31,11 +31,10 @@ namespace BizHawk.Bizware.Test GuiRenderer gr = new GuiRenderer(igl); - TestForm tf = new TestForm(); - GraphicsControl c = igl.CreateGraphicsControl(); + RetainedGraphicsControl c = new RetainedGraphicsControl(igl); tf.Controls.Add(c); - c.Control.Dock = System.Windows.Forms.DockStyle.Fill; + c.Dock = System.Windows.Forms.DockStyle.Fill; tf.FormClosing += (object sender, System.Windows.Forms.FormClosingEventArgs e) => { tf.Controls.Remove(c); @@ -44,6 +43,8 @@ namespace BizHawk.Bizware.Test }; tf.Show(); + //tf.Paint += (object sender, PaintEventArgs e) => c.Refresh(); + c.SetVsync(false); //create a render target, in the control context @@ -58,45 +59,57 @@ namespace BizHawk.Bizware.Test rt.Unbind(); c.End(); + bool running = true; + c.MouseClick += (object sender, MouseEventArgs e) => + { + if(e.Button == MouseButtons.Left) + running ^= true; + if (e.Button == MouseButtons.Right) + c.Retain ^= true; + }; + DateTime start = DateTime.Now; int wobble = 0; for (; ; ) { if (c == null) break; - c.Begin(); + if (running) + { + c.Begin(); + igl.SetClearColor(Color.Red); + igl.Clear(ClearBufferMask.ColorBufferBit); - igl.SetClearColor(Color.Red); - igl.Clear(ClearBufferMask.ColorBufferBit); + int frame = (int)((DateTime.Now - start).TotalSeconds) % testArts.Count; - int frame = (int)((DateTime.Now - start).TotalSeconds) % testArts.Count; + gr.Begin(c.ClientSize.Width, c.ClientSize.Height); - gr.Begin(c.Control.ClientSize.Width, c.Control.ClientSize.Height); - - gr.SetBlendState(igl.BlendNone); - gr.Draw(rt.Texture2d, 0, 20); - gr.SetBlendState(igl.BlendNormal); + gr.SetBlendState(igl.BlendNone); + gr.Draw(rt.Texture2d, 0, 20); + gr.SetBlendState(igl.BlendNormal); - sr.RenderString(gr, 0, 0, "?? fps"); - gr.Modelview.Translate((float)Math.Sin(wobble / 360.0f) * 50, 0); - gr.Modelview.Translate(100, 100); - gr.Modelview.Push(); - gr.Modelview.Translate(testArts[frame].Width, 0); - gr.Modelview.Scale(-1, 1); - wobble++; - gr.SetModulateColor(Color.Yellow); - gr.DrawFlipped(testArts[frame], true, false); - gr.SetModulateColorWhite(); - gr.Modelview.Pop(); - gr.SetBlendState(igl.BlendNormal); - gr.Draw(smile); - gr.End(); + sr.RenderString(gr, 0, 0, "?? fps"); + gr.Modelview.Translate((float)Math.Sin(wobble / 360.0f) * 50, 0); + gr.Modelview.Translate(100, 100); + gr.Modelview.Push(); + gr.Modelview.Translate(testArts[frame].Width, 0); + gr.Modelview.Scale(-1, 1); + wobble++; + gr.SetModulateColor(Color.Yellow); + gr.DrawFlipped(testArts[frame], true, false); + gr.SetModulateColorWhite(); + gr.Modelview.Pop(); + gr.SetBlendState(igl.BlendNormal); + gr.Draw(smile); + gr.End(); - c.SwapBuffers(); - c.End(); + c.SwapBuffers(); + c.End(); + } System.Windows.Forms.Application.DoEvents(); + System.Threading.Thread.Sleep(0); } } }