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