Partage
  • Partager sur Facebook
  • Partager sur Twitter

[PyOpengl] Tres tres basses performances

J'utilise les VBO en plus

    14 août 2010 à 2:09:43


    Bonjour,
    Dans le cadre de developpement de mon moteur 3D en python et opengl je fais face a un probleme tres embetant: Les performances sont tres basses(~ 20 FPS). Le moteur est encore super simple, je en fais que charger des modeles 3D d'un fichier .obj + la texture, et les afficher. J'utilise une classe VBO pour masquer les details bas niveau.
    Voici le code en question:
    la classe Mesh qui contient les vbos et les affiche:
    class Mesh:
        def __init__(self, mesh_file, texture_file=None):
            
            loader = ObjLoader()
            self.vbos = loader.load(mesh_file)
            self.texture = None
            if texture_file:
                self.texture = texture.Texture(texture_file)
    
        def draw(self):
            if self.texture:
                self.texture.bind()
                
            for v in self.vbos:
                v.bind()
    
            glDrawArrays(GL_TRIANGLES, 0, len(self.vbos[0]))
    
            for v in self.vbos:
                v.unbind()
                
            if self.texture:
                self.texture.unbind()
    

    la classe ObjLoader qui char un fichier .obj et retourne les vbo des positions/textures/normals
    class ObjLoader:
    
        def load(self, obj_file):
            positions = []
            normals = []
            textures = []
            faces = []
            with open(obj_file) as f:
                for line in f:
                    n = line.find('#')
                    line = line[:n].strip().split()
                    if line:
                        if line[0] == 'v':
                            positions += [map(float, line[1:4])]
                        if line[0] == 'vn':
                            normals += [map(float, line[1:4])]
                        if line[0] == 'vt':
                            textures += [map(float, line[1:3])]
                        if line and line[0] == 'f':
                            faces += \
                                map(self.parse_face, line[1:])
            
            position_vbo = vbo.PositionVBO([positions[pos] for pos, _, _ in faces])
            texture_vbo = vbo.TextureVBO([textures[tex] for _, tex, _ in faces])
            normal_vbo = vbo.NormalVBO([normals[norm] for _, _, norm in faces])
            
            return [position_vbo, texture_vbo, normal_vbo]
            
            
        def parse_face(self, vertex):
            pattern = '(?P<v>\d*)/(?P<vt>\d*)/(?P<vn>\d*)'
            r = re.match(pattern, vertex)
    
            v = r.group('v')
            vt = r.group('vt')
            vn = r.group('vn')
            if not v or not vt or not vn:
                raise ValueError, "obj file bad formatted"
    
            return map(lambda x: int(x) - 1, [v, vt, vn])
    

    la classe VBO
    class VBO:
        def __init__(self, data, usage=GL_STATIC_DRAW):
            self.buffer = GL.GLuint(0)
            self.buffer = glGenBuffers(1)
            self.count = len(data)
            self.size = len(data[0])
            glBindBuffer(GL_ARRAY_BUFFER_ARB, self.buffer)
            data = numpy.array(data, dtype=numpy.float32)
            glBufferData(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(data), ADT.voidDataPointer(data), usage)
    
        def __del__(self):
            print 'deleting vbo'
            glDeleteBuffers(1, GL.GLuint(self.buffer))
        
        def __len__(self):
            return self.count
            
        def bind(self):
            glBindBuffer(GL_ARRAY_BUFFER_ARB, self.buffer)
    
        def unbind(self):
            glBindBuffer(GL_ARRAY_BUFFER_ARB, self.buffer)
    
    class PositionVBO(VBO):
        def bind(self):
            VBO.bind(self)
            glVertexPointerf(None)
    
    class TextureVBO(VBO):
        def bind(self):
            VBO.bind(self)
            glTexCoordPointerf(None)
    
    class NormalVBO(VBO):
        def bind(self):
            VBO.bind(self)        
            glNormalPointerf(None)
            
    class ColorVBO(VBO):
        def bind(self):
            VBO.bind(self)
            glColorPointerf(None)
    


    Le code qui exploite tout cela:
    # Initialisation d'OpenGL
    meshes = []
    for i in range(20):
        meshes +=  [Mesh('data/objs/cube.obj', 'data/textures/texture.jpg')]
        
    while True:
        # Preparation du rendu
        
        for i, m in enumerate(meshes):
            # transformer et une classe qui se charge des transformation 3d(translation + rotation)
            transformer.translate(Vector(i, 0, 0))
            m.draw()
        # Fin du rendu, on efface l'ecran
    



    • Partager sur Facebook
    • Partager sur Twitter
      27 août 2010 à 17:19:21

      Le Python sera toujours moins rapide que du C ! Ou que tout langage interpété au moins pour ce genre d'apllications. Si tu utilises Python 2.0, utilises Psycho qui est, il me semble, un compilateur just-in-time (qui compile au moment où tu lances le logiciel). Sinon, crée les fonctions leese plus lentes en C, et utilises le mécanisme d'"interfaçage" avec Python pour appeler ces fonctions C de Python.
      • Partager sur Facebook
      • Partager sur Twitter

      [PyOpengl] Tres tres basses performances

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown