I have encountered a problem working with OpenGL-ES (1.0) for android that i'm not able to wrap my head around. I have multiple 3D objects showing through OpenGL-ES that iv'e decided to give some material using:
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_... , ... , 0);
For each object i'm drawing I do it something like this:
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();
Where "ambient", "diffuse" and "specular" is unique to each object.
The result being that if I use a higher amount of red ambient for example in one material, this will affect the other visible object to also be showing of a little bit in red.
As seen below, two out of three objects to the left is set to get more red ambient in it's material. The material to the right shouldn't be glowing since it's material hasn't but still it does. (picture obviously a bit modified to make it clearer).
Every object i use has an own material class consisting of information regarding it's material.
Any idea of something iv'e missed or is this how materials acctually work in OpenGL?
(I use a direcitonal light lighting up the whole scene in a direction)
Edit: Just to make this clearer, it's not just ambient colors that affect other objects, if for example an object with a material that recievs 0.2 of all colors in ambient, specular and diffuse comes close to another object with higher values of for example specular, the first object will be much more lightned up as well.
Edit2:
This is the function for drawing all the objects
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);
What happens on draw in object class is following
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)); leads to following
// 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);
}
and where obj.getMaterial().enable(gl); will be the material for the object. Following is my material class
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);
}
Where the variables for ambient, diffuse, specular and shininess is set like following
public void setAmbient(float r, float g, float b, float a)
{
ambient[0] = r;
ambient[1] = g;
ambient[2] = b;
ambient[3] = a;
}