Reorganise GL initialisation.
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user