00001 #region License
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #endregion
00027
00028 using System;
00029 using System.Collections.Generic;
00030 using System.Text;
00031 using System.Windows.Forms;
00032 using System.Diagnostics;
00033 using System.Runtime.InteropServices;
00034
00035 using OpenTK.Graphics;
00036 using ColorDepth = OpenTK.Graphics.ColorFormat;
00037
00038 namespace OpenTK.Platform.Windows
00039 {
00040 internal class WinGraphicsMode : IGraphicsMode
00041 {
00042
00043
00044 #region --- Fields ---
00045
00046
00047 bool creating;
00048
00049 #endregion
00050
00051 #region --- Constructors ---
00052
00053 public WinGraphicsMode()
00054 {
00055 }
00056
00057 #endregion
00058
00059 #region --- IGraphicsMode Members ---
00060
00061 public GraphicsMode SelectGraphicsMode(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
00062 int buffers, bool stereo)
00063 {
00064 GraphicsMode mode = null;
00065 if (!creating)
00066 {
00067 try
00068 {
00069 creating = true;
00070 mode = SelectGraphicsModeARB(color, depth, stencil, samples, accum, buffers, stereo);
00071 }
00072 finally
00073 {
00074 creating = false;
00075 }
00076 }
00077 if (mode == null)
00078 mode = SelectGraphicsModePFD(color, depth, stencil, samples, accum, buffers, stereo);
00079 return mode;
00080 }
00081
00082 #endregion
00083
00084 #region --- Private Methods ---
00085
00086 #region SelectGraphicsModePFD
00087
00088 GraphicsMode SelectGraphicsModePFD(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
00089 int buffers, bool stereo)
00090 {
00091 using (Control native_window = new Control())
00092 using (WinWindowInfo window = new WinWindowInfo(native_window.Handle, null))
00093 {
00094 IntPtr deviceContext = ((WinWindowInfo)window).DeviceContext;
00095 Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
00096
00097 Debug.Write("Selecting pixel format... ");
00098 PixelFormatDescriptor pixelFormat = new PixelFormatDescriptor();
00099 pixelFormat.Size = API.PixelFormatDescriptorSize;
00100 pixelFormat.Version = API.PixelFormatDescriptorVersion;
00101 pixelFormat.Flags =
00102 PixelFormatDescriptorFlags.SUPPORT_OPENGL |
00103 PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
00104 pixelFormat.ColorBits = (byte)(color.Red + color.Green + color.Blue);
00105
00106 pixelFormat.PixelType = color.IsIndexed ? PixelType.INDEXED : PixelType.RGBA;
00107 pixelFormat.RedBits = (byte)color.Red;
00108 pixelFormat.GreenBits = (byte)color.Green;
00109 pixelFormat.BlueBits = (byte)color.Blue;
00110 pixelFormat.AlphaBits = (byte)color.Alpha;
00111
00112 if (accum.BitsPerPixel > 0)
00113 {
00114 pixelFormat.AccumBits = (byte)(accum.Red + accum.Green + accum.Blue);
00115 pixelFormat.AccumRedBits = (byte)accum.Red;
00116 pixelFormat.AccumGreenBits = (byte)accum.Green;
00117 pixelFormat.AccumBlueBits = (byte)accum.Blue;
00118 pixelFormat.AccumAlphaBits = (byte)accum.Alpha;
00119 }
00120
00121 pixelFormat.DepthBits = (byte)depth;
00122 pixelFormat.StencilBits = (byte)stencil;
00123
00124 if (depth <= 0) pixelFormat.Flags |= PixelFormatDescriptorFlags.DEPTH_DONTCARE;
00125 if (stereo) pixelFormat.Flags |= PixelFormatDescriptorFlags.STEREO;
00126 if (buffers > 1) pixelFormat.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
00127
00128 int pixel = Functions.ChoosePixelFormat(deviceContext, ref pixelFormat);
00129 if (pixel == 0)
00130 throw new GraphicsModeException("The requested GraphicsMode is not available.");
00131
00132
00133 PixelFormatDescriptor pfd = new PixelFormatDescriptor();
00134 pixelFormat.Size = API.PixelFormatDescriptorSize;
00135 pixelFormat.Version = API.PixelFormatDescriptorVersion;
00136 Functions.DescribePixelFormat(deviceContext, pixel, API.PixelFormatDescriptorSize, ref pfd);
00137 GraphicsMode fmt = new GraphicsMode((IntPtr)pixel,
00138 new ColorDepth(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
00139 pfd.DepthBits,
00140 pfd.StencilBits,
00141 0,
00142 new ColorDepth(pfd.AccumBits),
00143 (pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
00144 (pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
00145
00146 return fmt;
00147 }
00148 }
00149
00150 #endregion
00151
00152 #region SelectGraphicsModeARB
00153
00154 GraphicsMode SelectGraphicsModeARB(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum,
00155 int buffers, bool stereo)
00156 {
00157 using (INativeWindow native_window = new NativeWindow())
00158 using (IGraphicsContext context = new GraphicsContext(new GraphicsMode(new ColorFormat(), 0, 0, 0, new ColorFormat(), 2, false), native_window.WindowInfo, 1, 0, GraphicsContextFlags.Default))
00159 {
00160 WinWindowInfo window = (WinWindowInfo)native_window.WindowInfo;
00161
00162 Debug.Write("Selecting pixel format (ARB)... ");
00163 if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
00164 {
00165 Debug.WriteLine("failed");
00166 return null;
00167 }
00168
00169 int[] attribs = new int[]
00170 {
00171 (int)WGL_ARB_pixel_format.AccelerationArb,
00172
00173 (int)WGL_ARB_pixel_format.AlphaBitsArb,
00174 (int)WGL_ARB_pixel_format.RedBitsArb,
00175 (int)WGL_ARB_pixel_format.GreenBitsArb,
00176 (int)WGL_ARB_pixel_format.BlueBitsArb,
00177 (int)WGL_ARB_pixel_format.ColorBitsArb,
00178
00179 (int)WGL_ARB_pixel_format.DepthBitsArb,
00180 (int)WGL_ARB_pixel_format.StencilBitsArb,
00181
00182 (int)WGL_ARB_multisample.SampleBuffersArb,
00183 (int)WGL_ARB_multisample.SamplesArb,
00184
00185 (int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
00186 (int)WGL_ARB_pixel_format.AccumRedBitsArb,
00187 (int)WGL_ARB_pixel_format.AccumGreenBitsArb,
00188 (int)WGL_ARB_pixel_format.AccumBlueBitsArb,
00189 (int)WGL_ARB_pixel_format.AccumBitsArb,
00190
00191 (int)WGL_ARB_pixel_format.DoubleBufferArb,
00192 (int)WGL_ARB_pixel_format.StereoArb,
00193 0
00194 };
00195
00196 int[] values = new int[attribs.Length];
00197
00198 int[] attribs_values = new int[]
00199 {
00200 (int)WGL_ARB_pixel_format.AccelerationArb, (int)WGL_ARB_pixel_format.FullAccelerationArb,
00201
00202 (int)WGL_ARB_pixel_format.RedBitsArb, color.Red,
00203 (int)WGL_ARB_pixel_format.GreenBitsArb, color.Green,
00204 (int)WGL_ARB_pixel_format.BlueBitsArb, color.Blue,
00205 (int)WGL_ARB_pixel_format.AlphaBitsArb, color.Alpha,
00206 (int)WGL_ARB_pixel_format.ColorBitsArb, color.BitsPerPixel,
00207
00208 (int)WGL_ARB_pixel_format.DepthBitsArb, depth,
00209 (int)WGL_ARB_pixel_format.StencilBitsArb, stencil,
00210
00211 (int)WGL_ARB_multisample.SampleBuffersArb, samples > 0 ? 1 : 0,
00212 (int)WGL_ARB_multisample.SamplesArb, samples,
00213
00214 (int)WGL_ARB_pixel_format.AccumRedBitsArb, accum.Red,
00215 (int)WGL_ARB_pixel_format.AccumGreenBitsArb, accum.Green,
00216 (int)WGL_ARB_pixel_format.AccumBlueBitsArb, accum.Blue,
00217 (int)WGL_ARB_pixel_format.AccumAlphaBitsArb, accum.Alpha,
00218 (int)WGL_ARB_pixel_format.AccumBitsArb, accum.BitsPerPixel,
00219
00220 (int)WGL_ARB_pixel_format.DoubleBufferArb, 1,
00221 (int)WGL_ARB_pixel_format.StereoArb, stereo ? 1 : 0,
00222 0, 0
00223 };
00224
00225 int[] pixel = new int[1], num_formats = new int[1];
00226 Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 1, pixel, num_formats);
00227 if (num_formats[0] == 0 || pixel[0] == 0)
00228 {
00229
00230 attribs_values[10 * 2 + 1] = attribs_values[11 * 2 + 1] = attribs_values[12 * 2 + 1] = attribs_values[13 * 2 + 1] = attribs_values[14 * 2 + 1] = 0;
00231 Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 1, pixel, num_formats);
00232 }
00233 if (num_formats[0] == 0 || pixel[0] == 0)
00234 {
00235 Debug.WriteLine("failed");
00236 return null;
00237 }
00238
00239
00240 Wgl.Arb.GetPixelFormatAttrib(window.DeviceContext, pixel[0], 0, attribs.Length, attribs, values);
00241
00242 GraphicsMode mode = new GraphicsMode(new IntPtr(pixel[0]),
00243 new ColorDepth(values[1], values[2], values[3], values[4]),
00244 values[6],
00245 values[7],
00246 values[8] != 0 ? values[9] : 0,
00247 new ColorDepth(values[10], values[11], values[12], values[13]),
00248 values[15] == 1 ? 2 : 1,
00249 values[16] == 1 ? true : false);
00250
00251 Debug.WriteLine("success!");
00252 return mode;
00253 }
00254 }
00255
00256 #endregion
00257
00258 #endregion
00259 }
00260 }