OpenGL:在Python中加载模型时显示不正确

2 投票
2 回答
604 浏览
提问于 2025-04-16 07:03

我有一个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()

alt text

2 个回答

0

这看起来是你的法线出了问题。

self.normals里的数据可能不对:你需要重新计算法线,确保在计算每个法线的时候,总是按照面周围的顶点逆时针的顺序来进行。

(另外,你应该在绘制每个顶点或面之前调用glNormal)

(还有,我不太清楚你在计算每个顶点的颜色时发生了什么:但要检查一下这是否造成了问题)

6

现在你在给顶点指定法线的时候,是在顶点之后指定的,而不是之前。简单来说,你是给顶点X指定了顶点X+1的法线。这是你当前代码中最重要的问题。

还有,那个 calculateVertexIntensity 是干嘛的?首先,你的代码里已经开启了光照,所以 glColor 会被忽略。不过看起来你在这里做了一些不必要的事情——OpenGL的固定功能渲染已经会根据 glLight*glMaterial* 的设置来计算顶点的亮度了。

另外,你可能需要对你的 lightVector 进行归一化,我不确定OpenGL是否会为你自动处理这个。

(另外,确保查看一下最近的OpenGL特性;你现在使用的是一些过时的函数,可能会很快遇到性能瓶颈。首先要关注的是 vertex arraysVBO,接下来是 shaders。)

撰写回答