0

我在使用适用于 android 的 OpenGL-ES (1.0) 时遇到了一个问题,我无法理解。我有多个通过 OpenGL-ES 显示的 3D 对象,我决定使用以下方法提供一些材料:

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);
}

调整(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;
}
4

1 回答 1

1

那么如果你有一个“enableMaterial”为假的对象会发生什么?你有没有重置过材料?它似乎仍将应用于任何未来的对象。

于 2012-05-08T04:19:06.983 回答