/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "binding_helpers.h" #include "core/material_to_shader_tree.h" #include "core/render_data.h" #include "gpu/gpu_material.h" using namespace GS::Render; using namespace GS::Script; //------------------------------------------------------------------------------ SQInteger MaterialGetDiffuse(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNVECTORW(m->diffuse) } SQInteger MaterialSetDiffuse(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETVECTORW(c) __SQ_GETEND m->diffuse = c; __SQ_RETURN } SQInteger MaterialGetSpecular(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNVECTORW(m->specular) } SQInteger MaterialSetSpecular(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETVECTORW(c) __SQ_GETEND m->specular = c; __SQ_RETURN } SQInteger MaterialGetSelf(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNVECTORW(m->self) } SQInteger MaterialSetSelf(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETVECTORW(c) __SQ_GETEND m->self = c; __SQ_RETURN } SQInteger MaterialGetAmbient(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNVECTORW(m->ambient) } SQInteger MaterialSetAmbient(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETVECTORW(c) __SQ_GETEND m->ambient = c; __SQ_RETURN } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialGetGlossiness(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNFLOAT(m->glossiness) } SQInteger MaterialSetGlossiness(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETFLOAT(v) __SQ_GETEND m->glossiness = v; __SQ_RETURN } SQInteger MaterialGetOpacity(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNFLOAT(m->opacity) } SQInteger MaterialSetOpacity(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETFLOAT(v) __SQ_GETEND m->opacity = v; __SQ_RETURN } SQInteger MaterialGetAlphaThreshold(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNFLOAT(m->athreshold) } SQInteger MaterialSetAlphaThreshold(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETFLOAT(v) __SQ_GETEND m->athreshold = v; __SQ_RETURN } SQInteger MaterialGetDepthBias(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(m, Material, typetag_Material) __SQ_RETURNFLOAT(m->depth_bias) } SQInteger MaterialSetDepthBias(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(m, Material, typetag_Material) __SQ_GETFLOAT(v) __SQ_GETEND m->depth_bias = v; __SQ_RETURN } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialGetName(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(mat, Material, typetag_Material) __SQ_RETURNSTRING(mat->name.c_str()) } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialFlagGet(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(mat, Material, typetag_Material) __SQ_GETINT(flag) __SQ_GETEND __SQ_RETURNBOOL(asbool(mat->renderword & flag)) } SQInteger MaterialFlagSet(HSQUIRRELVM vm) { __SQ_GETSTART(3) __SQ_GETSAFEPTR(mat, Material, typetag_Material) __SQ_GETINT(flag) __SQ_GETBOOL(state) __SQ_GETEND if (state) mat->renderword |= flag; else mat->renderword &= ~flag; __SQ_RETURN } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialGetBlendOperator(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(mat, Material, typetag_Material) __SQ_RETURNINT(mat->blendop) } SQInteger MaterialSetBlendOperator(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(mat, Material, typetag_Material) __SQ_GETINT(op) __SQ_GETEND mat->blendop = op; __SQ_RETURN } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialGetTexture(HSQUIRRELVM vm) { __SQ_GETSTART(2) __SQ_GETSAFEPTR(mat, Material, typetag_Material) __SQ_GETINT(slot) __SQ_GETEND if ((slot < 0) || (slot >= GS::Core::Material::max_texture_stage)) return sq_throwerror(vm, "Invalid material texture slot index."); __SQ_RETURNSAFEPTR(mat->texture_table[slot].c_ptr(), typetag_Texture) } SQInteger MaterialSetTexture(HSQUIRRELVM vm) { __SQ_GETSTART(3) __SQ_GETSAFEPTR(mat, Material, typetag_Material) __SQ_GETINT(slot) __SQ_GETSAFEPTR(tex, Texture, typetag_Texture) __SQ_GETEND if ((slot < 0) || (slot >= GS::Core::Material::max_texture_stage)) return sq_throwerror(vm, "Invalid material texture slot index."); mat->texture_table[slot] = tex; __SQ_RETURN } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialClone(HSQUIRRELVM vm) { __LOG_W__ << "[SQ] MaterialClone: Called from Squirrel.\n"; __SQ_GETSINGLESAFEPTR(mat, Material, typetag_Material) __LOG_W__ << "[SQ] MaterialClone: Got material pointer: " << (void*)mat << "\n"; if (!mat) { __LOG_E__ << "[SQ] MaterialClone: Input material is NULL!\n"; return sq_throwerror(vm, "Input material is NULL"); } __LOG_W__ << "[SQ] MaterialClone: Material name: '" << mat->name << "'\n"; __LOG_W__ << "[SQ] MaterialClone: Material refcount: " << mat->GetRefCount() << "\n"; // Cast to GPU::Material to ensure we're working with the right type __LOG_W__ << "[SQ] MaterialClone: Attempting dynamic_cast to GPU::Material...\n"; GS::GPU::Material *gpu_mat = dynamic_cast(mat); if (!gpu_mat) { __LOG_E__ << "[SQ] MaterialClone: Material is not a GPU::Material! Cannot clone.\n"; return sq_throwerror(vm, "Material type not supported for cloning"); } __LOG_W__ << "[SQ] MaterialClone: dynamic_cast succeeded, got GPU::Material at " << (void*)gpu_mat << "\n"; // WORKAROUND: Clone manually without calling virtual methods // (calling virtual methods crashes for unknown reason) __LOG_W__ << "[SQ] MaterialClone: Cloning manually (bypassing virtual Clone())...\n"; Material *cloned = NULL; try { __LOG_W__ << "[SQ] MaterialClone: Accessing renderer reference...\n"; GS::GPU::Renderer &rend = gpu_mat->renderer; __LOG_W__ << "[SQ] MaterialClone: Renderer at: " << (void*)&rend << "\n"; __LOG_W__ << "[SQ] MaterialClone: Allocating new GPU::Material...\n"; cloned = new GS::GPU::Material(rend); __LOG_W__ << "[SQ] MaterialClone: Allocation succeeded: " << (void*)cloned << "\n"; // Copy properties manually __LOG_W__ << "[SQ] MaterialClone: Copying name...\n"; cloned->name = gpu_mat->name + "_clone"; __LOG_W__ << "[SQ] MaterialClone: Copying BasicMaterial properties...\n"; *((GS::Core::BasicMaterial *)cloned) = *((GS::Core::BasicMaterial *)gpu_mat); __LOG_W__ << "[SQ] MaterialClone: Copying shader reference...\n"; ((GS::GPU::Material*)cloned)->shader = gpu_mat->shader; __LOG_W__ << "[SQ] MaterialClone: Copying texture table...\n"; for (uint n = 0; n < GS::Core::Material::max_texture_stage; ++n) { cloned->texture_table[n] = gpu_mat->texture_table[n]; } __LOG_W__ << "[SQ] MaterialClone: Manual clone complete!\n"; } catch (...) { __LOG_E__ << "[SQ] MaterialClone: EXCEPTION caught during manual clone!\n"; if (cloned) delete cloned; return sq_throwerror(vm, "Exception during clone"); } __LOG_W__ << "[SQ] MaterialClone: Clone() returned: " << (void*)cloned << "\n"; if (!cloned) { __LOG_E__ << "[SQ] MaterialClone: Clone() returned NULL!\n"; return sq_throwerror(vm, "Failed to clone material"); } __LOG_W__ << "[SQ] MaterialClone: Returning managed pointer to Squirrel...\n"; // Use managed pointer so Squirrel will handle the reference counting __SQ_RETURNMANAGEDSAFEPTR(cloned, typetag_Material) } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ SQInteger MaterialGetShader(HSQUIRRELVM vm) { __SQ_GETSINGLESAFEPTR(mat, Material, typetag_Material) __SQ_RETURNSAFEPTR(mat->GetShader(), typetag_MaterialShader) } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void RegisterMaterialBinding(HSQUIRRELVM vm) { /*# Topic: Material Type: Material Type: MaterialShader #*/ /*# Section: MaterialRenderAttributes Desc: Render attributes functions #*/ /*# Func: MaterialGetDiffuse Proto: Vector:Material material Desc: Get material diffuse color. #*/ sq_register(vm, MaterialGetDiffuse, "MaterialGetDiffuse", _SC(".x")); /*# Func: MaterialSetDiffuse Proto: void:Material material,Vector diffuse_color Desc: Set material diffuse color. #*/ sq_register(vm, MaterialSetDiffuse, "MaterialSetDiffuse", _SC(".xx")); /*# Func: MaterialGetSpecular Proto: Vector:Material material Desc: Get material specular color. #*/ sq_register(vm, MaterialGetSpecular, "MaterialGetSpecular", _SC(".x")); /*# Func: MaterialSetSpecular Proto: void:Material material,Vector specular_color Desc: Set material specular color. Note: This value is combined with the light source own specular color and intensity. #*/ sq_register(vm, MaterialSetSpecular, "MaterialSetSpecular", _SC(".xx")); /*# Func: MaterialGetSelf Proto: Vector:Material material Desc: Get material self color. #*/ sq_register(vm, MaterialGetSelf, "MaterialGetSelf", _SC(".x")); /*# Func: MaterialSetSelf Proto: void:Material material,Vector self_color Desc: Set material self color. #*/ sq_register(vm, MaterialSetSelf, "MaterialSetSelf", _SC(".xx")); /*# Func: MaterialGetAmbient Proto: Vector:Material material Desc: Get material ambient color. #*/ sq_register(vm, MaterialGetAmbient, "MaterialGetAmbient", _SC(".x")); /*# Func: MaterialSetAmbient Proto: void:Material material,Vector ambient_color Desc: Set material ambient color. #*/ sq_register(vm, MaterialSetAmbient, "MaterialSetAmbient", _SC(".xx")); /*# Func: MaterialGetGlossiness Proto: float:Material material Desc: Get material glossiness. #*/ sq_register(vm, MaterialGetGlossiness, "MaterialGetGlossiness", _SC(".x")); /*# Func: MaterialSetGlossiness Proto: void:Material material,float glossiness Desc: Set material glossiness. #*/ sq_register(vm, MaterialSetGlossiness, "MaterialSetGlossiness", _SC(".xn")); /*# Func: MaterialGetOpacity Proto: float:Material material Desc: Get material opacity. #*/ sq_register(vm, MaterialGetOpacity, "MaterialGetOpacity", _SC(".x")); /*# Func: MaterialSetOpacity Proto: void:Material material,float opacity Desc: Set material opacity. See: MaterialSetBlendOperator #*/ sq_register(vm, MaterialSetOpacity, "MaterialSetOpacity", _SC(".xn")); /*# Func: MaterialGetAlphaThreshold Proto: float:Material material Desc: Get material alpha threshold. #*/ sq_register(vm, MaterialGetAlphaThreshold, "MaterialGetAlphaThreshold", _SC(".x")); /*# Func: MaterialSetAlphaThreshold Proto: void:Material material,float threshold Desc: Set material alpha threshold. #*/ sq_register(vm, MaterialSetAlphaThreshold, "MaterialSetAlphaThreshold", _SC(".xn")); /*# Func: MaterialGetDepthBias Proto: float:Material material Desc: Get material depth bias. #*/ sq_register(vm, MaterialGetDepthBias, "MaterialGetDepthBias", _SC(".x")); /*# Func: MaterialSetDepthBias Proto: void:Material material,float depth_bias Desc: Set material depth bias. #*/ sq_register(vm, MaterialSetDepthBias, "MaterialSetDepthBias", _SC(".xn")); /*# Func: MaterialGetTexture Proto: Texture:Material material,int slot Desc: Get texture at a given material slot. #*/ sq_register(vm, MaterialGetTexture, "MaterialGetTexture", _SC(".xn")); /*# Func: MaterialSetTexture Proto: void:Material material,int slot,Texture texture Desc: Set texture at a given material slot. #*/ sq_register(vm, MaterialSetTexture, "MaterialSetTexture", _SC(".xnx")); /*# Func: MaterialGetShader Proto: MaterialShader:Material material Desc: Return the material shader for a given material. Note: A material shader encapsulates all the variants of a shader required to render a material. #*/ sq_register(vm, MaterialGetShader, "MaterialGetShader", _SC(".x")); /*# Section: MaterialGeneric Desc: Generic functions #*/ /*# Func: MaterialGetName Proto: string:Material mat Desc: Get material name. #*/ sq_register(vm, MaterialGetName, "MaterialGetName", _SC(".x")); /*# Func: MaterialClone Proto: Material:Material mat Desc: Clone a material (create an independent copy in memory). Note: The cloned material has all the same textures, properties, and configuration as the original, but changes to the clone won't affect the original material. Example: local mat_clone = MaterialClone(original_material) #*/ sq_register(vm, MaterialClone, "MaterialClone", _SC(".x")); /*# Section: MaterialFlag Desc: Rendering flag functions #*/ /*# Func: MaterialSetRenderFlag Proto: void:Material mat,MaterialRenderFlag flag,bool state Desc: Add or remove a material render flag. Example: // Set the first material of a geometry to be double-sided. local mat = GeometryGetMaterialFromIndex(geo, 0) MaterialSetRenderFlag(mat, MaterialRenderDoubleSided, true) #*/ sq_register(vm, MaterialFlagSet, "MaterialFlagSet", _SC(".xib")); sq_register(vm, MaterialFlagSet, "MaterialSetRenderFlag", _SC(".xib")); /*# Func: MaterialTestRenderFlag Proto: bool:Material mat,MaterialRenderFlag flag Desc: Test a material render flag. #*/ sq_register(vm, MaterialFlagGet, "MaterialFlagGet", _SC(".xi")); sq_register(vm, MaterialFlagGet, "MaterialTestRenderFlag", _SC(".xi")); /*# Func: MaterialSetBlendOperator Proto: void:Material mat,MaterialBlendOperator op Desc: Set the material blend operator. The blend operator controls how a material is composited onto screen. Example: // Set the first material of a geometry to use additive blending. local mat = GeometryGetMaterialFromIndex(geo, 0) MaterialSetBlendOperator(mat, MaterialBlendAdditive) #*/ sq_register(vm, MaterialSetBlendOperator, "MaterialSetBlendOperator", _SC(".xi")); /*# Func: MaterialGetBlendOperator Proto: MaterialBlendOperator:Material mat Desc: Get the material blend operator. See: MaterialSetBlendOperator #*/ sq_register(vm, MaterialGetBlendOperator, "MaterialGetBlendOperator", _SC(".x")); // sq_pushroottable(vm); sq_pushstring(vm, "NullMaterial", -1); CObject::Push(vm, NULL, typetag_Material); sq_newslot(vm, -3, true); using GS::Core::Material; /*# Enum: MaterialBlendOperator Values: MaterialBlendNone,MaterialBlendAlpha,MaterialBlendAdditive #*/ sq_pushstring(vm, "MaterialBlendNone", -1); sq_pushinteger(vm, Material::Blend_None); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialBlendAlpha", -1); sq_pushinteger(vm, Material::Blend_Alpha); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialBlendAdditive", -1); sq_pushinteger(vm, Material::Blend_Add); sq_newslot(vm, -3, true); /*# Enum: MaterialRenderFlag Values: MaterialRenderUnlit,MaterialRenderSmooth,MaterialRenderNormalMapTangent,MaterialRenderNoFog,MaterialRenderDoubleSided,MaterialRenderWire,MaterialRenderVertexColor,MaterialRenderParralax,MaterialRenderToonShading,MaterialRenderNoDepthWrite,MaterialRenderNoDepthTest,MaterialRenderAlphaSoftZ,MaterialRenderAlphaInShadow #*/ sq_pushstring(vm, "MaterialRenderUnlit", -1); sq_pushinteger(vm, Material::Render_Unlit); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderSmooth", -1); sq_pushinteger(vm, Material::Render_Smooth); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderNormalMapTangent", -1); sq_pushinteger(vm, Material::Render_NormalTangent); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderNoFog", -1); sq_pushinteger(vm, Material::Render_NoFog); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderDoubleSided", -1); sq_pushinteger(vm, Material::Render_DoubleSided); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderWire", -1); sq_pushinteger(vm, Material::Render_Wire); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderVertexColor", -1); sq_pushinteger(vm, Material::Render_VertexColor); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderParralax", -1); sq_pushinteger(vm, Material::Render_ParralaxDisp); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderToonShading", -1); sq_pushinteger(vm, Material::Render_Toon); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderNoDepthWrite", -1); sq_pushinteger(vm, Material::Render_NoZWrite); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderNoDepthTest", -1); sq_pushinteger(vm, Material::Render_NoZTest); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderAlphaSoftZ", -1); sq_pushinteger(vm, Material::Render_AlphaSoftZ); sq_newslot(vm, -3, true); sq_pushstring(vm, "MaterialRenderAlphaInShadow", -1); sq_pushinteger(vm, Material::Render_AlphaInShadow); sq_newslot(vm, -3, true); sq_pop(vm, 1); } //------------------------------------------------------------------------------