Как импортировать 3D-текстуру в pyOpenGL из файла obj

Я пытаюсь добавить 3D-текстуру в свой проект PyopenGL с помощью pygame. я использовал следующий код и получаю сообщение об ошибке в glTexImage3D

def MTL(filename):
    contents = {}
    mtl = None
    for line in open(filename, "r"):
        if line.startswith('#'):
            continue
        values = line.split()
        if not values:
            continue
        if values[0] == 'newmtl':
            mtl = contents[values[1]] = {}
        elif mtl is None:
            raise ValueError, "mtl file doesn't start with newmtl stmt"
        elif values[0] == 'map_Kd':
            # load the texture referred to by this declaration
            mtl[values[0]] = values[1]
            surf = pygame.image.load(mtl['map_Kd'])
            image = pygame.image.tostring(surf, 'RGBA', 1)
            ix, iy = surf.get_rect().size
            texid = mtl['texture_Kd'] = glGenTextures(1)
            glBindTexture(GL_TEXTURE_3D, texid)
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT)
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT)
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT)
            glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, ix, 0, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
        else:
            mtl[values[0]] = map(float, values[1:])
    return contents



class OBJ:
    def __init__(self, filename, swapyz=False):
        """Loads a Wavefront OBJ file. """
        self.vertices = []
        self.normals = []
        self.texcoords = []
        self.faces = []
        material = None
        for line in open(filename, "r"):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values[0] == 'v':
                v = map(float, values[1:4])
                if swapyz:
                    v = v[0], v[2], v[1]
                self.vertices.append(v)
            elif values[0] == 'vn':
                v = map(float, values[1:4])
                if swapyz:
                    v = v[0], v[2], v[1]
                self.normals.append(v)
            elif values[0] == 'vt':
                self.texcoords.append(map(float, values[1:3]))
            elif values[0] in ('usemtl', 'usemat'):
                material = values[1]
            elif values[0] == 'mtllib':
                self.mtl = MTL(values[1])
            elif values[0] == 'f':
                face = []
                texcoords = []
                norms = []
                for v in values[1:]:
                    w = v.split('/')
                    face.append(int(w[0]))
                    if len(w) >= 2 and len(w[1]) > 0:
                        texcoords.append(int(w[1]))
                    else:
                        texcoords.append(0)
                    if len(w) >= 3 and len(w[2]) > 0:
                        norms.append(int(w[2]))
                    else:
                        norms.append(0)
                self.faces.append((face, norms, texcoords, material))

        self.gl_list = glGenLists(1)
        glNewList(self.gl_list, GL_COMPILE)
        glEnable(GL_TEXTURE_3D)
        glFrontFace(GL_CCW)
        for face in self.faces:
            vertices, normals, texture_coords, material = face

            mtl = self.mtl[material]
            if 'texture_Kd' in mtl:
                # use diffuse texmap
                glBindTexture(GL_TEXTURE_3D, mtl['texture_Kd'])
            else:
                # just use diffuse colour
                glColor(*mtl['Kd'])

            glBegin(GL_POLYGON)
            for i in range(len(vertices)):
                if normals[i] > 0:
                    glNormal3fv(self.normals[normals[i] - 1])
                if texture_coords[i] > 0:
                    glTexCoord3fv(self.texcoords[texture_coords[i] - 1])
                glVertex3fv(self.vertices[vertices[i] - 1])
            glEnd()
        glDisable(GL_TEXTURE_3D)
        glEndList()

в основном я просто загружаю

   obj = OBJ("ground_NFL.obj", swapyz=True)

и пока правда:

   glCallList(obj.gl_list)

ошибка:

OpenGL.error.GLError: GLError(
err = 1281,
description = 'invalid value',
baseOperation = glTexImage3D,
pyArgs = (
    GL_TEXTURE_3D,
    0,
    GL_RGBA,
    4096,
    4096,
    0,
    0,
    GL_RGBA,
    GL_UNSIGNED_BYTE,
    'NrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\xffNrN\...,
),

я думаю, что что-то не так с потоком. спасибо за помощь, проект использует pygame и pyopengl. Я взял исходный код из pygame по следующей ссылке https://www.pygame.org/wiki/OBJFileLoader, но конвертирует только 2D-изображения.


person Bob Sfog    schedule 30.06.2019    source источник
comment
Вы уверены, что вам нужно трехмерное изображение текстуры glTexImage3D< /а>? Разве это не двухмерное изображение текстуры glTexImage2D . Сообщение об ошибке не соответствует параметрам ...,ix, 0, iy, ... в glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, ix, 0, iy, ...   -  person Rabbid76    schedule 30.06.2019
comment
Когда я пытался использовать glteximage2d, результаты - это изображение в 90 градусах GlbindTexture (GL_TEXTURE_2D, TEXID) GLTEXPARAMETERI (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) GLTEXPARAMETERI (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER) GLTEMAREMERI (GL_TEXTURE_2D, Glteximure. GL_RGBA, GL_UNSIGNED_BYTE, изображение) как я могу повернуть изображение, чтобы оно было только на x, 0, z? когда я помещаю iy в глубину, я получаю сообщение об ошибке.   -  person Bob Sfog    schedule 30.06.2019
comment
о, изображение 2d. но текстура 3d. как мне их совместить?   -  person Bob Sfog    schedule 30.06.2019
comment
у меня есть изображение obj, mtl, 2d jpg, я хочу добавить текстуру в свой проект, что я делаю неправильно?   -  person Bob Sfog    schedule 30.06.2019
comment
Вероятно, ошибка invalid value вызвана слишком большим размером изображения.   -  person Rabbid76    schedule 30.06.2019
comment
#1 Я никогда не видел, чтобы 3D-текстура использовалась в wavefront obj+mtl, весьма вероятно, что вы получили 2D-текстуру, а не 3D, но без образца мы можем только догадываться #2 4096 для 3D-текстуры огромно ...,4096,4096,0,... даже не 2D !!! для 2D должно быть ...,4096,4096,1,... но не все карты gfx поддерживают текстуры с разрешением 4096 #3 when i tried to use glTexImage2D the results is the image in 90 degrees что, черт возьми, это значит? # 5 см. Доступ к 3D-массиву во фрагментном шейдере, это пример использования 3D-текстуры...   -  person Spektre    schedule 03.07.2019


Ответы (1)


да, я пытался загрузить 2D-текстуру, замена 3D на 2D исправила проблему

person Bob Sfog    schedule 07.07.2019