diff --git a/Engine.cc b/Engine.cc index 603e5b4..a205e9c 100644 --- a/Engine.cc +++ b/Engine.cc @@ -276,18 +276,20 @@ bool Engine::fileExists(const string & path) } int Engine::addObject(WFObj * obj, bool is_static, bool is_reference, - float scale) + bool enable_blending, float scale) { - Object * o = new Object(is_static, is_reference, m_world, obj, scale); + Object * o = new Object(is_static, is_reference, enable_blending, + m_world, obj, scale); int id = m_objects.add(o); o->setID(id); return id; } -int Engine::addObject(bool is_static, bool is_reference, +int Engine::addObject(bool is_static, bool is_reference, bool enable_blending, OdeWorld::GeomType geom_type, refptr< vector > args) { - Object * o = new Object(is_static, is_reference, m_world, geom_type, args); + Object * o = new Object(is_static, is_reference, enable_blending, + m_world, geom_type, args); int id = m_objects.add(o); o->setID(id); return id; @@ -535,7 +537,7 @@ int Engine::clearEventHandler(lua_State * L) } int Engine::loadModel(const string & name, bool is_static, bool is_reference, - float scale) + bool enable_blending, float scale) { size_t pos = name.find_first_not_of(FILENAME_SAFE_CHARS); if (pos == string::npos) @@ -547,7 +549,8 @@ int Engine::loadModel(const string & name, bool is_static, bool is_reference, if (obj->load(model_path)) { - int id = addObject(obj, is_static, is_reference, scale); + int id = addObject(obj, is_static, is_reference, enable_blending, + scale); Engine::Object * engine_obj = getObject(id); if (engine_obj != NULL) { @@ -1205,7 +1208,7 @@ void Engine::drawObjects() /******** Engine::Object functions ********/ /* used for objects loaded directly from model files */ -Engine::Object::Object(bool is_static, bool is_reference, +Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending, OdeWorld & world, WFObj * obj, float scale) : m_world(world) { @@ -1220,7 +1223,8 @@ Engine::Object::Object(bool is_static, bool is_reference, m_ode_object->setUserData(this); } m_is_static = is_static; - m_display_list = obj->render(); + m_enable_blending = enable_blending; + m_display_list = obj->render(true, enable_blending); const float * obj_aabb = obj->getAABB(); for (int i = 0; i < 6; i++) m_aabb[i] = scale * obj_aabb[i]; @@ -1236,12 +1240,13 @@ Engine::Object::Object(bool is_static, bool is_reference, } /* used for "managed" objects with one geom */ -Engine::Object::Object(bool is_static, bool is_reference, OdeWorld & world, - OdeWorld::GeomType geom_type, +Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending, + OdeWorld & world, OdeWorld::GeomType geom_type, refptr< std::vector > args) : m_world(world) { m_is_reference = is_reference; + m_enable_blending = enable_blending; m_is_static = geom_type == OdeWorld::PLANE ? false : is_static; m_is_visible = true; m_scale = 1.0f; @@ -1278,6 +1283,7 @@ Engine::Object::Object(const Engine::Object & orig) m_is_reference = false; m_is_visible = orig.m_is_visible; m_is_static = orig.m_is_static; + m_enable_blending = orig.m_enable_blending; m_scale = orig.m_scale; m_is_scaled = orig.m_is_scaled; m_phy = orig.m_phy; @@ -1417,7 +1423,17 @@ void Engine::Object::render() } checkGLError(); glNewList(m_display_list, GL_COMPILE); - glPushAttrib(GL_ENABLE_BIT); + int attrib_flags = GL_ENABLE_BIT; + if (m_enable_blending) + { + attrib_flags |= GL_COLOR_BUFFER_BIT; + } + glPushAttrib(attrib_flags); + if (m_enable_blending) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } if (m_texture != 0) { gluQuadricTexture(quad, 1); diff --git a/Engine.h b/Engine.h index 1d0e0d3..7556c1a 100644 --- a/Engine.h +++ b/Engine.h @@ -23,10 +23,10 @@ class Engine class Object { public: - Object(bool is_static, bool is_reference, + Object(bool is_static, bool is_reference, bool enable_blending, OdeWorld & world, WFObj * wfobj, float scale = 1.0f); - Object(bool is_static, bool is_reference, + Object(bool is_static, bool is_reference, bool enable_blending, OdeWorld & world, OdeWorld::GeomType geom_type, refptr< std::vector > args); Object(const Object & orig); @@ -114,6 +114,7 @@ class Engine bool m_mass_is_set; bool m_gravity_mode; int m_id; + bool m_enable_blending; /* for "pre-loaded" objects */ int * m_display_list_refcnt; @@ -158,8 +159,8 @@ class Engine void reportErrors(int status); OdeWorld & getWorld() { return m_world; } int addObject(WFObj * obj, bool is_static, bool is_reference, - float scale = 1.0f); - int addObject(bool is_static, bool is_reference, + bool enable_blending, float scale = 1.0f); + int addObject(bool is_static, bool is_reference, bool enable_blending, OdeWorld::GeomType geom_type, refptr< std::vector > args); int addSound(refptr avs); @@ -193,7 +194,7 @@ class Engine void startFrame(); void endFrame(); int loadModel(const std::string & name, bool is_static, - bool is_reference, float scale = 1.0f); + bool is_reference, bool enable_blending, float scale = 1.0f); int loadSound(const std::string & name); bool isKeyDown(const std::string & key); void exit(); diff --git a/ag.cc b/ag.cc index 1ccafa3..7207d49 100644 --- a/ag.cc +++ b/ag.cc @@ -510,16 +510,18 @@ fail: bool added = false; int argc = lua_gettop(L); - if (argc == 4 + if (argc == 5 && lua_isstring(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) - && lua_isboolean(L, 4)) + && lua_isboolean(L, 4) + && lua_isboolean(L, 5)) { int id = g_engine->loadModel( lua_tostring(L, 1), /* name */ lua_toboolean(L, 3), /* static */ lua_toboolean(L, 4), /* reference */ + lua_toboolean(L, 5), /* enable blending */ lua_tonumber(L, 2)); /* scale */ if (id > 0) { @@ -1030,28 +1032,30 @@ fail: } static void addManagedObject(lua_State * L, bool is_static, - bool is_reference, + bool is_reference, bool enable_blending, OdeWorld::GeomType geom_type, refptr< vector > args) { - int id = g_engine->addObject(is_static, is_reference, geom_type, args); + int id = g_engine->addObject(is_static, is_reference, enable_blending, + geom_type, args); createLuaObject(L, id); } int createBoxSpecify(lua_State * L) { int argc = lua_gettop(L); - if (argc == 5 + if (argc == 6 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isboolean(L, 4) - && lua_isboolean(L, 5)) + && lua_isboolean(L, 5) + && lua_isboolean(L, 6)) { refptr< vector > args = new vector(); for (int i = 1; i <= 3; i++) args->push_back(lua_tonumber(L, i)); addManagedObject(L, lua_toboolean(L, 4), lua_toboolean(L, 5), - OdeWorld::BOX, args); + lua_toboolean(L, 6), OdeWorld::BOX, args); } else lua_pushnil(L); @@ -1061,15 +1065,16 @@ fail: int createSphereSpecify(lua_State * L) { int argc = lua_gettop(L); - if (argc == 3 + if (argc == 4 && lua_isnumber(L, 1) && lua_isboolean(L, 2) - && lua_isboolean(L, 3)) + && lua_isboolean(L, 3) + && lua_isboolean(L, 4)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); addManagedObject(L, lua_toboolean(L, 2), lua_toboolean(L, 3), - OdeWorld::SPHERE, args); + lua_toboolean(L, 4), OdeWorld::SPHERE, args); } else lua_pushnil(L); @@ -1079,10 +1084,10 @@ fail: int createPlaneSpecify(lua_State * L) { int argc = lua_gettop(L); - if (argc == 5 || argc == 7) + if (argc == 6 || argc == 8) { - bool valid = lua_isboolean(L, argc); - for (int i = 1; i < argc; i++) + bool valid = true; + for (int i = 1; i < argc - 1; i++) { if (!lua_isnumber(L, i)) { @@ -1093,10 +1098,10 @@ fail: if (valid) { refptr< vector > args = new vector(); - for (int i = 1; i < argc; i++) + for (int i = 1; i < argc - 1; i++) args->push_back(lua_tonumber(L, i)); - addManagedObject(L, true, lua_toboolean(L, argc), - OdeWorld::PLANE, args); + addManagedObject(L, true, lua_toboolean(L, argc - 1), + lua_toboolean(L, argc), OdeWorld::PLANE, args); return 1; } } @@ -1107,17 +1112,18 @@ fail: int createCylinderSpecify(lua_State * L) { int argc = lua_gettop(L); - if (argc == 4 + if (argc == 5 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) - && lua_isboolean(L, 4)) + && lua_isboolean(L, 4) + && lua_isboolean(L, 5)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); args->push_back(lua_tonumber(L, 2)); addManagedObject(L, lua_toboolean(L, 3), lua_toboolean(L, 4), - OdeWorld::CYLINDER, args); + lua_toboolean(L, 5), OdeWorld::CYLINDER, args); } else lua_pushnil(L); @@ -1127,17 +1133,18 @@ fail: int createCapsuleSpecify(lua_State * L) { int argc = lua_gettop(L); - if (argc == 4 + if (argc == 5 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) - && lua_isboolean(L, 4)) + && lua_isboolean(L, 4) + && lua_isboolean(L, 5)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); args->push_back(lua_tonumber(L, 2)); addManagedObject(L, lua_toboolean(L, 3), lua_toboolean(L, 4), - OdeWorld::CAPSULE, args); + lua_toboolean(L, 5), OdeWorld::CAPSULE, args); } else lua_pushnil(L); diff --git a/ag.lua b/ag.lua index 7c8d359..4479160 100644 --- a/ag.lua +++ b/ag.lua @@ -111,6 +111,7 @@ ag.loadModel = function(name, args) local scale = 1.0 local static = false local reference = false + local blending = false if (type(args) == "table") then if (type(args.scale) == "number") then scale = args.scale @@ -121,13 +122,17 @@ ag.loadModel = function(name, args) if (type(args.reference) == "boolean") then reference = args.reference end + if (type(args.enable_blending) == "boolean") then + blending = args.enable_blending + end end - return ag.loadModelSpecify(name, scale, static, reference) + return ag.loadModelSpecify(name, scale, static, blending, reference) end ag.createBox = function(x, y, z, args) local static = false local reference = false + local blending = false if (type(args) == "table") then if (type(args.static) == "boolean") then static = args.static @@ -135,13 +140,17 @@ ag.createBox = function(x, y, z, args) if (type(args.reference) == "boolean") then reference = args.reference end + if (type(args.enable_blending) == "boolean") then + blending = args.enable_blending + end end - return ag.createBoxSpecify(x, y, z, static, reference) + return ag.createBoxSpecify(x, y, z, static, reference, blending) end ag.createSphere = function(radius, args) local static = false local reference = false + local blending = false if (type(args) == "table") then if (type(args.static) == "boolean") then static = args.static @@ -149,8 +158,11 @@ ag.createSphere = function(radius, args) if (type(args.reference) == "boolean") then reference = args.reference end + if (type(args.enable_blending) == "boolean") then + blending = args.enable_blending + end end - return ag.createSphereSpecify(radius, static, reference) + return ag.createSphereSpecify(radius, static, reference, blending) end ag.createPlane = function(a, b, c, d, x, y, z) @@ -162,21 +174,26 @@ ag.createPlane = function(a, b, c, d, x, y, z) t = z end local reference = false + local blending = false if (type(t) == "table") then if (type(t.reference) == "boolean") then reference = t.reference end + if (type(args.enable_blending) == "boolean") then + blending = args.enable_blending + end end if (type(y) == "nil") then - return ag.createPlaneSpecify(a, b, c, d, reference) + return ag.createPlaneSpecify(a, b, c, d, reference, blending) else - return ag.createPlaneSpecify(a, b, c, d, x, y, reference) + return ag.createPlaneSpecify(a, b, c, d, x, y, reference, blending) end end ag.createCapsule = function(radius, length, args) local static = false local reference = false + local blending = false if (type(args) == "table") then if (type(args.static) == "boolean") then static = args.static @@ -184,6 +201,9 @@ ag.createCapsule = function(radius, length, args) if (type(args.reference) == "boolean") then reference = args.reference end + if (type(args.enable_blending) == "boolean") then + blending = args.enable_blending + end end - return ag.createCapsuleSpecify(radius, length, static, reference) + return ag.createCapsuleSpecify(radius, length, static, reference, blending) end