gKit2 light
Public Member Functions | Public Attributes | List of all members
Histogram Struct Reference
+ Inheritance diagram for Histogram:

Public Member Functions

 Histogram (const char *filename)
 
int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application. More...
 
 Histogram (const char *filename)
 
int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application. More...
 
 Histogram (const char *filename)
 
int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon. More...
 
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application. More...
 
- Public Member Functions inherited from App
 App (const int width, const int height, const int major=3, const int minor=3, const int samples=0)
 constructeur, dimensions de la fenetre et version d'openGL. More...
 
virtual int update (const float time, const float delta)
 a deriver et redefinir pour animer les objets en fonction du temps. More...
 
int run ()
 execution de l'application. More...
 

Public Attributes

ImageData m_image
 
GLuint m_program
 
GLuint m_time_query
 
GLuint m_histogram
 
GLuint m_texture
 
GLint m_threads [3]
 

Additional Inherited Members

- Protected Member Functions inherited from App
virtual int prerender ()
 
virtual int postrender ()
 
void vsync_off ()
 
- Protected Attributes inherited from App
Window m_window
 
Context m_context
 
bool sync
 

Detailed Description

Definition at line 13 of file tuto_histogram1_compute.cpp.

Member Function Documentation

◆ init() [1/3]

int Histogram::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 20 of file tuto_histogram1_compute.cpp.

21  {
22  if(m_image.pixels.size() == 0)
23  // pas d'image
24  return -1;
25 
26  // cree la texture pour stocker l'image
27  GLenum data_type= GL_UNSIGNED_BYTE;
28  GLenum data_format= GL_RGBA;
29  if(m_image.channels == 1)
30  data_format= GL_RED;
31  else if(m_image.channels == 2)
32  data_format= GL_RG;
33  else if(m_image.channels == 3)
34  data_format= GL_RGB;
35  //~ else
36  //~ data_format= GL_RGBA;
37 
38  glGenTextures(1, &m_texture);
39  glBindTexture(GL_TEXTURE_2D, m_texture);
40  glTexImage2D(GL_TEXTURE_2D, 0,
41  GL_RGBA8, m_image.width, m_image.height, 0,
42  data_format, data_type, m_image.data());
43 
44  // pas la peine de construire les mipmaps, le shader ne va ecrire que le mipmap 0
45  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
46 
47  // cree le buffer pour stocker l'histogramme
48  glGenBuffers(1, &m_histogram);
49  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_histogram);
50  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * 16, nullptr, GL_STATIC_COPY);
51 
52  m_program= read_program("tutos/M2/histogram1.glsl");
53  program_print_errors(m_program);
54 
55  glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, m_threads);
56 
57  // mesure temps gpu
58  glGenQueries(1, &m_time_query);
59 
60  // histogramme cpu pour comparer...
61  {
62  auto start= std::chrono::high_resolution_clock::now();
63 
64  int histogram[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
65  for(int y= 0; y < m_image.height; y++)
66  for(int x= 0; x < m_image.width; x++)
67  {
68  size_t offset= m_image.offset(x, y);
69  int r= m_image.pixels[offset];
70  int g= m_image.pixels[offset+1];
71  int b= m_image.pixels[offset+2];
72  int bin= 15 * (r+g+b) / (255*3);
73  histogram[bin]++;
74  }
75 
76  auto stop= std::chrono::high_resolution_clock::now();
77  int cpu_time= std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
78 
79  for(int i= 0; i < 16; i++)
80  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
81 
82  printf("cpu %dus\n", cpu_time);
83  }
84 
85  return 1;
86  }
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
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:204
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:432

◆ quit() [1/3]

int Histogram::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 88 of file tuto_histogram1_compute.cpp.

89  {
90  release_program(m_program);
91  glDeleteBuffers(1, &m_histogram);
92  glDeleteTextures(1, &m_texture);
93  glDeleteQueries(1, &m_time_query);
94  return 0;
95  }
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211

◆ render() [1/3]

int Histogram::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 97 of file tuto_histogram1_compute.cpp.

98  {
99  glViewport(0, 0, window_width(), window_height());
100  glClear(GL_COLOR_BUFFER_BIT);
101 
102  glUseProgram(m_program);
103 
104  // storage buffer 0
105  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_histogram);
106  // remet a zero l'histogramme
107  glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
108 
109  // image texture 0, ecriture seule, mipmap 0 + format rgba8 classique
110  glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
111  // configurer le shader
112  program_uniform(m_program, "image", 0);
113 
114  int nx= m_image.width / m_threads[0];
115  int ny= m_image.height / m_threads[1];
116  // on suppose que les dimensions de l'image sont multiples de 8...
117  // sinon calculer correctement le nombre de groupes pour x et y.
118 
119  glBeginQuery(GL_TIME_ELAPSED, m_time_query);
120  {
121  // go !!
122  //~ for(int i= 0; i < 100; i++) // eventuellement recommencer plein de fois pour stabiliser les frequences du gpu...
123  glDispatchCompute(nx, ny, 1);
124 
125  // attendre le resultat
126  glMemoryBarrier(GL_ALL_BARRIER_BITS);
127  }
128  glEndQuery(GL_TIME_ELAPSED);
129 
130  // relire le buffer resultat
131  int histogram[16];
132  {
133  // creer un buffer temporaire pour le transfert depuis le buffer resultat
134  GLuint buffer= 0;
135  glGenBuffers(1, &buffer);
136  glBindBuffer(GL_COPY_READ_BUFFER, buffer);
137  glBufferData(GL_COPY_READ_BUFFER, sizeof(int) * 16, nullptr, GL_DYNAMIC_READ);
138 
139  // copie les resultats
140  glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0, sizeof(int) * 16);
141 
142  // recupere les resultats depuis le buffer intermediaire
143  glGetBufferSubData(GL_COPY_READ_BUFFER, 0, sizeof(int) * 16, histogram);
144 
145  // detruit le buffer intermediaire
146  glDeleteBuffers(1, &buffer);
147  }
148 
149  for(int i= 0; i < 16; i++)
150  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
151 
152  printf("\n%dx%d groups, %d threads\n", nx, ny, nx*ny*m_threads[0]*m_threads[1]);
153 
154  // attendre le resultat de la requete
155  GLint64 gpu_time= 0;
156  glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
157  //~ gpu_time/= 100;
158  printf("gpu %02dms %03dus\n\n", int(gpu_time / 1000000), int((gpu_time / 1000) % 1000));
159 
160  return 0; // une seule fois
161  //~ return 1; // recommencer jusqu'a la fermeture de la fenetre...
162  }
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:29
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:25
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

◆ init() [2/3]

int Histogram::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 20 of file tuto_histogram2_compute.cpp.

21  {
22  if(m_image.pixels.size() == 0)
23  // pas d'image
24  return -1;
25 
26  // cree la texture pour stocker l'image
27  GLenum data_type= GL_UNSIGNED_BYTE;
28  GLenum data_format= GL_RGBA;
29  if(m_image.channels == 1)
30  data_format= GL_RED;
31  else if(m_image.channels == 2)
32  data_format= GL_RG;
33  else if(m_image.channels == 3)
34  data_format= GL_RGB;
35  //~ else
36  //~ data_format= GL_RGBA;
37 
38  glGenTextures(1, &m_texture);
39  glBindTexture(GL_TEXTURE_2D, m_texture);
40  glTexImage2D(GL_TEXTURE_2D, 0,
41  GL_RGBA8, m_image.width, m_image.height, 0,
42  data_format, data_type, m_image.data());
43 
44  // pas la peine de construire les mipmaps, le shader ne va ecrire que le mipmap 0
45  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
46 
47  // cree le buffer pour stocker l'histogramme
48  glGenBuffers(1, &m_histogram);
49  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_histogram);
50  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * 16, nullptr, GL_STATIC_COPY);
51 
52  m_program= read_program("tutos/M2/histogram2.glsl");
53  program_print_errors(m_program);
54 
55  glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, m_threads);
56 
57  // mesure temps gpu
58  glGenQueries(1, &m_time_query);
59 
60  // histogramme cpu pour comparer...
61  {
62  auto start= std::chrono::high_resolution_clock::now();
63 
64  int histogram[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
65  for(int y= 0; y < m_image.height; y++)
66  for(int x= 0; x < m_image.width; x++)
67  {
68  size_t offset= m_image.offset(x, y);
69  int r= m_image.pixels[offset];
70  int g= m_image.pixels[offset+1];
71  int b= m_image.pixels[offset+2];
72  int bin= 15 * (r+g+b) / (255*3);
73  histogram[bin]++;
74  }
75 
76  auto stop= std::chrono::high_resolution_clock::now();
77  int cpu_time= std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
78 
79  for(int i= 0; i < 16; i++)
80  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
81 
82  printf("cpu %dus\n", cpu_time);
83  }
84 
85  return 1;
86  }

◆ quit() [2/3]

int Histogram::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 88 of file tuto_histogram2_compute.cpp.

89  {
90  release_program(m_program);
91  glDeleteBuffers(1, &m_histogram);
92  glDeleteTextures(1, &m_texture);
93  glDeleteQueries(1, &m_time_query);
94  return 0;
95  }

◆ render() [2/3]

int Histogram::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 97 of file tuto_histogram2_compute.cpp.

98  {
99  glViewport(0, 0, window_width(), window_height());
100  glClear(GL_COLOR_BUFFER_BIT);
101 
102  glUseProgram(m_program);
103 
104  // storage buffer 0
105  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_histogram);
106  // remet a zero l'histogramme
107  glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
108 
109  // image texture 0, ecriture seule, mipmap 0 + format rgba8 classique
110  glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
111  // configurer le shader
112  program_uniform(m_program, "image", 0);
113 
114  int nx= m_image.width / m_threads[0];
115  int ny= m_image.height / m_threads[1];
116  // on suppose que les dimensions de l'image sont multiples de 8...
117  // sinon calculer correctement le nombre de groupes pour x et y.
118 
119  glBeginQuery(GL_TIME_ELAPSED, m_time_query);
120  {
121  // go !!
122  //~ for(int i= 0; i < 100; i++) // eventuellement recommencer plein de fois pour stabiliser les frequences du gpu...
123  glDispatchCompute(nx, ny, 1);
124 
125  // attendre le resultat
126  glMemoryBarrier(GL_ALL_BARRIER_BITS);
127  }
128  glEndQuery(GL_TIME_ELAPSED);
129 
130  // relire le buffer resultat
131  int histogram[16];
132  {
133  // creer un buffer temporaire pour le transfert depuis le buffer resultat
134  GLuint buffer= 0;
135  glGenBuffers(1, &buffer);
136  glBindBuffer(GL_COPY_READ_BUFFER, buffer);
137  glBufferData(GL_COPY_READ_BUFFER, sizeof(int) * 16, nullptr, GL_DYNAMIC_READ);
138 
139  // copie les resultats
140  glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0, sizeof(int) * 16);
141 
142  // recupere les resultats depuis le buffer intermediaire
143  glGetBufferSubData(GL_COPY_READ_BUFFER, 0, sizeof(int) * 16, histogram);
144 
145  // detruit le buffer intermediaire
146  glDeleteBuffers(1, &buffer);
147  }
148 
149  for(int i= 0; i < 16; i++)
150  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
151 
152  printf("\n%dx%d groups, %d threads\n", nx, ny, nx*ny*m_threads[0]*m_threads[1]);
153 
154  // attendre le resultat de la requete
155  GLint64 gpu_time= 0;
156  glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
157  //~ gpu_time/= 100;
158  printf("gpu %02dms %03dus\n\n", int(gpu_time / 1000000), int((gpu_time / 1000) % 1000));
159 
160  return 0; // une seule fois
161  //~ return 1; // recommencer jusqu'a la fermeture de la fenetre...
162  }

◆ init() [3/3]

int Histogram::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 20 of file tuto_histogram_compute.cpp.

21  {
22  if(m_image.pixels.size() == 0)
23  // pas d'image
24  return -1;
25 
26  // cree la texture pour stocker l'image
27  GLenum data_type= GL_UNSIGNED_BYTE;
28  GLenum data_format= GL_RGBA;
29  if(m_image.channels == 1)
30  data_format= GL_RED;
31  else if(m_image.channels == 2)
32  data_format= GL_RG;
33  else if(m_image.channels == 3)
34  data_format= GL_RGB;
35  //~ else
36  //~ data_format= GL_RGBA;
37 
38  glGenTextures(1, &m_texture);
39  glBindTexture(GL_TEXTURE_2D, m_texture);
40  glTexImage2D(GL_TEXTURE_2D, 0,
41  GL_RGBA8, m_image.width, m_image.height, 0,
42  data_format, data_type, m_image.data());
43 
44  // pas la peine de construire les mipmaps, le shader ne va ecrire que le mipmap 0
45  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
46 
47  // cree le buffer pour stocker l'histogramme
48  glGenBuffers(1, &m_histogram);
49  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_histogram);
50  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * 16, nullptr, GL_STATIC_COPY);
51 
52  m_program= read_program("tutos/M2/histogram.glsl");
53  program_print_errors(m_program);
54 
55  glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, m_threads);
56 
57  // mesure temps gpu
58  glGenQueries(1, &m_time_query);
59 
60  // histogramme cpu pour comparer...
61  {
62  auto start= std::chrono::high_resolution_clock::now();
63 
64  int histogram[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
65  for(int y= 0; y < m_image.height; y++)
66  for(int x= 0; x < m_image.width; x++)
67  {
68  size_t offset= m_image.offset(x, y);
69  #if 0
70  float r= float(m_image.pixels[offset]) / 255;
71  float g= float(m_image.pixels[offset+1]) / 255;
72  float b= float(m_image.pixels[offset+2]) / 255;
73  float grey= (r+g+b) / 3;
74  int bin= int(15 * grey);
75  #else
76  // nettement plus rapide ...
77  int r= m_image.pixels[offset];
78  int g= m_image.pixels[offset+1];
79  int b= m_image.pixels[offset+2];
80  int bin= 15 * (r+g+b) / (255*3);
81  #endif
82  histogram[bin]++;
83  }
84 
85  auto stop= std::chrono::high_resolution_clock::now();
86  int cpu_time= std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
87 
88  for(int i= 0; i < 16; i++)
89  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
90 
91  printf("cpu %dus\n", cpu_time);
92  }
93 
94  return 1;
95  }

◆ quit() [3/3]

int Histogram::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 97 of file tuto_histogram_compute.cpp.

98  {
99  release_program(m_program);
100  glDeleteBuffers(1, &m_histogram);
101  glDeleteTextures(1, &m_texture);
102  glDeleteQueries(1, &m_time_query);
103  return 0;
104  }

◆ render() [3/3]

int Histogram::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 106 of file tuto_histogram_compute.cpp.

107  {
108  glViewport(0, 0, window_width(), window_height());
109  glClear(GL_COLOR_BUFFER_BIT);
110 
111  glUseProgram(m_program);
112 
113  // storage buffer 0
114  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_histogram);
115  // remet a zero l'histogramme
116  glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
117 
118  // image texture 0, ecriture seule, mipmap 0 + format rgba8 classique
119  glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
120  // configurer le shader
121  program_uniform(m_program, "image", 0);
122 
123  int nx= m_image.width / m_threads[0] / 4;
124  int ny= m_image.height / m_threads[1] / 4;
125  // on suppose que les dimensions de l'image sont multiples de 8*4...
126  // sinon calculer correctement le nombre de groupes pour x et y.
127 
128  glBeginQuery(GL_TIME_ELAPSED, m_time_query);
129  {
130  // go !!
131  //~ for(int i= 0; i < 100; i++) // eventuellement recommencer plein de fois pour stabiliser les frequences du gpu...
132  glDispatchCompute(nx, ny, 1);
133 
134  // attendre le resultat
135  glMemoryBarrier(GL_ALL_BARRIER_BITS);
136  }
137  glEndQuery(GL_TIME_ELAPSED);
138 
139  // relire le buffer resultat
140  int histogram[16];
141  #if 1
142  {
143  // creer un buffer temporaire pour le transfert depuis le buffer resultat
144  GLuint buffer= 0;
145  glGenBuffers(1, &buffer);
146  glBindBuffer(GL_COPY_READ_BUFFER, buffer);
147  glBufferData(GL_COPY_READ_BUFFER, sizeof(int) * 16, nullptr, GL_DYNAMIC_READ);
148 
149  // copie les resultats
150  glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0, sizeof(int) * 16);
151 
152  // recupere les resultats depuis le buffer intermediaire
153  glGetBufferSubData(GL_COPY_READ_BUFFER, 0, sizeof(int) * 16, histogram);
154 
155  // detruit le buffer intermediaire
156  glDeleteBuffers(1, &buffer);
157  }
158  #else
159  glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int) * 16, histogram);
160  #endif
161 
162  for(int i= 0; i < 16; i++)
163  printf("bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
164 
165  printf("\n%dx%d groups, %d threads\n", nx, ny, nx*ny*m_threads[0]*m_threads[1]);
166  // attendre le resultat de la requete
167  GLint64 gpu_time= 0;
168  glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
169  //~ gpu_time/= 100;
170  printf("gpu %02dms %03dus\n\n", int(gpu_time / 1000000), int((gpu_time / 1000) % 1000));
171 
172  return 0; // une seule fois
173  //~ return 1; // recommencer jusqu'a la fermeture de la fenetre...
174  }

The documentation for this struct was generated from the following files: