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 | |
---|
20 | using namespace std; |
---|
21 | using namespace lol; |
---|
22 | #define MESH_DIST 5.0f |
---|
23 | |
---|
24 | class MeshViewer : public WorldEntity |
---|
25 | { |
---|
26 | public: |
---|
27 | MeshViewer() |
---|
28 | { |
---|
29 | int i=10; |
---|
30 | while (i--) |
---|
31 | { |
---|
32 | m_meshes.Push(EasyMesh()); |
---|
33 | m_meshes.Last().Compile("[sc#0f0 ab 2 2 2 t .8 .8 .8 rx 20 ry 20 [sc#00f 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 | min_pos = vec3(FLT_MAX); |
---|
47 | max_pos = vec3(-FLT_MAX); |
---|
48 | |
---|
49 | m_ready = false; |
---|
50 | } |
---|
51 | |
---|
52 | ~MeshViewer() |
---|
53 | { |
---|
54 | Ticker::Unref(m_camera); |
---|
55 | } |
---|
56 | |
---|
57 | virtual void TickGame(float seconds) |
---|
58 | { |
---|
59 | WorldEntity::TickGame(seconds); |
---|
60 | //vec4 vertex = in_ModelView * vec4(in_Vertex, 1.0); |
---|
61 | // gl_Position = in_Proj * vertex; |
---|
62 | |
---|
63 | |
---|
64 | m_angle += seconds * 70.0f; |
---|
65 | m_mat = mat4::rotate(m_angle, vec3(0, 1, 0)); |
---|
66 | |
---|
67 | //mat4 screen_matrix = Scene::GetDefault()->GetProjMatrix() * Scene::GetDefault()->GetViewMatrix(); |
---|
68 | mat4 world_view_matrix = m_camera->GetViewMatrix() * m_mat; |
---|
69 | mat4 world_screen_matrix = m_camera->GetProjMatrix() * world_view_matrix; |
---|
70 | mat4 view_world_matrix = inverse(m_camera->GetViewMatrix()); |
---|
71 | mat4 screen_view_matrix = inverse(m_camera->GetProjMatrix()); |
---|
72 | vec4 a(0, 2, 0, 1.0f); |
---|
73 | vec4 b(0,-2, 0, 1.0f); |
---|
74 | vec4 c(0, 0, -2, 1.0f); |
---|
75 | vec4 d(-1, -1, 1, 1.0f); |
---|
76 | |
---|
77 | //vec2 toto; |
---|
78 | //near plane : vec4(toto, 1.f, 1.f); |
---|
79 | //far plane : vec4(toto, -1.f, 1.f); |
---|
80 | |
---|
81 | a = vec4((world_screen_matrix * a).xyz / a.w, a.w); |
---|
82 | b = vec4((world_screen_matrix * b).xyz / b.w, b.w); |
---|
83 | c = vec4((inverse(world_screen_matrix) * c).xyz / c.w, c.w); |
---|
84 | d = vec4((inverse(world_screen_matrix) * d).xyz / d.w, d.w); |
---|
85 | a = b; |
---|
86 | c = d; |
---|
87 | |
---|
88 | //this is the algorithm for a camera that must keep n target in the screen |
---|
89 | { |
---|
90 | //Get the Min/Max needed |
---|
91 | vec3 new_min_pos(FLT_MAX); |
---|
92 | vec3 new_max_pos(-FLT_MAX); |
---|
93 | for (int i = 0; i < m_meshes.Last().GetVertexCount(); i++) |
---|
94 | { |
---|
95 | vec4 vpos = world_view_matrix * vec4(m_meshes.Last().GetVertexLocation(i), 1.0f); |
---|
96 | new_min_pos = min(vpos.xyz, new_min_pos); |
---|
97 | new_max_pos = max(vpos.xyz, new_max_pos); |
---|
98 | } |
---|
99 | |
---|
100 | //Actual camera algorithm |
---|
101 | { |
---|
102 | vec4 BottomLeft = m_camera->GetProjMatrix() * vec4(new_min_pos.xy, new_min_pos.z, 1.0f); |
---|
103 | vec4 TopRight = m_camera->GetProjMatrix() * vec4(new_max_pos.xy, new_min_pos.z, 1.0f); |
---|
104 | BottomLeft = vec4(BottomLeft.xyz / BottomLeft.w, BottomLeft.w); |
---|
105 | TopRight = vec4(TopRight.xyz / TopRight.w, TopRight.w); |
---|
106 | //vec2 NewSize = TopRight.xy - BottomLeft.xy; |
---|
107 | //NewSize.x = max(NewSize.x, NewSize.y) * 1.5f; |
---|
108 | vec4 DistantPoint = screen_view_matrix * vec4(vec2(1.0f, 1.0f), TopRight.z * TopRight.w, TopRight.w); |
---|
109 | |
---|
110 | vec3 vcenter = vec3(new_min_pos.xy + new_max_pos.xy, .0f) * .5f; |
---|
111 | vec4 new_pos = screen_view_matrix * vec4(.0f, .0f, new_min_pos.z, 1.0f); |
---|
112 | //vcenter.z += (new_pos.z - new_pos.z * NewSize.x); |
---|
113 | vcenter = (view_world_matrix * vec4(vcenter, 1.0f)).xyz; |
---|
114 | |
---|
115 | m_camera->SetPosition(damp(m_camera->GetPosition(), vcenter, 0.4f, seconds)); |
---|
116 | //m_camera->SetPosition(vcenter); |
---|
117 | m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f)); |
---|
118 | } |
---|
119 | // |
---|
120 | } |
---|
121 | } |
---|
122 | |
---|
123 | virtual void TickDraw(float seconds) |
---|
124 | { |
---|
125 | WorldEntity::TickDraw(seconds); |
---|
126 | |
---|
127 | if (!m_ready) |
---|
128 | { |
---|
129 | for (int i = 0; i < m_meshes.Count(); i++) |
---|
130 | m_meshes[i].MeshConvert(); |
---|
131 | m_ready = true; |
---|
132 | } |
---|
133 | |
---|
134 | Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); |
---|
135 | |
---|
136 | m_mat = mat4::translate(vec3(m_meshes.Count() * MESH_DIST * 0.5f, 0, m_meshes.Count() * MESH_DIST) * -1.0f) * m_mat; |
---|
137 | for (int i = 0; i < m_meshes.Count(); i++) |
---|
138 | { |
---|
139 | m_mat = mat4::translate(vec3(MESH_DIST * 0.5f, 0, MESH_DIST)) * m_mat; |
---|
140 | m_meshes[i].Render(m_mat); |
---|
141 | Video::Clear(ClearMask::Depth); |
---|
142 | } |
---|
143 | //m_mat = mat4::translate(vec3(.0f)); |
---|
144 | //m_meshes.Last().Render(m_mat); |
---|
145 | } |
---|
146 | |
---|
147 | private: |
---|
148 | //Array<EasyMesh, mat4, float> m_gears; |
---|
149 | float m_angle; |
---|
150 | mat4 m_mat; |
---|
151 | vec3 min_pos; |
---|
152 | vec3 max_pos; |
---|
153 | |
---|
154 | Array<EasyMesh> m_meshes; |
---|
155 | Camera *m_camera; |
---|
156 | |
---|
157 | bool m_ready; |
---|
158 | }; |
---|
159 | |
---|
160 | int main(int argc, char **argv) |
---|
161 | { |
---|
162 | System::Init(argc, argv); |
---|
163 | |
---|
164 | Application app("MeshViewer", ivec2(960, 600), 60.0f); |
---|
165 | new MeshViewer(); |
---|
166 | app.Run(); |
---|
167 | |
---|
168 | return EXIT_SUCCESS; |
---|
169 | } |
---|
170 | |
---|