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

EffectParameters now filled in! (except for textures)

parent 34b3f35b
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
......@@ -27,7 +28,24 @@ using Microsoft.Xna.Framework.Graphics;
*/
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 {
internal uint oldprgm;
bool disposed;
......@@ -51,11 +69,15 @@ namespace PoroCYon.FNAGLSL {
EffectTechnique fakeTech;
IntPtr unifDataBacking;
UnifData[] unifs;
//readonly static List<EffectTechnique> emptyEffTechList = new List<EffectTechnique>();
public unsafe GLSLEffect(GraphicsDevice gd,
IDictionary<GLSLPurpose, string> shaders)
: base(/*UGLY hack*/new BasicEffect(gd)) {
fakeTech = Techniques[0];
unifDataBacking = IntPtr.Zero;
// cause NullRefExns when dumb code would try to access the techns
this.SetTechniques(null/*ReflUtil.CreateTechColl(emptyEffTechList)*/);
......@@ -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() {
// TODO: build EffectParameter stuff
int attrs = GL.GetProgramiv(glprgm, GL.ACTIVE_ATTRIBUTES);
/*int attrs = GL.GetProgramiv(glprgm, GL.ACTIVE_ATTRIBUTES);
GL.Throw();
Console.WriteLine("#attrs = " + attrs);
for (int i = 0; i < attrs; ++i) {
......@@ -146,12 +171,15 @@ namespace PoroCYon.FNAGLSL {
Console.WriteLine("attrs["+i+"] = {size=" + size + ", type="
+ type + ", name=" + name + ", loc="+loc+"}");
}
}*/
int unifs = GL.GetProgramiv(glprgm, GL.ACTIVE_UNIFORMS);
int nunifs = GL.GetProgramiv(glprgm, GL.ACTIVE_UNIFORMS);
GL.Throw();
Console.WriteLine("#unifs = " + unifs);
for (int i = 0; i < unifs; ++i) {
unifs = new UnifData[nunifs];
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;
GL.GetActiveUniform(glprgm, unchecked((uint)i), out size,
out type, out name);
......@@ -159,16 +187,42 @@ namespace PoroCYon.FNAGLSL {
int loc = GL.GetUniformLocation(glprgm, name);
GL.Throw();
Console.WriteLine("unifs["+i+"] = {size=" + size + ", type="
+ type + ", name=" + name + ", loc="+loc+"}");
uint bytesize = unchecked((uint)(typ2size[type]*size));
unifs[i] = new UnifData(loc, name, type, size, GetRows(type),
GetCols(type), typ2class[type], typ2type[type], bytesize);
totalsize += bytesize;
}
IntPtr bleh = Marshal.AllocHGlobal((IntPtr)totalsize);
bool ok = false;
try {
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;
}
}
}
/* #attrs = 1
* attrs[0] = {size=1, type=FLOAT_VEC3, name=in_pos, loc=0}
* #unifs = 2
* unifs[0] = {size=1, type=FLOAT, name=fGlobalTime, loc=0}
* unifs[1] = {size=1, type=FLOAT_VEC2, name=v2Resolution, loc=1}
*/
void ApplyUnifs() {
// TODO
}
// TODO: find out a better (i.e. more API-conform) way to do this!
......@@ -188,7 +242,7 @@ namespace PoroCYon.FNAGLSL {
GL.UseProgram(glprgm);
GL.Throw();
// TODO: apply uniforms and samplers! (XNA API -> OpenGL state)
ApplyUnifs();
return new ActiveEffect(oldprgm);
}
......@@ -209,8 +263,15 @@ namespace PoroCYon.FNAGLSL {
if (!IsDisposed) {
DelShdrPrgm();
this.SetTechniques(ReflUtil.CreateTechColl(new[]{fakeTech}.ToList()));
fakeTech = null;
if (fakeTech != null) {
this.SetTechniques(ReflUtil.CreateTechColl(new[]{fakeTech}.ToList()));
fakeTech = null;
}
if (unifDataBacking != IntPtr.Zero) {
Marshal.FreeHGlobal(unifDataBacking);
unifDataBacking = IntPtr.Zero;
}
}
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 {
FLOAT_MAT2 = 0x8B5A,
FLOAT_MAT3 = 0x8B5B,
FLOAT_MAT4 = 0x8B5C,
FLOAT_MAT2x3 = 0x8B65,
FLOAT_MAT2x3 = 0x8B65, // column x row
FLOAT_MAT2x4 = 0x8B66,
FLOAT_MAT3x2 = 0x8B67,
FLOAT_MAT3x4 = 0x8B68,
......@@ -80,7 +80,7 @@ namespace PoroCYon.FNAGLSL {
SAMPLER_2D = 0x8B5E,
SAMPLER_3D = 0x8B5F,
SAMPLER_CUBE = 0x8B60,
SAMPLER_1D_SHADOW = 0x8B61,
/*SAMPLER_1D_SHADOW = 0x8B61,
SAMPLER_2D_SHADOW = 0x8B62,
SAMPLER_1D_ARRAY = 0x8DC0,
SAMPLER_2D_ARRAY = 0x0DC1,
......@@ -91,27 +91,27 @@ namespace PoroCYon.FNAGLSL {
SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B,
SAMPLER_2D_RECT = 0x8B63,
SAMPLER_2D_RECT_SHADOW = 0x8B64,
SAMPLER_BUFFER = 0x8DC2,
SAMPLER_BUFFER = 0x8DC2,*/
INT_SAMPLER_1D = 0x8DC9,
INT_SAMPLER_2D = 0x8DCA,
INT_SAMPLER_3D = 0x8DCB,
INT_SAMPLER_CUBE = 0x8DCD,
INT_SAMPLER_1D_ARRAY = 0x8DCE,
/*INT_SAMPLER_1D_ARRAY = 0x8DCE,
INT_SAMPLER_2D_ARRAY = 0x8DCF,
INT_SAMPLER_2D_MULTISAMPLE = 0x9109,
INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C,
INT_SAMPLER_BUFFER = 0x8DD0,
INT_SAMPLER_2D_RECT = 0x8DCD,
INT_SAMPLER_2D_RECT = 0x8DCD,*/
UNSIGNED_INT_SAMPLER_1D = 0x8DD1,
UNSIGNED_INT_SAMPLER_2D = 0x8DD2,
UNSIGNED_INT_SAMPLER_3D = 0x8DD3,
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_MULTISAMPLE = 0x910A,
UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D,
UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8,
UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5
UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5*/
}
}
......@@ -169,10 +169,20 @@ namespace PoroCYon.FNAGLSL {
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});
IntPtr data, uint dataSize) {
int plen = ci_EffParam.GetParameters().Length;
if (plen == 11) {
return (EffectParameter)ci_EffParam.Invoke(new object[]{name, semantic,
rowCount, colCount, elemCount, paramClass, paramType,
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,
int rowCount, int colCount, EffectParameterClass paramClass,
EffectParameterType paramType, IntPtr data)
......
......@@ -123,7 +123,10 @@ class TestGame : Game {
base.UnloadContent();
}
TimeSpan totalTime = TimeSpan.Zero;
protected override void Update(GameTime gt) {
totalTime += gt.ElapsedGameTime;
ks = Keyboard.GetState();
base.Update(gt);
......@@ -150,6 +153,14 @@ class TestGame : Game {
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()) {
GraphicsDevice.DrawUserPrimitives<VertexType>(
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