Maybe this surprises you, but OpenGL has no such thing qualifying as "models". What OpenGL does is, it accepts a bunch of data and it is upon you to make OpenGL access this data so that the operations it performs on that data will result in a nice image on the screen.
So after that introduction, let's say you got a model, like a cube. A cube consists of 6 faces with 4 corners each. While each corner positions is shared by 3 faces each, the face direction, the so called Normal, is very different on that corner depending which face you're looking at. Position, Normal and a few other attributes form what is known as a vertex. Thus for a cube we have 6 * 4 = 24 vertices (capital position, lower normal)
X, Y, Z, x, y, z
-1, -1, -1, -1, 0, 0
-1, -1, 1, -1, 0, 0
-1, 1, 1, -1, 0, 0
-1, 1, -1, -1, 0, 0
1, -1, -1, 1, 0, 0
1, -1, 1, 1, 0, 0
1, 1, 1, 1, 0, 0
1, 1, -1, 1, 0, 0
…
And so on, I hope you get the idea. Each line forms a vertex vector. The format of this vector is arbitrary. You can place those attributes (Position, Normal, etc.) in one common, interleaved array, or you use multiple arrays for each attribute in its own array. Interleaved arrays oftenly are more efficient though.
Together with the list of vertices you also have a list of faces, i.e. tuple of vertex indices, which for a face, so in the case of a cube those tuples, designating quadrilaterals would be
0, 1, 2, 3
4, 5, 6, 7
...
20, 21, 22, 23
Loading a model means, you write some program that reads the data from a model file format (preferably a documented one, or one you came up with yourself and wrote an exporter for your modelling program for). The read data is then placed into memory in such a way as outlined above so that OpenGL can make use of it.
You then supply this data to OpenGL. There are two options: You keep the data in your program's process address space (Client Side Vertex Arrays), or you upload the data into a OpenGL buffer object (Vertex Buffer Object).
Then you tell OpenGL to fetch its geometry data.
In the case of Client Side Vertex Arrays this is done in the following way
GLenum primitive_mode;
GLfloat *vertex_data;
GLushort *indices_data;
int face_count;
void load_model(...)
{
/* ... */
read_vertex_data_from_file(&vertex_data,
&indices_data,
&face_count,
&primitive_mode, ...);
}
/*...*/
void draw_model()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(
3, /* we're supplying vectors of which the 3 first elements are to be used for vertex position */
GL_FLOAT, /* the type of each vector element is GLfloat */
sizeof(GLfloat)*6, /* the beginnings of vectors in vertex_data are 6 * sizeof(GLfloat) apart */
vertex_data + 0 /* the pointer to the data, positions are offset 0 */
);
glNormalPointer( /* normals always have 3 elements, no size given */
GL_FLOAT, /* the type of each vector element is GLfloat */
sizeof(GLfloat)*6, /* the beginnings of vectors in vertex_data are 6 * sizeof(GLfloat) apart */
vertex_data + 3 /* the pointer to the data, normals are offset 3 */
);
glDrawElements(primitive_mode, face_count, GL_UNSIGNED_SHORT, indices_data);
}
It is upon you to either implement the model loader yourself, or use some third party library for this task.