VBO nVidia problems

Hi,

I have a project which runs correctly in a laptop with ATI graphic card but when I try to compile on a PC with nVidia graphic card (with updated drivers) I have a segmentation fault when I call glDrawArrays().

The code is exactly the same (copy&paste from to laptop to PC).

Is there someone who understand this?

I’ve read some posts in different forums where they say that VBO can have some problems with nVidia cards, is it possible? In this case, is there a way solve it?

Thanks

Please provide a little bit more information about the issue. Some source code or pseudo-code for the VBO setup and usage would help.

I have a segmentation fault when I call glDrawArrays()

This most commonly happens if you have a vertex array enabled but with invalid data, or if you overshoot the bounds of a VBO while drawing. The ATI driver may be benignly swallowing the error, but NVIDIA is not. Either way, the problem is most likely in your code rather than in the driver.

Array initialization:


//sizeVertex = size of a vector where I add vertices objects(3 floats, x y and z) 
//There's to vectors of this type: vertexVector and normalVector. I have done this because all points are read from a .stl file.
void Joint::initArray()
{
    vertexArray = new GLfloat[sizeVertex]; 
    normalArray = new GLfloat[sizeVertex];
    Vertex v;
    Vertex n;
    int i = 0;
    int j;
    for(j=0;j<vertexVector.size();j++)
    {
        v = vertexVector[j];
        vertexArray[i] = v.x;
        vertexArray[i+1] = v.y;
        vertexArray[i+2] = v.z;

        i+=3;
    }


    i = 0;
    for(j=0;j<normalVector.size();j++)
    {
        n = normalVector[j];
        normalArray[i] = n.x;
        normalArray[i+1] = n.y;
        normalArray[i+2] = n.z;
        normalArray[i+3] = n.x;
        normalArray[i+4] = n.y;
        normalArray[i+5] = n.z;
        normalArray[i+6] = n.x;
        normalArray[i+7] = n.y;
        normalArray[i+8] = n.z;
        i+=9;
    }

    GLuint vertexs;
    GLuint normals;

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glEnableClientState(GL_VERTEX_ARRAY);

    glGenBuffers(1,&vertexs);
    glBindBuffer(GL_ARRAY_BUFFER,vertexs);
    glBufferData(GL_ARRAY_BUFFER,sizeVertex*sizeof(GLfloat),vertexArray,GL_DYNAMIC_DRAW);
    glVertexPointer(3,GL_FLOAT,0,0);

    glEnableClientState(GL_NORMAL_ARRAY);

    glGenBuffers(1,&normals);
    glBindBuffer(GL_ARRAY_BUFFER,normals);
    glBufferData(GL_ARRAY_BUFFER,sizeVertex*sizeof(GLfloat),normalArray,GL_DYNAMIC_DRAW);
    glNormalPointer(GL_FLOAT,0,0);

}

Render function:


void Joint::render()
{
    qDebug()<<name;
    this->changeCoordinates();

    glBindVertexArray(vao);

    glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,difus);
    glMaterialfv(GL_FRONT,GL_SPECULAR,especular);

    glDrawArrays(GL_TRIANGLES,0,sizeVertex/3);
}

There is something awfully odd about your normal vector values:


i = 0;
    for(j=0;j<normalVector.size();j++)
    {
        n = normalVector[j];
        normalArray[i] = n.x;
        normalArray[i+1] = n.y;
        normalArray[i+2] = n.z;
        normalArray[i+3] = n.x;
        normalArray[i+4] = n.y;
        normalArray[i+5] = n.z;
        normalArray[i+6] = n.x;
        normalArray[i+7] = n.y;
        normalArray[i+8] = n.z;
        i+=9;
    }

why are you replicating each normal vector 3 times? Also, are you 100% sure that 9normalVector.size() equals sizeVertex and that 3vertexVector.size() equals sizeVertex as well? These issues would crash on other platforms too with segmentation fault often enough. Also, I strongly advise for you to use std::vector<> for your arrays or atleast remember to call delete[] at the end of Joint::initArray().

My one hunch, is that maybe perhaps that the NVIDIA driver does not respect the fixed function array state in it’s VAO’s (that would be out of spec though!). Try setting up your code without using VAO’s to see if that is the issue, and just to check, vao is a member of Joint right? and also just to check is the code like this:


Joint some_joint;
..
..

some_joint.init(args); //only called once

..
..
..

while(renderloop)
{
   ..
   ..
   some_joint.render()
}



i.e. init is called exactly once for a given Joint object.

In my .stl file, I have one normal per three vertex. In this forum they recommend me to copy the normal of the triangle for each vertex of this one.

Gonna do this ok!

That s exaclty how my code works. However, I don t know how to set the code without VAO. I have different joints, each joint has these VBO, if I don t use VAO I cannot draw all the joints (if I m right, VAO is a way to separate VBO´s)

Yes :D.

Judging by the “qDebug()” in your code, I assume you re using Qt. With that in mind, be aware that Qt does not use VAO anywhere within its code base. Add


glBindVertexArray(0);

to the end of Joint::init(), i.e. that is the last statement of that method. This will make sure that nothing else affects the VAO, vao. Also to make sure Qt does not affect the state of your VAO’s, you need to make sure you also call glBindVertexArray(0) whenever Qt might use GL, the brute force would be to add that just after your glDrawArrays call in Joint::render(), but I advise to add glBindVertexArray(0) as the last GL call you do in your “render” loop. If you have any Qt calls that can affect GL state (namely any QPainter call typically), you’ll need to insert glBindVertexArray(0) before any such block of such calls.

Thanks kRogue, this is the problem and now it’s solved!

Thanks again!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.