gKit2 light
tuto5GL_multi.cpp
Go to the documentation of this file.
1 
3 
4 #include "window.h"
5 #include "vec.h"
6 #include "mat.h"
7 
8 #include "program.h"
9 #include "uniforms.h"
10 
11 #include "mesh.h"
12 #include "wavefront.h"
13 
14 #include "orbiter.h"
15 #include "texture.h"
16 
17 #include <stdio.h>
18 
19 
20 GLuint program;
21 
22 GLuint base_texture;
23 GLuint detail_texture;
24 GLuint sampler;
25 
26 GLuint vao;
27 GLuint vertex_buffer;
28 GLuint texcoord_buffer;
29 int vertex_count;
30 
31 Orbiter camera;
32 
33 
34 int init( )
35 {
36  // etape 1 : shaders
37  program= read_program("tutos/tuto5GL_multi.glsl");
38  program_print_errors(program);
39 
40  // etape 2 : charger un mesh, (avec des texcoords), vao + vertex buffer
41  Mesh mesh= read_mesh("data/cube.obj");
42  if(mesh.vertex_count() == 0)
43  return -1; // gros probleme, pas de sommets...
44 
45  vertex_count= mesh.vertex_count();
46 
47  Point pmin, pmax;
48  mesh.bounds(pmin, pmax);
49  camera.lookat(pmin, pmax);
50 
51  // vertex format : position + texcoord,
52  // cf tuto4GL_normals.cpp
53  glGenVertexArrays(1, &vao);
54  glBindVertexArray(vao);
55 
56  // vertex buffer
57  glGenBuffers(1, &vertex_buffer);
58  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
59  glBufferData(GL_ARRAY_BUFFER, mesh.vertex_buffer_size(), mesh.vertex_buffer(), GL_STATIC_DRAW);
60 
61  // configurer l'attribut position
62  GLint position= glGetAttribLocation(program, "position");
63  if(position < 0)
64  return -1;
65  glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);
66  glEnableVertexAttribArray(position);
67 
68  // texcoord buffer
69  glGenBuffers(1, &texcoord_buffer);
70  glBindBuffer(GL_ARRAY_BUFFER, texcoord_buffer);
71  glBufferData(GL_ARRAY_BUFFER, mesh.texcoord_buffer_size(), mesh.texcoord_buffer(), GL_STATIC_DRAW);
72 
73  // configurer l'attribut texcoord
74  GLint texcoord= glGetAttribLocation(program, "texcoord");
75  if(texcoord < 0)
76  return -1;
77  glVertexAttribPointer(texcoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
78  glEnableVertexAttribArray(texcoord);
79 
80  // nettoyage
81  mesh.release();
82  glBindVertexArray(0);
83  glBindBuffer(GL_ARRAY_BUFFER, 0);
84 
85  // etape 3 : sampler, parametres de filtrage des textures
86  glGenSamplers(1, &sampler);
87 
88  glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
89  glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90  glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
91  glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
92 
93  // etape 4 : creation des textures
94  /* utilise les utilitaires de texture.h
95  */
96  base_texture= read_texture(0, "data/font.png"); // texture 'base'
97  detail_texture= read_texture(0, "data/debug2x2red.png"); // texture 'detail'
98 
99  // nettoyage
100  glBindTexture(GL_TEXTURE_2D, 0);
101  glUseProgram(0);
102 
103  // etat par defaut
104  glClearColor(0.2f, 0.2f, 0.2f, 1);
105  glClearDepthf(1);
106 
107  glDepthFunc(GL_LESS);
108  glEnable(GL_DEPTH_TEST);
109 
110  glFrontFace(GL_CCW);
111  glCullFace(GL_BACK);
112  glEnable(GL_CULL_FACE);
113  return 0;
114 }
115 
116 int quit( )
117 {
118  release_program(program);
119  glDeleteVertexArrays(1, &vao);
120  glDeleteBuffers(1, &vertex_buffer);
121  glDeleteBuffers(1, &texcoord_buffer);
122  glDeleteSamplers(1, &sampler);
123  glDeleteTextures(1, &base_texture);
124  glDeleteTextures(1, &detail_texture);
125  return 0;
126 }
127 
128 int draw( )
129 {
130  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
131 
132  // recupere les mouvements de la souris, utilise directement SDL2
133  int mx, my;
134  unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
135 
136  // deplace la camera
137  if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
138  // tourne autour de l'objet
139  camera.rotation(mx, my);
140 
141  else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
142  // approche / eloigne l'objet
143  camera.move(mx);
144 
145  else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
146  // deplace le point de rotation
147  camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
148 
149 
150  /* config pipeline
151  vertex array object
152  program
153  uniforms
154  sampler
155  texture
156  */
157 
158  glBindVertexArray(vao);
159  glUseProgram(program);
160 
161  // recupere le point de vue et la projection de la camera
162  Transform model= Identity();
163  Transform view= camera.view();
164  Transform projection= camera.projection(window_width(), window_height(), 45);
165 
166  // compose les matrices pour passer du repere local de l'objet au repere projectif
167  Transform mvp= projection * view * model;
168  program_uniform(program, "mvpMatrix", mvp);
169 
170  // texture et parametres de filtrage de la texture
171  glActiveTexture(GL_TEXTURE0);
172  glBindTexture(GL_TEXTURE_2D, base_texture);
173  glBindSampler(0, sampler);
174 
175  glActiveTexture(GL_TEXTURE0 +1);
176  glBindTexture(GL_TEXTURE_2D, detail_texture);
177  glBindSampler(1, sampler);
178 
179  // uniform sampler2D declares par le fragment shader
180  GLint location;
181  location= glGetUniformLocation(program, "base_texture");
182  glUniform1i(location, 0);
183 
184  location= glGetUniformLocation(program, "detail_texture");
185  glUniform1i(location, 1);
186 
187  /* ou plus court, utilise les utilitaires de uniforms.h, pour configurer a la fois le pipeline
188  (unite de texture + sampler) et l'uniform du fragment shader
189 
190  #include "uniforms.h"
191 
192  program_use_texture(program, "base_texture", base_texture, sampler);
193  program_use_texture(program, "detail_texture", detail_texture, sampler);
194  */
195 
196  glDrawArrays(GL_TRIANGLES, 0, vertex_count);
197 
198  // nettoyage
199  glBindTexture(GL_TEXTURE_2D, 0);
200  glBindSampler(0, 0);
201  glUseProgram(0);
202  glBindVertexArray(0);
203 
204  return 1;
205 }
206 
207 
208 int main( int argc, char **argv )
209 {
210  // etape 1 : creer la fenetre
211  Window window= create_window(1024, 640);
212  if(window == NULL)
213  return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
214 
215  // etape 2 : creer un contexte opengl pour pouvoir dessiner
216  Context context= create_context(window);
217  if(context == NULL)
218  return 1; // erreur lors de la creation du contexte opengl
219 
220  // etape 3 : creation des objets
221  if(init() < 0)
222  {
223  printf("[error] init failed.\n");
224  return 1;
225  }
226 
227  // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
228  run(window, draw);
229 
230  // etape 5 : nettoyage
231  quit();
232  release_context(context);
233  release_window(window);
234  return 0;
235 }
representation d'un objet / maillage.
Definition: mesh.h:112
std::size_t texcoord_buffer_size() const
renvoie la taille (en octets) du texcoord buffer.
Definition: mesh.h:308
const float * vertex_buffer() const
renvoie l'adresse de la position du premier sommet. permet de construire les vertex buffers openGL....
Definition: mesh.h:296
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Definition: mesh.cpp:503
std::size_t vertex_buffer_size() const
renvoie la longueur (en octets) du vertex buffer.
Definition: mesh.h:298
const float * texcoord_buffer() const
renvoie l'adresse des coordonnees de textures du premier sommet. par convention, c'est un vec2,...
Definition: mesh.h:306
int vertex_count() const
renvoie le nombre de sommets.
Definition: mesh.h:291
void release()
detruit les objets openGL.
Definition: mesh.cpp:64
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition: orbiter.h:17
void lookat(const Point &center, const float size)
observe le point center a une distance size.
Definition: orbiter.cpp:7
void move(const float z)
rapproche / eloigne la camera du centre.
Definition: orbiter.cpp:33
Transform projection(const int width, const int height, const float fov)
fixe la projection reglee pour une image d'aspect width / height, et une demi ouverture de fov degres...
Definition: orbiter.cpp:47
void translation(const float x, const float y)
deplace le centre / le point observe.
Definition: orbiter.cpp:27
void rotation(const float x, const float y)
change le point de vue / la direction d'observation.
Definition: orbiter.cpp:21
Transform view() const
renvoie la transformation vue.
Definition: orbiter.cpp:40
Context create_context(Window window)
cree et configure un contexte opengl
Definition: window.cpp:356
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:29
void release_window(Window window)
destruction de la fenetre.
Definition: window.cpp:325
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:259
void release_context(Context context)
detruit le contexte openGL.
Definition: window.cpp:422
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:25
Transform Identity()
construit la transformation identite.
Definition: mat.cpp:187
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_program(const char *filename, const char *definitions)
Definition: program.cpp:204
void program_uniform(const GLuint program, const char *uniform, const std::vector< unsigned > &v)
affecte un tableau de valeurs a un uniform du shader program.
Definition: uniforms.cpp:94
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:432
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211
GLuint read_texture(const int unit, const char *filename, const GLenum texel_type)
Definition: texture.cpp:148
int init(std::vector< const char * > &options)
Definition: shader_kit.cpp:96
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
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
Definition: window.cpp:147