gKit2 light
tuto5GL_samplers.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 "image_io.h"
16 
17 #include <stdio.h>
18 
19 
20 GLuint program;
21 
22 GLuint texture;
23 GLuint sampler;
24 GLuint sampler_linear;
25 GLuint sampler_aniso;
26 
27 GLuint vao;
28 GLuint vertex_buffer;
29 GLuint texcoord_buffer;
30 unsigned int vertex_count;
31 
32 Orbiter camera;
33 
34 
35 int init( )
36 {
37  // etape 1 : shaders
38  program= read_program("tutos/tuto5GL.glsl");
39  program_print_errors(program);
40 
41  // etape 2 : charger un mesh, (avec des texcoords), vao + vertex buffer
42  Mesh mesh= read_mesh("data/cube.obj");
43  if(mesh.vertex_count() == 0)
44  return -1; // gros probleme, pas de sommets...
45 
46  vertex_count= mesh.vertex_count();
47 
48  camera.lookat(Point(0, 0, 0), 5);
49 
50  // vertex format : position + texcoord,
51  // cf tuto4GL_normals.cpp
52  glGenVertexArrays(1, &vao);
53  glBindVertexArray(vao);
54 
55  // vertex buffer
56  glGenBuffers(1, &vertex_buffer);
57  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
58  glBufferData(GL_ARRAY_BUFFER, mesh.vertex_buffer_size(), mesh.vertex_buffer(), GL_STATIC_DRAW);
59 
60  // configurer l'attribut position
61  GLint position= glGetAttribLocation(program, "position");
62  if(position < 0)
63  return -1;
64  glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);
65  glEnableVertexAttribArray(position);
66 
67  // texcoord buffer
68  glGenBuffers(1, &texcoord_buffer);
69  glBindBuffer(GL_ARRAY_BUFFER, texcoord_buffer);
70  glBufferData(GL_ARRAY_BUFFER, mesh.texcoord_buffer_size(), mesh.texcoord_buffer(), GL_STATIC_DRAW);
71 
72  // configurer l'attribut texcoord
73  GLint texcoord= glGetAttribLocation(program, "texcoord");
74  if(texcoord < 0)
75  return -1;
76  glVertexAttribPointer(texcoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
77  glEnableVertexAttribArray(texcoord);
78 
79  // nettoyage
80  mesh.release();
81  glBindVertexArray(0);
82  glBindBuffer(GL_ARRAY_BUFFER, 0);
83 
84  // etape 3 : sampler
85  glGenSamplers(1, &sampler);
86 
87  glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
88  glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
89  glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
90  glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
91 
92 #if 1
93  glGenSamplers(1, &sampler_linear);
94 
95  glSamplerParameteri(sampler_linear, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
96  glSamplerParameteri(sampler_linear, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
97  glSamplerParameteri(sampler_linear, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
98  glSamplerParameteri(sampler_linear, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
99 
100  glGenSamplers(1, &sampler_aniso);
101 
102  glSamplerParameteri(sampler_aniso, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
103  glSamplerParameteri(sampler_aniso, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
104  glSamplerParameteri(sampler_aniso, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
105  glSamplerParameteri(sampler_aniso, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
106  glSamplerParameterf(sampler_aniso, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
107 #endif
108 
109  // etape 4 : texture
110  ImageData image= read_image_data("data/debug2x2red.png");
111 
112  GLenum data_format= GL_RGBA;
113  GLenum data_type= GL_UNSIGNED_BYTE;
114  if(image.channels == 3)
115  data_format= GL_RGB;
116 
117  glGenTextures(1, &texture);
118  glBindTexture(GL_TEXTURE_2D, texture);
119 
120  glTexImage2D(GL_TEXTURE_2D, 0,
121  GL_RGBA, image.width, image.height, 0,
122  data_format, data_type, image.data() );
123 
124  glGenerateMipmap(GL_TEXTURE_2D);
125 
126  // nettoyage
127  glBindTexture(GL_TEXTURE_2D, 0);
128  glUseProgram(0);
129 
130  // etat par defaut
131  glClearColor(0.2f, 0.2f, 0.2f, 1);
132  glClearDepthf(1);
133 
134  glDepthFunc(GL_LESS);
135  glEnable(GL_DEPTH_TEST);
136 
137  glFrontFace(GL_CCW);
138  glCullFace(GL_BACK);
139  glEnable(GL_CULL_FACE);
140  return 0;
141 }
142 
143 int quit( )
144 {
145  release_program(program);
146  glDeleteVertexArrays(1, &vao);
147  glDeleteBuffers(1, &vertex_buffer);
148  glDeleteBuffers(1, &texcoord_buffer);
149  glDeleteSamplers(1, &sampler);
150  glDeleteTextures(1, &texture);
151  return 0;
152 }
153 
154 int draw( )
155 {
156  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
157 
158  // recupere les mouvements de la souris, utilise directement SDL2
159  int mx, my;
160  unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
161 
162  // deplace la camera
163  if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
164  // tourne autour de l'objet
165  camera.rotation(mx, my);
166 
167  else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
168  // approche / eloigne l'objet
169  camera.move(mx);
170 
171  else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
172  // deplace le point de rotation
173  camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
174 
175 
176  /* config pipeline
177  vertex array object
178  program
179  uniforms
180  sampler
181  texture
182  */
183 
184  glBindVertexArray(vao);
185  glUseProgram(program);
186 
187  // recupere le point de vue et la projection de la camera
188  Transform model= Identity();
189  Transform view= camera.view();
190  Transform projection= camera.projection(window_width(), window_height(), 45);
191 
192  // compose les matrices pour passer du repere local de l'objet au repere projectif
193  Transform mvp= projection * view * model;
194  program_uniform(program, "mvpMatrix", mvp);
195 
196  // texture et parametres d'acces a la texture
197  glBindSampler(0, sampler);
198  glBindTexture(GL_TEXTURE_2D, texture);
199 
200  // sampler2D déclare par le fragment shader
201  GLint location= glGetUniformLocation(program, "texture0");
202  glUniform1i(location, 0);
203  // ou program_uniform(program, "texture0", 0);
204 
205  glDrawArrays(GL_TRIANGLES, 0, vertex_count);
206 
207 #if 1
208  for(int i= 0; i <4; i++)
209  {
210  Transform model= Translation( -1.5, 0, - i*1.5 );
211  Transform view= camera.view();
212  Transform projection= camera.projection(window_width(), window_height(), 45);
213 
214  // compose les matrices pour passer du repere local de l'objet au repere projectif
215  Transform mvp= projection * view * model;
216  program_uniform(program, "mvpMatrix", mvp);
217 
218  glBindSampler(0, sampler_linear);
219  glBindTexture(GL_TEXTURE_2D, texture);
220 
221  GLint location= glGetUniformLocation(program, "texture0");
222  glUniform1i(location, 0);
223 
224  glDrawArrays(GL_TRIANGLES, 0, vertex_count);
225  }
226 
227  for(int i= 0; i <4; i++)
228  {
229  Transform model= Translation( 1.5, 0, - i*1.5 );
230  Transform view= camera.view();
231  Transform projection= camera.projection(window_width(), window_height(), 45);
232 
233  // compose les matrices pour passer du repere local de l'objet au repere projectif
234  Transform mvp= projection * view * model;
235  program_uniform(program, "mvpMatrix", mvp);
236 
237  glBindSampler(0, sampler_aniso);
238  glBindTexture(GL_TEXTURE_2D, texture);
239 
240  GLint location= glGetUniformLocation(program, "texture0");
241  glUniform1i(location, 0);
242 
243  glDrawArrays(GL_TRIANGLES, 0, vertex_count);
244  }
245 #endif
246 
247  // nettoyage
248  glBindTexture(GL_TEXTURE_2D, 0);
249  glBindSampler(0, 0);
250  glUseProgram(0);
251  glBindVertexArray(0);
252 
253  return 1;
254 }
255 
256 
257 int main( int argc, char **argv )
258 {
259  // etape 1 : creer la fenetre
260  Window window= create_window(1024, 640);
261  if(window == NULL)
262  return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
263 
264  // etape 2 : creer un contexte opengl pour pouvoir dessiner
265  Context context= create_context(window);
266  if(context == NULL)
267  return 1; // erreur lors de la creation du contexte opengl
268 
269  // etape 3 : creation des objets
270  if(init() < 0)
271  {
272  printf("[error] init failed.\n");
273  return 1;
274  }
275 
276  // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
277  run(window, draw);
278 
279  // etape 5 : nettoyage
280  quit();
281  release_context(context);
282  release_window(window);
283  return 0;
284 }
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
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
ImageData read_image_data(const char *filename)
charge les donnees d'un fichier png. renvoie une image initialisee par defaut en cas d'echec.
Definition: image_io.cpp:216
Transform Identity()
construit la transformation identite.
Definition: mat.cpp:187
Transform Translation(const Vector &v)
renvoie la matrice representant une translation par un vecteur.
Definition: mat.cpp:216
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
int init(std::vector< const char * > &options)
Definition: shader_kit.cpp:96
stockage temporaire des donnees d'une image.
Definition: image_io.h:38
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