Question

I have a question regarding interleaved vbo's. I have a structure that looks like this

struct VertexData{
    float x,y,z;   //vertex coordinates
    float normalx,normaly,normalz;  //vertex normal
    float cx,cy,cz;  //vertex color
};

And this is how i create my VBO,VAO,IBO:

    //creat OpenGL objects to use in drawing
    unsigned int gl_vertex_array_object, gl_vertex_buffer_object, gl_index_buffer_object;

    //vertex array object 
    glGenVertexArrays(1, &gl_vertex_array_object);
    glBindVertexArray(gl_vertex_array_object);

    //vertex buffer object -> we hold the vertices 
    glGenBuffers(1,&gl_vertex_buffer_object);
    glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer_object);
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(VertexData), &vertices[0], GL_STATIC_DRAW);


    //index buffer object -> we hold the index of vertex
    glGenBuffers(1,&gl_index_buffer_object);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_index_buffer_object);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    //the connection between attributes, interleaved data
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(VertexData),(void*)0);                       //send positions on pipe 0
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(VertexData),(void*)(sizeof(float)*3));       //send normals on pipe 1
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,sizeof(VertexData),(void*)(3*sizeof(float)*3));     //send colors on pipe 2

    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glNormalPointer(GL_FLOAT,sizeof(VertexData),(void*)(sizeof(float)*3));   
    glColorPointer(3,GL_FLOAT,sizeof(VertexData),(void*)(3*sizeof(float)*3));

    vao = gl_vertex_array_object;
    vbo = gl_vertex_buffer_object;
    ibo = gl_index_buffer_object;
    num_indices = indices.size();

If my VBO is a vector of VertexData , does it mean it is interleaved ? And did i send the data correct above ? with stride and offset ? All this is in another class. Here is how i load the mesh and draw it in the main class

    //load
 teren::loadTerrain("resurse\\heightmap.bmp","resurse\\heightmap_color.bmp",mesh_vao_ground, mesh_vbo_ground, mesh_ibo_ground, mesh_num_indices_ground,20);
    //draw
    glUniformMatrix4fv(glGetUniformLocation(gl_program_shader_curent, "model_matrix"),1,false,glm::value_ptr(matrice_translatie));
    glBindVertexArray(mesh_vao_ground);
    glDrawElements(GL_TRIANGLES, mesh_num_indices_ground, GL_UNSIGNED_INT, 0);

My terrain is drawn but it has a weird colouring. It has pink and blue and whatnot, doesn't look anything like the color image from which i get my vertex colors. Here is my gourard vertex shader:

layout(location = 0) in vec3 in_position;       
layout(location = 1) in vec3 in_normal; 
layout(location = 2) in vec3 in_color;  

uniform mat4 model_matrix, view_matrix, projection_matrix;
uniform vec3 light_position;
uniform vec3 eye_position;
uniform int material_shininess;
uniform float material_kd;
uniform float material_ks;

out vec3 light;
void main(){


gl_Position = projection_matrix*view_matrix*model_matrix*vec4(in_position,1.0); 
float fDiffuseIntensity = material_kd * max(0.0, dot(normalize(in_normal), normalize(light_position)));
light = material_ks * in_color * fDiffuseIntensity;
}

And my gourard fragment shader:

in vec3 light;
out vec4 out_color;

void main()
{
    out_color = vec4(light,1.0);
}

I am really stuck right now. Is it a problem with my shaders or my vbo/attributes,etc or maybe even both. I would really appreciate some help.(PS:If in the vertex shader i change to light=in_color , everything is white).I also have a light rotating above the terrain. Here is a photo of what is happening: http://i44.tinypic.com/69j0cg.jpg

Was it helpful?

Solution

This line:

glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,sizeof(VertexData),(void*)(3*sizeof(float)*3));

Should be:

glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,sizeof(VertexData),(void*)(sizeof(float)*6));

Also you don't need these stuffs:

glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glNormalPointer(GL_FLOAT,sizeof(VertexData),(void*)(sizeof(float)*3));   
glColorPointer(3,GL_FLOAT,sizeof(VertexData),(void*)(3*sizeof(float)*3));

All the rest is correct.


does it mean it is interleaved?

Yes.


Language lawyers will probably tell you that since the compiler is allowed to add padding anywhere inside the VertexData struct, the correct approach to pass these data to GL would be to manually convert your vector of VertexData to a buffer of floats. Practically speaking, no compiler pads floats inside a struct like that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top