// // Lol Engine - EasyMesh tutorial // // Copyright: (c) 2011-2013 Sam Hocevar // (c) 2012-2013 Benjamin "Touky" Huet // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See // http://www.wtfpl.net/ for more details. // #if defined HAVE_CONFIG_H # include "config.h" #endif #include /* for FLT_MAX */ #include "core.h" using namespace std; using namespace lol; #define MESH_DIST 5.0f class MeshViewer : public WorldEntity { public: MeshViewer() { int i=10; while (i--) { m_meshes.Push(EasyMesh()); m_meshes.Last().Compile("[sc#2f2 ab 2 2 2 t .8 .8 .8 rx 20 ry 20 [sc#22f ab 2 2 2 tx 0 csgu]]"); } m_angle = 0; m_camera = new Camera(vec3(0.f, 600.f, 0.f), vec3(0.f, 0.f, 0.f), vec3(0, 1, 0)); m_camera->SetPerspective(60.f, 16, 9, .1f, 1000.f); m_camera->SetTarget(vec3(0.f, 0.f, 0.f)); m_camera->SetPosition(vec3(0.f, 0.f, 5.f)); m_camera->ForceSceneUpdate(); Ticker::Ref(m_camera); m_lights << new Light(); m_lights.Last()->SetPosition(vec4(4.f, -1.f, -4.f, 0.f)); m_lights.Last()->SetColor(vec4(.0f, .2f, .5f, 1.f)); Ticker::Ref(m_lights.Last()); m_lights << new Light(); m_lights.Last()->SetPosition(vec4(8.f, 2.f, 6.f, 1.f)); m_lights.Last()->SetColor(vec4(.5f, .3f, .0f, 1.f)); Ticker::Ref(m_lights.Last()); min_pos = vec3(FLT_MAX); max_pos = vec3(-FLT_MAX); m_ready = false; } ~MeshViewer() { Ticker::Unref(m_camera); for (int i = 0; i < m_lights.Count(); ++i) Ticker::Unref(m_lights[i]); } virtual void TickGame(float seconds) { WorldEntity::TickGame(seconds); //vec4 vertex = in_ModelView * vec4(in_Vertex, 1.0); // gl_Position = in_Proj * vertex; m_angle += seconds * 70.0f; m_mat = mat4::rotate(m_angle, vec3(0, 1, 0)); //mat4 screen_matrix = Scene::GetDefault()->GetProjMatrix() * Scene::GetDefault()->GetViewMatrix(); mat4 world_view_matrix = m_camera->GetViewMatrix() * m_mat; mat4 world_screen_matrix = m_camera->GetProjMatrix() * world_view_matrix; mat4 view_world_matrix = inverse(m_camera->GetViewMatrix()); mat4 screen_view_matrix = inverse(m_camera->GetProjMatrix()); vec4 a(0, 2, 0, 1.0f); vec4 b(0,-2, 0, 1.0f); vec4 c(0, 0, -2, 1.0f); vec4 d(-1, -1, 1, 1.0f); //vec2 toto; //near plane : vec4(toto, 1.f, 1.f); //far plane : vec4(toto, -1.f, 1.f); a = vec4((world_screen_matrix * a).xyz / a.w, a.w); b = vec4((world_screen_matrix * b).xyz / b.w, b.w); c = vec4((inverse(world_screen_matrix) * c).xyz / c.w, c.w); d = vec4((inverse(world_screen_matrix) * d).xyz / d.w, d.w); a = b; c = d; //this is the algorithm for a camera that must keep n target in the screen { //Get the Min/Max needed vec3 new_min_pos(FLT_MAX); vec3 new_max_pos(-FLT_MAX); for (int i = 0; i < m_meshes.Last().GetVertexCount(); i++) { vec4 vpos = world_view_matrix * vec4(m_meshes.Last().GetVertexLocation(i), 1.0f); new_min_pos = min(vpos.xyz, new_min_pos); new_max_pos = max(vpos.xyz, new_max_pos); } //Actual camera algorithm { vec4 BottomLeft = m_camera->GetProjMatrix() * vec4(new_min_pos.xy, new_min_pos.z, 1.0f); vec4 TopRight = m_camera->GetProjMatrix() * vec4(new_max_pos.xy, new_min_pos.z, 1.0f); BottomLeft = vec4(BottomLeft.xyz / BottomLeft.w, BottomLeft.w); TopRight = vec4(TopRight.xyz / TopRight.w, TopRight.w); //vec2 NewSize = TopRight.xy - BottomLeft.xy; //NewSize.x = max(NewSize.x, NewSize.y) * 1.5f; vec4 DistantPoint = screen_view_matrix * vec4(vec2(1.0f, 1.0f), TopRight.z * TopRight.w, TopRight.w); vec3 vcenter = vec3(new_min_pos.xy + new_max_pos.xy, .0f) * .5f; vec4 new_pos = screen_view_matrix * vec4(.0f, .0f, new_min_pos.z, 1.0f); //vcenter.z += (new_pos.z - new_pos.z * NewSize.x); vcenter = (view_world_matrix * vec4(vcenter, 1.0f)).xyz; m_camera->SetPosition(damp(m_camera->GetPosition(), vcenter, 0.4f, seconds)); //m_camera->SetPosition(vcenter); m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f)); } // } } virtual void TickDraw(float seconds) { WorldEntity::TickDraw(seconds); if (!m_ready) { for (int i = 0; i < m_meshes.Count(); i++) m_meshes[i].MeshConvert(); m_ready = true; } Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); m_mat = mat4::translate(vec3(m_meshes.Count() * MESH_DIST * 0.5f, 0, m_meshes.Count() * MESH_DIST) * -1.0f) * m_mat; for (int i = 0; i < m_meshes.Count(); i++) { m_mat = mat4::translate(vec3(MESH_DIST * 0.5f, 0, MESH_DIST)) * m_mat; m_meshes[i].Render(m_mat); Video::Clear(ClearMask::Depth); } //m_mat = mat4::translate(vec3(.0f)); //m_meshes.Last().Render(m_mat); } private: //Array m_gears; float m_angle; mat4 m_mat; vec3 min_pos; vec3 max_pos; Array m_meshes; Array m_lights; Camera *m_camera; bool m_ready; }; int main(int argc, char **argv) { System::Init(argc, argv); Application app("MeshViewer", ivec2(960, 600), 60.0f); new MeshViewer(); app.Run(); return EXIT_SUCCESS; }