public XnaHardwareVertexBuffer(HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, GraphicsDevice dev, bool useSystemMemory, bool useShadowBuffer) : base(manager, vertexDeclaration, numVertices, usage, useSystemMemory, useShadowBuffer) { _device = dev; if (!(vertexDeclaration is XnaVertexDeclaration)) { throw new AxiomException( "Invalid VertexDeclaration supplied, must be created by HardwareBufferManager.CreateVertexDeclaration()"); } if (usage == BufferUsage.Dynamic || usage == BufferUsage.DynamicWriteOnly) { _buffer = new DynamicVertexBuffer(_device, ((XnaVertexDeclaration)vertexDeclaration).XFGVertexDeclaration, numVertices, XnaHelper.Convert(usage)); } else { _buffer = new VertexBuffer(_device, ((XnaVertexDeclaration)vertexDeclaration).XFGVertexDeclaration, numVertices, XnaHelper.Convert(usage)); } _bufferBytes = new byte[vertexDeclaration.GetVertexSize() * numVertices]; _bufferBytes.Initialize(); }
public Rectangle2D(bool includeTextureCoordinates) { vertexData = new VertexData(); vertexData.vertexStart = 0; vertexData.vertexCount = 4; VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding binding = vertexData.vertexBufferBinding; decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); binding.SetBinding(POSITION, buffer); if (includeTextureCoordinates) { decl.AddElement(TEXCOORD, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords); buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(TEXCOORD), vertexData.vertexCount, BufferUsage.StaticWriteOnly); binding.SetBinding(TEXCOORD, buffer); buffer.WriteData(0, buffer.Size, texCoords, true); } // TODO: Fix material = MaterialManager.Instance.GetByName("BaseWhite"); material.Lighting = false; }
static TerrainPage() { terrainVertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration(); // set up the vertex declaration int vDecOffset = 0; terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords); vertexSize = terrainVertexDeclaration.GetVertexSize(0) / 4; }
public HardwareVertexBuffer(HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, bool useSystemMemory, bool useShadowBuffer) : base(usage, useSystemMemory, useShadowBuffer) { this.vertexDeclaration = vertexDeclaration; this.numVertices = numVertices; this.Manager = manager; // calculate the size in bytes of this buffer sizeInBytes = vertexDeclaration.GetVertexSize() * numVertices; // create a shadow buffer if required if (useShadowBuffer) { shadowBuffer = new DefaultHardwareVertexBuffer(this.Manager, vertexDeclaration, numVertices, BufferUsage.Dynamic); } this.useCount = 0; }
public HardwareVertexBuffer( HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, bool useSystemMemory, bool useShadowBuffer ) : base( usage, useSystemMemory, useShadowBuffer ) { this.vertexDeclaration = vertexDeclaration; this.numVertices = numVertices; this.Manager = manager; // calculate the size in bytes of this buffer sizeInBytes = vertexDeclaration.GetVertexSize()*numVertices; // create a shadow buffer if required if ( useShadowBuffer ) { shadowBuffer = new DefaultHardwareVertexBuffer( this.Manager, vertexDeclaration, numVertices, BufferUsage.Dynamic ); } this.useCount = 0; }
/// <summary> /// </summary> /// <param name="vertexSize"> </param> /// <param name="numVertices"> </param> /// <param name="usage"> </param> public GLDefaultHardwareVertexBuffer(VertexDeclaration declaration, int numVertices, BufferUsage usage) : base( null, declaration, numVertices, usage, true, false ) { this._data = new byte[ declaration.GetVertexSize() * numVertices ]; this._dataPtr = BufferBase.Wrap( this._data ); }
public XnaHardwareVertexBuffer( HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, XFG.GraphicsDevice dev, bool useSystemMemory, bool useShadowBuffer ) : base( manager, vertexDeclaration, numVertices, usage, useSystemMemory, useShadowBuffer ) { _device = dev; if ( !( vertexDeclaration is XnaVertexDeclaration ) ) { throw new AxiomException ("Invalid VertexDeclaration supplied, must be created by HardwareBufferManager.CreateVertexDeclaration()" ); } if (usage == BufferUsage.Dynamic || usage == BufferUsage.DynamicWriteOnly) { _buffer = new XFG.DynamicVertexBuffer(_device, ( (XnaVertexDeclaration)vertexDeclaration ).XFGVertexDeclaration , numVertices, XnaHelper.Convert(usage)); } else _buffer = new XFG.VertexBuffer(_device, ( (XnaVertexDeclaration)vertexDeclaration ).XFGVertexDeclaration, numVertices, XnaHelper.Convert(usage)); _bufferBytes = new byte[ vertexDeclaration.GetVertexSize() * numVertices]; _bufferBytes.Initialize(); }
/// <summary> /// Sets up the surface by defining it's control points, type and initial subdivision level. /// </summary> /// <remarks> /// This method initialises the surface by passing it a set of control points. The type of curves to be used /// are also defined here, although the only supported option currently is a bezier patch. You can also /// specify a global subdivision level here if you like, although it is recommended that the parameter /// is left as AUTO_LEVEL, which means the system decides how much subdivision is required (based on the /// curvature of the surface). /// </remarks> /// <param name="controlPoints"> /// A pointer to a buffer containing the vertex data which defines control points /// of the curves rather than actual vertices. Note that you are expected to provide not /// just position information, but potentially normals and texture coordinates too. The /// format of the buffer is defined in the VertexDeclaration parameter. /// </param> /// <param name="decl"> /// VertexDeclaration describing the contents of the buffer. /// Note this declaration must _only_ draw on buffer source 0! /// </param> /// <param name="width">Specifies the width of the patch in control points.</param> /// <param name="height">Specifies the height of the patch in control points.</param> /// <param name="type">The type of surface.</param> /// <param name="uMaxSubdivisionLevel"> /// If you want to manually set the top level of subdivision, /// do it here, otherwise let the system decide. /// </param> /// <param name="vMaxSubdivisionLevel"> /// If you want to manually set the top level of subdivision, /// do it here, otherwise let the system decide. /// </param> /// <param name="side">Determines which side of the patch (or both) triangles are generated for.</param> public unsafe void DefineSurface(System.Array controlPointBuffer, VertexDeclaration declaration, int width, int height, PatchSurfaceType type, int uMaxSubdivisionLevel, int vMaxSubdivisionLevel, VisibleSide visibleSide) { if (height == 0 || width == 0) { return; // Do nothing - garbage } this.type = type; this.controlWidth = width; this.controlHeight = height; this.controlCount = width * height; this.controlPointBuffer = controlPointBuffer; this.declaration = declaration; // Copy positions into Vector3 vector controlPoints.Clear(); VertexElement elem = declaration.FindElementBySemantic(VertexElementSemantic.Position); int vertSize = declaration.GetVertexSize(0); byte *pVert = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(controlPointBuffer, 0); float* pReal = null; for (int i = 0; i < controlCount; i++) { pReal = (float*)(pVert + elem.Offset); controlPoints.Add(new Vector3(pReal[0], pReal[1], pReal[2])); pVert += vertSize; } this.side = visibleSide; // Determine max level // Initialise to 100% detail subdivisionFactor = 1.0f; if (uMaxSubdivisionLevel == AUTO_LEVEL) { uLevel = maxULevel = GetAutoULevel(); } else { uLevel = maxULevel = uMaxSubdivisionLevel; } if (vMaxSubdivisionLevel == AUTO_LEVEL) { vLevel = maxVLevel = GetAutoVLevel(); } else { vLevel = maxVLevel = vMaxSubdivisionLevel; } // Derive mesh width / height meshWidth = (LevelWidth(maxULevel) - 1) * ((controlWidth-1) / 2) + 1; meshHeight = (LevelWidth(maxVLevel) - 1) * ((controlHeight-1) / 2) + 1; // Calculate number of required vertices / indexes at max resolution requiredVertexCount = meshWidth * meshHeight; int iterations = (side == VisibleSide.Both)? 2 : 1; requiredIndexCount = (meshWidth-1) * (meshHeight - 1) * 2 * iterations * 3; // Calculate bounds based on control points Vector3 min = Vector3.Zero; Vector3 max = Vector3.Zero; float maxSqRadius = 0.0f; bool first = true; for(int i = 0; i < controlPoints.Count; i++) { Vector3 vec = controlPoints[i]; if (first) { min = max = vec; maxSqRadius = vec.LengthSquared; first = false; } else { min.Floor(vec); max.Ceil(vec); maxSqRadius = MathUtil.Max(vec.LengthSquared, maxSqRadius); } } // set the bounds of the patch aabb.SetExtents(min, max); boundingSphereRadius = MathUtil.Sqrt(maxSqRadius); }
/// <summary> /// Sets up the surface by defining it's control points, type and initial subdivision level. /// </summary> /// <remarks> /// This method initialises the surface by passing it a set of control points. The type of curves to be used /// are also defined here, although the only supported option currently is a bezier patch. You can also /// specify a global subdivision level here if you like, although it is recommended that the parameter /// is left as AUTO_LEVEL, which means the system decides how much subdivision is required (based on the /// curvature of the surface). /// </remarks> /// <param name="controlPointArray"> /// An array containing the vertex data which define control points of the curves /// rather than actual vertices. Note that you are expected to provide not /// just position information, but potentially normals and texture coordinates too. /// The array is internally treated as a contiguous memory buffer without any gaps between the elements. /// The format of the buffer is defined in the VertexDeclaration parameter. /// </param> /// <param name="declaration"> /// VertexDeclaration describing the contents of the buffer. /// Note this declaration must _only_ draw on buffer source 0! /// </param> /// <param name="width">Specifies the width of the patch in control points.</param> /// <param name="height">Specifies the height of the patch in control points.</param> /// <param name="type">The type of surface.</param> /// <param name="uMaxSubdivisionLevel"> /// If you want to manually set the top level of subdivision, /// do it here, otherwise let the system decide. /// </param> /// <param name="vMaxSubdivisionLevel"> /// If you want to manually set the top level of subdivision, /// do it here, otherwise let the system decide. /// </param> /// <param name="visibleSide">Determines which side of the patch (or both) triangles are generated for.</param> public void DefineSurface( Array controlPointArray, VertexDeclaration declaration, int width, int height, PatchSurfaceType type, int uMaxSubdivisionLevel, int vMaxSubdivisionLevel, VisibleSide visibleSide ) { if ( height == 0 || width == 0 ) { return; // Do nothing - garbage } //pin the input to have a pointer Memory.UnpinObject( controlPointArray ); this.controlPointBuffer = Memory.PinObject( controlPointArray ); this.type = type; this.controlWidth = width; this.controlHeight = height; this.controlCount = width*height; this.declaration = declaration; // Copy positions into Vector3 vector this.controlPoints.Clear(); var elem = declaration.FindElementBySemantic( VertexElementSemantic.Position ); var vertSize = declaration.GetVertexSize( 0 ); #if !AXIOM_SAFE_ONLY unsafe #endif { var pVert = this.controlPointBuffer; for ( var i = 0; i < this.controlCount; i++ ) { var pReal = ( pVert + ( ( i*vertSize ) + elem.Offset ) ).ToFloatPointer(); this.controlPoints.Add( new Vector3( pReal[ 0 ], pReal[ 1 ], pReal[ 2 ] ) ); } } this.side = visibleSide; // Determine max level // Initialize to 100% detail this.subdivisionFactor = 1.0f; if ( uMaxSubdivisionLevel == AUTO_LEVEL ) { this.uLevel = this.maxULevel = GetAutoULevel(); } else { this.uLevel = this.maxULevel = uMaxSubdivisionLevel; } if ( vMaxSubdivisionLevel == AUTO_LEVEL ) { this.vLevel = this.maxVLevel = GetAutoVLevel(); } else { this.vLevel = this.maxVLevel = vMaxSubdivisionLevel; } // Derive mesh width / height this.meshWidth = ( LevelWidth( this.maxULevel ) - 1 )*( ( this.controlWidth - 1 )/2 ) + 1; this.meshHeight = ( LevelWidth( this.maxVLevel ) - 1 )*( ( this.controlHeight - 1 )/2 ) + 1; // Calculate number of required vertices / indexes at max resolution this.requiredVertexCount = this.meshWidth*this.meshHeight; var iterations = ( this.side == VisibleSide.Both ) ? 2 : 1; this.requiredIndexCount = ( this.meshWidth - 1 )*( this.meshHeight - 1 )*2*iterations*3; // Calculate bounds based on control points var min = Vector3.Zero; var max = Vector3.Zero; var maxSqRadius = 0.0f; var first = true; for ( var i = 0; i < this.controlPoints.Count; i++ ) { var vec = this.controlPoints[ i ]; if ( first ) { min = max = vec; maxSqRadius = vec.LengthSquared; first = false; } else { min.Floor( vec ); max.Ceil( vec ); maxSqRadius = Utility.Max( vec.LengthSquared, maxSqRadius ); } } // set the bounds of the patch this.aabb.SetExtents( min, max ); this.boundingSphereRadius = Utility.Sqrt( maxSqRadius ); }
//protected HardwareVertexBuffer GetVertexBuffer( ref List<HardwareVertexBuffer> list, int vertexSize, int numVertices ) protected HardwareVertexBuffer GetVertexBuffer( ref List<HardwareVertexBuffer> list, VertexDeclaration decl, int numVertices ) { int sz = decl.GetVertexSize()*numVertices; // vertexSize* numVertices; foreach ( var i in list ) { if ( i.Size == sz ) { HardwareVertexBuffer ret = i; list.Remove( i ); return ret; } } // Didn't find one? return HardwareBufferManager.Instance.CreateVertexBuffer( decl, numVertices, BufferUsage.StaticWriteOnly ); //TODO It should looks like this //return HardwareBufferManager.Instance.CreateVertexBuffer( vertexSize, numVertices, BufferUsage.StaticWriteOnly ); }
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); }