Hi Yuri,

    After further investigation I've closed this bug.
The original AppearanceTest has the scenegraph structure

       BG
     /...\
   O1, ...O8, T1

contains 9 Shape3D O1, ...O8, T1
where Oi are opaque objects and T1 is transparency object.
By default Java3D will render the opaque object first
follow by transparency object with so it appears
correct.

In the modified AppearanceTest the user add an OrderedGroup above
the BranchGroup as follows:

       OG
       |
       BG
     /...\
   T1, ...T8, O1

The specification did not mention very clear but
OrderedGroup will override the rendering order of all child and
grand children under it. So the shape under it will not render
in two pass as expected: first opaque follow by transparent
object with depth buffer write disable.

Thus for the following scene graph

               OG
            /      \
           /         \
        BG1           BG2
     /  |  \  \     /  |  \  \
    T1  O1  T2 O2   T3  O3  T4 O4

where Ti are transparency object and Oi are opaque object.
Java3D will NOT render in order of O1, O2, T1, T2, O3, O4, T3, T4.
Instead the rendering order within the children of BG1
can be random since they are not direct children of OG
and it is a grandchildren of OG.
Similarly for the rendering order within the children of BG2.
One thing Java3D gaurantee is that all the child under BG1
will render BEFORE BG2.

To get the effect of what you want, it can be workaround
by using another OrderedGroup, group together
the opaque and transparent object explicitly, then set
the RenderingAttributes depthBufferWriteEnable to false
for all transparency Shape3D appearance as follows:


               OG
            /      \
           /         \
        OG1            OG2
       /   \          /   \
     BG1  BG2       BG3   BG4
    /  \  /  \     /  \   /  \
   O1  O2 T1 T2   O3  O4 T3  T4
          |  |           |   |
          R  R           R   R

Where BG1, BG3 contains all opaque objects
and BG2, BG4 contains all transparency objects.
R is RenderingAttributes with depthBufferWrite disable.

Attach is the modified AppearanceTest to show how
it works.


Thanks.

- Kelvin
------------------
Java 3D Team
Sun Microsystems Inc.


>Delivered-To: [EMAIL PROTECTED]
>MIME-Version: 1.0
>Content-MD5: qlL+zFoj8sN2ZQQc28otCQ==
>Date: Tue, 22 Jan 2002 11:45:48 -0800
>From: Kelvin Chung <[EMAIL PROTECTED]>
>Subject: Re: [JAVA3D] Transparency problem in 1.2.1
>Comments: To: [EMAIL PROTECTED]
>To: [EMAIL PROTECTED]
>
>Hi Yuri,
>
>  We can reproduce the bug and Bug 4626671 is filed
>for investigation.
>
>Thanks for your bug report.
>
>- Kelvin
>---------------
>Java 3D Team
>Sun Microsystems Inc.
>
>>From: Yuri Nikishkov <[EMAIL PROTECTED]>
>>To: "'Kelvin Chung'" <[EMAIL PROTECTED]>
>>Cc: [EMAIL PROTECTED]
>>Subject: RE: [JAVA3D] Transparency problem in 1.2.1
>>Date: Mon, 21 Jan 2002 11:13:10 -0500
>>MIME-Version: 1.0
>>
>>Kelvin,
>>
>>I have investigated the problem more and have been able to localize it. I
>>have an OrderedGroup object on top of my scene graph (not on the level of
>>transparent objects) and that seems to be the reason for transparency
>>problems. If I replace an OrderedGroup instance with a regular Group then
>>everything works fine. Moreover, I have been able to reproduce it on the
>>demo example. Please see  attached AppearanceTest.java from the Appearance
>>demo modified to demonstrate the problem. Orbit the scene and you can see
>>the transparent tetrahedron obstructing the red unlit tetrahedron (and/or
>>possibly others).
>>
>>Java3D v1.2.1_03 has exactly the same problem. v1.3beta1 still has the
>>problem but the rendering order seems to be different and so are the
>>obstructed objects (did not try to switch on the transparency sorting).
>>
>>Also I would appreciate very much if you can suggest some work-around for
>>this problem. I cannot get rid of OrderedGroup since I need it to enforce
>>rendering order to make some objects seen-through. And I need to be able to
>>correctly show the transparent shapes at least in one branch of the
>>OrderedGroup. Presently I can do one or the other but not both together.
>>
>>Thanks,
>>Yuri.
>
>===========================================================================
>To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
>of the message "signoff JAVA3D-INTEREST".  For general help, send email to
>[EMAIL PROTECTED] and include in the body of the message "help".
/*
 *      @(#)AppearanceTest.java 1.25 01/01/11 07:29:43
 *
 * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.image.TextureLoader;
import javax.media.j3d.*;
import javax.vecmath.*;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;

public class AppearanceTest extends Applet {

// YN   Set to true to demonstrate the bug
    private static final boolean SHOW_BUG = true;

    private java.net.URL texImage = null;
    private java.net.URL bgImage = null;

    private SimpleUniverse u = null;

    private BranchGroup createSceneGraph() {
        // Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

        // Create a bounds for the background and lights
        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

        // Set up the background
        TextureLoader bgTexture = new TextureLoader(bgImage, this);
        Background bg = new Background(bgTexture.getImage());
        bg.setApplicationBounds(bounds);
        objRoot.addChild(bg);

        // Set up the global lights
        Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
        Vector3f lDir1  = new Vector3f(-1.0f, -1.0f, -1.0f);
        Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);

        AmbientLight aLgt = new AmbientLight(alColor);
        aLgt.setInfluencingBounds(bounds);
        DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
        lgt1.setInfluencingBounds(bounds);
        objRoot.addChild(aLgt);
        objRoot.addChild(lgt1);

// YN    This only to see shapes better
    TransformGroup mrotgroup = new TransformGroup();
    mrotgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    mrotgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    MouseRotate mrotbeh = new MouseRotate(mrotgroup);
    mrotbeh.setSchedulingBounds(bounds);
    mrotgroup.addChild(mrotbeh);

        // Create a bunch of objects with a behavior and add them
        // into the scene graph.

        int row, col;
        Appearance[][] app = new Appearance[3][3];

        BranchGroup opaqueGroup = new BranchGroup();
        BranchGroup transparentGroup = new BranchGroup();



        for (row = 0; row < 3; row++)
            for (col = 0; col < 3; col++)
                app[row][col] = createAppearance(row * 3 + col);

        for (int i = 0; i < 3; i++) {
            double ypos = (double)(i - 1) * 0.6;
            for (int j = 0; j < 3; j++) {
                double xpos = (double)(j - 1) * 0.6;
//              objRoot.addChild(createObject(app[i][j], 0.12,  xpos, ypos));
                if ((j != 2) || (i != 1)) {
                    // skip transparent object
                    opaqueGroup.addChild(createObject(app[i][j], 0.12,
                                                      xpos, ypos));
                }
            }
        }

        // Freeze depth buffer write when rendering Transparency object
        Appearance transparentApp = app[1][2];
        RenderingAttributes renderingAttrs = new RenderingAttributes();
        renderingAttrs.setDepthBufferWriteEnable(false);
        transparentApp.setRenderingAttributes(renderingAttrs);

        // add transparent object
        transparentGroup.addChild(createObject(transparentApp, 0.12, 0.6, 0));

        // Use OrderedGroup to enforce ordering
        OrderedGroup og = new OrderedGroup();
        mrotgroup.addChild(og);
        // Render Opaque object first
        og.addChild(opaqueGroup);

        // Follow by Transparent object
        og.addChild(transparentGroup);

        // Let Java 3D perform optimizations on this scene graph.
//        objRoot.compile();

// YN attach ordered group
    if (SHOW_BUG) {
        OrderedGroup mordgroup = new OrderedGroup();
        mordgroup.addChild(mrotgroup);
        objRoot.addChild(mordgroup);
    } else
// YN attach rotational group
        objRoot.addChild(mrotgroup);

        return objRoot;
    }


    private Appearance createAppearance(int idx) {
        Appearance app = new Appearance();

        // Globally used colors
        Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
        Color3f white = new Color3f(1.0f, 1.0f, 1.0f);

        switch (idx) {
        // Unlit solid
        case 0:
            {
                // Set up the coloring properties
                Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f);
                ColoringAttributes ca = new ColoringAttributes();
                ca.setColor(objColor);
                app.setColoringAttributes(ca);
                break;
            }


        // Unlit wire frame
        case 1:
            {
                // Set up the coloring properties
                Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f);
                ColoringAttributes ca = new ColoringAttributes();
                ca.setColor(objColor);
                app.setColoringAttributes(ca);

                // Set up the polygon attributes
                PolygonAttributes pa = new PolygonAttributes();
                pa.setPolygonMode(pa.POLYGON_LINE);
                pa.setCullFace(pa.CULL_NONE);
                app.setPolygonAttributes(pa);
                break;
            }

        // Unlit points
        case 2:
            {
                // Set up the coloring properties
                Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f);
                ColoringAttributes ca = new ColoringAttributes();
                ca.setColor(objColor);
                app.setColoringAttributes(ca);

                // Set up the polygon attributes
                PolygonAttributes pa = new PolygonAttributes();
                pa.setPolygonMode(pa.POLYGON_POINT);
                pa.setCullFace(pa.CULL_NONE);
                app.setPolygonAttributes(pa);

                // Set up point attributes
                PointAttributes pta = new PointAttributes();
                pta.setPointSize(5.0f);
                app.setPointAttributes(pta);
                break;
            }

        // Lit solid
        case 3:
            {
                // Set up the material properties
                Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
                app.setMaterial(new Material(objColor, black, objColor,
                                             white, 80.0f));
                break;
            }

        // Texture mapped, lit solid
        case 4:
            {
                // Set up the texture map
                TextureLoader tex = new TextureLoader(texImage, this);
                app.setTexture(tex.getTexture());

                TextureAttributes texAttr = new TextureAttributes();
                texAttr.setTextureMode(TextureAttributes.MODULATE);
                app.setTextureAttributes(texAttr);

                // Set up the material properties
                app.setMaterial(new Material(white, black, white, black, 1.0f));
                break;
            }

        // Transparent, lit solid
        case 5:
            {
                // Set up the transparency properties
                TransparencyAttributes ta = new TransparencyAttributes();
                ta.setTransparencyMode(ta.BLENDED);
                ta.setTransparency(0.6f);
                app.setTransparencyAttributes(ta);

                // Set up the polygon attributes
                PolygonAttributes pa = new PolygonAttributes();
                pa.setCullFace(pa.CULL_NONE);
                app.setPolygonAttributes(pa);

                // Set up the material properties
                Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
                app.setMaterial(new Material(objColor, black, objColor,
                                             black, 1.0f));
                break;
            }

        // Lit solid, no specular
        case 6:
            {
                // Set up the material properties
                Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
                app.setMaterial(new Material(objColor, black, objColor,
                                             black, 80.0f));
                break;
            }

        // Lit solid, specular only
        case 7:
            {
                // Set up the material properties
                Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
                app.setMaterial(new Material(black, black, black,
                                             white, 80.0f));
                break;
            }

        // Another lit solid with a different color
        case 8:
            {
                // Set up the material properties
                Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f);
                app.setMaterial(new Material(objColor, black, objColor,
                                             white, 80.0f));
                break;
            }

        default:
            {
                ColoringAttributes ca = new ColoringAttributes();
                ca.setColor(new Color3f(0.0f, 1.0f, 0.0f));
                app.setColoringAttributes(ca);
            }
        }

        return app;
    }


    private Group createObject(Appearance app, double scale,
                               double xpos, double ypos) {

        // Create a transform group node to scale and position the object.
        Transform3D t = new Transform3D();
        t.set(scale, new Vector3d(xpos, ypos, 0.0));
        TransformGroup objTrans = new TransformGroup(t);

        // Create a second transform group node and initialize it to the
        // identity.  Enable the TRANSFORM_WRITE capability so that
        // our behavior code can modify it at runtime.
        TransformGroup spinTg = new TransformGroup();
        spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        // Create a simple shape leaf node and set the appearance
        Shape3D shape = new Tetrahedron();

        shape.setAppearance(app);

        // add it to the scene graph.
        spinTg.addChild(shape);

        // Create a new Behavior object that will perform the desired
        // operation on the specified transform object and add it into
        // the scene graph.
        Transform3D yAxis = new Transform3D();
        Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
                                        0, 0,
                                        5000, 0, 0,
                                        0, 0, 0);

        RotationInterpolator rotator =
            new RotationInterpolator(rotationAlpha, spinTg, yAxis,
                                     0.0f, (float) Math.PI*2.0f);

        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

        rotator.setSchedulingBounds(bounds);

        // Add the behavior and the transform group to the object
        objTrans.addChild(rotator);
        objTrans.addChild(spinTg);

        return objTrans;
    }


    public AppearanceTest() {
    }

    public AppearanceTest(java.net.URL bgurl, java.net.URL texurl) {
        bgImage = bgurl;
        texImage = texurl;
    }

    public void init() {
        if (bgImage == null) {
            // the path to the image for an applet
            try {
                bgImage = new java.net.URL(getCodeBase().toString() +
                                           "../images/bg.jpg");
            }
            catch (java.net.MalformedURLException ex) {
                System.out.println(ex.getMessage());
                System.exit(1);
            }
        }

        if (texImage == null) {
            // the path to the image for an applet
            try {
                texImage = new java.net.URL(getCodeBase().toString() +
                                            "../images/apimage.jpg");
            }
            catch (java.net.MalformedURLException ex) {
                System.out.println(ex.getMessage());
                System.exit(1);
            }
        }
        setLayout(new BorderLayout());
        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();

        Canvas3D c = new Canvas3D(config);
        add("Center", c);

        // Create a simple scene and attach it to the virtual universe
        BranchGroup scene = createSceneGraph();
        u = new SimpleUniverse(c);

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        u.getViewingPlatform().setNominalViewingTransform();

        u.addBranchGraph(scene);
    }

    public void destroy() {
    u.removeAllLocales();
    }


    //
    // The following allows AppearanceTest to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
        // the path to the image file for an application
        java.net.URL bgurl = null;
        java.net.URL texurl = null;
        try {
          bgurl = new java.net.URL("file:../images/bg.jpg");
          texurl = new java.net.URL("file:../images/apimage.jpg");
        }
        catch (java.net.MalformedURLException ex) {
            System.out.println(ex.getMessage());
            System.exit(1);
        }
        new MainFrame(new AppearanceTest(bgurl, texurl), 700, 700);
    }
}

Reply via email to