This commit is contained in:
Yoshman29
2022-11-02 00:26:47 +01:00
parent 0a8ff569b4
commit bf1e581479
5 changed files with 135 additions and 3 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

+1 -1
View File
@@ -1 +1 @@
949
958
+1
View File
@@ -61,6 +61,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
"Conductor" => funkin.system.Conductor,
"CoolUtil" => funkin.system.CoolUtil,
"FunkinShader" => funkin.shaders.FunkinShader,
"CustomShader" => funkin.shaders.CustomShader,
];
}
/**
+123 -2
View File
@@ -1,5 +1,126 @@
package funkin.shaders;
class CustomShader extends FunkinShader {
import haxe.Exception;
import openfl.display.ShaderParameter;
import openfl.display.BitmapData;
import openfl.display.ShaderInput;
import openfl.Assets;
import hscript.IHScriptCustomBehaviour;
/**
* Class for custom shaders.
*
* To create one, create a `shaders` folder in your assets/mod folder, then add a file named `my-shader.frag` or/and `my-shader.vert`.
*
* Non-existent shaders will only load the default one, and throw a warning in the console.
*
* To access the shader's uniform variables, use `shader.variable`
*/
class CustomShader extends FunkinShader implements IHScriptCustomBehaviour {
private static var __instanceFields = Type.getInstanceFields(CustomShader);
/**
* Creates a new custom shader
* @param name Name of the frag and vert files.
* @param glslVersion GLSL version to use. Defaults to `120`.
*/
public function new(name:String, glslVersion:String = "120") {
var fragShaderPath = Paths.fragShader(name);
var vertShaderPath = Paths.vertShader(name);
var fragCode = Assets.exists(fragShaderPath) ? Assets.getText(fragShaderPath) : null;
var vertCode = Assets.exists(vertShaderPath) ? Assets.getText(vertShaderPath) : null;
if (fragCode != null && vertCode != null) {
// TODO: logging!!
}
super(fragCode, vertCode, glslVersion);
}
public function hget(v:String):Dynamic {
if (__instanceFields.contains(v) || __instanceFields.contains('get_${v}')) {
return Reflect.getProperty(this, v);
}
if (!Reflect.hasField(data, v)) return null;
var field = Reflect.field(data, v);
if (field is ShaderInput) {
var si = cast(field, ShaderInput<Dynamic>);
return si.input;
} else if (field is ShaderParameter) {
var sp = cast(field, ShaderParameter<Dynamic>);
switch(sp.type) {
case BOOL, FLOAT, INT:
return sp.value[0];
default:
return sp.value;
}
}
return field;
}
public function hset(v:String, val:Dynamic):Dynamic {
if (__instanceFields.contains(v) || __instanceFields.contains('set_${v}')) {
Reflect.setProperty(this, v, val);
return val;
}
if (!Reflect.hasField(data, v)) {
Reflect.setField(data, v, val);
return val;
} else {
var field = Reflect.field(data, v);
var cl = Std.string(Type.getClass(field));
// cant do "field is ShaderInput" for some reason
if (cl.startsWith("openfl.display.ShaderInput")) {
// shader input!!
if (!(val is BitmapData)) {
throw new ShaderTypeException(v, Type.getClass(val), BitmapData);
return null;
}
field.input = cast val;
} else if (cl.startsWith("openfl.display.ShaderParameter")) {
@:privateAccess
if (field.__arrayLength <= 1) {
// that means we wait for a single number, instead of an array
@:privateAccess
if (field.__isInt && !(val is Int)) {
throw new ShaderTypeException(v, Type.getClass(val), 'Int');
return null;
} else
@:privateAccess
if (field.__isBool && !(val is Bool)) {
throw new ShaderTypeException(v, Type.getClass(val), 'Bool');
return null;
} else
@:privateAccess
if (field.__isFloat && !(val is Float)) {
throw new ShaderTypeException(v, Type.getClass(val), 'Float');
return null;
}
return field.value = [val];
} else {
if (!(val is Array)) {
throw new ShaderTypeException(v, Type.getClass(val), Array);
return null;
}
return field.value = val;
}
}
}
return val;
}
}
class ShaderTypeException extends Exception {
var has:Class<Dynamic>;
var want:Class<Dynamic>;
var name:String;
public function new(name:String, has:Class<Dynamic>, want:Dynamic) {
this.has = has;
this.want = want;
this.name = name;
super('ShaderTypeException - Tried to set the shader uniform "${name}" as a ${Type.getClassName(has)}, but the shader uniform is a ${Std.string(want)}.');
}
}
+10
View File
@@ -60,6 +60,16 @@ class Paths
return getPath('data/$key.txt', TEXT, library);
}
inline static public function fragShader(key:String, ?library:String)
{
return getPath('shaders/$key.frag', TEXT, library);
}
inline static public function vertShader(key:String, ?library:String)
{
return getPath('shaders/$key.vert', TEXT, library);
}
inline static public function xml(key:String, ?library:String)
{
return getPath('data/$key.xml', TEXT, library);