Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

11855 Posts in 1569 Topics- by 3045 Members - Latest Member: lensreslai

10. February 2012, 05:00:04 AM
Xith3D CommunityGeneral CategorySupport (Moderator: Marvin Fröhlich)Update of shared PolygonAttributes or xxxAttributes flawed?
Pages: [1]
Print
Author Topic: Update of shared PolygonAttributes or xxxAttributes flawed?  (Read 422 times)
rwb1977
Enjoying the stay
*
Offline Offline

Posts: 45


View Profile
« on: 01. April 2010, 09:09:00 PM »

Let's say I have two Shapes, with a shared TransparencyAttributes object.

If I happen to change the transparency at some point, then TransparencyAttributes status gets marked as changed. Then during culling, during the ShapeAtoms.updateStateUnits method for one atom, the "changed" status of the TransparencyAttributes gets set to false.  So one atom's state is updated, but the other atom's state map is not updated.  Isn't this a problem, or am I not using the concept of shared TransparencyAttributes correctly? (applies to all Appearance attributes).

thanks.
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4337


May the 4th, be with you...


View Profile
« Reply #1 on: 02. April 2010, 09:53:25 AM »

Is this a theoretical question? I don't see a problem here. It shouldn't be a problem anyway, because state units are centralized deep inside the xith core and this change will affect any using Appearance.

I have tested it and it works.

Marvin
Logged
horati
Global Moderator
Getting respectable
*****
Offline Offline

Posts: 393


View Profile
« Reply #2 on: 02. April 2010, 02:46:08 PM »

I think you guys must be thinking of different scenarios.  RWB, can you post test code that produces a problem?
Logged

Kevin
"It may not seem like a big deal, but ignorance of character encoding issues leads to insidious code rot akin to y2k."
http://stackoverflow.com/users/3474/sylvarking
rwb1977
Enjoying the stay
*
Offline Offline

Posts: 45


View Profile
« Reply #3 on: 02. April 2010, 10:04:16 PM »

So, when does an atom's translucency status get updated?

So whether an atom gets put in the opaque bin or transparent bin is determined by calling the ColoringStateUnit's isTranslucent() method.  This ColoringStateUnit's translucent variable gets set only when updateStateUnit is called.  However, updateStateUnit only gets called from the ShapeAtom's constructor (initially with opaque value) or in ShapeAntom.updateStateUnits() if the coloring and transparency attributes are default or null (mine are not).  If I have my own transparency attributes there, the updateStateUnit does not get called, so the ColoringStateUnit doesn't get translucent value set to true, so it doesn't get put in the transparent bin for proper sorting.

If I have a shape that is initially opaque.  Then it gets transparency attributes ... it seems it is still in the opaque bin.  It's isTranslucent value is still marked opaque.  And then if I change the transparency value, it doesn't get updated, or it does, but it's in the wrong bin so it looks very wrong depending on rest of scene.

Logged
rwb1977
Enjoying the stay
*
Offline Offline

Posts: 45


View Profile
« Reply #4 on: 02. April 2010, 10:58:53 PM »

In this version, the front sphere starts out opaque, but then after 7 seconds, gets transparency attributes, but as you can see, it just turns "dark" and sorting doesn't work.

In the second version the front two spheres start out opaque.  Then after 7 seconds, the front one gets a fixed transparency, it looks wrong, and the second one gets the same transparency attribute as the third one, but doesn't look the same as the third one.

I believe it's due to the atoms not getting their translucent status updated and put in the proper bin after having been instantiated.

Code:
/**
 * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
 *
 * Portions based on the Java3D interface, Copyright by Sun Microsystems.
 * Many thanks to the developers of Java3D and Sun Microsystems for their
 * innovation and design.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the 'Xith3D Project Group' nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE
 */
package org.xith3d.test.render;

import org.jagatoo.input.InputSystem;
import org.jagatoo.input.devices.components.Key;
import org.jagatoo.input.events.KeyReleasedEvent;
import org.jagatoo.opengl.enums.DrawMode;
import org.jagatoo.opengl.enums.FaceCullMode;
import org.openmali.vecmath2.Vector3f;
import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loop.CanvasFPSListener;
import org.xith3d.loop.opscheduler.Animator;
import org.xith3d.render.Canvas3D;
import org.xith3d.render.Canvas3DFactory;
import org.xith3d.resources.ResourceLocator;
import org.xith3d.scenegraph.BranchGroup;
import org.xith3d.scenegraph.PolygonAttributes;
import org.xith3d.scenegraph.TransparencyAttributes;
import org.xith3d.scenegraph.primitives.Cube;
import org.xith3d.scenegraph.primitives.Sphere;
import org.xith3d.schedops.movement.RotatableGroup;
import org.xith3d.schedops.movement.TransformationDirectives;
import org.xith3d.test.Xith3DTest;
import org.xith3d.test.util.TestUtils;
import org.xith3d.utility.commandline.BasicApplicationArguments;
import org.xith3d.utility.events.WindowClosingRenderLoopEnder;

@Xith3DTest.Description
(
    fulltext = {
                   "This test case demonstrates, how a semi-transparent",
                   "sphere can be rendered in Xith3D.."
               },
    authors = { "Marvin Froehlich (aka Qudus)" }
)
public class TransparentSphereTest2 extends Xith3DTest //InputAdapterRenderLoop
{
    private PolygonAttributes polyAttrs;
   
    @Override
    public void onKeyReleased( KeyReleasedEvent e, Key key )
    {
        switch ( key.getKeyID() )
        {
            case SPACE:
                polyAttrs.setFaceCullMode( FaceCullMode.values()[ (polyAttrs.getFaceCullMode().ordinal() + 1) % FaceCullMode.values().length ] );
                break;
           
            case ESCAPE:
                this.end();
                break;
        }
    }
    Sphere sphere3 = null;
    Sphere sphere2 = null;
    final TransparencyAttributes ta = new TransparencyAttributes( TransparencyAttributes.BLENDED, 0.3f );
   
    private BranchGroup createScene( Animator animator ) throws Exception
    {
        BranchGroup scene = new BranchGroup();
       
        Cube background = new Cube( 10.0f, "stone.jpg" );
        scene.addChild( background );
       
       
       
//        Cube cube = new Cube( 1.0f, "jplogo.jpg" );
//        scene.addChild( cube );
       
       
        sphere3 = new Sphere( 0.5f, 32, 32, "deathstar.jpg" );
       
        sphere3.getAppearance( true ).setPolygonAttributes( new PolygonAttributes(DrawMode.FILL, FaceCullMode.NONE, 0) );
     
        RotatableGroup rg3 = new RotatableGroup();
        rg3.setTranslation( new Vector3f(.25f, .25f, 3.0f));
        rg3.setTransformationDirectives( new TransformationDirectives( 0.025f, 0.025f, 0.0f));
        rg3.addChild( sphere3 );
       
        scene.addChild( rg3 );
       
        Sphere sphere = new Sphere( 1.0f, 32, 32, "deathstar.jpg" );
        sphere.getAppearance( true ).setTransparencyAttributes( ta );
       
        sphere2 = new Sphere( .75f, 32, 32, "deathstar.jpg" );
        sphere2.getAppearance( true ).setTransparencyAttributes( ta );
       
        /*
         * This is the important thing!!!
         *
         * The Sphere sill be rendered twice.
         * Once (and first) with back-face-culling,
         * and once with front-face-culling.
         */
        polyAttrs = new PolygonAttributes( PolygonAttributes.CULL_NONE );
        sphere.getAppearance().setPolygonAttributes( polyAttrs );
        sphere2.getAppearance().setPolygonAttributes( polyAttrs );
       
        RotatableGroup rg = new RotatableGroup( new TransformationDirectives( 0.05f, 0.05f, 0.0f ) );
        rg.addChild( sphere );
        scene.addChild( rg );
       
        RotatableGroup rg2 = new RotatableGroup();
        rg2.setTranslation( new Vector3f(.5f, 1.0f, 2f));
        rg2.setTransformationDirectives( new TransformationDirectives( 0.025f, 0.025f, 0.0f));
        rg2.addChild( sphere2 );
        scene.addChild( rg2 );
       
       
       
       
//        animator.addAnimatableObject( rg );
//        animator.addAnimatableObject( rg2 );
       
        new Thread("Change Transparency Thread")
        {
        public void run()
        {
        while (true)
        {
        ta.setTransparency((float)Math.random());
       
        try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
        }
       
        }
        }.start();
       
        return ( scene );
    }
    public static BranchGroup sceneBranch = null;
   
    public TransparentSphereTest2( BasicApplicationArguments arguments ) throws Throwable
    {
        super( arguments.getMaxFPS() );
       
        Xith3DEnvironment env = new Xith3DEnvironment( this );
       
        ResourceLocator resLoc = TestUtils.createResourceLocator();
       
        resLoc.createAndAddTSL( "textures" );
       
        sceneBranch = createScene( this.getAnimator() );
        env.addPerspectiveBranch( sceneBranch );
       
        Canvas3D canvas = Canvas3DFactory.create( arguments.getCanvasConstructionInfo(), getClass().getSimpleName() );
        env.addCanvas( canvas );
       
        canvas.addWindowClosingListener( new WindowClosingRenderLoopEnder( this ) );
        this.addFPSListener( new CanvasFPSListener( canvas ) );
       
        InputSystem.getInstance().registerNewKeyboardAndMouse( canvas.getPeer() );
    }
   
    public static boolean addShapeTransparency = true;
    public static long startTime = System.nanoTime();
    /**
     * {@inheritDoc}
     */
    @Override
    protected long nextIteration( boolean force )
    {
        if (addShapeTransparency && (System.nanoTime() - startTime)*1e-9f > 10)
        {
        addShapeTransparency = false;
       
//        sphere2.getAppearance( true ).setTransparencyAttributes( ta );
       
        final TransparencyAttributes ta = new TransparencyAttributes( TransparencyAttributes.BLENDED, 0.5f );
        sphere3.getAppearance( true ).setTransparencyAttributes( ta );
           
           
        }
       
        return ( super.nextIteration( force ) );
    }
   
    public static void main( String[] args ) throws Throwable
    {
    TransparentSphereTest2 test = new TransparentSphereTest2( parseCommandLine( args ) );
       
        test.begin();
    }
}

Code:
/**
 * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
 *
 * Portions based on the Java3D interface, Copyright by Sun Microsystems.
 * Many thanks to the developers of Java3D and Sun Microsystems for their
 * innovation and design.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the 'Xith3D Project Group' nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE
 */
package org.xith3d.test.render;

import org.jagatoo.input.InputSystem;
import org.jagatoo.input.devices.components.Key;
import org.jagatoo.input.events.KeyReleasedEvent;
import org.jagatoo.opengl.enums.DrawMode;
import org.jagatoo.opengl.enums.FaceCullMode;
import org.openmali.vecmath2.Vector3f;
import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loop.CanvasFPSListener;
import org.xith3d.loop.opscheduler.Animator;
import org.xith3d.render.Canvas3D;
import org.xith3d.render.Canvas3DFactory;
import org.xith3d.resources.ResourceLocator;
import org.xith3d.scenegraph.BranchGroup;
import org.xith3d.scenegraph.PolygonAttributes;
import org.xith3d.scenegraph.TransparencyAttributes;
import org.xith3d.scenegraph.primitives.Cube;
import org.xith3d.scenegraph.primitives.Sphere;
import org.xith3d.schedops.movement.RotatableGroup;
import org.xith3d.schedops.movement.TransformationDirectives;
import org.xith3d.test.Xith3DTest;
import org.xith3d.test.util.TestUtils;
import org.xith3d.utility.commandline.BasicApplicationArguments;
import org.xith3d.utility.events.WindowClosingRenderLoopEnder;

@Xith3DTest.Description
(
    fulltext = {
                   "This test case demonstrates, how a semi-transparent",
                   "sphere can be rendered in Xith3D.."
               },
    authors = { "Marvin Froehlich (aka Qudus)" }
)
public class TransparentSphereTest2 extends Xith3DTest //InputAdapterRenderLoop
{
    private PolygonAttributes polyAttrs;
   
    @Override
    public void onKeyReleased( KeyReleasedEvent e, Key key )
    {
        switch ( key.getKeyID() )
        {
            case SPACE:
                polyAttrs.setFaceCullMode( FaceCullMode.values()[ (polyAttrs.getFaceCullMode().ordinal() + 1) % FaceCullMode.values().length ] );
                break;
           
            case ESCAPE:
                this.end();
                break;
        }
    }
    Sphere sphere3 = null;
    Sphere sphere2 = null;
    final TransparencyAttributes ta = new TransparencyAttributes( TransparencyAttributes.BLENDED, 0.3f );
   
    private BranchGroup createScene( Animator animator ) throws Exception
    {
        BranchGroup scene = new BranchGroup();
       
        Cube background = new Cube( 10.0f, "stone.jpg" );
        scene.addChild( background );
       
       
       
//        Cube cube = new Cube( 1.0f, "jplogo.jpg" );
//        scene.addChild( cube );
       
       
        sphere3 = new Sphere( 0.5f, 32, 32, "deathstar.jpg" );
       
        sphere3.getAppearance( true ).setPolygonAttributes( new PolygonAttributes(DrawMode.FILL, FaceCullMode.NONE, 0) );
     
        RotatableGroup rg3 = new RotatableGroup();
        rg3.setTranslation( new Vector3f(.25f, .25f, 3.0f));
        rg3.setTransformationDirectives( new TransformationDirectives( 0.025f, 0.025f, 0.0f));
        rg3.addChild( sphere3 );
       
        scene.addChild( rg3 );
       
        Sphere sphere = new Sphere( 1.0f, 32, 32, "deathstar.jpg" );
        sphere.getAppearance( true ).setTransparencyAttributes( ta );
       
        sphere2 = new Sphere( .75f, 32, 32, "deathstar.jpg" );
//        sphere2.getAppearance( true ).setTransparencyAttributes( ta );
       
        /*
         * This is the important thing!!!
         *
         * The Sphere sill be rendered twice.
         * Once (and first) with back-face-culling,
         * and once with front-face-culling.
         */
        polyAttrs = new PolygonAttributes( PolygonAttributes.CULL_NONE );
        sphere.getAppearance().setPolygonAttributes( polyAttrs );
        sphere2.getAppearance().setPolygonAttributes( polyAttrs );
       
        RotatableGroup rg = new RotatableGroup( new TransformationDirectives( 0.05f, 0.05f, 0.0f ) );
        rg.addChild( sphere );
        scene.addChild( rg );
       
        RotatableGroup rg2 = new RotatableGroup();
        rg2.setTranslation( new Vector3f(.5f, 1.0f, 2f));
        rg2.setTransformationDirectives( new TransformationDirectives( 0.025f, 0.025f, 0.0f));
        rg2.addChild( sphere2 );
        scene.addChild( rg2 );
       
       
       
       
//        animator.addAnimatableObject( rg );
//        animator.addAnimatableObject( rg2 );
       
        new Thread("Change Transparency Thread")
        {
        public void run()
        {
        while (true)
        {
        ta.setTransparency((float)Math.random());
       
        try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
        }
       
        }
        }.start();
       
        return ( scene );
    }
    public static BranchGroup sceneBranch = null;
   
    public TransparentSphereTest2( BasicApplicationArguments arguments ) throws Throwable
    {
        super( arguments.getMaxFPS() );
       
        Xith3DEnvironment env = new Xith3DEnvironment( this );
       
        ResourceLocator resLoc = TestUtils.createResourceLocator();
       
        resLoc.createAndAddTSL( "textures" );
       
        sceneBranch = createScene( this.getAnimator() );
        env.addPerspectiveBranch( sceneBranch );
       
        Canvas3D canvas = Canvas3DFactory.create( arguments.getCanvasConstructionInfo(), getClass().getSimpleName() );
        env.addCanvas( canvas );
       
        canvas.addWindowClosingListener( new WindowClosingRenderLoopEnder( this ) );
        this.addFPSListener( new CanvasFPSListener( canvas ) );
       
        InputSystem.getInstance().registerNewKeyboardAndMouse( canvas.getPeer() );
    }
   
    public static boolean addShapeTransparency = true;
    public static long startTime = System.nanoTime();
    /**
     * {@inheritDoc}
     */
    @Override
    protected long nextIteration( boolean force )
    {
        if (addShapeTransparency && (System.nanoTime() - startTime)*1e-9f > 10)
        {
        addShapeTransparency = false;
       
        sphere2.getAppearance( true ).setTransparencyAttributes( ta );
       
        final TransparencyAttributes ta = new TransparencyAttributes( TransparencyAttributes.BLENDED, 0.25f );
        sphere3.getAppearance( true ).setTransparencyAttributes( ta );
           
           
        }
       
        return ( super.nextIteration( force ) );
    }
   
    public static void main( String[] args ) throws Throwable
    {
    TransparentSphereTest2 test = new TransparentSphereTest2( parseCommandLine( args ) );
       
        test.begin();
    }
}

Logged
horati
Global Moderator
Getting respectable
*****
Offline Offline

Posts: 393


View Profile
« Reply #5 on: 03. April 2010, 02:51:35 AM »

Awesome, thanks for two specific test cases.  I am not sufficiently versed to look at that code without a lot of research but am sure this will help Marvin immensely.
Logged

Kevin
"It may not seem like a big deal, but ignorance of character encoding issues leads to insidious code rot akin to y2k."
http://stackoverflow.com/users/3474/sylvarking
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4337


May the 4th, be with you...


View Profile
« Reply #6 on: 03. April 2010, 01:14:00 PM »

Thanks for the testcases.

So far xith didn't support changing the blended state after the shape was once rendered. Now I have added support for this and your testcases will work.

I have added your first testcase to xith-tk under the name "TransparentStateChangeTest. You may want to have a look at it to see some nice features, that you don't seem to know yet like the Interval class. You must not modify the scenegraph from within another thread like you did.

Marvin
Logged
rwb1977
Enjoying the stay
*
Offline Offline

Posts: 45


View Profile
« Reply #7 on: 06. April 2010, 04:40:14 PM »

Thanks!  This works in my app as well.  And thanks for the interval tip.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic