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,81 +347,99 @@ 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");
} }
glFlush = Bind<Flush>("glFlush"); DetectGLFeatures();
glViewport = Bind<Viewport>("glViewport"); if (!Features.HasFlag(GLFeatures.GL2OrGreater) || !Features.HasFlag(GLFeatures.FramebufferExt))
glClear = Bind<Clear>("glClear"); {
glClearColor = Bind<ClearColor>("glClearColor"); WriteGraphicsLog("Unsupported OpenGL version: " + glGetString(OpenGL.GL_VERSION));
glGetError = Bind<GetError>("glGetError"); throw new InvalidProgramException("OpenGL Version Error: See graphics.log for details.");
glGetStringInternal = Bind<GetString>("glGetString"); }
glGetIntegerv = Bind<GetIntegerv>("glGetIntegerv"); else
glFinish = Bind<Finish>("glFinish"); Console.WriteLine("OpenGL version: " + glGetString(OpenGL.GL_VERSION));
glCreateProgram = Bind<CreateProgram>("glCreateProgram");
glUseProgram = Bind<UseProgram>("glUseProgram"); try
glGetProgramiv = Bind<GetProgramiv>("glGetProgramiv"); {
glCreateShader = Bind<CreateShader>("glCreateShader"); glFlush = Bind<Flush>("glFlush");
glShaderSource = Bind<ShaderSource>("glShaderSource"); glViewport = Bind<Viewport>("glViewport");
glCompileShader = Bind<CompileShader>("glCompileShader"); glClear = Bind<Clear>("glClear");
glGetShaderiv = Bind<GetShaderiv>("glGetShaderiv"); glClearColor = Bind<ClearColor>("glClearColor");
glAttachShader = Bind<AttachShader>("glAttachShader"); glGetIntegerv = Bind<GetIntegerv>("glGetIntegerv");
glGetShaderInfoLog = Bind<GetShaderInfoLog>("glGetShaderInfoLog"); glFinish = Bind<Finish>("glFinish");
glLinkProgram = Bind<LinkProgram>("glLinkProgram"); glCreateProgram = Bind<CreateProgram>("glCreateProgram");
glGetProgramInfoLog = Bind<GetProgramInfoLog>("glGetProgramInfoLog"); glUseProgram = Bind<UseProgram>("glUseProgram");
glGetUniformLocation = Bind<GetUniformLocation>("glGetUniformLocation"); glGetProgramiv = Bind<GetProgramiv>("glGetProgramiv");
glGetActiveUniform = Bind<GetActiveUniform>("glGetActiveUniform"); glCreateShader = Bind<CreateShader>("glCreateShader");
glUniform1i = Bind<Uniform1i>("glUniform1i"); glShaderSource = Bind<ShaderSource>("glShaderSource");
glUniform1f = Bind<Uniform1f>("glUniform1f"); glCompileShader = Bind<CompileShader>("glCompileShader");
glUniform2f = Bind<Uniform2f>("glUniform2f"); glGetShaderiv = Bind<GetShaderiv>("glGetShaderiv");
glUniform1fv = Bind<Uniform1fv>("glUniform1fv"); glAttachShader = Bind<AttachShader>("glAttachShader");
glUniform2fv = Bind<Uniform2fv>("glUniform2fv"); glGetShaderInfoLog = Bind<GetShaderInfoLog>("glGetShaderInfoLog");
glUniform3fv = Bind<Uniform3fv>("glUniform3fv"); glLinkProgram = Bind<LinkProgram>("glLinkProgram");
glUniform4fv = Bind<Uniform4fv>("glUniform4fv"); glGetProgramInfoLog = Bind<GetProgramInfoLog>("glGetProgramInfoLog");
glUniformMatrix4fv = Bind<UniformMatrix4fv>("glUniformMatrix4fv"); glGetUniformLocation = Bind<GetUniformLocation>("glGetUniformLocation");
glGenBuffers = Bind<GenBuffers>("glGenBuffers"); glGetActiveUniform = Bind<GetActiveUniform>("glGetActiveUniform");
glBindBuffer = Bind<BindBuffer>("glBindBuffer"); glUniform1i = Bind<Uniform1i>("glUniform1i");
glBufferData = Bind<BufferData>("glBufferData"); glUniform1f = Bind<Uniform1f>("glUniform1f");
glBufferSubData = Bind<BufferSubData>("glBufferSubData"); glUniform2f = Bind<Uniform2f>("glUniform2f");
glDeleteBuffers = Bind<DeleteBuffers>("glDeleteBuffers"); glUniform1fv = Bind<Uniform1fv>("glUniform1fv");
glBindAttribLocation = Bind<BindAttribLocation>("glBindAttribLocation"); glUniform2fv = Bind<Uniform2fv>("glUniform2fv");
glVertexAttribPointer = Bind<VertexAttribPointer>("glVertexAttribPointer"); glUniform3fv = Bind<Uniform3fv>("glUniform3fv");
glEnableVertexAttribArray = Bind<EnableVertexAttribArray>("glEnableVertexAttribArray"); glUniform4fv = Bind<Uniform4fv>("glUniform4fv");
glDisableVertexAttribArray = Bind<DisableVertexAttribArray>("glDisableVertexAttribArray"); glUniformMatrix4fv = Bind<UniformMatrix4fv>("glUniformMatrix4fv");
glDrawArrays = Bind<DrawArrays>("glDrawArrays"); glGenBuffers = Bind<GenBuffers>("glGenBuffers");
glEnable = Bind<Enable>("glEnable"); glBindBuffer = Bind<BindBuffer>("glBindBuffer");
glDisable = Bind<Disable>("glDisable"); glBufferData = Bind<BufferData>("glBufferData");
glBlendEquation = Bind<BlendEquation>("glBlendEquation"); glBufferSubData = Bind<BufferSubData>("glBufferSubData");
glBlendFunc = Bind<BlendFunc>("glBlendFunc"); glDeleteBuffers = Bind<DeleteBuffers>("glDeleteBuffers");
glScissor = Bind<Scissor>("glScissor"); glBindAttribLocation = Bind<BindAttribLocation>("glBindAttribLocation");
glPushClientAttrib = Bind<PushClientAttrib>("glPushClientAttrib"); glVertexAttribPointer = Bind<VertexAttribPointer>("glVertexAttribPointer");
glPopClientAttrib = Bind<PopClientAttrib>("glPopClientAttrib"); glEnableVertexAttribArray = Bind<EnableVertexAttribArray>("glEnableVertexAttribArray");
glPixelStoref = Bind<PixelStoref>("glPixelStoref"); glDisableVertexAttribArray = Bind<DisableVertexAttribArray>("glDisableVertexAttribArray");
glReadPixels = Bind<ReadPixels>("glReadPixels"); glDrawArrays = Bind<DrawArrays>("glDrawArrays");
glGenTextures = Bind<GenTextures>("glGenTextures"); glEnable = Bind<Enable>("glEnable");
glDeleteTextures = Bind<DeleteTextures>("glDeleteTextures"); glDisable = Bind<Disable>("glDisable");
glBindTexture = Bind<BindTexture>("glBindTexture"); glBlendEquation = Bind<BlendEquation>("glBlendEquation");
glActiveTexture = Bind<ActiveTexture>("glActiveTexture"); glBlendFunc = Bind<BlendFunc>("glBlendFunc");
glTexImage2D = Bind<TexImage2D>("glTexImage2D"); glScissor = Bind<Scissor>("glScissor");
glGetTexImage = Bind<GetTexImage>("glGetTexImage"); glPushClientAttrib = Bind<PushClientAttrib>("glPushClientAttrib");
glTexParameteri = Bind<TexParameteri>("glTexParameteri"); glPopClientAttrib = Bind<PopClientAttrib>("glPopClientAttrib");
glTexParameterf = Bind<TexParameterf>("glTexParameterf"); glPixelStoref = Bind<PixelStoref>("glPixelStoref");
glGenFramebuffersEXT = Bind<GenFramebuffersEXT>("glGenFramebuffersEXT"); glReadPixels = Bind<ReadPixels>("glReadPixels");
glBindFramebufferEXT = Bind<BindFramebufferEXT>("glBindFramebufferEXT"); glGenTextures = Bind<GenTextures>("glGenTextures");
glFramebufferTexture2DEXT = Bind<FramebufferTexture2DEXT>("glFramebufferTexture2DEXT"); glDeleteTextures = Bind<DeleteTextures>("glDeleteTextures");
glDeleteFramebuffersEXT = Bind<DeleteFramebuffersEXT>("glDeleteFramebuffersEXT"); glBindTexture = Bind<BindTexture>("glBindTexture");
glGenRenderbuffersEXT = Bind<GenRenderbuffersEXT>("glGenRenderbuffersEXT"); glActiveTexture = Bind<ActiveTexture>("glActiveTexture");
glBindRenderbufferEXT = Bind<BindRenderbufferEXT>("glBindRenderbufferEXT"); glTexImage2D = Bind<TexImage2D>("glTexImage2D");
glRenderbufferStorageEXT = Bind<RenderbufferStorageEXT>("glRenderbufferStorageEXT"); glGetTexImage = Bind<GetTexImage>("glGetTexImage");
glDeleteRenderbuffersEXT = Bind<DeleteRenderbuffersEXT>("glDeleteRenderbuffersEXT"); glTexParameteri = Bind<TexParameteri>("glTexParameteri");
glFramebufferRenderbufferEXT = Bind<FramebufferRenderbufferEXT>("glFramebufferRenderbufferEXT"); glTexParameterf = Bind<TexParameterf>("glTexParameterf");
glCheckFramebufferStatus = Bind<CheckFramebufferStatus>("glCheckFramebufferStatus"); glGenFramebuffersEXT = Bind<GenFramebuffersEXT>("glGenFramebuffersEXT");
glBindFramebufferEXT = Bind<BindFramebufferEXT>("glBindFramebufferEXT");
glFramebufferTexture2DEXT = Bind<FramebufferTexture2DEXT>("glFramebufferTexture2DEXT");
glDeleteFramebuffersEXT = Bind<DeleteFramebuffersEXT>("glDeleteFramebuffersEXT");
glGenRenderbuffersEXT = Bind<GenRenderbuffersEXT>("glGenRenderbuffersEXT");
glBindRenderbufferEXT = Bind<BindRenderbufferEXT>("glBindRenderbufferEXT");
glRenderbufferStorageEXT = Bind<RenderbufferStorageEXT>("glRenderbufferStorageEXT");
glDeleteRenderbuffersEXT = Bind<DeleteRenderbuffersEXT>("glDeleteRenderbuffersEXT");
glFramebufferRenderbufferEXT = Bind<FramebufferRenderbufferEXT>("glFramebufferRenderbufferEXT");
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)
@@ -420,27 +447,29 @@ namespace OpenRA.Platforms.Default
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 version = versionString.Contains(" ") ? versionString.Split(' ')[0].Split('.') : versionString.Split('.');
var major = 0;
if (version.Length > 0)
int.TryParse(version[0], out major);
var minor = 0;
if (version.Length > 1)
int.TryParse(version[1], out minor);
Console.WriteLine("Detected OpenGL version: {0}.{1}".F(major, minor));
if (major < 2)
{ {
OpenGL.WriteGraphicsLog("OpenRA requires OpenGL version 2.0 or greater and detected {0}.{1}".F(major, minor)); var versionString = glGetString(OpenGL.GL_VERSION);
throw new InvalidProgramException("OpenGL Version Error: See graphics.log for details."); var version = versionString.Contains(" ") ? versionString.Split(' ')[0].Split('.') : versionString.Split('.');
}
CheckGlError(); var major = 0;
if (version.Length > 0)
int.TryParse(version[0], out major);
var minor = 0;
if (version.Length > 1)
int.TryParse(version[1], out minor);
if (major >= 2 && minor >= 0)
Features |= GLFeatures.GL2OrGreater;
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()