Commit fdea97de authored by pcy's avatar pcy
Browse files

IT WORKS! (to some degree)

parent bb441b3e
......@@ -49,6 +49,7 @@ namespace PoroCYon.FNAGLSL {
IDictionary<GLSLPurpose, string> shaders)
: base(/*UGLY hack*/new BasicEffect(gd)) {
GL.Init(gd);
GL.GetError(); // ignore errors from FNA/mojoshader
// 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,
......@@ -129,7 +130,9 @@ namespace PoroCYon.FNAGLSL {
///<summary>
///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... }
///</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));
GL.Throw();
......@@ -144,9 +147,10 @@ namespace PoroCYon.FNAGLSL {
public ActiveEffect Apply() { return Bind(); }
void DelShdrPrgm() {
for (int i = 0; i < glshdrs.Length; ++i)
for (int i = 0; glshdrs != null && i < glshdrs.Length; ++i)
if (glshdrs[i] != 0)
GL.DeleteShader(glshdrs[i]);
glshdrs = null;
if (glprgm != 0)
GL.DeleteProgram(glprgm);
......
......@@ -14,7 +14,7 @@ namespace PoroCYon.FNAGLSL {
public static void Throw() {
GLError err = GetError();
if (err != GLError.NoError) throw new GLException(GetError());
if (err != GLError.NoError) throw new GLException(err);
}
internal static void CheckFNA() {
......
......@@ -28,21 +28,21 @@ namespace PoroCYon.FNAGLSL {
CURRENT_PROGRAM = 0x8B8D;
static void InitProcs() {
_GetError = GetProcAddress<Func<GLenum>>("GetError");
_CreateProgram = GetProcAddress<Func<GLuint>>("CreateProgram");
_CreateShader = GetProcAddress<Func<GLenum, GLuint>>("CreateShader");
_ShaderSource = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("ShaderSource");
_CompileShader = GetProcAddress<Action<GLuint>>("CompileShader");
_GetShaderiv = GetProcAddress<Action<GLuint, GLenum, IntPtr>>("GetShaderiv");
_GetShaderInfoLog = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("GetShaderInfoLog");
_AttachShader = GetProcAddress<Action<GLuint, GLuint>>("AttachShader");
_LinkProgram = GetProcAddress<Action<GLuint>>("LinkProgram");
_GetProgramiv = GetProcAddress<Action<GLuint, GLenum, IntPtr>>("GetProgramiv");
_GetProgramInfoLog = GetProcAddress<Action<GLuint, GLsizei, IntPtr, IntPtr>>("GetProgramInfoLog");
_DeleteShader = GetProcAddress<Action<GLuint>>("DeleteShader");
_DeleteProgram = GetProcAddress<Action<GLuint>>("DeleteProgram");
_UseProgram = GetProcAddress<Action<GLuint>>("UseProgram");
_GetIntegerv = GetProcAddress<Action<GLenum, IntPtr>>("GetIntegerv");
_GetError = GetProcAddress<GetError_T>("GetError");
_CreateProgram = GetProcAddress<CreateProgram_T>("CreateProgram");
_CreateShader = GetProcAddress<CreateShader_T>("CreateShader");
_ShaderSource = GetProcAddress<ShaderSource_T>("ShaderSource");
_CompileShader = GetProcAddress<CompileShader_T>("CompileShader");
_GetShaderiv = GetProcAddress<GetShaderiv_T>("GetShaderiv");
_GetShaderInfoLog = GetProcAddress<GetShaderInfoLog_T>("GetShaderInfoLog");
_AttachShader = GetProcAddress<AttachShader_T>("AttachShader");
_LinkProgram = GetProcAddress<LinkProgram_T>("LinkProgram");
_GetProgramiv = GetProcAddress<GetProgramiv_T>("GetProgramiv");
_GetProgramInfoLog = GetProcAddress<GetProgramInfoLog_T>("GetProgramInfoLog");
_DeleteShader = GetProcAddress<DeleteShader_T>("DeleteShader");
_DeleteProgram = GetProcAddress<DeleteProgram_T>("DeleteProgram");
_UseProgram = GetProcAddress<UseProgram_T>("UseProgram");
_GetIntegerv = GetProcAddress<GetIntegerv_T>("GetIntegerv");
}
static void DeinitProcs() {
_GetError = null;
......@@ -62,76 +62,94 @@ namespace PoroCYon.FNAGLSL {
_GetIntegerv = null;
}
static Func<GLenum> _GetError;
delegate GLenum GetError_T();
static GetError_T _GetError;
public static GLError GetError() => (GLError)_GetError();
static Func<GLuint> _CreateProgram;
delegate GLuint CreateProgram_T();
static CreateProgram_T _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)
=> _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,
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); }
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) {
GLint* parm = stackalloc GLint[1];
*parm = 0;
_GetShaderiv(sh, pname, (IntPtr)parm);
_GetShaderiv(sh, pname, 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,
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) {
_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); }
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
public static GLint GetProgramiv(GLuint prgm, GLenum pname) {
GLint* parm = stackalloc GLint[3];
parm[2] = parm[1] = parm[0] = 0;
_GetProgramiv(prgm, pname, (IntPtr)parm);
_GetProgramiv(prgm, pname, parm);
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,
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); }
static Action<GLuint> _DeleteProgram;
delegate void DeleteProgram_T(GLuint pr);
static DeleteProgram_T _DeleteProgram;
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); }
static Action<GLenum, IntPtr> _GetIntegerv;
delegate void GetIntegerv_T(GLenum n, GLint* parm);
static GetIntegerv_T _GetIntegerv;
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;
_GetIntegerv(name, (IntPtr)parm);
_GetIntegerv(name, parm);
return parm[0];
}
}
......
......@@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using PoroCYon.FNAGLSL;
//using VertexType = Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture;
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
......@@ -33,6 +34,7 @@ class TestGame : Game {
SpriteBatch sb;
KeyboardState ks;
BasicEffect hlsl;
GLSLEffect glsl;
readonly VertexType[] vertices = new[] {
new VertexType(new Vector3(-1, -1, 0), Color.Red , new Vector2(0, 0))
......@@ -65,6 +67,46 @@ class TestGame : Game {
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();
}
......@@ -96,8 +138,10 @@ class TestGame : Game {
for (int i = 0; i < tech.Passes.Count; ++i) {
//Console.WriteLine(String.Format("p{0}: {1}", i, tech.Passes[i].Name));
tech.Passes[i].Apply();
GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices, 0, 2, VertexType.Format);
using (var act = glsl.Bind()) {
GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices, 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