From 8a53a142bb55e62258ba03c3235e99b6f5f53622 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Sat, 28 Feb 2009 20:40:10 +0000 Subject: [PATCH] Massively improved example: more information displayed, better layout. --- .../WinForms/W03_Extensions.Designer.cs | 190 ++++++++++++++-- Source/Examples/WinForms/W03_Extensions.cs | 208 +++++++++++++----- Source/Examples/WinForms/W03_Extensions.resx | 6 + 3 files changed, 329 insertions(+), 75 deletions(-) diff --git a/Source/Examples/WinForms/W03_Extensions.Designer.cs b/Source/Examples/WinForms/W03_Extensions.Designer.cs index 210bf4ba..9091dbdf 100644 --- a/Source/Examples/WinForms/W03_Extensions.Designer.cs +++ b/Source/Examples/WinForms/W03_Extensions.Designer.cs @@ -28,41 +28,199 @@ /// private void InitializeComponent() { - this.listBox1 = new System.Windows.Forms.ListBox(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.LabelVendor = new System.Windows.Forms.Label(); + this.LabelRenderer = new System.Windows.Forms.Label(); + this.LabelVersion = new System.Windows.Forms.Label(); + this.TextBoxVendor = new System.Windows.Forms.TextBox(); + this.TextBoxRenderer = new System.Windows.Forms.TextBox(); + this.TextBoxVersion = new System.Windows.Forms.TextBox(); + this.LabelSupport = new System.Windows.Forms.Label(); + this.TextBoxSupport = new System.Windows.Forms.TextBox(); + this.SupportedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.NameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CategoryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Version = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ExtensionColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); this.SuspendLayout(); // - // listBox1 - // - this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.listBox1.FormattingEnabled = true; - this.listBox1.Location = new System.Drawing.Point(0, 0); - this.listBox1.Name = "listBox1"; - this.listBox1.Size = new System.Drawing.Size(284, 264); - this.listBox1.TabIndex = 0; - // // backgroundWorker1 // this.backgroundWorker1.WorkerReportsProgress = true; this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.SupportedColumn, + this.NameColumn, + this.CategoryColumn, + this.Version, + this.ExtensionColumn}); + this.dataGridView1.Location = new System.Drawing.Point(0, 110); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.ReadOnly = true; + this.dataGridView1.Size = new System.Drawing.Size(467, 454); + this.dataGridView1.TabIndex = 1; + // + // LabelVendor + // + this.LabelVendor.AutoSize = true; + this.LabelVendor.Location = new System.Drawing.Point(12, 9); + this.LabelVendor.Name = "LabelVendor"; + this.LabelVendor.Size = new System.Drawing.Size(41, 13); + this.LabelVendor.TabIndex = 2; + this.LabelVendor.Text = "Vendor"; + // + // LabelRenderer + // + this.LabelRenderer.AutoSize = true; + this.LabelRenderer.Location = new System.Drawing.Point(12, 35); + this.LabelRenderer.Name = "LabelRenderer"; + this.LabelRenderer.Size = new System.Drawing.Size(51, 13); + this.LabelRenderer.TabIndex = 3; + this.LabelRenderer.Text = "Renderer"; + // + // LabelVersion + // + this.LabelVersion.AutoSize = true; + this.LabelVersion.Location = new System.Drawing.Point(12, 61); + this.LabelVersion.Name = "LabelVersion"; + this.LabelVersion.Size = new System.Drawing.Size(42, 13); + this.LabelVersion.TabIndex = 4; + this.LabelVersion.Text = "Version"; + // + // TextBoxVendor + // + this.TextBoxVendor.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TextBoxVendor.Location = new System.Drawing.Point(70, 6); + this.TextBoxVendor.Name = "TextBoxVendor"; + this.TextBoxVendor.ReadOnly = true; + this.TextBoxVendor.Size = new System.Drawing.Size(385, 20); + this.TextBoxVendor.TabIndex = 5; + // + // TextBoxRenderer + // + this.TextBoxRenderer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TextBoxRenderer.Location = new System.Drawing.Point(70, 32); + this.TextBoxRenderer.Name = "TextBoxRenderer"; + this.TextBoxRenderer.ReadOnly = true; + this.TextBoxRenderer.Size = new System.Drawing.Size(385, 20); + this.TextBoxRenderer.TabIndex = 6; + // + // TextBoxVersion + // + this.TextBoxVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TextBoxVersion.Location = new System.Drawing.Point(70, 58); + this.TextBoxVersion.Name = "TextBoxVersion"; + this.TextBoxVersion.ReadOnly = true; + this.TextBoxVersion.Size = new System.Drawing.Size(385, 20); + this.TextBoxVersion.TabIndex = 7; + // + // LabelSupport + // + this.LabelSupport.AutoSize = true; + this.LabelSupport.Location = new System.Drawing.Point(12, 87); + this.LabelSupport.Name = "LabelSupport"; + this.LabelSupport.Size = new System.Drawing.Size(44, 13); + this.LabelSupport.TabIndex = 8; + this.LabelSupport.Text = "Support"; + // + // TextBoxSupport + // + this.TextBoxSupport.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TextBoxSupport.Location = new System.Drawing.Point(70, 84); + this.TextBoxSupport.Name = "TextBoxSupport"; + this.TextBoxSupport.ReadOnly = true; + this.TextBoxSupport.Size = new System.Drawing.Size(385, 20); + this.TextBoxSupport.TabIndex = 9; + // + // SupportedColumn + // + this.SupportedColumn.HeaderText = ""; + this.SupportedColumn.Name = "SupportedColumn"; + this.SupportedColumn.ReadOnly = true; + this.SupportedColumn.Width = 24; + // + // NameColumn + // + this.NameColumn.HeaderText = "Name"; + this.NameColumn.Name = "NameColumn"; + this.NameColumn.ReadOnly = true; + // + // CategoryColumn + // + this.CategoryColumn.HeaderText = "Category"; + this.CategoryColumn.Name = "CategoryColumn"; + this.CategoryColumn.ReadOnly = true; + // + // Version + // + this.Version.HeaderText = "Introduced"; + this.Version.Name = "Version"; + this.Version.ReadOnly = true; + // + // ExtensionColumn + // + this.ExtensionColumn.HeaderText = "Extension"; + this.ExtensionColumn.Name = "ExtensionColumn"; + this.ExtensionColumn.ReadOnly = true; // // W03_Extensions // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(284, 264); - this.Controls.Add(this.listBox1); + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.AutoSize = true; + this.ClientSize = new System.Drawing.Size(467, 564); + this.Controls.Add(this.TextBoxSupport); + this.Controls.Add(this.LabelSupport); + this.Controls.Add(this.TextBoxVersion); + this.Controls.Add(this.TextBoxRenderer); + this.Controls.Add(this.TextBoxVendor); + this.Controls.Add(this.LabelVersion); + this.Controls.Add(this.LabelRenderer); + this.Controls.Add(this.LabelVendor); + this.Controls.Add(this.dataGridView1); this.Name = "W03_Extensions"; this.Text = "W03_Extensions"; + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); this.ResumeLayout(false); + this.PerformLayout(); } #endregion - private System.Windows.Forms.ListBox listBox1; private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.DataGridViewCheckBoxColumn ColumnSupported; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnName; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnCategory; + private System.Windows.Forms.Label LabelVendor; + private System.Windows.Forms.Label LabelRenderer; + private System.Windows.Forms.Label LabelVersion; + private System.Windows.Forms.TextBox TextBoxVendor; + private System.Windows.Forms.TextBox TextBoxRenderer; + private System.Windows.Forms.TextBox TextBoxVersion; + private System.Windows.Forms.Label LabelSupport; + private System.Windows.Forms.TextBox TextBoxSupport; + private System.Windows.Forms.DataGridViewCheckBoxColumn SupportedColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn NameColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn CategoryColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn Version; + private System.Windows.Forms.DataGridViewTextBoxColumn ExtensionColumn; } } \ No newline at end of file diff --git a/Source/Examples/WinForms/W03_Extensions.cs b/Source/Examples/WinForms/W03_Extensions.cs index 3b8c7b65..f99ab6ae 100644 --- a/Source/Examples/WinForms/W03_Extensions.cs +++ b/Source/Examples/WinForms/W03_Extensions.cs @@ -18,103 +18,119 @@ using OpenTK; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL.Enums; using OpenTK.Graphics; +using System.Text.RegularExpressions; namespace Examples.WinForms { [Example("Extensions", ExampleCategory.WinForms, 3)] public partial class W03_Extensions : Form { - GLControl glControl = new GLControl(GraphicsMode.Default); - Type glClass; - Type delegatesClass; - //Type importsClass; - int supported, all; // Number of supported extensions. - string driver; + #region Fields + + int supported_count, opengl_function_count; // Number of supported extensions. + SortedDictionary functions = new SortedDictionary(); + + #endregion + + #region Constructors public W03_Extensions() { + this.Font = SystemFonts.MessageBoxFont; InitializeComponent(); - glClass = typeof(GL); - delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic); - //importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic); - - glControl.CreateControl(); Application.Idle += StartAsync; } - protected override void OnClosed(EventArgs e) - { - glControl.Dispose(); - } + #endregion + #region Private Members + + // Creates a context and starts processing the GL class. + // The processing takes place in the background to avoid hanging the GUI. void StartAsync(object sender, EventArgs e) { Application.Idle -= StartAsync; - driver = - GL.GetString(StringName.Vendor) + " " + - GL.GetString(StringName.Renderer) + " " + - GL.GetString(StringName.Version); + // Create a context in order to load all GL methods (GL.LoadAll() is called automatically.) + using (GLControl control = new GLControl(GraphicsMode.Default)) + { + TextBoxVendor.Text = GL.GetString(StringName.Vendor); + TextBoxRenderer.Text = GL.GetString(StringName.Renderer); + TextBoxVersion.Text = GL.GetString(StringName.Version); + } - all = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic).Length; - this.Text = String.Format("Loading {0} functions...", all); - - this.backgroundWorker1.RunWorkerAsync(); + backgroundWorker1.RunWorkerAsync(); } - private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic); - int i = 0; - - try + foreach (Function f in LoadFunctionsFromType(typeof(GL))) { - foreach (FieldInfo f in v) - { - object d = f.GetValue(delegatesClass); - if (d != null) - ++supported; - - //if (i % 500 != 0) - backgroundWorker1.ReportProgress((int)(((float)i / all) * 100.0f), - String.Format("({0}/{1}) {2}:\t{3}", i.ToString(), all, d != null ? "ok" : "failed", f.Name)); - ++i; - } + // Only show a function as supported when all relevant overloads are supported. + if (!functions.ContainsKey(f)) + functions.Add(f, GL.SupportsFunction(f.EntryPoint)); + else + functions[f] &= GL.SupportsFunction(f.EntryPoint); } - catch (Exception expt) + + // Count supported functions using the delegates directly. + foreach (FieldInfo f in typeof(GL).GetNestedType("Delegates", BindingFlags.NonPublic) + .GetFields(BindingFlags.Static | BindingFlags.NonPublic)) { - MessageBox.Show(expt.ToString(), "An error occured while loading extensions", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - throw; + if (f.GetValue(null) != null) + supported_count++; + + opengl_function_count++; } } - List items = new List(); - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + // Recursively load all functions marked with [AutoGenerated] in the specified Type. + IEnumerable LoadFunctionsFromType(Type type) { - items.Add(e.UserState as string); - //listBox1.Items.Add(e.UserState as string); - /* - if ((e.UserState as string).Contains("failed")) + foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { - Graphics c = listBox1.CreateGraphics(); - c. - c.DrawRectangle(new Pen(Color.Gray), listBox1.GetItemRectangle(listBox1.Items.Count - 1)); - c.Dispose(); + // Functions in GLHelper.cs are not autogenerated and should be skipped. + AutoGeneratedAttribute[] attr = (AutoGeneratedAttribute[]) + method.GetCustomAttributes(typeof(AutoGeneratedAttribute), false); + if (attr.Length == 0) + continue; + + yield return new Function(method.Name, type.Name, + attr[0].EntryPoint, attr[0].Version, attr[0].Category); } - else - { - } - */ + + foreach (Type nested_type in type.GetNestedTypes(BindingFlags.Public | BindingFlags.Static)) + foreach (Function f in LoadFunctionsFromType(nested_type)) + yield return f; } + // Update the DataGridView with our findings. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { - listBox1.Items.AddRange(items.ToArray()); - this.Text = String.Format("{0}: {1}/{2} OpenGL functions supported.", - driver, supported, all); + TextBoxSupport.Text = String.Format("{0} of {1} functions supported.", + supported_count, opengl_function_count); + + foreach (Function f in functions.Keys) + { + dataGridView1.Rows.Add(functions[f], f.Name, f.Category, f.Version, f.Extension); + int index = dataGridView1.Rows.Count - 1; + + // Some simple coloring to make the GridView easier on the eyes. + // Supported functions are green, unsupported are redish. + dataGridView1.Rows[index].DefaultCellStyle.BackColor = + functions[f] ? + (index % 2 != 0 ? Color.FromArgb(128, 255, 192) : Color.FromArgb(192, 255, 192)) : + (index % 2 != 0 ? Color.FromArgb(255, 192, 160) : Color.FromArgb(255, 200, 160)); + } + + // Change the width of our Form to make every DataGridView column visible. + dataGridView1.AutoResizeColumns(); + this.Size = dataGridView1.GetPreferredSize(new Size(2000, Height)); } + #endregion + #region public static void Main() /// @@ -132,4 +148,78 @@ namespace Examples.WinForms #endregion } + + #region class Function + + // A simple class where we store information from OpenTK.Graphics.GL. + sealed class Function : IEquatable, IComparable + { + #region Fields + + // We use these fields to distinguish between functions. + public readonly string Name; + public readonly string Category; + // These fields just provide some extra (cosmetic) information. + public readonly string EntryPoint; + public readonly string Version; + public readonly string Extension; + + #endregion + + #region Constructors + + public Function(string name, string category, string entryPoint, string version, string extension) + { + Name = name; + Category = category == "GL" ? String.Empty : category; + EntryPoint = entryPoint; + Version = version; + Extension = extension; + } + + #endregion + + #region Public Members + + public override bool Equals(object obj) + { + if (obj is Function) + return this.Equals((Function)obj); + + return false; + } + + public override int GetHashCode() + { + return Name.GetHashCode() ^ Category.GetHashCode(); + } + + #endregion + + #region IEquatable Members + + public bool Equals(Function other) + { + return + Category == other.Category && + Name == other.Name; + } + + #endregion + + #region IComparable Members + + public int CompareTo(Function other) + { + int order = Category.CompareTo(other.Category); + if (order == 0) + order = Name.CompareTo(other.Name); + + return order; + } + + #endregion + } + + #endregion } \ No newline at end of file diff --git a/Source/Examples/WinForms/W03_Extensions.resx b/Source/Examples/WinForms/W03_Extensions.resx index 7aafc39c..d8b237ec 100644 --- a/Source/Examples/WinForms/W03_Extensions.resx +++ b/Source/Examples/WinForms/W03_Extensions.resx @@ -120,4 +120,10 @@ 17, 17 + + True + + + True + \ No newline at end of file