gKit2 light
Loading...
Searching...
No Matches
tuto_read_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 bilan de l'operation : c'est beaucoup plus simple et direct a faire avec glBufferStorage(), les flags de glBufferData() sont bien penibles a choisir correctement
20 remarque : un mauvais choix impactera sans doute les geforce plus que les radeon
21 */
22
23
24//~ #define USE_BUFFER_STORAGE
25//~ #define USE_MAP
26
27
28struct ReadBuffer : public App
29{
30 ReadBuffer( ) : App(1280, 768, 4,3) {}
31
32 int init( )
33 {
34 m_program= read_program("gkit2_tutos/M2/read_buffer.glsl");
35 program_print_errors(m_program);
36
37 std::vector<int> data(1024);
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_read_buffer);
56 glBindBuffer(GL_COPY_READ_BUFFER, m_read_buffer);
57 #ifdef USE_BUFFER_STORAGE
58 #ifdef USE_MAP
59 glBufferStorage(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT);
60 #else
61 glBufferStorage(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_CLIENT_STORAGE_BIT);
62 #endif
63 #else
64 glBufferData(GL_COPY_READ_BUFFER, sizeof(int) * data.size(), nullptr, GL_DYNAMIC_READ);
65 #endif
66
67 #ifdef USE_BUFFER_STORAGE
68 printf("!! use buffer storage\n");
69 #else
70 printf("!! use buffer data\n");
71 #endif
72
73 return 0;
74 }
75
76 int quit( )
77 {
78 release_program(m_program);
79 glDeleteBuffers(1, &m_gpu_buffer1);
80 glDeleteBuffers(1, &m_gpu_buffer2);
81 glDeleteBuffers(1, &m_read_buffer);
82
83 return 0;
84 }
85
86 int render( )
87 {
88 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_gpu_buffer1);
89 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_gpu_buffer2);
90
91 // execute le shader
92 glUseProgram(m_program);
93 glDispatchCompute(4, 1, 1);
94
95 // attends les resultats
96 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
97
98 // et maintenant comment on recupere les donnees qui se trouvent dans un buffer prive du gpu ?
99 // etape 1 : on commence par copier les donnees dans un buffer intermediaire qui est accessible a l'application,
100 // ie pas un buffer prive, cf la creation des 2 types de buffers dans init()...
101 glBindBuffer(GL_COPY_READ_BUFFER, m_read_buffer);
102 glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0, sizeof(int)*1024);
103
104 // etape 2 : on relit le contenu du buffer qui contient la copie des donnees
105 #ifdef USE_MAP
106 // soit avec map()
107 printf("!! use map\n");
108
109 int *tmp= (int *) glMapBuffer(GL_COPY_READ_BUFFER, GL_READ_ONLY);
110 {
111 for(unsigned i= 0; i < 1024; i++)
112 printf("%d ", tmp[i]);
113 printf("\n");
114 }
115 glUnmapBuffer(GL_COPY_READ_BUFFER);
116
117 #else
118 // soit avec getbuffer()
119 printf("!! use get buffer\n");
120
121 std::vector<int> tmp(1024);
122 glGetBufferSubData(GL_COPY_READ_BUFFER, 0, sizeof(int) * tmp.size(), tmp.data());
123 for(unsigned i= 0; i < tmp.size(); i++)
124 printf("%d ", tmp[i]);
125 printf("\n");
126 #endif
127
128 return 0;
129 }
130
131 GLuint m_gpu_buffer1;
132 GLuint m_gpu_buffer2;
133 GLuint m_read_buffer;
134 GLuint m_program;
135};
136
137int main( )
138{
139 ReadBuffer app;
140 app.run();
141
142 return 0;
143}
classe application.
Definition app.h:20
int run()
execution de l'application.
Definition app.cpp:36
App(const int width, const int height, const int major=3, const int minor=3)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app.cpp:11
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: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 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.