OpenGL: модель не выглядит правильно при загрузке в Python
У меня есть модель блендера, и ниже показано, как моя модель рендерится, когда я загружаю ее в python. Похоже, нормалы все испорчены. Я использую правильную нормаль для каждой вершины. Я экспортирую их в правильном порядке. Я проверяю это в консоли блендера, чтобы фактический файл экспорта содержал правильные данные.
Я знаю, что мне пришлось повернуть модель в python, потому что ось z отличается, поэтому я не уверен, что нормали z указывают в неправильном направлении.
Я использую Пиглет. Кто-нибудь когда-либо имел эту проблему раньше? Любые идеи о том, что я могу сделать, чтобы попытаться это исправить?
Я не уверен, если это проблема 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 Code:
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()
2 ответа
Прямо сейчас вы указываете нормаль после вершины, а не до, поэтому в основном вы указываете нормаль вершины X для вершины X+1. Это самый важный недостаток в текущем коде.
Кроме того, что это calculateVertexIntensity
? Во-первых, в вашем коде включено освещение, поэтому glColor
все равно будет проигнорировано, но все равно похоже, что вы пытались сделать что-то ненужное здесь - фиксированная функция рендеринга OpenGL уже вычислит интенсивность вершины на основе glLight*
настройки и glMaterial*
Настройки.
Кроме того, вы можете нормализовать lightVector
Я не уверен, собирается ли OpenGL нормализовать это для вас.
(Также не забудьте проверить последние функции OpenGL; вы используете устаревшие функции прямо сейчас, и из-за этого вы скоро столкнетесь с барьером производительности. Первое, на что тоже нужно обратить внимание, это vertex arrays
или же VBO
следующий shaders
.)
Это похоже на проблему с вашими нормальными.
Данные в self.normals
Возможно, это неправильно: вам следует пересчитать нормали, убедившись, что вы всегда используете последовательность вершин в направлении против часовой стрелки вокруг грани для вычисления каждой нормали.
(также вы должны вызывать glNormal перед рисованием каждой вершины / грани)
(также, я не знаю, что происходит, когда вы вычисляете цвет для каждой вершины: но убедитесь, что это не вызывает проблем)