diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 91d86ac3..b7349e96 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -101,6 +101,12 @@ void fmodCoreBindingInit(); void fmodStudioBindingInit(); #endif void screenBindingInit(); + +void compiledShaderBindingInit(); +void shaderBindingInit(); + +void etc_internalBindingInit(); + RB_METHOD(mriPrint); RB_METHOD(mriP); RB_METHOD(mkxpDataDirectory); @@ -144,6 +150,12 @@ static void mriBindingInit() fmodStudioBindingInit(); #endif screenBindingInit(); + + shaderBindingInit(); + compiledShaderBindingInit(); + + etc_internalBindingInit(); + rb_define_global_const("MODSHOT_VERSION", rb_str_new_cstr(MODSHOT_VERSION)); if (rgssVer >= 3) { diff --git a/binding-mri/binding-types.h b/binding-mri/binding-types.h index 1f0b3ae6..1f582319 100644 --- a/binding-mri/binding-types.h +++ b/binding-mri/binding-types.h @@ -37,4 +37,9 @@ DECL_TYPE(Viewport); DECL_TYPE(Tilemap); DECL_TYPE(Window); +DECL_TYPE(CustomShader); +DECL_TYPE(CompiledShader); + +DECL_TYPE(Vec2); +DECL_TYPE(Vec4); #endif // BINDINGTYPES_H diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index 5c742297..5526fd7d 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -27,6 +27,8 @@ #include "binding-util.h" #include "binding-types.h" +#include "rb_shader.h" + DEF_TYPE(Bitmap); static const char *objAsStringPtr(VALUE obj) @@ -401,23 +403,6 @@ RB_METHOD(bitmapBlur) return Qnil; } -RB_METHOD(bitmapMask) -{ - VALUE bitmapObj; - Bitmap *bitmap; - - int x = 0; - int y = 0; - rb_get_args(argc, argv, "o|ii", &bitmapObj, &x, &y RB_ARG_END); - bitmap = getPrivateDataCheck(bitmapObj, BitmapType); - - Bitmap *b = getPrivateData(self); - - b->mask(bitmap, x, y); - - return Qnil; -} - RB_METHOD(bitmapRadialBlur) { Bitmap *b = getPrivateData(self); @@ -451,6 +436,20 @@ RB_METHOD(bitmapInitializeCopy) } +RB_METHOD(bitmapShade) +{ + Bitmap *b = getPrivateData(self); + + VALUE shaderObj; + rb_get_args(argc, argv, "o", &shaderObj RB_ARG_END); + + CustomShader *shader = getPrivateDataCheck(shaderObj, CustomShaderType); + + b->shade(shader); + + return Qnil; +} + void bitmapBindingInit() { @@ -474,7 +473,6 @@ bitmapBindingInit() _rb_define_method(klass, "hue_change", bitmapHueChange); _rb_define_method(klass, "draw_text", bitmapDrawText); _rb_define_method(klass, "text_size", bitmapTextSize); - _rb_define_method(klass, "mask", bitmapMask); //if (rgssVer >= 2) //{ @@ -484,5 +482,7 @@ bitmapBindingInit() _rb_define_method(klass, "radial_blur", bitmapRadialBlur); //} + _rb_define_method(klass, "shade", bitmapShade); + INIT_PROP_BIND(Bitmap, Font, "font"); } diff --git a/binding-mri/compiled-shader-binding.cpp b/binding-mri/compiled-shader-binding.cpp new file mode 100644 index 00000000..07c2a2df --- /dev/null +++ b/binding-mri/compiled-shader-binding.cpp @@ -0,0 +1,86 @@ +#include "binding-util.h" +#include "rb_shader.h" +#include "shadable-element-binding.h" +#include "binding-types.h" + +DEF_TYPE(CompiledShader); + +RB_METHOD(comiledShaderInitialize) +{ + const char *contents; + VALUE aryArgs = 0; + VALUE vertContents = 0; + + rb_get_args(argc, argv, "z|oo", &contents, &aryArgs, &vertContents RB_ARG_END); + + if (!aryArgs) + aryArgs = rb_ary_new(); + + CompiledShader *shader; + if (vertContents) + { + shader = new CompiledShader(contents, aryArgs, rb_string_value_cstr(&vertContents)); + } + else + { + shader = new CompiledShader(contents, aryArgs); + } + setPrivateData(self, shader); + + rb_ary_freeze(aryArgs); + + rb_iv_set(self, "args", aryArgs); + + return self; +} + +RB_METHOD(compiledShaderArgs) +{ + RB_UNUSED_PARAM; + + return rb_iv_get(self, "args"); +} + +RB_METHOD(compiledShaderGetContents) +{ + RB_UNUSED_PARAM; + + CompiledShader *shader = getPrivateData(self); + + return rb_str_new_cstr(shader->getContents()); +} + +RB_METHOD(compiledShaderGetVertContents) +{ + RB_UNUSED_PARAM; + + CompiledShader *shader = getPrivateData(self); + + return rb_str_new_cstr(shader->getVertContents()); +} + +RB_METHOD(compiledShaderStringify) +{ + RB_UNUSED_PARAM; + + CompiledShader *shader = getPrivateData(self); + + return rb_sprintf( + "<#CompiledShader:%p private_shader=%p args=%" PRIsVALUE ">", + (void *)self, + (void *)shader, + rb_iv_get(self, "args")); +} + +void compiledShaderBindingInit() +{ + VALUE klass = rb_define_class("CompiledShader", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&CompiledShaderType>); + + _rb_define_method(klass, "initialize", comiledShaderInitialize); + _rb_define_method(klass, "args", compiledShaderArgs); + _rb_define_method(klass, "contents", compiledShaderGetContents); + _rb_define_method(klass, "vert_contents", compiledShaderGetVertContents); + _rb_define_method(klass, "to_s", compiledShaderStringify); + _rb_define_method(klass, "inspect", compiledShaderStringify); +} \ No newline at end of file diff --git a/binding-mri/etc-binding-util.h b/binding-mri/etc-binding-util.h new file mode 100644 index 00000000..273f05dd --- /dev/null +++ b/binding-mri/etc-binding-util.h @@ -0,0 +1,151 @@ +#ifndef ETC_BINDING_UTIL_H +#define ETC_BINDING_UTIL_H + +#define INIT_BIND(Klass) \ +{ \ + klass = rb_define_class(#Klass, rb_cObject); \ + rb_define_alloc_func(klass, classAllocate<&Klass##Type>); \ + rb_define_class_method(klass, "_load", Klass##Load); \ + serializableBindingInit(klass); \ + _rb_define_method(klass, "initialize", Klass##Initialize); \ + _rb_define_method(klass, "initialize_copy", Klass##InitializeCopy); \ + _rb_define_method(klass, "set", Klass##Set); \ + _rb_define_method(klass, "==", Klass##Equal); \ + _rb_define_method(klass, "===", Klass##Equal); \ + _rb_define_method(klass, "eql?", Klass##Equal); \ + _rb_define_method(klass, "to_s", Klass##Stringify); \ + _rb_define_method(klass, "inspect", Klass##Stringify); \ +} + +#define INIT_BIND_SERIALIZELESS(Klass) \ +{ \ + klass = rb_define_class(#Klass, rb_cObject); \ + rb_define_alloc_func(klass, classAllocate<&Klass##Type>); \ + _rb_define_method(klass, "initialize", Klass##Initialize); \ + _rb_define_method(klass, "initialize_copy", Klass##InitializeCopy); \ + _rb_define_method(klass, "set", Klass##Set); \ + _rb_define_method(klass, "==", Klass##Equal); \ + _rb_define_method(klass, "===", Klass##Equal); \ + _rb_define_method(klass, "eql?", Klass##Equal); \ + _rb_define_method(klass, "to_s", Klass##Stringify); \ + _rb_define_method(klass, "inspect", Klass##Stringify); \ +} + +#define MRB_ATTR_R(Class, attr) mrb_define_method(mrb, klass, #attr, Class##Get_##attr, MRB_ARGS_NONE()) +#define MRB_ATTR_W(Class, attr) mrb_define_method(mrb, klass, #attr "=", Class##Set_##attr, MRB_ARGS_REQ(1)) +#define MRB_ATTR_RW(Class, attr) { MRB_ATTR_R(Class, attr); MRB_ATTR_W(Class, attr); } + +#define RB_ATTR_R(Klass, Attr, attr) _rb_define_method(klass, #attr, Klass##Get##Attr) +#define RB_ATTR_W(Klass, Attr, attr) _rb_define_method(klass, #attr "=", Klass##Set##Attr) +#define RB_ATTR_RW(Klass, Attr, attr) \ + { RB_ATTR_R(Klass, Attr, attr); RB_ATTR_W(Klass, Attr, attr); } + +#define SET_FUN(Klass, param_type, param_t_s, last_param_def) \ + RB_METHOD(Klass##Set) \ + { \ + Klass *k = getPrivateData(self); \ + if (argc == 1) \ + { \ + VALUE otherObj = argv[0]; \ + Klass *other = getPrivateDataCheck(otherObj, Klass##Type); \ + *k = *other; \ + } \ + else \ + { \ + param_type p1, p2, p3, p4 = last_param_def; \ + rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4 RB_ARG_END); \ + k->set(p1, p2, p3, p4); \ + } \ + return self; \ + } + +#define SET_FUN_2(Klass, param_type, param_t_s, last_param_def) \ + RB_METHOD(Klass##Set) \ + { \ + Klass *k = getPrivateData(self); \ + if (argc == 1) \ + { \ + VALUE otherObj = argv[0]; \ + Klass *other = getPrivateDataCheck(otherObj, Klass##Type); \ + *k = *other; \ + } \ + else \ + { \ + param_type p1, p2 = last_param_def; \ + rb_get_args(argc, argv, param_t_s, &p1, &p2 RB_ARG_END); \ + k->set(p1, p2); \ + } \ + return self; \ + } + +#define INIT_FUN(Klass, param_type, param_t_s, last_param_def) \ + RB_METHOD(Klass##Initialize) \ + { \ + Klass *k; \ + if (argc == 0) \ + { \ + k = new Klass(); \ + } \ + else \ + { \ + param_type p1, p2, p3, p4 = last_param_def; \ + rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4 RB_ARG_END); \ + k = new Klass(p1, p2, p3, p4); \ + } \ + setPrivateData(self, k); \ + return self; \ + } + +#define INIT_FUN_2(Klass, param_type, param_t_s, last_param_def) \ + RB_METHOD(Klass##Initialize) \ + { \ + Klass *k; \ + if (argc == 0) \ + { \ + k = new Klass(); \ + } \ + else \ + { \ + param_type p1, p2 = last_param_def; \ + rb_get_args(argc, argv, param_t_s, &p1, &p2 RB_ARG_END); \ + k = new Klass(p1, p2); \ + } \ + setPrivateData(self, k); \ + return self; \ + } + +#define EQUAL_FUN(Klass) \ + RB_METHOD(Klass##Equal) \ + { \ + Klass *p = getPrivateData(self); \ + VALUE otherObj; \ + Klass *other; \ + rb_get_args(argc, argv, "o", &otherObj RB_ARG_END); \ + if (rgssVer >= 3) \ + if (!rb_typeddata_is_kind_of(otherObj, &Klass##Type)) \ + return Qfalse; \ + other = getPrivateDataCheck(otherObj, Klass##Type); \ + return rb_bool_new(*p == *other); \ + } + +#define ATTR_RW(Klass, Attr, arg_type, arg_t_s, value_fun) \ + RB_METHOD(Klass##Get##Attr) \ + { \ + RB_UNUSED_PARAM \ + Klass *p = getPrivateData(self); \ + return value_fun(p->get##Attr()); \ + } \ + RB_METHOD(Klass##Set##Attr) \ + { \ + Klass *p = getPrivateData(self); \ + arg_type arg; \ + rb_get_args(argc, argv, arg_t_s, &arg RB_ARG_END); \ + p->set##Attr(arg); \ + return *argv; \ + } + +#define ATTR_DOUBLE_RW(Klass, Attr) ATTR_RW(Klass, Attr, double, "f", rb_float_new) +#define ATTR_FLOAT_RW(Klass, Attr) ATTR_RW(Klass, Attr, float, "f", rb_float_new) +#define ATTR_INT_RW(Klass, Attr) ATTR_RW(Klass, Attr, int, "i", rb_fix_new) + +#endif \ No newline at end of file diff --git a/binding-mri/etc-binding.cpp b/binding-mri/etc-binding.cpp index 2c2cdd23..647aedeb 100644 --- a/binding-mri/etc-binding.cpp +++ b/binding-mri/etc-binding.cpp @@ -23,30 +23,12 @@ #include "binding-util.h" #include "serializable-binding.h" #include "sharedstate.h" +#include "etc-binding-util.h" DEF_TYPE(Color); DEF_TYPE(Tone); DEF_TYPE(Rect); -#define ATTR_RW(Klass, Attr, arg_type, arg_t_s, value_fun) \ - RB_METHOD(Klass##Get##Attr) \ - { \ - RB_UNUSED_PARAM \ - Klass *p = getPrivateData(self); \ - return value_fun(p->get##Attr()); \ - } \ - RB_METHOD(Klass##Set##Attr) \ - { \ - Klass *p = getPrivateData(self); \ - arg_type arg; \ - rb_get_args(argc, argv, arg_t_s, &arg RB_ARG_END); \ - p->set##Attr(arg); \ - return *argv; \ - } - -#define ATTR_DOUBLE_RW(Klass, Attr) ATTR_RW(Klass, Attr, double, "f", rb_float_new) -#define ATTR_INT_RW(Klass, Attr) ATTR_RW(Klass, Attr, int, "i", rb_fix_new) - ATTR_DOUBLE_RW(Color, Red) ATTR_DOUBLE_RW(Color, Green) ATTR_DOUBLE_RW(Color, Blue) @@ -62,65 +44,14 @@ ATTR_INT_RW(Rect, Y) ATTR_INT_RW(Rect, Width) ATTR_INT_RW(Rect, Height) -#define EQUAL_FUN(Klass) \ - RB_METHOD(Klass##Equal) \ - { \ - Klass *p = getPrivateData(self); \ - VALUE otherObj; \ - Klass *other; \ - rb_get_args(argc, argv, "o", &otherObj RB_ARG_END); \ - if (rgssVer >= 3) \ - if (!rb_typeddata_is_kind_of(otherObj, &Klass##Type)) \ - return Qfalse; \ - other = getPrivateDataCheck(otherObj, Klass##Type); \ - return rb_bool_new(*p == *other); \ - } - EQUAL_FUN(Color) EQUAL_FUN(Tone) EQUAL_FUN(Rect) -#define INIT_FUN(Klass, param_type, param_t_s, last_param_def) \ - RB_METHOD(Klass##Initialize) \ - { \ - Klass *k; \ - if (argc == 0) \ - { \ - k = new Klass(); \ - } \ - else \ - { \ - param_type p1, p2, p3, p4 = last_param_def; \ - rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4 RB_ARG_END); \ - k = new Klass(p1, p2, p3, p4); \ - } \ - setPrivateData(self, k); \ - return self; \ - } - INIT_FUN(Color, double, "fff|f", 255) INIT_FUN(Tone, double, "fff|f", 0) INIT_FUN(Rect, int, "iiii", 0) -#define SET_FUN(Klass, param_type, param_t_s, last_param_def) \ - RB_METHOD(Klass##Set) \ - { \ - Klass *k = getPrivateData(self); \ - if (argc == 1) \ - { \ - VALUE otherObj = argv[0]; \ - Klass *other = getPrivateDataCheck(otherObj, Klass##Type); \ - *k = *other; \ - } \ - else \ - { \ - param_type p1, p2, p3, p4 = last_param_def; \ - rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4 RB_ARG_END); \ - k->set(p1, p2, p3, p4); \ - } \ - return self; \ - } - SET_FUN(Color, double, "fff|f", 255) SET_FUN(Tone, double, "fff|f", 0) SET_FUN(Rect, int, "iiii", 0) @@ -171,31 +102,6 @@ INITCOPY_FUN(Tone) INITCOPY_FUN(Color) INITCOPY_FUN(Rect) -#define INIT_BIND(Klass) \ -{ \ - klass = rb_define_class(#Klass, rb_cObject); \ - rb_define_alloc_func(klass, classAllocate<&Klass##Type>); \ - rb_define_class_method(klass, "_load", Klass##Load); \ - serializableBindingInit(klass); \ - _rb_define_method(klass, "initialize", Klass##Initialize); \ - _rb_define_method(klass, "initialize_copy", Klass##InitializeCopy); \ - _rb_define_method(klass, "set", Klass##Set); \ - _rb_define_method(klass, "==", Klass##Equal); \ - _rb_define_method(klass, "===", Klass##Equal); \ - _rb_define_method(klass, "eql?", Klass##Equal); \ - _rb_define_method(klass, "to_s", Klass##Stringify); \ - _rb_define_method(klass, "inspect", Klass##Stringify); \ -} - -#define MRB_ATTR_R(Class, attr) mrb_define_method(mrb, klass, #attr, Class##Get_##attr, MRB_ARGS_NONE()) -#define MRB_ATTR_W(Class, attr) mrb_define_method(mrb, klass, #attr "=", Class##Set_##attr, MRB_ARGS_REQ(1)) -#define MRB_ATTR_RW(Class, attr) { MRB_ATTR_R(Class, attr); MRB_ATTR_W(Class, attr); } - -#define RB_ATTR_R(Klass, Attr, attr) _rb_define_method(klass, #attr, Klass##Get##Attr) -#define RB_ATTR_W(Klass, Attr, attr) _rb_define_method(klass, #attr "=", Klass##Set##Attr) -#define RB_ATTR_RW(Klass, Attr, attr) \ - { RB_ATTR_R(Klass, Attr, attr); RB_ATTR_W(Klass, Attr, attr); } - void etcBindingInit() { diff --git a/binding-mri/etc-internal-binding.cpp b/binding-mri/etc-internal-binding.cpp new file mode 100644 index 00000000..20378597 --- /dev/null +++ b/binding-mri/etc-internal-binding.cpp @@ -0,0 +1,62 @@ +#include "etc-binding-util.h" +#include "etc-internal.h" +#include "binding-util.h" +#include "sharedstate.h" + +DEF_TYPE(Vec2); +DEF_TYPE(Vec4); + +ATTR_DOUBLE_RW(Vec2, X); +ATTR_DOUBLE_RW(Vec2, Y); + +ATTR_DOUBLE_RW(Vec4, X); +ATTR_DOUBLE_RW(Vec4, Y); +ATTR_DOUBLE_RW(Vec4, Z); +ATTR_DOUBLE_RW(Vec4, W); + +EQUAL_FUN(Vec2); +EQUAL_FUN(Vec4); + +INIT_FUN_2(Vec2, double, "ff", 0); +INIT_FUN(Vec4, double, "ffff", 0); + +SET_FUN_2(Vec2, double, "ff", 0); +SET_FUN(Vec4, double, "ffff", 0); + +RB_METHOD(Vec2Stringify) +{ + RB_UNUSED_PARAM; + + Vec2 *v = getPrivateData(self); + + return rb_sprintf("(%f, %f)", v->x, v->y); +} + +RB_METHOD(Vec4Stringify) +{ + RB_UNUSED_PARAM; + + Vec4 *v = getPrivateData(self); + + return rb_sprintf("(%f, %f, %f, %f)", v->x, v->y, v->z, v->w); +} + +INITCOPY_FUN(Vec2); +INITCOPY_FUN(Vec4); + +void etc_internalBindingInit() +{ + VALUE klass; + + INIT_BIND_SERIALIZELESS(Vec2); + + RB_ATTR_RW(Vec2, X, x); + RB_ATTR_RW(Vec2, Y, y); + + INIT_BIND_SERIALIZELESS(Vec4); + + RB_ATTR_RW(Vec4, X, x); + RB_ATTR_RW(Vec4, Y, y); + RB_ATTR_RW(Vec4, Z, z); + RB_ATTR_RW(Vec4, W, w); +} \ No newline at end of file diff --git a/binding-mri/meson.build b/binding-mri/meson.build index 50ce9e1a..cc2b56b6 100644 --- a/binding-mri/meson.build +++ b/binding-mri/meson.build @@ -12,10 +12,14 @@ endif global_include_dirs += include_directories('.') binding_source = [files( + 'aleffect-binding.cpp', + 'audio-binding.cpp', + 'compiled-shader-binding.cpp', 'binding-mri.cpp', 'binding-util.cpp', 'bitmap-binding.cpp', 'etc-binding.cpp', + 'etc-internal-binding.cpp', 'filesystem-binding.cpp', 'font-binding.cpp', 'graphics-binding.cpp', @@ -27,6 +31,7 @@ binding_source = [files( 'modshot-binding.cpp', 'plane-binding.cpp', 'screen-binding.cpp', + 'shader-binding.cpp', 'sprite-binding.cpp', 'steam-binding.cpp', 'table-binding.cpp', diff --git a/binding-mri/plane-binding.cpp b/binding-mri/plane-binding.cpp index 391f3eff..1e5828a2 100644 --- a/binding-mri/plane-binding.cpp +++ b/binding-mri/plane-binding.cpp @@ -24,12 +24,14 @@ #include "viewportelement-binding.h" #include "binding-util.h" #include "binding-types.h" +#include "shadable-element-binding.h" DEF_TYPE(Plane); RB_METHOD(planeInitialize) { Plane *p = viewportElementInitialize(argc, argv, self); + shadableElementInitialize(self, p); setPrivateData(self, p); @@ -54,7 +56,6 @@ DEF_PROP_I(Plane, BlendType) DEF_PROP_F(Plane, ZoomX) DEF_PROP_F(Plane, ZoomY) -DEF_PROP_F(Plane, WaterTime) void @@ -65,6 +66,7 @@ planeBindingInit() disposableBindingInit (klass); viewportElementBindingInit(klass); + shadableElementBindingInit(klass); _rb_define_method(klass, "initialize", planeInitialize); @@ -78,5 +80,4 @@ planeBindingInit() INIT_PROP_BIND( Plane, BlendType, "blend_type" ); INIT_PROP_BIND( Plane, Color, "color" ); INIT_PROP_BIND( Plane, Tone, "tone" ); - INIT_PROP_BIND( Plane, WaterTime, "waterTime" ); } diff --git a/binding-mri/shadable-element-binding.h b/binding-mri/shadable-element-binding.h new file mode 100644 index 00000000..cd9573b3 --- /dev/null +++ b/binding-mri/shadable-element-binding.h @@ -0,0 +1,26 @@ +#ifndef SHADABLEBINDING_H +#define SHADABLEBINDING_H + +#include "binding-util.h" + +RB_METHOD(shadableGetShaders) { + + RB_UNUSED_PARAM; + + return rb_iv_get(self, "shaders"); +} + +template +void shadableElementInitialize(VALUE self, C *se) { + VALUE ary = rb_ary_new(); + + rb_iv_set(self, "shaders", ary); + + se->setShaderArr(ary); +} + +inline void shadableElementBindingInit(VALUE klass) { + _rb_define_method(klass, "shaders", shadableGetShaders); +} + +#endif \ No newline at end of file diff --git a/binding-mri/shader-binding.cpp b/binding-mri/shader-binding.cpp new file mode 100644 index 00000000..8e49abc6 --- /dev/null +++ b/binding-mri/shader-binding.cpp @@ -0,0 +1,91 @@ +#include "binding-util.h" +#include "rb_shader.h" +#include "shadable-element-binding.h" +#include "binding-types.h" + +DEF_TYPE_CUSTOMNAME(CustomShader, "Shader"); + +RB_METHOD(shaderInitialize) +{ + VALUE compiledShaderObj; + VALUE hashArgs = 0; + VALUE hashTexUnits = 0; + + rb_get_args(argc, argv, "o|oo", &compiledShaderObj, &hashArgs, &hashTexUnits RB_ARG_END); + + CompiledShader *compiledShader = getPrivateData(compiledShaderObj); + + rb_iv_set(self, "compiled_shader", compiledShaderObj); + + if (!hashArgs) + hashArgs = rb_hash_new(); + + if (!hashTexUnits) + hashTexUnits = rb_hash_new(); + + rb_iv_set(self, "args", hashArgs); + rb_iv_set(self, "tex_units", hashTexUnits); + + CustomShader *shader = new CustomShader(compiledShader, hashArgs, hashTexUnits); + + setPrivateData(self, shader); + + return self; +} + +RB_METHOD(shaderCompile) +{ + VALUE contents; + VALUE aryArgs= 0; + VALUE vertContents = 0; + + rb_get_args(argc, argv, "o|oo", &contents, &aryArgs, &vertContents RB_ARG_END); + + VALUE passedArgs[] = {contents, aryArgs, vertContents}; + + VALUE classConst = rb_const_get(rb_cObject, rb_intern("CompiledShader")); + VALUE shaderObj = rb_class_new_instance(3, passedArgs, classConst); + + return shaderObj; +} + +RB_METHOD(shaderArgs) +{ + RB_UNUSED_PARAM; + + return rb_iv_get(self, "args"); +} + +RB_METHOD(shaderGetCompiledShader) +{ + RB_UNUSED_PARAM; + + return rb_iv_get(self, "compiled_shader"); +} + +RB_METHOD(shaderStringify) +{ + RB_UNUSED_PARAM; + + CustomShader *shader = getPrivateData(self); + + return rb_sprintf( + "<#Shader:%p private_shader=%p args=%" PRIsVALUE " compiled_shader=%" PRIsVALUE ">", + (void *)self, + (void *)shader, + rb_iv_get(self, "args"), + rb_iv_get(self, "compiled_shader")); +} + +void shaderBindingInit() +{ + VALUE klass = rb_define_class("Shader", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&CustomShaderType>); + + _rb_define_method(klass, "initialize", shaderInitialize); + _rb_define_module_function(klass, "compile", shaderCompile); + _rb_define_method(klass, "args", shaderArgs); + _rb_define_method(klass, "compiled_shader", shaderGetCompiledShader); + _rb_define_method(klass, "to_s", shaderStringify); + _rb_define_method(klass, "inspect", shaderStringify); +} \ No newline at end of file diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index c659bc28..d5471a4c 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -28,12 +28,16 @@ #include "binding-util.h" #include "binding-types.h" +#include "shadable-element-binding.h" + DEF_TYPE(Sprite); RB_METHOD(spriteInitialize) { Sprite *s = viewportElementInitialize(argc, argv, self); + shadableElementInitialize(self, s); + setPrivateData(self, s); /* Wrap property objects */ @@ -72,8 +76,6 @@ DEF_PROP_B(Sprite, Mirror) DEF_PROP_B(Sprite, VMirror) DEF_PROP_B(Sprite, Obscured) -DEF_PROP_B(Sprite, Scanned) - RB_METHOD(spriteWidth) { RB_UNUSED_PARAM; @@ -107,6 +109,7 @@ spriteBindingInit() disposableBindingInit (klass); flashableBindingInit (klass); viewportElementBindingInit(klass); + shadableElementBindingInit(klass); _rb_define_method(klass, "initialize", spriteInitialize); @@ -127,7 +130,6 @@ spriteBindingInit() INIT_PROP_BIND( Sprite, Color, "color" ); INIT_PROP_BIND( Sprite, Tone, "tone" ); INIT_PROP_BIND( Sprite, Obscured, "obscured" ); - INIT_PROP_BIND( Sprite, Scanned, "scanned" ); INIT_PROP_BIND( Sprite, BushOpacity, "bush_opacity" ); INIT_PROP_BIND( Sprite, WaveAmp, "wave_amp" ); INIT_PROP_BIND( Sprite, WaveLength, "wave_length" ); diff --git a/binding-mri/viewport-binding.cpp b/binding-mri/viewport-binding.cpp index 184d5ded..c7a5cf10 100644 --- a/binding-mri/viewport-binding.cpp +++ b/binding-mri/viewport-binding.cpp @@ -27,6 +27,8 @@ #include "binding-util.h" #include "binding-types.h" +#include "shadable-element-binding.h" + DEF_TYPE(Viewport); RB_METHOD(viewportInitialize) @@ -59,6 +61,8 @@ RB_METHOD(viewportInitialize) v = new Viewport(x, y, width, height); } + shadableElementInitialize(self, v); + setPrivateData(self, v); /* Wrap property objects */ @@ -76,75 +80,12 @@ RB_METHOD(viewportInitialize) return self; } -RB_METHOD(setRGBOffset) -{ - double x, y, z; - double x2, y2, z2; - rb_get_args(argc, argv, "ffffff", &x, &y, &z, &x2, &y2, &z2); - - Viewport *v = getPrivateData(self); - - v->setRGBOffsetx(Vec4(x, y, z, 0)); - v->setRGBOffsety(Vec4(x2, y2, z2, 0)); - - return Qnil; -} - -RB_METHOD(setCubicTime) -{ - double time; - rb_get_args(argc, argv, "f", &time); - - Viewport *v = getPrivateData(self); - - v->setCubicTime(time); - - return Qnil; -} - -RB_METHOD(setBinaryStrength) -{ - double strength; - rb_get_args(argc, argv, "f", &strength); - - Viewport *v = getPrivateData(self); - - v->setBinaryStrength(clamp(strength, 0.0, 1.0)); - - return Qnil; -} - -RB_METHOD(setWaterTime) -{ - double time; - rb_get_args(argc, argv, "f", &time); - - Viewport *v = getPrivateData(self); - - v->setWaterTime(time); - - return Qnil; -} - -RB_METHOD(setZoom) -{ - double x, y; - rb_get_args(argc, argv, "ff", &x, &y); - - Viewport *v = getPrivateData(self); - - v->setZoom(Vec2(x, y)); - - return Qnil; -} - DEF_PROP_OBJ_VAL(Viewport, Rect, Rect, "rect") DEF_PROP_OBJ_VAL(Viewport, Color, Color, "color") DEF_PROP_OBJ_VAL(Viewport, Tone, Tone, "tone") DEF_PROP_I(Viewport, OX) DEF_PROP_I(Viewport, OY) -DEF_PROP_B(Viewport, Scanned) void viewportBindingInit() @@ -155,19 +96,14 @@ viewportBindingInit() disposableBindingInit (klass); flashableBindingInit (klass); sceneElementBindingInit(klass); + shadableElementBindingInit(klass); _rb_define_method(klass, "initialize", viewportInitialize); - _rb_define_method(klass, "setRGBOffset", setRGBOffset); - _rb_define_method(klass, "setZoom", setZoom); - _rb_define_method(klass, "setCubicTime", setCubicTime); - _rb_define_method(klass, "setBinaryStrength", setBinaryStrength); - _rb_define_method(klass, "setWaterTime", setWaterTime); - + INIT_PROP_BIND( Viewport, Rect, "rect" ); INIT_PROP_BIND( Viewport, OX, "ox" ); INIT_PROP_BIND( Viewport, OY, "oy" ); INIT_PROP_BIND( Viewport, Color, "color" ); INIT_PROP_BIND( Viewport, Tone, "tone" ); - INIT_PROP_BIND( Viewport, Scanned, "scanned"); } diff --git a/shader/binary_glitch.frag b/shader/binary_glitch.frag deleted file mode 100644 index a2ab297c..00000000 --- a/shader/binary_glitch.frag +++ /dev/null @@ -1,53 +0,0 @@ - -// Binary Glitch - based on Luminosity. -// use the Mouse to effect the strength. - - -// by D34N 4L3X -// dean@neuroid.co.uk - -uniform sampler2D texture; -uniform float strength; -varying vec2 v_texCoord; - -void main() -{ - vec2 uv = v_texCoord.xy; -// uv.t = 1.0 - uv.t; - - float x = uv.s; - float y = uv.t; - - // - float glitchStrength = strength * 5.0; - - // get snapped position - float psize = 0.04 * glitchStrength; - float psq = 1.0 / psize; - - float px = floor( x * psq + 0.5) * psize; - float py = floor( y * psq + 0.5) * psize; - - vec4 colSnap = texture2D( texture, vec2( px,py) ); - - float lum = pow( 1.0 - (colSnap.r + colSnap.g + colSnap.b) / 3.0, glitchStrength ); // remove the minus one if you want to invert luma - - - - // do move with lum as multiplying factor - float qsize = psize * lum; - - float qsq = 1.0 / qsize; - - float qx = floor( x * qsq + 0.5) * qsize; - float qy = floor( y * qsq + 0.5) * qsize; - - float rx = (px - qx) * lum + x; - float ry = (py - qy) * lum + y; - - vec4 colMove = texture2D( texture, vec2( rx,ry) ); - - - // final color - gl_FragColor = colMove; -} \ No newline at end of file diff --git a/shader/crt.frag b/shader/crt.frag deleted file mode 100644 index 7a2dba8c..00000000 --- a/shader/crt.frag +++ /dev/null @@ -1,46 +0,0 @@ -uniform sampler2D texture; - -varying vec2 v_texCoord; - -vec2 curvature = vec2(3.0, 3.0); -vec2 screenResolution = vec2(640, 480); -vec2 scanLineOpacity = vec2(0.75, 0.75); -float vignetteOpacity = 1.0; -float brightness = 2.5; -float vignetteRoundness = 1.0; - - -vec2 curveRemapUV(vec2 uv) -{ - // as we near the edge of our screen apply greater distortion using a sinusoid. - uv = uv * 2.0 - 1.0; - vec2 offset = abs(uv.yx) / vec2(curvature.x, curvature.y); - uv = uv + uv * offset * offset; - uv = uv * 0.5 + 0.5; - return uv; -} -vec4 scanLineIntensity(float uv, float resolution, float opacity) -{ - float intensity = sin(uv * resolution * 3.1415926538 * 2.0); - intensity = ((0.5 * intensity) + 0.5) * 0.9 + 0.1; - return vec4(vec3(pow(intensity, opacity)), 1.0); -} -vec4 vignetteIntensity(vec2 uv, vec2 resolution, float opacity, float roundness) -{ - float intensity = uv.x * uv.y * (1.0 - uv.x) * (1.0 - uv.y); - return vec4(vec3(clamp(pow((resolution.x / roundness) * intensity, opacity), 0.0, 1.0)), 1.0); -} -void main() -{ - vec2 remappedUV = curveRemapUV(vec2(v_texCoord.x, v_texCoord.y)); - vec4 baseColor = texture2D(texture, remappedUV); - baseColor *= vignetteIntensity(remappedUV, screenResolution, vignetteOpacity, vignetteRoundness); - baseColor *= scanLineIntensity(remappedUV.x, screenResolution.y, scanLineOpacity.x); - baseColor *= scanLineIntensity(remappedUV.y, screenResolution.x, scanLineOpacity.y); - baseColor *= vec4(vec3(brightness), 1.0); - if (remappedUV.x < 0.0 || remappedUV.y < 0.0 || remappedUV.x > 1.0 || remappedUV.y > 1.0){ - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - } else { - gl_FragColor = baseColor; - } -} \ No newline at end of file diff --git a/shader/crt_sprite.frag b/shader/crt_sprite.frag deleted file mode 100644 index dc785de6..00000000 --- a/shader/crt_sprite.frag +++ /dev/null @@ -1,89 +0,0 @@ -vec2 u_resolution = vec2(320, 240); -uniform sampler2D texture; -varying vec2 v_texCoord; - -const float SIZE = 0.0075; // Tweakable. Original: 0.0075 -const float VERTICAL_FACTOR = 0.75; // Tweakable. Original: 0.86 - -// Other constants for readability -const float SIZE_HALF = SIZE * 0.5; -const float TO_ONE = 1. / SIZE; -const float VERTICAL_FACTOR_INV = 1. - VERTICAL_FACTOR; - -float Distance(vec2 origin, vec2 point) { - return abs(sqrt(pow(point.x - origin.x, 2.) + pow(point.y - origin.y, 2.))); -} - -bool IsOutside(float distance){ - return mod(distance, SIZE) > SIZE_HALF; -} - -vec2 GridCoords(vec2 st){ - return vec2( - (st.x - mod(st.x, SIZE)) * TO_ONE, - (st.y - mod(st.y, SIZE)) * TO_ONE - ); -} - -// Returns a color to reduce off the fragment based on its coordinates -vec4 ColorReduction(vec2 st){ - vec2 gridCoords = GridCoords(st); - - st.x = st.x + SIZE_HALF * gridCoords.y; - - vec2 pointLeft = vec2( - st.x - mod(st.x, SIZE), - st.y - mod(st.y, SIZE) - SIZE_HALF * VERTICAL_FACTOR_INV - ); - - vec2 pointRight = vec2( - (st.x + SIZE) - mod(st.x, SIZE), - st.y - mod(st.y, SIZE) - SIZE_HALF * VERTICAL_FACTOR_INV - ); - - vec2 pointUp = vec2( - st.x - mod(st.x, SIZE) + SIZE_HALF, - st.y - mod(st.y, SIZE) + SIZE * VERTICAL_FACTOR - ); - - float distLeft = Distance(st, pointLeft); - float distRight = Distance(st, pointRight); - float distUp = Distance(st, pointUp); - - vec2 point; - bool isOutside = false; - float off = 0.; - - if (distUp <= distLeft && distUp <= distRight){ - point = pointUp; - isOutside = IsOutside(distUp); - off = 1.; - } else if (distRight <= distLeft){ - point = pointRight; - isOutside = IsOutside(distRight); - } else { - point = pointLeft; - isOutside = IsOutside(distLeft); - } - - if (isOutside) - return vec4(1); - - vec2 colorCoords = GridCoords(point); - float colorIndex = mod(colorCoords.y + colorCoords.x + off, 3.); - - if (colorIndex == 0.) - return vec4(0, 1, 1, 0); - - if (colorIndex == 1.) - return vec4(1, 0, 1, 0); - - return vec4(1, 1, 0, 0); -} - -void main() { - vec2 st = gl_FragCoord.xy / min(u_resolution.y, u_resolution.x); - vec4 color = ColorReduction(st); - vec4 usedTexture = texture2D(texture, v_texCoord); - gl_FragColor = usedTexture - color; -} \ No newline at end of file diff --git a/shader/cubic_lens.frag b/shader/cubic_lens.frag deleted file mode 100644 index 68f8a16c..00000000 --- a/shader/cubic_lens.frag +++ /dev/null @@ -1,39 +0,0 @@ -uniform sampler2D texture; -uniform float iTime; - -varying vec2 v_texCoord; - -vec2 computeUV( vec2 uv, float k, float kcube ){ - - vec2 t = uv - .5; - float r2 = t.x * t.x + t.y * t.y; - float f = 0.; - - if( kcube == 0.0){ - f = 1. + r2 * k; - }else{ - f = 1. + r2 * ( k + kcube * sqrt( r2 ) ); - } - - vec2 nUv = f * t + .5; - nUv.y = 1. - nUv.y; - - return nUv; - -} - -void main() { - - vec2 uv = vec2(v_texCoord.s, 1.0 - v_texCoord.t); - float k = 1.0 * sin( iTime * .9 ); - float kcube = .5 * sin( iTime ); - - float offset = .1 * sin( iTime * .5 ); - - float red = texture2D( texture, computeUV( uv, k + offset, kcube ) ).r; - float green = texture2D( texture, computeUV( uv, k, kcube ) ).g; - float blue = texture2D( texture, computeUV( uv, k - offset, kcube ) ).b; - - gl_FragColor = vec4( red, green,blue, 1. ); - -} \ No newline at end of file diff --git a/shader/mask.frag b/shader/mask.frag deleted file mode 100644 index ca2eed04..00000000 --- a/shader/mask.frag +++ /dev/null @@ -1,20 +0,0 @@ -uniform sampler2D maskTex; -uniform sampler2D texture; -uniform vec2 maskTranslation; - -varying vec2 v_maskTexCoord; -varying vec2 v_texCoord; - -vec4 colorOut; - -void main(){ - - vec4 color = texture2D(texture,v_texCoord); - vec4 mask = texture2D(maskTex,v_maskTexCoord); - - // alpha value can be in any channel, depends on texture format. - - colorOut = vec4(color.rgb, color.a * mask.r); - - gl_FragColor = colorOut; -} \ No newline at end of file diff --git a/shader/mask.vert b/shader/mask.vert deleted file mode 100644 index 383693fd..00000000 --- a/shader/mask.vert +++ /dev/null @@ -1,20 +0,0 @@ - -uniform mat4 projMat; - -uniform vec2 texSizeInv; -uniform vec2 maskTexCoords; -uniform vec2 translation; - -attribute vec2 position; -attribute vec2 texCoord; - -varying vec2 v_texCoord; -varying vec2 v_maskTexCoord; - -void main() -{ - gl_Position = projMat * vec4(position + translation, 0, 1); - - v_texCoord = texCoord * texSizeInv; - v_maskTexCoord = texCoord * maskTexCoords; -} diff --git a/shader/meson.build b/shader/meson.build index 644ea09b..64d84f8a 100644 --- a/shader/meson.build +++ b/shader/meson.build @@ -1,20 +1,13 @@ embedded_shaders = [ - 'binary_glitch.frag', 'bitmapBlit.frag', 'blur.frag', 'blurH.vert', 'blurV.vert', - 'chronos.frag', 'common.h', - 'crt_sprite.frag', - 'crt.frag', - 'cubic_lens.frag', 'flashMap.frag', 'flatColor.frag', 'gray.frag', 'hue.frag', - 'mask.frag', - 'mask.vert', 'minimal.vert', 'obscured.frag', 'plane.frag', @@ -30,8 +23,7 @@ embedded_shaders = [ 'tilemap.vert', 'trans.frag', 'transSimple.frag', - 'water.frag', - 'zoom.vert' + 'rb_simple.vert' ] embedded_shaders_f = files(embedded_shaders) diff --git a/shader/zoom.vert b/shader/rb_simple.vert similarity index 86% rename from shader/zoom.vert rename to shader/rb_simple.vert index 41e65eea..ad16d47b 100644 --- a/shader/zoom.vert +++ b/shader/rb_simple.vert @@ -3,7 +3,6 @@ uniform mat4 projMat; uniform vec2 texSizeInv; uniform vec2 translation; -uniform vec2 zoom; attribute vec2 position; attribute vec2 texCoord; @@ -15,5 +14,4 @@ void main() gl_Position = projMat * vec4(position + translation, 0, 1); v_texCoord = texCoord * texSizeInv; - v_texCoord *= zoom; } diff --git a/shader/water.frag b/shader/water.frag deleted file mode 100644 index 4e5547d6..00000000 --- a/shader/water.frag +++ /dev/null @@ -1,122 +0,0 @@ -uniform sampler2D texture; -uniform float iTime; -uniform lowp float opacity; - -varying vec2 v_texCoord; - -#define T iTime -vec3 mod289(vec3 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 mod289(vec4 x) { - return x - floor(x * (1.0 / 289.0)) * 289.0; -} - -vec4 permute(vec4 x) { - return mod289(((x*34.0)+1.0)*x); -} - -vec4 taylorInvSqrt(vec4 r) -{ - return 1.79284291400159 - 0.85373472095314 * r; -} - -float snoise(vec3 v) - { - const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; - const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); - -// First corner - vec3 i = floor(v + dot(v, C.yyy) ); - vec3 x0 = v - i + dot(i, C.xxx) ; - -// Other corners - vec3 g = step(x0.yzx, x0.xyz); - vec3 l = 1.0 - g; - vec3 i1 = min( g.xyz, l.zxy ); - vec3 i2 = max( g.xyz, l.zxy ); - - // x0 = x0 - 0.0 + 0.0 * C.xxx; - // x1 = x0 - i1 + 1.0 * C.xxx; - // x2 = x0 - i2 + 2.0 * C.xxx; - // x3 = x0 - 1.0 + 3.0 * C.xxx; - vec3 x1 = x0 - i1 + C.xxx; - vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y - vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y - -// Permutations - i = mod289(i); - vec4 p = permute( permute( permute( - i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) - + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); - -// Gradients: 7x7 points over a square, mapped onto an octahedron. -// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) - float n_ = 0.142857142857; // 1.0/7.0 - vec3 ns = n_ * D.wyz - D.xzx; - - vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) - - vec4 x_ = floor(j * ns.z); - vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) - - vec4 x = x_ *ns.x + ns.yyyy; - vec4 y = y_ *ns.x + ns.yyyy; - vec4 h = 1.0 - abs(x) - abs(y); - - vec4 b0 = vec4( x.xy, y.xy ); - vec4 b1 = vec4( x.zw, y.zw ); - - //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; - //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; - vec4 s0 = floor(b0)*2.0 + 1.0; - vec4 s1 = floor(b1)*2.0 + 1.0; - vec4 sh = -step(h, vec4(0.0)); - - vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; - vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; - - vec3 p0 = vec3(a0.xy,h.x); - vec3 p1 = vec3(a0.zw,h.y); - vec3 p2 = vec3(a1.xy,h.z); - vec3 p3 = vec3(a1.zw,h.w); - -//Normalise gradients - vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - -// Mix final noise value - vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); - m = m * m; - return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), - dot(p2,x2), dot(p3,x3) ) ); - } -float MUL = 10.; -vec2 FLOW = vec2(1); -float h (vec3 v) { - return snoise(vec3(v.x*MUL-T*FLOW.x,T,v.z*MUL-T*FLOW.y)); -} -float function(vec3 v) { - return v.y-h(v); -} -vec3 calcNormal( in vec3 x, in float eps ) -{ - vec2 e = vec2( eps, 0.0 ); - return normalize( vec3( function(x+e.xyy) - function(x-e.xyy), - function(x+e.yxy) - function(x-e.yxy), - function(x+e.yyx) - function(x-e.yyx) ) ); -} -void main() -{ - - vec2 uv = v_texCoord; - vec3 v = calcNormal(vec3(uv.x,1,uv.y),.01); - vec4 fragColor = texture2D(texture,uv+(v.xz/15.*.25)); - fragColor.a *= opacity; - gl_FragColor = fragColor; -} \ No newline at end of file diff --git a/src/graphics/headers/bitmap.h b/src/graphics/headers/bitmap.h index bacf662a..3a264896 100644 --- a/src/graphics/headers/bitmap.h +++ b/src/graphics/headers/bitmap.h @@ -26,6 +26,8 @@ #include "etc-internal.h" #include "etc.h" +#include "rb_shader.h" + #include class Font; @@ -73,11 +75,10 @@ class Bitmap : public Disposable int width, int height); void clearRect(const IntRect &rect); - void mask(Bitmap *mask, int x, int y); - void blur(); void radialBlur(int angle, int divisions); + void shade(CustomShader* shader); void clear(); diff --git a/src/graphics/headers/plane.h b/src/graphics/headers/plane.h index 792cc8d4..20a05327 100644 --- a/src/graphics/headers/plane.h +++ b/src/graphics/headers/plane.h @@ -47,7 +47,7 @@ class Plane : public ViewportElement, public Disposable DECL_ATTR( BlendType, int ) DECL_ATTR( Color, Color& ) DECL_ATTR( Tone, Tone& ) - DECL_ATTR( WaterTime, float ) + DECL_ATTR( ShaderArr, VALUE ) void initDynAttribs(); diff --git a/src/graphics/headers/rb_shader.h b/src/graphics/headers/rb_shader.h new file mode 100644 index 00000000..f9900281 --- /dev/null +++ b/src/graphics/headers/rb_shader.h @@ -0,0 +1,48 @@ +#ifndef RB_SHADER_H +#define RB_SHADER_H + +#include "glstate.h" +#include "gl-util.h" +#include "binding-util.h" +#include "shader.h" +#include + +class CompiledShader : public ShaderBase +{ +public: + CompiledShader(const char *contents, VALUE args); + CompiledShader(const char *contents, VALUE args, const char *vertContents); + + const char *getContents(); + const char *getVertContents(); + GLuint getProgram(); + std::map getArgs(); + +private: + void setupShaderSource(const char *contents, GLuint shader, bool vert); + void compileShader(const char *contents, GLuint shader, GLuint program, bool vert); + void setupArgs(VALUE args); + + const char *contents; + const char *vertContents; + std::map args; +}; +class CustomShader +{ +public: + CustomShader(CompiledShader* shader, VALUE args, VALUE texUnits); + + void applyArgs(); + + GLint getUniform(const char *name); + bool supportsSpriteMat(); + void setSpriteMat(const float value[16]); + CompiledShader* getShader(); + +private: + CompiledShader* shader; + VALUE args; + VALUE texUnits; +}; + +#endif \ No newline at end of file diff --git a/src/graphics/headers/scene.h b/src/graphics/headers/scene.h index 34dde593..da5cdb0c 100644 --- a/src/graphics/headers/scene.h +++ b/src/graphics/headers/scene.h @@ -26,6 +26,7 @@ #include "intrulist.h" #include "etc.h" #include "etc-internal.h" +#include "binding-util.h" class SceneElement; class Viewport; @@ -58,13 +59,7 @@ class Scene virtual void requestViewportRender(const Vec4& /* color */, const Vec4& /* flash */, const Vec4& /* tone */, - const bool /* scanned */, - const Vec4 /* rbg */, - const Vec4 /* rbg */, - const Vec2 /* zoom */, - const float /* cubic */, - const float /* water */, - const float /* binary */) {} + const VALUE& /* shader arr */) {} const Geometry &getGeometry() const { return geometry; } diff --git a/src/graphics/headers/sprite.h b/src/graphics/headers/sprite.h index 805286f0..9ec3031c 100644 --- a/src/graphics/headers/sprite.h +++ b/src/graphics/headers/sprite.h @@ -27,6 +27,7 @@ #include "disposable.h" #include "viewport.h" #include "util.h" +#include "binding-util.h" class Bitmap; struct Color; @@ -45,6 +46,7 @@ class Sprite : public ViewportElement, public Flashable, public Disposable int getHeight() const; void update(); + void drawCustomShader(long i); DECL_ATTR( Bitmap, Bitmap* ) DECL_ATTR( SrcRect, Rect& ) @@ -55,7 +57,7 @@ class Sprite : public ViewportElement, public Flashable, public Disposable DECL_ATTR( ZoomX, float ) DECL_ATTR( ZoomY, float ) DECL_ATTR( Angle, float ) - DECL_ATTR( VMirror, bool ) + DECL_ATTR( VMirror, bool ) DECL_ATTR( Mirror, bool ) DECL_ATTR( BushDepth, int ) DECL_ATTR( BushOpacity, int ) @@ -68,7 +70,7 @@ class Sprite : public ViewportElement, public Flashable, public Disposable DECL_ATTR( WaveSpeed, int ) DECL_ATTR( WavePhase, float ) DECL_ATTR( Obscured, bool ) - DECL_ATTR( Scanned, bool ) + DECL_ATTR( ShaderArr, VALUE ) void initDynAttribs(); diff --git a/src/graphics/headers/viewport.h b/src/graphics/headers/viewport.h index f856a448..2b968bd5 100644 --- a/src/graphics/headers/viewport.h +++ b/src/graphics/headers/viewport.h @@ -25,6 +25,7 @@ #include "scene.h" #include "flashable.h" #include "disposable.h" +#include "binding-util.h" #include "util.h" struct ViewportPrivate; @@ -42,15 +43,9 @@ class Viewport : public Scene, public SceneElement, public Flashable, public Dis DECL_ATTR( Rect, Rect& ) DECL_ATTR( OX, int ) DECL_ATTR( OY, int ) - DECL_ATTR( Scanned, bool ) DECL_ATTR( Color, Color& ) DECL_ATTR( Tone, Tone& ) - DECL_ATTR( RGBOffsetx, Vec4 ) - DECL_ATTR( RGBOffsety, Vec4 ) - DECL_ATTR( CubicTime, float ) - DECL_ATTR( BinaryStrength, float ) - DECL_ATTR( WaterTime, float ) - DECL_ATTR( Zoom, Vec2 ) + DECL_ATTR( ShaderArr, VALUE ) void initDynAttribs(); diff --git a/src/graphics/source/bitmap.cpp b/src/graphics/source/bitmap.cpp index 0c31792f..f66c9401 100644 --- a/src/graphics/source/bitmap.cpp +++ b/src/graphics/source/bitmap.cpp @@ -44,6 +44,8 @@ #include "font.h" #include "eventthread.h" +#include "rb_shader.h" + #define GUARD_MEGA \ { \ if (p->megaSurface) \ @@ -609,49 +611,6 @@ void Bitmap::clearRect(const IntRect &rect) p->onModified(); } -void Bitmap::mask(Bitmap *mask, int x, int y) -{ - guardDisposed(); - - GUARD_MEGA; - - Quad &quad = shState->gpQuad(); - FloatRect rect(0, 0, width(), height()); - quad.setTexPosRect(rect, rect); - - TEXFBO auxTex = shState->texPool().request(width(), height()); - - MaskShader &shader = shState->shaders().mask; - - glState.blend.pushSet(false); - glState.viewport.pushSet(IntRect(0, 0, width(), height())); - - TEX::bind(p->gl.tex); - FBO::bind(auxTex.fbo); - - shader.bind(); - shader.setTexSize(Vec2i(width(), height())); - shader.setMaskTranslation(Vec2i(x, y)); - shader.setMaskCoords(Vec2i(mask->width(), mask->height())); - shader.setMask(mask->p->gl.tex); - shader.applyViewportProj(); - - quad.draw(); - - TEX::bind(auxTex.tex); - p->bindFBO(); - - quad.draw(); - - glState.viewport.pop(); - glState.blend.pop(); - - shState->texPool().release(auxTex); - - p->onModified(); -} - - void Bitmap::blur() { guardDisposed(); @@ -792,6 +751,36 @@ void Bitmap::radialBlur(int angle, int divisions) p->onModified(); } +void Bitmap::shade(CustomShader *shader) { + guardDisposed(); + + GUARD_MEGA; + + Quad &quad = shState->gpQuad(); + FloatRect rect(0, 0, width(), height()); + quad.setTexPosRect(rect, rect); + + glState.blend.pushSet(false); + glState.viewport.pushSet(IntRect(0, 0, width(), height())); + + TEX::bind(p->gl.tex); + p->bindFBO(); + + CompiledShader* compiled = shader->getShader(); + + compiled->bind(); + compiled->setTexSize(Vec2i(width(), height())); + compiled->applyViewportProj(); + shader->applyArgs(); + + quad.draw(); + + glState.viewport.pop(); + glState.blend.pop(); + + p->onModified(); +} + void Bitmap::clear() { guardDisposed(); diff --git a/src/graphics/source/graphics.cpp b/src/graphics/source/graphics.cpp index 797006fd..0ca7007d 100644 --- a/src/graphics/source/graphics.cpp +++ b/src/graphics/source/graphics.cpp @@ -45,21 +45,24 @@ #include #ifndef _MSC_VER -#include +// #include #endif #include #include -#define DEF_SCREEN_W (rgssVer == 1 ? 640 : 544) -#define DEF_SCREEN_H (rgssVer == 1 ? 480 : 416) -#define DEF_FRAMERATE (rgssVer == 1 ? 40 : 60) +#include "rb_shader.h" +#include "binding-types.h" + +#define DEF_SCREEN_W (rgssVer == 1 ? 640 : 544) +#define DEF_SCREEN_H (rgssVer == 1 ? 480 : 416) +#define DEF_FRAMERATE (rgssVer == 1 ? 40 : 60) #if defined _WIN32 - #define OS_W32 +#define OS_W32 #elif defined __APPLE__ - #define OS_OSX +#define OS_OSX #else - #define OS_LINUX +#define OS_LINUX #endif struct PingPong @@ -69,8 +72,8 @@ struct PingPong int screenW, screenH; PingPong(int screenW, int screenH) - : srcInd(0), dstInd(1), - screenW(screenW), screenH(screenH) + : srcInd(0), dstInd(1), + screenW(screenW), screenH(screenH) { for (int i = 0; i < 2; ++i) { @@ -144,7 +147,7 @@ class ScreenScene : public Scene { public: ScreenScene(int width, int height) - : pp(width, height) + : pp(width, height) { updateReso(width, height); @@ -178,22 +181,16 @@ class ScreenScene : public Scene } } - void requestViewportRender(const Vec4 &c, const Vec4 &f, const Vec4 &t, const bool s, const Vec4 rx, const Vec4 ry, const Vec2 z, const float cubic, const float water, const float binary) + void requestViewportRender(const Vec4 &c, const Vec4 &f, const Vec4 &t, const VALUE &shaderArr) { const IntRect &viewpRect = glState.scissorBox.get(); const IntRect &screenRect = geometry.rect; - const bool toneRGBEffect = t.xyzNotNull(); - const bool toneGrayEffect = t.w != 0 && !s; - const bool colorEffect = c.w > 0; - const bool flashEffect = f.w > 0; - const bool waterEffect = water != 0; - const bool cubicEffect = cubic != 0; - const bool rgbOffset = rx.xyzNotNull() || ry.xyzNotNull() && !toneGrayEffect && !s && !(z.x != 1 || z.y != 1) && !cubicEffect; - const bool scannedEffect = s && !t.w != 0 && !rgbOffset && !(z.x != 1 || z.y != 1) && !cubicEffect; - const bool zoomEffect = (z.x != 1 || z.y != 1) && !scannedEffect && !rgbOffset && !cubicEffect; - const bool binaryEffect = binary != 0; - + const bool toneRGBEffect = t.xyzNotNull(); + const bool toneGrayEffect = t.w != 0; + const bool colorEffect = c.w > 0; + const bool flashEffect = f.w > 0; + if (toneGrayEffect) { pp.swapRender(); @@ -226,194 +223,45 @@ class ScreenScene : public Scene glState.blend.pop(); } - if (binaryEffect) - { - pp.swapRender(); - - if (!viewpRect.encloses(screenRect)) - { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); - - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); - - glState.scissorTest.pop(); - } - - BinaryShader &shader = shState->shaders().binary; - shader.bind(); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); - - TEX::bind(pp.backBuffer().tex); - - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); - } - - if (scannedEffect) - { - pp.swapRender(); - - if (!viewpRect.encloses(screenRect)) - { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); - - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); - - glState.scissorTest.pop(); - } - - ScannedShader &shader = shState->shaders().scanned; - shader.bind(); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); - - TEX::bind(pp.backBuffer().tex); - - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); - } - - if (waterEffect) - { - pp.swapRender(); - - if (!viewpRect.encloses(screenRect)) - { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); - - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); - - glState.scissorTest.pop(); - } - - WaterShader &shader = shState->shaders().water; - shader.bind(); - shader.setiTime(water); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); - - TEX::bind(pp.backBuffer().tex); - - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); - } - - if (cubicEffect) + if (shaderArr) { - pp.swapRender(); + long size = rb_array_len(shaderArr); - if (!viewpRect.encloses(screenRect)) + for (long i = 0; i < size; i++) { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); - - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); - - glState.scissorTest.pop(); - } - - CubicShader &shader = shState->shaders().cubic; - shader.bind(); - shader.setiTime(cubic); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); - - TEX::bind(pp.backBuffer().tex); - - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); - } - - if (rgbOffset) - { - pp.swapRender(); - - if (!viewpRect.encloses(screenRect)) - { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); + VALUE value = rb_ary_entry(shaderArr, i); - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); + pp.swapRender(); - glState.scissorTest.pop(); - } + if (!viewpRect.encloses(screenRect)) + { + /* Scissor test _does_ affect FBO blit operations, + * and since we're inside the draw cycle, it will + * be turned on, so turn it off temporarily */ + glState.scissorTest.pushSet(false); - ChronosShader &shader = shState->shaders().chronos; - shader.bind(); - shader.setrgbOffset(rx, ry); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); + GLMeta::blitBegin(pp.frontBuffer()); + GLMeta::blitSource(pp.backBuffer()); + GLMeta::blitRectangle(geometry.rect, Vec2i()); + GLMeta::blitEnd(); - TEX::bind(pp.backBuffer().tex); + glState.scissorTest.pop(); + } - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); - } + CustomShader *shader = getPrivateDataCheck(value, CustomShaderType); + CompiledShader *compiled = shader->getShader(); - if (zoomEffect) - { - pp.swapRender(); + compiled->bind(); + compiled->applyViewportProj(); + shader->applyArgs(); + compiled->setTexSize(screenRect.size()); - if (!viewpRect.encloses(screenRect)) - { - /* Scissor test _does_ affect FBO blit operations, - * and since we're inside the draw cycle, it will - * be turned on, so turn it off temporarily */ - glState.scissorTest.pushSet(false); - - GLMeta::blitBegin(pp.frontBuffer()); - GLMeta::blitSource(pp.backBuffer()); - GLMeta::blitRectangle(geometry.rect, Vec2i()); - GLMeta::blitEnd(); + TEX::bind(pp.backBuffer().tex); - glState.scissorTest.pop(); + glState.blend.pushSet(false); + screenQuad.draw(); + glState.blend.pop(); } - - ZoomShader &shader = shState->shaders().zoom; - shader.bind(); - shader.setZoom(z); - shader.applyViewportProj(); - shader.setTexSize(screenRect.size()); - - TEX::bind(pp.backBuffer().tex); - - glState.blend.pushSet(false); - screenQuad.draw(); - glState.blend.pop(); } if (!toneRGBEffect && !colorEffect && !flashEffect) @@ -466,7 +314,7 @@ class ScreenScene : public Scene { gl.BlendEquation(GL_FUNC_ADD); gl.BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, - GL_ZERO, GL_ONE); + GL_ZERO, GL_ONE); } if (colorEffect) @@ -555,11 +403,11 @@ struct FPSLimiter } adj; FPSLimiter(uint16_t desiredFPS) - : lastTickCount(SDL_GetPerformanceCounter()), - tickFreq(SDL_GetPerformanceFrequency()), - tickFreqMS(tickFreq / 1000), - tickFreqNS((double) tickFreq / NS_PER_S), - disabled(false) + : lastTickCount(SDL_GetPerformanceCounter()), + tickFreq(SDL_GetPerformanceFrequency()), + tickFreqMS(tickFreq / 1000), + tickFreqNS((double)tickFreq / NS_PER_S), + disabled(false) { setDesiredFPS(desiredFPS); @@ -691,17 +539,17 @@ struct GraphicsPrivate TEX::ID obscuredTex; GraphicsPrivate(RGSSThreadData *rtData) - : scRes(DEF_SCREEN_W, DEF_SCREEN_H), - scSize(scRes), - winSize(rtData->config.defScreenW, rtData->config.defScreenH), - screen(scRes.x, scRes.y), - threadData(rtData), - glCtx(SDL_GL_GetCurrentContext()), - frameRate(DEF_FRAMERATE), - frameCount(0), - brightness(255), - fpsLimiter(frameRate), - frozen(false) + : scRes(DEF_SCREEN_W, DEF_SCREEN_H), + scSize(scRes), + winSize(rtData->config.defScreenW, rtData->config.defScreenH), + screen(scRes.x, scRes.y), + threadData(rtData), + glCtx(SDL_GL_GetCurrentContext()), + frameRate(DEF_FRAMERATE), + frameCount(0), + brightness(255), + fpsLimiter(frameRate), + frozen(false) { recalculateScreenSize(rtData); updateScreenResoRatio(rtData); @@ -730,8 +578,8 @@ struct GraphicsPrivate void updateScreenResoRatio(RGSSThreadData *rtData) { Vec2 &ratio = rtData->sizeResoRatio; - ratio.x = (float) scRes.x / scSize.x; - ratio.y = (float) scRes.y / scSize.y; + ratio.x = (float)scRes.x / scSize.x; + ratio.y = (float)scRes.y / scSize.y; rtData->screenOffset = scOffset; } @@ -747,8 +595,8 @@ struct GraphicsPrivate return; } - float resRatio = (float) scRes.x / scRes.y; - float winRatio = (float) winSize.x / winSize.y; + float resRatio = (float)scRes.x / scRes.y; + float winRatio = (float)winSize.x / winSize.y; if (resRatio > winRatio) scSize.y = scSize.x / resRatio; @@ -768,7 +616,7 @@ struct GraphicsPrivate recalculateScreenSize(threadData); updateScreenResoRatio(threadData); - SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y }; + SDL_Rect screen = {scOffset.x, scOffset.y, scSize.x, scSize.y}; threadData->ethread->notifyGameScreenChange(screen); } } @@ -811,8 +659,8 @@ struct GraphicsPrivate void metaBlitBufferFlippedScaled() { GLMeta::blitRectangle(IntRect(0, 0, scRes.x, scRes.y), - IntRect(scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y), - threadData->config.smoothScaling); + IntRect(scOffset.x, scSize.y + scOffset.y, scSize.x, -scSize.y), + threadData->config.smoothScaling); } void redrawScreen() @@ -928,8 +776,8 @@ void Graphics::freeze() } void Graphics::transition(int duration, - const char *filename, - int vague) + const char *filename, + int vague) { p->checkSyncLock(); @@ -949,7 +797,7 @@ void Graphics::transition(int duration, * the transition, we can reuse it as the target buffer for * the final rendered image. */ TEXFBO ¤tScene = p->screen.getPP().frontBuffer(); - TEXFBO &transBuffer = p->screen.getPP().backBuffer(); + TEXFBO &transBuffer = p->screen.getPP().backBuffer(); /* If no transition bitmap is provided, * we can use a simplified shader */ @@ -1017,9 +865,10 @@ void Graphics::transition(int duration, simpleShader.setProg(prog); } - #ifndef OS_LINUX - if (p->threadData->exiting) SDL_SetWindowOpacity(p->threadData->window, 1.0f - prog); - #endif +#ifndef OS_LINUX + if (p->threadData->exiting) + SDL_SetWindowOpacity(p->threadData->window, 1.0f - prog); +#endif /* Draw the composed frame to a buffer first * (we need this because we're skipping PingPong) */ @@ -1088,7 +937,7 @@ void Graphics::fadeout(int duration) float curr = p->brightness; float diff = 255.0f - curr; - for (int i = duration-1; i > -1; --i) + for (int i = duration - 1; i > -1; --i) { setBrightness(diff + (curr / duration) * i); @@ -1165,8 +1014,8 @@ int Graphics::height() const void Graphics::resizeScreen(int width, int height) { - width = width; //clamp(width, 1, ); - height = height; //clamp(height, 1, 480); + width = width; // clamp(width, 1, ); + height = height; // clamp(height, 1, 480); Vec2i size(width, height); @@ -1209,8 +1058,8 @@ void Graphics::reset() IntruListLink *iter; for (iter = p->dispList.begin(); - iter != p->dispList.end(); - iter = iter->next) + iter != p->dispList.end(); + iter = iter->next) { iter->data->dispose(); } diff --git a/src/graphics/source/plane.cpp b/src/graphics/source/plane.cpp index 86471219..026cf451 100644 --- a/src/graphics/source/plane.cpp +++ b/src/graphics/source/plane.cpp @@ -35,6 +35,10 @@ #include "shader.h" #include "glstate.h" +#include "binding-util.h" +#include "rb_shader.h" +#include "binding-types.h" + #include static float fwrap(float value, float range) @@ -57,8 +61,6 @@ struct PlanePrivate int ox, oy; float zoomX, zoomY; - float waterTime; - Scene::Geometry sceneGeo; bool quadSourceDirty; @@ -70,6 +72,8 @@ struct PlanePrivate sigc::connection prepareCon; sigc::connection srcRectCon; + VALUE shaderArr; + PlanePrivate() : bitmap(0), srcRect(&tmp.rect), @@ -80,7 +84,7 @@ struct PlanePrivate ox(0), oy(0), zoomX(1), zoomY(1), quadSourceDirty(false), - waterTime(0.0) + shaderArr(0) { updateSrcRectCon(); prepareCon = shState->prepareDraw.connect @@ -189,7 +193,7 @@ DEF_ATTR_SIMPLE(Plane, SrcRect, Rect&, *p->srcRect) DEF_ATTR_SIMPLE(Plane, Opacity, int, p->opacity) DEF_ATTR_SIMPLE(Plane, Color, Color&, *p->color) DEF_ATTR_SIMPLE(Plane, Tone, Tone&, *p->tone) -DEF_ATTR_SIMPLE(Plane, WaterTime, float, p->waterTime) +DEF_ATTR_SIMPLE(Plane, ShaderArr, VALUE, p->shaderArr) Plane::~Plane() { @@ -293,17 +297,7 @@ void Plane::draw() ShaderBase *base; - if (p->waterTime != 0) - { - WaterShader &shader = shState->shaders().water; - shader.bind(); - shader.applyViewportProj(); - shader.setiTime(p->waterTime); - shader.setOpacity(p->opacity.norm); - - base = &shader; - } - else if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255) + if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255) { PlaneShader &shader = shState->shaders().plane; @@ -327,6 +321,23 @@ void Plane::draw() base = &shader; } + if (p->shaderArr) { + long size = rb_array_len(p->shaderArr); + + for (long i = 0; i < size; i++) { + VALUE value = rb_ary_entry(p->shaderArr, i); + + CustomShader* shader = getPrivateDataCheck(value, CustomShaderType); + CompiledShader* compiled = shader->getShader(); + + compiled->bind(); + compiled->applyViewportProj(); + shader->applyArgs(); + + base = compiled; + } + } + glState.blendMode.pushSet(p->blendType); p->bitmap->bindTex(*base); diff --git a/src/graphics/source/rb_shader.cpp b/src/graphics/source/rb_shader.cpp new file mode 100644 index 00000000..ef622bd0 --- /dev/null +++ b/src/graphics/source/rb_shader.cpp @@ -0,0 +1,232 @@ +#include "rb_shader.h" +#include "glstate.h" +#include "gl-util.h" +#include "binding-util.h" +#include "sharedstate.h" +#include "shader.h" +#include "rb_simple.vert.xxd" +#include "bitmap.h" + +#include +#include + +CompiledShader::CompiledShader(const char *contents, VALUE args) : contents(contents), + vertContents((const char *)___shader_rb_simple_vert) +{ + fragShader = gl.CreateShader(GL_FRAGMENT_SHADER); + vertShader = gl.CreateShader(GL_VERTEX_SHADER); + + program = gl.CreateProgram(); + + compileShader(contents, fragShader, program, false); + compileShader(vertContents, vertShader, program, true); + setupArgs(args); + + ShaderBase::init(); +} + +CompiledShader::CompiledShader(const char *contents, VALUE args, const char *vertContents) : contents(contents), + vertContents(vertContents) +{ + fragShader = gl.CreateShader(GL_FRAGMENT_SHADER); + vertShader = gl.CreateShader(GL_VERTEX_SHADER); + + program = gl.CreateProgram(); + + compileShader(contents, fragShader, program, false); + compileShader(vertContents, vertShader, program, true); + setupArgs(args); + + ShaderBase::init(); +} + +std::string getShaderLog(GLuint shader) +{ + GLint logLength; + gl.GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + + std::string log(logLength, '\0'); + gl.GetShaderInfoLog(shader, log.size(), 0, &log[0]); + + return log; +} + +void CompiledShader::setupShaderSource(const char *contents, GLuint shader, bool vert) +{ + static const char glesDefine[] = "#define GLSLES\n"; + static const char fragDefine[] = "#define FRAGMENT_SHADER\n"; + + const GLchar *shaderSrc[3]; + GLint shaderSrcSize[3]; + size_t i = 0; + + if (gl.glsles) + { + shaderSrc[i] = glesDefine; + shaderSrcSize[i] = sizeof(glesDefine) - 1; + ++i; + } + + if (!vert) + { + shaderSrc[i] = fragDefine; + shaderSrcSize[i] = sizeof(fragDefine) - 1; + ++i; + } + + shaderSrc[i] = (const GLchar *)contents; + shaderSrcSize[i] = strlen(contents); + ++i; + + gl.ShaderSource(shader, i, shaderSrc, shaderSrcSize); +} + +void CompiledShader::compileShader(const char *contents, GLuint shader, GLuint program, bool vert) +{ + GLint success; + + setupShaderSource(contents, shader, vert); + gl.CompileShader(shader); + + gl.GetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) + { + rb_raise(rb_eRuntimeError, "Shader compilation failed with: \n%s", getShaderLog(shader).c_str()); + return; + } + + gl.AttachShader(program, shader); + + gl.BindAttribLocation(program, Position, "position"); + gl.BindAttribLocation(program, TexCoord, "texCoord"); + gl.BindAttribLocation(program, Color, "color"); + + gl.LinkProgram(program); + + gl.GetProgramiv(program, GL_LINK_STATUS, &success); + + if (!success) + { + rb_raise(rb_eRuntimeError, "Shader linking failed with: \n%s", getShaderLog(program).c_str()); + return; + } +} + +void CompiledShader::setupArgs(VALUE pargs) +{ + long argc = rb_array_len(pargs); + args = std::map(); + + for (long i = 0; i < argc; ++i) + { + VALUE arg = rb_ary_entry(pargs, i); + const char *name = rb_string_value_cstr(&arg); + args[name] = gl.GetUniformLocation(program, name); + } +} + +const char *CompiledShader::getContents() +{ + return contents; +} + +const char *CompiledShader::getVertContents() +{ + return vertContents; +} + +std::map CompiledShader::getArgs() +{ + return args; +} + +GLuint CompiledShader::getProgram() +{ + return program; +} + +CustomShader::CustomShader(CompiledShader *shader, VALUE args, VALUE texUnits) : shader(shader), + args(args), texUnits(texUnits) +{ +} + +GLint CustomShader::getUniform(const char *name) +{ + return gl.GetUniformLocation(shader->getProgram(), name); +} + +bool CustomShader::supportsSpriteMat() +{ + return getUniform("spriteMat") != -1; +} + +void CustomShader::setSpriteMat(const float value[16]) +{ + gl.UniformMatrix4fv(getUniform("spriteMat"), 1, GL_FALSE, value); +} + +#define IS_A(klass) if ( \ + rb_obj_is_kind_of( \ + value, \ + rb_path2class(klass))) + +void CustomShader::applyArgs() +{ + std::map args = shader->getArgs(); + std::map::iterator it; + for (it = args.begin(); it != args.end(); it++) + { + VALUE value = rb_hash_aref(this->args, rb_str_new_cstr(it->first)); + + if (value == Qnil) + rb_raise(rb_eIndexError, "No such argument: %s", it->first); + + if (it->second == -1) + rb_raise(rb_eIndexError, "No such uniform declared in shader: %s", it->first); + + IS_A("Float") + { + gl.Uniform1f(it->second, NUM2DBL(value)); + } + else IS_A("Integer") + { + gl.Uniform1i(it->second, NUM2INT(value)); + } + else IS_A("Vec2") + { + Vec2 *vec2 = getPrivateData(value); + gl.Uniform2f(it->second, vec2->x, vec2->y); + } + else IS_A("Vec4") + { + Vec4 *vec4 = getPrivateData(value); + gl.Uniform4f(it->second, vec4->x, vec4->y, vec4->z, vec4->w); + } + else IS_A("Bitmap") + { + VALUE unitObj = rb_hash_fetch(texUnits, rb_str_new_cstr(it->first)); + + if (unitObj == Qnil) + rb_raise(rb_eIndexError, "No such texture unit: %s, please supply this when creating the shader", it->first); + + unsigned unitNum = NUM2UINT(unitObj); + Bitmap *bitmap = getPrivateData(value); + + GLenum texUnit = GL_TEXTURE0 + unitNum; + + gl.ActiveTexture(texUnit); + gl.BindTexture(GL_TEXTURE_2D, bitmap->getGLTypes().tex.gl); + gl.Uniform1i(it->second, unitNum); + gl.ActiveTexture(GL_TEXTURE0); + } + else + { + rb_raise(rb_eArgError, "Argument %s is of type %s, which is not a supported type", it->first, rb_obj_classname(value)); + } + } +} + +CompiledShader *CustomShader::getShader() +{ + return shader; +} \ No newline at end of file diff --git a/src/graphics/source/sprite.cpp b/src/graphics/source/sprite.cpp index 1f0c2d60..7a4d4efb 100644 --- a/src/graphics/source/sprite.cpp +++ b/src/graphics/source/sprite.cpp @@ -42,8 +42,14 @@ #include +#include "binding-util.h" + +#include "rb_shader.h" +#include "binding-types.h" +#include "texpool.h" + #ifndef M_PI - #define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif struct SpritePrivate @@ -72,11 +78,12 @@ struct SpritePrivate bool isVisible; bool obscured; - bool scanned; Color *color; Tone *tone; + VALUE shaderArr; + struct { int amp; @@ -96,28 +103,27 @@ struct SpritePrivate sigc::connection prepareCon; SpritePrivate() - : bitmap(0), - srcRect(&tmp.rect), - vmirrored(false), + : bitmap(0), + srcRect(&tmp.rect), + vmirrored(false), mirrored(false), - bushDepth(0), - efBushDepth(0), - bushOpacity(128), - opacity(255), - blendType(BlendNormal), - isVisible(false), - obscured(false), - scanned(false), - color(&tmp.color), - tone(&tmp.tone) + bushDepth(0), + efBushDepth(0), + bushOpacity(128), + opacity(255), + blendType(BlendNormal), + isVisible(false), + obscured(false), + color(&tmp.color), + tone(&tmp.tone), + shaderArr(0) { sceneRect.x = sceneRect.y = 0; updateSrcRectCon(); - prepareCon = shState->prepareDraw.connect - (sigc::mem_fun(this, &SpritePrivate::prepare)); + prepareCon = shState->prepareDraw.connect(sigc::mem_fun(this, &SpritePrivate::prepare)); wave.amp = 0; wave.length = 180; @@ -139,18 +145,20 @@ struct SpritePrivate /* Calculate effective (normalized) bush depth */ float texBushDepth = (bushDepth / trans.getScale().y) - - (srcRect->y + srcRect->height) + - bitmap->height(); + (srcRect->y + srcRect->height) + + bitmap->height(); efBushDepth = 1.0f - texBushDepth / bitmap->height(); } FloatRect getMirroredTexRect(FloatRect texrect) { - if (mirrored) { + if (mirrored) + { texrect = texrect.hFlipped(); } - if (vmirrored) { + if (vmirrored) + { texrect = texrect.vFlipped(); } return texrect; @@ -166,8 +174,8 @@ struct SpritePrivate /* Clamp the rectangle so it doesn't reach outside * the bitmap bounds */ - rect.w = clamp(rect.w, 0, bmSize.x-rect.x); - rect.h = clamp(rect.h, 0, bmSize.y-rect.y); + rect.w = clamp(rect.w, 0, bmSize.x - rect.x); + rect.h = clamp(rect.h, 0, bmSize.y - rect.y); quad.setTexRect(getMirroredTexRect(rect)); @@ -182,8 +190,7 @@ struct SpritePrivate /* Cut old connection */ srcRectCon.disconnect(); /* Create new one */ - srcRectCon = srcRect->valueChanged.connect - (sigc::mem_fun(this, &SpritePrivate::onSrcRectChange)); + srcRectCon = srcRect->valueChanged.connect(sigc::mem_fun(this, &SpritePrivate::onSrcRectChange)); } void updateVisibility() @@ -224,17 +231,20 @@ struct SpritePrivate } void emitWaveChunk(SVertex *&vert, float phase, int width, - float zoomY, int chunkY, int chunkLength) + float zoomY, int chunkY, int chunkLength) { - float wavePos = phase + (chunkY / (float) wave.length) * (float) (M_PI * 2); + float wavePos = phase + (chunkY / (float)wave.length) * (float)(M_PI * 2); float chunkX = sin(wavePos) * wave.amp; FloatRect tex = getMirroredTexRect(srcRect->toFloatRect()); // note: width is ignored, we're using the mirrored srcRect (the original width is from srcRect anyway) - if (tex.h < 0) { // texture itself is vflipped + if (tex.h < 0) + { // texture itself is vflipped tex.y -= chunkY / zoomY; tex.h = -chunkLength / zoomY; - } else { + } + else + { tex.y += chunkY / zoomY; tex.h = chunkLength / zoomY; } @@ -289,7 +299,7 @@ struct SpritePrivate int visibleLength = height * zoomY; /* First chunk length (aligned to 8 pixel boundary */ - int firstLength = ((int) trans.getPosition().y) % 8; + int firstLength = ((int)trans.getPosition().y) % 8; /* Amount of full 8 pixel chunks in the middle */ int chunks = (visibleLength - firstLength) / 8; @@ -300,7 +310,7 @@ struct SpritePrivate wave.qArray.resize(!!firstLength + chunks + !!lastLength); SVertex *vert = &wave.qArray.vertices[0]; - float phase = (wave.phase * (float) M_PI) / 180.0f; + float phase = (wave.phase * (float)M_PI) / 180.0f; if (firstLength > 0) emitWaveChunk(vert, phase, width, zoomY, 0, firstLength); @@ -327,7 +337,7 @@ struct SpritePrivate }; Sprite::Sprite(Viewport *viewport) - : ViewportElement(viewport) + : ViewportElement(viewport) { p = new SpritePrivate; onGeometryChange(scene->getGeometry()); @@ -338,32 +348,32 @@ Sprite::~Sprite() dispose(); } -DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap) -DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x) -DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y) -DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x) -DEF_ATTR_RD_SIMPLE(Sprite, OY, int, p->trans.getOrigin().y) -DEF_ATTR_RD_SIMPLE(Sprite, ZoomX, float, p->trans.getScale().x) -DEF_ATTR_RD_SIMPLE(Sprite, ZoomY, float, p->trans.getScale().y) -DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation()) -DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored) -DEF_ATTR_RD_SIMPLE(Sprite, VMirror, bool, p->vmirrored) -DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth) -DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType) -DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width) -DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height) -DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp) -DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length) -DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed) -DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) - -DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity) -DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity) -DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect&, *p->srcRect) -DEF_ATTR_SIMPLE(Sprite, Color, Color&, *p->color) -DEF_ATTR_SIMPLE(Sprite, Tone, Tone&, *p->tone) -DEF_ATTR_SIMPLE(Sprite, Obscured, bool, p->obscured) -DEF_ATTR_SIMPLE(Sprite, Scanned, bool, p->scanned) +DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap *, p->bitmap) +DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x) +DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y) +DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x) +DEF_ATTR_RD_SIMPLE(Sprite, OY, int, p->trans.getOrigin().y) +DEF_ATTR_RD_SIMPLE(Sprite, ZoomX, float, p->trans.getScale().x) +DEF_ATTR_RD_SIMPLE(Sprite, ZoomY, float, p->trans.getScale().y) +DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation()) +DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored) +DEF_ATTR_RD_SIMPLE(Sprite, VMirror, bool, p->vmirrored) +DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth) +DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType) +DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width) +DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height) +DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp) +DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length) +DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed) +DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) + +DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity) +DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity) +DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect &, *p->srcRect) +DEF_ATTR_SIMPLE(Sprite, Color, Color &, *p->color) +DEF_ATTR_SIMPLE(Sprite, Tone, Tone &, *p->tone) +DEF_ATTR_SIMPLE(Sprite, Obscured, bool, p->obscured) +DEF_ATTR_SIMPLE(Sprite, ShaderArr, VALUE, p->shaderArr) void Sprite::setBitmap(Bitmap *bitmap) { @@ -469,7 +479,7 @@ void Sprite::setVMirror(bool vmirrored) return; p->vmirrored = vmirrored; - p->onSrcRectChange(); + p->onSrcRectChange(); } void Sprite::setMirror(bool mirrored) { @@ -499,33 +509,33 @@ void Sprite::setBlendType(int type) switch (type) { - default : - case BlendNormal : + default: + case BlendNormal: p->blendType = BlendNormal; return; - case BlendAddition : + case BlendAddition: p->blendType = BlendAddition; return; - case BlendSubstraction : + case BlendSubstraction: p->blendType = BlendSubstraction; return; } } -#define DEF_WAVE_SETTER(Name, name, type) \ +#define DEF_WAVE_SETTER(Name, name, type) \ void Sprite::setWave##Name(type value) \ - { \ - guardDisposed(); \ - if (p->wave.name == value) \ - return; \ - p->wave.name = value; \ - p->wave.dirty = true; \ + { \ + guardDisposed(); \ + if (p->wave.name == value) \ + return; \ + p->wave.name = value; \ + p->wave.dirty = true; \ } -DEF_WAVE_SETTER(Amp, amp, int) +DEF_WAVE_SETTER(Amp, amp, int) DEF_WAVE_SETTER(Length, length, int) -DEF_WAVE_SETTER(Speed, speed, int) -DEF_WAVE_SETTER(Phase, phase, float) +DEF_WAVE_SETTER(Speed, speed, int) +DEF_WAVE_SETTER(Phase, phase, float) #undef DEF_WAVE_SETTER @@ -549,6 +559,23 @@ void Sprite::update() p->wave.dirty = true; } +void Sprite::drawCustomShader(long i) +{ + VALUE value = rb_ary_entry(p->shaderArr, i); + + CustomShader *shader = getPrivateDataCheck(value, CustomShaderType); + CompiledShader *compiled = shader->getShader(); + + compiled->bind(); + compiled->applyViewportProj(); + shader->applyArgs(); + + compiled->setTexSize(Vec2i( + p->bitmap->width(), p->bitmap->height())); + + p->quad.draw(); +} + /* SceneElement */ void Sprite::draw() { @@ -561,9 +588,44 @@ void Sprite::draw() ShaderBase *base; bool renderEffect = p->color->hasEffect() || - p->tone->hasEffect() || - flashing || - p->bushDepth != 0; + p->tone->hasEffect() || + flashing || + p->bushDepth != 0; + + TEX::bind( + p->bitmap->getGLTypes().tex); + + TEXFBO auxTex; + bool destroyAuxTex = false; + if (p->shaderArr) + { + long size = rb_array_len(p->shaderArr); + + if (size > 0) + { + auxTex = shState->texPool().request( + p->bitmap->width(), p->bitmap->height()); + destroyAuxTex = true; + + glState.blend.pushSet(false); + glState.viewport.pushSet(IntRect(0, 0, p->bitmap->width(), p->bitmap->height())); + + FBO::bind(auxTex.fbo); + // FBO::setTarget(auxTex.tex); + + drawCustomShader(0); + + TEX::bind(auxTex.tex); + + for (long i = 1; i < size; i++) + { + drawCustomShader(i); + } + + glState.viewport.pop(); + glState.blend.pop(); + } + } if (p->obscured) { @@ -573,15 +635,6 @@ void Sprite::draw() shader.setObscured(shState->graphics().obscuredTex()); base = &shader; } - else if (p->scanned) - { - ScannedShaderSprite &shader = shState->shaders().scanned_sprite; - shader.bind(); - shader.applyViewportProj(); - shader.setSpriteMat(p->trans.getMatrix()); - - base = &shader; - } else if (renderEffect) { SpriteShader &shader = shState->shaders().sprite; @@ -597,8 +650,7 @@ void Sprite::draw() /* When both flashing and effective color are set, * the one with higher alpha will be blended */ - const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ? - &flashColor : &p->color->norm; + const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ? &flashColor : &p->color->norm; shader.setColor(*blend); @@ -624,9 +676,10 @@ void Sprite::draw() base = &shader; } - glState.blendMode.pushSet(p->blendType); + base->setTexSize(Vec2i( + p->bitmap->width(), p->bitmap->height())); - p->bitmap->bindTex(*base); + glState.blendMode.pushSet(p->blendType); if (p->wave.active) p->wave.qArray.draw(); @@ -634,6 +687,9 @@ void Sprite::draw() p->quad.draw(); glState.blendMode.pop(); + + if (destroyAuxTex) + shState->texPool().release(auxTex); } void Sprite::onGeometryChange(const Scene::Geometry &geo) diff --git a/src/graphics/source/viewport.cpp b/src/graphics/source/viewport.cpp index 898cfc37..0a947fb1 100644 --- a/src/graphics/source/viewport.cpp +++ b/src/graphics/source/viewport.cpp @@ -27,6 +27,8 @@ #include "quad.h" #include "glstate.h" #include "graphics.h" +#include "binding-util.h" +#include "debugwriter.h" #include @@ -46,36 +48,19 @@ struct ViewportPrivate IntRect screenRect; int isOnScreen; - bool scanned; - - Vec4 rgbOffsetx; - Vec4 rgbOffsety; - - float cubicTime; - - float waterTime; - - float binaryStrength; - - Vec2 zoom; - EtcTemps tmp; + VALUE shaderArr; + ViewportPrivate(int x, int y, int width, int height, Viewport *self) : self(self), rect(&tmp.rect), color(&tmp.color), tone(&tmp.tone), - isOnScreen(false), - scanned(false), - rgbOffsetx(Vec4(0, 0, 0, 0)), - rgbOffsety(Vec4(0, 0, 0, 0)), - cubicTime(0.0), - waterTime(0.0), - binaryStrength(0.0), - zoom(Vec2(1.0, 1.0)) + isOnScreen(false) { rect->set(x, y, width, height); + shaderArr = 0; updateRectCon(); } @@ -112,8 +97,14 @@ struct ViewportPrivate bool needsEffectRender(bool flashing) { + if (shaderArr) { + if (rb_array_len(shaderArr) > 0) { + return true; + } + } + bool rectEffective = !rect->isEmpty(); - bool colorToneEffective = color->hasEffect() || tone->hasEffect() || flashing || scanned || rgbOffsetx.xyzNotNull() || rgbOffsety.xyzNotNull() || zoom.x != 1 || zoom.y != 1 || cubicTime != 0.0 || waterTime != 0.0 || binaryStrength != 0.0; + bool colorToneEffective = color->hasEffect() || tone->hasEffect() || flashing; return (rectEffective && colorToneEffective && isOnScreen); } @@ -170,13 +161,7 @@ DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.orig.y) DEF_ATTR_SIMPLE(Viewport, Rect, Rect&, *p->rect) DEF_ATTR_SIMPLE(Viewport, Color, Color&, *p->color) DEF_ATTR_SIMPLE(Viewport, Tone, Tone&, *p->tone) -DEF_ATTR_SIMPLE(Viewport, Scanned, bool, p->scanned) -DEF_ATTR_SIMPLE(Viewport, CubicTime, float, p->cubicTime) -DEF_ATTR_SIMPLE(Viewport, BinaryStrength, float, p->binaryStrength) -DEF_ATTR_SIMPLE(Viewport, WaterTime, float, p->waterTime) -DEF_ATTR_SIMPLE(Viewport, RGBOffsetx, Vec4, p->rgbOffsetx) -DEF_ATTR_SIMPLE(Viewport, RGBOffsety, Vec4, p->rgbOffsety) -DEF_ATTR_SIMPLE(Viewport, Zoom, Vec2, p->zoom) +DEF_ATTR_SIMPLE(Viewport, ShaderArr, VALUE, p->shaderArr) void Viewport::setOX(int value) { @@ -230,7 +215,7 @@ void Viewport::composite() * render them. */ if (renderEffect) scene->requestViewportRender - (p->color->norm, flashColor, p->tone->norm, p->scanned, p->rgbOffsetx, p->rgbOffsety, p->zoom, p->cubicTime, p->waterTime, p->binaryStrength); + (p->color->norm, flashColor, p->tone->norm, p->shaderArr); glState.scissorBox.pop(); glState.scissorTest.pop(); diff --git a/src/meson.build b/src/meson.build index 80793e0c..11c0e806 100644 --- a/src/meson.build +++ b/src/meson.build @@ -110,15 +110,16 @@ main_source = files( 'filesystem/source/rgssad.cpp', 'graphics/source/autotiles.cpp', 'graphics/source/bitmap.cpp', - 'graphics/source/graphics.cpp', 'graphics/source/font.cpp', + 'graphics/source/graphics.cpp', + 'graphics/source/plane.cpp', + 'graphics/source/rb_shader.cpp', 'graphics/source/sprite.cpp', 'graphics/source/scene.cpp', 'graphics/source/tilemap.cpp', 'graphics/source/tileatlas.cpp', 'graphics/source/window.cpp', 'graphics/source/viewport.cpp', - 'graphics/source/plane.cpp', 'input/source/input.cpp', 'input/source/keybindings.cpp', 'input/source/settingsmenu.cpp', diff --git a/src/oneshot/source/oneshot.cpp b/src/oneshot/source/oneshot.cpp index 31ee6523..45703fe8 100644 --- a/src/oneshot/source/oneshot.cpp +++ b/src/oneshot/source/oneshot.cpp @@ -16,7 +16,9 @@ // OS-Specific code #if defined _WIN32 #define OS_W32 - //#define WIN32_LEAN_AND_MEAN + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif #define SECURITY_WIN32 #include #include diff --git a/src/opengl/headers/gl-util.h b/src/opengl/headers/gl-util.h index 2ca8ece7..c82919ce 100644 --- a/src/opengl/headers/gl-util.h +++ b/src/opengl/headers/gl-util.h @@ -125,6 +125,7 @@ namespace FBO static inline void bind(ID id) { gl.BindFramebuffer(GL_FRAMEBUFFER, id.gl); + // std::cout << "FBO bound: " << id.gl << std::endl; } static inline void unbind() diff --git a/src/opengl/headers/shader.h b/src/opengl/headers/shader.h index 5c16d529..25f9a7fe 100644 --- a/src/opengl/headers/shader.h +++ b/src/opengl/headers/shader.h @@ -316,94 +316,6 @@ class ObscuredShader : public ShaderBase GLint u_obscured; }; -class MaskShader : public ShaderBase -{ -public: - MaskShader(); - - void setMask(const TEX::ID value); - void setMaskCoords(const Vec2i value); - void setMaskTranslation(const Vec2i value); - -private: - GLint u_maskTex; - GLint u_maskTexCoords; - GLint u_maskTranslation; -}; - -class ScannedShader : public ShaderBase -{ -public: - ScannedShader(); -}; - -class ScannedShaderSprite : public ShaderBase -{ -public: - ScannedShaderSprite(); - - void setSpriteMat(const float value[16]); - -private: - GLint u_spriteMat; -}; - -class ChronosShader : public ShaderBase -{ -public: - ChronosShader(); - - void setrgbOffset(const Vec4 rx, const Vec4 ry); - -private: - GLint u_rgbOffsetx; - GLint u_rgbOffsety; -}; - -class ZoomShader : public ShaderBase -{ -public: - ZoomShader(); - - void setZoom(const Vec2 zoom); - -private: - GLint u_zoom; -}; - -class CubicShader : public ShaderBase -{ -public: - CubicShader(); - - void setiTime(const float value); - -private: - GLint u_iTime; -}; - -class WaterShader : public ShaderBase -{ -public: - WaterShader(); - - void setiTime(const float value); - void setOpacity(const float opacity); - -private: - GLint u_iTime, u_opacity; -}; - -class BinaryShader : public ShaderBase -{ -public: - BinaryShader(); - - void setStrength(const float value); -private: - GLint u_strength; -}; - /* Global object containing all available shaders */ struct ShaderSet @@ -426,14 +338,6 @@ struct ShaderSet SimpleMatrixShader simpleMatrix; BlurShader blur; ObscuredShader obscured; - MaskShader mask; - ScannedShader scanned; - ScannedShaderSprite scanned_sprite; - ChronosShader chronos; - ZoomShader zoom; - CubicShader cubic; - WaterShader water; - BinaryShader binary; }; #endif // SHADER_H diff --git a/src/opengl/source/shader.cpp b/src/opengl/source/shader.cpp index 25199014..cf704427 100644 --- a/src/opengl/source/shader.cpp +++ b/src/opengl/source/shader.cpp @@ -52,16 +52,6 @@ #include "blurH.vert.xxd" #include "blurV.vert.xxd" #include "obscured.frag.xxd" -#include "mask.frag.xxd" -#include "mask.vert.xxd" -#include "crt.frag.xxd" -#include "crt_sprite.frag.xxd" -#include "cubic_lens.frag.xxd" -#include "water.frag.xxd" -#include "binary_glitch.frag.xxd" -#include "chronos.frag.xxd" -#include "zoom.vert.xxd" - #define INIT_SHADER(vert, frag, name) \ { \ @@ -647,129 +637,4 @@ ObscuredShader::ObscuredShader() void ObscuredShader::setObscured(const TEX::ID value) { setTexUniform(u_obscured, 1, value); -} - -MaskShader::MaskShader() -{ - INIT_SHADER(mask, mask, MaskShader); - - ShaderBase::init(); - - GET_U(maskTex); - GET_U(maskTexCoords); - GET_U(maskTranslation); -} - -void MaskShader::setMask(const TEX::ID value) -{ - setTexUniform(u_maskTex, 1, value); -} - -void MaskShader::setMaskCoords(const Vec2i value) -{ - setVec2Uniform(u_maskTexCoords, value); -} - -void MaskShader::setMaskTranslation(const Vec2i value) -{ - setVec2Uniform(u_maskTranslation, value); -} - -ScannedShader::ScannedShader() -{ - INIT_SHADER(simple, crt, ScannedShader); - - ShaderBase::init(); -} - -ScannedShaderSprite::ScannedShaderSprite() -{ - INIT_SHADER(sprite, crt_sprite, ScannedShaderSprite); - - ShaderBase::init(); - - GET_U(spriteMat); -} - -void ScannedShaderSprite::setSpriteMat(const float value[16]) -{ - gl.UniformMatrix4fv(u_spriteMat, 1, GL_FALSE, value); -} - -ChronosShader::ChronosShader() -{ - INIT_SHADER(simple, chronos, ChronosShader); - - ShaderBase::init(); - - GET_U(rgbOffsetx); - GET_U(rgbOffsety); -} - -void ChronosShader::setrgbOffset(const Vec4 ox, const Vec4 oy) -{ - gl.Uniform4f(u_rgbOffsetx, ox.x, ox.y, ox.z, 0); - gl.Uniform4f(u_rgbOffsety, oy.x, oy.y, oy.z, 0); -} - -ZoomShader::ZoomShader() -{ - INIT_SHADER(zoom, simple, ZoomShader); - - ShaderBase::init(); - - GET_U(zoom); -} - -void ZoomShader::setZoom(const Vec2 zoom) -{ - gl.Uniform2f(u_zoom, zoom.x, zoom.y); -} - -CubicShader::CubicShader() -{ - INIT_SHADER(simple, cubic_lens, CubicShader); - - ShaderBase::init(); - - GET_U(iTime); -} - -void CubicShader::setiTime(const float value) -{ - gl.Uniform1f(u_iTime, value); -} - -WaterShader::WaterShader() -{ - INIT_SHADER(simple, water, WaterShader); - - ShaderBase::init(); - - GET_U(iTime); - GET_U(opacity); -} - -void WaterShader::setiTime(const float value) -{ - gl.Uniform1f(u_iTime, value); -} - -void WaterShader::setOpacity(const float value) -{ - gl.Uniform1f(u_opacity, value); -} - -BinaryShader::BinaryShader() -{ - INIT_SHADER(simple, binary_glitch, BinaryShader); - - ShaderBase::init(); - - GET_U(strength); -} - -void BinaryShader::setStrength(const float value) -{ - gl.Uniform1f(u_strength, value); } \ No newline at end of file diff --git a/src/rgss/headers/etc-internal.h b/src/rgss/headers/etc-internal.h index e0b17a1b..8be743b1 100644 --- a/src/rgss/headers/etc-internal.h +++ b/src/rgss/headers/etc-internal.h @@ -42,6 +42,18 @@ struct Vec2 { return (x == other.x && y == other.y); } + + float getX() const { return x; } + float getY() const { return y; } + + void setX(float x) { this->x = x; } + void setY(float y) { this->y = y; } + + void set(float x, float y) + { + this->x = x; + this->y = y; + } }; struct Vec4 @@ -65,6 +77,24 @@ struct Vec4 { return (x != 0.0f || y != 0.0f || z != 0.0f); } + + float getX() const { return x; } + float getY() const { return y; } + float getZ() const { return z; } + float getW() const { return w; } + + void setX(float x) { this->x = x; } + void setY(float y) { this->y = y; } + void setZ(float z) { this->z = z; } + void setW(float w) { this->w = w; } + + void set(float x, float y, float z, float w) + { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } }; struct Vec2i @@ -155,6 +185,18 @@ struct Vec2i { return Vec2(x, y); } + + int getX() const { return x; } + int getY() const { return y; } + + void setX(int x) { this->x = x; } + void setY(int y) { this->y = y; } + + void set(int x, int y) + { + this->x = x; + this->y = y; + } }; struct IntRect : SDL_Rect diff --git a/windows/install.sh b/windows/install.sh index 2dceeb9d..94b3552f 100644 --- a/windows/install.sh +++ b/windows/install.sh @@ -34,6 +34,7 @@ shopt -s dotglob echo "Relocating dependencies..." DESTDIR="${MESON_INSTALL_PREFIX}/lib" +rm -r $DESTDIR mkdir -p $DESTDIR copy_dependencies $BINARY $BINARY