Commit fdea97de authored by pcy's avatar pcy
Browse files

IT WORKS! (to some degree)

parent bb441b3e
...@@ -49,6 +49,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -49,6 +49,7 @@ namespace PoroCYon.FNAGLSL {
IDictionary<GLSLPurpose, string> shaders) IDictionary<GLSLPurpose, string> shaders)
: base(/*UGLY hack*/new BasicEffect(gd)) { : base(/*UGLY hack*/new BasicEffect(gd)) {
GL.Init(gd); GL.Init(gd);
GL.GetError(); // ignore errors from FNA/mojoshader
// this basically makes FNA think this effect is a noop, so binding // this basically makes FNA think this effect is a noop, so binding
// 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,
...@@ -129,7 +130,9 @@ namespace PoroCYon.FNAGLSL { ...@@ -129,7 +130,9 @@ namespace PoroCYon.FNAGLSL {
///<summary> ///<summary>
///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... } ///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... }
///</summary> ///</summary>
public ActiveEffect Bind() { public ActiveEffect Bind() { // TODO: how to warn on discarding the retval?
GL.GetError(); // ignore errors from FNA/mojoshader
uint oldprgm = unchecked((uint)GL.GetIntegerv(GL.CURRENT_PROGRAM)); uint oldprgm = unchecked((uint)GL.GetIntegerv(GL.CURRENT_PROGRAM));
GL.Throw(); GL.Throw();
...@@ -144,9 +147,10 @@ namespace PoroCYon.FNAGLSL { ...@@ -144,9 +147,10 @@ namespace PoroCYon.FNAGLSL {
public ActiveEffect Apply() { return Bind(); } public ActiveEffect Apply() { return Bind(); }
void DelShdrPrgm() { void DelShdrPrgm() {
for (int i = 0; i < glshdrs.Length; ++i) for (int i = 0; glshdrs != null && i < glshdrs.Length; ++i)
if (glshdrs[i] != 0) if (glshdrs[i] != 0)
GL.DeleteShader(glshdrs[i]); GL.DeleteShader(glshdrs[i]);
glshdrs = null;
if (glprgm != 0) if (glprgm != 0)
GL.DeleteProgram(glprgm); GL.DeleteProgram(glprgm);
......
...@@ -14,7 +14,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -14,7 +14,7 @@ namespace PoroCYon.FNAGLSL {
public static void Throw() { public static void Throw() {
GLError err = GetError(); GLError err = GetError();
if (err != GLError.NoError) throw new GLException(GetError()); if (err != GLError.NoError) throw new GLException(err);
} }
internal static void CheckFNA() { internal static void CheckFNA() {
......
...@@ -28,21 +28,21 @@ namespace PoroCYon.FNAGLSL { ...@@ -28,21 +28,21 @@ namespace PoroCYon.FNAGLSL {
CURRENT_PROGRAM = 0x8B8D; CURRENT_PROGRAM = 0x8B8D;
static void InitProcs() { static void InitProcs() {
_GetError = GetProcAddress<Func<GLenum>>("GetError"); _GetError = GetProcAddress<GetError_T>("GetError");
_CreateProgram = GetProcAddress<Func<GLuint>>("CreateProgram"); _CreateProgram = GetProcAddress<CreateProgram_T>("CreateProgram");
_CreateShader = GetProcAddress<Func<GLenum, GLuint>>("CreateShader"); _CreateShader = GetProcAddress<CreateShader_T>("CreateShader");
_ShaderSource = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("ShaderSource"); _ShaderSource = GetProcAddress<ShaderSource_T>("ShaderSource");
_CompileShader = GetProcAddress<Action<GLuint>>("CompileShader"); _CompileShader = GetProcAddress<CompileShader_T>("CompileShader");
_GetShaderiv = GetProcAddress<Action<GLuint, GLenum, IntPtr>>("GetShaderiv"); _GetShaderiv = GetProcAddress<GetShaderiv_T>("GetShaderiv");
_GetShaderInfoLog = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("GetShaderInfoLog"); _GetShaderInfoLog = GetProcAddress<GetShaderInfoLog_T>("GetShaderInfoLog");
_AttachShader = GetProcAddress<Action<GLuint, GLuint>>("AttachShader"); _AttachShader = GetProcAddress<AttachShader_T>("AttachShader");
_LinkProgram = GetProcAddress<Action<GLuint>>("LinkProgram"); _LinkProgram = GetProcAddress<LinkProgram_T>("LinkProgram");
_GetProgramiv = GetProcAddress<Action<GLuint, GLenum, IntPtr>>("GetProgramiv"); _GetProgramiv = GetProcAddress<GetProgramiv_T>("GetProgramiv");
_GetProgramInfoLog = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("GetProgramInfoLog"); _GetProgramInfoLog = GetProcAddress<GetProgramInfoLog_T>("GetProgramInfoLog");
_DeleteShader = GetProcAddress<Action<GLuint>>("DeleteShader"); _DeleteShader = GetProcAddress<DeleteShader_T>("DeleteShader");
_DeleteProgram = GetProcAddress<Action<GLuint>>("DeleteProgram"); _DeleteProgram = GetProcAddress<DeleteProgram_T>("DeleteProgram");
_UseProgram = GetProcAddress<Action<GLuint>>("UseProgram"); _UseProgram = GetProcAddress<UseProgram_T>("UseProgram");
_GetIntegerv = GetProcAddress<Action<GLenum, IntPtr>>("GetIntegerv"); _GetIntegerv = GetProcAddress<GetIntegerv_T>("GetIntegerv");
} }
static void DeinitProcs() { static void DeinitProcs() {
_GetError = null; _GetError = null;
...@@ -62,76 +62,94 @@ namespace PoroCYon.FNAGLSL { ...@@ -62,76 +62,94 @@ namespace PoroCYon.FNAGLSL {
_GetIntegerv = null; _GetIntegerv = null;
} }
static Func<GLenum> _GetError; delegate GLenum GetError_T();
static GetError_T _GetError;
public static GLError GetError() => (GLError)_GetError(); public static GLError GetError() => (GLError)_GetError();
static Func<GLuint> _CreateProgram; delegate GLuint CreateProgram_T();
static CreateProgram_T _CreateProgram;
public static GLuint CreateProgram() => _CreateProgram(); public static GLuint CreateProgram() => _CreateProgram();
static Func<GLenum, GLuint> _CreateShader; delegate GLuint CreateShader_T(GLenum shtyp);
static CreateShader_T _CreateShader;
public static GLuint CreateShader(GLSLPurpose shtyp) public static GLuint CreateShader(GLSLPurpose shtyp)
=> _CreateShader((GLenum)shtyp); => _CreateShader((GLenum)shtyp);
static Action<GLuint, GLsizei, IntPtr, IntPtr> _ShaderSource; delegate void ShaderSource_T(GLuint sh, GLsizei count,
GLchar** str, GLint* len);
static ShaderSource_T _ShaderSource;
public static void ShaderSource(GLuint sh, GLsizei count, public static void ShaderSource(GLuint sh, GLsizei count,
GLchar** str, GLint* len) { GLchar** str, GLint* len) {
_ShaderSource(sh, count, (IntPtr)str, (IntPtr)len); _ShaderSource(sh, count, str, len);
} }
static Action<GLuint> _CompileShader; delegate void CompileShader_T(GLuint sh);
static CompileShader_T _CompileShader;
public static void CompileShader(GLuint sh) { _CompileShader(sh); } public static void CompileShader(GLuint sh) { _CompileShader(sh); }
static Action<GLuint, GLenum, IntPtr> _GetShaderiv; delegate void GetShaderiv_T(GLuint sh, GLenum pname, GLint* parm);
static GetShaderiv_T _GetShaderiv;
public static GLint GetShaderiv(GLuint sh, GLenum pname) { public static GLint GetShaderiv(GLuint sh, GLenum pname) {
GLint* parm = stackalloc GLint[1]; GLint* parm = stackalloc GLint[1];
*parm = 0; *parm = 0;
_GetShaderiv(sh, pname, (IntPtr)parm); _GetShaderiv(sh, pname, parm);
return *parm; return *parm;
} }
static Action<GLuint, GLsizei, IntPtr, IntPtr> _GetShaderInfoLog; delegate void GetShaderInfoLog_T(GLuint sh, GLsizei maxl, GLsizei* len,
GLchar* infolog);
static GetShaderInfoLog_T _GetShaderInfoLog;
public static void GetShaderInfoLog(GLuint sh, GLsizei maxl, public static void GetShaderInfoLog(GLuint sh, GLsizei maxl,
GLsizei* len, GLchar* infolog) { GLsizei* len, GLchar* infolog) {
_GetShaderInfoLog(sh, maxl, (IntPtr)len, (IntPtr)infolog); _GetShaderInfoLog(sh, maxl, len, infolog);
} }
static Action<GLuint, GLuint> _AttachShader; delegate void AttachShader_T(GLuint pr, GLuint sh);
static AttachShader_T _AttachShader;
public static void AttachShader(GLuint prgm, GLuint sh) { public static void AttachShader(GLuint prgm, GLuint sh) {
_AttachShader(prgm, sh); _AttachShader(prgm, sh);
} }
static Action<GLuint> _LinkProgram; delegate void LinkProgram_T(GLuint pr);
static LinkProgram_T _LinkProgram;
public static void LinkProgram(GLuint prgm) { _LinkProgram(prgm); } public static void LinkProgram(GLuint prgm) { _LinkProgram(prgm); }
static Action<GLuint, GLenum, IntPtr> _GetProgramiv; delegate void GetProgramiv_T(GLuint pr, GLuint pnam, GLint* parm);
static GetProgramiv_T _GetProgramiv;
// FIXME: won't work with GL_COMPUTE_WORK_GROUP_SIZE // FIXME: won't work with GL_COMPUTE_WORK_GROUP_SIZE
public static GLint GetProgramiv(GLuint prgm, GLenum pname) { public static GLint GetProgramiv(GLuint prgm, GLenum pname) {
GLint* parm = stackalloc GLint[3]; GLint* parm = stackalloc GLint[3];
parm[2] = parm[1] = parm[0] = 0; parm[2] = parm[1] = parm[0] = 0;
_GetProgramiv(prgm, pname, (IntPtr)parm); _GetProgramiv(prgm, pname, parm);
return parm[0]; return parm[0];
} }
static Action<GLuint, GLsizei, IntPtr, IntPtr> _GetProgramInfoLog; delegate void GetProgramInfoLog_T(GLuint pr, GLsizei maxl,
GLsizei* len, GLchar* infolog);
static GetProgramInfoLog_T _GetProgramInfoLog;
public static void GetProgramInfoLog(GLuint prgm, GLsizei maxl, public static void GetProgramInfoLog(GLuint prgm, GLsizei maxl,
GLsizei* len, GLchar* infolog) { GLsizei* len, GLchar* infolog) {
_GetProgramInfoLog(prgm, maxl, (IntPtr)len, (IntPtr)infolog); _GetProgramInfoLog(prgm, maxl, len, infolog);
} }
static Action<GLuint> _DeleteShader; delegate void DeleteShader_T(GLuint sh);
static DeleteShader_T _DeleteShader;
public static void DeleteShader(GLuint sh) { _DeleteShader(sh); } public static void DeleteShader(GLuint sh) { _DeleteShader(sh); }
static Action<GLuint> _DeleteProgram; delegate void DeleteProgram_T(GLuint pr);
static DeleteProgram_T _DeleteProgram;
public static void DeleteProgram(GLuint prgm) { _DeleteProgram(prgm); } public static void DeleteProgram(GLuint prgm) { _DeleteProgram(prgm); }
static Action<GLuint> _UseProgram; delegate void UseProgram_T(GLuint pr);
static UseProgram_T _UseProgram;
public static void UseProgram(GLuint prgm) { _UseProgram(prgm); } public static void UseProgram(GLuint prgm) { _UseProgram(prgm); }
static Action<GLenum, IntPtr> _GetIntegerv; delegate void GetIntegerv_T(GLenum n, GLint* parm);
static GetIntegerv_T _GetIntegerv;
public static GLint GetIntegerv(GLenum name) { public static GLint GetIntegerv(GLenum name) {
GLint* parm = stackalloc GLint[4]; GLint* parm = stackalloc GLint[4]; // let's hope 4 is good enough
parm[3] = parm[2] = parm[1] = parm[0] = 0; parm[3] = parm[2] = parm[1] = parm[0] = 0;
_GetIntegerv(name, (IntPtr)parm); _GetIntegerv(name, parm);
return parm[0]; return parm[0];
} }
} }
......
...@@ -5,6 +5,7 @@ using System.Runtime.InteropServices; ...@@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using PoroCYon.FNAGLSL;
//using VertexType = Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture; //using VertexType = Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture;
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
...@@ -33,6 +34,7 @@ class TestGame : Game { ...@@ -33,6 +34,7 @@ class TestGame : Game {
SpriteBatch sb; SpriteBatch sb;
KeyboardState ks; KeyboardState ks;
BasicEffect hlsl; BasicEffect hlsl;
GLSLEffect glsl;
readonly VertexType[] vertices = new[] { 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.Red , new Vector2(0, 0))
...@@ -65,6 +67,46 @@ class TestGame : Game { ...@@ -65,6 +67,46 @@ class TestGame : Game {
hlsl.World = hlsl.View = hlsl.Projection = Matrix.Identity; hlsl.World = hlsl.View = hlsl.Projection = Matrix.Identity;
glsl = new GLSLEffect(GraphicsDevice, new Dictionary<GLSLPurpose, string>() {
{ GLSLPurpose.VertexShader ,
"#version 430 core\n"+
"in vec3 in_pos;\n"+
"in vec4 in_col;\n"+
"in vec2 in_texcoord;\n"+
"out vec2 out_texcoord;\n"+
"void main() {\n"+
" gl_Position = vec4(in_pos.x, in_pos.y, in_pos.z, 1.0);\n"+
" out_texcoord = in_texcoord;\n"+
"}\n"
/*"#version 430 core\n"+
"vec2 y = vec2(1., -1.);\n"+
"vec4 x[4] = {y.yyxx, y.xyxx, y.yxxx, y.xxxx};\n"+
"void main() {\n"+
" gl_Position = x[gl_VertexID];\n"+
"}\n"*/
},
{ GLSLPurpose.FragmentShader,
"#version 430 core\n"+
"layout(location = 0) out vec4 C;\n"+
"vec4 plas(vec2 v) {\n"+
" float c = 0.5 + sin(v.x * 10.0) + cos(sin(v.y) * 20.0);\n"+
" return vec4(sin(c * 0.2 + 1), c * 0.15, cos(c * 0.1) * .25, 1.0);\n"+
"}\n"+
"void main() {\n"+
" float pi = 4*atan(1);\n"+
" vec2 uv = vec2(gl_FragCoord.x/1920.0, gl_FragCoord.y/1080);\n"+
" uv -= 0.5;\n"+
" uv /= vec2(float(1920)/1080.0, 1.);\n"+
" vec2 m;\n"+
" m.x = atan(uv.x / uv.y) / pi;\n"+
" m.y = 1 / length(uv) * .2;\n"+
" float d = m.y;\n"+
" vec4 t = plas(m * pi) / d;\n"+
" C = clamp(t, 0.0, 1.0);\n"+
" /*gl_FragColor = vec4(0);*/\n"+
"}\n"}
});
base.LoadContent(); base.LoadContent();
} }
...@@ -96,10 +138,12 @@ class TestGame : Game { ...@@ -96,10 +138,12 @@ class TestGame : Game {
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, 0, 2, VertexType.Format);
} }
} }
}
} }
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