Package com.ardor3d.example.renderer

Source Code of com.ardor3d.example.renderer.CombinerExample

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.example.renderer;

import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.DataMode;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.StripBox;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
import com.ardor3d.util.geom.MeshCombiner;
import com.ardor3d.util.stat.MultiStatSample;
import com.ardor3d.util.stat.StatCollector;
import com.ardor3d.util.stat.StatType;

/**
* An example showing use of MeshCombiner to weld together a bunch of boxes into a single mesh.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.renderer.CombinerExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/renderer_CombinerExample.jpg", //
maxHeapMemory = 64)
public class CombinerExample extends ExampleBase {

    private final Node origNode = new Node("orig");
    private final BasicText[] text = new BasicText[3];
    private final int edge = 50;

    private boolean showMerged = true;
    private boolean useVBO = false;

    public static void main(final String[] args) {
        // turn on stats so we can use them to calc tris/sec
        System.setProperty("ardor3d.stats", "true");
        start(CombinerExample.class);
    }

    @Override
    protected void initExample() {
        // make a scene node to hold our meshes.
        final Node scene = new Node();
        scene.getSceneHints().setCullHint(CullHint.Dynamic);
        _root.attachChild(scene);

        // Generate many boxes and place them in a 2D grid pattern, under the origNode.
        Mesh mesh;
        for (int i = 0, max = edge * edge; i < max; i++) {
            mesh = new StripBox("stripbox" + i, new Vector3(), .5, .5, .5);
            mesh.setTranslation(new Vector3(i % edge, i / edge, 0));

            mesh.setModelBound(new BoundingBox());
            mesh.setSolidColor(ColorRGBA.randomColor(null));
            origNode.attachChild(mesh);
        }

        // Create a single Mesh from the origNode and its children.
        final Mesh merged = MeshCombiner.combine(origNode);
        // attach to scene.. default will be to show the merged version first
        scene.attachChild(merged);

        // Use VBO, if indicated. This improves the rendering speed of the merged mesh.
        // Note that sometimes it is not efficient/possible to turn on VBO for tons of small meshes, but works well for
        // a single larger combined mesh.
        if (useVBO) {
            merged.getSceneHints().setDataMode(DataMode.VBO);
        }

        // and a texture, this will cover both the uncombined and combined meshes.
        final TextureState ts = new TextureState();
        ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
        scene.setRenderState(ts);

        // set a material state that applies our vertex coloring to the lighting equation
        final MaterialState ms = new MaterialState();
        ms.setColorMaterial(ColorMaterial.AmbientAndDiffuse);
        scene.setRenderState(ms);

        // position our camera to take in all of the mesh
        _canvas.getCanvasRenderer().getCamera().setLocation(edge / 2, edge / 2, 2 * edge);

        // |---------------- UI and control code below... ----------------|
        // Add a trigger on the M key to switch between merged and non-merged
        _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.M), new TriggerAction() {
            @Override
            public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) {
                showMerged = !showMerged;
                if (showMerged) {
                    origNode.removeFromParent();
                    scene.attachChild(merged);
                } else {
                    merged.removeFromParent();
                    scene.attachChild(origNode);
                }
                updateMergedLabel();
            }
        }));

        // Add a trigger on the V key to toggle VBO use (only on merged mesh)
        _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
            @Override
            public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) {
                useVBO = !useVBO;
                if (useVBO) {
                    merged.getSceneHints().setDataMode(DataMode.VBO);
                } else {
                    merged.getSceneHints().setDataMode(DataMode.Arrays);
                }
                updateMergedLabel();
            }
        }));

        // make some text labels...
        for (int i = 0; i < text.length; i++) {
            text[i] = BasicText.createDefaultTextLabel("Text" + i, "", 16);
            text[i].getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
            text[i].getSceneHints().setLightCombineMode(LightCombineMode.Off);
            text[i].setTranslation(new Vector3(10, 10 + i * 25, 0));
            _root.attachChild(text[i]);
        }

        // Update text on the labels
        updateMergedLabel();

        // Set root to always show, so our text attached to it doesn't disappear when the scene is out of view.
        // We created scene above so the meshes would not inherit this hint.
        _root.getSceneHints().setCullHint(CullHint.Never);
    }

    private void updateMergedLabel() {
        if (showMerged) {
            if (useVBO) {
                text[2].setText("Showing a single, merged Mesh using VBO.  [M] to un-merge.  [V] to disable VBO");
            } else {
                text[2].setText("Showing a single, merged Mesh.  [M] to un-merge.  [V] to enable VBO");
            }
        } else {
            text[2].setText("Showing " + (edge * edge) + " individual Meshes.  [M] to merge.");
        }
    }

    private double counter = 0;
    private int frames = 0;

    @Override
    protected void updateExample(final ReadOnlyTimer timer) {
        counter += timer.getTimePerFrame();
        frames++;
        if (counter > 1) {
            final double fps = (frames / counter);
            text[1].setText("Frames per second: " + Math.round(fps * 10) / 10.0);
            if (StatCollector.hasHistoricalStat(StatType.STAT_TRIANGLE_COUNT)
                    && StatCollector.hasHistoricalStat(StatType.STAT_FRAMES)) {
                final MultiStatSample stats = StatCollector.lastStats();
                final double triangles = stats.getStatValue(StatType.STAT_TRIANGLE_COUNT).getAccumulatedValue();
                final double frames = stats.getStatValue(StatType.STAT_FRAMES).getAccumulatedValue();
                final double tps = (triangles / frames) * fps;

                if (tps > 1000000) {
                    text[0].setText("Triangles per second: " + Math.round(tps / 100000) / 10.0 + " million");
                } else if (tps > 1000) {
                    text[0].setText("Triangles per second: " + Math.round(tps / 100) / 10.0 + " thousand");
                } else {
                    text[0].setText("Triangles per second: " + Math.round(tps));
                }
            }
            counter = 0;
            frames = 0;

        }
    }
}
TOP

Related Classes of com.ardor3d.example.renderer.CombinerExample

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.