Android 如何清除Opengl ES材质属性以避免重复使用不正确的材质?

Android 如何清除Opengl ES材质属性以避免重复使用不正确的材质?,android,opengl-es,3d,scenegraph,Android,Opengl Es,3d,Scenegraph,我正在开发一个Android opengl库,遇到了一个小问题。我知道这件事很容易解决,但我很难找到它。简而言之,我正在开发一个3d场景图库,它基于非常轻量级和非常棒的场景2D场景图库。深入解释结构可能需要很长时间,但本质上树中的每个节点都有一个加载(GL10 gl)方法,其中会发生任何纹理和/或材质初始化。然后有用于形状节点的draw()方法,也有用于材质的killDraw()方法 我的材质类旨在为像我这样来自3d建模应用程序(3ds max for me)的用户提供友好的界面。问题是: 我在

我正在开发一个Android opengl库,遇到了一个小问题。我知道这件事很容易解决,但我很难找到它。简而言之,我正在开发一个3d场景图库,它基于非常轻量级和非常棒的场景2D场景图库。深入解释结构可能需要很长时间,但本质上树中的每个节点都有一个加载(GL10 gl)方法,其中会发生任何纹理和/或材质初始化。然后有用于形状节点的draw()方法,也有用于材质的killDraw()方法

我的材质类旨在为像我这样来自3d建模应用程序(3ds max for me)的用户提供友好的界面。问题是:

我在场景中创建了一些3d形状:

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);
除了为第一个形状创建的红色材质不仅应用于第一个形状,而且还应用于第二个形状,尽管它有自己的纹理

以下是相关的材料方法

@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);
}
如果我在场景中放置10个形状,并在形状1和5中添加彩色材质,那么1-5是第一个材质,6-10是第二个材质

我想我应该能够做的是调用类似gl.glLoadIdentity()的东西并清除它,但对于材质参数,我找不到它。有人能帮忙吗

谢谢


对不起,篇幅太长了,我尽量简明扼要。如果有人对库或更多信息感兴趣,我在git hub上

您创建的每个对象都确切地知道它使用的是什么材质属性。只需让它在堆栈上推/弹出相关状态。

谢谢您的回复,但我已经在这样做了。I pushMatrix()然后调用节点渲染方法,然后调用popMatrix()。我已经找到了代码的一部分,在那里我应该有另一个push/pop来迭代组中的子对象,但这并没有解决问题…push和pop应该适用于颜色和材质参数以及翻译,对吗?如果我使用的是processing,我会使用pushStyle()和popStyle()方法。@Jon,我不知道你在说什么
glPushMatrix
完全按照它所说的做,它推动您指定的转换矩阵,仅此而已。在您粘贴的代码中,您正在更改材质,而没有在最后恢复材质,这就是使用
glPushAttrib
glu LIGHTING\u BIT
的原因。当然,这是一种糟糕的方法,即使是非常简单的场景,您也会有难以置信的开销。最好的方法是查看您正在做的事情并自己还原,而不使用GL堆栈。opengl es不支持glPushAttrib。。。很抱歉造成误解,我对opengl还相当陌生。我已经按照你的建议做了。现在,在我的killDraw()方法中,我调用了一个默认材质。只需再次调用glMaterialfv()四次,以抵消之前对我的材料所做的四次调用,这是一种好的做法吗?谢谢again@Jon,那么您必须在某个地方为下一个对象设置材质,或者在下一个对象的
绘图
中,或者在上一个对象的
杀死
中。