Reworked Primitive logic for scene rendering FileUpdateTester works now .....undefined
| @@ -1,19 +1,17 @@ | |||
| s0 = SceneSetup.New("DefaultSetup") | |||
| -- Gear 0: New style | |||
| em0 = EasyMesh.New("Mesh0"); | |||
| s0:AddLight("Point") | |||
| s0:Position(0, 0, 15) | |||
| s0:Color("#bbb") | |||
| s0:AddLight("Directional") | |||
| s0:Position(0, 0, 15) | |||
| s0:Color("#bbb") | |||
| --addlight 1 position (3 10 0) color #444 | |||
| em0:SetColor("#f00") | |||
| em0:AddBox(2) | |||
| em0:TranslateY(1.5) | |||
| em0:AddBox(2.5) | |||
| s0:Setup() | |||
| s0:Color("#ddd") | |||
| s0:Show("Gizmo") | |||
| s0:Show("Light") | |||
| -- Gear 1: New style | |||
| em1 = EasyMesh.New("Mesh1"); | |||
| em1:SetColor("#0f0") | |||
| em1:AddBox(2.5) | |||
| em1:TranslateY(2) | |||
| em1:AddBox(2) | |||
| --SCENE SETUP END | |||
| --addlight 0.0 position (1 0 1) color #0ff | |||
| --addlight 0.0 position (-0.2 -1 -0.5) color (.0 .2 .5 1) | |||
| @@ -0,0 +1,19 @@ | |||
| s0 = SceneSetup.New("DefaultSetup") | |||
| s0:AddLight("Point") | |||
| s0:Position(0, 0, 15) | |||
| s0:Color("#bbb") | |||
| s0:AddLight("Directional") | |||
| s0:Position(0, 0, 15) | |||
| s0:Color("#bbb") | |||
| --addlight 1 position (3 10 0) color #444 | |||
| s0:Setup() | |||
| s0:Color("#ddd") | |||
| s0:Show("Gizmo") | |||
| s0:Show("Light") | |||
| --SCENE SETUP END | |||
| --addlight 0.0 position (1 0 1) color #0ff | |||
| --addlight 0.0 position (-0.2 -1 -0.5) color (.0 .2 .5 1) | |||
| @@ -34,7 +34,7 @@ static int const TEXTURE_WIDTH = 256; | |||
| #define DEFAULT_HEIGHT (400.f * R_M) | |||
| #else | |||
| #define DEFAULT_WIDTH (1200.f * R_M) | |||
| #define DEFAULT_HEIGHT (400.f * R_M) | |||
| #define DEFAULT_HEIGHT (800.f * R_M) | |||
| #endif //HAS_WEB | |||
| #define WIDTH ((float)Video::GetSize().x) | |||
| #define HEIGHT ((float)Video::GetSize().y) | |||
| @@ -95,14 +95,26 @@ public: | |||
| array<vec3> m_targets; | |||
| }; | |||
| //EasyMeshViewerObject -------------------------------------------------------- | |||
| void EasyMeshViewerObject::TickDraw(float seconds, Scene &scene) | |||
| { | |||
| switch (m_mesh.GetMeshState().ToScalar()) | |||
| { | |||
| case MeshRender::NeedConvert: { m_mesh.MeshConvert(); break; } | |||
| case MeshRender::CanRender: { scene.AddPrimitive(m_mesh, mat4::identity/*TODO:FIX THAT*/); break; } | |||
| default: break; | |||
| } | |||
| } | |||
| //EasyMeshLoadJob ------------------------------------------------------------- | |||
| bool EasyMeshLoadJob::DoWork() | |||
| { | |||
| if (m_loader.ExecLuaFile(m_path)) | |||
| map<String, EasyMeshLuaObject*> meshes; | |||
| if (m_loader.ExecLuaFile(m_path) && EasyMeshLuaLoader::GetRegisteredMeshes(meshes)) | |||
| { | |||
| array<EasyMeshLuaObject*>& objs = m_loader.GetInstances(); | |||
| for (EasyMeshLuaObject* obj : objs) | |||
| m_meshes << new EasyMeshViewerObject(obj->GetMesh()); | |||
| array<String> keys = meshes.keys(); | |||
| for (String key : keys) | |||
| m_meshes << new EasyMeshViewerObject(key, meshes[key]->GetMesh()); | |||
| } | |||
| return !!m_meshes.count(); | |||
| } | |||
| @@ -111,7 +123,7 @@ bool EasyMeshLoadJob::DoWork() | |||
| MeshViewerLoadJob* EasyMeshLoadJob::GetInstance(String const& path) | |||
| { | |||
| if (Check(path)) | |||
| return new MeshViewerLoadJob(path); | |||
| return new EasyMeshLoadJob(path); | |||
| return nullptr; | |||
| } | |||
| @@ -126,11 +138,14 @@ void EasyMeshLoadJob::RetrieveResult(class MeshViewer* app) | |||
| //MeshViewer ------------------------------------------------------------------ | |||
| MeshViewer::MeshViewer(char const *file_name) | |||
| : m_file_name(file_name) | |||
| { } | |||
| { | |||
| LolImGui::Init(); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| MeshViewer::~MeshViewer() | |||
| { | |||
| LolImGui::Shutdown(); | |||
| Stop(); | |||
| } | |||
| @@ -140,26 +155,30 @@ void MeshViewer::Start() | |||
| /** OLD STUFF **/ | |||
| //Prepare(); | |||
| //Scene setup | |||
| m_setup_loader.ExecLuaFile("meshviewer_init.lua"); | |||
| //Threads setup | |||
| m_entities << (m_file_check = new FileUpdateTester()); | |||
| m_file_status = m_file_check->RegisterFile(m_file_name); | |||
| m_entities << (m_file_loader = new DefaultThreadManager(4, 0)); | |||
| //Scene setup | |||
| m_ssetup_file_name = "data/meshviewer.init.lua"; | |||
| UpdateSceneSetup(); | |||
| //m_entities << (m_file_loader = new DefaultThreadManager(1, 1)); | |||
| //Mesh file | |||
| m_file_status = m_file_check->RegisterFile(m_file_name); | |||
| m_file_loader->AddJob(GetLoadJob(m_file_name)); | |||
| //Camera setup | |||
| m_camera = new Camera(); | |||
| m_camera->SetView(vec3(0.f, 0.f, 10.f), vec3::zero, vec3::axis_y); | |||
| m_camera->SetProjection(0.f, .0001f, 2000.f, WIDTH * SCREEN_W, RATIO_HW); | |||
| m_camera->UseShift(true); | |||
| m_camera->SetView(vec3(10.f, 10.f, 10.f), vec3::zero, vec3::axis_y); | |||
| m_camera->SetProjection(40.f, .0001f, 2000.f); | |||
| //m_camera->SetProjection(90.f, .0001f, 2000.f, WIDTH * SCREEN_W, RATIO_HW); | |||
| //m_camera->UseShift(true); | |||
| g_scene->PushCamera(m_camera); | |||
| #if HAS_INPUT | |||
| InputProfile& ip = m_profile; | |||
| ip.AddBindings<MeshViewerKeyInput, MeshViewerKeyInput::KBD_BEG, MeshViewerKeyInput::KBD_END>(InputProfileType::Keyboard); | |||
| ip.AddBindings<MeshViewerKeyInput, MeshViewerKeyInput::MSE_BEG, MeshViewerKeyInput::MSE_END>(InputProfileType::Keyboard); | |||
| ip.AddBindings<MeshViewerKeyInput, MeshViewerKeyInput::MSE_BEG, MeshViewerKeyInput::MSE_END>(InputProfileType::MouseKey); | |||
| m_entities << (m_controller = new Controller("MeshViewer")); | |||
| m_controller->Init(m_profile); | |||
| @@ -179,9 +198,11 @@ void MeshViewer::Start() | |||
| //----------------------------------------------------------------------------- | |||
| void MeshViewer::Stop() | |||
| { | |||
| //Destroy scene setup | |||
| UpdateSceneSetup(true); | |||
| //Destroy core stuff | |||
| if (m_camera) g_scene->PopCamera(m_camera); | |||
| if (m_ssetup) delete m_ssetup; | |||
| m_file_check->UnregisterFile(m_file_status); | |||
| @@ -192,7 +213,6 @@ void MeshViewer::Stop() | |||
| while (m_objs.count()) delete m_objs.Pop(); | |||
| //Nullify all | |||
| m_ssetup = nullptr; | |||
| m_camera = nullptr; | |||
| m_controller = nullptr; | |||
| m_file_check = nullptr; | |||
| @@ -202,6 +222,35 @@ void MeshViewer::Stop() | |||
| m_init = false; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| void MeshViewer::UpdateSceneSetup(bool only_destroy) | |||
| { | |||
| //Delete previous setups | |||
| array<String> keys = m_ssetups.keys(); | |||
| for (String key : keys) | |||
| delete m_ssetups[key]; | |||
| m_ssetups.empty(); | |||
| if (m_ssetup_file_status) | |||
| { | |||
| m_file_check->UnregisterFile(m_ssetup_file_status); | |||
| delete m_ssetup_file_status; | |||
| } | |||
| m_ssetup_file_status = nullptr; | |||
| //Init new setups | |||
| if (!only_destroy) | |||
| { | |||
| m_ssetup_loader.ExecLuaFile(m_ssetup_file_name); | |||
| if (m_ssetup_loader.GetLoadedSetups(m_ssetups)) | |||
| { | |||
| m_ssetup_file_status = m_file_check->RegisterFile(m_ssetup_file_name); | |||
| array<String> keys = m_ssetups.keys(); | |||
| if (!m_ssetup_name.count() || !keys.find(m_ssetup_name)) | |||
| m_ssetup_name = keys[0]; | |||
| } | |||
| } | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| MeshViewerLoadJob* MeshViewer::GetLoadJob(String const& path) | |||
| { | |||
| @@ -220,17 +269,67 @@ void MeshViewer::TickGame(float seconds) | |||
| m_first_tick = true; | |||
| //Check file update | |||
| ASSERT(m_file_status); | |||
| if (false && m_file_status->HasUpdated()) | |||
| #if HAS_INPUT | |||
| { | |||
| //Shutdown logic | |||
| if (m_controller->IsKeyPressed(MeshViewerKeyInput::Exit)) | |||
| Ticker::Shutdown(); | |||
| } | |||
| #endif //HAS_INPUT | |||
| static bool default_open = true; | |||
| //static float fov = 40.f; | |||
| //static vec3 sphere_pos = vec3(20.f, 45.f, 45.f); | |||
| //static bool use_custom_cam = true; | |||
| //static float f; | |||
| //static int mesh_idx = 0; | |||
| //static array<char*> mesh_names_char; | |||
| //static array<String> mesh_names_str; | |||
| //Draw viewer objects | |||
| m_menu_mesh_names_char.empty(); | |||
| m_menu_mesh_names_str.empty(); | |||
| for (ViewerObject* obj : m_objs) | |||
| m_menu_mesh_names_str << obj->GetName(); | |||
| for (ptrdiff_t i = 0; i < m_menu_mesh_names_str.count(); ++i) | |||
| m_menu_mesh_names_char << m_menu_mesh_names_str[i].C(); | |||
| ImGuiIO& io = ImGui::GetIO(); | |||
| ImGui::Begin("Camera Setup" /*, &default_open, ImGuiWindowFlags_AlwaysAutoResize*/); | |||
| { | |||
| ImGui::Text("Hello, world!"); | |||
| ImGui::Checkbox("Use custom cam", &m_menu_cam_useage); | |||
| ImGui::Text("MousePos! %.2f/%.2f", io.MousePos.x, io.MousePos.y); | |||
| ImGui::Text("Left Mouse: %s", io.MouseDown[0] ? "true" : "false"); | |||
| ImGui::SliderFloat("Cam FOV", &m_menu_cam_fov, 0.1f, 120.0f); | |||
| ImGui::SliderFloat("Cam Distance", &m_menu_cam_pos.x, 0.1f, 30.f); | |||
| ImGui::SliderFloat("Cam H-axis", &m_menu_cam_pos.y, -180.f, 180.f); | |||
| ImGui::SliderFloat("Cam V-axis", &m_menu_cam_pos.z, -89.f, 89.f); | |||
| ImGui::ListBox("Meshes", &m_menu_mesh_idx, (const char**)m_menu_mesh_names_char.data(), (int)m_menu_mesh_names_char.count()); | |||
| //ImGui::ListBox() | |||
| } | |||
| ImGui::End(); | |||
| //Camera | |||
| if (m_menu_cam_useage) | |||
| { | |||
| MeshViewerLoadJob* job = GetLoadJob(m_file_name); | |||
| if (!job) | |||
| m_file_loader->AddJob(job); | |||
| vec3 sphere_pos_rad = m_menu_cam_pos; | |||
| sphere_pos_rad.z = (sphere_pos_rad.z > 0.f) ? (90.f - sphere_pos_rad.z) : (sphere_pos_rad.z - 90.f); | |||
| sphere_pos_rad = vec3(sphere_pos_rad.x, radians(sphere_pos_rad.y), radians(sphere_pos_rad.z)); | |||
| m_camera->SetFov(m_menu_cam_fov); | |||
| m_camera->SetPosition(cartesian(sphere_pos_rad)); | |||
| m_camera->SetTarget(vec3::zero, vec3::axis_y); | |||
| } | |||
| //Check file update | |||
| ASSERT(m_file_status); | |||
| //if (false) //DEBUG | |||
| //m_file_status->GetTime() | |||
| if (m_file_status->HasUpdated()) | |||
| m_file_loader->AddJob(GetLoadJob(m_file_name)); | |||
| //Check work done | |||
| if (false) | |||
| //if (false) //DEBUG | |||
| { | |||
| array<ThreadJob*> result; | |||
| m_file_loader->GetWorkResult(result); | |||
| @@ -257,6 +356,16 @@ void MeshViewer::TickDraw(float seconds, Scene &scene) | |||
| { | |||
| super::TickDraw(seconds, scene); | |||
| //Draw viewer objects | |||
| if (m_menu_mesh_idx >= 0 && m_menu_mesh_idx < m_objs.count()) | |||
| m_objs[m_menu_mesh_idx]->TickDraw(seconds, scene); | |||
| //Draw gizmos & grid | |||
| Debug::DrawGizmo(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | |||
| Debug::DrawSetupColor(Color::white); | |||
| Debug::DrawSetupSegment(1.f); | |||
| Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | |||
| /** OLD STUFF **/ | |||
| //Draw(seconds); | |||
| } | |||
| @@ -131,31 +131,41 @@ class ViewerObject | |||
| { | |||
| public: | |||
| ViewerObject() { } | |||
| ViewerObject(String const& name) : m_name(name) { } | |||
| virtual ~ViewerObject() { } | |||
| virtual void TickDraw(float seconds, Scene &scene) { } | |||
| String GetName() { return m_name; } | |||
| protected: | |||
| String m_name; | |||
| }; | |||
| //EasyMeshViewerObject -------------------------------------------------------- | |||
| class EasyMeshViewerObject : public ViewerObject | |||
| { | |||
| typedef ViewerObject super; | |||
| public: | |||
| EasyMeshViewerObject() | |||
| : ViewerObject() { } | |||
| EasyMeshViewerObject(EasyMesh const& mesh) | |||
| : EasyMeshViewerObject() | |||
| EasyMeshViewerObject(String const& name, EasyMesh const& mesh) | |||
| : ViewerObject(name) | |||
| { | |||
| Init(mesh); | |||
| Init(name, mesh); | |||
| } | |||
| virtual ~EasyMeshViewerObject() { } | |||
| void Init(EasyMesh const& mesh) | |||
| virtual void TickDraw(float seconds, Scene &scene); | |||
| void Init(String const& name, EasyMesh const& mesh) | |||
| { | |||
| m_name = name; | |||
| m_mesh = mesh; | |||
| } | |||
| protected: | |||
| EasyMesh m_mesh; | |||
| EasyMesh m_mesh; | |||
| }; | |||
| //MeshViewerLoadJob ----------------------------------------------------------- | |||
| @@ -214,6 +224,8 @@ public: | |||
| void Start(); | |||
| void Stop(); | |||
| void UpdateSceneSetup(bool only_destroy = false); | |||
| MeshViewerLoadJob* GetLoadJob(String const& path); | |||
| void AddViewerObj(ViewerObject* obj) { m_objs << obj; } | |||
| @@ -238,9 +250,22 @@ private: | |||
| bool m_init = false; | |||
| bool m_first_tick = false; | |||
| InputProfile m_profile; | |||
| Camera * m_camera = nullptr; | |||
| SceneSetup* m_ssetup = nullptr; | |||
| SceneSetupLuaLoader m_setup_loader; | |||
| Camera* m_camera = nullptr; | |||
| //ImGui stuff | |||
| bool m_menu_cam_useage = true; | |||
| float m_menu_cam_fov = 40.f; | |||
| vec3 m_menu_cam_pos = vec3(20.f, 45.f, 45.f); | |||
| int m_menu_mesh_idx = 0; | |||
| array<char*> m_menu_mesh_names_char; | |||
| array<String> m_menu_mesh_names_str; | |||
| //Scene setup data | |||
| SceneSetupLuaLoader m_ssetup_loader; | |||
| FileUpdateStatus* m_ssetup_file_status = nullptr; | |||
| String m_ssetup_file_name; | |||
| String m_ssetup_name; | |||
| map<String, SceneSetup*> m_ssetups; | |||
| //File data | |||
| String m_file_name; | |||
| @@ -260,6 +285,7 @@ private: | |||
| DefaultThreadManager* m_file_loader = nullptr; | |||
| //OLD --------------------------------------------------------------------- | |||
| SceneSetup* m_ssetup = nullptr; | |||
| array<LightData> m_light_datas; | |||
| short m_input_usage; | |||
| mat4 m_mat; | |||
| @@ -54,10 +54,10 @@ | |||
| <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> | |||
| <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | |||
| </None> | |||
| <None Include="data/meshviewer_init.lua"> | |||
| <None Include="data\meshviewer.easymesh.lua"> | |||
| <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | |||
| </None> | |||
| <None Include="data\meshviewer.easymesh.lua"> | |||
| <None Include="data\meshviewer.init.lua"> | |||
| <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | |||
| </None> | |||
| <None Include="meshviewer/meshviewer.index.html"> | |||
| @@ -299,4 +299,18 @@ void SceneSetupLuaLoader::RegisterSetup(SceneSetup* setup) | |||
| m_setups[setup->m_name] = setup; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool SceneSetupLuaLoader::GetRegisteredSetups(map<String, SceneSetup*>& setups) | |||
| { | |||
| setups = m_setups; | |||
| return !!m_setups.count(); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool SceneSetupLuaLoader::GetLoadedSetups(map<String, SceneSetup*>& setups) | |||
| { | |||
| return GetRegisteredSetups(setups); | |||
| } | |||
| } /* namespace lol */ | |||
| @@ -161,6 +161,9 @@ public: | |||
| //------------------------------------------------------------------------- | |||
| protected: | |||
| static void RegisterSetup(SceneSetup* setup); | |||
| static bool GetRegisteredSetups(map<String, SceneSetup*>& setups); | |||
| public: | |||
| bool GetLoadedSetups(map<String, SceneSetup*>& setups); | |||
| private: | |||
| static map<String, SceneSetup*> m_setups; | |||
| @@ -51,8 +51,24 @@ array<EasyMeshLuaObject*>& EasyMeshLuaLoader::GetInstances() | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| EasyMeshLuaObject::EasyMeshLuaObject() : LuaObject() | |||
| map<String, EasyMeshLuaObject*> EasyMeshLuaLoader::m_meshes; | |||
| void EasyMeshLuaLoader::RegisterMesh(EasyMeshLuaObject* mesh, String const& name) | |||
| { | |||
| m_meshes[name] = mesh; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool EasyMeshLuaLoader::GetRegisteredMeshes(map<String, EasyMeshLuaObject*>& meshes) | |||
| { | |||
| meshes = m_meshes; | |||
| return !!m_meshes.count(); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| EasyMeshLuaObject::EasyMeshLuaObject(String const& name) : LuaObject() | |||
| { | |||
| if (!!name.count()) | |||
| EasyMeshLuaLoader::RegisterMesh(this, name); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| @@ -65,7 +81,10 @@ EasyMeshLuaObject* EasyMeshLuaObject::New(LuaState* l, int arg_nb) | |||
| { | |||
| UNUSED(l); | |||
| UNUSED(arg_nb); | |||
| return new EasyMeshLuaObject(); | |||
| LuaStack s(l); | |||
| LuaString n("", true); | |||
| s >> n; | |||
| return new EasyMeshLuaObject(n()); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| @@ -22,7 +22,7 @@ class EasyMeshLuaObject : public LuaObject | |||
| EasyMesh m_instance; | |||
| public: | |||
| //------------------------------------------------------------------------- | |||
| EasyMeshLuaObject(); | |||
| EasyMeshLuaObject(String const& name); | |||
| virtual ~EasyMeshLuaObject(); | |||
| EasyMesh& GetMesh() { return m_instance; } | |||
| @@ -645,12 +645,23 @@ public: | |||
| //----------------------------------------------------------------------------- | |||
| class EasyMeshLuaLoader : public LuaLoader | |||
| { | |||
| friend class EasyMeshLuaObject; | |||
| public: | |||
| EasyMeshLuaLoader(); | |||
| virtual ~EasyMeshLuaLoader(); | |||
| //Virtual Store lua object ------------------------------------------------ | |||
| virtual void Store(LuaObject* obj); | |||
| array<EasyMeshLuaObject*>& GetInstances(); | |||
| //------------------------------------------------------------------------- | |||
| protected: | |||
| static void RegisterMesh(EasyMeshLuaObject* mesh, String const& name); | |||
| public: | |||
| static bool GetRegisteredMeshes(map<String, EasyMeshLuaObject*>& meshes); | |||
| private: | |||
| static map<String, EasyMeshLuaObject*> m_meshes; | |||
| }; | |||
| } /* namespace lol */ | |||
| @@ -22,6 +22,8 @@ namespace lol | |||
| class IndexBuffer | |||
| { | |||
| friend class Mesh; | |||
| public: | |||
| IndexBuffer(size_t size); | |||
| ~IndexBuffer(); | |||
| @@ -34,6 +36,9 @@ public: | |||
| void Bind(); | |||
| void Unbind(); | |||
| protected: | |||
| uint16_t *GetData(); | |||
| private: | |||
| class IndexBufferData *m_data; | |||
| }; | |||
| @@ -1240,9 +1240,9 @@ template<typename T, int SWIZZLE> | |||
| static inline vec_t<T, 3> cartesian(vec_t<T, 3, SWIZZLE> const &a) | |||
| { | |||
| vec_t<T, 3> ret; | |||
| ret.x = a[0] * lol::sin(a[1]) * lol::cos(a[2]); | |||
| ret.y = a[0] * lol::sin(a[1]) * lol::sin(a[2]); | |||
| ret.z = a[0] * lol::cos(a[1]); | |||
| ret.x = a[0] * lol::sin(a[2]) * lol::cos(a[1]); | |||
| ret.y = a[0] * lol::cos(a[2]); | |||
| ret.z = a[0] * lol::sin(a[2]) * lol::sin(a[1]); | |||
| return ret; | |||
| } | |||
| @@ -1261,8 +1261,8 @@ static inline vec_t<T, 3> spherical(vec_t<T, 3, SWIZZLE> const &a) | |||
| { | |||
| vec_t<T, 3> ret; | |||
| ret[0] = sqlength(a); | |||
| ret[1] = lol::acos(a.z / ret[a.x]); | |||
| ret[2] = lol::atan(a.y / a.x); | |||
| ret[1] = lol::atan(a.y / a.x); | |||
| ret[2] = lol::acos(a.z / ret[0]); | |||
| return ret; | |||
| } | |||
| @@ -96,7 +96,7 @@ LolImGui::~LolImGui() | |||
| delete m_vdecl; | |||
| } | |||
| //------------------------------------------------------------------------- | |||
| //----------------------------------------------------------------------------- | |||
| LolImGui* g_lolimgui = nullptr; | |||
| void LolImGui::Init() | |||
| { | |||
| @@ -147,7 +147,7 @@ void LolImGui::Shutdown() | |||
| ImGui::Shutdown(); | |||
| } | |||
| //------------------------------------------------------------------------- | |||
| //----------------------------------------------------------------------------- | |||
| static String g_clipboard; | |||
| void LolImGui::SetClipboard(const char* text) | |||
| { | |||
| @@ -158,7 +158,7 @@ const char* LolImGui::GetClipboard() | |||
| return g_clipboard.C(); | |||
| } | |||
| //------------------------------------------------------------------------- | |||
| //----------------------------------------------------------------------------- | |||
| void LolImGui::TickGame(float seconds) | |||
| { | |||
| super::TickGame(seconds); | |||
| @@ -227,6 +227,7 @@ void LolImGui::TickGame(float seconds) | |||
| cursor.y = 1.f - cursor.y; | |||
| cursor *= video_size; | |||
| io.MousePos = ImVec2(cursor.x, cursor.y); | |||
| Log::Debug(Line("%.2f/%.2f"), io.MousePos.x, io.MousePos.y); | |||
| io.MouseWheel = m_controller->GetAxisValue(LolImGuiAxis::Scroll); | |||
| for (int i = LolImGuiKey::MOUSE_KEY_START; i < LolImGuiKey::MOUSE_KEY_END; ++i) | |||
| @@ -237,8 +238,13 @@ void LolImGui::TickGame(float seconds) | |||
| io.MouseDown[i - LolImGuiKey::MOUSE_KEY_START] = m_controller->IsKeyPressed(i); | |||
| break; | |||
| case LolImGuiKey::Focus: | |||
| if (m_controller->IsKeyPressed(i)) | |||
| if (m_controller->IsKeyReleased(i)) | |||
| { | |||
| Log::Debug(Line("Not focused .....")); | |||
| io.MousePos = ImVec2(-1.f, -1.f); | |||
| } | |||
| else | |||
| Log::Debug(Line("Focused !!")); | |||
| break; | |||
| } | |||
| } | |||
| @@ -247,18 +253,23 @@ void LolImGui::TickGame(float seconds) | |||
| // Start the frame | |||
| ImGui::NewFrame(); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| void LolImGui::TickDraw(float seconds, Scene &scene) | |||
| { | |||
| super::TickDraw(seconds, scene); | |||
| ImGuiIO& io = ImGui::GetIO(); | |||
| scene.AddPrimitive(new PrimitiveLolImGui()); | |||
| } | |||
| void PrimitiveLolImGui::Render() const | |||
| { | |||
| g_renderer->Clear(ClearMask::Depth); | |||
| ImGuiIO& io = ImGui::GetIO(); | |||
| if (io.Fonts->TexID) | |||
| ImGui::Render(); | |||
| } | |||
| //// Data | |||
| //static GLFWwindow* g_Window = NULL; | |||
| //static double g_Time = 0.0f; | |||
| @@ -173,6 +173,14 @@ protected: | |||
| //map<ImGuiKey_, LolImGuiKey> m_keys; | |||
| }; | |||
| //----------------------------------------------------------------------------- | |||
| class PrimitiveLolImGui : public Primitive | |||
| { | |||
| public: | |||
| PrimitiveLolImGui() { } | |||
| virtual void Render() const; | |||
| }; | |||
| //bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); | |||
| //void ImGui_ImplGlfw_Shutdown(); | |||
| //void ImGui_ImplGlfw_NewFrame(); | |||
| @@ -271,13 +271,19 @@ public: | |||
| { | |||
| GetInc(l, index); | |||
| } | |||
| inline T* operator ()() { return m_value; } | |||
| inline T* operator ->() { return m_value; } | |||
| inline T* operator=(T* value) { m_value = value; } | |||
| inline T* operator ()() { return m_value; } | |||
| inline T* operator ->() { return m_value; } | |||
| inline T* operator=(T* value) { m_value = value; } | |||
| inline T* GetValue() { return m_value; } | |||
| inline bool IsValid(LuaState* l, int index) | |||
| { | |||
| return InnerIsValid(l, index); | |||
| } | |||
| inline bool IsOptional() | |||
| { | |||
| return m_optional; | |||
| } | |||
| private: | |||
| inline void GetInc(LuaState* l, int& index) | |||
| { | |||
| @@ -660,6 +666,10 @@ public: | |||
| { | |||
| return InnerIsValid(l, index); | |||
| } | |||
| inline bool IsOptional() | |||
| { | |||
| return m_value.IsOptional(); | |||
| } | |||
| private: | |||
| void GetInc(LuaState* l, int& index) | |||
| { | |||
| @@ -768,7 +778,7 @@ public: | |||
| { | |||
| GetInc(l, index); | |||
| } | |||
| VarEnum(vec4 value, LuaState* l, int& index, bool optional = false) | |||
| VarEnum(SafeEnum<E> value, LuaState* l, int& index, bool optional = false) | |||
| : VarEnum(value, optional) | |||
| { | |||
| GetInc(l, index); | |||
| @@ -781,6 +791,10 @@ public: | |||
| { | |||
| return InnerIsValid(l, index); | |||
| } | |||
| inline bool IsOptional() | |||
| { | |||
| return m_optional; | |||
| } | |||
| private: | |||
| void GetInc(LuaState* l, int& index) | |||
| { | |||
| @@ -866,15 +880,22 @@ public: | |||
| template<typename T> | |||
| Stack& operator>>(T& var) | |||
| { | |||
| var = T(m_state, m_index); | |||
| var = T(var.GetValue(), m_state, m_index, var.IsOptional()); | |||
| return *this; | |||
| } | |||
| /* | |||
| template<typename T> | |||
| Stack& operator>>(Var<T>& var) | |||
| { | |||
| var = Var<T>(m_state, m_index); | |||
| return *this; | |||
| var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional()); | |||
| return *this; | |||
| } | |||
| template<typename T> | |||
| Stack& operator>>(Var<T>& var) | |||
| { | |||
| var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional()); | |||
| return *this; | |||
| } | |||
| template<typename T> | |||
| Stack& operator>>(VarPtr<T>& var) | |||
| @@ -882,6 +903,15 @@ public: | |||
| var = VarPtr<T>(m_state, m_index); | |||
| return *this; | |||
| } | |||
| */ | |||
| /* | |||
| template<typename T> | |||
| Stack& operator>>(T& var) | |||
| { | |||
| Var<T> ret(m_state, m_index); | |||
| var = ret.GetValue(); | |||
| return *this; | |||
| } | |||
| template<typename T> | |||
| Stack& operator>>(VarPtrLight<T>& var) | |||
| { | |||
| @@ -899,9 +929,10 @@ public: | |||
| } | |||
| /* | |||
| template<typename T> | |||
| Stack& operator<<(Var<T>& var) | |||
| Stack& operator<<(T& var) | |||
| { | |||
| m_result += var.Return(m_state); | |||
| Var<T> ret(var, false); | |||
| m_result += ret.Return(m_state); | |||
| return *this; | |||
| } | |||
| template<typename T> | |||
| @@ -121,7 +121,7 @@ void SubMesh::Render() | |||
| attribs[j] = m_shader->GetAttribLocation(usage, usages[usage_index]++); | |||
| } | |||
| vertex_count = m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize(); | |||
| vertex_count = (int)m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize(); | |||
| m_vdecl->SetStream(m_vbos[i], attribs); | |||
| } | |||
| @@ -136,7 +136,7 @@ void SubMesh::Render() | |||
| m_ibo->Bind(); | |||
| m_vdecl->Bind(); | |||
| m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, 0, 0, vertex_count, | |||
| 0, m_ibo->GetSize() / sizeof(uint16_t)); | |||
| 0, (int)m_ibo->GetSize() / sizeof(uint16_t)); | |||
| m_vdecl->Unbind(); | |||
| m_ibo->Unbind(); | |||
| } | |||
| @@ -49,6 +49,8 @@ namespace lol | |||
| class Mesh | |||
| { | |||
| friend class Scene; | |||
| public: | |||
| Mesh(); | |||
| ~Mesh(); | |||
| @@ -56,9 +58,10 @@ public: | |||
| /* FIXME: this should eventually take a “material” as argument, which | |||
| * may behave differently between submeshes. */ | |||
| void SetMaterial(Shader *shader); | |||
| protected: | |||
| void Render(); | |||
| public: | |||
| array<class SubMesh *> m_submeshes; | |||
| }; | |||
| @@ -72,6 +75,9 @@ public: | |||
| class SubMesh | |||
| { | |||
| friend class PrimitiveMesh; | |||
| friend class Mesh; | |||
| public: | |||
| SubMesh(Shader *shader, VertexDeclaration* vdecl); | |||
| ~SubMesh(); | |||
| @@ -84,9 +90,9 @@ public: | |||
| void SetIndexBuffer(IndexBuffer* ibo); | |||
| void AddTexture(const char* name, Texture* texture); | |||
| protected: | |||
| void Render(); | |||
| protected: | |||
| MeshPrimitive m_mesh_prim; | |||
| Shader *m_shader; | |||
| VertexDeclaration* m_vdecl; | |||
| @@ -20,15 +20,73 @@ namespace lol | |||
| * Primitive class | |||
| */ | |||
| Primitive::Primitive(SubMesh *submesh, mat4 const &matrix) | |||
| PrimitiveMesh::PrimitiveMesh(SubMesh *submesh, mat4 const &matrix) | |||
| : m_submesh(submesh), | |||
| m_matrix(matrix) | |||
| { | |||
| } | |||
| Primitive::~Primitive() | |||
| PrimitiveMesh::~PrimitiveMesh() | |||
| { | |||
| } | |||
| void PrimitiveMesh::Render() const | |||
| { | |||
| /* TODO: this should be the main entry for rendering of all | |||
| * primitives found in the scene graph. When we have one. */ | |||
| Shader *shader = nullptr; | |||
| ShaderUniform u_model, u_modelview, u_normalmat, uni_tex, uni_texsize; | |||
| ShaderAttrib a_pos, a_tex; | |||
| { | |||
| /* If this primitive uses a new shader, update attributes */ | |||
| if (m_submesh->GetShader() != shader) | |||
| { | |||
| shader = m_submesh->GetShader(); | |||
| a_pos = shader->GetAttribLocation(VertexUsage::Position, 0); | |||
| a_tex = shader->GetAttribLocation(VertexUsage::TexCoord, 0); | |||
| shader->Bind(); | |||
| /* Per-scene matrices */ | |||
| ShaderUniform u_mat; | |||
| u_mat = shader->GetUniformLocation("u_projection"); | |||
| shader->SetUniform(u_mat, g_scene->GetCamera()->GetProjection()); | |||
| u_mat = shader->GetUniformLocation("u_view"); | |||
| shader->SetUniform(u_mat, g_scene->GetCamera()->GetView()); | |||
| u_mat = shader->GetUniformLocation("u_inv_view"); | |||
| shader->SetUniform(u_mat, inverse(g_scene->GetCamera()->GetView())); | |||
| /* Per-object matrices, will be set later */ | |||
| u_model = shader->GetUniformLocation("u_model"); | |||
| u_modelview = shader->GetUniformLocation("u_modelview"); | |||
| u_normalmat = shader->GetUniformLocation("u_normalmat"); | |||
| /* Per-scene environment */ | |||
| array<Light *> const &lights = g_scene->GetLights(); | |||
| array<vec4> light_data; | |||
| /* FIXME: the 4th component of the position can be used for other things */ | |||
| /* FIXME: GetUniform("blabla") is costly */ | |||
| for (auto l : lights) | |||
| light_data << vec4(l->GetPosition(), (float)l->GetType()) << l->GetColor(); | |||
| while (light_data.Count() < LOL_MAX_LIGHT_COUNT) | |||
| light_data << vec4::zero << vec4::zero; | |||
| ShaderUniform u_lights = shader->GetUniformLocation("u_lights"); | |||
| shader->SetUniform(u_lights, light_data); | |||
| } | |||
| shader->SetUniform(u_model, m_matrix); | |||
| mat4 modelview = g_scene->GetCamera()->GetView() * m_matrix; | |||
| shader->SetUniform(u_modelview, modelview); | |||
| shader->SetUniform(u_normalmat, transpose(inverse(mat3(modelview)))); | |||
| m_submesh->Render(); | |||
| } | |||
| } | |||
| } /* namespace lol */ | |||
| @@ -15,18 +15,17 @@ | |||
| // ------------------- | |||
| // | |||
| #include "mesh/mesh.h" | |||
| namespace lol | |||
| { | |||
| class Primitive | |||
| class PrimitiveMesh : public Primitive | |||
| { | |||
| friend class Scene; | |||
| public: | |||
| Primitive(SubMesh *submesh, mat4 const &matrix); | |||
| ~Primitive(); | |||
| PrimitiveMesh(SubMesh *submesh, mat4 const &matrix); | |||
| virtual ~PrimitiveMesh(); | |||
| virtual void Render() const; | |||
| private: | |||
| SubMesh *m_submesh; | |||
| @@ -56,7 +56,7 @@ class SceneData | |||
| private: | |||
| /* New scenegraph */ | |||
| array<Primitive> m_primitives; | |||
| array<Primitive*> m_primitives; | |||
| /* Old API <P0, P1, COLOR, TIME, MASK> */ | |||
| float m_new_line_time; | |||
| @@ -91,7 +91,7 @@ Scene::Scene(ivec2 size) | |||
| { | |||
| /* Create a default orthographic camera, in case the user doesn’t. */ | |||
| data->m_default_cam = new Camera(); | |||
| mat4 proj = mat4::ortho(0.f, size.x, 0.f, size.y, -1000.f, 1000.f); | |||
| mat4 proj = mat4::ortho(0.f, (float)size.x, 0.f, (float)size.y, -1000.f, 1000.f); | |||
| data->m_default_cam->SetProjection(proj); | |||
| PushCamera(data->m_default_cam); | |||
| @@ -133,7 +133,7 @@ int Scene::PushCamera(Camera *cam) | |||
| Ticker::Ref(cam); | |||
| data->m_camera_stack.Push(cam); | |||
| return data->m_camera_stack.Count() - 1; | |||
| return (int)data->m_camera_stack.Count() - 1; | |||
| } | |||
| void Scene::PopCamera(Camera *cam) | |||
| @@ -142,7 +142,7 @@ void Scene::PopCamera(Camera *cam) | |||
| /* Parse from the end because that’s probably where we’ll find | |||
| * our camera first. */ | |||
| for (int i = data->m_camera_stack.Count(); i--; ) | |||
| for (ptrdiff_t i = data->m_camera_stack.Count(); i--; ) | |||
| { | |||
| if (data->m_camera_stack[i] == cam) | |||
| { | |||
| @@ -174,25 +174,33 @@ void Scene::Reset() | |||
| data->m_tile_bufs.Empty(); | |||
| data->m_lights.Empty(); | |||
| for (int i = 0; i < data->m_primitives.count(); i++) | |||
| delete data->m_primitives[i]; | |||
| data->m_primitives.Empty(); | |||
| } | |||
| /*TODO: SAM/TOUKY: Change that*/ | |||
| void Scene::AddPrimitive(Mesh const &mesh, mat4 const &matrix) | |||
| { | |||
| for (int i = 0; i < mesh.m_submeshes.Count(); ++i) | |||
| { | |||
| data->m_primitives.Push(Primitive(mesh.m_submeshes[i], | |||
| matrix)); | |||
| AddPrimitive(new PrimitiveMesh(mesh.m_submeshes[i], matrix)); | |||
| } | |||
| } | |||
| void Scene::AddPrimitive(Primitive* primitive) | |||
| { | |||
| data->m_primitives.Push(primitive); | |||
| } | |||
| void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle) | |||
| { | |||
| ASSERT(id < tileset->GetTileCount()); | |||
| Tile t; | |||
| /* FIXME: this sorting only works for a 45-degree camera */ | |||
| t.prio = -pos.y - (int)(2 * 32 * pos.z) + (o ? 0 : 32); | |||
| t.prio = (uint32_t)(-pos.y - (int)(2 * 32 * pos.z) + ((float)o ? 0 : 32)); | |||
| t.tileset = tileset; | |||
| t.id = id; | |||
| t.pos = pos; | |||
| @@ -234,57 +242,9 @@ void Scene::RenderPrimitives() | |||
| /* TODO: this should be the main entry for rendering of all | |||
| * primitives found in the scene graph. When we have one. */ | |||
| Shader *shader = nullptr; | |||
| ShaderUniform u_model, u_modelview, u_normalmat, uni_tex, uni_texsize; | |||
| ShaderAttrib a_pos, a_tex; | |||
| for (Primitive const &p : data->m_primitives) | |||
| for (Primitive* p : data->m_primitives) | |||
| { | |||
| /* If this primitive uses a new shader, update attributes */ | |||
| if (p.m_submesh->GetShader() != shader) | |||
| { | |||
| shader = p.m_submesh->GetShader(); | |||
| a_pos = shader->GetAttribLocation(VertexUsage::Position, 0); | |||
| a_tex = shader->GetAttribLocation(VertexUsage::TexCoord, 0); | |||
| shader->Bind(); | |||
| /* Per-scene matrices */ | |||
| ShaderUniform u_mat; | |||
| u_mat = shader->GetUniformLocation("u_projection"); | |||
| shader->SetUniform(u_mat, GetCamera()->GetProjection()); | |||
| u_mat = shader->GetUniformLocation("u_view"); | |||
| shader->SetUniform(u_mat, GetCamera()->GetView()); | |||
| u_mat = shader->GetUniformLocation("u_inv_view"); | |||
| shader->SetUniform(u_mat, inverse(GetCamera()->GetView())); | |||
| /* Per-object matrices, will be set later */ | |||
| u_model = shader->GetUniformLocation("u_model"); | |||
| u_modelview = shader->GetUniformLocation("u_modelview"); | |||
| u_normalmat = shader->GetUniformLocation("u_normalmat"); | |||
| /* Per-scene environment */ | |||
| array<Light *> const &lights = GetLights(); | |||
| array<vec4> light_data; | |||
| /* FIXME: the 4th component of the position can be used for other things */ | |||
| /* FIXME: GetUniform("blabla") is costly */ | |||
| for (auto l : lights) | |||
| light_data << vec4(l->GetPosition(), l->GetType()) << l->GetColor(); | |||
| while (light_data.Count() < LOL_MAX_LIGHT_COUNT) | |||
| light_data << vec4::zero << vec4::zero; | |||
| ShaderUniform u_lights = shader->GetUniformLocation("u_lights"); | |||
| shader->SetUniform(u_lights, light_data); | |||
| } | |||
| shader->SetUniform(u_model, p.m_matrix); | |||
| mat4 modelview = GetCamera()->GetView() * p.m_matrix; | |||
| shader->SetUniform(u_modelview, modelview); | |||
| shader->SetUniform(u_normalmat, transpose(inverse(mat3(modelview)))); | |||
| p.m_submesh->Render(); | |||
| p->Render(); | |||
| } | |||
| } | |||
| @@ -419,7 +379,7 @@ void Scene::RenderLines(float seconds) // XXX: rename to Blit() | |||
| rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max); | |||
| rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); | |||
| int linecount = data->m_lines.Count(); | |||
| int linecount = (int)data->m_lines.Count(); | |||
| if (!data->m_line_shader) | |||
| data->m_line_shader = Shader::Create(LOLFX_RESOURCE_NAME(line)); | |||
| @@ -20,7 +20,6 @@ | |||
| #include "tileset.h" | |||
| #include "light.h" | |||
| #include "camera.h" | |||
| #include "mesh/primitive.h" | |||
| #define LOL_MAX_LIGHT_COUNT 8 | |||
| @@ -29,6 +28,20 @@ namespace lol | |||
| class SceneData; | |||
| //----------------------------------------------------------------------------- | |||
| class Primitive | |||
| { | |||
| friend class Scene; | |||
| public: | |||
| Primitive() { } | |||
| virtual ~Primitive() { } | |||
| virtual void Render() const { } | |||
| private: | |||
| }; | |||
| //----------------------------------------------------------------------------- | |||
| class Scene | |||
| { | |||
| friend class Video; | |||
| @@ -51,6 +64,7 @@ public: | |||
| /* New scenegraph */ | |||
| void AddPrimitive(Mesh const &mesh, mat4 const &matrix); | |||
| void AddPrimitive(Primitive* primitive); | |||
| /* FIXME: this should be deprecated -- it doesn't really match | |||
| * the architecture we want to build */ | |||
| @@ -174,7 +174,7 @@ int BaseThreadManager::GetDispatchedCount() | |||
| //----------------------------------------------------------------------------- | |||
| void BaseThreadManager::DispatchJob(ThreadJob* job) | |||
| { | |||
| m_job_dispatch << job; | |||
| if (job) m_job_dispatch << job; | |||
| } | |||
| void BaseThreadManager::DispatchJob(array<ThreadJob*> const& jobs) | |||
| { | |||
| @@ -52,19 +52,28 @@ public: | |||
| protected: | |||
| virtual bool DoWork() | |||
| { | |||
| array<String> pathlist = System::GetPathList(m_path); | |||
| File f; | |||
| f.Open(m_path, FileAccess::Read); | |||
| if (!f.IsValid()) | |||
| return false; | |||
| if (!m_ready) | |||
| m_time = f.GetModificationTime(); | |||
| else | |||
| for (String path : pathlist) | |||
| { | |||
| long int new_time = f.GetModificationTime(); | |||
| if (new_time > m_time) | |||
| m_updated = true; | |||
| f.Open(path, FileAccess::Read); | |||
| if (f.IsValid()) | |||
| { | |||
| long int new_time = f.GetModificationTime(); | |||
| if (!m_ready) | |||
| { | |||
| m_time = new_time; | |||
| m_ready = true; | |||
| } | |||
| else if (new_time > m_time) | |||
| { | |||
| m_time = new_time; | |||
| m_updated = true; | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| return true; | |||
| return false; | |||
| } | |||
| //----------------- | |||
| @@ -114,6 +123,11 @@ void FileUpdateTester::UnregisterFile(FileUpdateTester::Status*& status) | |||
| //----------------------------------------------------------------------------- | |||
| void FileUpdateTester::TickGame(float seconds) | |||
| { | |||
| //Reset update for this frame | |||
| array<String> keys = m_files.keys(); | |||
| for (String key : keys) | |||
| m_files[key]->SetUpdated(false); | |||
| super::TickGame(seconds); | |||
| if (!GetDispatchCount() && m_job_done.count()) | |||
| @@ -122,10 +136,6 @@ void FileUpdateTester::TickGame(float seconds) | |||
| return; | |||
| m_frame_count = 0; | |||
| array<String> keys = m_files.keys(); | |||
| for (String key : keys) | |||
| m_files[key]->SetUpdated(false); | |||
| DispatchJob(m_job_done); | |||
| m_job_done.empty(); | |||
| } | |||
| @@ -139,9 +149,9 @@ void FileUpdateTester::TreatResult(ThreadJob* result) | |||
| { | |||
| m_files[job->GetPath()]->SetTime(job->GetTime()); | |||
| m_files[job->GetPath()]->SetUpdated(true); | |||
| job->Restart(); | |||
| m_job_done << job; | |||
| } | |||
| job->Restart(); | |||
| m_job_done << job; | |||
| } | |||
| //AsyncImageJob --------------------------------------------------------------- | |||