Skip to content
GitLab
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
e7478816
Commit
e7478816
authored
Jun 19, 2020
by
pcy
Browse files
prepare stuff for texture support
parent
0ff4087d
Changes
5
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
e7478816
...
...
@@ -6,19 +6,18 @@ the `Effect` API as much as possible. (Which isn't always working.)
## Does it work?
Kinda. Static shaders work. Passing vertex data is very hacky and brittle.
Uniforms, samples/textures, ... don't work at all yet. Using regular shaders
interleaved w/ GLSL shader draw calls seems to work ok.
Uniforms seem to work, but aren't well-tested. Samples/textures, ... don't
work at all yet. Using regular shaders interleaved w/ GLSL shader draw calls
seems to work ok.
## How does this work?
No. Don't.
No. Don't.
Here be dragons.
## Are there things it can't do?
Yes:
*
No uniform support (this is being worked on! FNA/mojoshader internals might
throw a wrench tho)
*
No texture support (will have to be researched)
*
Passing this to a
`SpriteBatch`
will probably fail in a bad way (unlikely
to be fixed).
...
...
@@ -34,6 +33,8 @@ var glsl = new GLSLEffect(GraphicsDevice, new Dictionary<GLSLPurpose, string>()
// ...
glsl
.
Parameters
[
"paramname"
].
SetValueT
(
xyz
);
using
(
var
bound
=
glsl
.
Bind
())
{
GraphicsDevice
.
DrawPrimitives
(
/*...*/
);
...
...
src/GLSLEffect.cs
View file @
e7478816
...
...
@@ -20,7 +20,6 @@ using Microsoft.Xna.Framework.Graphics;
* --> circumvent? --> HOW??
* --> just go with it?? --> glProgramReady ok, glProgramViewportInfo might segfault!
*
* * uniforms
* * samplers, textures
* -> https://www.khronos.org/opengl/wiki/Program_Introspection
* -> https://stackoverflow.com/questions/440144/in-opengl-is-there-a-way-to-get-a-list-of-all-uniforms-attribs-used-by-a-shade#442819
...
...
@@ -48,10 +47,11 @@ namespace PoroCYon.FNAGLSL {
public
partial
class
GLSLEffect
:
Effect
{
public
struct
ActiveEffect
:
IDisposable
{
internal
uint
oldprgm
;
internal
List
<
uint
>
texs
;
bool
disposed
;
internal
ActiveEffect
(
uint
old
)
{
oldprgm
=
old
;
disposed
=
false
;
internal
ActiveEffect
(
uint
old
,
List
<
uint
>
ts
)
{
oldprgm
=
old
;
disposed
=
false
;
texs
=
ts
;
}
public
void
Dispose
()
{
...
...
@@ -60,6 +60,12 @@ namespace PoroCYon.FNAGLSL {
GL
.
UseProgram
(
oldprgm
);
oldprgm
=
0
;
// TODO: release textures
/*for (int i = 0; i < texs.Length; ++i) {
}*/
texs
.
Clear
();
disposed
=
true
;
}
}
...
...
@@ -153,10 +159,10 @@ namespace PoroCYon.FNAGLSL {
}
}
readonly
static
EffectParameterCollection
emptyParamColl
/*
readonly static EffectParameterCollection emptyParamColl
= ReflUtil.CreateParamColl(new List<EffectParameter >());
readonly static EffectAnnotationCollection emptyAnnotColl
=
ReflUtil
.
CreateAnnotColl
(
new
List
<
EffectAnnotation
>());
= ReflUtil.CreateAnnotColl(new List<EffectAnnotation>());
*/
void
ParseAttribUnif
()
{
/*int attrs = GL.GetProgramiv(glprgm, GL.ACTIVE_ATTRIBUTES);
GL.Throw();
...
...
@@ -194,6 +200,7 @@ namespace PoroCYon.FNAGLSL {
}
IntPtr
bleh
=
Marshal
.
AllocHGlobal
((
IntPtr
)
totalsize
);
ILUtil
.
Initblk
(
bleh
,
0
,
(
IntPtr
)
totalsize
);
bool
ok
=
false
;
try
{
...
...
@@ -221,18 +228,31 @@ namespace PoroCYon.FNAGLSL {
}
}
List
<
uint
>
usedTextures
=
new
List
<
uint
>();
void
ApplyUnifs
()
{
// TODO
usedTextures
.
Clear
();
// TODO: get active texture to restore later -> glGetIntegerv(GL_ACTIVE_TEXTURE)
// TODO: make list to hold used texture slots
IntPtr
data
=
unifDataBacking
;
for
(
int
i
=
0
;
i
<
unifs
.
Length
;
++
i
)
{
var
u
=
unifs
[
i
];
//var p = Parameters[i];
SetUniform
(
ref
u
,
data
);
var
p
=
Parameters
[
i
];
// TODO:
/*if (it's a texture) {
find empty texture slot, put texture in it
-> GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
-> GL_TEXTURE_BINDING_[123]D / _BINDING_CUBE_MAP
bind uniform to texture slot
add texture slot to the used slot list
}
else*/
SetUniform
(
ref
u
,
data
);
data
=
(
IntPtr
)((
long
)
data
+
u
.
bytesize
);
}
// TODO: restore active texture
}
// TODO: find out a better (i.e. more API-conform) way to do this!
...
...
@@ -254,7 +274,7 @@ namespace PoroCYon.FNAGLSL {
ApplyUnifs
();
return
new
ActiveEffect
(
oldprgm
);
return
new
ActiveEffect
(
oldprgm
,
usedTextures
);
}
[
Obsolete
(
"Please use Bind() instead"
)]
public
ActiveEffect
Apply
()
{
return
Bind
();
}
...
...
src/GLSLEffect_TypTbl.cs
View file @
e7478816
...
...
@@ -47,6 +47,19 @@ namespace PoroCYon.FNAGLSL {
{
FLOAT_MAT3x4
,
sizeof
(
float
)*
4
*
4
},
{
FLOAT_MAT4x2
,
sizeof
(
float
)*
4
*
4
},
{
FLOAT_MAT4x3
,
sizeof
(
float
)*
4
*
4
},
// int-sized bc. not used, but data ptr needs to be nonzero anyway
{
SAMPLER_1D
,
sizeof
(
int
)
},
{
SAMPLER_2D
,
sizeof
(
int
)
},
{
SAMPLER_3D
,
sizeof
(
int
)
},
{
SAMPLER_CUBE
,
sizeof
(
int
)
},
{
INT_SAMPLER_1D
,
sizeof
(
int
)
},
{
INT_SAMPLER_2D
,
sizeof
(
int
)
},
{
INT_SAMPLER_3D
,
sizeof
(
int
)
},
{
INT_SAMPLER_CUBE
,
sizeof
(
int
)
},
{
UNSIGNED_INT_SAMPLER_1D
,
sizeof
(
int
)
},
{
UNSIGNED_INT_SAMPLER_2D
,
sizeof
(
int
)
},
{
UNSIGNED_INT_SAMPLER_3D
,
sizeof
(
int
)
},
{
UNSIGNED_INT_SAMPLER_CUBE
,
sizeof
(
int
)
},
};
typ2class
=
new
Dictionary
<
GLSLType
,
EffectParameterClass
>()
{
{
FLOAT
,
Scalar
},
...
...
src/ReflUtil.cs
View file @
e7478816
...
...
@@ -12,6 +12,10 @@ namespace PoroCYon.FNAGLSL {
"GLDevice"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
readonly
static
FieldInfo
ef_glEffect_fi
=
typeof
(
Effect
).
GetField
(
"glEffect"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
readonly
static
FieldInfo
ep_texture_fi
=
typeof
(
EffectParameter
).
GetField
(
"texture"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
readonly
static
FieldInfo
tx_texture_fi
=
typeof
(
Texture
).
GetField
(
"texture"
,
BindingFlags
.
GetField
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
);
readonly
static
PropertyInfo
ef_Techniques_pi
=
typeof
(
Effect
).
GetProperty
(
"Techniques"
,
BindingFlags
.
SetProperty
|
BindingFlags
.
Public
|
BindingFlags
.
Instance
),
...
...
@@ -22,6 +26,12 @@ namespace PoroCYon.FNAGLSL {
ci_EffTechColl
,
ci_EffParamColl
,
ci_EffAnnotColl
,
ci_EffTech
,
ci_EffParam
,
ci_EffAnnot
;
readonly
static
int
ci_EffParam_plen
;
static
MethodInfo
gldev_DeleteEffect_mi
;
static
PropertyInfo
ef_GLEffectData_pi
,
ef_EffectData_pi
,
gltex_Handle_pi
,
gltex_Target_pi
;
static
ReflUtil
()
{
var
pm1f
=
new
ParameterModifier
(
1
);
pm1f
[
0
]
=
false
;
...
...
@@ -67,6 +77,9 @@ namespace PoroCYon.FNAGLSL {
// fuck it
typeof
(
EffectParameter
).
GetConstructors
(
BindingFlags
.
Instance
|
BindingFlags
.
CreateInstance
|
BindingFlags
.
NonPublic
)[
0
];
// ^ turns out, depending on the FNA version, the dataSize (uint)
// parameter mightn't be included
ci_EffParam_plen
=
ci_EffParam
.
GetParameters
().
Length
;
ci_EffAnnot
=
typeof
(
EffectAnnotation
).
GetConstructor
(
BindingFlags
.
CreateInstance
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Instance
,
...
...
@@ -80,9 +93,6 @@ namespace PoroCYon.FNAGLSL {
throw
new
Exception
(
"can't find ctors"
);
}
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
)
=>
...
...
@@ -170,7 +180,7 @@ namespace PoroCYon.FNAGLSL {
EffectParameterClass
paramClass
,
EffectParameterType
paramType
,
EffectParameterCollection
structMembers
,
EffectAnnotationCollection
annots
,
IntPtr
data
,
uint
dataSize
)
{
int
plen
=
ci_EffParam
.
GetParameters
().
Length
;
int
plen
=
ci_EffParam
_plen
;
if
(
plen
==
11
)
{
return
(
EffectParameter
)
ci_EffParam
.
Invoke
(
new
object
[]{
name
,
semantic
,
rowCount
,
colCount
,
elemCount
,
paramClass
,
paramType
,
...
...
@@ -188,6 +198,32 @@ namespace PoroCYon.FNAGLSL {
EffectParameterType
paramType
,
IntPtr
data
)
=>
(
EffectAnnotation
)
ci_EffAnnot
.
Invoke
(
new
object
[]{
name
,
semantic
,
rowCount
,
colCount
,
paramClass
,
paramType
,
data
});
public
static
Texture
GetValueTexture
(
this
EffectParameter
ep
)
=>
(
Texture
)
ep_texture_fi
.
GetValue
(
ep
);
public
static
uint
GetGLTexID
(
this
Texture
tex
)
{
// gl object id
var
igltex
=
tx_texture_fi
.
GetValue
(
tex
);
if
(
gltex_Handle_pi
==
null
)
{
// IGLTexture type not known at compile-time
gltex_Handle_pi
=
igltex
.
GetType
().
GetProperty
(
"Handle"
,
BindingFlags
.
GetProperty
|
BindingFlags
.
Instance
|
BindingFlags
.
Public
);
}
return
(
uint
)
gltex_Handle_pi
.
GetValue
(
igltex
,
null
);
}
public
static
int
GetGLTexTarget
(
this
Texture
tex
)
{
// GL_TEXTURE_[123]D etc
var
igltex
=
tx_texture_fi
.
GetValue
(
tex
);
if
(
gltex_Target_pi
==
null
)
{
// IGLTexture type not known at compile-time
gltex_Target_pi
=
igltex
.
GetType
().
GetProperty
(
"Target"
,
BindingFlags
.
GetProperty
|
BindingFlags
.
Instance
|
BindingFlags
.
Public
);
}
return
(
int
)
gltex_Target_pi
.
GetValue
(
igltex
,
null
);
}
}
}
src/test.cs
View file @
e7478816
...
...
@@ -176,7 +176,7 @@ class TestGame : Game {
}*/
var
vp
=
GraphicsDevice
.
Viewport
;
glsl
.
Parameters
[
"fGlobalTime"
].
SetValue
((
float
)
totalTime
.
TotalSeconds
);
glsl
.
Parameters
[
"fGlobalTime"
].
SetValue
((
float
)
totalTime
.
TotalSeconds
);
glsl
.
Parameters
[
"v2Resolution"
].
SetValue
(
new
Vector2
(
vp
.
Width
,
vp
.
Height
));
using
(
var
act
=
glsl
.
Bind
())
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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