如何将 Maya 等 3D 软件中的模型导入 OpenGL?

发布于 2024-11-30 19:44:48 字数 65 浏览 2 评论 0 原文

如何将 3D 模型从 MAYA 等 3D 建模软件导入 OpenGL,特别是针对 PC 而不是 Iphone 开发?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

焚却相思 2024-12-07 19:44:48

也许这会让您感到惊讶,但是 OpenGL 没有“模型”这样的东西。 OpenGL 所做的是,它接受一堆数据,并且您需要让 OpenGL 访问这些数据,以便它对这些数据执行的操作将在屏幕上生成漂亮的图像。

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

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
…

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

除了顶点列表之外,您还有一个面列表,即顶点索引元组,对于一个面来说,因此在立方体的情况下,这些元组,指定四边形将是

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

}

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

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.

浅浅淡淡 2024-12-07 19:44:48

Maya 可以导出为各种格式。如今,主要使用 FBX,因为许多艺术包都支持它。

如果您使用 C++ 编写应用程序,则可以使用 FBX Api 来读取 fbx 文件:
http://usa.autodesk.com/adsk/servlet/index ?siteID=123112&id=7478532

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

还有一个 Python 库,可以方便地从 fbx 文件中提取所需的数据:http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/files/WS73099cc142f48755-751de9951262947c01c-6dc7.htm

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

我确信,如果您用谷歌搜索一下,您会找到其他格式的导入器,例如也常用的 .obj

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文