22 if(m_image.pixels.size() == 0)
27 GLenum data_type= GL_UNSIGNED_BYTE;
28 GLenum data_format= GL_RGBA;
29 if(m_image.channels == 1)
31 else if(m_image.channels == 2)
33 else if(m_image.channels == 3)
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());
45 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
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);
55 glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, m_threads);
58 glGenQueries(1, &m_time_query);
62 auto start= std::chrono::high_resolution_clock::now();
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++)
68 size_t offset= m_image.offset(x, y);
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);
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);
85 auto stop= std::chrono::high_resolution_clock::now();
86 int cpu_time= std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
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));
91 printf(
"cpu %dus\n", cpu_time);
100 glDeleteBuffers(1, &m_histogram);
101 glDeleteTextures(1, &m_texture);
102 glDeleteQueries(1, &m_time_query);
109 glClear(GL_COLOR_BUFFER_BIT);
111 glUseProgram(m_program);
114 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_histogram);
116 glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
119 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
123 int nx= m_image.width / m_threads[0] / 4;
124 int ny= m_image.height / m_threads[1] / 4;
128 glBeginQuery(GL_TIME_ELAPSED, m_time_query);
132 glDispatchCompute(nx, ny, 1);
135 glMemoryBarrier(GL_ALL_BARRIER_BITS);
137 glEndQuery(GL_TIME_ELAPSED);
145 glGenBuffers(1, &buffer);
146 glBindBuffer(GL_COPY_READ_BUFFER, buffer);
147 glBufferData(GL_COPY_READ_BUFFER,
sizeof(
int) * 16,
nullptr, GL_DYNAMIC_READ);
150 glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0,
sizeof(
int) * 16);
153 glGetBufferSubData(GL_COPY_READ_BUFFER, 0,
sizeof(
int) * 16, histogram);
156 glDeleteBuffers(1, &buffer);
159 glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0,
sizeof(
int) * 16, histogram);
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));
165 printf(
"\n%dx%d groups, %d threads\n", nx, ny, nx*ny*m_threads[0]*m_threads[1]);
168 glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
170 printf(
"gpu %02dms %03dus\n\n",
int(gpu_time / 1000000),
int((gpu_time / 1000) % 1000));
186 int main(
int argc,
char **argv )
188 const char *filename=
"data/papillon.png";
int window_height()
renvoie la hauteur de la fenetre de l'application.
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().
int window_width()
renvoie la largeur de la fenetre de l'application.
ImageData read_image_data(const char *filename)
charge les donnees d'un fichier png. renvoie une image initialisee par defaut en cas d'echec.
GLuint read_program(const char *filename, const char *definitions)
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.
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
int release_program(const GLuint program)
detruit les shaders et le program.
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
stockage temporaire des donnees d'une image.