gKit2 light
Loading...
Searching...
No Matches
scene_tuto1.cpp
1
2#include <math.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <time.h>
6
7#include "window.h"
8
9#include "mesh.h"
10#include "wavefront.h"
11#include "texture.h"
12
13#include "orbiter.h"
14
15#include "draw.h"
16
17
18Orbiter camera;
19
20struct Object
21{
22 Object *parent;
23 Mesh *mesh;
24 Transform model;
25 GLuint texture;
26};
27
28Object *create_object( Mesh *mesh, const Transform model, Object *parent= NULL )
29{
30 Object *object= new Object;
31 object->mesh= mesh;
32 object->model= model;
33 object->parent= parent;
34 object->texture= 0;
35 return object;
36}
37
38Transform model_transform( Object *object )
39{
40 if(object->parent == NULL)
41 return object->model;
42
43 return object->model * model_transform(object->parent);
44}
45
46Transform model_transform( Object *object, const Transform& local )
47{
48 if(object->parent == NULL)
49 return object->model;
50
51 return local * object->model * model_transform(object->parent);
52}
53
54std::vector<Object *> scene;
55
56
57void mesh_normalize( Mesh& mesh )
58{
59 // calcule le centre de gravite
60 Vector g= make_vector(mesh.positions[0]);
61 for(unsigned int i= 1; i < (unsigned int) mesh.positions.size(); i++)
62 g= g + make_vector(mesh.positions[i]);
63 g= g / (float) mesh.positions.size();
64
65 // calcule la distance max
66 float dmax= length(make_vector(mesh.positions[0]) - g);
67 for(unsigned int i= 1; i < (unsigned int) mesh.positions.size(); i++)
68 dmax= std::max(dmax, length(make_vector(mesh.positions[i]) - g));
69
70 // normalise les distances au centre de gravite
71 for(unsigned int i= 0; i < (unsigned int) mesh.positions.size(); i++)
72 {
73 Vector d= make_vector(mesh.positions[i]) - g;
74 mesh.positions[i]= make_vec3(d / dmax);
75 }
76}
77
78int init( )
79{
80 // charge un cube
81 Mesh *mesh= new Mesh();
82 *mesh= read_mesh("data/cube.obj");
83 mesh_normalize(*mesh);
84
85 Mesh *mesh2= new Mesh();
86 *mesh2= read_mesh("data/bigguy.obj");
87 mesh_normalize(*mesh2);
88
89 GLuint texture= read_texture(0, "data/debug2x2red.png");
90
91 // cree plusieurs copies du cube placees au hasard sur une grille
92 srand(time(0));
93
94 int grid_width= 32;
95 int grid_height= 32;
96 for(unsigned int i= 0; i < 200; i++)
97 {
98 float x= (float) rand() / (float) RAND_MAX * (grid_width -1) - grid_width / 2;
99 float z= (float) rand() / (float) RAND_MAX * (grid_height -1) - grid_height / 2;
100 float y= (float) rand() / (float) RAND_MAX - 0.5;
101 y*= (float) rand() / (float) RAND_MAX * 10;
102 float a= (float) rand() / (float) RAND_MAX;
103 Transform model= make_translation( make_vector(x, y, z) ) * make_rotationY(a * 180);
104
105 Object *parent= create_object(mesh, model, NULL);
106 parent->texture= texture;
107 scene.push_back(parent);
108
109 Transform local= make_translation(make_vector(0, 1.3, 0));
110 //~ Transform local= make_identity();
111 Object *object= create_object(mesh2, local, parent);
112 object->texture= 0;
113 scene.push_back(object);
114 }
115
116 camera= make_orbiter_lookat( make_point(0, 0, 0), 32 );
117
118 // etat openGL par defaut
119 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
120
121 // etape 3 : configuration du pipeline.
122 glClearDepth(1.f); // profondeur par defaut
123 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
124 glEnable(GL_DEPTH_TEST); // activer le ztest
125
126 return 0; // ras, pas d'erreur
127}
128
129int draw( )
130{
131 // etape 2 : dessiner l'objet avec opengl
132
133 // on commence par effacer la fenetre avant de dessiner quelquechose
134 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
135 // on efface aussi le zbuffer
136
137 // recupere les mouvements de la souris, utilise directement SDL2
138 int mx, my;
139 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
140
141 // deplace la camera
142 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
143 // tourne autour de l'objet
144 orbiter_rotation(camera, mx, my);
145
146 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
147 // approche / eloigne l'objet
148 orbiter_move(camera, mx);
149
150 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
151 // deplace le point de rotation
152 orbiter_translation(camera, (float) mx / (float) window_width(), (float) my / (float) window_height());
153
154 float time= SDL_GetTicks();
155 for(unsigned int i= 0; i < scene.size(); i++)
156 {
157 // mouvement global
158 float x= cosf(time / 100 + (float) i / (float) scene.size() - 0.5 ) * 0.5;
159 //~ float y= cosf( time / 100 * M_PI / 2 );
160 float y= 0;
161 float z= sinf(time / 1000 + (float) i / (float) scene.size() - 0.5) * 0.25;
162 //~ Transform model= scene[i]->model * make_translation( make_vector(x, y, z) );
163
164 //~ Transform model= scene[i]->model;
165 //~ Transform model= model_transform(scene[i]);
166
167 // mouvement local
168 Transform local= make_translation( make_vector(0,
169 cosf(time / (100 - (float) i / (float) scene.size() * 80) // change de frequence
170 + (float) i / (float) scene.size() * M_PI / 2) * 0.25, 0) ); // change de phase
171
172 // transformation complete
173 Transform model= model_transform(scene[i], local);// * make_translation( make_vector(x, y, z) );
174
175 //~ printf("draw %d, texture %u\n", i, scene[i]->texture);
176 draw(*scene[i]->mesh,
177 model,
178 orbiter_view_transform(camera),
179 orbiter_projection_transform(camera, window_width(), window_height(), 45),
180 scene[i]->texture);
181 }
182
183 return 1;
184}
185
186int quit( )
187{
188
189 return 0; // ras, pas d'erreur
190}
191
192
193int main( int argc, char **argv )
194{
195 // etape 1 : creer la fenetre
196 Window window= create_window(1024, 640);
197 if(window == NULL)
198 return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
199
200 // etape 2 : creer un contexte opengl pour pouvoir dessiner
201 Context context= create_context(window);
202 if(context == NULL)
203 return 1; // erreur lors de la creation du contexte opengl
204
205 // etape 3 : creation des objets
206 if(init() < 0)
207 {
208 printf("[error] init failed.\n");
209 return 1;
210 }
211
212 // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
213 run(window, draw);
214
215 // etape 5 : nettoyage
216 quit();
217 release_context(context);
218 release_window(window);
219 return 0;
220}
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
Context create_context(Window window)
cree et configure un contexte opengl
Definition window.cpp:344
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
void release_window(Window window)
destruction de la fenetre.
Definition window.cpp:314
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
Definition window.cpp:145
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
Window create_window(const int w, const int h, const int major, const int minor, const int samples)
creation d'une fenetre pour l'application.
Definition window.cpp:249
void release_context(Context context)
detruit le contexte openGL.
Definition window.cpp:404
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
GLuint read_texture(const int unit, const char *filename, const GLenum texel_type)
Definition texture.cpp:133
int init(std::vector< const char * > &options)
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
representation d'un vecteur 3d.
Definition vec.h:67