From 8fd6508ac4fbf2664cb0b079ab608f4ea1f35ab0 Mon Sep 17 00:00:00 2001 From: "Alexander Klingenbeck (SHS DI SY R&D DEV4)" Date: Tue, 16 May 2023 11:59:29 +0200 Subject: [PATCH] fix shader binding of value types --- bindings/src/index.ts | 6 +- bindings/src/quickjs.ts | 20 +++-- examples/raymarching.js | 4 +- generate-bindings.js | 37 +++++++--- src/bindings/_js_raylib_texture.h | 119 ------------------------------ src/bindings/js_raylib_core.h | 5 +- thirdparty/raylib | 2 +- 7 files changed, 49 insertions(+), 144 deletions(-) delete mode 100644 src/bindings/_js_raylib_texture.h diff --git a/bindings/src/index.ts b/bindings/src/index.ts index f5761f8..01f597b 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -270,10 +270,12 @@ function main(){ gen.jsToC("Shader","shader","argv[0]", core.structLookup) gen.jsToC("int","locIndex","argv[1]", core.structLookup) gen.declare("value","void *", false, "NULL") + gen.declare("valueFloat", "float") + gen.declare("valueInt", "int") gen.jsToC("int","uniformType","argv[3]", core.structLookup) const sw = gen.switch("uniformType") let b = sw.caseBreak("SHADER_UNIFORM_FLOAT") - b.jsToC("float", "valueFloat", "argv[2]", core.structLookup) + b.jsToC("float", "valueFloat", "argv[2]", core.structLookup, true) b.statement("value = (void *)&valueFloat") b = sw.caseBreak("SHADER_UNIFORM_VEC2") b.jsToC("Vector2 *", "valueV2", "argv[2]", core.structLookup) @@ -285,7 +287,7 @@ function main(){ b.jsToC("Vector4 *", "valueV4", "argv[2]", core.structLookup) b.statement("value = (void*)valueV4") b = sw.caseBreak("SHADER_UNIFORM_INT") - b.jsToC("int", "valueInt", "argv[2]", core.structLookup) + b.jsToC("int", "valueInt", "argv[2]", core.structLookup, true) b.statement("value = (void*)&valueInt") b = sw.defaultBreak() b.returnExp("JS_EXCEPTION") diff --git a/bindings/src/quickjs.ts b/bindings/src/quickjs.ts index 4ea1e53..b0e129b 100644 --- a/bindings/src/quickjs.ts +++ b/bindings/src/quickjs.ts @@ -76,36 +76,40 @@ export abstract class GenericQuickJsGenerator extend return sub } - jsToC(type: string, name: string, src: string, classIds: StructLookup = {}){ + jsToC(type: string, name: string, src: string, classIds: StructLookup = {}, supressDeclaration = false){ switch (type) { case "const char *": case "char *": - this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`) + if(!supressDeclaration) this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`) + else this.statement(`${name} = (${type})JS_ToCString(ctx, ${src})`) break; case "double": - this.statement(`${type} ${name}`) + if(!supressDeclaration) this.statement(`${type} ${name}`) this.statement(`JS_ToFloat64(ctx, &${name}, ${src})`) break; case "float": this.statement("double _double_"+name) this.statement(`JS_ToFloat64(ctx, &_double_${name}, ${src})`) - this.statement(`${type} ${name} = (${type})_double_${name}`) + if(!supressDeclaration) this.statement(`${type} ${name} = (${type})_double_${name}`) + else this.statement(`${name} = (${type})_double_${name}`) break; case "int": - this.statement(`${type} ${name}`) + if(!supressDeclaration) this.statement(`${type} ${name}`) this.statement(`JS_ToInt32(ctx, &${name}, ${src})`) break; case "unsigned int": - this.statement(`${type} ${name}`) + if(!supressDeclaration) this.statement(`${type} ${name}`) this.statement(`JS_ToUint32(ctx, &${name}, ${src})`) break; case "unsigned char": this.statement("unsigned int _int_"+name) this.statement(`JS_ToUint32(ctx, &_int_${name}, ${src})`) - this.statement(`${type} ${name} = (${type})_int_${name}`) + if(!supressDeclaration) this.statement(`${type} ${name} = (${type})_int_${name}`) + else this.statement(`${name} = (${type})_int_${name}`) break; case "bool": - this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`) + if(!supressDeclaration) this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`) + else this.statement(`${name} = JS_ToBool(ctx, ${src})`) break; default: const isConst = type.startsWith('const') diff --git a/examples/raymarching.js b/examples/raymarching.js index bc72f3d..9ac6343 100644 --- a/examples/raymarching.js +++ b/examples/raymarching.js @@ -23,7 +23,7 @@ const viewCenterLoc = getShaderLocation(shader, "viewCenter"); const runTimeLoc = getShaderLocation(shader, "runTime"); const resolutionLoc = getShaderLocation(shader, "resolution"); -let resolution = new Vector2(screenWidth, screenHeight); +let resolution = new Vector2(getRenderWidth(), getRenderHeight()); setShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); let runTime = 0.0; @@ -50,7 +50,7 @@ while (!windowShouldClose()) // Detect window close button or ESC key // Check if screen is resized if (isWindowResized()) { - resolution = new Vector2(getScreenWidth(),getScreenHeight()) + resolution = new Vector2(getRenderWidth(), getRenderHeight()) setShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); } //---------------------------------------------------------------------------------- diff --git a/generate-bindings.js b/generate-bindings.js index 02986cb..a9f11ba 100644 --- a/generate-bindings.js +++ b/generate-bindings.js @@ -376,36 +376,51 @@ class GenericQuickJsGenerator extends generation_1.GenericCodeGenerator { const sub = this.function("js_" + jsName, "JSValue", args, true); return sub; } - jsToC(type, name, src, classIds = {}) { + jsToC(type, name, src, classIds = {}, supressDeclaration = false) { switch (type) { case "const char *": case "char *": - this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`); + if (!supressDeclaration) + this.statement(`${type} ${name} = (${type})JS_ToCString(ctx, ${src})`); + else + this.statement(`${name} = (${type})JS_ToCString(ctx, ${src})`); break; case "double": - this.statement(`${type} ${name}`); + if (!supressDeclaration) + this.statement(`${type} ${name}`); this.statement(`JS_ToFloat64(ctx, &${name}, ${src})`); break; case "float": this.statement("double _double_" + name); this.statement(`JS_ToFloat64(ctx, &_double_${name}, ${src})`); - this.statement(`${type} ${name} = (${type})_double_${name}`); + if (!supressDeclaration) + this.statement(`${type} ${name} = (${type})_double_${name}`); + else + this.statement(`${name} = (${type})_double_${name}`); break; case "int": - this.statement(`${type} ${name}`); + if (!supressDeclaration) + this.statement(`${type} ${name}`); this.statement(`JS_ToInt32(ctx, &${name}, ${src})`); break; case "unsigned int": - this.statement(`${type} ${name}`); + if (!supressDeclaration) + this.statement(`${type} ${name}`); this.statement(`JS_ToUint32(ctx, &${name}, ${src})`); break; case "unsigned char": this.statement("unsigned int _int_" + name); this.statement(`JS_ToUint32(ctx, &_int_${name}, ${src})`); - this.statement(`${type} ${name} = (${type})_int_${name}`); + if (!supressDeclaration) + this.statement(`${type} ${name} = (${type})_int_${name}`); + else + this.statement(`${name} = (${type})_int_${name}`); break; case "bool": - this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`); + if (!supressDeclaration) + this.statement(`${type} ${name} = JS_ToBool(ctx, ${src})`); + else + this.statement(`${name} = JS_ToBool(ctx, ${src})`); break; default: const isConst = type.startsWith('const'); @@ -1106,10 +1121,12 @@ function main() { gen.jsToC("Shader", "shader", "argv[0]", core.structLookup); gen.jsToC("int", "locIndex", "argv[1]", core.structLookup); gen.declare("value", "void *", false, "NULL"); + gen.declare("valueFloat", "float"); + gen.declare("valueInt", "int"); gen.jsToC("int", "uniformType", "argv[3]", core.structLookup); const sw = gen.switch("uniformType"); let b = sw.caseBreak("SHADER_UNIFORM_FLOAT"); - b.jsToC("float", "valueFloat", "argv[2]", core.structLookup); + b.jsToC("float", "valueFloat", "argv[2]", core.structLookup, true); b.statement("value = (void *)&valueFloat"); b = sw.caseBreak("SHADER_UNIFORM_VEC2"); b.jsToC("Vector2 *", "valueV2", "argv[2]", core.structLookup); @@ -1121,7 +1138,7 @@ function main() { b.jsToC("Vector4 *", "valueV4", "argv[2]", core.structLookup); b.statement("value = (void*)valueV4"); b = sw.caseBreak("SHADER_UNIFORM_INT"); - b.jsToC("int", "valueInt", "argv[2]", core.structLookup); + b.jsToC("int", "valueInt", "argv[2]", core.structLookup, true); b.statement("value = (void*)&valueInt"); b = sw.defaultBreak(); b.returnExp("JS_EXCEPTION"); diff --git a/src/bindings/_js_raylib_texture.h b/src/bindings/_js_raylib_texture.h deleted file mode 100644 index 74d11ef..0000000 --- a/src/bindings/_js_raylib_texture.h +++ /dev/null @@ -1,119 +0,0 @@ - -#ifndef JS_raylib_texture -#define JS_raylib_texture - -#include -#include -#include - -#include - -#ifndef countof -#define countof(x) (sizeof(x) / sizeof((x)[0])) -#endif - -// 1. class id -static JSClassID js_image_class_id; - - -// 2. finalize -static void js_image_finalizer(JSRuntime *rt, JSValue val) { - Image *image = JS_GetOpaque(val, js_image_class_id); - if (image) { - puts("Finalize image"); - UnloadImage(*image); - js_free_rt(rt, image); - } -} - -// 3. getter/setter -static JSValue js_image_get_width(JSContext *ctx, JSValueConst this_val) { - Image *image = JS_GetOpaque2(ctx, this_val, js_image_class_id); - if (!image) { - return JS_EXCEPTION; - } - int width = image->width; - return JS_NewInt32(ctx, width); -} - -static JSValue js_image_get_height(JSContext *ctx, JSValueConst this_val) { - Image *image = JS_GetOpaque2(ctx, this_val, js_image_class_id); - if (!image) { - return JS_EXCEPTION; - } - int height = image->height; - return JS_NewInt32(ctx, height); -} - -// 4. class members -static const JSCFunctionListEntry js_image_proto_funcs[] = { - JS_CGETSET_DEF("width", js_image_get_width, NULL), - JS_CGETSET_DEF("height", js_image_get_height, NULL), - JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Image", JS_PROP_CONFIGURABLE), -}; - -// 5. class declaration -static int js_declare_image(JSContext *ctx, JSModuleDef *m){ - // Define image struct - JS_NewClassID(&js_image_class_id); - JSClassDef js_image_class_def = { - .class_name = "Image", - .finalizer = js_image_finalizer, - }; - JS_NewClass(JS_GetRuntime(ctx), js_image_class_id, &js_image_class_def); - JSValue proto = JS_NewObject(ctx); - JS_SetPropertyFunctionList(ctx, proto, js_image_proto_funcs, countof(js_image_proto_funcs)); - JS_SetClassProto(ctx, js_image_class_id, proto); - return 0; -} - -static JSValue js_LoadImage(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { - const char *filename = JS_ToCString(ctx, argv[0]); - - Image _struct = LoadImage(filename); - Image* ptr = (Image*)js_malloc(ctx, sizeof(Image)); - *ptr = _struct; - JSValue obj = JS_NewObjectClass(ctx, js_image_class_id); - JS_SetOpaque(obj, ptr); - - JS_FreeCString(ctx, filename); - return obj; -} - -static const JSCFunctionListEntry js_raylib_texture_funcs[] = { - JS_CFUNC_DEF("loadImage", 1, js_LoadImage) -}; - -static int js_raylib_texture_init(JSContext *ctx, JSModuleDef *m) { - // 6. call declaration - js_declare_image(ctx, m); - - JS_SetModuleExportList(ctx, m, js_raylib_texture_funcs, countof(js_raylib_texture_funcs)); - - // Implement constructor - JSValue constr = JS_NewCFunction2(ctx, js_LoadImage, "Image", 4, JS_CFUNC_constructor_or_func, 0); - JS_SetModuleExport(ctx, m, "Image", constr); - - // TODO export module constants - //JS_SetModuleExport(ctx, m, "in", js_new_std_file(ctx, stdin, FALSE, FALSE)); - - return 0; -} - -JSModuleDef *js_init_module_raylib_texture(JSContext *ctx, const char *module_name) -{ - JSModuleDef *m; - m = JS_NewCModule(ctx, module_name, js_raylib_texture_init); - if (!m) - return NULL; - - JS_AddModuleExportList(ctx, m, js_raylib_texture_funcs,countof(js_raylib_texture_funcs)); - - //TODO export module contants - JS_AddModuleExport(ctx, m, "Image"); - - return m; -} - -#endif - \ No newline at end of file diff --git a/src/bindings/js_raylib_core.h b/src/bindings/js_raylib_core.h index 8f458e7..426af00 100644 --- a/src/bindings/js_raylib_core.h +++ b/src/bindings/js_raylib_core.h @@ -1888,6 +1888,8 @@ static JSValue js_setShaderValue(JSContext * ctx, JSValueConst this_val, int arg int locIndex; JS_ToInt32(ctx, &locIndex, argv[1]); void * value = NULL; + float valueFloat; + int valueInt; int uniformType; JS_ToInt32(ctx, &uniformType, argv[3]); switch(uniformType) { @@ -1895,7 +1897,7 @@ static JSValue js_setShaderValue(JSContext * ctx, JSValueConst this_val, int arg { double _double_valueFloat; JS_ToFloat64(ctx, &_double_valueFloat, argv[2]); - float valueFloat = (float)_double_valueFloat; + valueFloat = (float)_double_valueFloat; value = (void *)&valueFloat; break; } @@ -1922,7 +1924,6 @@ static JSValue js_setShaderValue(JSContext * ctx, JSValueConst this_val, int arg } case SHADER_UNIFORM_INT: { - int valueInt; JS_ToInt32(ctx, &valueInt, argv[2]); value = (void*)&valueInt; break; diff --git a/thirdparty/raylib b/thirdparty/raylib index a48bb6e..5573f0f 160000 --- a/thirdparty/raylib +++ b/thirdparty/raylib @@ -1 +1 @@ -Subproject commit a48bb6e1ed7b33190e486ba65b7875f0dff73701 +Subproject commit 5573f0f1c7b29bfe46d0b70487e4adb4d01cba62