00001 #region --- License ---
00002
00003
00004
00005
00006
00007 #endregion
00008
00009 using System;
00010 using System.Collections.Generic;
00011 using System.Text;
00012 using System.Runtime.InteropServices;
00013 using System.Diagnostics;
00014
00015 using OpenTK.Graphics;
00016
00017 namespace OpenTK.Platform.X11
00018 {
00019 class X11GraphicsMode : IGraphicsMode
00020 {
00021
00022
00023
00024
00025 #region Constructors
00026
00027 public X11GraphicsMode()
00028 {
00029 }
00030
00031 #endregion
00032
00033 #region IGraphicsMode Members
00034
00035 public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
00036 int buffers, bool stereo)
00037 {
00038 GraphicsMode gfx;
00039
00040 IntPtr visual = IntPtr.Zero;
00041 IntPtr display = API.DefaultDisplay;
00042
00043
00044
00045 visual = SelectVisualUsingFBConfig(color, depth, stencil, samples, accum, buffers, stereo);
00046
00047 if (visual == IntPtr.Zero)
00048 visual = SelectVisualUsingChooseVisual(color, depth, stencil, samples, accum, buffers, stereo);
00049
00050 if (visual == IntPtr.Zero)
00051 throw new GraphicsContextException("Requested GraphicsMode not available.");
00052
00053 XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
00054
00055
00056 int r, g, b, a;
00057 Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a);
00058 Glx.GetConfig(display, ref info, GLXAttribute.RED_SIZE, out r);
00059 Glx.GetConfig(display, ref info, GLXAttribute.GREEN_SIZE, out g);
00060 Glx.GetConfig(display, ref info, GLXAttribute.BLUE_SIZE, out b);
00061 int ar, ag, ab, aa;
00062 Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_ALPHA_SIZE, out aa);
00063 Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar);
00064 Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag);
00065 Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab);
00066 Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth);
00067 Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
00068 Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
00069 Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
00070 ++buffers;
00071
00072 int st;
00073 Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
00074 stereo = st != 0;
00075
00076 gfx = new GraphicsMode(info.VisualID, new ColorFormat(r, g, b, a), depth, stencil, samples,
00077 new ColorFormat(ar, ag, ab, aa), buffers, stereo);
00078
00079 using (new XLock(display))
00080 {
00081 Functions.XFree(visual);
00082 }
00083
00084 return gfx;
00085 }
00086
00087 #endregion
00088
00089 #region Private Members
00090
00091
00092
00093 IntPtr SelectVisualUsingFBConfig(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
00094 int buffers, bool stereo)
00095 {
00096 List<int> visualAttributes = new List<int>();
00097 IntPtr visual = IntPtr.Zero;
00098
00099 Debug.Print("Bits per pixel: {0}", color.BitsPerPixel);
00100
00101 if (color.BitsPerPixel > 0)
00102 {
00103 if (!color.IsIndexed)
00104 {
00105 visualAttributes.Add((int)GLXAttribute.RGBA);
00106 visualAttributes.Add(1);
00107 }
00108 visualAttributes.Add((int)GLXAttribute.RED_SIZE);
00109 visualAttributes.Add(color.Red);
00110 visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
00111 visualAttributes.Add(color.Green);
00112 visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
00113 visualAttributes.Add(color.Blue);
00114 visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
00115 visualAttributes.Add(color.Alpha);
00116 }
00117
00118 Debug.Print("Depth: {0}", depth);
00119
00120 if (depth > 0)
00121 {
00122 visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
00123 visualAttributes.Add(depth);
00124 }
00125
00126 if (buffers > 1)
00127 {
00128 visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
00129 visualAttributes.Add(1);
00130 }
00131
00132 if (stencil > 1)
00133 {
00134 visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
00135 visualAttributes.Add(stencil);
00136 }
00137
00138 if (accum.BitsPerPixel > 0)
00139 {
00140 visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
00141 visualAttributes.Add(accum.Alpha);
00142 visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
00143 visualAttributes.Add(accum.Blue);
00144 visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
00145 visualAttributes.Add(accum.Green);
00146 visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
00147 visualAttributes.Add(accum.Red);
00148 }
00149
00150 if (samples > 0)
00151 {
00152 visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS);
00153 visualAttributes.Add(1);
00154 visualAttributes.Add((int)GLXAttribute.SAMPLES);
00155 visualAttributes.Add(samples);
00156 }
00157
00158 if (stereo)
00159 {
00160 visualAttributes.Add((int)GLXAttribute.STEREO);
00161 visualAttributes.Add(1);
00162 }
00163
00164 visualAttributes.Add(0);
00165
00166
00167 IntPtr display = API.DefaultDisplay;
00168 using (new XLock(display))
00169 {
00170 try
00171 {
00172 int screen = Functions.XDefaultScreen(display);
00173 IntPtr root = Functions.XRootWindow(display, screen);
00174 Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
00175
00176 unsafe
00177 {
00178 Debug.Print("Getting FB config.");
00179 int fbcount;
00180
00181 IntPtr* fbconfigs = Glx.ChooseFBConfig(display, screen, visualAttributes.ToArray(), out fbcount);
00182 if (fbcount > 0 && fbconfigs != null)
00183 {
00184
00185 visual = Glx.GetVisualFromFBConfig(display, *fbconfigs);
00186 Functions.XFree((IntPtr)fbconfigs);
00187 }
00188 }
00189 }
00190 catch (EntryPointNotFoundException)
00191 {
00192 Debug.Print("Function glXChooseFBConfig not supported.");
00193 return IntPtr.Zero;
00194 }
00195 }
00196
00197 return visual;
00198 }
00199
00200
00201 IntPtr SelectVisualUsingChooseVisual(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
00202 int buffers, bool stereo)
00203 {
00204 List<int> visualAttributes = new List<int>();
00205
00206 Debug.Print("Bits per pixel: {0}", color.BitsPerPixel);
00207
00208 if (color.BitsPerPixel > 0)
00209 {
00210 if (!color.IsIndexed)
00211 visualAttributes.Add((int)GLXAttribute.RGBA);
00212 visualAttributes.Add((int)GLXAttribute.RED_SIZE);
00213 visualAttributes.Add(color.Red);
00214 visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
00215 visualAttributes.Add(color.Green);
00216 visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
00217 visualAttributes.Add(color.Blue);
00218 visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
00219 visualAttributes.Add(color.Alpha);
00220 }
00221
00222 Debug.Print("Depth: {0}", depth);
00223
00224 if (depth > 0)
00225 {
00226 visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
00227 visualAttributes.Add(depth);
00228 }
00229
00230 if (buffers > 1)
00231 visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
00232
00233 if (stencil > 1)
00234 {
00235 visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
00236 visualAttributes.Add(stencil);
00237 }
00238
00239 if (accum.BitsPerPixel > 0)
00240 {
00241 visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
00242 visualAttributes.Add(accum.Alpha);
00243 visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
00244 visualAttributes.Add(accum.Blue);
00245 visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
00246 visualAttributes.Add(accum.Green);
00247 visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
00248 visualAttributes.Add(accum.Red);
00249 }
00250
00251 if (samples > 0)
00252 {
00253 visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS);
00254 visualAttributes.Add(1);
00255 visualAttributes.Add((int)GLXAttribute.SAMPLES);
00256 visualAttributes.Add(samples);
00257 }
00258
00259 if (stereo)
00260 visualAttributes.Add((int)GLXAttribute.STEREO);
00261
00262 visualAttributes.Add(0);
00263
00264 Debug.Print("Falling back to glXChooseVisual.");
00265 IntPtr display = API.DefaultDisplay;
00266 using (new XLock(display))
00267 {
00268 return Glx.ChooseVisual(display, Functions.XDefaultScreen(display), visualAttributes.ToArray());
00269 }
00270 }
00271
00272 #endregion
00273 }
00274 }