Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
pcy
fnaglsl
Commits
bb441b3e
Commit
bb441b3e
authored
Jun 08, 2020
by
pcy
Browse files
make it compile again, also half-assed Bind()/Apply() impl. which probably doesn't work yet
parent
865206e0
Changes
5
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
bb441b3e
...
...
@@ -13,14 +13,14 @@ TARGET := bin/fnaglsl.exe
LIBS
:=
lib/FNA.dll lib/FNA.dll.config lib/libmojoshader.so
$(TARGET)
:
bin/ $(SOURCES) $(LIBS)
$(TARGET)
:
bin/ $(SOURCES)
#
$(LIBS)
$(CSC)
$(CSFLAGS)
-target
:exe
-out
:
"
$@
"
$(SOURCES)
all
:
$(TARGET)
$(LIBS)
:
lib/
@
>
&2
echo
"You need to put FNA.dll{,.config} and libmojoshader.so in the"
\
"
'
lib/' directory."
;
false
"
\`
lib/' directory."
;
false
debug
:
CSFLAGS += -debug+
debug
:
all
...
...
src/GLSLEffect.cs
View file @
bb441b3e
...
...
@@ -15,13 +15,33 @@ using Microsoft.Xna.Framework.Graphics;
* -> glEffect{Begin,End}Pass: bind shader! | state mgmt
* * GD draw calls: ok
* * EXCEPT mojoshader: glProgramReady, glProgramViewportInfo
* -> set up uniforms!
* -> set up uniforms and vertex arrays!
* --> circumvent? --> HOW??
* --> just go with it?? --> glProgramReady ok, glProgramViewportInfo might segfault!
* * uniforms
* * samplers, textures
*/
namespace
PoroCYon.FNAGLSL
{
public
class
GLSLEffect
:
Effect
{
public
struct
ActiveEffect
:
IDisposable
{
internal
uint
oldprgm
;
bool
disposed
;
internal
ActiveEffect
(
uint
old
)
{
oldprgm
=
old
;
disposed
=
false
;
}
public
void
Dispose
()
{
if
(
disposed
)
return
;
GL
.
UseProgram
(
oldprgm
);
oldprgm
=
0
;
disposed
=
true
;
}
}
uint
[]
glshdrs
;
uint
glprgm
;
...
...
@@ -30,8 +50,18 @@ namespace PoroCYon.FNAGLSL {
:
base
(
/*UGLY hack*/
new
BasicEffect
(
gd
))
{
GL
.
Init
(
gd
);
// TODO: gd.GLDevice.DeleteEffect(base.glEffect),
// set base.glEffect.{GL,}EffectData to IntPtr.Zero
// 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,
// so the BasicEffect used won't do much anymore
/*gd.DeleteEffect(this);
eff.SetGLEffectData(IntPtr.Zero);
eff.SetEffectData (IntPtr.Zero);*/
// turns out we can't do this, or libmojoshader will segfault
// because it lacks some null checking in
// glEffectEnd, glEffectBeginPass, glProgramViewportInfo :/ ...
// so we basically have to make sure the usual route of Apply()ing
// the shader happens (unless we can circumvent this *somehow*),
// and then apply the shader manually.
var
shdrs
=
new
uint
[
shaders
.
Count
];
bool
ok
=
false
;
...
...
@@ -95,13 +125,31 @@ namespace PoroCYon.FNAGLSL {
}
}
// TODO: find out a better (i.e. more API-conform) way to do this!
///<summary>
///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... }
///</summary>
public
ActiveEffect
Bind
()
{
uint
oldprgm
=
unchecked
((
uint
)
GL
.
GetIntegerv
(
GL
.
CURRENT_PROGRAM
));
GL
.
Throw
();
GL
.
UseProgram
(
glprgm
);
GL
.
Throw
();
// TODO: apply uniforms and samplers! (XNA API -> OpenGL state)
return
new
ActiveEffect
(
oldprgm
);
}
[
Obsolete
(
"Please use Bind() instead"
)]
public
ActiveEffect
Apply
()
{
return
Bind
();
}
void
DelShdrPrgm
()
{
for
(
int
i
=
0
;
i
<
glshdrs
.
Length
;
++
i
)
if
(
shdrs
[
i
]
!=
0
)
GL
.
DeleteShader
(
shdrs
[
i
]);
if
(
gl
shdrs
[
i
]
!=
0
)
GL
.
DeleteShader
(
gl
shdrs
[
i
]);
if
(
prgm
!=
0
)
GL
.
DeleteProgram
(
prgm
);
if
(
gl
prgm
!=
0
)
GL
.
DeleteProgram
(
gl
prgm
);
}
protected
override
void
Dispose
(
bool
disposing
)
{
...
...
src/GLUtil.cs
View file @
bb441b3e
...
...
@@ -43,11 +43,10 @@ namespace PoroCYon.FNAGLSL {
CheckFNA
();
if
(
inited
)
return
;
var
gldev
=
gd
.
GetType
().
GetField
(
"GLDevice"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
).
GetValue
(
gd
);
if
(
gldev
.
GetType
().
Name
.
EndsWith
(
"MetalDevice"
))
throw
new
NotSupportedException
(
"Metal isn't supported, need OpenGL!"
);
var
nam
=
gd
.
GLDevice
().
GetType
().
Name
;
if
(!
nam
.
Contains
(
"GLDevice"
))
throw
new
NotSupportedException
(
"need OpenGL, but FNA is using"
+
" the "
+
nam
+
" backend!"
);
InitProcs
();
...
...
src/GLUtil_GL.cs
View file @
bb441b3e
...
...
@@ -24,7 +24,8 @@ namespace PoroCYon.FNAGLSL {
public
const
GLenum
COMPILE_STATUS
=
0x8B81
,
INFO_LOG_LENGTH
=
0x8B84
,
LINK_STATUS
=
0x8B82
;
LINK_STATUS
=
0x8B82
,
CURRENT_PROGRAM
=
0x8B8D
;
static
void
InitProcs
()
{
_GetError
=
GetProcAddress
<
Func
<
GLenum
>>(
"GetError"
);
...
...
@@ -40,6 +41,8 @@ namespace PoroCYon.FNAGLSL {
_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"
);
}
static
void
DeinitProcs
()
{
_GetError
=
null
;
...
...
@@ -55,6 +58,8 @@ namespace PoroCYon.FNAGLSL {
_GetProgramInfoLog
=
null
;
_DeleteShader
=
null
;
_DeleteProgram
=
null
;
_UseProgram
=
null
;
_GetIntegerv
=
null
;
}
static
Func
<
GLenum
>
_GetError
;
...
...
@@ -118,6 +123,17 @@ namespace PoroCYon.FNAGLSL {
static
Action
<
GLuint
>
_DeleteProgram
;
public
static
void
DeleteProgram
(
GLuint
prgm
)
{
_DeleteProgram
(
prgm
);
}
static
Action
<
GLuint
>
_UseProgram
;
public
static
void
UseProgram
(
GLuint
prgm
)
{
_UseProgram
(
prgm
);
}
static
Action
<
GLenum
,
IntPtr
>
_GetIntegerv
;
public
static
GLint
GetIntegerv
(
GLenum
name
)
{
GLint
*
parm
=
stackalloc
GLint
[
4
];
parm
[
3
]
=
parm
[
2
]
=
parm
[
1
]
=
parm
[
0
]
=
0
;
_GetIntegerv
(
name
,
(
IntPtr
)
parm
);
return
parm
[
0
];
}
}
}
src/ReflUtil.cs
0 → 100644
View file @
bb441b3e
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Reflection
;
using
System.Runtime.InteropServices
;
using
Microsoft.Xna.Framework
;
using
Microsoft.Xna.Framework.Graphics
;
namespace
PoroCYon.FNAGLSL
{
public
static
class
ReflUtil
{
readonly
static
FieldInfo
gd_GLDevice_fi
=
typeof
(
GraphicsDevice
).
GetField
(
"GLDevice"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
readonly
static
FieldInfo
ef_glEffect_fi
=
typeof
(
Effect
).
GetField
(
"glEffect"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
static
MethodInfo
gldev_DeleteEffect_mi
;
static
PropertyInfo
ef_GLEffectData_pi
,
ef_EffectData_pi
;
public
static
object
GLDevice
(
this
GraphicsDevice
gd
)
=>
gd_GLDevice_fi
.
GetValue
(
gd
);
public
static
object
glEffect
(
this
Effect
eff
)
=>
ef_glEffect_fi
.
GetValue
(
eff
);
static
object
[]
arg1
=
new
object
[
1
];
public
static
void
DeleteEffect
(
this
GraphicsDevice
gd
,
Effect
eff
)
{
var
gldev
=
gd
.
GLDevice
();
if
(
gldev_DeleteEffect_mi
==
null
)
{
// type of the gldev not known at compile-time!
gldev_DeleteEffect_mi
=
gldev
.
GetType
().
GetMethod
(
"DeleteEffect"
,
BindingFlags
.
InvokeMethod
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
}
arg1
[
0
]
=
eff
.
glEffect
();
gldev_DeleteEffect_mi
.
Invoke
(
gldev
,
arg1
);
}
public
static
IntPtr
GetGLEffectData
(
this
Effect
eff
)
{
var
gleff
=
eff
.
glEffect
();
if
(
ef_GLEffectData_pi
==
null
)
{
// type of the gleff not known at compile-time!
ef_GLEffectData_pi
=
gleff
.
GetType
().
GetProperty
(
"GLEffectData"
,
BindingFlags
.
SetProperty
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
}
return
(
IntPtr
)
ef_GLEffectData_pi
.
GetValue
(
gleff
);
}
public
static
void
SetGLEffectData
(
this
Effect
eff
,
IntPtr
value
)
{
var
gleff
=
eff
.
glEffect
();
if
(
ef_GLEffectData_pi
==
null
)
{
// type of the gleff not known at compile-time!
ef_GLEffectData_pi
=
gleff
.
GetType
().
GetProperty
(
"GLEffectData"
,
BindingFlags
.
SetProperty
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
}
ef_GLEffectData_pi
.
SetValue
(
gleff
,
value
);
}
public
static
IntPtr
GetEffectData
(
this
Effect
eff
)
{
var
gleff
=
eff
.
glEffect
();
if
(
ef_EffectData_pi
==
null
)
{
// type of the gleff not known at compile-time!
ef_EffectData_pi
=
gleff
.
GetType
().
GetProperty
(
"EffectData"
,
BindingFlags
.
SetProperty
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
}
return
(
IntPtr
)
ef_EffectData_pi
.
GetValue
(
gleff
);
}
public
static
void
SetEffectData
(
this
Effect
eff
,
IntPtr
value
)
{
var
gleff
=
eff
.
glEffect
();
if
(
ef_EffectData_pi
==
null
)
{
// type of the gleff not known at compile-time!
ef_EffectData_pi
=
gleff
.
GetType
().
GetProperty
(
"EffectData"
,
BindingFlags
.
SetProperty
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
}
ef_EffectData_pi
.
SetValue
(
gleff
,
value
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment