W32GLContext.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * $Id$
  3. *
  4. * GtkGL# - OpenGL Graphics Library for the Gtk# Toolkit
  5. *
  6. * Copyright (c) 2002-2004 The Olympum Group, http://www.olympum.com/
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are met:
  11. *
  12. * - Redistributions of source code must retain the above copyright notice, this
  13. * list of conditions and the following disclaimer.
  14. *
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * - Neither the name of The Olympum Group nor the names of its contributors
  20. * may be used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  33. * DAMAGE.
  34. */
  35. namespace Gdk
  36. {
  37. using System;
  38. using System.Runtime.InteropServices;
  39. using System.Security;
  40. internal sealed class W32GLContext : GLContext
  41. {
  42. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  43. internal struct PIXELFORMATDESCRIPTOR
  44. {
  45. public ushort nSize;
  46. public ushort nVersion;
  47. public uint dwFlags;
  48. public byte iPixelType;
  49. public byte cColorBits;
  50. public byte cRedBits;
  51. public byte cRedShift;
  52. public byte cGreenBits;
  53. public byte cGreenShift;
  54. public byte cBlueBits;
  55. public byte cBlueShift;
  56. public byte cAlphaBits;
  57. public byte cAlphaShift;
  58. public byte cAccumBits;
  59. public byte cAccumRedBits;
  60. public byte cAccumGreenBits;
  61. public byte cAccumBlueBits;
  62. public byte cAccumAlphaBits;
  63. public byte cDepthBits;
  64. public byte cStencilBits;
  65. public byte cAuxBuffers;
  66. public byte iLayerType;
  67. public byte bReserved;
  68. public uint dwLayerMask;
  69. public uint dwVisibleMask;
  70. public uint dwDamageMask;
  71. }
  72. /* pixel types */
  73. internal const byte PFD_TYPE_RGBA = 0;
  74. internal const byte PFD_TYPE_COLORINDEX = 1;
  75. /* layer types */
  76. internal const uint PFD_MAIN_PLANE = 0;
  77. internal const uint PFD_OVERLAY_PLANE = 1;
  78. internal const uint PFD_UNDERLAY_PLANE = 0xff; // (-1)
  79. /* PIXELFORMATDESCRIPTOR flags */
  80. internal const uint PFD_DOUBLEBUFFER = 0x00000001;
  81. internal const uint PFD_STEREO = 0x00000002;
  82. internal const uint PFD_DRAW_TO_WINDOW = 0x00000004;
  83. internal const uint PFD_DRAW_TO_BITMAP = 0x00000008;
  84. internal const uint PFD_SUPPORT_GDI = 0x00000010;
  85. internal const uint PFD_SUPPORT_OPENGL = 0x00000020;
  86. internal const uint PFD_GENERIC_FORMAT = 0x00000040;
  87. internal const uint PFD_NEED_PALETTE = 0x00000080;
  88. internal const uint PFD_NEED_SYSTEM_PALETTE = 0x00000100;
  89. internal const uint PFD_SWAP_EXCHANGE = 0x00000200;
  90. internal const uint PFD_SWAP_COPY = 0x00000400;
  91. internal const uint PFD_SWAP_LAYER_BUFFERS = 0x00000800;
  92. internal const uint PFD_GENERIC_ACCELERATED = 0x00001000;
  93. internal const uint PFD_SUPPORT_DIRECTDRAW = 0x00002000;
  94. /* PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only */
  95. internal const uint PFD_DEPTH_DONTCARE = 0x20000000;
  96. internal const uint PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
  97. internal const uint PFD_STEREO_DONTCARE = 0x80000000;
  98. public const string GL_DLL = "opengl32.dll";
  99. [DllImport("libgdk-win32-2.0-0.dll"), SuppressUnmanagedCodeSecurityAttribute]
  100. static extern IntPtr gdk_win32_drawable_get_handle(IntPtr d);
  101. [DllImport("user32"), SuppressUnmanagedCodeSecurityAttribute]
  102. static extern IntPtr GetDC(IntPtr hwnd);
  103. [DllImport("gdi32"), SuppressUnmanagedCodeSecurityAttribute]
  104. static extern int ChoosePixelFormat(IntPtr hdc, IntPtr /*PIXELFORMATDESCRIPTOR*/ pfd);
  105. [DllImport("gdi32"), SuppressUnmanagedCodeSecurityAttribute]
  106. [return: MarshalAs(UnmanagedType.Bool)]
  107. static extern bool SetPixelFormat(IntPtr hdc, int iPixelFormat, IntPtr /*PIXELFORMATDESCRIPTOR*/ pfd);
  108. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  109. static extern IntPtr wglCreateContext(IntPtr hdc);
  110. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  111. [return: MarshalAs(UnmanagedType.Bool)]
  112. static extern bool wglMakeCurrent(IntPtr hdc, IntPtr hglrc);
  113. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  114. [return: MarshalAs(UnmanagedType.Bool)]
  115. static extern bool wglDeleteContext(IntPtr hglrc);
  116. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  117. [return: MarshalAs(UnmanagedType.Bool)]
  118. static extern bool wglShareLists(IntPtr context1, IntPtr context2);
  119. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  120. static extern IntPtr wglSwapBuffers(IntPtr hdc);
  121. [DllImport(GL_DLL), SuppressUnmanagedCodeSecurityAttribute]
  122. static extern void glFlush();
  123. IntPtr deviceContext;
  124. IntPtr renderingContext;
  125. bool initialized;
  126. int[] attributes;
  127. W32GLContext share;
  128. internal W32GLContext(int[] attributeList,
  129. W32GLContext share,
  130. IntPtr gdkDrawable)
  131. {
  132. this.attributes = attributeList;
  133. this.share = share;
  134. // force .net to load the OpenGL dll :-/
  135. glFlush();
  136. }
  137. ~W32GLContext()
  138. {
  139. if (renderingContext != IntPtr.Zero) {
  140. wglDeleteContext(renderingContext);
  141. renderingContext = IntPtr.Zero;
  142. }
  143. }
  144. public unsafe override bool MakeCurrent(IntPtr gdkDrawable)
  145. {
  146. if (!initialized) {
  147. IntPtr hwnd = gdk_win32_drawable_get_handle(gdkDrawable);
  148. deviceContext = GetDC(hwnd);
  149. // pfd Tells Windows How We Want Things To Be
  150. PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
  151. // Size Of This Pixel Format Descriptor
  152. pfd.nSize = (ushort)sizeof(PIXELFORMATDESCRIPTOR);
  153. pfd.nVersion = 1;
  154. pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
  155. pfd.iPixelType = PFD_TYPE_COLORINDEX;
  156. pfd.cColorBits = 32;
  157. for (int i = 0; i < attributes.Length; ++i) {
  158. switch (attributes[i]) {
  159. case GLContextAttributes.AccumAlphaSize:
  160. pfd.cAccumAlphaBits = (byte)attributes[++i];
  161. break;
  162. case GLContextAttributes.AccumBlueSize:
  163. pfd.cAccumBlueBits = (byte)attributes[++i];
  164. break;
  165. case GLContextAttributes.AccumGreenSize:
  166. pfd.cAccumGreenBits = (byte)attributes[++i];
  167. break;
  168. case GLContextAttributes.AccumRedSize:
  169. pfd.cAccumRedBits = (byte)attributes[++i];
  170. break;
  171. case GLContextAttributes.AlphaSize:
  172. pfd.cAlphaBits = (byte)attributes[++i];
  173. break;
  174. case GLContextAttributes.AuxBuffers:
  175. pfd.cAuxBuffers = (byte)attributes[++i];
  176. break;
  177. case GLContextAttributes.BlueSize:
  178. pfd.cBlueBits = (byte)attributes[++i];
  179. break;
  180. case GLContextAttributes.BufferSize:
  181. // ?!?
  182. ++i;
  183. break;
  184. case GLContextAttributes.DepthSize:
  185. pfd.cDepthBits = (byte)attributes[++i];
  186. break;
  187. case GLContextAttributes.DoubleBuffer:
  188. pfd.dwFlags |= PFD_DOUBLEBUFFER;
  189. break;
  190. case GLContextAttributes.GreenSize:
  191. pfd.cGreenBits = (byte)attributes[++i];
  192. break;
  193. case GLContextAttributes.Level:
  194. // ?
  195. ++i;
  196. break;
  197. case GLContextAttributes.None:
  198. // ?
  199. break;
  200. case GLContextAttributes.RedSize:
  201. pfd.cRedBits = (byte)attributes[++i];
  202. break;
  203. case GLContextAttributes.Rgba:
  204. pfd.iPixelType = PFD_TYPE_RGBA;
  205. break;
  206. case GLContextAttributes.StencilSize:
  207. pfd.cStencilBits = (byte)attributes[++i];
  208. break;
  209. case GLContextAttributes.Stereo:
  210. pfd.dwFlags |= PFD_STEREO;
  211. break;
  212. }
  213. }
  214. // Tell the graphics hardware how to display pixels.
  215. int pixelFormat = ChoosePixelFormat(deviceContext, new IntPtr(&pfd));
  216. if (pixelFormat == 0)
  217. return false;
  218. if (!SetPixelFormat(deviceContext, pixelFormat, new IntPtr(&pfd)))
  219. throw new Exception("Couldn't set pixelformat");
  220. renderingContext = wglCreateContext(deviceContext);
  221. if (renderingContext == IntPtr.Zero)
  222. throw new Exception("Couldn't create rendering context");
  223. if (share != null) {
  224. if (share.renderingContext != IntPtr.Zero) {
  225. Console.WriteLine("DoSharing");
  226. if (!wglShareLists(share.renderingContext, renderingContext))
  227. throw new Exception("Can't share opengl contexts");
  228. } else
  229. throw new Exception("Trying to share with uninitialized context...");
  230. } else {
  231. Console.WriteLine("Share zero");
  232. }
  233. initialized = true;
  234. }
  235. return wglMakeCurrent(deviceContext, renderingContext);
  236. }
  237. public override void SwapBuffers(IntPtr gdkDrawable)
  238. {
  239. wglSwapBuffers(deviceContext);
  240. }
  241. }
  242. }