source: trunk/demos/tutorial/07_input.cpp @ 2821

Last change on this file since 2821 was 2821, checked in by sam, 4 years ago

tutorial: tweak the input tutorial code.

  • Property svn:eol-style set to LF
File size: 7.1 KB
Line 
1//
2// Lol Engine - Cube tutorial
3//
4// Copyright: (c) 2011-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "core.h"
16#include "loldebug.h"
17
18using namespace std;
19using namespace lol;
20
21LOLFX_RESOURCE_DECLARE(07_input);
22
23enum
24{
25    KEY_MANUAL_ROTATION,
26    KEY_DRAG_MESH,
27    KEY_MAX
28};
29
30enum
31{
32    AXIS_DRAG_PITCH,
33    AXIS_DRAG_YAW,
34    AXIS_PITCH,
35    AXIS_YAW,
36    AXIS_MAX
37};
38
39#if LOL_INPUT_V2
40Controller* controller;
41#endif
42
43class Cube : public WorldEntity
44{
45public:
46    Cube()
47    {
48        m_pitch_angle = 0;
49        m_yaw_angle = 0;
50        m_autorot = true;
51
52        /* Front vertices/colors */
53        m_mesh.Push(vec3(-1.0, -1.0,  1.0), vec3(1.0, 0.0, 1.0));
54        m_mesh.Push(vec3( 1.0, -1.0,  1.0), vec3(0.0, 1.0, 0.0));
55        m_mesh.Push(vec3( 1.0,  1.0,  1.0), vec3(1.0, 0.5, 0.0));
56        m_mesh.Push(vec3(-1.0,  1.0,  1.0), vec3(1.0, 1.0, 0.0));
57        /* Back */
58        m_mesh.Push(vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0));
59        m_mesh.Push(vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0));
60        m_mesh.Push(vec3( 1.0,  1.0, -1.0), vec3(0.0, 0.5, 1.0));
61        m_mesh.Push(vec3(-1.0,  1.0, -1.0), vec3(0.0, 0.0, 1.0));
62
63        m_faces_indices << 0 << 1 << 2 << 2 << 3 << 0;
64        m_faces_indices << 1 << 5 << 6 << 6 << 2 << 1;
65        m_faces_indices << 7 << 6 << 5 << 5 << 4 << 7;
66        m_faces_indices << 4 << 0 << 3 << 3 << 7 << 4;
67        m_faces_indices << 4 << 5 << 1 << 1 << 0 << 4;
68        m_faces_indices << 3 << 2 << 6 << 6 << 7 << 3;
69
70        m_lines_indices << 0 << 1 << 1 << 2 << 2 << 3 << 3 << 0;
71        m_lines_indices << 4 << 5 << 5 << 6 << 6 << 7 << 7 << 4;
72        m_lines_indices << 0 << 4 << 1 << 5 << 2 << 6 << 3 << 7;
73
74        m_text = new Text(NULL, "data/font/ascii.png");
75        m_text->SetPos(ivec3(5, 5, 1));
76        Ticker::Ref(m_text);
77
78        m_ready = false;
79    }
80
81    ~Cube()
82    {
83        Ticker::Unref(m_text);
84    }
85
86    virtual void TickGame(float seconds)
87    {
88        WorldEntity::TickGame(seconds);
89
90#if LOL_INPUT_V2
91        if (controller->GetKey(KEY_MANUAL_ROTATION).IsPressed())
92            m_autorot = !m_autorot;
93
94        if (controller->GetKey(KEY_DRAG_MESH).IsDown())
95        {
96            InputDevice::CaptureMouse(true);
97            m_pitch_angle -= controller->GetAxis(AXIS_DRAG_PITCH).GetValue() * seconds * 100;
98            m_yaw_angle += controller->GetAxis(AXIS_DRAG_YAW).GetValue() * seconds * 100;
99        }
100        else
101        {
102            InputDevice::CaptureMouse(false);
103#endif
104            if (m_autorot)
105               m_yaw_angle += seconds * 20;
106#if LOL_INPUT_V2
107        }
108        if (lol::abs(controller->GetAxis(AXIS_PITCH).GetValue()) > 0.2f)
109            m_pitch_angle -= controller->GetAxis(AXIS_PITCH).GetValue() * seconds * 100;
110        if (lol::abs(controller->GetAxis(AXIS_YAW).GetValue()) > 0.2f)
111            m_yaw_angle += controller->GetAxis(AXIS_YAW).GetValue() * seconds * 100;
112
113        InputDevice* mouse = InputDevice::Get("Mouse");
114        if (mouse)
115        {
116            m_text->SetText(String::Printf(
117                "cursor: (%0.3f, %0.3f) - pixel (%d, %d)",
118                mouse->GetCursor(0).x, mouse->GetCursor(0).y,
119                mouse->GetCursorPixel(0).x, mouse->GetCursorPixel(0).y));
120        }
121        else
122#endif
123        {
124            m_text->SetText("no mouse detected");
125        }
126
127        mat4 anim = mat4::fromeuler_yxz(m_yaw_angle, m_pitch_angle, 0.f);
128        mat4 model = mat4::translate(vec3(0, 0, -4.5));
129        mat4 view = mat4::lookat(vec3(0, 2, 0), vec3(0, 0, -4), vec3(0, 1, 0));
130        mat4 proj = mat4::perspective(45.0f, 640.0f, 480.0f, 0.1f, 10.0f);
131
132        m_matrix = proj * view * model * anim;
133    }
134
135    virtual void TickDraw(float seconds)
136    {
137        WorldEntity::TickDraw(seconds);
138
139        if (!m_ready)
140        {
141            m_shader = Shader::Create(LOLFX_RESOURCE_NAME(07_input));
142
143            m_mvp = m_shader->GetUniformLocation("in_Matrix");
144            m_coord = m_shader->GetAttribLocation("in_Vertex",
145                                                  VertexUsage::Position, 0);
146            m_color = m_shader->GetAttribLocation("in_Color",
147                                                  VertexUsage::Color, 0);
148
149            m_vdecl =
150              new VertexDeclaration(VertexStream<vec3,vec3>(VertexUsage::Position,
151                                                            VertexUsage::Color));
152
153            m_vbo = new VertexBuffer(m_mesh.Bytes());
154            void *mesh = m_vbo->Lock(0, 0);
155            memcpy(mesh, &m_mesh[0], m_mesh.Bytes());
156            m_vbo->Unlock();
157
158            m_lines_ibo = new IndexBuffer(m_lines_indices.Bytes());
159            void *indices = m_lines_ibo->Lock(0, 0);
160            memcpy(indices, &m_lines_indices[0], m_lines_indices.Bytes());
161            m_lines_ibo->Unlock();
162
163            m_faces_ibo = new IndexBuffer(m_faces_indices.Bytes());
164            indices = m_faces_ibo->Lock(0, 0);
165            memcpy(indices, &m_faces_indices[0], m_faces_indices.Bytes());
166            m_faces_ibo->Unlock();
167
168            /* FIXME: this object never cleans up */
169            m_ready = true;
170        }
171
172        g_renderer->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
173
174        m_shader->Bind();
175        m_vdecl->SetStream(m_vbo, m_coord, m_color);
176        m_vdecl->Bind();
177
178        m_shader->SetUniform(m_mvp, m_matrix);
179        m_lines_ibo->Bind();
180        m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, 0, 0,
181                                     m_mesh.Count(), 0, m_lines_indices.Count());
182        m_lines_ibo->Unbind();
183
184        m_shader->SetUniform(m_mvp, m_matrix * mat4::scale(0.5f));
185        m_faces_ibo->Bind();
186        m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, 0, 0,
187                                     m_mesh.Count(), 0, m_faces_indices.Count());
188        m_faces_ibo->Unbind();
189
190        m_vdecl->Unbind();
191    }
192
193private:
194    bool m_autorot;
195    float m_pitch_angle;
196    float m_yaw_angle;
197    mat4 m_matrix;
198    Array<vec3,vec3> m_mesh;
199    Array<uint16_t> m_lines_indices, m_faces_indices;
200
201    Shader *m_shader;
202    ShaderAttrib m_coord, m_color;
203    ShaderUniform m_mvp;
204    VertexDeclaration *m_vdecl;
205    VertexBuffer *m_vbo;
206    IndexBuffer *m_lines_ibo, *m_faces_ibo;
207
208    Text *m_text;
209    bool m_ready;
210};
211
212int main(int argc, char **argv)
213{
214    System::Init(argc, argv);
215
216    Application app("Tutorial 7: Input", ivec2(640, 480), 60.0f);
217
218    new DebugFps(5, 5);
219    new Cube();
220
221#if LOL_INPUT_V2
222    controller = new Controller(KEY_MAX, AXIS_MAX);
223    controller->GetKey(KEY_MANUAL_ROTATION).Bind("Keyboard", "Space");
224    controller->GetKey(KEY_DRAG_MESH).Bind("Mouse", "ButtonLeft");
225    controller->GetAxis(AXIS_DRAG_PITCH).Bind("Mouse", "Y");
226    controller->GetAxis(AXIS_DRAG_YAW).Bind("Mouse", "X");
227    controller->GetAxis(AXIS_PITCH).Bind("Joystick1", "Axis2");
228    controller->GetAxis(AXIS_YAW).Bind("Joystick1", "Axis1");
229#endif
230
231    app.Run();
232
233    return EXIT_SUCCESS;
234}
235
Note: See TracBrowser for help on using the repository browser.