Bonjour !
j'essayes de fabriquer une classe d'objets OpenGL et je buttes sur un problème depuis plusieurs jours.

En effet, mon programme affiche correctement les points de l'objet choisi ( affichage avec Gl_LINE) par contre l'affichage par les vao et vbo est celui du dernier objet pushé.

J'ai l'impression de me prendre les pieds dans le tapis avec les VAO et VBO.

Je pensais qu'en créant des données membres m_vao, m_vbo , chaque objet aurait de fait son propre identifiant. J'ai l'impression que j'utilise mal l'appel aux fonctions glGenBuffers et glBindBuffers.

Comment faire ? merci

Nom : vao_vbo.jpg
Affichages : 722
Taille : 49,3 Ko

main:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
    //rajout d'un objet dans le vecteur
    Surfaces.push_back(Surface(6));
    Surfaces.push_back(Surface(5));
    Surfaces.push_back(Surface(4));
    Surfaces.push_back(Surface(3));
 
    nb_Surfaces=Surfaces.size();
 
 
    while (!glfwWindowShouldClose(window))
    {
 
    glClearColor(0.2f, 0.2f, 0.38f, 1.0f);//background color
    glClear (GL_COLOR_BUFFER_BIT |  GL_DEPTH_BUFFER_BIT );
    glEnable(GL_BLEND) ;
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glViewport (0, 0, window_sizex, window_sizey);//pour coller au redimensionnement de la fenêtre
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
 
    Surfaces[selected_Surface].draw();
classe hpp

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 
#ifndef DEF_Surface
#define DEF_Surface
 
#include <string>
#include <vector>
 
int nb_Surfaces=0;//nbre de Surface totales créées
int selected_Surface=0;
float rayon_editing_point=0.02;
 
struct Vertex
{
        float x, y, z;
};
 
 
class Surface
{
public://fonction membres allias méthodes
 
    //constructeur
    explicit Surface(int nb_points =4);
 
    ~Surface();//destructeur
 
    void give_a_name(std::string const &name);//user define
    std::string return_a_name() const;
 
    void build_shape(int nb_points);//build vertex default
    int return_nb_points() const;
    int return_array_size() const;
 
    void set_xy_point(int point, double x,double y);
    int return_mouse_over_point(double mousex,double mousey);
 
    void move_shape(double x, double y, double z);
 
 
    void refresh_VBO_vertex_array();//refresh position of points
    void create_shaders();//m_VS et m_FS glCreateShader
    void create_program();
    void compile_attach_shaders(const string &shadercode, GLenum shader_type);
    void link_program();
 
    void draw();
 
 
 
private://variables membres allias attributs
 
    GLuint m_ID;//ID by calling constructor and destructor
 
    std::string m_name; //name of the shape, user define
 
    int m_nb_vert;//number of vertices for the shape
 
    vector<Vertex> m_vertex; //vertex x y z, see struct vertex
 
    int m_over_point;//for editing point in surfaces
 
    GLuint m_VAO;//Vertex array object
    GLuint m_VBO;//Vertex buffer object
    GLuint m_program;
    GLuint m_VS;
    GLuint m_FS;
 
    const char* m_vertex_shader_code;
    const char* m_fragment_shader_code;
 
    float m_color[4];//r v b a
 
    vector<Vertex> m_position;//Surfaces pos x y z
};
#endif // DEF_Surface
classe cpp

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
 
#include <Surfaces.hpp>
 
using namespace std;
 
 
//constructeur par liste d'initialisation////////////constructeur par liste d'initialisation//////////
Surface::Surface(int nb_points)
{
    build_shape(nb_points);
    nb_Surfaces++;
    m_ID=nb_Surfaces;
 
    m_VBO=0;
    glGenBuffers ( 1, &m_VBO);
    glBindBuffer (GL_ARRAY_BUFFER, m_VBO);
    glBufferData (GL_ARRAY_BUFFER,  m_vertex.size() * sizeof(Vertex),   &m_vertex[0], GL_STATIC_DRAW);//GL_DYNAMIC_DRAW);
 
    glGenVertexArrays ( 1, &m_VAO);
    m_VAO=0;
    glBindVertexArray (m_VAO);
    glEnableVertexAttribArray (0);
    glEnableVertexAttribArray (0);
    glBindBuffer (GL_ARRAY_BUFFER, m_VBO);
    glVertexAttribPointer (0, 3 , GL_FLOAT, GL_FALSE, 0, NULL);
 
    refresh_VBO_vertex_array();
 
    m_program = glCreateProgram ();
    m_VS= glCreateShader (GL_VERTEX_SHADER);
    m_FS = glCreateShader (GL_FRAGMENT_SHADER);
 
    string default_VS=
    "#version 140 \n in vec3 vp; \n void main () { gl_Position = vec4 (vp, 1.0);}";
    string default_FS=
    "#version 140 \n out vec4 frag_colour; \n void main () { frag_colour = vec4 (0.7, 0.7, 0.5, .7);}";
 
    compile_attach_shaders(default_VS,GL_VERTEX_SHADER);
    compile_attach_shaders(default_FS,GL_FRAGMENT_SHADER);
 
    link_program();
}
 
//destructeur
Surface::~Surface()
{
}
///////////////////////////////////////////////////
 
void Surface::give_a_name(std::string const &name)
{
m_name=name;
}
 
std::string Surface::return_a_name() const
{
return m_name;
}
 
 
int Surface::return_nb_points() const
{
return(m_nb_vert);
}
 
int Surface::return_array_size() const
{
 return(m_vertex.size() * sizeof(Vertex));
}
 
 
void Surface::build_shape(int nb_points)
{
gl_log_err ("Build_shape BEGIN_\n");
m_nb_vert=nb_points;
m_vertex.resize(nb_points);
 
float r=0.3;
float angle=3.1415926f/nb_points;
float theta;
 
    for(int i=0;i<m_nb_vert;i++)
    {
    theta =  2.0f * 3.1415926f * float(i) / float(nb_points);//get the current angle
    m_vertex[i].x=   r * cosf(angle+ theta);
    m_vertex[i].y=   r * ratio_fenetre * sinf(angle +theta);
    m_vertex[i].z=   0.0f;
    }
 
gl_log_err ("Build_shape Nb Vertex: %d _END \n",nb_points);
}
 
 
 
 
 
void Surface::refresh_VBO_vertex_array()
{
    glEnableVertexAttribArray(0);
    glBindBuffer (GL_ARRAY_BUFFER, m_VBO);
    glBufferData (GL_ARRAY_BUFFER,  m_vertex.size() * sizeof(Vertex),   &m_vertex[0], GL_STATIC_DRAW);//GL_DYNAMIC_DRAW);
}
 
 
 
void Surface::compile_attach_shaders(const std::string &shadercode, GLenum shader_type)
{
GLint status;
 
const char* code = shadercode.c_str();
  switch (shader_type)
    {
    case GL_VERTEX_SHADER:
    gl_log_err ("COMPIL_ATTACH VERTEX SHADER BEGIN_\n");
    glShaderSource (m_VS, 1, (const GLchar**)&code, NULL);
    glCompileShader (m_VS);
    glGetShaderiv(m_VS, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
    gl_log_err ("Compile failure in VERTEX shader:\n");
    GLint infoLogLength;
    glGetShaderiv(m_VS, GL_INFO_LOG_LENGTH, &infoLogLength);
    char* strInfoLog = new char[infoLogLength + 1];
    glGetShaderInfoLog(m_VS, infoLogLength, NULL, strInfoLog);
    gl_log_err (strInfoLog);
    delete[] strInfoLog;
    glDeleteShader(m_VS); m_VS = 0;
    }
 
    glAttachShader (m_program, m_VS);
    gl_log_err ("COMPIL_ATTACH _END\n");
    break;
    case GL_FRAGMENT_SHADER:
    gl_log_err ("COMPIL_ATTACH FRAGMENT SHADER BEGIN_\n");
    glShaderSource (m_FS, 1, (const GLchar**)&code, NULL);
    glCompileShader (m_FS);
    glGetShaderiv(m_FS, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
    gl_log_err ("Compile failure in VERTEX shader:\n");
    GLint infoLogLength;
    glGetShaderiv(m_FS, GL_INFO_LOG_LENGTH, &infoLogLength);
    char* strInfoLog = new char[infoLogLength + 1];
    glGetShaderInfoLog(m_FS, infoLogLength, NULL, strInfoLog);
    gl_log_err (strInfoLog);
    delete[] strInfoLog;
    glDeleteShader(m_FS); m_FS = 0;
    }
    glAttachShader (m_program, m_FS);
    gl_log_err ("COMPIL_ATTACH _END\n");
    break;
    default:
    break;
    }
}
 
 
 
void Surface::link_program()
{
 
gl_log_err ("LINK_PROGRAM BEGIN_\n");
 
    glLinkProgram (m_program);
 
    GLint isLinked = 0;
    glGetProgramiv(m_program, GL_LINK_STATUS, &isLinked);
    if(isLinked == GL_FALSE)
    {
 
    GLint maxLength = 0;
    glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &maxLength);
    gl_log_err ("Linking program failed !\n");
 
    //The maxLength includes the NULL character
    std::vector<GLchar> infoLog(maxLength);
    glGetProgramInfoLog(m_program, maxLength, &maxLength, &infoLog[0]);
   // gl_log_err (infoLog);
    //The program is useless now. So delete it.
    glDeleteProgram(m_program);
 
    //Provide the infolog in whatever manner you deem best.
    //Exit with failure.
    return;
    }
 
gl_log_err ("LINK_PROGRAM _END\n");
}
 
 
 
void Surface::draw()
{
    //DRAW SHAPE
    glUseProgram (m_program);
    refresh_VBO_vertex_array();
    glBindVertexArray (m_VAO);
    glBindBuffer (GL_ARRAY_BUFFER, m_VBO);
    glBindVertexArray (0);
 
 switch(m_nb_vert)
    {
    case 3://TRIANGLE
        glDrawArrays (GL_TRIANGLES, 0, m_vertex.size()*sizeof(Vertex) );
    break;
    case 4://QUAD
        glDrawArrays (GL_QUADS, 0, m_vertex.size()*sizeof(Vertex) );
    break;
    default://POLYGON
        glDrawArrays (GL_POLYGON, 0, m_vertex.size()*sizeof(Vertex) );
    break;
    }
    glUseProgram(0);
 
    //DRAW IN EDIT MODE
    if(edit_geometry==1)
    {
        glLineWidth(width_line);
        //OUTLINING THE SHAPE
        glUseProgram (shader_prg_color_red);
 
        glBegin(GL_LINE_LOOP);
        for(int i=0;i<m_nb_vert;i++)
        {
        glVertex3d(m_vertex[i].x, m_vertex[i].y,z_menus_bottom);
        }
        glEnd();
 
        //CONTROL POINTS
        m_over_point=return_mouse_over_point(mouse_ox,mouse_oy);
        if(m_over_point!=-1 && m_over_point<m_nb_vert)
        {
        DrawCircle(m_vertex[m_over_point].x, m_vertex[m_over_point].y,z_editing_points,rayon_editing_point, width_line,18);
        if(mouse_button_on==1 )//edition du point survolé
        {set_xy_point(m_over_point, mouse_ox,mouse_oy);}
        }
 
        for(int i=0;i<m_nb_vert;i++)
        {
        DrawCircleOutline(m_vertex[i].x, m_vertex[i].y,z_editing_points,rayon_editing_point, width_line,18);
        }
 
        glUseProgram(0);
    }
}
 
 
 
 
void Surface::set_xy_point(int point, double xx,double yy)
{
m_vertex[point].x=xx;
m_vertex[point].y=yy;
}
 
 
 
int Surface::return_mouse_over_point(double mousex,double mousey)
{
int over_point=-1;
    for (int i=0;i<m_nb_vert;i++)
    {
    if(mousex>m_vertex[i].x-rayon_editing_point && mousex<m_vertex[i].x+rayon_editing_point && mousey>m_vertex[i].y-rayon_editing_point && mousey<m_vertex[i].y+rayon_editing_point)
    {
    over_point=i; break;
    }
 
    }
return(over_point);
}