我正在用OpenGL 1.1编写编程的灯光效果。光和法线的东西有效。我只有错误的颜色
我想使用所用材料的环境颜色,而不是全局环境光。
当我使用此代码时,我有一个深灰色(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
2件事要做:我必须删除 glEnable(GL_COLOR_MATERIAL);
我还必须使用 (1.0f,1.0f,1.0f,1.0f) 设置全局环境