栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从Superbible Opengl中读取,解析SBM文件格式

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从Superbible Opengl中读取,解析SBM文件格式

由于您已经在使用NumPy,我将给yuo一个答案,该答案使用NumPy读取二进制文件。NumPy具有一些功能,可以按不同的数据类型重新解释缓冲区数据,而这正是解释二进制文件所需要的。

二进制文件可以通过

numpy.fromfile
.eg读取为字节数组。

data = numpy.fromfile(filename, dtype=np.byte)

可以将数组的某些字节解释为无符号整数(

unit32
numpy.frombuffer
。例如:

class SB6M_HEADER:    def __init__(self, data):        int_data = np.frombuffer(np.array(data[:16], dtype=np.byte), dtype=np.uint32)        self.magic, self.size, self.num_chunks, self.flags = int_data         print(self.magic, self.size, self.num_chunks, self.flags)

Porting the source pre from
sb6mfile.h
respectively
sb7object.cpp
to python and reading and “*.sbm” file:

def SB6M_FOURCC(a,b,c,d):    return ( (ord(a) << 0) | (ord(b) << 8) | (ord(c) << 16) | (ord(d) << 24) )SB6M_MAGIC = SB6M_FOURCC('S','B','6','M')SB6M_CHUNK_TYPE_INDEX_DATA      = SB6M_FOURCC('I','N','D','X')SB6M_CHUNK_TYPE_VERTEX_DATA     = SB6M_FOURCC('V','R','T','X')SB6M_CHUNK_TYPE_VERTEX_ATTRIBS  = SB6M_FOURCC('A','T','R','B')SB6M_CHUNK_TYPE_SUB_OBJECT_LIST = SB6M_FOURCC('O','L','S','T')SB6M_CHUNK_TYPE_COMMENT         = SB6M_FOURCC('C','M','N','T')SB6M_CHUNK_TYPE_DATA = SB6M_FOURCC('D','A','T','A')class SB6M_HEADER:    def __init__(self, data):        int_data = np.frombuffer(np.array(data[:16], dtype=np.byte), dtype=np.uint32)        self.magic, self.size, self.num_chunks, self.flags = int_data         print(self.magic, self.size, self.num_chunks, self.flags)class SB6M_CHUNK_HEADER:    def __init__(self, data, offset):        int_data = np.frombuffer(np.array(data[offset:offset+8], dtype=np.byte), dtype=np.uint32)        self.type, self.size = int_dataclass SB6M_CHUNK_INDEX_DATA(SB6M_CHUNK_HEADER):     def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+20], dtype=np.byte), dtype=np.uint32)        self.index_type, self.index_count, self.index_data_offset = int_dataclass SB6M_CHUNK_VERTEX_DATA(SB6M_CHUNK_HEADER):     def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+20], dtype=np.byte), dtype=np.uint32)        self.data_size, self.data_offset, self.total_vertices = int_dataclass SB6M_CHUNK_VERTEX_DATA(SB6M_CHUNK_HEADER):     def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+20], dtype=np.byte), dtype=np.uint32)        self.data_size, self.data_offset, self.total_vertices = int_dataSB6M_VERTEX_ATTRIB_FLAG_NORMALIZED = 0x00000001SB6M_VERTEX_ATTRIB_FLAG_INTEGER    = 0x00000002class SB6M_VERTEX_ATTRIB_DECL:    def __init__(self, data, offset):        self.name = ''.join([chr(n) for n in data[offset:offset+64] if n > 30])        int_data = np.frombuffer(np.array(data[offset+64:offset+84], dtype=np.byte), dtype=np.uint32)        self.size, self.type, self.stride, self.flags, self.data_offset = int_dataclass SB6M_VERTEX_ATTRIB_CHUNK(SB6M_CHUNK_HEADER):    def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+12], dtype=np.byte), dtype=np.uint32)        self.attrib_count = int_data[0]        self.attrib_data = []        for i in range(self.attrib_count): self.attrib_data.append(SB6M_VERTEX_ATTRIB_DECL(data, offset+12+i*84))class SB6M_DATA_CHUNK(SB6M_CHUNK_HEADER):    def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+20], dtype=np.byte), dtype=np.uint32)        self.encoding, self.data_offset, self.data_length = int_dataclass SB6M_SUB_OBJECT_DECL:    def __init__(self, data, offset):        int_data = np.frombuffer(np.array(data[offset:offset+8], dtype=np.byte), dtype=np.uint32)        self.first, self.count = int_dataclass SB6M_CHUNK_SUB_OBJECT_LIST(SB6M_CHUNK_HEADER):    def __init__(self, data, offset):        super().__init__(data, offset)        int_data = np.frombuffer(np.array(data[offset+8:offset+12], dtype=np.byte), dtype=np.uint32)        self.count = int_data[0]        self.sub_object = []        for i in range(self.count): self.sub_object.append(SB6M_SUB_OBJECT_DECL(data, offset+12+i*8)) def load(filename):    vertex_attrib_chunk = None    vertex_data_chunk = None    index_data_chunk = None    sub_object_chunk = None    data_chunk = None    try:        data = numpy.fromfile(filename, dtype=np.byte)        filesize = data.size        header = SB6M_HEADER(data)        offset = header.size        for i in range(header.num_chunks): chunk = SB6M_CHUNK_HEADER(data, offset) if chunk.type == SB6M_CHUNK_TYPE_VERTEX_ATTRIBS:     vertex_attrib_chunk = SB6M_VERTEX_ATTRIB_CHUNK(data, offset)  elif chunk.type == SB6M_CHUNK_TYPE_VERTEX_data:     vertex_data_chunk = SB6M_CHUNK_VERTEX_DATA(data, offset) elif chunk.type == SB6M_CHUNK_TYPE_INDEX_data:     index_data_chunk = SB6M_CHUNK_INDEX_DATA(data, offset)  elif chunk.type == SB6M_CHUNK_TYPE_SUB_OBJECT_LIST:     sub_object_chunk = SB6M_CHUNK_SUB_OBJECT_LIST(data, offset) elif chunk.type == SB6M_CHUNK_TYPE_data:     data_chunk = SB6M_DATA_CHUNK(data, offset)  else:     raise offset += chunk.size    except:        print("error reading file {}".format(filename))

Finally the floating point vertex data can be read:

if vertex_data_chunk and vertex_attrib_chunk:    start = vertex_data_chunk.data_offset    end = start + vertex_data_chunk.data_size    vertex_data = np.frombuffer(np.array(data[start:end], dtype=np.byte), dtype=np.float)    data_buffer = glGenBuffers(1)    glBindBuffer(GL_ARRAY_BUFFER, data_buffer)    glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW)    vertexcount = vertex_data_chunk.total_vertices    vao = glGenVertexArrays(1)    glBindVertexArray(self.vao)    for attrib_i, attrib in enumerate(vertex_attrib_chunk.attrib_data):        if attrib.name=='position' or attrib.name=='map1':   glVertexAttribPointer(attrib_i,     attrib.size, attrib.type,     GL_TRUE if (attrib.flags & SB6M_VERTEX_ATTRIB_FLAG_NORMALIZED) != 0 else GL_FALSE,     attrib.stride, ctypes.c_void_p(int(attrib.data_offset))) glEnableVertexAttribArray(attrib_i)

Finally draw the mesh:

glBindVertexArray(vao)glDrawArrays(GL_TRIANGLES, 0, vertexcount)


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/668501.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号