/// <summary> /// Query the OpenGL implementation limits. /// </summary> /// <param name="glExtensions"> /// A <see cref="Gl.Extensions"/> that specify the supported OpenGL extension by the current /// implementation. /// </param> /// <returns> /// It returns a <see cref="GraphicsLimits"/> that specify the current OpenGL implementation limits. /// </returns> /// <remarks> /// It is assumed to have a valid OpenGL context current on the calling thread. /// </remarks> public static GraphicsLimits Query(Gl.Extensions glExtensions) { if (glExtensions == null) throw new ArgumentNullException("glExtensions"); KhronosApi.LogComment("Query OpenGL implementation imits."); GraphicsLimits graphicsLimits = new GraphicsLimits(); FieldInfo[] graphicsLimitsFields = typeof(GraphicsLimits).GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo field in graphicsLimitsFields) { GraphicsLimitAttribute graphicsLimitAttribute = (GraphicsLimitAttribute)Attribute.GetCustomAttribute(field, typeof(GraphicsLimitAttribute)); Attribute[] graphicsExtensionAttributes = Attribute.GetCustomAttributes(field, typeof(KhronosApi.ExtensionAttribute)); MethodInfo getMethod; if (graphicsLimitAttribute == null) continue; // Check extension support if ((graphicsExtensionAttributes != null) && (graphicsExtensionAttributes.Length > 0)) { bool supported = Array.Exists(graphicsExtensionAttributes, delegate(Attribute item) { return glExtensions.HasExtensions(((KhronosApi.ExtensionAttribute)item).ExtensionName); }); if (supported == false) continue; } // Determine which method is used to get the OpenGL limit if (field.FieldType != typeof(String)) { if (field.FieldType.IsArray == true) getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType }, null); else getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType.MakeByRefType() }, null); } else getMethod = typeof(Gl).GetMethod("GetString", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32) }, null); if (getMethod != null) { if (field.FieldType != typeof(String)) { object obj; if (field.FieldType.IsArray == false) obj = Activator.CreateInstance(field.FieldType); else obj = Array.CreateInstance(field.FieldType.GetElementType(), graphicsLimitAttribute.ArrayLenght); object[] @params = new object[] { graphicsLimitAttribute.EnumValue, obj }; try { getMethod.Invoke(null, @params); field.SetValue(graphicsLimits, @params[1]); } catch (Exception) { } } else { try { string s = (string)getMethod.Invoke(null, new object[] { graphicsLimitAttribute.EnumValue }); field.SetValue(graphicsLimits, s); } catch (Exception) { } } } else throw new InvalidOperationException("GraphicsLimits field " + field.Name + " doesn't have a OpenGL compatible type"); string fieldValueString; object fieldValue = field.GetValue(graphicsLimits); if (fieldValue is Array) { StringBuilder sb = new StringBuilder(); sb.Append("{ "); if (((Array)fieldValue).Length > 0) { foreach (object arrayItem in (Array)fieldValue) sb.AppendFormat("{0}, ", arrayItem); sb.Remove(sb.Length - 2, 2); } sb.Append(" }"); fieldValueString = sb.ToString(); } else fieldValueString = fieldValue.ToString(); } return (graphicsLimits); }