Subversion Repositories AndroidProjects

Rev

Rev 805 | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Tao.OpenGl;
using BauzoidNET.graphics;

#pragma warning disable 0618

namespace BauzoidNET.graphics.model
{
    public class VertexStream : GraphicsObject
    {
            /** Type of stream - single attribute or multi-attribute interleaved. */
            public enum StreamType
            {
                    INDIVIDUAL,
                    INTERLEAVED
            };
       
            //private static List<VertexStream> mManagedStreams = new ArrayList<VertexStream>();
        private static IList<VertexStream> mManagedStreams = new List<VertexStream>();
       
            private StreamType mStreamType;
            private string mName;
        private float[] mData = null;
            //private FloatBuffer mData = null;
            //private ByteBuffer mByteBuffer = null;
       
            private bool mIsDynamic = false;
       
            private int mVertexCount = 0;
            private int mCoordsPerElement = 0;
            private int mBytesPerElement = 0;
       
            private int mBufferID = 0;
        private static int[] BUFFERID = new int[1];
            //private static int[] BUFFERID = new int[1];
            //private static IntBuffer BUFFERID = BufferUtils.newIntBuffer(1);
       
            private VertexAttribute[] mAttribs;
       
            /** Constructor. */
            public VertexStream(Graphics graphics, StreamType streamType, string name, VertexAttribute[] attribs, bool isDynamic)
            : base(graphics)
            {
                    mStreamType = streamType;
                    mName = name;
                    mAttribs = attribs;
                    mIsDynamic = isDynamic;
               
                    mManagedStreams.Add(this);
            }
       
            /** Destroy all internal data. */
            public void dispose()
            {
                    mManagedStreams.Remove(this);
               
                    unload();
                    mAttribs = null;
                    mVertexCount = 0;
                    mCoordsPerElement = 0;
                    mBytesPerElement = 0;
               
                    /*if (mByteBuffer != null)
                    {
                            BufferUtils.disposeUnsafeByteBuffer(mByteBuffer);
                            mByteBuffer = null;
                    }*/

                    mData = null;
            }
       
            /** Reload all managed vertex streams. */
            public static void reloadManagedStreams()
            {
                    for (int i = 0; i < mManagedStreams.Count; i++)
                    {
                            VertexStream stream = mManagedStreams[i];
                            stream.upload();
                            //Gdx.app.log(Consts.LOG_TAG, "VertexStream '" + stream.getName() + "' reloaded!");
                    }
            }  

            /** Set the buffer data. */
        /*
            public void setData(byte[] data, int coordsPerElement, int bytesPerElement)
            {
                    if (data == null)
                    {
                            dispose();
                            return;
                    }
               
                    int newVertexCount = data.Length / bytesPerElement;
                    if ((mVertexCount != newVertexCount) || (mByteBuffer == null))
                    {
                            // reallocate
                            allocateBuffer(data.Length);
                    }
               
                    mVertexCount = newVertexCount;
                    mCoordsPerElement = coordsPerElement;
                    mBytesPerElement = bytesPerElement;
               
                    BufferUtils.copy(data, 0, mData, data.Length);
                    mData.position(0);
                    mData.limit(data.Length);
            }*/

       
            /** Set the buffer data. */
            public void setData(float[] data, int coordsPerElement, int bytesPerElement)
            {
                    if (data == null)
                    {
                            dispose();
                            return;
                    }
               
                    int newVertexCount = data.Length / coordsPerElement;
                    /*if ((mVertexCount != newVertexCount) || (mByteBuffer == null))
                    {
                            // reallocate
                            allocateBuffer(data.Length * sizeof(float));
                    }           */

               
                    mVertexCount = data.Length / coordsPerElement;
                    mCoordsPerElement = coordsPerElement;
                    mBytesPerElement = bytesPerElement;

            mData = (float[])data.Clone();
               
                    /*BufferUtils.copy(data, mByteBuffer, data.Length, 0);
                    mData.position(0);
                    mData.limit(data.Length);*/

            }
       
       
/*          public void allocateBuffer(int newSize)
            {
                    if (mByteBuffer != null)
                            BufferUtils.disposeUnsafeByteBuffer(mByteBuffer);
               
                    mByteBuffer = BufferUtils.newUnsafeByteBuffer(newSize);
                    mData = mByteBuffer.asFloatBuffer();
                    mData.flip();
                    mByteBuffer.flip();
            }*/

       
            /** Create GL handle and upload vertex data to hardware. */
            public void upload()
            {
                    if (mData == null)
                            return;

            Gl.glGenBuffers(1, BUFFERID);
            mBufferID = BUFFERID[0];

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mBufferID);

            int usage = Gl.GL_STATIC_DRAW;
            if (isDynamic())
                usage = Gl.GL_DYNAMIC_DRAW;

            Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(mData.Length * sizeof(float)), mData, usage);
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
               
                    /*Gdx.gl20.glGenBuffers(1, BUFFERID);
                    mBufferID = BUFFERID.get(0);
               
                    Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);
               
                    int usage = GL20.GL_STATIC_DRAW;
                    if (isDynamic())
                            usage = GL20.GL_DYNAMIC_DRAW;
               
                    Gdx.gl20.glBufferData(GL20.GL_ARRAY_BUFFER, mByteBuffer.limit(), mByteBuffer, usage);
                    Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);*/

            }
       
            /** Reupload data to hardware. */
            public void reupload()
            {
                    if (mBufferID == 0)
                    {
                            // perform initial upload
                            upload();
                            return;
                    }
               
                    if (mData == null)
                            return;

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mBufferID);
            Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)0, (IntPtr)(mData.Length * sizeof(float)), mData);
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
               
                    /*Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);
                    Gdx.gl20.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, mData.capacity() * Consts.SIZEOF_FLOAT, mData);
                    Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);*/

            }
       
            /** Unload vertex data from hardware. */
            public void unload()
            {
                    deactivate();
                    /*BUFFERID.put(0, mBufferID);
            Gdx.gl20.glDeleteBuffers(1, BUFFERID);*/

            BUFFERID[0] = mBufferID;
            Gl.glDeleteBuffers(1, BUFFERID);               
                    mBufferID = 0;
            }
       
            //static int mCurrentBufferId = 0;
       
            /** Activate stream for rendering. */
            public void activate()
            {
                    // TODO: buffer state tracking
                    //if (mCurrentBufferId != mBufferID)
                    {
                            /*Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);*/
                Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mBufferID);
                            //mCurrentBufferId = mBufferID;
                    }

            for (int i = 0; i < mAttribs.Length; i++)
                    {
                            VertexAttribute attrib = mAttribs[i];

                            // TODO: attrib to handle adapter
                            /*Gdx.gl20.glVertexAttribPointer(attrib.getAttribType(), attrib.getCoordsPerElement(), GL20.GL_FLOAT, false, getBytesPerElement(), attrib.getByteOffset());
                            Gdx.gl20.glEnableVertexAttribArray(attrib.getAttribType());*/

                Gl.glVertexAttribPointer(attrib.getAttribType(), attrib.getCoordsPerElement(), Gl.GL_FLOAT, Gl.GL_FALSE, getBytesPerElement(), (IntPtr)attrib.getByteOffset());
                Gl.glEnableVertexAttribArray(attrib.getAttribType());
                    }          

            }
       
            public void deactivate()
            {
                    for (int i = 0; i < mAttribs.Length; i++)
                    {
                            VertexAttribute attrib = mAttribs[i];
                       
                            // TODO: attrib to handle adapter
                            //Gdx.gl20.glDisableVertexAttribArray(attrib.getAttribType());
                Gl.glDisableVertexAttribArray(attrib.getAttribType());
                    }          
               
                    // TODO: buffer state tracking
                    //Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
            }
       
            /** Get Coords per element. */
            public int getCoordsPerElement()  
            {
                    return mCoordsPerElement;
            }
       
            /** Get number of bytes per complete element (equals vertex stride). */
            public int getBytesPerElement()
            {
                    return mBytesPerElement;
            }
       
            /** Get number of elements. */
            public int getVertexCount()
            {
                    return mVertexCount;
            }
       
            /** Get name of vertex stream. */
            public string getName()
            {
                    return mName;
            }
       
            /** Get stream type. */
            public StreamType getStreamType()
            {
                    return mStreamType;
            }

            /** Check if the stream is dynamic or static. */
            public bool isDynamic()
            {
                    return mIsDynamic;
            }
    }
}