Rendering data read from file.

Hey everyone!

I am having trouble rendering data I read in from a Collada file.
I have written an interface to read vertex, normal, texture, etc data from a Collada file and store it into my own structures for use in OpenGL.
The data loads just fine into my structures! I have checked this!
But when I try to render a simple cube it won’t show up!
I can render the cube just fine if I explicitly set up a vertex array and index array and pass that in, but when I try the same exact calls with the arrays from my data structure, the cube won’t display!

I think it is an issue with pointers to data and my lack of understanding the flow of data in OpenGL.

Can any noble soul help me?

I have a map from string to MyGeometry structures and I loop throw it and draw the geometry. All of the setup including creating vaos, vbos, and setting pointer attributes is done when reading in the file.

Here is my structure:

typedef cml::matrix44f_c Matrix;


struct SourceData {
  GLenum type;
  unsigned int size;
  unsigned int stride;
  void* data;
};


struct IndexData {
    unsigned short* data;
    int count;
};


struct MyGeometry {
  std::string id;
  SourceData vertices;
  SourceData normals;
  SourceData texcoords;
  IndexData vert_indices;
  IndexData norm_indices;
  IndexData tex_indices;
  GLenum primitive;
  Matrix model_matrix;
};

[b]
HERE IS MY SETUP CODE:[/b]


void LoadColladaFile(void)
{
std::string file_name;

std::cout << "Enter .dae file name: ";
std::cin >> file_name;


std::cout << "

READING FILE…
";

ColladaInterface::readFile(&geometries, file_name.data());


std::cout << "

READ FILE!!!
";

geometry_count = geometries.size();


/* Uniforms are used to pass data into the shaders */
/* First we need to get the uniform locations here */
std::cout << "

Getting uniform locations
";
ModelMatrixUniformLocation = glGetUniformLocation(program_ids[0], “ModelMatrix”);
ViewMatrixUniformLocation = glGetUniformLocation(program_ids[0], “ViewMatrix”);
ProjectionMatrixUniformLocation = glGetUniformLocation(program_ids[0], “ProjectionMatrix”);
ExitOnGLError(“ERROR: Could not get shader uniform locations”);

/* Generate vertex array objects */
std::cout << "Generating vaos : " << geometry_count << std::endl;
vaos = new GLuint[geometry_count];
glGenVertexArrays(geometry_count, vaos);
ExitOnGLError("ERROR: Could not generate the VAO");


/* Allocate vbos    */
vbos = new GLuint[geometry_count];
/* Generate buffer to hold vertex data */
glGenBuffers(geometry_count, vbos);
ExitOnGLError("ERROR: Could not generate the buffer objects");


/* Allocate ibos    */
ibos = new GLuint[geometry_count];
/* Generate buffer to hold index data */
glGenBuffers(geometry_count, ibos);
ExitOnGLError("ERROR: Could not generate the buffer objects");


/*    Loop through the geometries    */
std::cout << "

Linking OpenGL to geometries
";
int i = 0;
for(it=geometries.begin() ; it != geometries.end(); it++)
{
MyGeometry * current_geometry = &(*it).second;

    std::cout << "Linking " << current_geometry->id << std::endl;
    /*    Bind new vao for this geometry    */
    glBindVertexArray(vaos[i]);
    std::cout << "Using vao: " << i;
    ExitOnGLError("ERROR: Could not bind the VAO");


    /* Bind vertex buffer object and give it data from geometry*/

    vertices = (float*) current_geometry->vertices.data;


    std::cout << "number of elements: " << current_geometry->vertices.size << std::endl;
    std::cout << "type of elements: " << current_geometry->vertices.type << std::endl;
    std::cout << "stride of vertices: " << current_geometry->vertices.stride << std::endl;
    std::cout << "vertices: " << std::endl;


    for(int j = 0; j < (current_geometry->vertices.size); j++)
    {
        std::cout << vertices[j] << std::endl;
    }


    glBindBuffer(GL_ARRAY_BUFFER, vbos[i]);
    std::cout << "Using vdo: " << i;
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    ExitOnGLError("ERROR: Could not bind the VBO to the VAO");


    /* Bind index buffer and give it the index data */
    std::cout << "number of position indices: " << current_geometry->vert_indices.count << std::endl;
    indices = current_geometry->vert_indices.data;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibos[i]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    ExitOnGLError("ERROR: Could not bind the IBO to the VAO");


    /* Enable vertex attributes */
    glEnableVertexAttribArray(0);
    ExitOnGLError("ERROR: Could not enable vertex attributes");


    /* Set up vertex attribute pointers so that the shaders know what their input is */
    glVertexAttribPointer(
        0, 
        current_geometry->vertices.stride, 
        current_geometry->vertices.type, 
        GL_FALSE, 
        0, 
        0);
    ExitOnGLError("ERROR: Could not set VAO attributes");


    std::cout << "Press enter to link next geometry...";
    getchar();


    i++;
}
std::cout << "

Done linking geometries.
";
}



[b]AND HERE IS MY RENDER FUNCTION:[/b]




std::cout << "Drawing cursor." << std::endl;


    int i = 0;
    /*    Draw all parts of the cursor    */
    for(it=geometries.begin() ; it != geometries.end(); it++)
    {
        std::cout << "Drawing: " << (*it).second.id << std::endl;


        ModelMatrix = (*it).second.model_matrix;
        
        /*    Position and rotate the cursor    */
        /*    Rotate cursor.    */
        //matrix_rotate_about_local_axis(ModelMatrix, 0, ((float) cursor_angle[0]));
        //matrix_rotate_about_local_axis(ModelMatrix, 1, ((float) cursor_angle[1]));
        //matrix_rotate_about_local_axis(ModelMatrix, 2, ((float) cursor_angle[2]));


        /*    Position cursor.    */
        //matrix_set_translation(ModelMatrix, cursor_position[0], cursor_position[1], cursor_position[2]);


        glUseProgram(program_ids[0]);
        ExitOnGLError("ERROR: Could not use the shader program");


        glBindVertexArray(vaos[i]);
        ExitOnGLError("ERROR: Could not bind the VAO for drawing purposes");


        glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.data());
        glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.data());
        ExitOnGLError("ERROR: Could not set the shader uniforms");


        int num_elements = (*it).second.vert_indices.count;
        std::cout << "Number of indices for this object: " << num_elements << std::endl;
        glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_INT, (GLvoid*)0);
        ExitOnGLError("ERROR: Could not draw the cube");


        glBindVertexArray(0);
        glUseProgram(0);
        i++;
    }

Can any noble soul help me?

Let me put on my monocle.

I can render the cube just fine if I explicitly set up a vertex array and index array and pass that in, but when I try the same exact calls with the arrays from my data structure, the cube won’t display!

Well, kind sir, have you verified that the data you extract while parsing the XML file is correct? Have you tried a simple example which can be easily verified, like a quare made up of two triangles?

The reason I ask is that if you are able to draw manually it doesn’t make sense that an automatic approach doesn’t work - unless you data is incorrect or you’re object will simply not be visible with your current view matrix even if the data is correct.

sizeof (vertices) is not what you think it is - because it’s a float * type, this will (assuming 32-bit pointers) actually be 4. You want something like current_geometry->vertices.size * sizeof (float) instead.