Files
Webcam/include/modules/script_squirrel/legacy/material_binding.cpp

533 lines
18 KiB
C++

/* -----------------------------------------------------------------------------
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<GS::GPU::Material*>(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);
}
//------------------------------------------------------------------------------