diff --git a/data/levels/cemetery/cemetery.xml b/data/levels/cemetery/cemetery.xml index d9813be..fd02c6d 100644 --- a/data/levels/cemetery/cemetery.xml +++ b/data/levels/cemetery/cemetery.xml @@ -9,5 +9,13 @@ + + + + + + + + \ No newline at end of file diff --git a/data/scripts/actors/actor_player.lua b/data/scripts/actors/actor_player.lua index 314654d..9ea59a2 100644 --- a/data/scripts/actors/actor_player.lua +++ b/data/scripts/actors/actor_player.lua @@ -37,4 +37,8 @@ function actor_player:on_update(dt) self:update_camera_look() --self:update_camera_movement(dt) self:update_body_movement(dt) +end + +function actor_player:on_collide(other) + --console.print(string.format("actor_player:on_collide: %s", other:get_classname())) end \ No newline at end of file diff --git a/src/engine/camera.cpp b/src/engine/camera.cpp index 17f5f5e..07aeb2d 100644 --- a/src/engine/camera.cpp +++ b/src/engine/camera.cpp @@ -48,7 +48,7 @@ glm::mat4 Camera::GetProjectionMatrix(const Viewport& viewport) const else // if (m_projectionType == PERSPECTIVE): Control return in all path's { float aspectRatio = (float)viewport.width / (float)viewport.height; - proj = glm::perspective(glm::radians(m_fov), aspectRatio, 0.01f, 100.0f); + proj = glm::perspective(glm::radians(m_fov), aspectRatio, 0.1f, 100.0f); } return proj; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 8d388aa..76ccf49 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -329,6 +329,8 @@ void Engine::Disconnect() delete g_PhysicsWorld; g_PhysicsWorld = nullptr; } + + IEntityBase::ResetEntityID(); } SDL_Window* Engine::GetWindow() diff --git a/src/engine/entityregistrator.h b/src/engine/entityregistrator.h index 50fe653..e5e0493 100644 --- a/src/engine/entityregistrator.h +++ b/src/engine/entityregistrator.h @@ -10,7 +10,7 @@ struct EntityRegistrationInfo }; template -IEntityBase* createEntityTemplated() +IEntityBase* CreateEntityTemplated() { return new T(); } diff --git a/src/engine/ientity.cpp b/src/engine/ientity.cpp index 72e1cb0..f71cb18 100644 --- a/src/engine/ientity.cpp +++ b/src/engine/ientity.cpp @@ -2,13 +2,17 @@ #include +static int s_entityId = 0; + IEntityBase::IEntityBase() : m_worldTM(1.0f), m_position(0.0f), m_rotation(0.0f), m_scale(1.0f), - m_classname(nullptr) + m_classname(nullptr), + m_id(-1) { + m_id = s_entityId++; } IEntityBase::~IEntityBase() @@ -23,6 +27,10 @@ void IEntityBase::Render() { } +void IEntityBase::OnCollide(IEntityBase* other) +{ +} + void IEntityBase::SetPosition(const glm::vec3& pos) { m_position = pos; @@ -41,3 +49,13 @@ void IEntityBase::UpdateTransform() m_worldTM = glm::mat4(1.0f); m_worldTM = glm::translate(m_worldTM, m_position) * rotation * glm::scale(m_worldTM, m_scale); } + +uint32_t IEntityBase::GetID() +{ + return m_id; +} + +void IEntityBase::ResetEntityID() +{ + s_entityId = 0; +} diff --git a/src/engine/ientity.h b/src/engine/ientity.h index a4ada9e..adc4ab1 100644 --- a/src/engine/ientity.h +++ b/src/engine/ientity.h @@ -11,6 +11,7 @@ public: virtual void Update(float dt); virtual void Render(); + virtual void OnCollide(IEntityBase* other); const char* GetClassname() { return m_classname; } void SetClassname(const char* classname) { m_classname = classname; } @@ -22,6 +23,10 @@ public: const glm::mat4& GetWorldTransform(); void UpdateTransform(); + uint32_t GetID(); + + static void ResetEntityID(); + protected: glm::vec3 m_position; glm::vec3 m_rotation; @@ -32,17 +37,19 @@ protected: BoundingBox m_boundingBox; const char* m_classname; + + uint32_t m_id; }; // registration #include "engine/entityregistrator.h" #define REGISTER_ENTITY(CLASSNAME) \ - static EntityRegistrationInfo s_##CLASSNAME##RegisterInfo = { &createEntityTemplated, #CLASSNAME }; \ + static EntityRegistrationInfo s_##CLASSNAME##RegisterInfo = { &CreateEntityTemplated, #CLASSNAME }; \ static EntityRegistrator s_##CLASSNAME##Registrator(s_##CLASSNAME##RegisterInfo) #define REGISTER_ENTITY_EX(CLASSNAME, NAME) \ - static EntityRegistrationInfo s_##CLASSNAME##RegisterInfo = { &createEntityTemplated, NAME }; \ + static EntityRegistrationInfo s_##CLASSNAME##RegisterInfo = { &CreateEntityTemplated, NAME }; \ static EntityRegistrator s_##CLASSNAME##Registrator(s_##CLASSNAME##RegisterInfo) #endif // !ENTITYBASE_H diff --git a/src/engine/physics/physicsworld.cpp b/src/engine/physics/physicsworld.cpp index 56674ad..7f66d1b 100644 --- a/src/engine/physics/physicsworld.cpp +++ b/src/engine/physics/physicsworld.cpp @@ -1,6 +1,7 @@ #include "engine/core.h" #include "engine/log.h" #include "engine/engine.h" +#include "engine/ientity.h" #include "engine/camera.h" #include "engine/physics/physicsworld.h" #include "engine/physics/physicsdebugdraw.h" @@ -159,14 +160,27 @@ void PhysicsWorld::InternalTick() const btVector3& ptB = pt.getPositionWorldOnB(); const btVector3& normalOnB = pt.m_normalWorldOnB; - RigidBody* rbA = static_cast(obA->getUserPointer()); - RigidBody* rbB = static_cast(obB->getUserPointer()); + //RigidBody* rbA = static_cast(obA->getUserPointer()); + //RigidBody* rbB = static_cast(obB->getUserPointer()); + //if (!rbA || !rbB) + // continue; - if (!rbA || !rbB) + //SDL_assert(rbA); + //SDL_assert(rbB); + + + + IEntityBase* entA = static_cast(obA->getUserPointer()); + IEntityBase* entB = static_cast(obB->getUserPointer()); + if (!entA || !entB) continue; - SDL_assert(rbA); - SDL_assert(rbB); + if (entA) + entA->OnCollide(entB); + + if (entB) + entB->OnCollide(entA); + /*if (TriggerComponent* trigger = rbA->GetEntity()->GetComponent()) { @@ -211,13 +225,13 @@ void PhysicsWorld::AddCollisionModel(StaticMeshVertex* vertices, size_t vertices // Create collision body m_collisionModels[index].object = new btCollisionObject(); m_collisionModels[index].object->setCollisionShape(m_collisionModels[index].shape); - m_collisionModels[index].object->setUserPointer(&m_collisionModels[index]); + //m_collisionModels[index].object->setUserPointer(&m_collisionModels[index]); // Add to scene m_world->addCollisionObject(m_collisionModels[index].object); // Report - Msg("PhysicsSystem::AddCollisionModel: %i triangles %i bytes", trianglesCount, trianglesCount * sizeof(btVector3)); + Msg("PhysicsWorld::AddCollisionModel: %i triangles %i bytes", trianglesCount, trianglesCount * sizeof(btVector3)); } void PhysicsWorld::Reset() @@ -251,7 +265,7 @@ void PhysicsWorld::Reset() } } - Msg("PhysicsSystem: Destroyed %d static collision models", numModels); + Msg("PhysicsWorld: Destroyed %d static collision models", numModels); m_collisionModels.clear(); } diff --git a/src/engine/physics/rigidbody.cpp b/src/engine/physics/rigidbody.cpp index e820509..9f28836 100644 --- a/src/engine/physics/rigidbody.cpp +++ b/src/engine/physics/rigidbody.cpp @@ -76,7 +76,7 @@ RigidBody::~RigidBody() // } // } // -// CreateBody(); +// CreatePlayerBody(); // UpdateBodyTranslationDirty(); // // if (changeFilterUsableHack) diff --git a/src/game/game.cpp b/src/game/game.cpp index 97dcb26..58db76a 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -67,6 +67,7 @@ void registerClasses() // base thing GetLuaState().GetGlobals().RegisterDirect("load_script", &luaLoadScript); GetLuaState().DoString("g_factory = {}"); + GetLuaState().DoString("g_entities = {}"); registerEngine(); } @@ -196,11 +197,8 @@ void Game::LoadLevelXML(const char* mapname) } } - IEntityBase* entity = Lua_CreateEntity(classname.as_string()); - - // this is pure C++ entity :) - if (!entity) - entity = g_entityManager->CreateEntity(classname.as_string()); + // Create entity and expose it to the engine + Entity* entity = static_cast(Lua_CreateEntity(classname.as_string())); pugi::xml_node position = entitynode.child("Position"); if (position) @@ -212,6 +210,22 @@ void Game::LoadLevelXML(const char* mapname) entity->SetPosition(glm::vec3(x, y, z)); } + pugi::xml_node model = entitynode.child("Model"); + if (model) + { + const char* filename = model.attribute("filename").as_string(); + if (filename) + entity->LoadModel(filename); + } + + pugi::xml_node physics = entitynode.child("Physics"); + if (physics) + { + bool value = physics.attribute("value").as_bool(); + if (value) + entity->CreateTestBody(); + } + //IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string()); g_world->AddEntity(entity); } @@ -221,13 +235,62 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname) { using namespace LuaPlus; - //if (!classname) - // classname = "Entity"; - SDL_assert_always(classname); - LuaPrototype* pluaprototype = nullptr; + // find prototype + LuaPrototype* luaprototype = Lua_FindPrototype(classname); + // create an entity + Entity* entity = nullptr; + if (luaprototype) + { + entity = static_cast(g_entityManager->CreateEntity(luaprototype->m_enginename.c_str())); + + // override classname because of entity system is so dumb + entity->SetClassname(luaprototype->m_luaname.c_str()); + } + else + { + entity = static_cast(g_entityManager->CreateEntity(classname)); + } + + SDL_assert_always(entity); + + // get the factrory + LuaObject factory = GetLuaState().GetGlobal("g_factory"); + + // and the lookup table + LuaObject lookup = GetLuaState().GetGlobal("g_entities"); + + // generate name + char entityname[256]; + snprintf(entityname, sizeof(entityname), "%s_%d", classname, factory.GetTableCount()); + + // create an table + LuaObject entityTable = GetLuaState().CreateTable(); + entityTable.SetString("m_name", entityname); + entityTable.SetInteger("m_id", entity->GetID()); + + // assign prototype + if (luaprototype) + { + LuaObject prototype = GetLuaState().GetGlobal(luaprototype->m_luaname.c_str()); + SDL_assert_always(!prototype.IsNil()); + entityTable.SetMetatable(prototype); + } + + // link to the entity + entity->InitFromTable(entityTable); + + // push in to the factory + factory.SetObject(entityname, entityTable); + lookup.SetObject(entity->GetID(), entityTable); + + return entity; +} + +LuaPrototype* Game::Lua_FindPrototype(const char* classname) +{ // find a prototype for (std::vector::iterator it = g_prototypes.begin(); it != g_prototypes.end(); @@ -235,42 +298,9 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname) { if (strcmp((*it).m_luaname.c_str(), classname) == 0) { - pluaprototype = &(*it); - break; + return &(*it); } } - - if (pluaprototype) - { - Entity* entity = static_cast(g_entityManager->CreateEntity(pluaprototype->m_enginename.c_str())); - SDL_assert_always(entity); - - // get a prototype - LuaObject prototype = GetLuaState().GetGlobal(pluaprototype->m_luaname.c_str()); - SDL_assert_always(!prototype.IsNil()); - //prototype.SetObject("__index", prototype); - - // generate table - LuaObject factory = GetLuaState().GetGlobal("g_factory"); - - // generate name - std::string entityname = pluaprototype->m_luaname + "_" + std::to_string(factory.GetTableCount()); - - // create an table - LuaObject entityTable = GetLuaState().GetGlobals().CreateTable(entityname.c_str()); - entityTable.SetMetatable(prototype); - entityTable.SetString("m_name", entityname.c_str()); - - // push in to the factory - factory.SetObject(entityname.c_str(), entityTable); - - // link to the entity - entity->InitFromTable(entityTable); - - return entity; - } - - //IEntityBase* entity = g_entityManager->CreateEntity(classname); return nullptr; } @@ -278,3 +308,37 @@ IEntityBase* Game::Lua_CreateEntity(const char* classname) void Game::Shutdown() { } + +//LuaPrototype* pluaprototype = Lua_FindPrototype(classname); +// +//if (pluaprototype) +//{ +// Entity* entity = static_cast(g_entityManager->CreateEntity(pluaprototype->m_enginename.c_str())); +// SDL_assert_always(entity); + +// // get a prototype +// LuaObject prototype = GetLuaState().GetGlobal(pluaprototype->m_luaname.c_str()); +// SDL_assert_always(!prototype.IsNil()); +// //prototype.SetObject("__index", prototype); + +// // generate table +// LuaObject factory = GetLuaState().GetGlobal("g_factory"); + +// // generate name +// std::string entityname = pluaprototype->m_luaname + "_" + std::to_string(factory.GetTableCount()); +// +// // create an table +// LuaObject entityTable = GetLuaState().GetGlobals().CreateTable(entityname.c_str()); +// entityTable.SetMetatable(prototype); +// entityTable.SetString("m_name", entityname.c_str()); +// +// // push in to the factory +// factory.SetObject(entityname.c_str(), entityTable); + +// // link to the entity +// entity->InitFromTable(entityTable); + +// return entity; +//} + +//IEntityBase* entity = g_entityManager->CreateEntity(classname); diff --git a/src/game/game.h b/src/game/game.h index ae74b81..f233175 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -2,6 +2,7 @@ #define GAME_H class IEntityBase; +struct LuaPrototype; class Game { @@ -13,6 +14,8 @@ public: IEntityBase* Lua_CreateEntity(const char* classname); + LuaPrototype* Lua_FindPrototype(const char* classname); + void Shutdown(); }; diff --git a/src/game/game_object.cpp b/src/game/game_object.cpp index 6342a1c..6fe00af 100644 --- a/src/game/game_object.cpp +++ b/src/game/game_object.cpp @@ -66,7 +66,10 @@ void ActorBase_ActivateCamera(LuaPlus::LuaState* state) REGISTER_ENTITY(Entity); Entity::Entity() : - m_model(nullptr) + m_model(nullptr), + m_shape(nullptr), + m_rigidBody(nullptr), + m_bodyDirty(false) { } @@ -84,15 +87,20 @@ Entity::~Entity() if (name.IsString()) { LuaPlus::LuaObject factory = GetLuaState().GetGlobal("g_factory"); - factory.SetNil(m_luaObject); + factory.SetNil(name.GetString()); } + LuaPlus::LuaObject lookup = GetLuaState().GetGlobal("g_entities"); + lookup.SetNil(GetID()); + m_luaObject.AssignNil(); } } void Entity::Update(float dt) { + UpdateBody(); + if ( m_onUpdateFunction.IsFunction()) { LuaPlus::LuaFunctionVoid function = m_onUpdateFunction; @@ -113,6 +121,21 @@ void Entity::Render() } } +void Entity::OnCollide(IEntityBase* other) +{ + if (!m_onCollideFunction.IsFunction()) + return; + + // find entity + LuaPlus::LuaObject lookup = GetLuaState().GetGlobal("g_entities"); + LuaPlus::LuaObject otherTable = lookup.GetByIndex(other->GetID()); + if (!otherTable.IsNil()) + { + LuaPlus:: LuaFunctionVoid function = m_onCollideFunction; + function(m_luaObject, otherTable); + } +} + const std::string& Entity::GetName() { return m_name; @@ -148,9 +171,10 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object) m_onInitFunction = m_luaObject.GetByName("on_init"); m_onShutdownFunction = m_luaObject.GetByName("on_shutdown"); m_onUpdateFunction = m_luaObject.GetByName("on_update"); + m_onCollideFunction = m_luaObject.GetByName("on_collide"); // check - SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction()); + //SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction()); // register base entity functions RegisterBaseFunctions(); @@ -162,8 +186,11 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object) m_luaObject.SetLightUserdata("__object", this); // call init - LuaPlus::LuaFunctionVoid onInitFunction = m_onInitFunction; - onInitFunction(m_luaObject); + if (m_onInitFunction.IsFunction()) + { + LuaPlus::LuaFunctionVoid onInitFunction = m_onInitFunction; + onInitFunction(m_luaObject); + } } void Entity::RegisterBaseFunctions() @@ -171,6 +198,7 @@ void Entity::RegisterBaseFunctions() m_luaObject.Register("load_model", *this, &Entity::Lua_LoadModel); m_luaObject.Register("translate", *this, &Entity::Lua_Translate); m_luaObject.Register("set_position", *this, &Entity::Lua_SetPosition); + m_luaObject.Register("get_classname", *this, &Entity::Lua_GetClassname); // m_luaObject.RegisterDirect("load_model", &Entity_LoadModel); //m_luaObject.RegisterDirect("set_visible", &Entity_SetVisible); @@ -237,17 +265,69 @@ int Entity::Lua_SetPosition(LuaPlus::LuaState* state) return 0; } +int Entity::Lua_GetClassname(LuaPlus::LuaState* state) +{ + state->PushString(GetClassname()); + return 1; +} + const LuaPlus::LuaObject& Entity::GetLuaObject() { return m_luaObject; } +void Entity::CreateTestBody() +{ + m_shape = new btBoxShape(btVector3(0.2f, 0.2f, 0.2f)); + + m_mass = 80.0f; + btVector3 local_inertia(0.0f, 0.0f, 0.0f); + if (m_mass > 0.f) { + m_shape->calculateLocalInertia(m_mass, local_inertia); + } + + btRigidBody::btRigidBodyConstructionInfo rigid_body_ci(m_mass, nullptr, m_shape, local_inertia); + + m_rigidBody = new btRigidBody(rigid_body_ci); + m_rigidBody->setUserPointer(this); + m_rigidBody->setMotionState(&m_ph_motion_state); + m_ph_motion_state.setBody(m_rigidBody); + + // I'm sure that position is valid + btTransform xform; + xform.setIdentity(); + xform.setOrigin(glmVectorToBt(m_position)); + m_rigidBody->setWorldTransform(xform); + + // #TODO: body filter and mask + g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody); + + m_bodyDirty = true; +} + +void Entity::UpdateBody() +{ + m_position = btVectorToGlm(m_ph_motion_state.m_transform.getOrigin()); + m_ph_motion_state.m_transform.getRotation().getEulerZYX(m_rotation.z, m_rotation.y, m_rotation.x); + m_rotation = glm::degrees(m_rotation); +} + +void Entity::UpdateBodyDirty() +{ + if (m_bodyDirty) + { + btTransform xform; + xform.setIdentity(); + xform.setOrigin(glmVectorToBt(m_position)); + m_rigidBody->setWorldTransform(xform); + + m_bodyDirty = false; + } +} + REGISTER_ENTITY(ActorBase); -ActorBase::ActorBase() : - m_shape(nullptr), - m_rigidBody(nullptr), - m_bodyDirty(false) +ActorBase::ActorBase() { } @@ -273,7 +353,7 @@ void ActorBase::Update(float dt) static bool s_test = true; if (s_test) { - UpdateBody(); + UpdateBodyDirty(); Entity::Update(dt); AfterEngineStep(); } else { @@ -340,14 +420,27 @@ void ActorBase::UpdateBodyMovement(float dt) if (movementDir & EMovementDir_Right) dir += glm::normalize(glm::cross(camFront, m_camera.GetUp())); + btVector3 currentvel = m_rigidBody->getLinearVelocity(); glm::vec3 velocity = dir * speed; - if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump)) + if (OnGround()) { + m_rigidBody->setLinearVelocity(btVector3(velocity.x, currentvel.y(), velocity.z)); + if (movementDir & EMovementDir_Jump) { + m_rigidBody->setLinearVelocity(btVector3(currentvel.x(), PLAYER_PHYS_JUMPSPEEDY, currentvel.z())); + } + } else { + float airControl = 0.2f; + btVector3 airvel = currentvel + glmVectorToBt(dir * speed * airControl * dt); + m_rigidBody->setLinearVelocity(btVector3(airvel.x(), currentvel.y(), airvel.z())); + } + + /*if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump)) m_rigidBody->setLinearVelocity(glmVectorToBt(velocity)); if ((movementDir & EMovementDir_Jump) && OnGround()) { - m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY*25, 0.0f)); - } + m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY, 0.0f)); + movementDir &= ~EMovementDir_Jump; + }*/ } void ActorBase::UpdateCameraLook() @@ -371,19 +464,6 @@ void ActorBase::UpdateCameraLook() m_camera.SetYawPitch(yaw, pitch); } -void ActorBase::UpdateBody() -{ - if (m_bodyDirty) - { - btTransform xform; - xform.setIdentity(); - xform.setOrigin(glmVectorToBt(m_position)); - m_rigidBody->setWorldTransform(xform); - - m_bodyDirty = false; - } -} - void ActorBase::ActivateCamera() { g_inputManager.SetRelativeMouseMode(true); @@ -391,7 +471,7 @@ void ActorBase::ActivateCamera() g_cameraManager.SetActiveCamera(&m_camera); } -void ActorBase::CreateBody() +void ActorBase::CreatePlayerBody() { m_shape = new btCapsuleShape(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0); @@ -417,7 +497,14 @@ void ActorBase::CreateBody() // ACTOR STUFF m_rigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f)); - m_rigidBody->setFriction(2.5f); + + + //m_rigidBody->setFriction(2.5f); + + m_rigidBody->setFriction(0.0f); + m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f)); + m_rigidBody->setDamping(0.1f, 0.0f); + m_rigidBody->setActivationState(DISABLE_DEACTIVATION); // #TODO: body filter and mask @@ -492,7 +579,7 @@ int ActorBase::Lua_ActivateCamera(LuaPlus::LuaState* state) int ActorBase::Lua_CreateBody(LuaPlus::LuaState* state) { - CreateBody(); + CreatePlayerBody(); return 0; } @@ -523,16 +610,20 @@ uint32_t ActorBase::GenMovementDir() return movementDir; } -REGISTER_ENTITY(Weapon); +REGISTER_ENTITY(WeaponBase); -Weapon::Weapon() +WeaponBase::WeaponBase() { } -Weapon::~Weapon() +WeaponBase::~WeaponBase() { } -void Weapon::Update(float dt) +void WeaponBase::Update(float dt) +{ +} + +void WeaponBase::Fire(const glm::vec3& direction, float damage) { } diff --git a/src/game/game_object.h b/src/game/game_object.h index d3391c8..4da9f58 100644 --- a/src/game/game_object.h +++ b/src/game/game_object.h @@ -67,6 +67,7 @@ public: virtual void Update(float dt); virtual void Render(); + virtual void OnCollide(IEntityBase* other); // Game entity extensions const std::string& GetName(); @@ -76,6 +77,11 @@ public: void SetVisible(bool visible); bool GetVisible(); + // Game entity physics + void CreateTestBody(); + void UpdateBody(); + void UpdateBodyDirty(); + // Game entity lua bindings void InitFromTable(LuaPlus::LuaObject& _object); @@ -89,6 +95,7 @@ public: int Lua_LoadModel(LuaPlus::LuaState* state); int Lua_Translate(LuaPlus::LuaState* state); int Lua_SetPosition(LuaPlus::LuaState* state); + int Lua_GetClassname(LuaPlus::LuaState* state); const LuaPlus::LuaObject& GetLuaObject(); @@ -101,6 +108,14 @@ protected: LuaPlus::LuaObject m_onInitFunction; LuaPlus::LuaObject m_onShutdownFunction; LuaPlus::LuaObject m_onUpdateFunction; + LuaPlus::LuaObject m_onCollideFunction; + +protected: + btCollisionShape* m_shape; + btRigidBody* m_rigidBody; + ph_motion_state m_ph_motion_state; + float m_mass; + bool m_bodyDirty; }; class ActorBase : public Entity @@ -119,11 +134,9 @@ public: void UpdateCameraLook(); - void UpdateBody(); - void ActivateCamera(); - void CreateBody(); + void CreatePlayerBody(); bool OnGround(); @@ -143,21 +156,18 @@ private: private: Camera m_camera; -private: - btCollisionShape* m_shape; - btRigidBody* m_rigidBody; - ph_motion_state m_ph_motion_state; - float m_mass; - bool m_bodyDirty; + }; -class Weapon : public Entity +class WeaponBase : public Entity { public: - Weapon(); - ~Weapon(); + WeaponBase(); + ~WeaponBase(); virtual void Update(float dt); + + void Fire(const glm::vec3& direction, float damage); }; #endif // !GAME_OBJECT_H diff --git a/src/render/render.cpp b/src/render/render.cpp index 0b808cf..d77b191 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -32,6 +32,10 @@ glm::vec3 g_viewOrient; #define GL_DEBUG_TYPE_ERROR_ARB 0x824C #endif // !GL_DEBUG_TYPE_ERROR_ARB +#ifndef GL_DEBUG_OUTPUT +#define GL_DEBUG_OUTPUT 0x92E0 +#endif // !GL_DEBUG_OUTPUT + #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); @@ -52,7 +56,7 @@ void APIENTRY GL_DebugOutput(GLenum source, const char* message, const void* userParam) { - // Nvidia spam too much about filenameBuffer mapping + // Nvidia spam too much about buffer mapping if (type == 0x8251) return; @@ -63,6 +67,7 @@ void APIENTRY GL_DebugOutput(GLenum source, if (type == GL_DEBUG_TYPE_ERROR_ARB) { bool debug = true; + __debugbreak(); } } @@ -107,25 +112,13 @@ void Render::Init(SDL_Window* pWindow) Msg("%s", (const char*)glGetString(GL_VENDOR)); Msg("%s", (const char*)glGetString(GL_RENDERER)); Msg("OpenGL ver. %s", (const char*)glGetString(GL_VERSION)); - Msg("Context created with OpenGL version %d.%d", GLVersion.major, GLVersion.minor); + Msg("Initializing OpenGL extensions..."); + InitGLExtensions(); + // Reset OpenGL error stack glGetError(); - // Load extension - glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); - - // Enable debug output - if (glDebugMessageCallbackARB) - { - Msg("...found GL_ARB_debug_output"); - - //glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - glDebugMessageCallbackARB(GL_DebugOutput, NULL); - } - - // Create render device g_renderDevice = new RenderDevice(); @@ -163,6 +156,75 @@ void Render::Init(SDL_Window* pWindow) } } +void Render::InitGLExtensions() +{ + //// Load extension + //glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); + + //// Enable debug output + //if (glDebugMessageCallbackARB) + //{ + // Msg("...found GL_ARB_debug_output"); + + // //glEnable(GL_DEBUG_OUTPUT); + // glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + // glDebugMessageCallbackARB(GL_DebugOutput, NULL); + //} + + //bool found_WGL_EXT_swap_control = false; + bool found_GL_ARB_debug_output = false; + + // Load extensions + char* extensions = (char*)glGetString(GL_EXTENSIONS); // OpenGL Error: GL_INVALID_ENUM at D:\projects\old\pke\src\render\shadersystem.cpp:169 + if (extensions) + { + char* extension = strtok(extensions, " "); + while (extension) + { + //if (strcmp(extension, "WGL_EXT_swap_control") == 0) + // found_WGL_EXT_swap_control = true; + + if (strcmp(extension, "GL_ARB_debug_output") == 0) + found_GL_ARB_debug_output = true; + + extension = strtok(NULL, " "); + } + } + else // core profile + { + int NumberOfExtensions; + glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions); + + for (int i = 0; i < NumberOfExtensions; i++) { + char* extension = (char*)glGetStringi(GL_EXTENSIONS, i); + + //if (strcmp(extension, "WGL_EXT_swap_control") == 0) + // found_WGL_EXT_swap_control = true; + + if (strcmp(extension, "GL_ARB_debug_output") == 0) + found_GL_ARB_debug_output = true; + + } + } + + // Enable debug output + if (found_GL_ARB_debug_output) + { + Msg("...found GL_ARB_debug_output"); + + glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); + + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + glDebugMessageCallbackARB(GL_DebugOutput, NULL); + } + else + { + Msg("...not found GL_ARB_debug_output"); + } + +} + void Render::Shutdown() { if (m_usingVAO) @@ -236,15 +298,20 @@ void Render::RenderStats() { char buffer[256]; - snprintf(buffer, sizeof(buffer), "Scene: %s", g_sceneManager->getSceneName()); + snprintf(buffer, sizeof(buffer), "FPS: %.1f", ImGui::GetIO().Framerate); ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 0.0f), 0xffffffff, buffer); - snprintf(buffer, sizeof(buffer), "numModels: %d", g_NumModels); + snprintf(buffer, sizeof(buffer), "Scene: %s", g_sceneManager->getSceneName()); ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 15.0f), 0xffffffff, buffer); + + snprintf(buffer, sizeof(buffer), "numModels: %d", g_NumModels); + ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 30.0f), 0xffffffff, buffer); } void Render::Present(bool vsync) { + SDL_GL_SetSwapInterval(vsync); + SDL_GL_SwapWindow(m_pWindow); // reset stats diff --git a/src/render/render.h b/src/render/render.h index 4932196..41448d5 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -16,6 +16,7 @@ public: ~Render(); void Init(SDL_Window* pWindow); + void InitGLExtensions(); void Shutdown(); void RenderScene();