OpenGL:在Python中加载模型时显示不正确
我有一个Blender模型,下面是我在Python中加载这个模型后渲染出来的图像。看起来模型的法线(也就是表面的方向)都搞乱了。我为每个顶点使用了正确的法线,并且导出的顺序也是对的。我在Blender控制台测试过,实际导出的文件里数据是正确的。
我知道在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)
绘制代码:
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 个回答
这看起来是你的法线出了问题。
self.normals
里的数据可能不对:你需要重新计算法线,确保在计算每个法线的时候,总是按照面周围的顶点逆时针的顺序来进行。
(另外,你应该在绘制每个顶点或面之前调用glNormal)
(还有,我不太清楚你在计算每个顶点的颜色时发生了什么:但要检查一下这是否造成了问题)
现在你在给顶点指定法线的时候,是在顶点之后指定的,而不是之前。简单来说,你是给顶点X指定了顶点X+1的法线。这是你当前代码中最重要的问题。
还有,那个 calculateVertexIntensity
是干嘛的?首先,你的代码里已经开启了光照,所以 glColor
会被忽略。不过看起来你在这里做了一些不必要的事情——OpenGL的固定功能渲染已经会根据 glLight*
和 glMaterial*
的设置来计算顶点的亮度了。
另外,你可能需要对你的 lightVector
进行归一化,我不确定OpenGL是否会为你自动处理这个。
(另外,确保查看一下最近的OpenGL特性;你现在使用的是一些过时的函数,可能会很快遇到性能瓶颈。首先要关注的是 vertex arrays
或 VBO
,接下来是 shaders
。)