2009-02-22 10:43:35 +00:00
|
|
|
|
#region --- License ---
|
|
|
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
|
|
|
* See license.txt for license info
|
|
|
|
|
*
|
|
|
|
|
* Date: 12/8/2007
|
2009-07-19 17:50:41 +00:00
|
|
|
|
* Time: 6:43 <EFBFBD><EFBFBD>
|
2009-02-22 10:43:35 +00:00
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
using System;
|
2014-01-10 08:24:59 +00:00
|
|
|
|
using System.Collections.Generic;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Reflection;
|
2014-01-21 08:00:25 +00:00
|
|
|
|
using OpenTK.Graphics;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
|
|
namespace OpenTK.Platform.Windows
|
|
|
|
|
{
|
2014-01-21 08:00:25 +00:00
|
|
|
|
internal partial class Wgl : GraphicsBindingsBase
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:00:25 +00:00
|
|
|
|
static IntPtr[] EntryPoints;
|
|
|
|
|
static string[] EntryPointNames;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
|
|
internal const string Library = "OPENGL32.DLL";
|
|
|
|
|
|
2014-01-10 08:24:59 +00:00
|
|
|
|
readonly static Dictionary<string, bool> extensions =
|
|
|
|
|
new Dictionary<string, bool>();
|
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
static readonly object sync = new object();
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
public Wgl()
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:00:25 +00:00
|
|
|
|
EntryPointsInstance = EntryPoints;
|
|
|
|
|
EntryPointNamesInstance = EntryPointNames;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
#region Public Members
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2014-01-10 08:24:59 +00:00
|
|
|
|
public static bool SupportsExtension(string name)
|
|
|
|
|
{
|
|
|
|
|
return SupportsExtension(Wgl.GetCurrentDC(), name);
|
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2014-01-10 08:24:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks if a Wgl extension is supported by the given context.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="context">The device context.</param>
|
|
|
|
|
/// <param name="ext">The extension to check.</param>
|
|
|
|
|
/// <returns>True if the extension is supported by the given context, false otherwise</returns>
|
|
|
|
|
public static bool SupportsExtension(IntPtr dc, string name)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
lock (sync)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
if (extensions.Count == 0)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
// We cache this locally, as another thread might create a context which doesn't support this method.
|
|
|
|
|
// The design is far from ideal, but there's no good solution to this issue as long as we are using
|
|
|
|
|
// static WGL/GL classes. Fortunately, this issue is extremely unlikely to arise in practice, as you'd
|
|
|
|
|
// have to create one accelerated and one non-accelerated context in the same application, with the
|
|
|
|
|
// non-accelerated context coming second.
|
|
|
|
|
bool get_arb = SupportsFunction("wglGetExtensionsStringARB");
|
|
|
|
|
bool get_ext = SupportsFunction("wglGetExtensionsStringEXT");
|
|
|
|
|
string str =
|
|
|
|
|
get_arb ? Arb.GetExtensionsString(dc) :
|
|
|
|
|
get_ext ? Ext.GetExtensionsString() :
|
|
|
|
|
String.Empty;
|
|
|
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(str))
|
2014-01-10 08:24:59 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
foreach (string ext in str.Split(' '))
|
|
|
|
|
{
|
|
|
|
|
extensions.Add(ext, true);
|
|
|
|
|
}
|
2014-01-10 08:24:59 +00:00
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-01-10 08:24:59 +00:00
|
|
|
|
|
|
|
|
|
if (extensions.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
return extensions.ContainsKey(name);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks whether an extension function is supported.
|
|
|
|
|
/// Do not use with core WGL functions, as this function
|
|
|
|
|
/// will incorrectly return false.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The extension function to check (e.g. "wglGetExtensionsStringARB"</param>
|
|
|
|
|
/// <returns>True if the extension function is supported; otherwise, false.</returns>
|
|
|
|
|
public static bool SupportsFunction(string name)
|
|
|
|
|
{
|
|
|
|
|
int index = Array.IndexOf(EntryPointNames, name);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
return EntryPoints[index] != IntPtr.Zero;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Protected Members
|
|
|
|
|
|
|
|
|
|
protected override object SyncRoot
|
|
|
|
|
{
|
|
|
|
|
get { return sync; }
|
|
|
|
|
}
|
2014-01-10 08:24:59 +00:00
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
protected override IntPtr GetAddress(string function_string)
|
2014-01-10 08:24:59 +00:00
|
|
|
|
{
|
2014-01-21 08:00:25 +00:00
|
|
|
|
IntPtr address = Wgl.GetProcAddress(function_string);
|
|
|
|
|
if (!IsValid(address))
|
|
|
|
|
{
|
|
|
|
|
address = Functions.GetProcAddress(WinFactory.OpenGLHandle, function_string);
|
|
|
|
|
}
|
|
|
|
|
return address;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
#endregion
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
#region Private Members
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2014-01-21 08:00:25 +00:00
|
|
|
|
static bool IsValid(IntPtr address)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2014-01-21 08:00:25 +00:00
|
|
|
|
// See https://www.opengl.org/wiki/Load_OpenGL_Functions
|
|
|
|
|
long a = address.ToInt64();
|
|
|
|
|
bool is_valid = (a < -1) || (a > 3);
|
|
|
|
|
return is_valid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Internal Members
|
|
|
|
|
|
|
|
|
|
internal override void LoadEntryPoints()
|
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
lock (SyncRoot)
|
2014-01-21 08:00:25 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
if (Wgl.GetCurrentContext() != IntPtr.Zero)
|
2014-01-21 08:00:25 +00:00
|
|
|
|
{
|
2014-01-21 08:04:27 +00:00
|
|
|
|
for (int i = 0; i < EntryPointsInstance.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
EntryPointsInstance[i] = GetAddress(EntryPointNamesInstance[i]);
|
|
|
|
|
}
|
|
|
|
|
extensions.Clear();
|
2014-01-21 08:00:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|