public RenderableBuffer(ModelObject modelObject, RenderedObjectType type, int id, Level level, Dictionary <Texture, int> textureIds)
        {
            this.modelObject = modelObject;
            this.id          = id;
            this.type        = type;
            this.textureIds  = textureIds;
            this.level       = level;

            BufferUsageHint hint = BufferUsageHint.StaticDraw;

            if (modelObject.IsDynamic())
            {
                hint = BufferUsageHint.DynamicDraw;
            }

            // IBO
            int iboLength = modelObject.GetIndices().Length *sizeof(ushort);

            if (iboLength > 0)
            {
                GL.GenBuffers(1, out ibo);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
                GL.BufferData(BufferTarget.ElementArrayBuffer, iboLength * sizeof(ushort), IntPtr.Zero, hint);
            }

            // VBO
            int vboLength = modelObject.GetVertices().Length *sizeof(float);

            switch (type)
            {
            case RenderedObjectType.Terrain:
                vboLength += modelObject.GetAmbientRgbas().Length *sizeof(Byte) + ((TerrainModel)modelObject.model).lights.Count * sizeof(int);
                break;

            case RenderedObjectType.Tie:
                vboLength += modelObject.GetAmbientRgbas().Length *sizeof(Byte);
                break;
            }

            if (vboLength > 0)
            {
                GL.GenBuffers(1, out vbo);
                GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
                GL.BufferData(BufferTarget.ArrayBuffer, vboLength, IntPtr.Zero, hint);
            }

            UpdateBuffers();
            UpdateVars();
        }
        /// <summary>
        /// Updates the buffers. This is not actually needed as long as mesh manipulations are not possible.
        /// </summary>
        public void UpdateBuffers()
        {
            if (BindIbo())
            {
                ushort[] iboData = modelObject.GetIndices();
                GL.BufferSubData(BufferTarget.ElementArrayBuffer, IntPtr.Zero, iboData.Length * sizeof(ushort), iboData);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
            }

            if (BindVbo())
            {
                float[] vboData = modelObject.GetVertices();
                switch (type)
                {
                case RenderedObjectType.Terrain:
                {
                    byte[]       rgbas        = modelObject.GetAmbientRgbas();
                    TerrainModel terrainModel = (TerrainModel)modelObject.model;
                    int[]        lights       = terrainModel.lights.ToArray();
                    float[]      fullData     = new float[vboData.Length + rgbas.Length / 4 + lights.Length];
                    for (int i = 0; i < vboData.Length / 8; i++)
                    {
                        fullData[10 * i + 0] = vboData[8 * i + 0];
                        fullData[10 * i + 1] = vboData[8 * i + 1];
                        fullData[10 * i + 2] = vboData[8 * i + 2];
                        fullData[10 * i + 3] = vboData[8 * i + 3];
                        fullData[10 * i + 4] = vboData[8 * i + 4];
                        fullData[10 * i + 5] = vboData[8 * i + 5];
                        fullData[10 * i + 6] = vboData[8 * i + 6];
                        fullData[10 * i + 7] = vboData[8 * i + 7];
                        fullData[10 * i + 8] = BitConverter.ToSingle(rgbas, i * 4);
                        fullData[10 * i + 9] = (float)lights[i];
                    }
                    vboData = fullData;
                    break;
                }

                case RenderedObjectType.Tie:
                {
                    byte[]  rgbas    = modelObject.GetAmbientRgbas();
                    float[] fullData = new float[vboData.Length + rgbas.Length / 4];
                    for (int i = 0; i < vboData.Length / 8; i++)
                    {
                        fullData[9 * i + 0] = vboData[8 * i + 0];
                        fullData[9 * i + 1] = vboData[8 * i + 1];
                        fullData[9 * i + 2] = vboData[8 * i + 2];
                        fullData[9 * i + 3] = vboData[8 * i + 3];
                        fullData[9 * i + 4] = vboData[8 * i + 4];
                        fullData[9 * i + 5] = vboData[8 * i + 5];
                        fullData[9 * i + 6] = vboData[8 * i + 6];
                        fullData[9 * i + 7] = vboData[8 * i + 7];
                        fullData[9 * i + 8] = BitConverter.ToSingle(rgbas, i * 4);
                    }
                    vboData = fullData;
                    break;
                }
                }
                GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, vboData.Length * sizeof(float), vboData);
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            }
        }