c++ - 物体 Material 错误

标签 c++ opengl freeglut

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

table 的 Material 应与椅子相同。

这是使用glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); enter image description here

这是与glColorMaterial(GL_BACK, GL_AMBIENT_AND_DIFFUSE); enter image description here

我希望 table 与椅子相同,正确的颜色在第一张图片中。

我的初始化:

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);

}

椅子和 table Material :

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() 之间每次创建椅子和 table 之前都会调用此函数

画椅:

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绘制对象并设置法线

最佳答案

glScalef(3, 3, 3);
...
glScalef(0.05, 0.05, 0.05);

小心那些。 Scaling applies to normals too:

The OpenGL specification needs normals to be unit length to achieve typical lighting results. The current ModelView matrix transforms normals. If that matrix contains a scale transformation, transformed normals might not be unit length, resulting in undesirable lighting problems.

OpenGL 1.1 lets you call glEnable(GL_NORMALIZE), which will make all normals unit length after they're transformed. This is often implemented with a square root and can be expensive for geometry limited applications.

Another solution, available in OpenGL 1.2 (and as an extension to many 1.1 implementations), is glEnable(GL_RESCALE_NORMAL). Rather than making normals unit length by computing a square root, GL_RESCALE_NORMAL multiplies the transformed normal by a scale factor. If the original normals are unit length, and the ModelView matrix contains uniform scaling, this multiplication will restore the normals to unit length.

If the ModelView matrix contains nonuniform scaling, GL_NORMALIZE is the preferred solution.

关于c++ - 物体 Material 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22988717/

相关文章:

c++ - 了解 GL_SHADER_STORAGE_BLOCK 绑定(bind)

opengl - 如何在OpenGL中绘制2D不规则曲线形状

c++ - OpenGL 错误。运行时立方体顶点位置错误?

c++ - 修复 LNK2019 : unresolved external symbol with freeglut

c++ - FreeGlut(类似于 OpenGL)正在拍摄我的桌面而不是绘制形状

c++ - error C2783 无法推断模板参数

c++ - 调用模板函数和非模板函数时的优先级是什么?

c - "openSuse and openGL"环境的示例程序

c++ - 我正在创建一个 C++ 程序,其中用户有 2 次尝试密码用户名组合的尝试。如果他们不能得到它,他们的程序就会停止

c++ - 从 C++ 到 ObjectPascal 的翻译检查哪个更好