×

Discussion Board

Results 1 to 2 of 2
  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    2

    Nokia M3G implementation - bug with Alpha/Blending ? [solved]

    Hello,

    I try to build a 2D tile-based mapping application (with GPS support) by using M3G.

    M3D is use for the convenience, mainly for the zoom-in/zoom-out
    it's seems to be the best way to use "a native code" for resizing the tiles.

    I read a XML file (by using an implementation of xmlpull http://www.xmlpull.org)

    - with the position, size, z-index and the filename of each tile
    - with the position of some "spots" where we need to start some medias when the user cross the radius of them

    For each tile (viewable in the current viewport), I create a mesh and apply the image by a texture.
    to implement the z-index, I use the z position of the mesh and enable the depth buffer

    On top of these tiles, I show each spot by a circle (texture) by the same way and by using a higher z-index.

    I use a thread to update the tiles and spots when we change the current viewport (pan/move the map)

    Each mesh use this CompositingMode:

    Code:
    compMode = new CompositingMode();
    compMode.setAlphaThreshold(0.01f);
    compMode.setAlphaWriteEnable(true);
    compMode.setColorWriteEnable(true);
    compMode.setDepthWriteEnable(true);
    compMode.setDepthTestEnable(true);
    compMode.setDepthOffset(-<z-index>,1.0f);
    compMode.setBlending(CompositingMode.ALPHA);
    But anyway with:

    Code:
    compMode = new CompositingMode();
    compMode.setAlphaThreshold(0.01f);
    compMode.setBlending(CompositingMode.ALPHA);
    It's the same result

    And this Background:

    Code:
    myBackground = new Background();
    myBackground.setColor(0xffffcc);
    myBackground.setColorClearEnable(true);
    myBackground.setDepthClearEnable(true);
    The render:

    Code:
    myGraphics3D.bindTarget(g,true,Graphics3D.OVERWRITE);
    myGraphics3D.setViewport(screen_x, screen_y, screen_width, screen_height);
    myGraphics3D.render(myWorld);
    myGraphics3D.releaseTarget();
    You can see the result here:
    http://download.fileshack.us/.../m3d-nokia-bug.png

    Like you can see the main issue seems to be in the blending

    It's look like a bug with the cache about the color of the lower layer/background (like the color buffer)

    And when we update this layer (tiles) the cache is not updating, some time it's fine and some time it's like on the screenshot.

    (like if I move the map and come back at the same place, after the update of some tiles behind the spot)

    It's append only when I use a texture with an alpha channel's value between 0 and 1 but not 0 or 1.

    When OpenGL need to blend the tile's color + spot's alpha + spot's color

    And only with your emulator (S60 Platform 3rd Ed, FP2) and on cell phone (N70 and N81) but not with the emulator include in the Sun Java Wireless Toolkit.

    * Each texture have power-of-two dimensions (256x256)
    * Tile images : PNG - 8bpp (RGB)
    * Spot images : PNG - 32bpp (RGBA)

    Thank you for your help

    Francois Weykmans
    Last edited by fanfoi; 2008-05-13 at 22:53.

  2. #2
    Registered User
    Join Date
    Feb 2008
    Posts
    2

    Re: Nokia M3G implementation - bug with Alpha/Blending ? [solved]

    I found the "bug"

    The Alpha channel depends on the depth buffer, but it depends also on the node order (at render time)

    And even if I use five groups like that:
    Code:
    myWorld.addChild(camera);
    myWorld.setActiveCamera(camera);
    ...
    myRootGroup = new Group();
    myRootGroup.setUserID(ROOT_GROUP_ID);
    myWorld.addChild(myRootGroup);
            
    myTilesGroup = new Group();
    myTilesGroup.setUserID(TILES_GROUP_ID);
    myRootGroup.addChild(myTilesGroup);
            
    mySpotsGroup = new Group();
    mySpotsGroup.setUserID(SPOTS_GROUP_ID);
    myRootGroup.addChild(mySpotsGroup);
            
    myGpsCoordsGroup = new Group();
    myGpsCoordsGroup.setUserID(GPSCOORDS_GROUP_ID);
    myRootGroup.addChild(myGpsCoordsGroup);
            
    myGpsDotGroup = new Group();
    myGpsDotGroup.setUserID(GPSDOT_GROUP_ID);
    myRootGroup.addChild(myGpsDotGroup);
    The Nokia's implementation don't follow this order and it's not a bug!

    It's strange because it's only if (alpha > 0) && (alpha < 1) (depth buffer ???)

    In the specification:
    Code:
    class Group
    
    public void addChild(Node child)
    
        Adds the given node to this Group, potentially changing the order and indices of the previously added children. The position at which the node is inserted among the existing children is deliberately left undefined. This gives implementations the freedom to select a data structure that best fits their needs, instead of mandating a particular kind of data structure.
    "The position at which the node is inserted among the existing children is deliberately left undefined. This gives implementations the freedom to select a data structure that best fits their needs"

    A workaround:

    The best way to control the render order is to use the immediate mode.

    Example:
    Code:
    // Replace:
    //myGraphics3D.render(myWorld);
    // By:
    renderWorld(myGraphics3D,myWorld);
    Code:
    private void renderWorld( Graphics3D graphics3D, World world ) {
    
        graphics3D.clear(world.getBackground());
        Camera camera = world.getActiveCamera();
    
        Transform tmp_transform = new Transform();
        camera.getTransformTo(world,tmp_transform);
        graphics3D.setCamera(camera,tmp_transform);
    
        // TODO: add Lights
        //graphics3D.resetLights();
    
        renderGroup(graphics3D,world,world);
    }
    
    private void renderGroup( Graphics3D graphics3D, World world, Group group ) {
    
        int childCount = group.getChildCount();
        Node node = null;
        for(int i=0;i<childCount;i++) {
            node = group.getChild(i);
            if(node instanceof Group) {
                renderGroup(graphics3D, world, (Group)node);
            }
            else if(node instanceof Sprite3D || node instanceof Mesh) {
                renderNode(graphics3D, world, node);
            }  
        }
    }
    
    private void renderNode( Graphics3D graphics3D, World world, Node node ) {
    
        Transform tmp_transform = new Transform();
        if(node.getTransformTo(world,tmp_transform)) {
            graphics3D.render(node,tmp_transform);
        }
        else {
            graphics3D.render(node,null);
        }
    }
    Francois Weykmans
    Last edited by fanfoi; 2008-05-13 at 23:02.

Similar Threads

  1. ###Upgrading Firmware###
    By zahid44 in forum General Development Questions
    Replies: 27
    Last Post: 2008-10-21, 07:17
  2. Nokia Image Converter
    By davidpurdie in forum General Development Questions
    Replies: 0
    Last Post: 2004-02-18, 15:31
  3. Nokia Mobile VPN Client
    By marcyl in forum Symbian Networking & Messaging (Closed)
    Replies: 1
    Last Post: 2003-12-01, 14:47

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×