FBX格式解析顶点信息和用OpenGL显示

FbxSDK是解析FBX的工具,在unity和ue中使用较多,下面介绍一下用这个工具解析FBX格式并用OpenGL显示出来。

FBX的scene是由一系列node组成的,node包含一个Transfrom和NodeAttribute,NodeAttribute包含很多类型,如eMaker、eSkeleton、eMaker、eMesh等。

模型的顶点信息存放在eMesh里,eMesh中包含了控制点信息和索引信息。索引信息指的是一系列index,如1个三角形由控制点的第0,1,2这三个点组成一个三角形,则索引信息存放这3个索引数组。

控制点 信息可以由GetControlPoints方法得到,而索引信息可以由GetPolygonVertex得到。

接下来用一个数组存放这些所有的控制点和索引号,定义如下数据结构:

struct Point{
    GLfloat x;
    GLfloat y;
    GLfloat z;
};

int TriangleVertexCount=0;
int TriangleIndexCount=0;

std::vector<Point> triangleVertexVec;         //控制点列表
std::vector<int> triangleIndexVec;              //索引序列

由于模型中的mesh不止一个,放在一起需要重新编号:

void readMesh(FbxMesh *mesh)
{
    int ctrlcount=mesh->GetControlPointsCount();
    FbxVector4 *ctrlpoints=mesh->GetControlPoints();
    for(int i=0;i<ctrlcount;i++)
    {
        Point p;
        p.x=ctrlpoints[i].mData[0];
        p.y=ctrlpoints[i].mData[1];
        p.z=ctrlpoints[i].mData[2];
        triangleVertexVec.push_back(p);
    }
    int pvcount=mesh->GetPolygonVertexCount();
    int pcount=mesh->GetPolygonCount();
    for(int i=0;i<pcount;i++)
    {
        int psize=mesh->GetPolygonSize(i);
        for(int j=0;j<psize;j++)
            triangleIndexVec.push_back(TriangleIndexCount+mesh->GetPolygonVertex(i,j));
    }
    TriangleVertexCount+=ctrlcount;          //加上上一个node的控制点个数
    TriangleIndexCount+=ctrlcount;
}

遍历所有node的函数如下:

void parseNode(FbxNode *node)              //如何加载fbx文件获得RootNode此处省略
{
    int count=node->GetChildCount();
    parseNodeAttribute(node);
    
    for(int i=0;i<count;i++)
    {
        FbxNode* son=node->GetChild(i);
        parseNode(node->GetChild(i));
    }
}

void parseNodeAttribute(FbxNode *node)
{
    int nacount=node->GetNodeAttributeCount();
    for(int i=0;i<nacount;i++)
    {
        FbxNodeAttribute *na=node->GetNodeAttributeByIndex(i);
        if(na->GetAttributeType()==FbxNodeAttribute::eMesh)
        {
            FbxMesh *mesh=(FbxMesh*)na;
            readMesh(mesh);
        }
    }

至此所有的mesh中的控制点和索引已经存放到triangleVertexVec和triangleIndexVec中,只需要将这个三角形面放入到OpenGL里实现就可以了。初始化OpenGL,编译shader的函数如下:

void init(void)
{
    ShaderInfo shaders[] = {
        { GL_VERTEX_SHADER, "primitive_restart.vs.glsl" },
        { GL_FRAGMENT_SHADER, "primitive_restart.fs.glsl" },
        { GL_NONE, NULL }
    };
    program=LoadShaders(shaders);         //此处用了OpenGL红宝书中的LoadShaders
    glUseProgram(program);
    glClearColor(0,0,0,1);
    glGenVertexArrays(4,voa);
    glBindVertexArray(voa[0]);
    glGenBuffers(4, vob);
    glBindBuffer(GL_ARRAY_BUFFER, vob[0]);
    triangleVertex=new GLfloat[triangleVertexVec.size()*3];
    for(int i=0;i<triangleVertexVec.size();i++)
    {
        triangleVertex[3*i]=triangleVertexVec[i].x;
        triangleVertex[3*i+1]=triangleVertexVec[i].y;
        triangleVertex[3*i+2]=triangleVertexVec[i].z;
    }
    triangleIndex=new GLuint[triangleIndexVec.size()*3];
    for(int i=0;i<triangleIndexVec.size();i++)
    {
        triangleIndex[i]=triangleIndexVec[i];
    }
    glBufferData(GL_ARRAY_BUFFER, triangleVertexVec.size()*3*sizeof(GLdouble), triangleVertex, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const void *)(0));
    glEnableVertexAttribArray(0);
    delete triangleVertex;
    delete triangleIndex;
}

绘制的函数如下:

void display()
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    GLuint t_index=glGetUniformLocation(program,"model_transform");
    vmath::mat4 transformMatrix=vmath::scale<float>(0.006);
    glUniformMatrix4fv(t_index,1,GL_FALSE,transformMatrix);
    glDrawElements(GL_TRIANGLES,triangleIndexVec.size(),GL_UNSIGNED_INT,triangleIndex);
    glFlush();
}

顶点着色器的代码为:

#version 400

layout (location = 0) in vec4 position;
uniform mat4 model_transform;

void main(void)
{
    
    gl_Position = model_transform*position;
}
片元着色器代码为:

#version 400
layout (location = 0) out vec4 color;


void main(void)
{
    color = vec4(1.0,0.0,0.0,1.0);
}

绘制出来的效果为:

虽然有点丑,但是还是能看出效果的哈。。。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在OpenGL显示FBX文件,您需要使用FBX SDK来解析FBX文件并提取所需的顶点和纹理等数据。然后,您可以使用OpenGL的渲染功能来绘制模型。 以下是一般的步骤: 1. 导入FBX SDK库:将FBX SDK库文件添加到您的项目中,并链接到您的代码中。 2. 创建一个FBX Manager对象:创建一个FBX Manager对象,它将负责加载和管理FBX文件。 3. 加载FBX文件:使用FBX Manager对象加载您要显示FBX文件。 4. 遍历场景中的节点:获取根节点,并遍历其子节点以获取所需的模型数据,例如顶点、法线、纹理坐标等。 5. 创建顶点缓冲对象(VBO):将提取的顶点数据存储在一个顶点缓冲对象中,以便在渲染时使用。 6. 创建纹理对象:如果FBX文件包含纹理信息,您可以使用OpenGL创建纹理对象并将纹理图像加载到其中。 7. 设置OpenGL状态:根据需要,设置OpenGL的渲染状态,例如光照、混合模式等。 8. 渲染:使用OpenGL的绘制函数(如glDrawArrays或glDrawElements)将顶点数据和纹理绑定到适当的渲染管线中进行渲染。 9. 清理资源:在完成后,释放和清理由FBX SDK分配的资源和内存。 这只是一个基本的概述,实际上在将FBX模型渲染到OpenGL中还有许多其他细节和技术要考虑,例如法线计算、动画处理等。您可能需要更深入地了解OpenGLFBX SDK的文档,并根据您的需求来实现具体的渲染逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值