gKit2 light
tuto_raytrace_fragment.cpp
Go to the documentation of this file.
1 
3 
4 #include <cfloat>
5 #include <cmath>
6 #include <algorithm>
7 
8 #include "app_time.h"
9 
10 #include "vec.h"
11 #include "color.h"
12 #include "mat.h"
13 
14 #include "mesh.h"
15 #include "wavefront.h"
16 
17 #include "program.h"
18 #include "uniforms.h"
19 
20 #include "orbiter.h"
21 
22 
23 // cf tuto_storage
24 namespace glsl
25 {
26  template < typename T >
27  struct alignas(8) gvec2
28  {
29  alignas(4) T x, y;
30 
31  gvec2( ) {}
32  gvec2( const vec2& v ) : x(v.x), y(v.y) {}
33  };
34 
35  typedef gvec2<float> vec2;
36  typedef gvec2<int> ivec2;
37  typedef gvec2<unsigned int> uvec2;
38  typedef gvec2<int> bvec2;
39 
40  template < typename T >
41  struct alignas(16) gvec3
42  {
43  alignas(4) T x, y, z;
44 
45  gvec3( ) {}
46  gvec3( const vec3& v ) : x(v.x), y(v.y), z(v.z) {}
47  gvec3( const Point& v ) : x(v.x), y(v.y), z(v.z) {}
48  gvec3( const Vector& v ) : x(v.x), y(v.y), z(v.z) {}
49  };
50 
51  typedef gvec3<float> vec3;
52  typedef gvec3<int> ivec3;
53  typedef gvec3<unsigned int> uvec3;
54  typedef gvec3<int> bvec3;
55 
56  template < typename T >
57  struct alignas(16) gvec4
58  {
59  alignas(4) T x, y, z, w;
60 
61  gvec4( ) {}
62  gvec4( const vec4& v ) : x(v.x), y(v.y), z(v.z), w(v.w) {}
63  };
64 
65  typedef gvec4<float> vec4;
66  typedef gvec4<int> ivec4;
67  typedef gvec4<unsigned int> uvec4;
68  typedef gvec4<int> bvec4;
69 }
70 
71 
72 struct RT : public AppTime
73 {
74  // constructeur : donner les dimensions de l'image, et eventuellement la version d'openGL.
75  RT( const char *filename ) : AppTime(1024, 640)
76  {
77  m_mesh= read_mesh(filename);
78  }
79 
80  int init( )
81  {
82  if(m_mesh == Mesh::error())
83  return -1;
84 
85  Point pmin, pmax;
86  m_mesh.bounds(pmin, pmax);
87  m_camera.lookat(pmin, pmax);
88 
89  glGenVertexArrays(1, &m_vao);
90  glBindVertexArray(m_vao);
91 
92  glGenBuffers(1, &m_buffer);
93  glBindBuffer(GL_UNIFORM_BUFFER, m_buffer);
94 
95  //
96  struct triangle
97  {
98  glsl::vec3 a;
99  glsl::vec3 ab;
100  glsl::vec3 ac;
101  };
102 
103  std::vector<triangle> data;
104  data.reserve(m_mesh.triangle_count());
105  for(int i= 0; i < m_mesh.triangle_count(); i++)
106  {
107  TriangleData t= m_mesh.triangle(i);
108  data.push_back( { Point(t.a), Point(t.b) - Point(t.a), Point(t.c) - Point(t.a) } );
109  }
110 
111  // alloue le buffer
112  // alloue au moins 1024 triangles, cf le shader
113  if(data.size() < 1024)
114  data.resize(1024);
115  glBufferData(GL_UNIFORM_BUFFER, data.size() * sizeof(triangle), data.data(), GL_STATIC_READ);
116 
117  //
118  m_program= read_program("tutos/M2/raytrace.glsl");
119  program_print_errors(m_program);
120 
121  // associe l'uniform buffer a l'entree 0
122  GLint index= glGetUniformBlockIndex(m_program, "triangleData");
123  glUniformBlockBinding(m_program, index, 0);
124 
125  return 0;
126  }
127 
128  int quit( )
129  {
130  return 0;
131  }
132 
133  int render( )
134  {
135  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
136 
137  if(key_state('f'))
138  {
139  clear_key_state('f');
140  Point pmin, pmax;
141  m_mesh.bounds(pmin, pmax);
142  m_camera.lookat(pmin, pmax);
143  }
144 
145  // deplace la camera
146  int mx, my;
147  unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
148  if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
149  m_camera.rotation(mx, my);
150  else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
151  m_camera.move(mx);
152  else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
153  m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
154 
155  Transform m;
156  Transform v= m_camera.view();
157  Transform p= m_camera.projection(window_width(), window_height(), 45);
158  Transform mvp= p * v * m;
159 
160  // config pipeline
161  glBindVertexArray(m_vao);
162  glUseProgram(m_program);
163 
164  // uniform buffer 0
165  glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer);
166  program_uniform(m_program, "triangle_count", std::min((int) m_mesh.triangle_count(), 1024) );
167 
168  program_uniform(m_program, "mvpInvMatrix", mvp.inverse());
169  glDrawArrays(GL_TRIANGLES, 0, 3);
170 
171  return 1;
172  }
173 
174 protected:
175  Mesh m_mesh;
176  Orbiter m_camera;
177 
178  GLuint m_program;
179  GLuint m_vao;
180  GLuint m_buffer;
181 };
182 
183 
184 int main( int argc, char **argv )
185 {
186  const char *filename= "data/cornell.obj";
187  if(argc > 1)
188  filename= argv[1];
189 
190  RT app(filename);
191  app.run();
192 
193  return 0;
194 }
representation d'un objet / maillage.
Definition: mesh.h:112
static Mesh & error()
Definition: mesh.h:348
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
Mesh & triangle(const unsigned int a, const unsigned int b, const unsigned int c)
Definition: mesh.cpp:192
int triangle_count() const
renvoie le nombre de triangles.
Definition: mesh.cpp:435
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
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:29
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition: window.cpp:48
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition: window.cpp:42
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:25
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
Definition: vec.cpp:30
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
representation d'un point 3d.
Definition: vec.h:21
int init()
a deriver pour creer les objets openGL.
int render()
a deriver pour afficher les objets.
int quit()
a deriver pour detruire les objets openGL.
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:21
Transform inverse() const
renvoie l'inverse de la matrice.
Definition: mat.cpp:399
representation d'un triangle.
Definition: mesh.h:95
vec3 c
positions
Definition: mesh.h:96
representation d'un vecteur 3d.
Definition: vec.h:59
vecteur generique, utilitaire.
Definition: vec.h:131
vecteur generique, utilitaire.
Definition: vec.h:146
vecteur generique 4d, ou 3d homogene, utilitaire.
Definition: vec.h:168