gKit2 light
object_tuto2.cpp
1 
2 #include "window.h"
3 
4 #include "vec.h"
5 #include "mat.h"
6 #include "color.h"
7 
8 #include "mesh.h"
9 #include "orbiter.h"
10 
11 #include "wavefront.h"
12 #include "draw.h"
13 
14 #include "texture.h"
15 
16 Orbiter camera;
17 
18 
19 struct Body
20 {
21  Mesh mesh;
22  Vector displacement ;
23  float spin ;
24  float scale ;
25  float revolution ;
26  Body* parent ;
27 
28  Body( ) :
29  displacement(make_vector(0.f, 0.f, 0.f)),
30  spin(0),
31  scale(1),
32  revolution(0),
33  parent(NULL)
34  {}
35 
36  Body( const Mesh& m, const Color& c ) :
37  mesh(m),
38  displacement(make_vector(0.f, 0.f, 0.f)),
39  spin(0),
40  scale(1),
41  revolution(0),
42  parent(NULL)
43  {
44  mesh.color= c ;
45  }
46 
47  Transform get_parent_transform(float time)
48  {
49  Transform res = make_identity() ;
50  if(parent)
51  {
52  res = res*parent->get_parent_transform(time) ;
53  }
54  res = res*make_rotationY(revolution*time) ;
55  res = res*make_translation(displacement) ;
56  return res ;
57  }
58 
59  Transform get_transform(float time)
60  {
61  Transform res = make_identity() ;
62  if(parent)
63  {
64  res = res*parent->get_parent_transform(time) ;
65  }
66  res = res*make_rotationY(revolution*time) ;
67  res = res*make_translation(displacement) ;
68  res = res*make_rotationY(spin*time) ;
69  res = res*make_scale(scale, scale, scale) ;
70  return res ;
71  }
72 
73 };
74 
75 
76 void draw( Body& body, float time, const Orbiter& orbiter )
77 {
78  draw(body.mesh, body.get_transform(time), orbiter);
79 }
80 
81 
82 Mesh grid;
83 
84 Body sun ;
85 Body planet ;
86 Body moon ;
87 
88 // utilitaire. creation d'une grille / repere.
89 Mesh make_grid( )
90 {
91  Mesh grid= create_mesh(GL_LINES);
92 
93  for(int x= 0; x < 10; x++)
94  {
95  float px= (float) x - 5.f + 0.5f;
96  push_vertex(grid, make_point(px, 0, -4.5f));
97  push_vertex(grid, make_point(px, 0, 4.5f));
98  }
99 
100  for(int z= 0; z < 10; z++)
101  {
102  float pz= (float) z - 5.f + 0.5f;
103  push_vertex(grid, make_point(-4.5f, 0, pz));
104  push_vertex(grid, make_point(4.5f, 0, pz));
105  }
106 
107  return grid;
108 }
109 
110 // creation des objets openGL
111 int init( )
112 {
113  // lire un maillage
114  Mesh cube= read_mesh("data/cube.obj");
115  if(cube.positions.size() == 0)
116  return -1;
117 
118  sun = Body(cube, make_red());
119  sun.spin = -0.02 ;
120 
121  planet = Body(cube, make_blue());
122  planet.displacement = make_vector(4, 0, 0) ;
123  planet.scale = 0.5 ;
124  planet.spin = 0.1 ;
125  planet.revolution = 0.05 ;
126  planet.parent = &sun ;
127 
128  moon = Body(cube, make_green()) ;
129  moon.displacement = make_vector(1, 0, 0) ;
130  moon.scale = 0.2 ;
131  moon.spin = 0.3 ;
132  moon.revolution = -0.1 ;
133  moon.parent = &planet ;
134 
135  camera= make_orbiter();
136  grid= make_grid();
137 
138  // etat par defaut
139  glClearColor(0.2, 0.2, 0.2, 1); // couleur par defaut de la fenetre
140 
141  glClearDepthf(1); // profondeur par defaut
142  glDepthFunc(GL_LEQUAL); // ztest, conserver l'intersection la plus proche de la camera
143  //~ glDepthFunc(GL_ALWAYS); // ztest, conserver l'intersection la plus proche de la camera
144  glEnable(GL_DEPTH_TEST); // activer le ztest
145  //~ glDisable(GL_DEPTH_TEST); // activer le ztest
146 
147  glLineWidth(2.5f); // epaisseur des lignes de la grille (pixels)
148 
149  return 0; // renvoyer 0 ras, pas d'erreur, sinon renvoyer -1
150 }
151 
152 // affichage
153 int draw( )
154 {
155  // on commence par effacer la fenetre avant de dessiner quelquechose
156  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
157  // on efface aussi le zbuffer
158 
159  // recupere les mouvements de la souris, utilise directement SDL2
160  int mx, my;
161  unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
162 
163  // deplace la camera
164  if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
165  // tourne autour de l'objet
166  orbiter_rotation(camera, mx, my);
167 
168  else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
169  // approche / eloigne l'objet
170  orbiter_move(camera, mx);
171 
172  else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
173  // deplace le point de rotation
174  orbiter_translation(camera, (float) mx / (float) window_width(), (float) my / (float) window_height());
175 
176  // affiche la grille / repere
177  draw(grid, camera);
178 
179  float sunx= 0;
180  float sunz= 0;
181  if(key_state('z'))
182  sunz-= 0.1f;
183  if(key_state('s'))
184  sunz+= 0.1f;
185  if(key_state('q'))
186  sunx-= 0.1f;
187  if(key_state('d'))
188  sunx+= 0.1f;
189 
190  sun.displacement = sun.displacement + make_vector(sunx, 0, sunz) ;
191 
192  float planet_dist= 0;
193  if(key_state('w'))
194  planet_dist-= 0.1f;
195  if(key_state('x'))
196  planet_dist+= 0.1f;
197 
198  planet.displacement = planet.displacement + make_vector(planet_dist, 0, 0) ;
199 
200  float moon_dist= 0;
201  if(key_state('c'))
202  moon_dist-= 0.1f;
203  if(key_state('v'))
204  moon_dist+= 0.1f;
205 
206  moon.displacement = moon.displacement + make_vector(moon_dist, 0, 0) ;
207 
208  float time = (float) SDL_GetTicks() ;
209 
210  // affiche les objets
211  draw(sun, time, camera);
212  draw(planet, time, camera);
213  draw(moon, time, camera);
214 
215 
216  static bool video= false;
217  if(key_state(SDLK_RETURN))
218  {
219  clear_key_state(SDLK_RETURN);
220  video= !video;
221 
222  if(video)
223  printf("start video capture...\n");
224  else
225  printf("stop video capture.\n");
226  }
227  if(video)
228  capture("tutok");
229 
230 
231  return 1; // on continue, renvoyer 0 pour sortir de l'application
232 }
233 
234 // destruction des objets openGL
235 int quit( )
236 {
237  return 0; // ras, pas d'erreur
238 }
239 
240 
241 int main( int argc, char **argv )
242 {
243  // etape 1 : creer la fenetre
244  Window window= create_window(1024, 640);
245  if(window == NULL)
246  return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
247 
248  // etape 2 : creer un contexte opengl pour pouvoir dessiner
249  Context context= create_context(window);
250  if(context == NULL)
251  return 1; // erreur lors de la creation du contexte opengl
252 
253  // etape 3 : creation des objets
254  if(init() < 0)
255  {
256  printf("[error] init failed.\n");
257  return 1;
258  }
259 
260  // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
261  run(window, draw);
262 
263  // etape 5 : nettoyage
264  quit();
265  release_context(context);
266  release_window(window);
267 
268  return 0;
269 }
Context create_context(Window window, const int major, const int minor)
cree et configure un contexte opengl
Definition: window.cpp:252
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet...
Definition: orbiter.h:16
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition: window.cpp:30
Mesh & color(const vec4 &c)
definit la couleur du prochain sommet.
Definition: mesh.cpp:37
representation d'un objet / maillage.
Definition: mesh.h:88
representation d'une couleur (rgba) transparente ou opaque.
Definition: color.h:13
void draw(Mesh &m, const Transform &model, const Transform &view, const Transform &projection, const GLuint texture)
applique une texture a la surface de l'objet. ne fonctionne que si les coordonnees de textures sont f...
Definition: draw.cpp:6
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:14
int capture(const char *prefix)
Definition: texture.cpp:126
representation d'un vecteur 3d.
Definition: vec.h:42
Window create_window(const int w, const int h)
creation d'une fenetre pour l'application.
Definition: window.cpp:186
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition: window.cpp:24
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition: text.cpp:140
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:18
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:20
void release_context(Context context)
detruit le contexte openGL.
Definition: window.cpp:306
void release_window(Window window)
destruction de la fenetre.
Definition: window.cpp:222
int run(Window window, int(*draw)(void))
fonction principale. gestion des evenements et appel de la fonction draw de l'application.
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes. utiliser glDrawArrays pour l'afficher. a detruire avec Mesh::release( ).
Definition: wavefront.cpp:8