0

I am working on an Android opengl lib and have hit a small issue. I know it is something easy to fix but I am having a lot of trouble tracking it down. In a nut shell, I am working on a 3d scene graph library which is based on the really light weight and awesome Scenario 2D scene graph library. It would take too long to explain the structure in depth, but essentially every node in the tree has a load(GL10 gl) method in which any texture and/or material initialization happens. There are then draw() methods for shape nodes, and also killDraw() for materials.

My material classes are intended to be user friendly for people like me who come from a 3d modeling app program standpoint (3ds max for me). Here is the issue:

I create a few 3d shapes in a scene:

FXShape shape4 = new FXShape();
shape4.setShape(new Model("cup.obj"));

Material material = new Material();
material.setAmientAndDiffuse(1,0,0,1);          
shape5.addMaterial(material);

add(shape4);

FXShape shape5 = new FXShape();
shape5.setShape(new Cube());
shape5.addMaterial(new TextureMaterial(shape5.getShape(),R.drawable.crate));
add(shape5);

Everything works great except that the red material which is create for the first shape is applying not only to that one, but the second shape even though it has it's own texture.

here are the relevant Material methods

@Override
public void loadMaterial(GL10 gl) { 
}

@Override
public void draw(GL10 gl){
    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,his.ambientBuffer);
    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, this.diffuseBuffer);
    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, this.specularBuffer);
    gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, Math.min(shininess, 128));    
}

@Override
public void killDraw(GL10 gl) {
    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}

If I put 10 shapes in the scene and add a colored material to shape 1 and 5, then 1-5 are the first material, and 6-10 are the second.

What I thought I should be able to do is just call something like gl.glLoadIdentity() and clear it out, but I can't find that for the material parameters. Can any one help?

thanks

sorry for the length, I tried to be as concise as possible. If anyone is interested in the lib or more info, I'm on git hub https://github.com/ghostandthemachine/DroidGraph

Jon Rose
  • 1,457
  • 1
  • 15
  • 25

1 Answers1

0

Each object you create knows exactly what material properties it's using. Just have it push/pop the relevant state on the stack.

Blindy
  • 65,249
  • 10
  • 91
  • 131
  • thanks for the reply, but I am already doing that. I pushMatrix() then call the node render methods then popMatrix(). I have found a part of the code where I should have had another push/pop for iterating over children in a group, but that hasn't fixed the issue...Push and Pop should work for color and material params as well as translations right? If I was using processing I would use the pushStyle() and popStyle() methods. – Jon Rose Apr 19 '11 at 17:01
  • @Jon, I have no idea what you're talking about. `glPushMatrix` does exactly what it says, it pushes the transormation matrix you specify, nothing more. In the code you pasted you're changing the **materials** without restoring them at the end, and that's where `glPushAttrib` with `GL_LIGHTING_BIT` comes in. – Blindy Apr 19 '11 at 17:10
  • Of course this is a terrible way to do this, you'd have an incredible amount of overhead even for very simple scenes. The best way would be to actually look at what you're doing and revert it yourself, without using the GL stack. – Blindy Apr 19 '11 at 17:12
  • glPushAttrib is not supported in opengl es... Sorry for the misunderstanding, I am fairly new to opengl. I have done what I think you suggested. Now in my killDraw() method I am calling on a default material. Is this good practice to just call the glMaterialfv() four times again to counter the four calls made previously to my material? thanks again – Jon Rose Apr 19 '11 at 17:36
  • @Jon, Well you have to set the material for the next object somewhere, either in the `draw` of the next object, or in the `kill` of the previous object. – Blindy Apr 19 '11 at 17:41
  • @blindy duh, makes sense. I just wasn't being thorough. Works well now, thanks for the help – Jon Rose Apr 19 '11 at 17:43