c++ - 如何使用 Material 的环境色代替灯光的全局环境色? (OpenGL 1)

标签 c++ opengl light opengl-compat opengl-1.x

我正在用 OpenGL 1.1 编写我的程序的灯光效果。灯光和法线的东西起作用了。我只有一个错误的颜色

我想使用已用 Material 的环境颜色,而不是全局环境光。

当我使用此代码时,我有一个深灰色 (64, 64, 64) 用于遮光面,但从来没有黑色 (0, 0, 0)。

这是伪代码:

void Init()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
SetAmbientLight(64, 64, 64); // global value
material.ambientColor = VECTOR3F(0,0,0); // black color, other are default values of OpenGL
}

void SetAmbientLight(U8 r, U8 g, U8 b)
{
    //  Ambient Light is a global value
    const GLfloat inv = 1.0f / 255.0f;
    const GLfloat ambientColor[] = {r * inv, g * inv, b * inv, 1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
}


void Render()
{
    UseMaterial(material);
    RenderTexturedObject();
    UseMaterial(NULL);
    UseLights();
}

void UseMaterial(MATERIAL *materialdata)
{
    if (materialdata)
    {
        const VECTOR3F& ambiantColor = materialdata->ambiantColor;
        const VECTOR3F& diffuseColor = materialdata->diffuseColor;
        const VECTOR3F& specularColor = materialdata->specularColor;
        const float& shiness = materialdata->shiness;
        const VECTOR3F& emissiveColor = materialdata->emissiveColor;

        const GLfloat amb[4] = {ambiantColor.x, ambiantColor.y, ambiantColor.z, 1.0f};
        const GLfloat diff[4] = {diffuseColor.x, diffuseColor.y, diffuseColor.z, 1.0f};
        const GLfloat spec[4] = {specularColor.x, specularColor.y, specularColor.z, 1.0f};
        const GLfloat emi[4] = {emissiveColor.x, emissiveColor.y, emissiveColor.z, 1.0f};

        glEnable(GL_COLOR_MATERIAL);

        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shiness);
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emi);
    }
    else
    {
        glDisable(GL_COLOR_MATERIAL);
    }
}

void RenderTexturedObject()
{
  FillVertexBuffer(mesh, t);
  FillTexCoordBuffer(mesh);
  FillColorBuffer(mesh, 255, 255, 255);

  glColor3ub(255, 255, 255);

  // Use normals only when lighting is used
  if (IsLightingEnabled() && s_nbLights > 0)
  {
    FillNormalBuffer(mesh, t);
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 12, gNormals);
  }

  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, tex);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);

  glVertexPointer(3, GL_FLOAT, 0, gVertices);
  glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);
  glColorPointer(3, GL_UNSIGNED_BYTE, 0, gColors);
  glDrawElements(GL_TRIANGLES, 3 * mesh->nbtriangles, GL_UNSIGNED_SHORT, gIndexes);

  glDisable (GL_TEXTURE_2D);
  if (IsLightingEnabled() && s_nbLights > 0)
  {
    glDisableClientState(GL_NORMAL_ARRAY);
  }
}

void UseLights()
{
        for (int lightIdx = GL_LIGHT0; lightIdx <= GL_LIGHT7; lightIdx++)
        {
            const int idx = lightIdx - GL_LIGHT0;
            const LIGHT_DATA& lightdata = s_lightsData[idx];

            const VECTOR3F& ambiantColor = lightdata.ambiantColor;
            const VECTOR3F& diffuseColor = lightdata.diffuseColor;
            const VECTOR3F& specularColor = lightdata.specularColor;
            const VECTOR3F& direction = lightdata.direction;

            const GLfloat amb[4] = {ambiantColor.x, ambiantColor.y, ambiantColor.z, 1.0f};
            const GLfloat diff[4] = {diffuseColor.x, diffuseColor.y, diffuseColor.z, 1.0f};
            const GLfloat spec[4] = {specularColor.x, specularColor.y, specularColor.z, 1.0f};
            const GLfloat dir[4] = {-direction.x, -direction.y, -direction.z, 0.0f}; // always use w=0.0 for a direction

            glLightfv(lightIdx, GL_AMBIENT, amb);
            glLightfv(lightIdx, GL_DIFFUSE, diff);
            glLightfv(lightIdx, GL_SPECULAR, spec);
            glLightfv(lightIdx, GL_POSITION, dir);
            glLightf(lightIdx, GL_SPOT_EXPONENT, 0.0f);
            glLightf(lightIdx, GL_SPOT_CUTOFF, 180.0f);
        }

}

最佳答案

解决方案在这里:https://www.sjbaker.org/steve/omniv/opengl_lighting.html

要做的两件事: 我必须删除 glEnable(GL_COLOR_MATERIAL);

我还必须使用 (1.0f,1.0f,1.0f,1.0f) 设置全局环境

关于c++ - 如何使用 Material 的环境色代替灯光的全局环境色? (OpenGL 1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46974175/

相关文章:

c++ - 我无法使图像中的透明度起作用

ios - 在没有私有(private) API 的情况下在 iOS 中获取光传感器值?

java - Libgdx Box2D 灯,在 Android 设备上看起来不同,光的轮廓很奇怪

c++ - 由围绕矩形顺时针方向移动的数字组成的图案(长度和宽度每次都减小)

c++ - 在C++中保留字符串中所需的字符

c++ - 在 Eigen 中提高 SelfAdjointEigenSolver 的精度

c++ - C++ : scoping, 中的工厂方法模式实现和指针与引用

c - GLUT 跟踪按下的键(当按下 SHIFT 键并在没有它的情况下释放时)

java - 在 Java 中加载 OpenGL 和 LWJGL3 中的纹理

windows-8 - 适用于 Windows 8 桌面的虚拟光传感器