Package com.ardor3d.renderer

Source Code of com.ardor3d.renderer.AbstractFBOTextureRenderer

/**
* 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.renderer;

import java.nio.IntBuffer;
import java.util.EnumMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.ardor3d.framework.Scene;
import com.ardor3d.image.Texture;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyColorRGBA;
import com.ardor3d.renderer.state.RenderState;
import com.ardor3d.renderer.state.RenderState.StateType;
import com.ardor3d.scenegraph.Spatial;

public abstract class AbstractFBOTextureRenderer implements TextureRenderer {
    private static final Logger logger = Logger.getLogger(AbstractFBOTextureRenderer.class.getName());

    /** List of states that override any set states on a spatial if not null. */
    protected final EnumMap<RenderState.StateType, RenderState> _enforcedStates = new EnumMap<RenderState.StateType, RenderState>(
            RenderState.StateType.class);

    protected final Camera _camera = new Camera(1, 1);

    protected final ColorRGBA _backgroundColor = new ColorRGBA(1, 1, 1, 1);

    protected int _active;

    protected int _fboID = 0, _depthRBID = 0;
    protected int _msfboID = 0, _msdepthRBID = 0, _mscolorRBID = 0;
    protected int _width = 0, _height = 0, _samples = 0, _depthBits = 0;

    protected IntBuffer _attachBuffer = null;
    protected boolean _usingDepthRB = false;
    protected final boolean _supportsDepthTexture;
    protected final boolean _supportsMultisample;
    protected boolean _neededClip;

    protected final Renderer _parentRenderer;

    public AbstractFBOTextureRenderer(final int width, final int height, final int depthBits, final int samples,
            final Renderer parentRenderer, final ContextCapabilities caps) {
        _parentRenderer = parentRenderer;
        _samples = Math.min(samples, caps.getMaxFBOSamples());
        _depthBits = depthBits;
        _supportsDepthTexture = caps.isDepthTextureSupported();
        _supportsMultisample = caps.getMaxFBOSamples() != 0;

        int w = width;
        int h = height;
        if (!caps.isNonPowerOfTwoTextureSupported()) {
            // Check if we have non-power of two sizes. If so, find the smallest power of two size that is greater than
            // the provided size.
            if (!MathUtils.isPowerOfTwo(w)) {
                int newWidth = 2;
                do {
                    newWidth <<= 1;

                } while (newWidth < w);
                w = newWidth;
            }

            if (!MathUtils.isPowerOfTwo(h)) {
                int newHeight = 2;
                do {
                    newHeight <<= 1;

                } while (newHeight < h);
                h = newHeight;
            }
        }

        logger.fine("Creating FBO sized: " + w + " x " + h);

        _width = w;
        _height = h;

        _camera.resize(_width, _height);
        _camera.setFrustum(1.0f, 1000.0f, -0.50f, 0.50f, 0.50f, -0.50f);
        final Vector3 loc = new Vector3(0.0f, 0.0f, 0.0f);
        final Vector3 left = new Vector3(-1.0f, 0.0f, 0.0f);
        final Vector3 up = new Vector3(0.0f, 1.0f, 0.0f);
        final Vector3 dir = new Vector3(0.0f, 0f, -1.0f);
        _camera.setFrame(loc, left, up, dir);
    }

    /**
     * <code>getCamera</code> retrieves the camera this renderer is using.
     *
     * @return the camera this renderer is using.
     */
    public Camera getCamera() {
        return _camera;
    }

    public void setBackgroundColor(final ReadOnlyColorRGBA c) {
        _backgroundColor.set(c);
    }

    public ReadOnlyColorRGBA getBackgroundColor() {
        return _backgroundColor;
    }

    public void render(final Spatial toDraw, final Texture tex, final int clear) {
        try {
            ContextManager.getCurrentContext().pushFBOTextureRenderer(this);

            setupForSingleTexDraw(tex);

            if (_samples > 0 && _supportsMultisample) {
                setMSFBO();
            }

            switchCameraIn(clear);
            doDraw(toDraw);
            switchCameraOut();

            if (_samples > 0 && _supportsMultisample) {
                blitMSFBO();
            }

            takedownForSingleTexDraw(tex);

            ContextManager.getCurrentContext().popFBOTextureRenderer();
        } catch (final Exception e) {
            logger.logp(Level.SEVERE, this.getClass().toString(), "render(Spatial, Texture, boolean)", "Exception", e);
        }
    }

    public void render(final Scene toDraw, final Texture tex, final int clear) {
        try {
            ContextManager.getCurrentContext().pushFBOTextureRenderer(this);

            setupForSingleTexDraw(tex);

            if (_samples > 0 && _supportsMultisample) {
                setMSFBO();
            }

            switchCameraIn(clear);
            doDraw(toDraw);
            switchCameraOut();

            if (_samples > 0 && _supportsMultisample) {
                blitMSFBO();
            }

            takedownForSingleTexDraw(tex);

            ContextManager.getCurrentContext().popFBOTextureRenderer();
        } catch (final Exception e) {
            logger.logp(Level.SEVERE, this.getClass().toString(), "render(Spatial, Texture, boolean)", "Exception", e);
        }
    }

    public void render(final List<? extends Spatial> toDraw, final Texture tex, final int clear) {
        try {
            ContextManager.getCurrentContext().pushFBOTextureRenderer(this);

            setupForSingleTexDraw(tex);

            if (_samples > 0 && _supportsMultisample) {
                setMSFBO();
            }

            switchCameraIn(clear);
            doDraw(toDraw);
            switchCameraOut();

            if (_samples > 0 && _supportsMultisample) {
                blitMSFBO();
            }

            takedownForSingleTexDraw(tex);

            ContextManager.getCurrentContext().popFBOTextureRenderer();
        } catch (final Exception e) {
            logger.logp(Level.SEVERE, this.getClass().toString(), "render(List<Spatial>, Texture, boolean)",
                    "Exception", e);
        }
    }

    protected abstract void activate();

    protected abstract void setupForSingleTexDraw(Texture tex);

    protected abstract void takedownForSingleTexDraw(Texture tex);

    protected abstract void setMSFBO();

    protected abstract void blitMSFBO();

    protected abstract void deactivate();

    private Camera _oldCamera;

    protected void switchCameraIn(final int clear) {
        // grab non-rtt settings
        _oldCamera = Camera.getCurrentCamera();

        // swap to rtt settings
        _parentRenderer.getQueue().pushBuckets();

        // clear the scene
        if (clear != 0) {
            clearBuffers(clear);
        }

        getCamera().update();
        getCamera().apply(_parentRenderer);
    }

    protected abstract void clearBuffers(int clear);

    protected void switchCameraOut() {
        _parentRenderer.flushFrame(false);

        // reset previous camera
        _oldCamera.update();
        _oldCamera.apply(_parentRenderer);

        // back to the non rtt settings
        _parentRenderer.getQueue().popBuckets();
    }

    protected void doDraw(final Spatial spat) {
        // Override parent's last frustum test to avoid accidental incorrect cull
        if (spat.getParent() != null) {
            spat.getParent().setLastFrustumIntersection(Camera.FrustumIntersect.Intersects);
        }

        // do rtt scene render
        spat.onDraw(_parentRenderer);
    }

    protected void doDraw(final List<? extends Spatial> toDraw) {
        for (int x = 0, max = toDraw.size(); x < max; x++) {
            final Spatial spat = toDraw.get(x);
            doDraw(spat);
        }
    }

    protected void doDraw(final Scene toDraw) {
        toDraw.renderUnto(_parentRenderer);
    }

    public int getWidth() {
        return _width;
    }

    public int getHeight() {
        return _height;
    }

    public Renderer getParentRenderer() {
        return _parentRenderer;
    }

    public void setMultipleTargets(final boolean multi) {
    // ignore. Does not matter to FBO.
    }

    public void enforceState(final RenderState state) {
        _enforcedStates.put(state.getType(), state);
    }

    public void enforceStates(final EnumMap<StateType, RenderState> states) {
        _enforcedStates.putAll(states);
    }

    public void clearEnforcedState(final StateType type) {
        _enforcedStates.remove(type);
    }

    public void clearEnforcedStates() {
        _enforcedStates.clear();
    }
}
TOP

Related Classes of com.ardor3d.renderer.AbstractFBOTextureRenderer

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.