在 OpenGL 中导入和显示 .fbx 文件

Posted

技术标签:

【中文标题】在 OpenGL 中导入和显示 .fbx 文件【英文标题】:Importing and Displaying .fbx files in OpenGl 【发布时间】:2012-12-15 05:07:57 【问题描述】:

我一直在尝试使用FBX SDK.Untill 导入和显示一个 fbx 文件。我设法加载了文件,但我卡在了必须显示它的部分。 问题:

    这些索引到底是什么? 我应该如何显示顶点?

这是我制作的课程:

3dModelBasicStructs.h

struct vertex

float x,y,z;
;

struct texturecoords

float a,b;
;

struct poligon

int a,b,c;
;

Model.h

#ifndef MODEL_H
#define MODEL_H
#define FBXSDK_NEW_API

#define MAX_VERTICES 80000
#define MAX_POLIGONS 80000


#include <fbxsdk.h>
#include "3dModelBasicStructs.h"
#include <iostream>
#include <GL/glut.h>
using namespace std;

class Model


     public:

         Model(char*);
         ~Model();

         void ShowDetails();

         char* GetModelName();
         void  SetModelName( char* );
         void  GetFbxInfo( FbxNode* );
         void  RenderModel();
                     void  InitializeVertexBuffer( vertex* );

      private:

          char Name[25];

          vertex vertices[MAX_VERTICES];
          poligon poligons[MAX_POLIGONS];

          int *indices;
          int numIndices;

          int numVertices;


;


#endif

Model.cpp

#include "Model.h"






Model::Model(char *filename)

cout<<"\nA model has been built!";

numVertices=0;
numIndices=0;

FbxManager *manager = FbxManager::Create();

FbxIOSettings *ioSettings = FbxIOSettings::Create(manager, IOSROOT);
manager->SetIOSettings(ioSettings);

FbxImporter *importer=FbxImporter::Create(manager,"");
importer->Initialize(filename,-1,manager->GetIOSettings());

FbxScene *scene = FbxScene::Create(manager,"tempName");

importer->Import(scene);
importer->Destroy();

FbxNode* rootNode = scene->GetRootNode();
this->SetModelName(filename);
if(rootNode)  this->GetFbxInfo(rootNode); 



Model::~Model()

cout<<"\nA model has been destroied!";



void Model::ShowDetails()

cout<<"\nName:"<<Name;
cout<<"\nVertices Number:"<<numVertices;
cout<<"\nIndices which i never get:"<<indices;



char* Model::GetModelName()

return Name;


void Model::SetModelName(char *x)

strcpy(Name,x);


void Model::GetFbxInfo( FbxNode* Node )


int numKids = Node->GetChildCount();
FbxNode *childNode = 0;

for ( int i=0 ; i<numKids ; i++)

    childNode = Node->GetChild(i);
    FbxMesh *mesh = childNode->GetMesh();

    if ( mesh != NULL)
    
//================= Get Vertices ====================================
        int numVerts = mesh->GetControlPointsCount();

        for ( int j=0; j<numVerts; j++)
        
            FbxVector4 vert = mesh->GetControlPointAt(j);
            vertices[numVertices].x=(float)vert.mData[0];
            vertices[numVertices].y=(float)vert.mData[1];
            vertices[numVertices++].z=(float)vert.mData[2];
            cout<<"\n"<<vertices[numVertices-1].x<<" "<<vertices[numVertices-    1].y<<" "<<vertices[numVertices-1].z;
this->InitializeVertexBuffer(vertices);
        
//================= Get Indices ====================================
        int *indices = mesh->GetPolygonVertices();
        numIndices+=mesh->GetPolygonVertexCount();
    
    this->GetFbxInfo(childNode);



void Model::RenderModel()

glDrawElements(GL_TRIANGLES,36,GL_INT,indices);

void Model::InitializeVertexBuffer(vertex *vertices)

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vertices);
//glDrawArrays(GL_TRIANGLES,0,36);

可悲的是,当我尝试使用 drawelements 时,我得到了这个错误: A new begging.exe 中 0x77e215de 处未处理的异常:0xC0000005:访问冲突读取位置 0xcdcdcdcd。

【问题讨论】:

访问冲突只是一个指针“指向”它的边界,可能像操作系统的边界等。我不知道如何解决这个问题,最好尝试查明该指针并可能不要对访问冲突的事情使用指针。或者您可以前卫并将 KERNAL32 导入您的程序以可能修复它。检查任何可能导致问题的 char[MAX+1] 【参考方案1】:

2) 我应该如何显示顶点?

这些问题表明您应该学习一些 OpenGL 教程。这些是基础知识,您需要了解它们。

对于您的问题,这是一个好的开始,但您需要完成整个教程 http://opengl.datenwolf.net/gltut/html/Basics/Tut01%20Following%20the%20Data.html

1) 这些索引到底是什么?

你有一个顶点列表。顶点的索引是它在该列表中的位置。您可以使用glDrawElements通过其索引绘制顶点数组

因评论而更新

假设您有一个具有共享顶点的立方体(在 OpenGL 中不常见,但我懒得写下 24 个顶点)。

我在我的程序中将它们放在一个数组中,形成一个它们位置的列表。你从一个文件中加载它们,我正在给它们写一个 C 数组:

GLfloat vertices[3][] = 
    -1,-1, 1,
     1,-1, 1,
     1, 1, 1,
    -1, 1, 1,
    -1,-1,-1,
     1,-1,-1,
     1, 1,-1,
    -1, 1,-1,
;

这给出了顶点索引(数组中的位置),在图片中看起来像

要绘制一个立方体,我们必须告诉 OpenGL 在哪些顶点,以什么顺序构成一个面。那么让我们来看看面孔:

我们要用三角形构建那个立方体。 3 个连续的指数组成一个三角形。对于立方体,这是

GLuint face_indices[3][] = 
    0,1,2,2,3,0,
    1,5,6,6,2,1,
    5,4,7,7,6,5,
    4,0,3,3,7,4,
    3,2,6,6,7,2,
    4,5,0,1,0,5
;

然后您可以通过将 OpenGL 指向顶点数组来绘制它

glVertexPointer(3, GL_FLOAT, 0, &vertices[0][0]);

并在带有顶点的数组上发出批处理调用。有 6*2 = 12 个三角形,每个三角形由 3 个顶点组成,构成一个包含 36 个索引的列表。

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, &face_indices[0][0]);

【讨论】:

Thnx 对于本教程,我会检查一下(我知道如何显示顶点等,但我并没有真正使用过顶点数组或缓冲区等)关于这些索引,我知道它们是一个列表,但我只是不明白它们代表什么? (我的意思是说我们有一个顶点数组和一个三角形,三角形的每个点都是顶点数组的索引/当我看到索引这个词时,这主要是我所理解的) 好的,我已经阅读了,这些是属性索引吗?如果这是真的那意味着我需要超过 1 个指针(对于更大的 3d 模型)对吗? @Taigi:指针数量与模型大小无关。顶点不仅仅是一个位置(常见的误解),而是由许多属性组成;位置、法线、颜色、纹理坐标等。为每个属性设置一个指针,以便 OpenGL 知道从哪里获取该属性。索引将原始顶点“打包”到具有结构的东西中。 好吧...我真的不明白...(我真傻)你有Skype之类的东西,所以我们可以更轻松地交谈吗? @Taigi:查看我的答案更新。我更喜欢异步通信(电子邮件等),因此我既不使用 Skype 也不使用 VoIP。

以上是关于在 OpenGL 中导入和显示 .fbx 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JAVA 在 Web App 中导入和显示 3D 文件 (.stl)?

如何在 Vue 单文件组件中导入和使用图片?

在 OCaml 中导入和解析日历

如何在 R 中导入和合并多个文件?

如何使用maya创建的fbx文件在xna中导入约束

如何在flutter中导入和使用另一个dart文件中的函数