-
-
Save DeafMan1983/408a434d992367c2109dfe0c4ac656f9 to your computer and use it in GitHub Desktop.
GLArea for GtkSharp 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
namespace Gtk | |
{ | |
public unsafe class GLArea : DrawingArea, IDisposable | |
{ | |
private IntPtr display, window, visualinfo, glx_context; | |
private int screen_number; | |
private bool initialized = true; | |
private const string libgdkx112 = "libgdk-x11-2.0.so.0"; | |
private const string libx11 = "libX11.so.6"; | |
private const string libGLX = "libGLX.so.0"; | |
// Gdk-X11 2 | |
[DllImport(libgdkx112)] | |
private extern static IntPtr gdk_x11_display_get_xdisplay(IntPtr gdk_display); | |
[DllImport(libgdkx112)] | |
private extern static IntPtr gdk_x11_drawable_get_xid(IntPtr gdk_window); | |
[DllImport(libgdkx112)] | |
private extern static IntPtr gdk_x11_visual_get_xvisual(IntPtr gdk_visual); | |
// GLX | |
[DllImport(libGLX)] | |
private extern static IntPtr glXGetProcAddress(IntPtr* func_name); | |
[DllImport(libGLX)] | |
private extern static bool glXIsDirect(IntPtr display, IntPtr glx_context); | |
[DllImport(libGLX)] | |
private extern static IntPtr glXChooseVisual(IntPtr display, int screen_numberm, ref int[] attrilists); | |
[DllImport(libGLX)] | |
private extern static IntPtr glXCreateContext(IntPtr x_display, IntPtr x_visualinfo, IntPtr share, bool direct); | |
[DllImport(libGLX)] | |
private extern static bool glXMakeCurrent(IntPtr x_display, IntPtr x_window, IntPtr glx_context); | |
[DllImport(libGLX)] | |
private extern static void glXSwapBuffers(IntPtr display, IntPtr drawable); | |
[DllImport(libGLX)] | |
private extern static void glXDestroyContext(IntPtr display, IntPtr glx_context); | |
[Flags] | |
internal enum GLXAttribute | |
{ | |
TRANSPARENT_BLUE_VALUE_EXT = 0x27, | |
GRAY_SCALE = 0x8006, | |
RGBA_TYPE = 0x8014, | |
TRANSPARENT_RGB_EXT = 0x8008, | |
ACCUM_BLUE_SIZE = 16, | |
SHARE_CONTEXT_EXT = 0x800A, | |
STEREO = 6, | |
ALPHA_SIZE = 11, | |
FLOAT_COMPONENTS_NV = 0x20B0, | |
NONE = 0x8000, | |
DEPTH_SIZE = 12, | |
TRANSPARENT_INDEX_VALUE_EXT = 0x24, | |
MAX_PBUFFER_WIDTH_SGIX = 0x8016, | |
GREEN_SIZE = 9, | |
X_RENDERABLE_SGIX = 0x8012, | |
LARGEST_PBUFFER = 0x801C, | |
DONT_CARE = unchecked((int)0xFFFFFFFF), | |
TRANSPARENT_ALPHA_VALUE_EXT = 0x28, | |
PSEUDO_COLOR_EXT = 0x8004, | |
USE_GL = 1, | |
SAMPLE_BUFFERS_SGIS = 100000, | |
TRANSPARENT_GREEN_VALUE_EXT = 0x26, | |
HYPERPIPE_ID_SGIX = 0x8030, | |
COLOR_INDEX_TYPE_SGIX = 0x8015, | |
SLOW_CONFIG = 0x8001, | |
PRESERVED_CONTENTS = 0x801B, | |
ACCUM_RED_SIZE = 14, | |
EVENT_MASK = 0x801F, | |
VISUAL_ID_EXT = 0x800B, | |
EVENT_MASK_SGIX = 0x801F, | |
SLOW_VISUAL_EXT = 0x8001, | |
TRANSPARENT_GREEN_VALUE = 0x26, | |
MAX_PBUFFER_WIDTH = 0x8016, | |
DIRECT_COLOR_EXT = 0x8003, | |
VISUAL_ID = 0x800B, | |
ACCUM_GREEN_SIZE = 15, | |
DRAWABLE_TYPE_SGIX = 0x8010, | |
SCREEN_EXT = 0x800C, | |
SAMPLES = 100001, | |
HEIGHT = 0x801E, | |
TRANSPARENT_INDEX_VALUE = 0x24, | |
SAMPLE_BUFFERS_ARB = 100000, | |
PBUFFER = 0x8023, | |
RGBA_TYPE_SGIX = 0x8014, | |
MAX_PBUFFER_HEIGHT = 0x8017, | |
FBCONFIG_ID_SGIX = 0x8013, | |
DRAWABLE_TYPE = 0x8010, | |
SCREEN = 0x800C, | |
RED_SIZE = 8, | |
VISUAL_SELECT_GROUP_SGIX = 0x8028, | |
VISUAL_CAVEAT_EXT = 0x20, | |
PSEUDO_COLOR = 0x8004, | |
PBUFFER_HEIGHT = 0x8040, | |
STATIC_GRAY = 0x8007, | |
PRESERVED_CONTENTS_SGIX = 0x801B, | |
RGBA_FLOAT_TYPE_ARB = 0x20B9, | |
TRANSPARENT_RED_VALUE = 0x25, | |
TRANSPARENT_ALPHA_VALUE = 0x28, | |
WINDOW = 0x8022, | |
X_RENDERABLE = 0x8012, | |
STENCIL_SIZE = 13, | |
TRANSPARENT_RGB = 0x8008, | |
LARGEST_PBUFFER_SGIX = 0x801C, | |
STATIC_GRAY_EXT = 0x8007, | |
TRANSPARENT_BLUE_VALUE = 0x27, | |
DIGITAL_MEDIA_PBUFFER_SGIX = 0x8024, | |
BLENDED_RGBA_SGIS = 0x8025, | |
NON_CONFORMANT_VISUAL_EXT = 0x800D, | |
COLOR_INDEX_TYPE = 0x8015, | |
TRANSPARENT_RED_VALUE_EXT = 0x25, | |
GRAY_SCALE_EXT = 0x8006, | |
WINDOW_SGIX = 0x8022, | |
X_VISUAL_TYPE = 0x22, | |
MAX_PBUFFER_HEIGHT_SGIX = 0x8017, | |
DOUBLEBUFFER = 5, | |
OPTIMAL_PBUFFER_WIDTH_SGIX = 0x8019, | |
X_VISUAL_TYPE_EXT = 0x22, | |
WIDTH_SGIX = 0x801D, | |
STATIC_COLOR_EXT = 0x8005, | |
BUFFER_SIZE = 2, | |
DIRECT_COLOR = 0x8003, | |
MAX_PBUFFER_PIXELS = 0x8018, | |
NONE_EXT = 0x8000, | |
HEIGHT_SGIX = 0x801E, | |
RENDER_TYPE = 0x8011, | |
FBCONFIG_ID = 0x8013, | |
TRANSPARENT_INDEX_EXT = 0x8009, | |
TRANSPARENT_INDEX = 0x8009, | |
TRANSPARENT_TYPE_EXT = 0x23, | |
ACCUM_ALPHA_SIZE = 17, | |
PBUFFER_SGIX = 0x8023, | |
MAX_PBUFFER_PIXELS_SGIX = 0x8018, | |
OPTIMAL_PBUFFER_HEIGHT_SGIX = 0x801A, | |
DAMAGED = 0x8020, | |
SAVED_SGIX = 0x8021, | |
TRANSPARENT_TYPE = 0x23, | |
MULTISAMPLE_SUB_RECT_WIDTH_SGIS = 0x8026, | |
NON_CONFORMANT_CONFIG = 0x800D, | |
BLUE_SIZE = 10, | |
TRUE_COLOR_EXT = 0x8002, | |
SAMPLES_SGIS = 100001, | |
SAMPLES_ARB = 100001, | |
TRUE_COLOR = 0x8002, | |
RGBA = 4, | |
AUX_BUFFERS = 7, | |
SAMPLE_BUFFERS = 100000, | |
SAVED = 0x8021, | |
MULTISAMPLE_SUB_RECT_HEIGHT_SGIS = 0x8027, | |
DAMAGED_SGIX = 0x8020, | |
STATIC_COLOR = 0x8005, | |
PBUFFER_WIDTH = 0x8041, | |
WIDTH = 0x801D, | |
LEVEL = 3, | |
CONFIG_CAVEAT = 0x20, | |
RENDER_TYPE_SGIX = 0x8011, | |
SWAP_INTERVAL_EXT = 0x20F1, | |
MAX_SWAP_INTERVAL_EXT = 0x20F2, | |
} | |
// X11 | |
[DllImport(libx11)] | |
private extern static void XFree(IntPtr handle); | |
[DllImport(libx11)] | |
private extern static IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int alloc); | |
[DllImport(libx11)] | |
private extern static int XMapWindow(IntPtr display, IntPtr window); | |
[DllImport(libx11)] | |
private extern static void XDestroyWindow(IntPtr display, IntPtr window); | |
[DllImport(libx11)] | |
private extern static void XFlush(IntPtr display); | |
public GLArea() | |
{ | |
AppPaintable = true; | |
} | |
~GLArea() | |
{ | |
Dispose(false); | |
} | |
public override void Dispose() | |
{ | |
GC.SuppressFinalize(this); | |
Dispose(true); | |
base.Dispose(); | |
} | |
public virtual void Dispose(bool disposing) | |
{ | |
if (disposing) | |
{ | |
glXMakeCurrent(display, window, glx_context); | |
if (display != IntPtr.Zero && window != IntPtr.Zero || glx_context != IntPtr.Zero) | |
{ | |
display = window = glx_context = IntPtr.Zero; | |
} | |
glXDestroyContext(display, glx_context); | |
XDestroyWindow(display, window); | |
} | |
} | |
public event EventHandler Initialized; | |
protected virtual void OnInitialized() | |
{ | |
if (Initialized != null) | |
Initialized(this, EventArgs.Empty); | |
} | |
public event EventHandler RenderFrame; | |
protected virtual void OnRenderFrame() | |
{ | |
if (RenderFrame != null) | |
RenderFrame(this, EventArgs.Empty); | |
} | |
protected override bool OnExposeEvent(Gdk.EventExpose evnt) | |
{ | |
if (!initialized) | |
{ | |
display = gdk_x11_display_get_xdisplay(Display.Handle); | |
window = gdk_x11_drawable_get_xid(GdkWindow.Handle); | |
screen_number = Screen.Number; | |
int[] attributes = | |
{ | |
(int)GLXAttribute.RGBA, | |
(int)GLXAttribute.RED_SIZE, 8, | |
(int)GLXAttribute.GREEN_SIZE, 8, | |
(int)GLXAttribute.BLUE_SIZE, 8, | |
(int)GLXAttribute.DOUBLEBUFFER, | |
(int)GLXAttribute.USE_GL | |
}; | |
visualinfo = glXChooseVisual(display, screen_number, ref attributes); | |
glx_context = glXCreateContext(display, visualinfo, IntPtr.Zero, true); | |
if (visualinfo == IntPtr.Zero) | |
XFree(visualinfo); | |
XMapWindow(display, window); | |
XFlush(display); | |
OnInitialized(); | |
} | |
/*else | |
{ | |
glXMakeCurrent(display, window, glx_context); | |
}*/ | |
glXMakeCurrent(display, window, glx_context); | |
bool result = base.OnExposeEvent(evnt); | |
OnRenderFrame(); | |
evnt.Window.Display.Sync(); | |
glXSwapBuffers(display, window); | |
return result; | |
} | |
public IntPtr GetProcAddress(string func_name) | |
{ | |
IntPtr* proc_name_ptr = stackalloc IntPtr[1]; | |
proc_name_ptr[1] = Marshal.StringToHGlobalAnsi(func_name); | |
return glXGetProcAddress(proc_name_ptr); | |
} | |
public bool IsDirect | |
{ | |
get | |
{ | |
return glXIsDirect(display, glx_context); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment