Commit 97564363 authored by pcy's avatar pcy
Browse files

reflection setup stuff for effectparameters

parent fdea97de
...@@ -18,8 +18,12 @@ using Microsoft.Xna.Framework.Graphics; ...@@ -18,8 +18,12 @@ using Microsoft.Xna.Framework.Graphics;
* -> set up uniforms and vertex arrays! * -> set up uniforms and vertex arrays!
* --> circumvent? --> HOW?? * --> circumvent? --> HOW??
* --> just go with it?? --> glProgramReady ok, glProgramViewportInfo might segfault! * --> just go with it?? --> glProgramReady ok, glProgramViewportInfo might segfault!
*
* * uniforms * * uniforms
* * samplers, textures * * samplers, textures
* -> https://www.khronos.org/opengl/wiki/Program_Introspection
* -> https://stackoverflow.com/questions/440144/in-opengl-is-there-a-way-to-get-a-list-of-all-uniforms-attribs-used-by-a-shade#442819
* * vertex format verification!
*/ */
namespace PoroCYon.FNAGLSL { namespace PoroCYon.FNAGLSL {
...@@ -45,9 +49,17 @@ namespace PoroCYon.FNAGLSL { ...@@ -45,9 +49,17 @@ namespace PoroCYon.FNAGLSL {
uint[] glshdrs; uint[] glshdrs;
uint glprgm; uint glprgm;
EffectTechnique fakeTech;
readonly static List<EffectTechnique> emptyEffTechList = new List<EffectTechnique>();
public unsafe GLSLEffect(GraphicsDevice gd, public unsafe GLSLEffect(GraphicsDevice gd,
IDictionary<GLSLPurpose, string> shaders) IDictionary<GLSLPurpose, string> shaders)
: base(/*UGLY hack*/new BasicEffect(gd)) { : base(/*UGLY hack*/new BasicEffect(gd)) {
fakeTech = Techniques[0];
// cause NullRefExns when dumb code would try to access the techns
this.SetTechniques(null/*ReflUtil.CreateTechColl(emptyEffTechList)*/);
GL.Init(gd); GL.Init(gd);
GL.GetError(); // ignore errors from FNA/mojoshader GL.GetError(); // ignore errors from FNA/mojoshader
...@@ -55,8 +67,8 @@ namespace PoroCYon.FNAGLSL { ...@@ -55,8 +67,8 @@ namespace PoroCYon.FNAGLSL {
// this effect will do the same as binding the 0 program in OpenGL, // this effect will do the same as binding the 0 program in OpenGL,
// so the BasicEffect used won't do much anymore // so the BasicEffect used won't do much anymore
/*gd.DeleteEffect(this); /*gd.DeleteEffect(this);
eff.SetGLEffectData(IntPtr.Zero); this.SetGLEffectData(IntPtr.Zero);
eff.SetEffectData (IntPtr.Zero);*/ this.SetEffectData (IntPtr.Zero);*/
// turns out we can't do this, or libmojoshader will segfault // turns out we can't do this, or libmojoshader will segfault
// because it lacks some null checking in // because it lacks some null checking in
// glEffectEnd, glEffectBeginPass, glProgramViewportInfo :/ ... // glEffectEnd, glEffectBeginPass, glProgramViewportInfo :/ ...
...@@ -133,6 +145,10 @@ namespace PoroCYon.FNAGLSL { ...@@ -133,6 +145,10 @@ namespace PoroCYon.FNAGLSL {
public ActiveEffect Bind() { // TODO: how to warn on discarding the retval? public ActiveEffect Bind() { // TODO: how to warn on discarding the retval?
GL.GetError(); // ignore errors from FNA/mojoshader GL.GetError(); // ignore errors from FNA/mojoshader
// workaround FNA crap
CurrentTechnique = fakeTech;
fakeTech.Passes[0].Apply();
uint oldprgm = unchecked((uint)GL.GetIntegerv(GL.CURRENT_PROGRAM)); uint oldprgm = unchecked((uint)GL.GetIntegerv(GL.CURRENT_PROGRAM));
GL.Throw(); GL.Throw();
...@@ -159,6 +175,9 @@ namespace PoroCYon.FNAGLSL { ...@@ -159,6 +175,9 @@ namespace PoroCYon.FNAGLSL {
protected override void Dispose(bool disposing) { protected override void Dispose(bool disposing) {
if (!IsDisposed) { if (!IsDisposed) {
DelShdrPrgm(); DelShdrPrgm();
this.SetTechniques(ReflUtil.CreateTechColl(new[]{fakeTech}.ToList()));
fakeTech = null;
} }
base.Dispose(disposing); base.Dispose(disposing);
......
...@@ -13,6 +13,73 @@ namespace PoroCYon.FNAGLSL { ...@@ -13,6 +13,73 @@ namespace PoroCYon.FNAGLSL {
readonly static FieldInfo ef_glEffect_fi = typeof(Effect).GetField( readonly static FieldInfo ef_glEffect_fi = typeof(Effect).GetField(
"glEffect", BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance); "glEffect", BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance);
readonly static PropertyInfo ef_Techniques_pi = typeof(Effect).GetProperty(
"Techniques", BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance),
ef_Parameters_pi = typeof(Effect).GetProperty(
"Parameters", BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance);
readonly static ConstructorInfo
ci_EffTechColl, ci_EffParamColl, ci_EffAnnotColl,
ci_EffTech, ci_EffParam, ci_EffAnnot;
static ReflUtil() {
var pm1f = new ParameterModifier(1);
pm1f[0] = false;
var pm4f = new ParameterModifier(4);
pm4f[3] = pm4f[2] = pm4f[1] = pm4f[0] = false;
var pm11f = new ParameterModifier(11);
pm11f[3] = pm11f[2] = pm11f[1] = pm11f[0] = false;
pm11f[7] = pm11f[6] = pm11f[5] = pm11f[4] = false;
pm11f[10]= pm11f[9] = pm11f[8] = false;
var pm7f = new ParameterModifier(7);
pm7f[3] = pm7f[2] = pm7f[1] = pm7f[0] = false;
pm7f[6] = pm7f[5] = pm7f[4] = false;
var pm1fa = new[]{pm1f};
ci_EffTechColl = typeof(EffectTechniqueCollection)
.GetConstructor(BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(List<EffectTechnique>)}, pm1fa);
ci_EffParamColl = typeof(EffectParameterCollection)
.GetConstructor(BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(List<EffectParameter>)}, pm1fa);
ci_EffAnnotColl = typeof(EffectAnnotationCollection)
.GetConstructor(BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(List<EffectAnnotation>)}, pm1fa);
ci_EffTech = typeof(EffectTechnique).GetConstructor(
BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(string), typeof(IntPtr),
typeof(EffectPassCollection), typeof(EffectAnnotationCollection)},
new[]{pm4f});
ci_EffParam = /*typeof(EffectParameter).GetConstructor( // FIXME: no worky
BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(string), typeof(string), typeof(int),
typeof(int), typeof(int), typeof(EffectParameterClass),
typeof(EffectParameterType), typeof(EffectParameterCollection),
typeof(EffectAnnotationCollection), typeof(IntPtr), typeof(uint)},
new[]{pm11f});*/
// fuck it
typeof(EffectParameter).GetConstructors(BindingFlags.Instance
|BindingFlags.CreateInstance|BindingFlags.NonPublic)[0];
ci_EffAnnot = typeof(EffectAnnotation).GetConstructor(
BindingFlags.CreateInstance|BindingFlags.NonPublic|BindingFlags.Instance,
null, new[]{typeof(string), typeof(string), typeof(int),
typeof(int), typeof(EffectParameterClass),
typeof(EffectParameterType), typeof(IntPtr)}, new[]{pm7f});
if (ci_EffTechColl == null || ci_EffParamColl == null ||
ci_EffAnnotColl == null || ci_EffTech == null ||
ci_EffParam == null || ci_EffAnnot == null)
throw new Exception("can't find ctors");
}
static MethodInfo gldev_DeleteEffect_mi; static MethodInfo gldev_DeleteEffect_mi;
static PropertyInfo ef_GLEffectData_pi, ef_EffectData_pi; static PropertyInfo ef_GLEffectData_pi, ef_EffectData_pi;
...@@ -79,6 +146,38 @@ namespace PoroCYon.FNAGLSL { ...@@ -79,6 +146,38 @@ namespace PoroCYon.FNAGLSL {
ef_EffectData_pi.SetValue(gleff, value); ef_EffectData_pi.SetValue(gleff, value);
} }
public static void SetTechniques(this Effect eff, EffectTechniqueCollection value) {
ef_Techniques_pi.SetValue(eff, value);
}
public static void SetParameters(this Effect eff, EffectParameterCollection value) {
ef_Parameters_pi.SetValue(eff, value);
}
public static EffectTechniqueCollection CreateTechColl(List<EffectTechnique> techniques)
=> (EffectTechniqueCollection)ci_EffTechColl.Invoke(new[]{techniques});
public static EffectParameterCollection CreateParamColl(List<EffectParameter> parms)
=> (EffectParameterCollection)ci_EffParamColl.Invoke(new[]{parms});
public static EffectAnnotationCollection CreateAnnotColl(List<EffectAnnotation> annots)
=> (EffectAnnotationCollection)ci_EffAnnotColl.Invoke(new[]{annots});
public static EffectTechnique CreateTechnique(string name, IntPtr pointer,
EffectPassCollection passes, EffectAnnotationCollection annots)
=> (EffectTechnique)ci_EffTech.Invoke(new object[]{name, pointer,
passes, annots});
public static EffectParameter CreateParameter(string name, string semantic,
int rowCount, int colCount, int elemCount,
EffectParameterClass paramClass, EffectParameterType paramType,
EffectParameterCollection structMembers, EffectAnnotationCollection annots,
IntPtr data, uint dataSize)
=> (EffectParameter)ci_EffParam.Invoke(new object[]{name, semantic,
rowCount, colCount, elemCount, paramClass, paramType,
structMembers, annots, data, dataSize});
public static EffectAnnotation CreateAnnotation(string name, string semantic,
int rowCount, int colCount, EffectParameterClass paramClass,
EffectParameterType paramType, IntPtr data)
=> (EffectAnnotation)ci_EffAnnot.Invoke(new object[]{name, semantic,
rowCount, colCount, paramClass, paramType, data});
} }
} }
...@@ -36,13 +36,6 @@ class TestGame : Game { ...@@ -36,13 +36,6 @@ class TestGame : Game {
BasicEffect hlsl; BasicEffect hlsl;
GLSLEffect glsl; GLSLEffect glsl;
readonly VertexType[] vertices = new[] {
new VertexType(new Vector3(-1, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3(-1, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 1, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 1, 1, 0), Color.Yellow, new Vector2(1, 1))
};
public TestGame() : base() { public TestGame() : base() {
gdm = new GraphicsDeviceManager(this); gdm = new GraphicsDeviceManager(this);
} }
...@@ -132,18 +125,65 @@ class TestGame : Game { ...@@ -132,18 +125,65 @@ class TestGame : Game {
/*for (int i = 0; i < hlsl.Techniques.Count; ++i) /*for (int i = 0; i < hlsl.Techniques.Count; ++i)
Console.WriteLine(String.Format("t{0}: {1}", i, hlsl.Techniques[i].Name));*/ Console.WriteLine(String.Format("t{0}: {1}", i, hlsl.Techniques[i].Name));*/
/*var tech = hlsl.CurrentTechnique = hlsl.Techniques[0];
var tech = hlsl.CurrentTechnique = hlsl.Techniques[0];
for (int i = 0; i < tech.Passes.Count; ++i) { for (int i = 0; i < tech.Passes.Count; ++i) {
//Console.WriteLine(String.Format("p{0}: {1}", i, tech.Passes[i].Name)); //Console.WriteLine(String.Format("p{0}: {1}", i, tech.Passes[i].Name));
tech.Passes[i].Apply(); tech.Passes[i].Apply();
using (var act = glsl.Bind()) {
GraphicsDevice.DrawUserPrimitives<VertexType>( GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices, 0, 2, VertexType.Format); PrimitiveType.TriangleStrip, vertices_l, 0, 2, VertexType.Format);
} }*/
using (var act = glsl.Bind()) {
GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices_br, 0, 2, VertexType.Format);
} }
} }
readonly VertexType[] vertices_fs = new[] {
new VertexType(new Vector3(-1, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3(-1, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 1, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 1, 1, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_r = new[] {
new VertexType(new Vector3( 0, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3( 0, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 1, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 1, 1, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_l = new[] {
new VertexType(new Vector3(-1, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3(-1, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 0, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 0, 1, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_tr = new[] {
new VertexType(new Vector3( 0, 0, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3( 0, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 1, 0, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 1, 1, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_br = new[] {
new VertexType(new Vector3( 0, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3( 0, 0, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 1, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 1, 0, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_tl = new[] {
new VertexType(new Vector3(-1, 0, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3(-1, 1, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 0, 0, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 0, 1, 0), Color.Yellow, new Vector2(1, 1))
};
readonly VertexType[] vertices_bl = new[] {
new VertexType(new Vector3(-1, -1, 0), Color.Red , new Vector2(0, 0))
, new VertexType(new Vector3(-1, 0, 0), Color.Blue , new Vector2(0, 1))
, new VertexType(new Vector3( 0, -1, 0), Color.Green , new Vector2(1, 0))
, new VertexType(new Vector3( 0, 0, 0), Color.Yellow, new Vector2(1, 1))
};
} }
static class Program { static class Program {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment