OpenGL: модель не выглядит правильно при загрузке в Python - PullRequest
2 голосов
/ 14 ноября 2010

У меня есть модель блендера, а ниже - изображение того, как моя модель рендерится, когда я загружаю ее в python.Похоже, нормалы все испорчены.Я использую правильную нормаль для каждой вершины.Я экспортирую их в правильном порядке.Я проверяю это в консоли блендера, чтобы фактический файл экспорта содержал правильные данные.

Я знаю, что мне пришлось вращать модель в python, потому что ось z отличается, поэтому я не уверен, что нормали z указывают в неправильном направлении.

Я использую pyglet.Кто-нибудь когда-нибудь имел эту проблему раньше?Любые идеи о том, что я могу сделать, чтобы попытаться это исправить?

Я не уверен, если это проблема OpenGL или python.

Код установки opengl:

glMatrixMode(GL_PROJECTION)
    zNear = 0.01
    zFar = 1000.0
    fieldOfView = 45.0
    size = zNear * math.tan(math.radians(fieldOfView) / 2.0)
    glFrustum(-size, size, -size / (w / h), size / 
           (w / h), zNear, zFar); 
    glViewport(0, 0, w, h);  
    # Set-up projection matrix
    # TODO


    glMatrixMode(GL_MODELVIEW)
    glShadeModel(GL_SMOOTH)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)


    light0Ambient = (GLfloat * 4)(*[])
    light0Ambient[0] = 0.2
    light0Ambient[1] = 0.2
    light0Ambient[2] = 0.2
    light0Ambient[3] = 1.0
    glLightfv(GL_LIGHT0, GL_AMBIENT, light0Ambient);


    lightpos = (GLfloat * 3)(*[])
    lightpos[0] = 5.0
    lightpos[1] = 5.0
    lightpos[2] = 5.0
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos)


    tempLV = self.kjgCreateVectorWithStartandEndPoints((5.0,5.0,5.0), (0.0,0.0,-3.0))
    lightVector = (GLfloat * 3)(*[])
    lightVector[0] = tempLV[0]
    lightVector[1] = tempLV[1]
    lightVector[2] = tempLV[2]
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION,lightVector);

    glLoadIdentity( )
    glTranslatef(0.0, 2.0, -18.0)
    #glScalef(0.4, 0.4, 0.4)
    glRotatef(-90, 1.0, 0.0, 0.0)

DrawКод:

    for face in self.faces:
        #print group
        if len(face) == 3:
                glBegin(GL_TRIANGLES)
        elif len(face) == 4:
                glBegin(GL_QUADS)
        else:
                glBegin(GL_POLYGON)
        for i in face:
            if i in (104,16,18,102):
                    glVertex3f(*self.vertices[i])
                    color = self.calculateVertexIntensity((.5,.5,.5),self.normals[i],self.vertices[i])
                    glColor3f(*color)
                    glNormal3f(*self.normals[i])
        glEnd()

alt text

Ответы [ 2 ]

6 голосов
/ 14 ноября 2010

Прямо сейчас вы указываете нормальную после вершины вместо до , поэтому в основном вы задаете нормаль вершины X для вершины X + 1. Это самый важный недостаток в текущем коде.

Кроме того, что это calculateVertexIntensity? Во-первых, в вашем коде включено освещение, поэтому glColor все равно будет игнорироваться, но все равно похоже, что вы пытались сделать что-то здесь ненужное - фиксированная функция рендеринга OpenGL уже вычислит интенсивность вершин на основе glLight* настройки и glMaterial* настройки.

Кроме того, вы можете захотеть нормализовать ваш lightVector, я не уверен, собирается ли OpenGL нормализовать его для вас.

(Также не забудьте проверить последние функции OpenGL; вы используете устаревшие функции прямо сейчас, и из-за этого вы скоро столкнетесь с барьером производительности. Первое, на что нужно обратить внимание, это vertex arrays или VBO, следующий shaders.)

0 голосов
/ 14 ноября 2010

Это похоже на проблему с вашими нормалями.

Данные в self.normals, вероятно, неверны: вам следует пересчитать нормали, убедившись, что вы всегда используете последовательность вершин в направлении против часовой стрелки вокруг грани, чтобырассчитать каждую нормаль.

(также вы должны вызывать glNormal перед рисованием каждой вершины / грани)

(также, я не знаю, что происходит, когда вы вычисляете цвет для каждоговершина: но убедитесь, что это не вызывает проблем)

...