gKit2 light
tuto_count_buffer.cpp
Go to the documentation of this file.
1 
3 
4 #include <vector>
5 
6 #include "app.h"
7 #include "program.h"
8 
9 /*
10  cree 2 buffers dans la memoire privee du gpu, soit avec glBufferData(GL_STATIC) comme d'habitude,
11  soit avec glBufferStorage() introduit par opengl 4.4
12 
13  pour relire les resultats qui se trouvent dans un buffer prive du gpu, il faut d'abord copier les valeurs dans un buffer accessible par l'application,
14  puis relire enfin les valeurs dans l'application, soit en utilisant glGetBufferSubData() soit en utilisant glMapBuffer()
15 
16  les differentes solutions sont dispo pour tester, il suffit de definir (ou pas) USE_BUFFER_STORAGE et USE_MAP.
17  la configuration choisie est affichee par init().
18  */
19 
20 
21 //~ #define USE_BUFFER_STORAGE
22 //~ #define USE_MAP
23 
24 
25 struct ReadBuffer : public App
26 {
27  ReadBuffer( ) : App(1280, 768, 4,3) {}
28 
29  int init( )
30  {
31  m_program= read_program("tutos/M2/count_buffer.glsl");
32  program_print_errors(m_program);
33 
34  std::vector<int> data(1024);
35  for(unsigned i= 0; i < data.size(); i++)
36  data[i]= i % 16;
37 
38 
39  glGenBuffers(1, &m_gpu_buffer1);
40  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_gpu_buffer1);
41  #ifdef USE_BUFFER_STORAGE
42  glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(int) * data.size(), data.data(), 0);
43  #else
44  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * data.size(), data.data(), GL_STATIC_COPY);
45  #endif
46 
47  glGenBuffers(1, &m_gpu_buffer2);
48  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_gpu_buffer2);
49  #ifdef USE_BUFFER_STORAGE
50  glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(int) * data.size(), nullptr, 0);
51  #else
52  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * data.size(), nullptr, GL_STATIC_COPY);
53  #endif
54 
55  glGenBuffers(1, &m_gpu_count);
56  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_gpu_count);
57  #ifdef USE_BUFFER_STORAGE
58  glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(int), nullptr, 0);
59  #else
60  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), nullptr, GL_STATIC_COPY);
61  #endif
62 
63  glGenBuffers(1, &m_read_buffer);
64  glBindBuffer(GL_COPY_READ_BUFFER, m_read_buffer);
65  #ifdef USE_BUFFER_STORAGE
66  #ifdef USE_MAP
67  glBufferStorage(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT);
68  #else
69  glBufferStorage(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_CLIENT_STORAGE_BIT);
70  #endif
71  #else
72  glBufferData(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_DYNAMIC_READ);
73  #endif
74 
75  #ifdef USE_BUFFER_STORAGE
76  printf("!! use buffer storage\n");
77  #else
78  printf("!! use buffer data\n");
79  #endif
80 
81  return 0;
82  }
83 
84  int quit( )
85  {
86  release_program(m_program);
87  glDeleteBuffers(1, &m_gpu_buffer1);
88  glDeleteBuffers(1, &m_gpu_buffer2);
89  glDeleteBuffers(1, &m_read_buffer);
90 
91  return 0;
92  }
93 
94  int render( )
95  {
96  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_gpu_buffer1);
97  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_gpu_buffer2);
98 
99  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_gpu_count);
100  // remet le compteur a zero
101  int zero= 0;
102  glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, &zero);
103 
104  glUseProgram(m_program);
105  glDispatchCompute(4, 1, 1);
106 
107  glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
108 
109  glBindBuffer(GL_COPY_READ_BUFFER, m_read_buffer);
110  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_gpu_buffer2);
111  glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0, sizeof(int)*1024);
112 
113  #ifdef USE_MAP
114  printf("!! use map\n");
115 
116  // TODO: recupere n, le nombre de valeurs...
117 
118  //~ int *tmp= (int *) glMapBuffer(GL_COPY_READ_BUFFER, GL_READ_ONLY);
119  //~ {
120  //~ for(unsigned i= 0; i < 1024; i++)
121  //~ printf("%d ", tmp[i]);
122  //~ printf("\n");
123  //~ }
124  //~ glUnmapBuffer(GL_COPY_READ_BUFFER);
125 
126  #else
127  printf("!! use get buffer\n");
128 
129  // recupere le nombre de valeurs stockees dans le buffer resultat
130  int n= 0;
131  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_gpu_count);
132  glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int), &n);
133 
134  printf("%d values\n", n);
135 
136  // recupere les valeurs
137  std::vector<int> tmp(n);
138  glGetBufferSubData(GL_COPY_READ_BUFFER, 0, sizeof(int) * tmp.size(), tmp.data());
139 
140  for(unsigned i= 0; i < tmp.size(); i++)
141  printf("%d ", tmp[i]);
142  printf("\n");
143  #endif
144 
145  return 0;
146  }
147 
148  GLuint m_gpu_buffer1;
149  GLuint m_gpu_buffer2;
150  GLuint m_gpu_count;
151  GLuint m_read_buffer;
152  GLuint m_program;
153 };
154 
155 int main( )
156 {
157  ReadBuffer app;
158  app.run();
159 
160  return 0;
161 }
classe application.
Definition: app.h:20
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.
Definition: app.cpp:11
int run()
execution de l'application.
Definition: app.cpp:36
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
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
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.