File: Extensions.cs

package info (click to toggle)
opentk 1.0.20101006%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 38,896 kB
  • ctags: 68,704
  • sloc: cs: 424,330; xml: 96,546; ansic: 3,597; makefile: 24
file content (250 lines) | stat: -rw-r--r-- 9,042 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
 * See license.txt for license info
 */
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Text.RegularExpressions;

namespace Examples.WinForms
{
    [Example("OpenGL Extensions", ExampleCategory.OpenTK, "Test", Documentation="Extensions")]
    public partial class Extensions : Form
    {
        #region Fields

        int supported_count, opengl_function_count;      // Number of supported extensions.
        SortedDictionary<Function, bool> functions = new SortedDictionary<Function, bool>();

        #endregion

        #region Constructors

        public Extensions()
        {
            this.Font = SystemFonts.MessageBoxFont;
            InitializeComponent();

            Application.Idle += StartAsync;

            // Workaround for missing Idle event on Mono/Windows.
            if (Configuration.RunningOnMono && Configuration.RunningOnWindows)
                Application.RaiseIdle(EventArgs.Empty);
        }

        #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;

            // Create a context to load all GL entry points.
            // The loading part is handled automatically by OpenTK.
            using (INativeWindow window = new OpenTK.NativeWindow())
            using (IGraphicsContext context = new GraphicsContext(GraphicsMode.Default, window.WindowInfo, 3, 0, GraphicsContextFlags.Default))
            {
                window.ProcessEvents();
                context.MakeCurrent(window.WindowInfo);
                (context as IGraphicsContextInternal).LoadAll();

                TextBoxVendor.Text = GL.GetString(StringName.Vendor);
                TextBoxRenderer.Text = GL.GetString(StringName.Renderer);
                TextBoxVersion.Text = GL.GetString(StringName.Version);
            }

            backgroundWorker1.RunWorkerAsync();
            TextBoxSupport.Text = "processing... (please be patient)";
        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Type delegates = typeof(GL).GetNestedType("Delegates", BindingFlags.NonPublic | BindingFlags.Static);

            foreach (Function f in LoadFunctionsFromType(typeof(GL)))
            {
                FieldInfo @delegate = delegates.GetField(f.EntryPoint,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
                
                // Only show a function as supported when all relevant overloads are supported.
                if (!functions.ContainsKey(f))
                    functions.Add(f, @delegate != null && @delegate.GetValue(null) != null);
                else
                    functions[f] &= @delegate != null && @delegate.GetValue(null) != null;
            }

            // Count supported functions using the delegates directly.
            foreach (FieldInfo f in typeof(GL).GetNestedType("Delegates", BindingFlags.NonPublic)
                .GetFields(BindingFlags.Static | BindingFlags.NonPublic))
            {
                if (f.GetValue(null) != null)
                    supported_count++;

                opengl_function_count++;
            }
        }

        // Recursively load all functions marked with [AutoGenerated] in the specified Type.
        IEnumerable<Function> LoadFunctionsFromType(Type type)
        {
            foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
            {
                // Functions in GLHelper.cs are not autogenerated and should be skipped.
                AutoGeneratedAttribute[] attr = (AutoGeneratedAttribute[])
                    method.GetCustomAttributes(typeof(AutoGeneratedAttribute), false);
                if (attr.Length == 0)
                    continue;
                string returnType = method.ReturnParameter.ToString();
                List<string> args = new List<string>();
                foreach (ParameterInfo item in method.GetParameters())
                {
                    args.Add(item.ToString());
                }

                string argsStr = String.Join(", ", args.ToArray());
                string fullMethodName = String.Format("{0} {1}({2})", returnType, method.Name, argsStr);

                yield return new Function(fullMethodName, type.Name,
                    attr[0].EntryPoint, attr[0].Version, attr[0].Category);
            }

            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)
        {
            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, f.EntryPoint);
                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(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
            dataGridView1.Columns[1].Width = 450;
            this.Size = dataGridView1.GetPreferredSize(new System.Drawing.Size(2000, Height));
        }

        #endregion

        #region public static void Main()

        /// <summary>
        /// Entry point of this example.
        /// </summary>
        [STAThread]
        public static void Main()
        {
            using (Extensions example = new Extensions())
            {
                Utilities.SetWindowTitle(example);
                example.ShowDialog();
            }
        }

        #endregion
    }

    #region class Function

    // A simple class where we store information from OpenTK.Graphics.GL.
    sealed class Function : IEquatable<Function>, IComparable<Function>
    {
        #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<Function> Members

        public bool Equals(Function other)
        {
            return
                Category == other.Category &&
                Name == other.Name;
        }

        #endregion

        #region IComparable<Function> Members

        public int CompareTo(Function other)
        {
            int order = Category.CompareTo(other.Category);
            if (order == 0)
                order = Name.CompareTo(other.Name);

            return order;
        }

        #endregion
    }

    #endregion
}