How to Import models from 3D software, like Maya i

2020-05-29 11:50发布

How can I import 3D models from 3D modelling software like MAYA into OpenGL especially for PC rather than for Iphone development ?

标签: opengl 3d maya
2条回答
对你真心纯属浪费
2楼-- · 2020-05-29 12:26

Maya can export to various formats. Nowadays, mainly FBX is used because it's supported by many art packages.

If you're writing an application in c++, there's a FBX Api you can use to read fbx files: http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=7478532

I think XNA uses this sdk in the background in it's content pipeline. (If you're familiar with xna)

There is also a Python library which can be handy to extract just the data you need from the fbx file: http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/files/WS73099cc142f48755-751de9951262947c01c-6dc7.htm

You could also write your own export script in Maya using python, but be aware that this is not a straightforward task.

I'm sure if you google a bit, you'll find importers for other formats like .obj which is also commonly used.

查看更多
家丑人穷心不美
3楼-- · 2020-05-29 12:46

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.

查看更多
登录 后发表回答