source: trunk/test/MeshViewer.cpp @ 2370

Last change on this file since 2370 was 2370, checked in by touky, 7 years ago

render : Added DebugRenderMode & corresponding shaders. naive (VERY) implementation in MeshViewer.

File size: 14.4 KB
RevLine 
[2353]1
[2294]2//
3// Lol Engine - EasyMesh tutorial
4//
5// Copyright: (c) 2011-2013 Sam Hocevar <sam@hocevar.net>
6//            (c) 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
7//   This program is free software; you can redistribute it and/or
8//   modify it under the terms of the Do What The Fuck You Want To
9//   Public License, Version 2, as published by Sam Hocevar. See
10//   http://www.wtfpl.net/ for more details.
11//
12
13#if defined HAVE_CONFIG_H
14#   include "config.h"
15#endif
16
[2296]17#include <cfloat> /* for FLT_MAX */
18
[2294]19#include "core.h"
20
21using namespace std;
22using namespace lol;
23
[2353]24#define    IPT_CAM_RESET          "Cam_Center"
25#define    IPT_CAM_FORWARD        "Cam_Forward"
26#define    IPT_CAM_BACKWARD       "Cam_Backward"
27#define    IPT_CAM_ZOOM_OUT       "Cam_Zoom_In"
28#define    IPT_CAM_ZOOM_IN        "Cam_Zoom_Out"
29
30#define    IPT_MESH_UPDATE        "Mesh_Update"
31#define    IPT_MESH_RESET         "Mesh_Reset"
32
33#define    IPT_MESH_LEFT          "Mesh_Left"
34#define    IPT_MESH_RIGHT         "Mesh_Right"
35#define    IPT_MESH_UP            "Mesh_Up"
36#define    IPT_MESH_DOWN          "Mesh_Down"
37#define    IPT_MESH_SCALE_UP      "Mesh_Scale_Up"
38#define    IPT_MESH_SCALE_DOWN    "Mesh_Scale_Down"
39#define    IPT_MESH_OFFSET_UP     "Mesh_Offset_Up"
40#define    IPT_MESH_OFFSET_DOWN   "Mesh_Offset_Down"
41#define    IPT_MESH_ROT_LEFT      "Mesh_Rot_Left"
42#define    IPT_MESH_ROT_RIGHT     "Mesh_Rot_Right"
43#define    IPT_MESH_ROT_UP        "Mesh_Rot_Up"
44#define    IPT_MESH_ROT_DOWN      "Mesh_Rot_Down"
45
[2294]46class MeshViewer : public WorldEntity
47{
48public:
[2353]49    void SetFov(float new_fov=60.0f)
[2294]50    {
[2353]51        //FOV compensation doesn't work
52        ivec2 video_size = Video::GetSize();
[2370]53        float near = (float)-video_size.x - video_size.y;
54        float far = (float)video_size.x + video_size.y;
[2353]55        float t1 = tanf(new_fov / 2);
[2370]56        float dist = (float)video_size.x / (2.0f * t1);
[2353]57        //m_fov_compensation = mat4::translate(-0.5f * video_size.x, -0.5f * video_size.y, -dist);
58        m_fov_compensation = mat4::translate(vec3(.0f));
59        if (new_fov > 0.1f)
60            m_camera->SetPerspective(new_fov, (float)video_size.x, (float)video_size.y, .1f, 1000.f);
61        else
62            m_camera->SetOrtho((float)video_size.x, (float)video_size.y, .1f, 1000.f);
63    }
[2294]64
[2364]65    MeshViewer(char const *file_name = "MeshViewerBuffer.txt")
66      : m_file_name(file_name)
[2353]67    {
68        //Input setup
[2356]69        Input::LinkActionToKey(IPT_CAM_RESET,           Key::Return);
70        Input::LinkActionToKey(IPT_CAM_FORWARD,         Key::PageUp);
71        Input::LinkActionToKey(IPT_CAM_BACKWARD,        Key::PageDown);
72        Input::LinkActionToKey(IPT_CAM_ZOOM_IN,         Key::Home);
73        Input::LinkActionToKey(IPT_CAM_ZOOM_OUT,        Key::End);
[2353]74
[2356]75        Input::LinkActionToKey(IPT_MESH_LEFT,           Key::Left);
76        Input::LinkActionToKey(IPT_MESH_RIGHT,          Key::Right);
77        Input::LinkActionToKey(IPT_MESH_UP,             Key::Up);
78        Input::LinkActionToKey(IPT_MESH_DOWN,           Key::Down);
79
[2353]80        Input::LinkActionToKey(IPT_MESH_UPDATE,         Key::Space);
81        Input::LinkActionToKey(IPT_MESH_RESET,          Key::KP0);
[2356]82
83        Input::LinkActionToKey(IPT_MESH_OFFSET_DOWN,    Key::KP1);
84        Input::LinkActionToKey(IPT_MESH_OFFSET_UP,      Key::KP3);
85        Input::LinkActionToKey(IPT_MESH_SCALE_DOWN,     Key::KP7);
[2353]86        Input::LinkActionToKey(IPT_MESH_SCALE_UP,       Key::KP9);
[2356]87
88        Input::LinkActionToKey(IPT_MESH_ROT_LEFT,       Key::KP4);
[2353]89        Input::LinkActionToKey(IPT_MESH_ROT_RIGHT,      Key::KP6);
[2356]90        Input::LinkActionToKey(IPT_MESH_ROT_UP,         Key::KP8);
[2353]91        Input::LinkActionToKey(IPT_MESH_ROT_DOWN,       Key::KP5);
[2356]92
[2294]93        m_angle = 0;
94
[2353]95        //Camera Setup
96        m_fov_zoom_damp = .0f;
97        m_fov_damp = 60.0f;
98        m_fov = 60.0f;
[2294]99        m_camera = new Camera(vec3(0.f, 600.f, 0.f),
100                              vec3(0.f, 0.f, 0.f),
101                              vec3(0, 1, 0));
[2353]102        SetFov(m_fov_damp);
[2294]103        m_camera->SetTarget(vec3(0.f, 0.f, 0.f));
[2353]104        m_camera->SetPosition(vec3(0.f, 0.f, 10.f));
[2294]105        m_camera->ForceSceneUpdate();
106        Ticker::Ref(m_camera);
[2298]107
[2353]108        //Lights setup
[2298]109        m_lights << new Light();
110        m_lights.Last()->SetPosition(vec4(4.f, -1.f, -4.f, 0.f));
111        m_lights.Last()->SetColor(vec4(.0f, .2f, .5f, 1.f));
112        Ticker::Ref(m_lights.Last());
113
114        m_lights << new Light();
115        m_lights.Last()->SetPosition(vec4(8.f, 2.f, 6.f, 1.f));
116        m_lights.Last()->SetColor(vec4(.5f, .3f, .0f, 1.f));
117        Ticker::Ref(m_lights.Last());
118
[2353]119        //Speed damp
120        m_mesh_rotate_damp = vec2(.0f);
121        m_mesh_screen_move_damp = vec2(.0f);
122        m_mesh_move_damp = vec2(.0f);
[2294]123
[2353]124        //Actual values
125        SetDefaultMeshTransform();
126
127        //Actual values damp
128        m_mesh_rotation_damp = vec2(.0f);
129        m_mesh_screen_offset_damp = vec2(.0f);
130        m_mesh_offset_damp = vec2(.0f);
131
132
133        m_mat = mat4::rotate(m_mesh_rotation.x, vec3(1, 0, 0)) *
134                mat4::rotate(m_angle, vec3(0, 1, 0)) *
135                mat4::rotate(m_mesh_rotation.y, vec3(0, 1, 0));
136
[2364]137        m_stream_update_time = 2.0f;
[2353]138        m_stream_update_timer = 1.0f;
[2294]139    }
140
141    ~MeshViewer()
142    {
143        Ticker::Unref(m_camera);
[2298]144        for (int i = 0; i < m_lights.Count(); ++i)
145            Ticker::Unref(m_lights[i]);
[2294]146    }
147
[2353]148    void SetDefaultMeshTransform()
149    {
150        m_mesh_rotation = vec2(25.0f, .0f);
151        m_mesh_screen_offset = vec2(.54f, .0f);
152        m_mesh_offset = vec2(-.64f, .07f);
153    }
[2356]154
[2294]155    virtual void TickGame(float seconds)
156    {
157        WorldEntity::TickGame(seconds);
158
[2370]159        //TODO : This should probably be "standard LoL behaviour"
160        {
161            //Shutdown logic
162            if (Input::WasReleased(Key::Escape))
163                Ticker::Shutdown();
164        }
[2294]165
[2353]166        //Update Mesh BBox - Get the Min/Max needed
167        vec3 min_max[2] = { vec3(FLT_MAX), vec3(-FLT_MAX) };
168        int mesh_id = m_meshes.Count() - 1;
169        for (; mesh_id >= 0; mesh_id--)
170            if (m_meshes[mesh_id].m2)
171                break;
[2294]172
[2353]173        if (m_meshes.Count() && mesh_id >= 0)
174        {
175            for (int i = 0; i < m_meshes[mesh_id].m1.GetVertexCount(); i++)
176            {
177                vec3 vpos = m_meshes[mesh_id].m1.GetVertexLocation(i);
178                min_max[0] = min(vpos.xyz, min_max[0]);
179                min_max[1] = max(vpos.xyz, min_max[1]);
180            }
181        }
182        else
183        {
184            min_max[0] = vec3(.0f);
185            min_max[1] = vec3(.0f);
186        }
187        //[0] : center, [1] : size.
188        vec3 BBox[2] = { vec3(.0f), vec3(.0f) };
189        BBox[1] = min_max[1] - min_max[0];
190        BBox[0] = min_max[0] + BBox[1] * .5f;
191        vec3 BBox_mod = BBox[1];
[2298]192
[2353]193        //--
194        //Camera movement handling
195        //--
[2356]196        vec3 cam_move = BBox_mod * seconds *
197                        vec3(.0f, .0f, (float)(Input::GetStatus(IPT_CAM_BACKWARD) - Input::GetStatus(IPT_CAM_FORWARD)));
198
[2353]199        if (Input::WasReleased(IPT_CAM_RESET))
200            SetFov();
[2356]201
[2353]202        float fov_zoom = (float)(Input::GetStatus(IPT_CAM_ZOOM_OUT) - Input::GetStatus(IPT_CAM_ZOOM_IN));
203        m_fov_zoom_damp = damp(m_fov_zoom_damp, fov_zoom, (fov_zoom == .0f)?(.15f):(0.5f), seconds);
[2356]204        m_fov = max(.0f, m_fov + seconds * 10.0f * m_fov_zoom_damp);
205        m_fov_damp = damp(m_fov_damp, m_fov, .2f, seconds);
[2353]206        SetFov(m_fov_damp);
[2294]207
[2353]208        m_camera->SetPosition(m_camera->GetPosition() + cam_move);
209        m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f));
[2294]210
[2353]211        //--
212        //Mesh movement handling
213        //--
214        if (Input::WasReleased(IPT_MESH_RESET))
215            SetDefaultMeshTransform();
216
217        vec2 new_move = vec2(.0f);
[2356]218
219        new_move = vec2((float)(Input::GetStatus(IPT_MESH_RIGHT) - Input::GetStatus(IPT_MESH_LEFT)),
[2353]220                        (float)(Input::GetStatus(IPT_MESH_UP)    - Input::GetStatus(IPT_MESH_DOWN)));
221        m_mesh_screen_move_damp = vec2(damp(m_mesh_screen_move_damp.x, new_move.x, (new_move.x == .0f)?(.15f):(0.5f), seconds),
222                                         damp(m_mesh_screen_move_damp.y, new_move.y, (new_move.y == .0f)?(.15f):(0.5f), seconds));
[2356]223
224        new_move = vec2((float)(Input::GetStatus(IPT_MESH_OFFSET_UP) - Input::GetStatus(IPT_MESH_OFFSET_DOWN)),
[2353]225                        (float)(Input::GetStatus(IPT_MESH_SCALE_UP)  - Input::GetStatus(IPT_MESH_SCALE_DOWN)));
226        m_mesh_move_damp = vec2(damp(m_mesh_move_damp.x, new_move.x, (new_move.x == .0f)?(.15f):(0.5f), seconds),
227                                  damp(m_mesh_move_damp.y, new_move.y, (new_move.y == .0f)?(.15f):(0.5f), seconds));
[2356]228
229        new_move = vec2((float)(Input::GetStatus(IPT_MESH_ROT_UP)    - Input::GetStatus(IPT_MESH_ROT_DOWN)),
[2353]230                        (float)(Input::GetStatus(IPT_MESH_ROT_RIGHT) - Input::GetStatus(IPT_MESH_ROT_LEFT)));
231        m_mesh_rotate_damp = vec2(damp(m_mesh_rotate_damp.x, new_move.x, (new_move.x == .0f)?(.15f):(0.5f), seconds),
[2356]232                                    damp(m_mesh_rotate_damp.y, new_move.y, (new_move.y == .0f)?(.15f):(0.5f), seconds));
[2353]233
[2356]234        vec2 mesh_screen_move = seconds * 0.6f * m_mesh_screen_move_damp;
235        vec2 mesh_offset_move = seconds * vec2(.6f, .2f) * m_mesh_move_damp;
236        vec2 mesh_rotate = seconds * vec2(40.0f, 60.0f) * m_mesh_rotate_damp;
237
238        //Add movement
239        m_mesh_screen_offset += mesh_screen_move;
[2353]240        m_mesh_offset += mesh_offset_move;
[2356]241        m_mesh_rotation += mesh_rotate;
242
243        //Compute damp
[2353]244        m_mesh_rotation_damp = damp(m_mesh_rotation_damp, m_mesh_rotation, .2f, seconds);
245        m_mesh_screen_offset_damp = damp(m_mesh_screen_offset_damp, m_mesh_screen_offset, .2f, seconds);
246        m_mesh_offset_damp = damp(m_mesh_offset_damp, m_mesh_offset, .2f, seconds);
247
[2356]248        //Clamp necessary
249        m_mesh_rotation.x = clamp(m_mesh_rotation.x, -90.0f, 90.0f);
250        m_mesh_offset.y = max(.0f, m_mesh_offset.y);
251
[2353]252        //m_angle += seconds * 70.0f;
253        m_mat = mat4::rotate(m_mesh_rotation.x, vec3(1, 0, 0)) *
254                mat4::rotate(m_angle, vec3(0, 1, 0)) *
255                mat4::rotate(m_mesh_rotation.y, vec3(0, 1, 0));
256
257        //--
258        //File management
259        //--
260        if (Input::WasReleased(IPT_MESH_UPDATE))
261            m_stream_update_time = m_stream_update_timer + 1.0f;
262        m_stream_update_time += seconds;
[2356]263
[2364]264        if (m_stream_update_time > m_stream_update_timer)
[2294]265        {
[2364]266            m_stream_update_time = 0.f;
[2294]267
[2364]268            File f;
269            f.Open(m_file_name.C(), FileAccess::Read);
270            String cmd = f.ReadString();
271            f.Close();
[2353]272
[2364]273            if (cmd.Count()
274                 && (!m_cmdlist.Count() || cmd != m_cmdlist.Last()))
[2294]275            {
[2364]276                m_cmdlist << cmd;
[2294]277
[2353]278                //Create a new mesh
279                m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f));
[2364]280                m_meshes.Last().m1.Compile(cmd.C());
[2294]281            }
282        }
283    }
284
285    virtual void TickDraw(float seconds)
286    {
287        WorldEntity::TickDraw(seconds);
288
[2370]289        //TODO : This should probably be "standard LoL behaviour"
290        {
291            if (Input::WasReleased(Key::F1))
292                Video::SetDebugRenderMode(DebugRenderMode::Default);
293            if (Input::WasReleased(Key::F2))
294                Video::SetDebugRenderMode(DebugRenderMode::Wireframe);
295            if (Input::WasReleased(Key::F3))
296                Video::SetDebugRenderMode(DebugRenderMode::Lighting);
297            if (Input::WasReleased(Key::F4))
298                Video::SetDebugRenderMode(DebugRenderMode::Normal);
299            if (Input::WasReleased(Key::F5))
300                Video::SetDebugRenderMode(DebugRenderMode::UV);
301        }
302
[2353]303        for (int i = 0; i < m_meshes.Count(); i++)
[2294]304        {
[2353]305            if (!m_meshes[i].m2)
306            {
307                m_meshes[i].m1.MeshConvert();
308                m_meshes[i].m2 = true;
309            }
[2294]310        }
311
312        Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
313
[2353]314        mat4 default_proj = Scene::GetDefault()->GetProjMatrix();
[2294]315        for (int i = 0; i < m_meshes.Count(); i++)
316        {
[2353]317            float new_scale = max(.0f, 1.0f - (m_mesh_offset_damp.y * (float)(m_meshes.Count() - (i + 1))));
318            m_meshes[i].m3 = damp(m_meshes[i].m3, new_scale, .35f, seconds);
319            if (m_meshes[i].m3 > .0f)
320            {
321                vec3 new_mesh_offset = vec3(.0f);
322                for (int j = m_meshes.Count() - 1; j > i; j--)
323                {
324                    float ofs_scale = max(.0f, 1.0f - (m_mesh_offset_damp.y * (float)(m_meshes.Count() - (j + 0))));
325                    new_mesh_offset = new_mesh_offset + vec3(m_meshes[j].m3 * ofs_scale * ofs_scale * m_mesh_offset_damp.x, .0f, .0f);
326                }
327                m_meshes[i].m4 = damp(m_meshes[i].m4, new_mesh_offset, .35f, seconds);
328                Scene::GetDefault()->SetProjMatrix(mat4::translate(m_meshes[i].m4) *
329                                                   mat4::translate(vec3(m_mesh_screen_offset_damp, .0f)) *
330                                                   mat4::scale(vec3(vec2(m_meshes[i].m3), 1.0f)) *
331                                                   default_proj *
332                                                   m_fov_compensation);
333                m_meshes[i].m1.Render(m_mat);
334                Video::Clear(ClearMask::Depth);
335            }
[2294]336        }
[2353]337        Scene::GetDefault()->SetProjMatrix(default_proj);
[2294]338    }
339
340private:
[2353]341    float           m_angle;
342    mat4            m_mat;
[2294]343
[2353]344    //Mesh infos
345    //Move damping
346    vec2            m_mesh_rotate_damp;
347    vec2            m_mesh_screen_move_damp;
348    vec2            m_mesh_move_damp;
[2294]349
[2353]350    //Move transform damping
351    vec2            m_mesh_rotation_damp;
352    vec2            m_mesh_screen_offset_damp;
[2356]353    vec2            m_mesh_offset_damp;
[2353]354
355    vec2            m_mesh_rotation;     //Meshes rotation
356    vec2            m_mesh_screen_offset;//Meshes screen offset
357    vec2            m_mesh_offset;       //Mesh Offset after first mesh (x: offset, y: scale)
358
359    //File data
[2364]360    String          m_file_name;
361    Array<String>   m_cmdlist;
[2353]362    float           m_stream_update_time;
363    float           m_stream_update_timer;
364
365    //misc datas
366    Array<EasyMesh, bool, float, vec3> m_meshes;
367    Array<Light *>  m_lights;
368    Camera *        m_camera;
369    float           m_fov;
370    float           m_fov_damp;
371    float           m_fov_zoom_damp;
372    mat4            m_fov_compensation;
[2294]373};
374
[2356]375//The basic main :
[2294]376int main(int argc, char **argv)
377{
378    System::Init(argc, argv);
379
[2353]380    Application app("MeshViewer", ivec2(1600, 600), 60.0f);
381    if (argc > 1)
382        new MeshViewer(argv[1]);
383    else
384        new MeshViewer();
[2294]385    app.Run();
386
387    return EXIT_SUCCESS;
388}
389
Note: See TracBrowser for help on using the repository browser.