对象上的错误材料

Posted

技术标签:

【中文标题】对象上的错误材料【英文标题】:Wrong material on objects 【发布时间】:2014-04-10 12:55:26 【问题描述】:

我有这个场景,一些物体(桌子,橱柜..)没有正确的颜色,我不知道为什么。我认为问题出在对象的正面/背面,但不知道如何纠正。

桌子的材质应该和椅子一样。

这是glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

这是glColorMaterial(GL_BACK, GL_AMBIENT_AND_DIFFUSE);

我希望桌子和椅子一样,正确的颜色在第一张图片中。

我的初始化:

void init()
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glShadeModel(GL_SMOOTH);

    GLfloat ambientColor[] =  0, 0, 0, 1 ;
    GLfloat diffuseColor[] =  0.1, 0.1, 0.1, 1 ;
    GLfloat specularColor[] =  0.1, 0.1, 0.1, 1 ;
    GLfloat lightPosition[] =  1, 1, 0, 1;


    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
    glLightfv(GL_LIGHT0, GL_AMBIENT, specularColor);

    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);


桌椅材质:

void setChairMaterial()
    GLfloat ambientChair[] =  0.1745,0.01175,0.01175 ;
    GLfloat diffuseChair[] =  0.61424,0.04136,0.04136 ;
    GLfloat specularChair[] =  0.727811,0.626959,0.626959 ;
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientChair);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseChair);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularChair);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.6);

glPushAttrib(GL_LIGHTING_BIT)glPopAttrib() 之间每次创建椅子和桌子之前都会调用此函数

画椅:

glPushMatrix();
glPushAttrib(GL_LIGHTING_BIT);
glTranslatef(8, 0, 8);
glRotatef(-90, 0, 1, 0);
glScalef(3, 3, 3);
setChairMaterial();
drawObj("chair.obj");
glPopAttrib();
glPopMatrix();

绘制表格:

glPushMatrix();
glPushAttrib(GL_LIGHTING_BIT);
glTranslatef(5, 0, 18);
glScalef(0.05, 0.05, 0.05);
setChairMaterial();
drawObj("table.obj");
glPopAttrib();
glPopMatrix();

函数drawObj(const char* path)GL_TRIANGLES绘制对象并设置法线

【问题讨论】:

如果您包含用于实际绘制桌椅的代码,这可能会有所帮助。如果在绘制椅子之前调用了 setChairMaterial,但是在绘制可能与它有关的桌子之前有一些东西会重置材料。您发布的代码在确定这一点时并不是非常有用。仅供参考,使用 glMaterial 等固定功能命令也已弃用,理想情况下,您应该为材质使用着色器。 @SeanBurton 添加了该部分!对此感到抱歉。 【参考方案1】:
glScalef(3, 3, 3);
...
glScalef(0.05, 0.05, 0.05);

小心那些。 Scaling applies to normals too:

OpenGL 规范需要法线为单位长度才能实现典型的光照效果。当前的 ModelView 矩阵转换法线。如果该矩阵包含比例变换,则变换后的法线可能不是单位长度,从而导致不理想的光照问题。

OpenGL 1.1 允许您调用 glEnable(GL_NORMALIZE),这将使所有法线在转换后成为单位长度。这通常使用平方根来实现,并且对于几何受限的应用程序来说可能很昂贵。

在 OpenGL 1.2 中可用的另一个解决方案(并且作为许多 1.1 实现的扩展)是 glEnable(GL_RESCALE_NORMAL)。 GL_RESCALE_NORMAL 不是通过计算平方根来使法线为单位长度,而是将转换后的法线乘以比例因子。如果原始法线是单位长度,并且 ModelView 矩阵包含统一缩放,则此乘法会将法线恢复为单位长度。

如果 ModelView 矩阵包含非均匀缩放,GL_NORMALIZE 是首选解决方案。

【讨论】:

以上是关于对象上的错误材料的主要内容,如果未能解决你的问题,请参考以下文章

Reactjs - 如何在 reactjs 材料表中加载和映射数据

setAdapter 上的空对象引用错误

React 对象不是 useEffect 上的函数错误

Flutter 上的 Xcode 构建错误任何对象错误和 openURL 错误

错误'AttributeError:'DataFrameGroupBy'对象没有属性'而数据框上的groupby功能

致命错误:在第 7 行调用非对象上的成员函数 prepare()。我想不通,为啥会出现此错误?