source: trunk/test/MeshViewer.cpp @ 2298

Last change on this file since 2298 was 2298, checked in by sam, 9 years ago

meshviewer: add two lights.

File size: 6.0 KB
Line 
1//
2// Lol Engine - EasyMesh tutorial
3//
4// Copyright: (c) 2011-2013 Sam Hocevar <sam@hocevar.net>
5//            (c) 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
6//   This program is free software; you can redistribute it and/or
7//   modify it under the terms of the Do What The Fuck You Want To
8//   Public License, Version 2, as published by Sam Hocevar. See
9//   http://www.wtfpl.net/ for more details.
10//
11
12#if defined HAVE_CONFIG_H
13#   include "config.h"
14#endif
15
16#include <cfloat> /* for FLT_MAX */
17
18#include "core.h"
19
20using namespace std;
21using namespace lol;
22#define MESH_DIST 5.0f
23
24class MeshViewer : public WorldEntity
25{
26public:
27    MeshViewer()
28    {
29        int i=10;
30        while (i--)
31        {
32            m_meshes.Push(EasyMesh());
33            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]]");
34        }
35
36        m_angle = 0;
37
38        m_camera = new Camera(vec3(0.f, 600.f, 0.f),
39                              vec3(0.f, 0.f, 0.f),
40                              vec3(0, 1, 0));
41        m_camera->SetPerspective(60.f, 16, 9, .1f, 1000.f);
42        m_camera->SetTarget(vec3(0.f, 0.f, 0.f));
43        m_camera->SetPosition(vec3(0.f, 0.f, 5.f));
44        m_camera->ForceSceneUpdate();
45        Ticker::Ref(m_camera);
46
47        m_lights << new Light();
48        m_lights.Last()->SetPosition(vec4(4.f, -1.f, -4.f, 0.f));
49        m_lights.Last()->SetColor(vec4(.0f, .2f, .5f, 1.f));
50        Ticker::Ref(m_lights.Last());
51
52        m_lights << new Light();
53        m_lights.Last()->SetPosition(vec4(8.f, 2.f, 6.f, 1.f));
54        m_lights.Last()->SetColor(vec4(.5f, .3f, .0f, 1.f));
55        Ticker::Ref(m_lights.Last());
56
57        min_pos = vec3(FLT_MAX);
58        max_pos = vec3(-FLT_MAX);
59
60        m_ready = false;
61    }
62
63    ~MeshViewer()
64    {
65        Ticker::Unref(m_camera);
66        for (int i = 0; i < m_lights.Count(); ++i)
67            Ticker::Unref(m_lights[i]);
68    }
69
70    virtual void TickGame(float seconds)
71    {
72        WorldEntity::TickGame(seconds);
73        //vec4 vertex = in_ModelView * vec4(in_Vertex, 1.0);
74        //    gl_Position = in_Proj * vertex;
75
76
77        m_angle += seconds * 70.0f;
78        m_mat = mat4::rotate(m_angle, vec3(0, 1, 0));
79
80        //mat4 screen_matrix = Scene::GetDefault()->GetProjMatrix() * Scene::GetDefault()->GetViewMatrix();
81        mat4 world_view_matrix = m_camera->GetViewMatrix() * m_mat;
82        mat4 world_screen_matrix = m_camera->GetProjMatrix() * world_view_matrix;
83        mat4 view_world_matrix = inverse(m_camera->GetViewMatrix());
84        mat4 screen_view_matrix = inverse(m_camera->GetProjMatrix());
85        vec4 a(0, 2, 0, 1.0f);
86        vec4 b(0,-2, 0, 1.0f);
87        vec4 c(0, 0, -2, 1.0f);
88        vec4 d(-1, -1, 1, 1.0f);
89
90        //vec2 toto;
91        //near plane : vec4(toto, 1.f, 1.f);
92        //far plane : vec4(toto, -1.f, 1.f);
93
94        a = vec4((world_screen_matrix * a).xyz / a.w, a.w);
95        b = vec4((world_screen_matrix * b).xyz / b.w, b.w);
96        c = vec4((inverse(world_screen_matrix) * c).xyz / c.w, c.w);
97        d = vec4((inverse(world_screen_matrix) * d).xyz / d.w, d.w);
98        a = b;
99        c = d;
100
101        //this is the algorithm for a camera that must keep n target in the screen
102        {
103            //Get the Min/Max needed
104            vec3 new_min_pos(FLT_MAX);
105            vec3 new_max_pos(-FLT_MAX);
106            for (int i = 0; i < m_meshes.Last().GetVertexCount(); i++)
107            {
108                vec4 vpos = world_view_matrix * vec4(m_meshes.Last().GetVertexLocation(i), 1.0f);
109                new_min_pos = min(vpos.xyz, new_min_pos);
110                new_max_pos = max(vpos.xyz, new_max_pos);
111            }
112
113            //Actual camera algorithm
114            {
115                vec4 BottomLeft = m_camera->GetProjMatrix() * vec4(new_min_pos.xy, new_min_pos.z, 1.0f);
116                vec4 TopRight = m_camera->GetProjMatrix() * vec4(new_max_pos.xy, new_min_pos.z, 1.0f);
117                BottomLeft = vec4(BottomLeft.xyz / BottomLeft.w, BottomLeft.w);
118                TopRight = vec4(TopRight.xyz / TopRight.w, TopRight.w);
119                //vec2 NewSize = TopRight.xy - BottomLeft.xy;
120                //NewSize.x = max(NewSize.x, NewSize.y) * 1.5f;
121                vec4 DistantPoint = screen_view_matrix * vec4(vec2(1.0f, 1.0f), TopRight.z * TopRight.w, TopRight.w);
122
123                vec3 vcenter = vec3(new_min_pos.xy + new_max_pos.xy, .0f) * .5f;
124                vec4 new_pos = screen_view_matrix * vec4(.0f, .0f, new_min_pos.z, 1.0f);
125                //vcenter.z += (new_pos.z - new_pos.z * NewSize.x);
126                vcenter = (view_world_matrix * vec4(vcenter, 1.0f)).xyz;
127
128                m_camera->SetPosition(damp(m_camera->GetPosition(), vcenter, 0.4f, seconds));
129                //m_camera->SetPosition(vcenter);
130                m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f));
131            }
132            //
133        }
134    }
135
136    virtual void TickDraw(float seconds)
137    {
138        WorldEntity::TickDraw(seconds);
139
140        if (!m_ready)
141        {
142            for (int i = 0; i < m_meshes.Count(); i++)
143                m_meshes[i].MeshConvert();
144            m_ready = true;
145        }
146
147        Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
148
149        m_mat = mat4::translate(vec3(m_meshes.Count() * MESH_DIST * 0.5f, 0, m_meshes.Count() * MESH_DIST) * -1.0f) * m_mat;
150        for (int i = 0; i < m_meshes.Count(); i++)
151        {
152            m_mat = mat4::translate(vec3(MESH_DIST * 0.5f, 0, MESH_DIST)) * m_mat;
153            m_meshes[i].Render(m_mat);
154            Video::Clear(ClearMask::Depth);
155        }
156        //m_mat = mat4::translate(vec3(.0f));
157        //m_meshes.Last().Render(m_mat);
158    }
159
160private:
161    //Array<EasyMesh, mat4, float> m_gears;
162    float m_angle;
163    mat4 m_mat;
164    vec3 min_pos;
165    vec3 max_pos;
166
167    Array<EasyMesh> m_meshes;
168    Array<Light *> m_lights;
169    Camera *m_camera;
170
171    bool m_ready;
172};
173
174int main(int argc, char **argv)
175{
176    System::Init(argc, argv);
177
178    Application app("MeshViewer", ivec2(960, 600), 60.0f);
179    new MeshViewer();
180    app.Run();
181
182    return EXIT_SUCCESS;
183}
184
Note: See TracBrowser for help on using the repository browser.