openGL GLFW PMX模型 学习笔记 m8w2(d1)

目前UE/Unity都只能靠第三方插件导入Pmx模型,看LearnOpenGL的目的还是想自己实现把MMD模型给导入到游戏引擎中。

PMX格式资料:https://www.cnblogs.com/ifwz/p/17544729.html

PMX载入方法参考(C++):GitHub - benikabocha/saba: OpenGL Viewer (OBJ PMD PMX)

PMX文件读取方式

我这是用fread做的文件读取,fread接收3个参数

  • 需要被写入变量的地址;
  • 单个值的字节数量;
  • 值的数量;
  • 需要读取的文件(FILE类型);
// sample
fread(&vertcount, sizeof(vertcount), 1, file);

如上面的例子,fread读取数据的时候,根据第二个参数,读取第三个参数数量的数据,所以总共会读取 sizeof(vertcount) * 1 个字节到vertcount中,这个过程就是非常简单直接的读取。如果想要给glm::vec3类型的变量获取数据,第二个参数用sizeof(float)【因为glm::vec3是三个连续的float类型的数据】,然后第三个参数用3即可;

头部信息

头部信息的获取还是比较容易的,需要注意一下的就是控制台输出编码可能和文件的编码方式不一样,这里我用的是吟霖的Q版模型,控制台输出如下;

Pmx文件大小: 3441418
签名: PMX
version: 2
全局信息数量: 8
全局信息: 0 3 2 1 1 2 2 2
本地模型名: 吟霖Q
通用模型名: New MMD Model
本地语言描述模型: 吟霖Q

请在借物表中注明:
模型:鸣潮/白泽

通用语言描述模型: exported by mmd_tools

顶点信息 

顶点这块主要就注意字节数不要读错了,比如骨骼索引大小是2个字节,但是只读了一个字节给变量,那后面读取的值肯定就全错了;

大致画了个PMX文件中头信息和顶点信息的图,所有的字节对应的内容都在上面了,额外vec4的数量N由全局信息的第二个值可知,顶点绑骨信息顺序和字节大小在最开始给的资料中可以知道。

索引信息

PMX中面是根据索引确定的,每三个索引确定一个三角形面片,索引数据组织方式和顶点数据类似,但是内容就简单很多了,顶点索引大小也是由全局信息知道的。

有顶点信息有索引,自此,我们就可以用顶点,法线和索引结合一个简单的BlinnPhong光照模型,把模型在glfw窗口中用openGl绘制出来叻 ^ ^

先前是用了一个结构体去存储模型的每个顶点信息,创建一个PMXVert数组存储全部的顶点数据。

struct PMXVert {
    glm::vec3 mPos;
    glm::vec3 mNormal;
    glm::vec2 mUV;

    glm::vec4 addiVert[3];
    uint8_t weightType;

    int32_t		boneIndices[4];
    float		boneWeights[4];
    glm::vec3	sdefC;
    glm::vec3	sdefR0;
    glm::vec3	sdefR1;

    float edgeMag;
};

然后把这个PMXVert数组存到VBO中,只用前8个float(对应位置,法线,UV)传入着色器。索引部分,直接就用一个uint16_t类型的数组fread就好。

Pmx文件大小: 3441418
签名: PMX
version: 2
全局信息数量: 8
全局信息: 0 3 2 1 1 2 2 2
本地模型名: 吟霖Q
通用模型名: New MMD Model
本地语言描述模型: 吟霖Q

请在借物表中注明:
模型:鸣潮/白泽

通用语言描述模型: exported by mmd_tools
顶点数量: 26898
Begin read vertex info...
End read vertex info.
面数量: 104193
Begin read face info...
End read face info.

右上角是光源位置, 模型看起来很正常,那么就说明顶点位置,法线和光照参数都正确读取啦 ^ ^

下一个坑:添加模型纹理和材质 :D

posted @ 2024-08-08 09:20  PAddingoi  阅读(10)  评论(0编辑  收藏  举报  来源