159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.*;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.FastMath;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.Renderer;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.NativeObject;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.*;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * A <code>VertexBuffer</code> contains a particular type of geometry
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * data used by {@link Mesh}es. Every VertexBuffer set on a <code>Mesh</code>
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * is sent as an attribute to the vertex shader to be processed.
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Several terms are used throughout the javadoc for this class, explanation:
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <ul>
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <li>Element - A single element is the largest individual object
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * inside a VertexBuffer. E.g. if the VertexBuffer is used to store 3D position
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * data, then an element will be a single 3D vector.</li>
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <li>Component - A component represents the parts inside an element.
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * For a 3D vector, a single component is one of the dimensions, X, Y or Z.</li>
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * </ul>
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class VertexBuffer extends NativeObject implements Savable, Cloneable {
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Type of buffer. Specifies the actual attribute it defines.
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static enum Type {
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Position of the vertex (3 floats)
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Position,
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * The size of the point when using point buffers (float).
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Size,
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Normal vector, normalized (3 floats).
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Normal,
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate (2 float)
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord,
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Color and Alpha (4 floats)
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Color,
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Tangent vector, normalized (4 floats) (x,y,z,w)
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * the w component is called the binormal parity, is not normalized and is either 1f or -1f
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * It's used to compuste the direction on the binormal verctor on the GPU at render time.
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Tangent,
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Binormal vector, normalized (3 floats, optional)
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Binormal,
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Specifies the source data for various vertex buffers
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * when interleaving is used. By default the format is
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * byte.
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InterleavedData,
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Do not use.
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        @Deprecated
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        MiscAttrib,
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Specifies the index buffer, must contain integer data
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * (ubyte, ushort, or uint).
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Index,
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Initial vertex position, used with animation.
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Should have the same format and size as {@link Type#Position}.
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * If used with software skinning, the usage should be
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link Usage#CpuOnly}, and the buffer should be allocated
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * on the heap.
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BindPosePosition,
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Initial vertex normals, used with animation.
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Should have the same format and size as {@link Type#Normal}.
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * If used with software skinning, the usage should be
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link Usage#CpuOnly}, and the buffer should be allocated
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * on the heap.
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BindPoseNormal,
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Bone weights, used with animation (4 floats).
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * If used with software skinning, the usage should be
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link Usage#CpuOnly}, and the buffer should be allocated
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * on the heap.
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BoneWeight,
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Bone indices, used with animation (4 ubytes).
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * If used with software skinning, the usage should be
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link Usage#CpuOnly}, and the buffer should be allocated
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * on the heap.
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BoneIndex,
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #2
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord2,
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #3
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord3,
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #4
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord4,
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #5
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord5,
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #6
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord6,
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #7
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord7,
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Texture coordinate #8
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TexCoord8,
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Initial vertex tangents, used with animation.
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Should have the same format and size as {@link Type#Tangent}.
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * If used with software skinning, the usage should be
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link Usage#CpuOnly}, and the buffer should be allocated
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * on the heap.
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        BindPoseTangent,
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The usage of the VertexBuffer, specifies how often the buffer
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is used. This can determine if a vertex buffer is placed in VRAM
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * or held in video memory, but no guarantees are made- it's only a hint.
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static enum Usage {
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Mesh data is sent once and very rarely updated.
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Static,
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Mesh data is updated occasionally (once per frame or less).
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Dynamic,
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Mesh data is updated every frame.
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Stream,
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Mesh data is <em>not</em> sent to GPU at all. It is only
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * used by the CPU.
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        CpuOnly;
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Specifies format of the data stored in the buffer.
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This should directly correspond to the buffer's class, for example,
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * an {@link Format#UnsignedShort} formatted buffer should use the
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * class {@link ShortBuffer} (e.g. the closest resembling type).
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * For the {@link Format#Half} type, {@link ByteBuffer}s should
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be used.
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static enum Format {
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Half precision floating point.
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 2 bytes, signed.
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Half(2),
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Single precision floating point.
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 4 bytes, signed
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Float(4),
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Double precision floating point.
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 8 bytes, signed. May not
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * be supported by all GPUs.
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Double(8),
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 1 byte integer, signed.
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Byte(1),
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 1 byte integer, unsigned.
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        UnsignedByte(1),
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 2 byte integer, signed.
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Short(2),
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 2 byte integer, unsigned.
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        UnsignedShort(2),
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 4 byte integer, signed.
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Int(4),
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * 4 byte integer, unsigned.
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        UnsignedInt(4);
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        private int componentSize = 0;
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Format(int componentSize){
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.componentSize = componentSize;
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * Returns the size in bytes of this data type.
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         *
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * @return Size in bytes of this data type.
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public int getComponentSize(){
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return componentSize;
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int offset = 0;
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int lastLimit = 0;
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int stride = 0;
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int components = 0;
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * derived from components * format.getComponentSize()
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected transient int componentsLength = 0;
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Buffer data = null;
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Usage usage;
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Type bufType;
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Format format;
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean normalized = false;
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected transient boolean dataSizeChanged = false;
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates an empty, uninitialized buffer.
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Must call setupData() to initialize.
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public VertexBuffer(Type type){
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super(VertexBuffer.class);
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.bufType = type;
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Serialization only. Do not use.
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public VertexBuffer(){
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super(VertexBuffer.class);
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected VertexBuffer(int id){
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super(VertexBuffer.class, id);
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The offset after which the data is sent to the GPU.
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #setOffset(int)
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getOffset() {
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return offset;
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param offset Specify the offset (in bytes) from the start of the buffer
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * after which the data is sent to the GPU.
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setOffset(int offset) {
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.offset = offset;
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The stride (in bytes) for the data.
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see #setStride(int)
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getStride() {
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return stride;
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the stride (in bytes) for the data.
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * If the data is packed in the buffer, then stride is 0, if there's other
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * data that is between the current component and the next component in the
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * buffer, then this specifies the size in bytes of that additional data.
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param stride the stride (in bytes) for the data
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setStride(int stride) {
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.stride = stride;
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the raw internal data buffer used by this VertexBuffer.
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This buffer is not safe to call from multiple threads since buffers
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * have their own internal position state that cannot be shared.
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Call getData().duplicate(), getData().asReadOnlyBuffer(), or
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the more convenient getDataReadOnly() if the buffer may be accessed
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * from multiple threads.
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A native buffer, in the specified {@link Format format}.
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Buffer getData(){
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return data;
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a safe read-only version of this VertexBuffer's data.  The
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * contents of the buffer will reflect whatever changes are made on
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * other threads (eventually) but these should not be used in that way.
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This method provides a read-only buffer that is safe to _read_ from
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * a separate thread since it has its own book-keeping state (position, limit, etc.)
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A rewound native buffer in the specified {@link Format format}
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         that is safe to read from a separate thread from other readers.
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Buffer getDataReadOnly() {
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data == null) {
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Create a read-only duplicate().  Note: this does not copy
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // the underlying memory, it just creates a new read-only wrapper
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // with its own buffer position state.
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Unfortunately, this is not 100% straight forward since Buffer
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // does not have an asReadOnlyBuffer() method.
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer result;
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if( data instanceof ByteBuffer ) {
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            result = ((ByteBuffer)data).asReadOnlyBuffer();
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if( data instanceof FloatBuffer ) {
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            result = ((FloatBuffer)data).asReadOnlyBuffer();
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if( data instanceof ShortBuffer ) {
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            result = ((ShortBuffer)data).asReadOnlyBuffer();
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if( data instanceof IntBuffer ) {
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            result = ((IntBuffer)data).asReadOnlyBuffer();
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException( "Cannot get read-only view of buffer type:" + data );
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Make sure the caller gets a consistent view since we may
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // have grabbed this buffer while another thread was reading
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // the raw data.
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.rewind();
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return result;
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The usage of this buffer. See {@link Usage} for more
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * information.
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Usage getUsage(){
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return usage;
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param usage The usage of this buffer. See {@link Usage} for more
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * information.
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setUsage(Usage usage){
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (id != -1)
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            throw new UnsupportedOperationException("Data has already been sent. Cannot set usage.");
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.usage = usage;
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param normalized Set to true if integer components should be converted
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * from their maximal range into the range 0.0 - 1.0 when converted to
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * a floating-point value for the shader.
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * E.g. if the {@link Format} is {@link Format#UnsignedInt}, then
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the components will be converted to the range 0.0 - 1.0 by dividing
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * every integer by 2^32.
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setNormalized(boolean normalized){
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.normalized = normalized;
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if integer components should be converted to the range 0-1.
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see VertexBuffer#setNormalized(boolean)
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isNormalized(){
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return normalized;
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The type of information that this buffer has.
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Type getBufferType(){
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return bufType;
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link Format format}, or data type of the data.
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Format getFormat(){
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return format;
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The number of components of the given {@link Format format} per
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * element.
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getNumComponents(){
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return components;
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The total number of data elements in the data buffer.
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getNumElements(){
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int elements = data.capacity() / components;
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (format == Format.Half)
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            elements /= 2;
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return elements;
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Called to initialize the data in the <code>VertexBuffer</code>. Must only
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be called once.
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param usage The usage for the data, or how often will the data
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be updated per frame. See the {@link Usage} enum.
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param components The number of components per element.
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param format The {@link Format format}, or data-type of a single
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * component.
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data A native buffer, the format of which matches the {@link Format}
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * argument.
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setupData(Usage usage, int components, Format format, Buffer data){
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id != -1)
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("Data has already been sent. Cannot setupData again.");
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (usage == null || format == null || data == null)
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("None of the arguments can be null");
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data.isReadOnly())
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException( "VertexBuffer data cannot be read-only." );
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (components < 1 || components > 4)
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("components must be between 1 and 4");
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.data = data;
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.components = components;
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.usage = usage;
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.format = format;
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.componentsLength = components * format.getComponentSize();
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.lastLimit = data.limit();
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setUpdateNeeded();
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Called to update the data in the buffer with new data. Can only
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be called after {@link VertexBuffer#setupData(com.jme3.scene.VertexBuffer.Usage, int, com.jme3.scene.VertexBuffer.Format, java.nio.Buffer) }
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * has been called. Note that it is fine to call this method on the
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * data already set, e.g. vb.updateData(vb.getData()), this will just
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * set the proper update flag indicating the data should be sent to the GPU
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * again.
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * It is allowed to specify a buffer with different capacity than the
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * originally set buffer.
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data The data buffer to set
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateData(Buffer data){
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id != -1){
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // request to update data is okay
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Check if the data buffer is read-only which is a sign
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // of a bug on the part of the caller
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data != null && data.isReadOnly()) {
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException( "VertexBuffer data cannot be read-only." );
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // will force renderer to call glBufferData again
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data != null && (this.data.getClass() != data.getClass() || data.limit() != lastLimit)){
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            dataSizeChanged = true;
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            lastLimit = data.limit();
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.data = data;
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setUpdateNeeded();
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns true if the data size of the VertexBuffer has changed.
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Internal use only.
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return true if the data size has changed
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean hasDataSizeChanged() {
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return dataSizeChanged;
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearUpdateNeeded(){
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.clearUpdateNeeded();
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dataSizeChanged = false;
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts single floating-point data to {@link Format#Half half} floating-point data.
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void convertToHalf(){
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id != -1)
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("Data has already been sent.");
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (format != Format.Float)
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Format must be float!");
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int numElements = data.capacity() / components;
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        format = Format.Half;
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.componentsLength = components * format.getComponentSize();
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer halfData = BufferUtils.createByteBuffer(componentsLength * numElements);
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        halfData.rewind();
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer floatData = (FloatBuffer) data;
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        floatData.rewind();
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < floatData.capacity(); i++){
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float f = floatData.get(i);
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            short half = FastMath.convertFloatToHalf(f);
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            halfData.putShort(half);
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.data = halfData;
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setUpdateNeeded();
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dataSizeChanged = true;
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Reduces the capacity of the buffer to the given amount
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of elements, any elements at the end of the buffer are truncated
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * as necessary.
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param numElements The number of elements to reduce to.
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void compact(int numElements){
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int total = components * numElements;
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        data.clear();
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bbuf = (ByteBuffer) data;
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bbuf.limit(total);
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bnewBuf = BufferUtils.createByteBuffer(total);
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bnewBuf.put(bbuf);
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = bnewBuf;
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer sbuf = (ShortBuffer) data;
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sbuf.limit(total);
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer snewBuf = BufferUtils.createShortBuffer(total);
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                snewBuf.put(sbuf);
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = snewBuf;
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer ibuf = (IntBuffer) data;
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ibuf.limit(total);
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer inewBuf = BufferUtils.createIntBuffer(total);
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                inewBuf.put(ibuf);
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = inewBuf;
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fbuf = (FloatBuffer) data;
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fbuf.limit(total);
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fnewBuf = BufferUtils.createFloatBuffer(total);
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fnewBuf.put(fbuf);
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = fnewBuf;
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecognized buffer format: "+format);
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        data.clear();
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setUpdateNeeded();
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dataSizeChanged = true;
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Modify a component inside an element.
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The <code>val</code> parameter must be in the buffer's format:
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link Format}.
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param elementIndex The element index to modify
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param componentIndex The component index to modify
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param val The value to set, either byte, short, int or float depending
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * on the {@link Format}.
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setElementComponent(int elementIndex, int componentIndex, Object val){
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int inPos = elementIndex * components;
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int elementPos = componentIndex;
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (format == Format.Half){
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inPos *= 2;
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            elementPos *= 2;
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        data.clear();
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bin = (ByteBuffer) data;
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bin.put(inPos + elementPos, (Byte)val);
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer sin = (ShortBuffer) data;
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sin.put(inPos + elementPos, (Short)val);
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer iin = (IntBuffer) data;
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iin.put(inPos + elementPos, (Integer)val);
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fin = (FloatBuffer) data;
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fin.put(inPos + elementPos, (Float)val);
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecognized buffer format: "+format);
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Get the component inside an element.
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param elementIndex The element index
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param componentIndex The component index
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The component, as one of the primitive types, byte, short,
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * int or float.
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Object getElementComponent(int elementIndex, int componentIndex){
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int inPos = elementIndex * components;
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int elementPos = componentIndex;
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (format == Format.Half){
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inPos *= 2;
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            elementPos *= 2;
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer srcData = getDataReadOnly();
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bin = (ByteBuffer) srcData;
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return bin.get(inPos + elementPos);
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer sin = (ShortBuffer) srcData;
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return sin.get(inPos + elementPos);
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer iin = (IntBuffer) srcData;
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return iin.get(inPos + elementPos);
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fin = (FloatBuffer) srcData;
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return fin.get(inPos + elementPos);
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecognized buffer format: "+format);
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copies a single element of data from this <code>VertexBuffer</code>
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to the given output VertexBuffer.
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param inIndex The input element index
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param outVb The buffer to copy to
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param outIndex The output element index
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If the formats of the buffers do not
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * match.
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void copyElement(int inIndex, VertexBuffer outVb, int outIndex){
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        copyElements(inIndex, outVb, outIndex, 1);
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copies a sequence of elements of data from this <code>VertexBuffer</code>
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to the given output VertexBuffer.
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param inIndex The input element index
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param outVb The buffer to copy to
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param outIndex The output element index
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param len The number of elements to copy
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If the formats of the buffers do not
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * match.
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void copyElements(int inIndex, VertexBuffer outVb, int outIndex, int len){
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (outVb.format != format || outVb.components != components)
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Buffer format mismatch. Cannot copy");
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int inPos  = inIndex  * components;
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int outPos = outIndex * components;
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int elementSz = components;
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (format == Format.Half){
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // because half is stored as bytebuf but its 2 bytes long
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            inPos *= 2;
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            outPos *= 2;
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            elementSz *= 2;
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Make sure to grab a read-only copy in case some other
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // thread is also accessing the buffer and messing with its
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // position()
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer srcData = getDataReadOnly();
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        outVb.data.clear();
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bin = (ByteBuffer) srcData;
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ByteBuffer bout = (ByteBuffer) outVb.data;
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bin.position(inPos).limit(inPos + elementSz * len);
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bout.position(outPos).limit(outPos + elementSz * len);
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                bout.put(bin);
81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer sin = (ShortBuffer) srcData;
81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ShortBuffer sout = (ShortBuffer) outVb.data;
81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sin.position(inPos).limit(inPos + elementSz * len);
81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sout.position(outPos).limit(outPos + elementSz * len);
81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                sout.put(sin);
81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer iin = (IntBuffer) srcData;
82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                IntBuffer iout = (IntBuffer) outVb.data;
82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iin.position(inPos).limit(inPos + elementSz * len);
82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iout.position(outPos).limit(outPos + elementSz * len);
82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                iout.put(iin);
82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fin = (FloatBuffer) srcData;
83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                FloatBuffer fout = (FloatBuffer) outVb.data;
83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fin.position(inPos).limit(inPos + elementSz * len);
83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fout.position(outPos).limit(outPos + elementSz * len);
83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fout.put(fin);
83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecognized buffer format: "+format);
83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Clear the output buffer to rewind it and reset its
84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // limit from where we shortened it above.
84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        outVb.data.clear();
84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a {@link Buffer} that satisfies the given type and size requirements
84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of the parameters. The buffer will be of the type specified by
84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link Format format} and would be able to contain the given number
84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of elements with the given number of components in each element.
84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Buffer createBuffer(Format format, int components, int numElements){
85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (components < 1 || components > 4)
85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Num components must be between 1 and 4");
85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int total = numElements * components;
85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createByteBuffer(total);
86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createByteBuffer(total * 2);
86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createShortBuffer(total);
86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createIntBuffer(total);
86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createFloatBuffer(total);
87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Double:
87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return BufferUtils.createDoubleBuffer(total);
87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecoginized buffer format: "+format);
87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a deep clone of the {@link VertexBuffer}.
87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Deep clone of this buffer
88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public VertexBuffer clone(){
88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // NOTE: Superclass GLObject automatically creates shallow clone
88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // e.g re-use ID.
88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer vb = (VertexBuffer) super.clone();
88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.handleRef = new Object();
88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.id = -1;
88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data != null) {
89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Make sure to pass a read-only buffer to clone so that
89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // the position information doesn't get clobbered by another
89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // reading thread during cloning (and vice versa) since this is
89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // a purely read-only operation.
89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vb.updateData(BufferUtils.clone(getDataReadOnly()));
89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return vb;
89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a deep clone of this VertexBuffer but overrides the
90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link Type}.
90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param overrideType The type of the cloned VertexBuffer
90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A deep clone of the buffer
90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public VertexBuffer clone(Type overrideType){
90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer vb = new VertexBuffer(overrideType);
90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.components = components;
91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.componentsLength = componentsLength;
91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Make sure to pass a read-only buffer to clone so that
91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // the position information doesn't get clobbered by another
91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // reading thread during cloning (and vice versa) since this is
91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // a purely read-only operation.
91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.data = BufferUtils.clone(getDataReadOnly());
91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.format = format;
91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.handleRef = new Object();
91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.id = -1;
92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.normalized = normalized;
92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.offset = offset;
92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.stride = stride;
92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.updateNeeded = true;
92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.usage = usage;
92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return vb;
92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public String toString(){
93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String dataTxt = null;
93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data != null){
93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            dataTxt = ", elements="+data.capacity();
93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return getClass().getSimpleName() + "[fmt="+format.name()
93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                            +", type="+bufType.name()
93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                            +", usage="+usage.name()
93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                            +dataTxt+"]";
93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void resetObject() {
94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        assert this.id != -1;
94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.id = -1;
94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setUpdateNeeded();
94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteObject(Object rendererObject) {
94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ((Renderer)rendererObject).deleteBuffer(this);
95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public NativeObject createDestructableClone(){
95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new VertexBuffer(id);
95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void write(JmeExporter ex) throws IOException {
95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        OutputCapsule oc = ex.getCapsule(this);
95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(components, "components", 0);
96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(usage, "usage", Usage.Dynamic);
96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(bufType, "buffer_type", null);
96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(format, "format", Format.Float);
96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(normalized, "normalized", false);
96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(offset, "offset", 0);
96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(stride, "stride", 0);
96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String dataName = "data" + format.name();
96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer roData = getDataReadOnly();
96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                oc.write((FloatBuffer) roData, dataName, null);
97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                oc.write((ShortBuffer) roData, dataName, null);
97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                oc.write((ByteBuffer) roData, dataName, null);
98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                oc.write((IntBuffer) roData, dataName, null);
98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IOException("Unsupported export buffer format: "+format);
98859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
98959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
99059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
99159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void read(JmeImporter im) throws IOException {
99259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InputCapsule ic = im.getCapsule(this);
99359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        components = ic.readInt("components", 0);
99459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        usage = ic.readEnum("usage", Usage.class, Usage.Dynamic);
99559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        bufType = ic.readEnum("buffer_type", Type.class, null);
99659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        format = ic.readEnum("format", Format.class, Format.Float);
99759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        normalized = ic.readBoolean("normalized", false);
99859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        offset = ic.readInt("offset", 0);
99959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stride = ic.readInt("stride", 0);
100059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        componentsLength = components * format.getComponentSize();
100159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
100259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String dataName = "data" + format.name();
100359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format){
100459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
100559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = ic.readFloatBuffer(dataName, null);
100659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
100759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
100859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
100959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = ic.readShortBuffer(dataName, null);
101059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
101159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
101259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
101359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
101459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = ic.readByteBuffer(dataName, null);
101559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
101659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
101759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
101859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = ic.readIntBuffer(dataName, null);
101959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
102059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
102159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IOException("Unsupported import buffer format: "+format);
102259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
102359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
102459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
1026