Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region License
2
//
3
// The Open Toolkit Library License
4
//
5
// Copyright (c) 2006 - 2009 the Open Toolkit library.
6
//
7
// Permission is hereby granted, free of charge, to any person obtaining a copy
8
// of this software and associated documentation files (the "Software"), to deal
9
// in the Software without restriction, including without limitation the rights to 
10
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
// the Software, and to permit persons to whom the Software is furnished to do
12
// so, subject to the following conditions:
13
//
14
// The above copyright notice and this permission notice shall be included in all
15
// copies or substantial portions of the Software.
16
//
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
// OTHER DEALINGS IN THE SOFTWARE.
25
//
26
#endregion
27
 
28
using System;
29
using System.Collections.Generic;
30
using System.Text;
31
using System.Windows.Forms;
32
using System.Diagnostics;
33
using System.Runtime.InteropServices;
34
 
35
using OpenTK.Graphics;
36
using ColorDepth = OpenTK.Graphics.ColorFormat;
37
 
38
namespace OpenTK.Platform.Windows
39
{
40
    internal class WinGraphicsMode : IGraphicsMode
41
    {
42
        // Todo: Get rid of the System.Windows.Forms.Control dependency.
43
 
44
        #region --- Fields ---
45
 
46
        // To avoid recursion when calling GraphicsMode.Default
47
        bool creating;
48
 
49
        #endregion
50
 
51
        #region --- Constructors ---
52
 
53
        public WinGraphicsMode()
54
        {
55
        }
56
 
57
        #endregion
58
 
59
        #region --- IGraphicsMode Members ---
60
 
61
        public GraphicsMode SelectGraphicsMode(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
62
                                               int buffers, bool stereo)
63
        {
64
            GraphicsMode mode = null;
65
            if (!creating)
66
            {
67
                try
68
                {
69
                    creating = true;
70
                    mode = SelectGraphicsModeARB(color, depth, stencil, samples, accum, buffers, stereo);
71
                }
72
                finally
73
                {
74
                    creating = false;
75
                }
76
            }
77
            if (mode == null)
78
                mode = SelectGraphicsModePFD(color, depth, stencil, samples, accum, buffers, stereo);
79
            return mode;
80
        }
81
 
82
        #endregion
83
 
84
        #region --- Private Methods ---
85
 
86
        #region SelectGraphicsModePFD
87
 
88
        GraphicsMode SelectGraphicsModePFD(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
89
            int buffers, bool stereo)
90
        {
91
            using (Control native_window = new Control())
92
            using (WinWindowInfo window = new WinWindowInfo(native_window.Handle, null))
93
            {
94
                IntPtr deviceContext = ((WinWindowInfo)window).DeviceContext;
95
                Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
96
 
97
                Debug.Write("Selecting pixel format... ");
98
                PixelFormatDescriptor pixelFormat = new PixelFormatDescriptor();
99
                pixelFormat.Size = API.PixelFormatDescriptorSize;
100
                pixelFormat.Version = API.PixelFormatDescriptorVersion;
101
                pixelFormat.Flags =
102
                    PixelFormatDescriptorFlags.SUPPORT_OPENGL |
103
                    PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
104
                pixelFormat.ColorBits = (byte)(color.Red + color.Green + color.Blue);
105
 
106
                pixelFormat.PixelType = color.IsIndexed ? PixelType.INDEXED : PixelType.RGBA;
107
                pixelFormat.RedBits = (byte)color.Red;
108
                pixelFormat.GreenBits = (byte)color.Green;
109
                pixelFormat.BlueBits = (byte)color.Blue;
110
                pixelFormat.AlphaBits = (byte)color.Alpha;
111
 
112
                if (accum.BitsPerPixel > 0)
113
                {
114
                    pixelFormat.AccumBits = (byte)(accum.Red + accum.Green + accum.Blue);
115
                    pixelFormat.AccumRedBits = (byte)accum.Red;
116
                    pixelFormat.AccumGreenBits = (byte)accum.Green;
117
                    pixelFormat.AccumBlueBits = (byte)accum.Blue;
118
                    pixelFormat.AccumAlphaBits = (byte)accum.Alpha;
119
                }
120
 
121
                pixelFormat.DepthBits = (byte)depth;
122
                pixelFormat.StencilBits = (byte)stencil;
123
 
124
                if (depth <= 0) pixelFormat.Flags |= PixelFormatDescriptorFlags.DEPTH_DONTCARE;
125
                if (stereo) pixelFormat.Flags |= PixelFormatDescriptorFlags.STEREO;
126
                if (buffers > 1) pixelFormat.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
127
 
128
                int pixel = Functions.ChoosePixelFormat(deviceContext, ref pixelFormat);
129
                if (pixel == 0)
130
                    throw new GraphicsModeException("The requested GraphicsMode is not available.");
131
 
132
                // Find out what we really got as a format:
133
                PixelFormatDescriptor pfd = new PixelFormatDescriptor();
134
                pixelFormat.Size = API.PixelFormatDescriptorSize;
135
                pixelFormat.Version = API.PixelFormatDescriptorVersion;
136
                Functions.DescribePixelFormat(deviceContext, pixel, API.PixelFormatDescriptorSize, ref pfd);
137
                GraphicsMode fmt = new GraphicsMode((IntPtr)pixel,
138
                    new ColorDepth(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
139
                    pfd.DepthBits,
140
                    pfd.StencilBits,
141
                    0,
142
                    new ColorDepth(pfd.AccumBits),
143
                    (pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
144
                    (pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
145
 
146
                return fmt;
147
            }
148
        }
149
 
150
        #endregion
151
 
152
        #region SelectGraphicsModeARB
153
 
154
        GraphicsMode SelectGraphicsModeARB(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
155
            int buffers, bool stereo)
156
        {
157
            using (INativeWindow native_window = new NativeWindow())
158
            using (IGraphicsContext context = new GraphicsContext(new GraphicsMode(new ColorFormat(), 0, 0, 0, new ColorFormat(), 2, false), native_window.WindowInfo, 1, 0, GraphicsContextFlags.Default))
159
            {
160
                WinWindowInfo window = (WinWindowInfo)native_window.WindowInfo;
161
 
162
                // See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
163
                // for more details
164
                Debug.Write("Selecting pixel format (ARB)... ");
165
                if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
166
                {
167
                    Debug.WriteLine("failed");
168
                    return null;
169
                }
170
 
171
                int[] attribs = new int[]
172
                {
173
                    (int)WGL_ARB_pixel_format.AccelerationArb,
174
 
175
                    (int)WGL_ARB_pixel_format.RedBitsArb,
176
                    (int)WGL_ARB_pixel_format.GreenBitsArb,
177
                    (int)WGL_ARB_pixel_format.BlueBitsArb,
178
                    (int)WGL_ARB_pixel_format.AlphaBitsArb,
179
                    (int)WGL_ARB_pixel_format.ColorBitsArb,
180
 
181
                    (int)WGL_ARB_pixel_format.DepthBitsArb,
182
                    (int)WGL_ARB_pixel_format.StencilBitsArb,
183
 
184
                    (int)WGL_ARB_multisample.SampleBuffersArb,
185
                    (int)WGL_ARB_multisample.SamplesArb,
186
 
187
                    (int)WGL_ARB_pixel_format.AccumRedBitsArb,
188
                    (int)WGL_ARB_pixel_format.AccumGreenBitsArb,
189
                    (int)WGL_ARB_pixel_format.AccumBlueBitsArb,
190
                    (int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
191
                    (int)WGL_ARB_pixel_format.AccumBitsArb,
192
 
193
                    (int)WGL_ARB_pixel_format.DoubleBufferArb,
194
                    (int)WGL_ARB_pixel_format.StereoArb,
195
 
196
                };
197
 
198
                int[] values = new int[attribs.Length];
199
 
200
                int[] attribs_values = new int[]
201
                {
202
                    (int)WGL_ARB_pixel_format.AccelerationArb, (int)WGL_ARB_pixel_format.FullAccelerationArb,
203
                    (int)WGL_ARB_pixel_format.DrawToWindowArb, 1,
204
 
205
                    (int)WGL_ARB_pixel_format.RedBitsArb, color.Red,
206
                    (int)WGL_ARB_pixel_format.GreenBitsArb, color.Green,
207
                    (int)WGL_ARB_pixel_format.BlueBitsArb, color.Blue,
208
                    (int)WGL_ARB_pixel_format.AlphaBitsArb, color.Alpha,
209
                    (int)WGL_ARB_pixel_format.ColorBitsArb, color.BitsPerPixel - color.Alpha, // Should not contain alpha bpp (see spec)
210
 
211
                    (int)WGL_ARB_pixel_format.DepthBitsArb, depth,
212
                    (int)WGL_ARB_pixel_format.StencilBitsArb, stencil,
213
 
214
                    (int)WGL_ARB_multisample.SampleBuffersArb, samples > 0 ? 1 : 0,
215
                    (int)WGL_ARB_multisample.SamplesArb, samples,
216
 
217
                    (int)WGL_ARB_pixel_format.AccumRedBitsArb, accum.Red,
218
                    (int)WGL_ARB_pixel_format.AccumGreenBitsArb, accum.Green,
219
                    (int)WGL_ARB_pixel_format.AccumBlueBitsArb, accum.Blue,
220
                    (int)WGL_ARB_pixel_format.AccumAlphaBitsArb, accum.Alpha,
221
                    (int)WGL_ARB_pixel_format.AccumBitsArb, accum.BitsPerPixel, // Spec doesn't mention wether alpha bpp should be included...
222
 
223
                    (int)WGL_ARB_pixel_format.DoubleBufferArb, buffers > 1 ? 1 : 0,
224
                    (int)WGL_ARB_pixel_format.StereoArb, stereo ? 1 : 0,
225
                    0, 0
226
                };
227
 
228
                int[] pixel = new int[1], num_formats = new int[1];
229
                bool success = Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 1, pixel, num_formats);
230
                if (!success || num_formats[0] == 0 || pixel[0] == 0)
231
                {
232
                    // Try again without an accumulator. Many modern cards cannot accelerate multisampled formats with accumulator buffers.
233
                    int index_of_accum = Array.IndexOf(attribs_values, (int)WGL_ARB_pixel_format.AccumRedBitsArb);
234
                    attribs_values[index_of_accum + 1] = attribs_values[index_of_accum + 3] =
235
                        attribs_values[index_of_accum + 5] = attribs_values[index_of_accum + 7] =
236
                        attribs_values[index_of_accum + 9] = 0;
237
                    Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 1, pixel, num_formats);
238
                }
239
                if (!success || num_formats[0] == 0 || pixel[0] == 0)
240
                {
241
                    Debug.WriteLine("failed (no suitable pixel format).");
242
                    return null;
243
                }
244
 
245
                // Find out what we really got as a format:
246
                success = Wgl.Arb.GetPixelFormatAttrib(window.DeviceContext, pixel[0], 0, attribs.Length - 1, attribs, values);
247
                if (!success)
248
                {
249
                    Debug.WriteLine("failed (pixel format attributes could not be determined).");
250
                    return null;
251
                }
252
 
253
                GraphicsMode mode = new GraphicsMode(new IntPtr(pixel[0]),
254
                    new ColorDepth(values[1], values[2], values[3], values[4]),
255
                    values[6],
256
                    values[7],
257
                    values[8] != 0 ? values[9] : 0,
258
                    new ColorDepth(values[10], values[11], values[12], values[13]),
259
                    values[15] == 1 ? 2 : 1,
260
                    values[16] == 1 ? true : false);
261
 
262
                Debug.WriteLine("success!");
263
                return mode;
264
            }
265
        }
266
 
267
        #endregion
268
 
269
        #endregion
270
    }
271
}
272