gKit2 light
Loading...
Searching...
No Matches
tuto4GL_normals.cpp
Go to the documentation of this file.
1
6
7#include "window.h"
8#include "vec.h"
9#include "mat.h"
10
11#include "program.h"
12#include "uniforms.h"
13
14#include "orbiter.h"
15#include "mesh.h"
16#include "wavefront.h"
17
18#include <stdio.h>
19
20// shader program
21GLuint program;
22
23// vertex array object
24GLuint vao;
25GLuint vertex_buffer;
26GLuint normal_buffer;
27unsigned int vertex_count;
28
29// camera
30Orbiter camera;
31
32
33int init( )
34{
35 // compile un shader program
36 program= read_program("gkit2_tutos/tuto4GL_normals.glsl");
37 program_print_errors(program);
38
39 // charge un objet
40 Mesh mesh= read_mesh("data/bigguy.obj");
41 vertex_count= mesh.vertex_count();
42
43 // camera
44 Point pmin, pmax;
45 mesh.bounds(pmin, pmax);
46
47 camera.lookat(pmin, pmax);
48
49 glGenBuffers(1, &vertex_buffer);
50 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
51
52 // dimensionne le buffer actif sur array_buffer, l'alloue et l'initialise avec les positions des sommets de l'objet
53 glBufferData(GL_ARRAY_BUFFER,
54 /* length */ mesh.vertex_buffer_size(),
55 /* data */ mesh.vertex_buffer(),
56 /* usage */ GL_STATIC_DRAW);
57 // GL_STATIC_DRAW decrit l'utilisation du contenu du buffer. dans ce cas, utilisation par draw, sans modifications
58
59 // on recommence avec les normales
60 glGenBuffers(1, &normal_buffer);
61 glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
62 glBufferData(GL_ARRAY_BUFFER, mesh.normal_buffer_size(), mesh.normal_buffer(), GL_STATIC_DRAW);
63
64/* attention: c'est normal_buffer qui est selectionne maintenant sur array_buffer, plus vertex_buffer...
65 */
66
67 // creation d'un vertex array object
68 glGenVertexArrays(1, &vao);
69 glBindVertexArray(vao);
70
71 // recuperer l'identifiant de l'attribut : cf in vec3 position; dans le vertex shader
72 GLint attribute= glGetAttribLocation(program, "position");
73 if(attribute < 0)
74 return -1;
75
76 // re-selectionne vertex buffer pour configurer les positions
77 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
78 // format et organisation des donnees dans le vertex buffer selectionne sur array_buffer,
79 glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0);
80 glEnableVertexAttribArray(attribute);
81
82 // on recommence pour les normales
83 attribute= glGetAttribLocation(program, "normal");
84 if(attribute < 0)
85 return -1;
86
87 // re-selectionne normal_buffer pour configurer les normales
88 glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
89 glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0); // in vec3 normal;
90 glEnableVertexAttribArray(attribute);
91
92
93/* creer 2 buffers pour ranger les positions et les normales est arbitraire, on peut tres bien ne creer qu'un seul buffer,
94 par contre, la description du format / de l'organisation sera differente...
95 ce sont les parametres stride et offset de glVertexAttribPointer() qui permettent d'organiser les donnees librement,
96 ils permettent d'iterer sur les donnees, offset definit le premier element et stride permet de passer au suivant.
97
98 exemple 1: un seul buffer, toutes les positions, puis toutes les normales
99
100 PPPPPPPPNNNNNNNN
101
102 offset(position)= 0;
103 stride(position)= 0; // par definition stride(position) == sizeof(vec3)
104
105 offset(normal)= sizeof(vec3) * size(positions);
106 stride(normal)= 0; // ou sizeof(vec3)
107
108 exemple 2: un seul buffer, alterner les donnees, position + normale sommet 0, position + normale sommet 1, etc.
109
110 PNPNPNPNPNPNPN
111
112 offset(position)= 0;
113 stride(position)= sizeof(vec3) + sizeof(vec3); // la prochaine position se trouve apres la normale du sommet
114
115 offset(normal)= sizeof(vec3); // la premiere normale se trouve apres la premiere position
116 stride(normal)= sizeof(vec3) + sizeof(vec3);
117
118 exemple 3: et pour normale suivie de position ?
119
120 NPNPNPNPNPNPNPNP
121
122 */
123
124 // nettoyage
125 glBindVertexArray(0);
126 glBindBuffer(GL_ARRAY_BUFFER, 0);
127
128 // etat par defaut openGL
129 glClearColor(0.2f, 0.2f, 0.2f, 1);
130 glClearDepthf(1);
131
132 glDepthFunc(GL_LESS);
133 glEnable(GL_DEPTH_TEST);
134
135 glEnable(GL_CULL_FACE);
136 // glViewport(0, 0, window_width(), window_height()) // deja fait dans run( )
137 return 0;
138}
139
140int quit( )
141{
142 release_program(program);
143 glDeleteBuffers(1, &vertex_buffer);
144 glDeleteVertexArrays(1, &vao);
145 return 0;
146}
147
148int draw( )
149{
150 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
151
152 // todo recuperez les mouvements de la souris pour deplacer la camera, cf gkit2_tutos/tuto6.cpp
153 // recupere les mouvements de la souris, utilise directement SDL2
154 int mx, my;
155 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
156
157 // deplace la camera
158 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
159 // tourne autour de l'objet
160 camera.rotation(mx, my);
161
162 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
163 // approche / eloigne l'objet
164 camera.move(mx);
165
166 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
167 // deplace le point de rotation
168 camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
169
170
171/* configuration minimale du pipeline
172 vertex array
173 shader program
174 uniforms du shader program
175 */
176 glBindVertexArray(vao);
177
178 glUseProgram(program);
179
180 // recupere le point de vue et la projection de la camera
181 Transform model= Identity();
182 Transform view= camera.view();
183 Transform projection= camera.projection(window_width(), window_height(), 45);
184
185 // compose les matrices pour passer du repere local de l'objet au repere projectif
186 Transform mvp= projection * view * model;
187 Transform mv= view * model;
188
189 GLuint location;
190 location= glGetUniformLocation(program, "mvpMatrix");
191 glUniformMatrix4fv(location, 1, GL_TRUE, mvp.data());
192
193 // les normales ne subissent pas tout a fait la meme transformation que les sommets
194 program_uniform(program, "mvMatrix", mv.normal());
195
196 program_uniform(program, "color", vec3(1, 0.5, 0.));
197
198 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
199
200 // nettoyage
201 glUseProgram(0);
202 glBindVertexArray(0);
203 return 1;
204}
205
206
207int main( int argc, char **argv )
208{
209 // etape 1 : creer la fenetre
210 Window window= create_window(1024, 640);
211 if(window == NULL)
212 return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
213
214 // etape 2 : creer un contexte opengl pour pouvoir dessiner
215 Context context= create_context(window);
216 if(context == NULL)
217 return 1; // erreur lors de la creation du contexte opengl
218
219 // etape 3 : creation des objets
220 if(init() < 0)
221 {
222 printf("[error] init failed.\n");
223 return 1;
224 }
225
226 // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
227 run(window, draw);
228
229 // etape 5 : nettoyage
230 quit();
231 release_context(context);
232 release_window(window);
233 return 0;
234}
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:358
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:328
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
Definition window.cpp:158
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)
creation d'une fenetre pour l'application.
Definition window.cpp:262
void release_context(Context context)
detruit le contexte openGL.
Definition window.cpp:439
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
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:217
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
Definition program.cpp:461
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:240
int init(std::vector< const char * > &options)
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
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition mat.cpp:181
const float * data() const
renvoie l'adresse de la premiere valeur de la matrice.
Definition mat.h:75
vecteur generique, utilitaire.
Definition vec.h:169