如何将模型从3D软件(如Maya)导入OpenGL?

如何将模型从3D软件(如Maya)导入OpenGL?,opengl,3d,maya,Opengl,3d,Maya,如何将3D模型从3D建模软件(如MAYA)导入OpenGL,尤其是针对PC而非Iphone开发的3D模型?MAYA可以导出为各种格式。现在,主要使用FBX,因为它有许多艺术软件包支持 如果你在C++中写一个应用程序,那么有一个FBX API可以用来读取FBX文件: 我认为XNA在其内容管道的后台使用此sdk。(如果您熟悉xna) 还有一个Python库,可以方便地从fbx文件中提取所需的数据: 您也可以使用python在Maya中编写自己的导出脚本,但请注意,这不是一项简单的任务 我相信如果你

如何将3D模型从3D建模软件(如MAYA)导入OpenGL,尤其是针对PC而非Iphone开发的3D模型?

MAYA可以导出为各种格式。现在,主要使用FBX,因为它有许多艺术软件包支持

如果你在C++中写一个应用程序,那么有一个FBX API可以用来读取FBX文件:

我认为XNA在其内容管道的后台使用此sdk。(如果您熟悉xna)

还有一个Python库,可以方便地从fbx文件中提取所需的数据:

您也可以使用python在Maya中编写自己的导出脚本,但请注意,这不是一项简单的任务


我相信如果你搜索一下,你会找到其他格式的导入程序,比如
.obj
,这也是常用的格式。

Maya可以导出到各种格式。现在,主要使用FBX,因为它有许多艺术软件包支持

如果你在C++中写一个应用程序,那么有一个FBX API可以用来读取FBX文件:

我认为XNA在其内容管道的后台使用此sdk。(如果您熟悉xna)

还有一个Python库,可以方便地从fbx文件中提取所需的数据:

您也可以使用python在Maya中编写自己的导出脚本,但请注意,这不是一项简单的任务


我敢肯定,如果你在谷歌上搜索一下,你会找到其他格式的导入程序,比如
.obj
,这也是常用的格式。

也许这让你感到惊讶,但OpenGL没有“模型”这样的限定条件。OpenGL所做的是,它接受一组数据,您有责任让OpenGL访问这些数据,这样它对这些数据执行的操作将在屏幕上产生一个漂亮的图像

在介绍之后,假设你得到了一个模型,比如一个立方体。立方体由6个面组成,每个面有4个角。虽然每个角点位置由3个面共享,但面方向(即所谓的法线)在该角点上非常不同,具体取决于您所看到的面。位置、法线和其他一些属性构成了所谓的顶点。因此,对于立方体,我们有6*4=24个顶点(大写位置,下法线)

等等,我希望你能明白。每条线形成一个顶点向量。此向量的格式是任意的。您可以将这些属性(位置、法线等)放置在一个公共交错数组中,也可以对其自身数组中的每个属性使用多个数组。不过,交错数组通常更有效

与顶点列表一起,还有一个面列表,即顶点索引的元组,对于面而言,这些元组表示四边形,因此在立方体的情况下,这些元组表示四边形

0, 1, 2, 3
4, 5, 6, 7
...
20, 21, 22, 23
加载模型意味着,您可以编写一些程序,从模型文件格式中读取数据(最好是有文档记录的格式,或者是您自己为建模程序编写导出程序的格式)。然后,将读取的数据以如上所述的方式放入内存,以便OpenGL可以使用它

然后将这些数据提供给OpenGL。有两种选择:将数据保存在程序的进程地址空间(客户端顶点数组)中,或者将数据上载到OpenGL缓冲区对象(顶点缓冲区对象)中

然后告诉OpenGL获取其几何体数据

在客户端顶点数组的情况下,这是通过以下方式完成的

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);

}

您可以自己实现模型加载器,或者使用第三方库来完成此任务。

这可能会让您感到惊讶,但OpenGL没有“模型”这样的东西。OpenGL所做的是,它接受一组数据,您有责任让OpenGL访问这些数据,这样它对这些数据执行的操作将在屏幕上产生一个漂亮的图像

在介绍之后,假设你得到了一个模型,比如一个立方体。立方体由6个面组成,每个面有4个角。虽然每个角点位置由3个面共享,但面方向(即所谓的法线)在该角点上非常不同,具体取决于您所看到的面。位置、法线和其他一些属性构成了所谓的顶点。因此,对于立方体,我们有6*4=24个顶点(大写位置,下法线)

等等,我希望你能明白。每条线形成一个顶点向量。此向量的格式是任意的。您可以将这些属性(位置、法线等)放置在一个公共交错数组中,也可以对其自身数组中的每个属性使用多个数组。不过,交错数组通常更有效

与顶点列表一起,还有一个面列表,即顶点索引的元组,对于面而言,这些元组表示四边形,因此在立方体的情况下,这些元组表示四边形

0, 1, 2, 3
4, 5, 6, 7
...
20, 21, 22, 23
加载模型意味着,您可以编写一些程序,从模型文件格式中读取数据(最好是有文档记录的格式,或者是您自己为建模程序编写导出程序的格式)。然后,将读取的数据以如上所述的方式放入内存,以便OpenGL可以使用它

然后将这些数据提供给OpenGL。有两种选择:将数据保存在程序的进程地址空间(客户端顶点数组)中,或者将数据上载到OpenGL缓冲区对象(顶点缓冲区对象)中

然后告诉OpenGL获取其几何体数据

在客户端顶点数组的情况下,这是通过以下方式完成的

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);

}

您可以自己实现模型加载器,也可以使用第三方库来完成此任务。

感谢大家的贡献!我已经得到了Brad Larson给出的解决方案。非常感谢他……!:)好吧,我接受我的道歉,因为我错误地将这个先前提出的问题发布到论坛上。这里回复的每个人都再次表示感谢。感谢大家的合作