Reorganise GL initialisation.

This commit is contained in:
Paul Chote
2015-12-28 11:18:03 +00:00
parent e63fc00b76
commit e69c3360f6

View File

@@ -23,6 +23,15 @@ namespace OpenRA.Platforms.Default
Justification = "C-style naming is kept for consistency with the underlying native API.")] Justification = "C-style naming is kept for consistency with the underlying native API.")]
internal static class OpenGL internal static class OpenGL
{ {
public enum GLFeatures
{
None = 0,
GL2OrGreater = 1,
FramebufferExt = 4,
}
public static GLFeatures Features { get; private set; }
public const int GL_FALSE = 0; public const int GL_FALSE = 0;
// ClearBufferMask // ClearBufferMask
@@ -338,21 +347,33 @@ namespace OpenRA.Platforms.Default
public static void Initialize() public static void Initialize()
{ {
CheckGlVersion(); // glGetError and glGetString are used in our error handlers
// so we want these to be available early.
if (SDL.SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object") == SDL.SDL_bool.SDL_FALSE) try
{ {
OpenGL.WriteGraphicsLog("OpenRA requires the OpenGL extension GL_EXT_framebuffer_object.\n" glGetError = Bind<GetError>("glGetError");
+ "Please try updating your GPU driver to the latest version provided by the manufacturer."); glGetStringInternal = Bind<GetString>("glGetString");
throw new InvalidProgramException("Missing OpenGL extension GL_EXT_framebuffer_object. See graphics.log for details."); }
catch (Exception)
{
throw new InvalidProgramException("Failed to initialize low-level OpenGL bindings. GPU information is not available");
} }
DetectGLFeatures();
if (!Features.HasFlag(GLFeatures.GL2OrGreater) || !Features.HasFlag(GLFeatures.FramebufferExt))
{
WriteGraphicsLog("Unsupported OpenGL version: " + glGetString(OpenGL.GL_VERSION));
throw new InvalidProgramException("OpenGL Version Error: See graphics.log for details.");
}
else
Console.WriteLine("OpenGL version: " + glGetString(OpenGL.GL_VERSION));
try
{
glFlush = Bind<Flush>("glFlush"); glFlush = Bind<Flush>("glFlush");
glViewport = Bind<Viewport>("glViewport"); glViewport = Bind<Viewport>("glViewport");
glClear = Bind<Clear>("glClear"); glClear = Bind<Clear>("glClear");
glClearColor = Bind<ClearColor>("glClearColor"); glClearColor = Bind<ClearColor>("glClearColor");
glGetError = Bind<GetError>("glGetError");
glGetStringInternal = Bind<GetString>("glGetString");
glGetIntegerv = Bind<GetIntegerv>("glGetIntegerv"); glGetIntegerv = Bind<GetIntegerv>("glGetIntegerv");
glFinish = Bind<Finish>("glFinish"); glFinish = Bind<Finish>("glFinish");
glCreateProgram = Bind<CreateProgram>("glCreateProgram"); glCreateProgram = Bind<CreateProgram>("glCreateProgram");
@@ -414,15 +435,23 @@ namespace OpenRA.Platforms.Default
glFramebufferRenderbufferEXT = Bind<FramebufferRenderbufferEXT>("glFramebufferRenderbufferEXT"); glFramebufferRenderbufferEXT = Bind<FramebufferRenderbufferEXT>("glFramebufferRenderbufferEXT");
glCheckFramebufferStatus = Bind<CheckFramebufferStatus>("glCheckFramebufferStatus"); glCheckFramebufferStatus = Bind<CheckFramebufferStatus>("glCheckFramebufferStatus");
} }
catch (Exception e)
{
OpenGL.WriteGraphicsLog("Failed to initialize OpenGL bindings.\nInner exception was: {0}".F(e));
throw new InvalidProgramException("Failed to initialize OpenGL. See graphics.log for details.");
}
}
static T Bind<T>(string name) static T Bind<T>(string name)
{ {
return (T)(object)Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress(name), typeof(T)); return (T)(object)Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress(name), typeof(T));
} }
static void CheckGlVersion() public static void DetectGLFeatures()
{ {
var versionString = OpenGL.glGetString(OpenGL.GL_VERSION); try
{
var versionString = glGetString(OpenGL.GL_VERSION);
var version = versionString.Contains(" ") ? versionString.Split(' ')[0].Split('.') : versionString.Split('.'); var version = versionString.Contains(" ") ? versionString.Split(' ')[0].Split('.') : versionString.Split('.');
var major = 0; var major = 0;
@@ -433,14 +462,14 @@ namespace OpenRA.Platforms.Default
if (version.Length > 1) if (version.Length > 1)
int.TryParse(version[1], out minor); int.TryParse(version[1], out minor);
Console.WriteLine("Detected OpenGL version: {0}.{1}".F(major, minor)); if (major >= 2 && minor >= 0)
if (major < 2) Features |= GLFeatures.GL2OrGreater;
{
OpenGL.WriteGraphicsLog("OpenRA requires OpenGL version 2.0 or greater and detected {0}.{1}".F(major, minor));
throw new InvalidProgramException("OpenGL Version Error: See graphics.log for details.");
}
CheckGlError(); var hasFramebufferExt = SDL.SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object") == SDL.SDL_bool.SDL_TRUE;
if (hasFramebufferExt)
Features |= GLFeatures.FramebufferExt;
}
catch (Exception) { }
} }
public static void CheckGLError() public static void CheckGLError()