gKit2 light
Loading...
Searching...
No Matches
tuto_transform.cpp
Go to the documentation of this file.
1
3
4#include "mat.h"
5#include "wavefront.h"
6
7#include "orbiter.h"
8#include "draw.h"
9#include "app.h"
10
11
12// renvoie vrai si la boite englobante est au moins partiellement visible
13bool visible( const Transform& mvp, const Point& pmin, const Point& pmax )
14{
15 int planes[6] = { };
16
17 // enumere les 8 sommets de la boite englobante
18 for(unsigned int i= 0; i < 8; i++)
19 {
20 Point p= pmin;
21 if(i & 1) p.x= pmax.x;
22 if(i & 2) p.y= pmax.y;
23 if(i & 4) p.z= pmax.z;
24
25 // transformation du point homogene (x, y, z, w= 1)
26 vec4 h= mvp(vec4(p));
27
28 // teste la position du point homogene par rapport aux 6 faces de la region visible
29 if(h.x < -h.w) planes[0]++; // trop a gauche
30 if(h.x > h.w) planes[1]++; // trop a droite
31
32 if(h.y < -h.w) planes[2]++; // trop bas
33 if(h.y > h.w) planes[3]++; // trop haut
34
35 if(h.z < -h.w) planes[4]++; // trop pres
36 if(h.z > h.w) planes[5]++; // trop loin
37 }
38
39 // verifie si tous les sommets sont du "mauvais cote" d'une seule face, planes[i] == 8
40 for(unsigned int i= 0; i < 6; i++)
41 if(planes[i] == 8)
42 return false; // la boite englobante n'est pas visible
43
44 // l'objet doit etre visible, ou pas, il faut aussi le test dans l'autre sens...
45 return true;
46}
47
48
49class TP : public App
50{
51public:
52 // constructeur : donner les dimensions de l'image, et eventuellement la version d'openGL.
53 TP( ) : App(1024, 640) {}
54
55 int init( )
56 {
57 // volume visible par une camera, un cube -1 1
58 m_frustum= read_mesh("data/frustum.obj");
59
60 // grille / plan de reference
61 m_grid.create(GL_LINES);
62 for(int x= 0; x < 10; x++)
63 {
64 float px= (float) x - 5.f + 0.5f;
65 m_grid.vertex(px, 0, -4.5f);
66 m_grid.vertex(px, 0, 4.5f);
67 }
68
69 for(int z= 0; z < 10; z++)
70 {
71 float pz= (float) z - 5.f + 0.5f;
72 m_grid.vertex(-4.5f, 0, pz);
73 m_grid.vertex(4.5f, 0, pz);
74 }
75
76 // charge un objet a afficher
77 m_objet= read_mesh("data/bigguy.obj");
78
79 // conserve (les extremites de) sa boite englobante
80 m_objet.bounds(m_pmin, m_pmax);
81 m_camera.lookat(m_pmin, m_pmax);
82 //~ m_camera.lookat(Point(), 10);
83
84 m_objet.default_color(Green());
85
86 // etat openGL par defaut
87 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
88
89 glClearDepth(1.f); // profondeur par defaut
90 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
91 glEnable(GL_DEPTH_TEST); // activer le ztest
92
93 return 0; // ras, pas d'erreur
94 }
95
96 // destruction des objets de l'application
97 int quit( )
98 {
99 m_frustum.release();
100 m_grid.release();
101 m_objet.release();
102 glDeleteTextures(1, &m_texture);
103
104 return 0;
105 }
106
107 int update( const float time, const float delta )
108 {
109 // modifier l'orientation du cube a chaque image.
110 // time est le temps ecoule depuis le demarrage de l'application, en millisecondes,
111 // delta est le temps ecoule depuis l'affichage de la derniere image / le dernier appel a draw(), en millisecondes.
112
113 m_model= RotationY(time / 20);
114 return 0;
115 }
116
117 // dessiner une nouvelle image
118 int render( )
119 {
120 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
121
122 // deplace la camera
123 int mx, my;
124 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
125
126 if(key_state(' '))
127 {
128 // deplace la camera "normale"
129 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
130 m_camera.rotation((float) mx, (float) my);
131 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
132 m_camera.move((float) mx);
133 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
134 m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
135 }
136 else
137 {
138 // deplace l'observateur
139 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
140 m_observer.rotation((float) mx / 10, (float) my / 10);
141 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
142 m_observer.move((float) mx / 10);
143 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
144 m_observer.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
145 }
146
147 // affiche l'objet en rouge, si sa boite englobante n'est pas visible pour la camera.
148 if(visible(m_camera.projection((float) window_width(), (float)window_height(), 45) * m_camera.view() * m_model, m_pmin, m_pmax))
149 m_objet.default_color(Green());
150 else
151 m_objet.default_color(Red());
152
153
154 Transform view= m_observer.view();
155 Transform projection= Perspective(45, (float) window_width() / (float) window_height(), .1f, 1000.f);
156
157 static bool wireframe= false;
158 if(key_state(' '))
159 {
160 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
161
162 // afficher le point de vue "normal"
163 draw(m_grid, m_camera);
164 draw(m_objet, m_model, m_camera);
165 }
166 else
167 {
168 if(key_state('w'))
169 {
170 clear_key_state('w');
171 wireframe= !wireframe;
172 }
173
174 if(!wireframe)
175 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
176 else
177 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
178
179 #if 1
180 // afficher le volume visible de la camera dans le repere monde
181 draw(m_grid, Identity(), view, projection);
182 draw(m_frustum, Inverse(m_camera.projection((float) window_width(), (float) window_height(), 45) * m_camera.view()), view, projection);
183 draw(m_objet, m_model, view, projection);
184
185 #else
186 // afficher dans le repere image
187 draw(m_grid, m_camera.projection(window_width(), window_height(), 45) * m_camera.view(), view, projection);
188 draw(m_frustum, m_camera.projection(window_width(), window_height(), 45) * m_camera.view() * Inverse(m_camera.projection(window_width(), window_height(), 45) * m_camera.view()), view, projection);
189 // remarque : ca se simplifie non ??
190 draw(m_objet, m_camera.projection(window_width(), window_height(), 45) * m_camera.view() * m_model, view, projection);
191 #endif
192 }
193
194 return 1;
195 }
196
197protected:
198 Transform m_model;
199 Mesh m_frustum;
200 Mesh m_objet;
201 Mesh m_grid;
202 GLuint m_texture;
203 Orbiter m_camera;
204 Orbiter m_observer;
205
206 Point m_pmin, m_pmax;
207};
208
209
210int main( int argc, char **argv )
211{
212 TP tp;
213 tp.run();
214
215 return 0;
216}
classe application.
Definition app.h:20
App(const int width, const int height, const int major=3, const int minor=3, const int samples=0)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app.cpp:11
int run()
execution de l'application.
Definition app.cpp:36
representation d'un objet / maillage.
Definition mesh.h:121
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition orbiter.h:17
Definition alpha.cpp:58
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int update(const float time, const float delta)
a deriver et redefinir pour animer les objets en fonction du temps.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition window.cpp:46
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:40
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
Color Red()
utilitaire. renvoie une couleur rouge.
Definition color.cpp:28
Color Green()
utilitaire. renvoie une couleur verte.
Definition color.cpp:33
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition mat.cpp:197
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition mat.cpp:242
Transform Perspective(const float fov, const float aspect, const float znear, const float zfar)
renvoie la matrice representant une transformation projection perspective.
Definition mat.cpp:329
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
representation d'un point 3d.
Definition vec.h:21
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
vecteur generique 4d, ou 3d homogene, utilitaire.
Definition vec.h:192