Records the state of all the vertex buffer bindings required to provide a vertex declaration with the input data it needs for the vertex elements.
Why do we have this binding list rather than just have VertexElement referring to the vertex buffers direct? Well, in the underlying APIs, binding the vertex buffers to an index (or 'stream') is the way that vertex data is linked, so this structure better reflects the realities of that. In addition, by separating the vertex declaration from the list of vertex buffer bindings, it becomes possible to reuse bindings between declarations and vice versa, giving opportunities to reduce the state changes required to perform rendering.
Beispiel #1
0
		/// <summary>
		///		Default constructor.  Calls on the current buffer manager to initialize the bindings and declarations.
		/// </summary>
		public VertexData()
		{
			vertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration();
			vertexBufferBinding = HardwareBufferManager.Instance.CreateVertexBufferBinding();
		}
Beispiel #2
0
        public void SetVertexBufferBinding(VertexBufferBinding binding,
            int numberOfInstances, bool useGlobalInstancingVertexBufferIsAvailable, bool indexesUsed)
        {
            if ( useGlobalInstancingVertexBufferIsAvailable )
            {
                numberOfInstances *= GlobalNumberOfInstances;
            }

            var globalInstanceVertexBuffer = GlobalInstanceVertexBuffer;
            var globalVertexDeclaration = GlobalInstanceVertexBufferVertexDeclaration;
            var hasInstanceData = useGlobalInstancingVertexBufferIsAvailable &&
                                  globalInstanceVertexBuffer != null && globalVertexDeclaration != null
                || binding.HasInstanceData;


            // TODO: attempt to detect duplicates
            var binds = binding.Bindings;
            var source = -1;
            foreach ( var i in binds )
            {
                source++;
                var d3D9Buf = (D3DHardwareVertexBuffer)i.Value;
                //D3D9HardwareVertexBuffer* d3d9buf = 
                //    static_cast<D3D9HardwareVertexBuffer*>(i->second.get());

                // Unbind gap sources
                for ( ; source < i.Key; ++source )
                {
                    ActiveD3D9Device.SetStreamSource( source, null, 0, 0 );
                }

                ActiveD3D9Device.SetStreamSource(source, d3D9Buf.D3DVertexBuffer, 0, d3D9Buf.VertexSize);

                // SetStreamSourceFreq
                if ( hasInstanceData )
                {
                    if ( d3D9Buf.IsInstanceData )
                    {
                        ActiveD3D9Device.SetStreamSourceFrequency(source, d3D9Buf.InstanceDataStepRate, StreamSource.InstanceData);
                    }
                    else
                    {
                        if ( !indexesUsed )
                        {
                            throw new AxiomException( "Instance data used without index data." );
                        }
                        ActiveD3D9Device.SetStreamSourceFrequency(source, numberOfInstances, StreamSource.InstanceData);
                    }
                }
                else
                {
                    // SlimDX workaround see http://www.gamedev.net/topic/564376-solved-slimdx---instancing-problem/
                    ActiveD3D9Device.ResetStreamSourceFrequency(source);
                    //device.SetStreamSourceFrequency( source, 1, StreamSource.IndexedData );
                }

            }

            if ( useGlobalInstancingVertexBufferIsAvailable )
            {
                // bind global instance buffer if exist
                if ( globalInstanceVertexBuffer != null )
                {
                    if ( !indexesUsed )
                    {
                        throw new AxiomException( "Instance data used without index data." );
                    }

                    var d3D9Buf = (D3DHardwareVertexBuffer)globalInstanceVertexBuffer;
                    ActiveD3D9Device.SetStreamSource(source, d3D9Buf.D3DVertexBuffer, 0, d3D9Buf.VertexSize);

                    ActiveD3D9Device.SetStreamSourceFrequency(source, d3D9Buf.InstanceDataStepRate, StreamSource.InstanceData);
                }

            }

            // Unbind any unused sources
            for ( var unused = source; unused < _lastVertexSourceCount; ++unused )
            {

                ActiveD3D9Device.SetStreamSource(unused, null, 0, 0);
                ActiveD3D9Device.SetStreamSourceFrequency(source, 1, StreamSource.IndexedData);
            }
            _lastVertexSourceCount = source;
        }
		public override void DestroyVertexBufferBinding( VertexBufferBinding binding )
		{
			_baseInstance.DestroyVertexBufferBinding( binding );
		}
		protected void CreateCpuVertexData()
		{
			if ( this.mVertexDataRecord != null )
			{
				DestroyCpuVertexData();

				// create vertex structure, not using GPU for now (these are CPU structures)
				var dcl = new VertexDeclaration();
				var bufbind = new VertexBufferBinding();

				this.mVertexDataRecord.CpuVertexData = new VertexData( dcl, bufbind );

				// Vertex declaration
				// TODO: consider vertex compression
				int offset = 0;
				// POSITION 
				// float3(x, y, z)
				offset += dcl.AddElement( POSITION_BUFFER, offset, VertexElementType.Float3, VertexElementSemantic.Position ).Size;
				// UV0
				// float2(u, v)
				// TODO - only include this if needing fixed-function
				offset +=
					dcl.AddElement( POSITION_BUFFER, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 ).Size;
				// UV1 delta information
				// float2(delta, deltaLODthreshold)
				offset = 0;
				offset += dcl.AddElement( DELTA_BUFFER, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1 ).Size;

				// Calculate number of vertices
				// Base geometry size * size
				var baseNumVerts = (int)Utility.Sqr( this.mVertexDataRecord.Size );
				var numVerts = baseNumVerts;
				// Now add space for skirts
				// Skirts will be rendered as copies of the edge vertices translated downwards
				// Some people use one big fan with only 3 vertices at the bottom, 
				// but this requires creating them much bigger that necessary, meaning
				// more unnecessary overdraw, so we'll use more vertices 
				// You need 2^levels + 1 rows of full resolution (max 129) vertex copies, plus
				// the same number of columns. There are common vertices at intersections
				var levels = this.mVertexDataRecord.TreeLevels;
				this.mVertexDataRecord.NumSkirtRowsCols = (ushort)( System.Math.Pow( 2, levels ) + 1 );
				this.mVertexDataRecord.SkirtRowColSkip =
					(ushort)( ( this.mVertexDataRecord.Size - 1 )/( this.mVertexDataRecord.NumSkirtRowsCols - 1 ) );
				numVerts += this.mVertexDataRecord.Size*this.mVertexDataRecord.NumSkirtRowsCols;
				numVerts += this.mVertexDataRecord.Size*this.mVertexDataRecord.NumSkirtRowsCols;

				//manually create CPU-side buffer
				var posBuf = HardwareBufferManager.Instance.CreateVertexBuffer( dcl.Clone( POSITION_BUFFER ), numVerts,
				                                                                BufferUsage.StaticWriteOnly, false );
				var deltabuf = HardwareBufferManager.Instance.CreateVertexBuffer( dcl.Clone( DELTA_BUFFER ), numVerts,
				                                                                  BufferUsage.StaticWriteOnly, false );

				this.mVertexDataRecord.CpuVertexData.vertexStart = 0;
				this.mVertexDataRecord.CpuVertexData.vertexCount = numVerts;

				var updateRect = new Rectangle( this.mOffsetX, this.mOffsetY, this.mBoundaryX, this.mBoundaryY );
				UpdateVertexBuffer( posBuf, deltabuf, updateRect );
				this.mVertexDataRecord.IsGpuVertexDataDirty = true;
				bufbind.SetBinding( POSITION_BUFFER, posBuf );
				bufbind.SetBinding( DELTA_BUFFER, deltabuf );
			}
		}
		public void SetVertexDeclaration( VertexDeclaration declaration, VertexBufferBinding binding )
		{
			var gles2decl = declaration as GLES2VertexDeclaration;
			
			if( null != gles2decl )
				gles2decl.Bind();
		}
Beispiel #6
0
		public VertexData( VertexDeclaration dcl, VertexBufferBinding bind )
			: base()
		{
			// this is a fallback rather than actively used
			this._mgr = HardwareBufferManager.Instance;
			this.vertexDeclaration = dcl;
			this.vertexBufferBinding = bind;
			DeleteDclBinding = false;
		}
Beispiel #7
0
		/// <summary>
		/// </summary>
		private void _setVertexBufferBinding(VertexBufferBinding binding)
		{
			var bindings = binding.Bindings;

			var xnaBindings = new Microsoft.Xna.Framework.Graphics.VertexBufferBinding[binding.BindingCount];
			var index = 0;
			foreach (var stream in bindings.Keys)
			{
				var buffer = (XnaHardwareVertexBuffer)bindings[stream];
				xnaBindings[index++] =
					new Microsoft.Xna.Framework.Graphics.VertexBufferBinding(buffer.XnaVertexBuffer);
			}

			_device.SetVertexBuffers(xnaBindings);
		}
 /// <summary>
 ///		Creates a new <see cref="VertexBufferBinding"/>.
 /// </summary>
 /// <param name="binding"></param>
 public virtual void DestroyVertexBufferBinding(VertexBufferBinding binding)
 {
     vertexBufferBindings.Remove(binding);
 }
Beispiel #9
0
		public VertexData( HardwareBufferManagerBase mgr )
			: base()
		{
			this._mgr = mgr != null ? mgr : HardwareBufferManager.Instance;
			this.vertexBufferBinding = HardwareBufferManager.Instance.CreateVertexBufferBinding();
			this.vertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration();
			DeleteDclBinding = true;
		}
 /// <summary>
 ///     Creates a new VertexBufferBinding.
 /// </summary>
 public virtual VertexBufferBinding CreateVertexBufferBinding()
 {
     VertexBufferBinding binding = new VertexBufferBinding();
     vertexBufferBindings.Add(binding);
     return binding;
 }
        /// <summary>
        /// 
        /// </summary>
        protected void SetVertexBufferBinding(VertexBufferBinding binding)
        {
            Dictionary<ushort, HardwareVertexBuffer> bindings = binding.Bindings;

            // TODO: Optimize to remove enumeration if possible, although with so few iterations it may never make a difference
            int c = 0;
            foreach (ushort stream in bindings.Keys) {
                D3DHardwareVertexBuffer buffer = (D3DHardwareVertexBuffer)bindings[stream];
                if (cache.streamNull[c] || cache.vertexBuffer[c] != buffer) {
                    cache.vertexBuffer[c] = buffer;
                    cache.streamNull[c] = false;
                    device.SetStreamSource(stream, buffer.D3DVertexBuffer, 0, buffer.VertexSize);
                }
                c++;
                lastVertexSourceCount++;
            }

            // Unbind any unused sources
            for(int i = bindings.Count; i < lastVertexSourceCount; i++) {
                if (!cache.streamNull[i]) {
                    cache.streamNull[i] = true;
                    device.SetStreamSource(i, null, 0, 0);
                }
            }

            lastVertexSourceCount = bindings.Count;
        }
Beispiel #12
0
 public override void DestroyVertexBufferBinding(VertexBufferBinding binding)
 {
     this._baseInstance.DestroyVertexBufferBinding(binding);
 }
Beispiel #13
0
        private void CreateBuffers(ushort[] indices, short[] vertices)
        {
            var numIndices = indices.Length;
            var numVertices = vertices.Length;

            _vertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration();
            _vertexDeclaration.AddElement(0, 0, VertexElementType.Short2, VertexElementSemantic.Position);
            _ib = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, numIndices, BufferUsage.WriteOnly);
            _vb = HardwareBufferManager.Instance.CreateVertexBuffer(_vertexDeclaration, numVertices, BufferUsage.WriteOnly, false);

            _ib.WriteData(0, numIndices * sizeof(ushort), indices, true);
            _vb.WriteData(0, numVertices * sizeof(ushort), vertices, true);

            var binding = new VertexBufferBinding();
            binding.SetBinding(0, _vb);

            VertexData = new VertexData();
            VertexData.vertexDeclaration = _vertexDeclaration;
            VertexData.vertexBufferBinding = binding;
            VertexData.vertexCount = numVertices;
            VertexData.vertexStart = 0;

            IndexData = new IndexData();
            IndexData.indexBuffer = _ib;
            IndexData.indexCount = numIndices;
            IndexData.indexStart = 0;
        }
        protected void SetPointsImpl(List <Vector3> points, List <ColorEx> colors, List <List <VertexBoneAssignment> > boneAssignments)
        {
            if (colors != null && points.Count != colors.Count)
            {
                throw new Exception("Invalid parameters to SetPoints.  Point list length does not match colors list length");
            }
            Vector3 min = Vector3.Zero;
            Vector3 max = Vector3.Zero;

            // set up vertex data
            vertexData = new VertexData();

            // set up vertex declaration
            VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
            int currentOffset = 0;

            // always need positions
            vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            int colorOffset = currentOffset / sizeof(float);

            if (colors != null)
            {
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Color, VertexElementSemantic.Diffuse);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Color);
            }
            int boneIndexOffset = currentOffset / sizeof(float);

            if (boneAssignments != null)
            {
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.UByte4, VertexElementSemantic.BlendIndices);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.UByte4);
            }
            int boneWeightOffset = currentOffset / sizeof(float);

            if (boneAssignments != null)
            {
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float4, VertexElementSemantic.BlendWeights);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Float4);
            }
            int stride = currentOffset / sizeof(float);

            vertexData.vertexCount = points.Count;

            // allocate vertex buffer
            HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, BufferUsage.StaticWriteOnly);

            // set up the binding, one source only
            VertexBufferBinding binding = vertexData.vertexBufferBinding;

            binding.SetBinding(0, vertexBuffer);

            // Generate vertex data
            unsafe {
                // lock the vertex buffer
                IntPtr data = vertexBuffer.Lock(BufferLocking.Discard);

                byte * pData  = (byte *)data.ToPointer();
                float *pFloat = (float *)pData;
                uint * pInt   = (uint *)pData;
                for (int i = 0; i < points.Count; ++i)
                {
                    Vector3 vec = points[i];
                    // assign to geometry
                    pFloat[stride * i]     = vec.x;
                    pFloat[stride * i + 1] = vec.y;
                    pFloat[stride * i + 2] = vec.z;
                    if (colors != null)
                    {
                        // assign to diffuse
                        pInt[stride * i + colorOffset] = Root.Instance.RenderSystem.ConvertColor(colors[i]);
                    }
                    if (boneAssignments != null)
                    {
                        for (int j = 0; j < 4; ++j)
                        {
                            pData[4 * (stride * i + boneIndexOffset) + j] = (byte)(boneAssignments[i][j].boneIndex);
                            pFloat[stride * i + boneWeightOffset + j]     = boneAssignments[i][j].weight;
                        }
                    }
                }
                // unlock the buffer
                vertexBuffer.Unlock();
            } // unsafe

            for (int i = 0; i < points.Count; ++i)
            {
                Vector3 vec = points[i];
                // Also update the bounding sphere radius
                float len = vec.Length;
                if (len > boundingSphereRadius)
                {
                    boundingSphereRadius = len;
                }
                // Also update the bounding box
                if (vec.x < min.x)
                {
                    min.x = vec.x;
                }
                if (vec.y < min.y)
                {
                    min.y = vec.y;
                }
                if (vec.z < min.z)
                {
                    min.z = vec.z;
                }
                if (vec.x > max.x)
                {
                    max.x = vec.x;
                }
                if (vec.y > max.y)
                {
                    max.y = vec.y;
                }
                if (vec.z > max.z)
                {
                    max.z = vec.z;
                }
            }

            // Set the SimpleRenderable bounding box
            box = new AxisAlignedBox(min, max);
        }