Commit 12a42e47 authored by pcy's avatar pcy
Browse files

EffectParameters now filled in! (except for textures)

parent 34b3f35b
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
...@@ -27,7 +28,24 @@ using Microsoft.Xna.Framework.Graphics; ...@@ -27,7 +28,24 @@ using Microsoft.Xna.Framework.Graphics;
*/ */
namespace PoroCYon.FNAGLSL { namespace PoroCYon.FNAGLSL {
public class GLSLEffect : Effect { struct UnifData {
public int location;
public string name;
public GLSLType type;
public int size;
public int rows, cols;
public EffectParameterClass epclass;
public EffectParameterType eptype;
public uint bytesize;
public UnifData(int loc, string n, GLSLType t, int sz, int r, int c,
EffectParameterClass epc, EffectParameterType ept, uint bsz) {
location = loc; name = n; type = t; size = sz; rows = r;
cols = c; epclass = epc; eptype = ept; bytesize = bsz;
}
}
public partial class GLSLEffect : Effect {
public struct ActiveEffect : IDisposable { public struct ActiveEffect : IDisposable {
internal uint oldprgm; internal uint oldprgm;
bool disposed; bool disposed;
...@@ -51,11 +69,15 @@ namespace PoroCYon.FNAGLSL { ...@@ -51,11 +69,15 @@ namespace PoroCYon.FNAGLSL {
EffectTechnique fakeTech; EffectTechnique fakeTech;
IntPtr unifDataBacking;
UnifData[] unifs;
//readonly static List<EffectTechnique> emptyEffTechList = new List<EffectTechnique>(); //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]; fakeTech = Techniques[0];
unifDataBacking = IntPtr.Zero;
// cause NullRefExns when dumb code would try to access the techns // cause NullRefExns when dumb code would try to access the techns
this.SetTechniques(null/*ReflUtil.CreateTechColl(emptyEffTechList)*/); this.SetTechniques(null/*ReflUtil.CreateTechColl(emptyEffTechList)*/);
...@@ -131,9 +153,12 @@ namespace PoroCYon.FNAGLSL { ...@@ -131,9 +153,12 @@ namespace PoroCYon.FNAGLSL {
} }
} }
readonly static EffectParameterCollection emptyParamColl
= ReflUtil.CreateParamColl(new List<EffectParameter >());
readonly static EffectAnnotationCollection emptyAnnotColl
= ReflUtil.CreateAnnotColl(new List<EffectAnnotation>());
void ParseAttribUnif() { void ParseAttribUnif() {
// TODO: build EffectParameter stuff /*int attrs = GL.GetProgramiv(glprgm, GL.ACTIVE_ATTRIBUTES);
int attrs = GL.GetProgramiv(glprgm, GL.ACTIVE_ATTRIBUTES);
GL.Throw(); GL.Throw();
Console.WriteLine("#attrs = " + attrs); Console.WriteLine("#attrs = " + attrs);
for (int i = 0; i < attrs; ++i) { for (int i = 0; i < attrs; ++i) {
...@@ -146,12 +171,15 @@ namespace PoroCYon.FNAGLSL { ...@@ -146,12 +171,15 @@ namespace PoroCYon.FNAGLSL {
Console.WriteLine("attrs["+i+"] = {size=" + size + ", type=" Console.WriteLine("attrs["+i+"] = {size=" + size + ", type="
+ type + ", name=" + name + ", loc="+loc+"}"); + type + ", name=" + name + ", loc="+loc+"}");
} }*/
int unifs = GL.GetProgramiv(glprgm, GL.ACTIVE_UNIFORMS); int nunifs = GL.GetProgramiv(glprgm, GL.ACTIVE_UNIFORMS);
GL.Throw(); GL.Throw();
Console.WriteLine("#unifs = " + unifs); unifs = new UnifData[nunifs];
for (int i = 0; i < unifs; ++i) { var parms = new List<EffectParameter>();
uint totalsize = 0;
//Console.WriteLine("#unifs = " + nunifs);
for (int i = 0; i < nunifs; ++i) {
int size; GLSLType type; string name; int size; GLSLType type; string name;
GL.GetActiveUniform(glprgm, unchecked((uint)i), out size, GL.GetActiveUniform(glprgm, unchecked((uint)i), out size,
out type, out name); out type, out name);
...@@ -159,16 +187,42 @@ namespace PoroCYon.FNAGLSL { ...@@ -159,16 +187,42 @@ namespace PoroCYon.FNAGLSL {
int loc = GL.GetUniformLocation(glprgm, name); int loc = GL.GetUniformLocation(glprgm, name);
GL.Throw(); GL.Throw();
Console.WriteLine("unifs["+i+"] = {size=" + size + ", type=" uint bytesize = unchecked((uint)(typ2size[type]*size));
+ type + ", name=" + name + ", loc="+loc+"}"); unifs[i] = new UnifData(loc, name, type, size, GetRows(type),
GetCols(type), typ2class[type], typ2type[type], bytesize);
totalsize += bytesize;
} }
/* #attrs = 1 IntPtr bleh = Marshal.AllocHGlobal((IntPtr)totalsize);
* attrs[0] = {size=1, type=FLOAT_VEC3, name=in_pos, loc=0} bool ok = false;
* #unifs = 2
* unifs[0] = {size=1, type=FLOAT, name=fGlobalTime, loc=0} try {
* unifs[1] = {size=1, type=FLOAT_VEC2, name=v2Resolution, loc=1} uint sizepos = 0;
*/ for (int i = 0; i < nunifs; ++i) {
var u = unifs[i];
IntPtr bps = (IntPtr)((long)bleh + sizepos);
parms.Add(ReflUtil.CreateParameter(u.name, null/*semantic: ???*/,
u.rows, u.cols, (u.size == 1) ? 0 : u.size,
u.epclass, u.eptype, null, null, //emptyParamColl, emptyAnnotColl,
bps, u.bytesize));
sizepos += u.bytesize;
}
ok = true;
} finally {
if (ok) {
unifDataBacking = bleh;
this.SetParameters(ReflUtil.CreateParamColl(parms));
} else {
Marshal.FreeHGlobal(bleh);
unifDataBacking = IntPtr.Zero;
}
}
}
void ApplyUnifs() {
// TODO
} }
// TODO: find out a better (i.e. more API-conform) way to do this! // TODO: find out a better (i.e. more API-conform) way to do this!
...@@ -188,7 +242,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -188,7 +242,7 @@ namespace PoroCYon.FNAGLSL {
GL.UseProgram(glprgm); GL.UseProgram(glprgm);
GL.Throw(); GL.Throw();
// TODO: apply uniforms and samplers! (XNA API -> OpenGL state) ApplyUnifs();
return new ActiveEffect(oldprgm); return new ActiveEffect(oldprgm);
} }
...@@ -209,10 +263,17 @@ namespace PoroCYon.FNAGLSL { ...@@ -209,10 +263,17 @@ namespace PoroCYon.FNAGLSL {
if (!IsDisposed) { if (!IsDisposed) {
DelShdrPrgm(); DelShdrPrgm();
if (fakeTech != null) {
this.SetTechniques(ReflUtil.CreateTechColl(new[]{fakeTech}.ToList())); this.SetTechniques(ReflUtil.CreateTechColl(new[]{fakeTech}.ToList()));
fakeTech = null; fakeTech = null;
} }
if (unifDataBacking != IntPtr.Zero) {
Marshal.FreeHGlobal(unifDataBacking);
unifDataBacking = IntPtr.Zero;
}
}
base.Dispose(disposing); base.Dispose(disposing);
} }
} }
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using static PoroCYon.FNAGLSL.GLSLType;
using static Microsoft.Xna.Framework.Graphics.EffectParameterClass;
using static Microsoft.Xna.Framework.Graphics.EffectParameterType ;
using C = Microsoft.Xna.Framework.Graphics.EffectParameterClass;
using T = Microsoft.Xna.Framework.Graphics.EffectParameterType ;
namespace PoroCYon.FNAGLSL {
public partial class GLSLEffect : Effect {
readonly static Dictionary<GLSLType, int > typ2size ;
readonly static Dictionary<GLSLType, EffectParameterClass> typ2class;
readonly static Dictionary<GLSLType, EffectParameterType > typ2type ;
static GLSLEffect() {
typ2size = new Dictionary<GLSLType, int>() {
{ FLOAT, sizeof(float) },
{ FLOAT_VEC2, sizeof(float)*2 },
{ FLOAT_VEC3, sizeof(float)*3 },
{ FLOAT_VEC4, sizeof(float)*4 },
{ INT, sizeof(int) },
{ INT_VEC2, sizeof(int)*2 },
{ INT_VEC3, sizeof(int)*3 },
{ INT_VEC4, sizeof(int)*4 },
{ UNSIGNED_INT, sizeof(uint) },
{ UNSIGNED_INT_VEC2, sizeof(uint)*2 },
{ UNSIGNED_INT_VEC3, sizeof(uint)*3 },
{ UNSIGNED_INT_VEC4, sizeof(uint)*4 },
{ BOOL, sizeof(uint)/*!!!*/ },
{ BOOL_VEC2, sizeof(uint)*2 },
{ BOOL_VEC3, sizeof(uint)*3 },
{ BOOL_VEC4, sizeof(uint)*4 },
// NOTE: need to be converted when sending these thru the
// glUniform fns
{ FLOAT_MAT2, sizeof(float)*4*4 },
{ FLOAT_MAT3, sizeof(float)*4*4 },
{ FLOAT_MAT4, sizeof(float)*4*4 },
{ FLOAT_MAT2x3, sizeof(float)*4*4 },
{ FLOAT_MAT2x4, sizeof(float)*4*4 },
{ FLOAT_MAT3x2, sizeof(float)*4*4 },
{ FLOAT_MAT3x4, sizeof(float)*4*4 },
{ FLOAT_MAT4x2, sizeof(float)*4*4 },
{ FLOAT_MAT4x3, sizeof(float)*4*4 },
};
typ2class = new Dictionary<GLSLType, EffectParameterClass>() {
{ FLOAT, Scalar },
{ FLOAT_VEC2, Vector },
{ FLOAT_VEC3, Vector },
{ FLOAT_VEC4, Vector },
{ INT, Scalar },
{ INT_VEC2, Vector },
{ INT_VEC3, Vector },
{ INT_VEC4, Vector },
{ UNSIGNED_INT, Scalar },
{ UNSIGNED_INT_VEC2, Vector },
{ UNSIGNED_INT_VEC3, Vector },
{ UNSIGNED_INT_VEC4, Vector },
{ BOOL, Scalar },
{ BOOL_VEC2, Vector },
{ BOOL_VEC3, Vector },
{ BOOL_VEC4, Vector },
{ FLOAT_MAT2, C.Matrix },
{ FLOAT_MAT3, C.Matrix },
{ FLOAT_MAT4, C.Matrix },
{ FLOAT_MAT2x3, C.Matrix },
{ FLOAT_MAT2x4, C.Matrix },
{ FLOAT_MAT3x2, C.Matrix },
{ FLOAT_MAT3x4, C.Matrix },
{ FLOAT_MAT4x2, C.Matrix },
{ FLOAT_MAT4x3, C.Matrix },
{ SAMPLER_1D, C.Object },
{ SAMPLER_2D, C.Object },
{ SAMPLER_3D, C.Object },
{ SAMPLER_CUBE, C.Object },
{ INT_SAMPLER_1D, C.Object },
{ INT_SAMPLER_2D, C.Object },
{ INT_SAMPLER_3D, C.Object },
{ INT_SAMPLER_CUBE, C.Object },
{ UNSIGNED_INT_SAMPLER_1D, C.Object },
{ UNSIGNED_INT_SAMPLER_2D, C.Object },
{ UNSIGNED_INT_SAMPLER_3D, C.Object },
{ UNSIGNED_INT_SAMPLER_CUBE, C.Object },
};
typ2type = new Dictionary<GLSLType, EffectParameterType>() {
{ FLOAT, T.Single },
{ FLOAT_VEC2, T.Single },
{ FLOAT_VEC3, T.Single },
{ FLOAT_VEC4, T.Single },
{ INT, T.Int32 },
{ INT_VEC2, T.Int32 },
{ INT_VEC3, T.Int32 },
{ INT_VEC4, T.Int32 },
{ UNSIGNED_INT, T.Int32 },
{ UNSIGNED_INT_VEC2, T.Int32 },
{ UNSIGNED_INT_VEC3, T.Int32 },
{ UNSIGNED_INT_VEC4, T.Int32 },
{ BOOL, T.Bool },
{ BOOL_VEC2, T.Bool },
{ BOOL_VEC3, T.Bool },
{ BOOL_VEC4, T.Bool },
{ FLOAT_MAT2, T.Single },
{ FLOAT_MAT3, T.Single },
{ FLOAT_MAT4, T.Single },
{ FLOAT_MAT2x3, T.Single },
{ FLOAT_MAT2x4, T.Single },
{ FLOAT_MAT3x2, T.Single },
{ FLOAT_MAT3x4, T.Single },
{ FLOAT_MAT4x2, T.Single },
{ FLOAT_MAT4x3, T.Single },
{ SAMPLER_1D, T.Texture1D },
{ SAMPLER_2D, T.Texture2D },
{ SAMPLER_3D, T.Texture3D },
{ SAMPLER_CUBE, T.TextureCube },
{ INT_SAMPLER_1D, T.Texture1D },
{ INT_SAMPLER_2D, T.Texture2D },
{ INT_SAMPLER_3D, T.Texture3D },
{ INT_SAMPLER_CUBE, T.TextureCube },
{ UNSIGNED_INT_SAMPLER_1D, T.Texture1D },
{ UNSIGNED_INT_SAMPLER_2D, T.Texture2D },
{ UNSIGNED_INT_SAMPLER_3D, T.Texture3D },
{ UNSIGNED_INT_SAMPLER_CUBE, T.TextureCube },
};
}
static int GetRows(GLSLType t) {
switch (t) {
case FLOAT_MAT2: case FLOAT_MAT3x2: case FLOAT_MAT4x2:
return 2;
case FLOAT_MAT3: case FLOAT_MAT2x3: case FLOAT_MAT4x3:
return 3;
case FLOAT_MAT4: case FLOAT_MAT2x4: case FLOAT_MAT3x4:
return 4;
}
return 0;
}
static int GetCols(GLSLType t) {
switch (t) {
case FLOAT_MAT2: case FLOAT_MAT2x3: case FLOAT_MAT2x4:
return 2;
case FLOAT_MAT3: case FLOAT_MAT3x2: case FLOAT_MAT3x4:
return 3;
case FLOAT_MAT4: case FLOAT_MAT4x2: case FLOAT_MAT4x3:
return 4;
}
return 0;
}
}
}
...@@ -70,7 +70,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -70,7 +70,7 @@ namespace PoroCYon.FNAGLSL {
FLOAT_MAT2 = 0x8B5A, FLOAT_MAT2 = 0x8B5A,
FLOAT_MAT3 = 0x8B5B, FLOAT_MAT3 = 0x8B5B,
FLOAT_MAT4 = 0x8B5C, FLOAT_MAT4 = 0x8B5C,
FLOAT_MAT2x3 = 0x8B65, FLOAT_MAT2x3 = 0x8B65, // column x row
FLOAT_MAT2x4 = 0x8B66, FLOAT_MAT2x4 = 0x8B66,
FLOAT_MAT3x2 = 0x8B67, FLOAT_MAT3x2 = 0x8B67,
FLOAT_MAT3x4 = 0x8B68, FLOAT_MAT3x4 = 0x8B68,
...@@ -80,7 +80,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -80,7 +80,7 @@ namespace PoroCYon.FNAGLSL {
SAMPLER_2D = 0x8B5E, SAMPLER_2D = 0x8B5E,
SAMPLER_3D = 0x8B5F, SAMPLER_3D = 0x8B5F,
SAMPLER_CUBE = 0x8B60, SAMPLER_CUBE = 0x8B60,
SAMPLER_1D_SHADOW = 0x8B61, /*SAMPLER_1D_SHADOW = 0x8B61,
SAMPLER_2D_SHADOW = 0x8B62, SAMPLER_2D_SHADOW = 0x8B62,
SAMPLER_1D_ARRAY = 0x8DC0, SAMPLER_1D_ARRAY = 0x8DC0,
SAMPLER_2D_ARRAY = 0x0DC1, SAMPLER_2D_ARRAY = 0x0DC1,
...@@ -91,27 +91,27 @@ namespace PoroCYon.FNAGLSL { ...@@ -91,27 +91,27 @@ namespace PoroCYon.FNAGLSL {
SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B, SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B,
SAMPLER_2D_RECT = 0x8B63, SAMPLER_2D_RECT = 0x8B63,
SAMPLER_2D_RECT_SHADOW = 0x8B64, SAMPLER_2D_RECT_SHADOW = 0x8B64,
SAMPLER_BUFFER = 0x8DC2, SAMPLER_BUFFER = 0x8DC2,*/
INT_SAMPLER_1D = 0x8DC9, INT_SAMPLER_1D = 0x8DC9,
INT_SAMPLER_2D = 0x8DCA, INT_SAMPLER_2D = 0x8DCA,
INT_SAMPLER_3D = 0x8DCB, INT_SAMPLER_3D = 0x8DCB,
INT_SAMPLER_CUBE = 0x8DCD, INT_SAMPLER_CUBE = 0x8DCD,
INT_SAMPLER_1D_ARRAY = 0x8DCE, /*INT_SAMPLER_1D_ARRAY = 0x8DCE,
INT_SAMPLER_2D_ARRAY = 0x8DCF, INT_SAMPLER_2D_ARRAY = 0x8DCF,
INT_SAMPLER_2D_MULTISAMPLE = 0x9109, INT_SAMPLER_2D_MULTISAMPLE = 0x9109,
INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C, INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C,
INT_SAMPLER_BUFFER = 0x8DD0, INT_SAMPLER_BUFFER = 0x8DD0,
INT_SAMPLER_2D_RECT = 0x8DCD, INT_SAMPLER_2D_RECT = 0x8DCD,*/
UNSIGNED_INT_SAMPLER_1D = 0x8DD1, UNSIGNED_INT_SAMPLER_1D = 0x8DD1,
UNSIGNED_INT_SAMPLER_2D = 0x8DD2, UNSIGNED_INT_SAMPLER_2D = 0x8DD2,
UNSIGNED_INT_SAMPLER_3D = 0x8DD3, UNSIGNED_INT_SAMPLER_3D = 0x8DD3,
UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4,
UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, /*UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6,
UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7,
UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A, UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A,
UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D,
UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8,
UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5 UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5*/
} }
} }
...@@ -169,10 +169,20 @@ namespace PoroCYon.FNAGLSL { ...@@ -169,10 +169,20 @@ namespace PoroCYon.FNAGLSL {
int rowCount, int colCount, int elemCount, int rowCount, int colCount, int elemCount,
EffectParameterClass paramClass, EffectParameterType paramType, EffectParameterClass paramClass, EffectParameterType paramType,
EffectParameterCollection structMembers, EffectAnnotationCollection annots, EffectParameterCollection structMembers, EffectAnnotationCollection annots,
IntPtr data, uint dataSize) IntPtr data, uint dataSize) {
=> (EffectParameter)ci_EffParam.Invoke(new object[]{name, semantic, int plen = ci_EffParam.GetParameters().Length;
if (plen == 11) {
return (EffectParameter)ci_EffParam.Invoke(new object[]{name, semantic,
rowCount, colCount, elemCount, paramClass, paramType, rowCount, colCount, elemCount, paramClass, paramType,
structMembers, annots, data, dataSize}); structMembers, annots, data, dataSize});
} else if (plen == 10) {
return (EffectParameter)ci_EffParam.Invoke(new object[]{name, semantic,
rowCount, colCount, elemCount, paramClass, paramType,
structMembers, annots, data});
} else {
throw new NotSupportedException("Unsupported nargs for EffectParameter ctor! (" + plen + ")");
}
}
public static EffectAnnotation CreateAnnotation(string name, string semantic, public static EffectAnnotation CreateAnnotation(string name, string semantic,
int rowCount, int colCount, EffectParameterClass paramClass, int rowCount, int colCount, EffectParameterClass paramClass,
EffectParameterType paramType, IntPtr data) EffectParameterType paramType, IntPtr data)
......
...@@ -123,7 +123,10 @@ class TestGame : Game { ...@@ -123,7 +123,10 @@ class TestGame : Game {
base.UnloadContent(); base.UnloadContent();
} }
TimeSpan totalTime = TimeSpan.Zero;
protected override void Update(GameTime gt) { protected override void Update(GameTime gt) {
totalTime += gt.ElapsedGameTime;
ks = Keyboard.GetState(); ks = Keyboard.GetState();
base.Update(gt); base.Update(gt);
...@@ -150,6 +153,14 @@ class TestGame : Game { ...@@ -150,6 +153,14 @@ class TestGame : Game {
PrimitiveType.TriangleStrip, vertices_l, 0, 2, VertexType.Format); PrimitiveType.TriangleStrip, vertices_l, 0, 2, VertexType.Format);
}*/ }*/
/*int i = 0;
foreach (var p in glsl.Parameters) {
Console.WriteLine("param[" + i + "] = " + p.Name);
++i;
}*/
glsl.Parameters["fGlobalTime"].SetValue((float)totalTime.TotalSeconds);
glsl.Parameters["v2Resolution"].SetValue(new Vector2(1920, 1080));
using (var act = glsl.Bind()) { using (var act = glsl.Bind()) {
GraphicsDevice.DrawUserPrimitives<VertexType>( GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices_br, 0, 2, VertexType.Format); PrimitiveType.TriangleStrip, vertices_br, 0, 2, VertexType.Format);
......
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