我在使用Android的OpenGL-ES (1.0)时遇到了一个问题,我无法理解。我有多个3D对象通过OpenGL-ES显示,我决定使用一些材料。
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_... , ... , 0);
对于每一个我正在绘制的对象,我都是这样做的:
gl.glPushMatrix();
*make some adjustment to object*
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambient, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuse, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specular, 0);
gl.glPopMatrix();
其中 "环境"、"漫射 "和 "镜面 "对每个对象都是唯一的。
结果是,如果我在一个材料中使用了较多的红色环境色,这将影响到其他可见的对象,使其也显示出一点红色。
如下图所示,左边的三个物体中有两个被设置为在它的材质中获得更多的红色环境。右边的材质不应该发光,因为它的材质还没有,但还是发光了。(图片明显修改了一下,让它更清晰)。
我使用的每一个对象都有自己的材质类,由它的材质信息组成。
是否有什么地方遗漏了,或者这就是材质在OpenGL中的实际工作方式?
(我使用了一个方向灯照亮整个场景的一个方向)
编辑:为了更清楚地说明这一点,影响其他物体的不仅仅是环境色,例如,如果一个物体的材质在环境色、镜面色和漫反射色中的所有颜色中占0.2,靠近另一个具有较高数值的物体,例如镜面色,第一个物体也会被照亮。
编辑2:
这是绘制所有物体的功能
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
Enumeration<String> key = objects.keys();
while (key.hasMoreElements())
{
String k = key.nextElement();
if(objects.get(k).visible)
{
gl.glPushMatrix();
try
{
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturemanager._tm.get(k.trim())
.getTexture()[filter]);
}
catch(Exception e){};
adjust(gl, objects.get(k));
objects.get(k).draw(gl, 1);
gl.glPopMatrix();
}
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
在对象类中绘制时发生的情况如下
protected void draw(GL10 gl, int filter)
{
updatePhysics();
bounds.center.set(this);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, data.vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, data.textureBuffer);
gl.glNormalPointer(GL10.GL_FLOAT, 0, data.normalBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, data.numIndices,
GL10.GL_UNSIGNED_SHORT, data.indicesBuffer);
}
adjust(gl, objects.get(k))。 导致以下结果
// rotating, translating and scaling object
if (obj.blend)
{
gl.glEnable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DEPTH_TEST);
} else
{
gl.glDisable(GL10.GL_BLEND);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
if(obj.enableMaterial)
{
obj.getMaterial().enable(gl);
}
而在 obj.getMaterial().enable(gl)。 以下是我的材质类。
public void enable(GL10 gl)
{
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambient, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuse, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specular, 0);
gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, shininess);
}
其中环境、漫射、镜面和光泽度的变量设置如下。
public void setAmbient(float r, float g, float b, float a)
{
ambient[0] = r;
ambient[1] = g;
ambient[2] = b;
ambient[3] = a;
}
如果你有一个对象的 "enableMaterial "为false,会发生什么?你有没有重置过材质?似乎它仍然会应用于任何未来的对象。