public static void GetSubmeshVertexData(out Vector3[] points, VertexData vertexData) { // if (subMesh.operationType != RenderMode.TriangleList) // continue; points = null; for (ushort bindIdx = 0; bindIdx < vertexData.vertexDeclaration.ElementCount; ++bindIdx) { VertexElement element = vertexData.vertexDeclaration.GetElement(bindIdx); HardwareVertexBuffer vBuffer = vertexData.vertexBufferBinding.GetBuffer(bindIdx); if (element.Semantic != VertexElementSemantic.Position) continue; points = new Vector3[vertexData.vertexCount]; ReadBuffer(vBuffer, vertexData.vertexCount, element.Size, ref points); return; } Debug.Assert(points != null, "Unable to retrieve position vertex data"); }
/// <summary> /// Default constructor. /// </summary> public WireBoundingBox() { vertexData = new VertexData(); vertexData.vertexCount = 24; vertexData.vertexStart = 0; // get a reference to the vertex declaration and buffer binding VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding binding = vertexData.vertexBufferBinding; // add elements for position and color only decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(COLOR, 0, VertexElementType.Color, VertexElementSemantic.Diffuse); // create a new hardware vertex buffer for the position data HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind the position buffer binding.SetBinding(POSITION, buffer); // create a new hardware vertex buffer for the color data buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(COLOR), vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind the color buffer binding.SetBinding(COLOR, buffer); Material mat = MaterialManager.Instance.GetByName("Core/WireBB"); if(mat == null) { mat = MaterialManager.Instance.GetByName("BaseWhite"); mat = mat.Clone("Core/WireBB"); mat.Lighting = false; } this.Material = mat; }
public GeometryBucket(MaterialBucket parent, string formatString, VertexData vData, IndexData iData) { // Clone the structure from the example this.parent = parent; this.formatString = formatString; vertexData = vData.Clone(false); indexData = iData.Clone(false); vertexData.vertexCount = 0; vertexData.vertexStart = 0; indexData.indexCount = 0; indexData.indexStart = 0; indexType = indexData.indexBuffer.Type; queuedGeometry = new List<QueuedGeometry>(); // Derive the max vertices if (indexType == IndexType.Size32) maxVertexIndex = int.MaxValue; else maxVertexIndex = ushort.MaxValue; // Check to see if we have blend indices / blend weights // remove them if so, they can try to blend non-existent bones! VertexElement blendIndices = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendIndices); VertexElement blendWeights = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendWeights); if (blendIndices != null && blendWeights != null) { Debug.Assert(blendIndices.Source == blendWeights.Source, "Blend indices and weights should be in the same buffer"); // Get the source ushort source = blendIndices.Source; Debug.Assert(blendIndices.Size + blendWeights.Size == vertexData.vertexBufferBinding.GetBuffer(source).VertexSize, "Blend indices and blend buffers should have buffer to themselves!"); // Unset the buffer vertexData.vertexBufferBinding.UnsetBinding(source); // Remove the elements vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendIndices); vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendWeights); } }
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; }
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; }
/// <summary> /// Internal method to clone vertex data definitions but to remove blend buffers. /// </summary> /// <param name="source">Vertex data to clone.</param> /// <returns>A cloned instance of 'source' without blending information.</returns> protected internal VertexData CloneVertexDataRemoveBlendInfo( VertexData source ) { // Clone without copying data var ret = source.Clone( false ); var blendIndexElem = source.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.BlendIndices ); var blendWeightElem = source.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.BlendWeights ); // Remove blend index if ( blendIndexElem != null ) { // Remove buffer reference ret.vertexBufferBinding.UnsetBinding( blendIndexElem.Source ); } if ( blendWeightElem != null && blendWeightElem.Source != blendIndexElem.Source ) { // Remove buffer reference ret.vertexBufferBinding.UnsetBinding( blendWeightElem.Source ); } // remove elements from declaration ret.vertexDeclaration.RemoveElement( VertexElementSemantic.BlendIndices ); ret.vertexDeclaration.RemoveElement( VertexElementSemantic.BlendWeights ); // copy reference to w-coord buffer if ( source.hardwareShadowVolWBuffer != null ) { ret.hardwareShadowVolWBuffer = source.hardwareShadowVolWBuffer; } return ret; }
/// <summary> /// Initialize the hardware animation elements for given vertex data /// </summary> private void InitHardwareAnimationElements( VertexData vdata, ushort numberOfElements ) { if ( vdata.HWAnimationDataList.Count < numberOfElements ) { vdata.AllocateHardwareAnimationElements( numberOfElements ); } // Initialize parametrics incase we don't use all of them for ( var i = 0; i < vdata.HWAnimationDataList.Count; i++ ) { vdata.HWAnimationDataList[ i ].Parametric = 0.0f; } // reset used count vdata.HWAnimDataItemsUsed = 0; }
private VertexData InitVertexBuffer(int numVerts) { vertexData = new VertexData(); vertexData.vertexCount = numVerts; vertexData.vertexStart = 0; // set up the vertex declaration int vDecOffset = 0; vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2); // create the hardware vertex buffer and set up the buffer binding HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, BufferUsage.StaticWriteOnly, false); vertexData.vertexBufferBinding.SetBinding(0, hvBuffer); return vertexData; }
protected override void ReadGeometryTexCoords( short bindIdx, BinaryReader reader, VertexData data, int coordSet ) { // get the number of texture dimensions (1D, 2D, 3D, etc) var dim = ReadUShort( reader ); // add a vertex element for the current tex coord set data.vertexDeclaration.AddElement( bindIdx, 0, VertexElement.MultiplyTypeCount( VertexElementType.Float1, dim ), VertexElementSemantic.TexCoords, coordSet ); // create the vertex buffer for the tex coords var vBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( data.vertexDeclaration.Clone( bindIdx ), data.vertexCount, mesh.VertexBufferUsage, mesh.UseVertexShadowBuffer ); // lock the vertex buffer var texCoords = vBuffer.Lock( BufferLocking.Discard ); // blast the tex coord data into the buffer ReadFloats( reader, data.vertexCount*dim, texCoords ); // Adjust individual v values to (1 - v) if ( dim == 2 ) { var count = 0; #if !AXIOM_SAFE_ONLY unsafe #endif { var pTex = texCoords.ToFloatPointer(); for ( var i = 0; i < data.vertexCount; i++ ) { count++; // skip u pTex[ count ] = 1.0f - pTex[ count ]; // v = 1 - v count++; } } } // unlock the buffer to commit vBuffer.Unlock(); // bind the tex coord buffer data.vertexBufferBinding.SetBinding( bindIdx, vBuffer ); }
protected virtual void ReadGeometryColors( short bindIdx, BinaryReader reader, VertexData data ) { // add an element for normals data.vertexDeclaration.AddElement( bindIdx, 0, VertexElementType.Color, VertexElementSemantic.Diffuse ); var vBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( data.vertexDeclaration.Clone( bindIdx ), data.vertexCount, mesh.VertexBufferUsage, mesh.UseVertexShadowBuffer ); // lock the buffer for editing var colors = vBuffer.Lock( BufferLocking.Discard ); // stuff the floats into the normal buffer ReadInts( reader, data.vertexCount, colors ); // unlock the buffer to commit vBuffer.Unlock(); // bind this buffer data.vertexBufferBinding.SetBinding( bindIdx, vBuffer ); }
/// <summary> /// Internal method - given vertex data which could be from the <see cref="Mesh"/> or /// any <see cref="SubMesh"/>, finds the temporary blend copy. /// </summary> /// <param name="originalData"></param> /// <returns></returns> protected VertexData FindBlendedVertexData( VertexData originalData ) { if ( originalData == this.mesh.SharedVertexData ) { return HasSkeleton ? this.skelAnimVertexData : this.softwareVertexAnimVertexData; } foreach ( var se in this.subEntityList ) { if ( originalData == se.SubMesh.vertexData ) { return HasSkeleton ? se.SkelAnimVertexData : se.SoftwareVertexAnimVertexData; } } throw new Exception( "Cannot find blended version of the vertex data specified." ); }
/// <summary> /// Clones this vertex data, potentially including replicating any vertex buffers. /// </summary> /// <param name="copyData"> /// If true, makes a copy the vertex buffer in addition to the definition. /// If false, the clone will refer to the same vertex buffer this object refers to. /// </param> /// <returns>A cloned vertex data object.</returns> public VertexData Clone(bool copyData) { var dest = new VertexData(); // Copy vertex buffers in turn var bindings = this.vertexBufferBinding.Bindings; foreach (var source in bindings.Keys) { var srcbuf = bindings[source]; HardwareVertexBuffer dstBuf; if (copyData) { // create new buffer with the same settings dstBuf = HardwareBufferManager.Instance.CreateVertexBuffer(srcbuf.VertexDeclaration, srcbuf.VertexCount, srcbuf.Usage, srcbuf.HasShadowBuffer); // copy data dstBuf.CopyTo(srcbuf, 0, 0, srcbuf.Size, true); } else { // don't copy, point at existing buffer dstBuf = srcbuf; } // Copy binding dest.vertexBufferBinding.SetBinding(source, dstBuf); } // Basic vertex info dest.vertexStart = this.vertexStart; dest.vertexCount = this.vertexCount; // Copy elements for (var i = 0; i < this.vertexDeclaration.ElementCount; i++) { var element = this.vertexDeclaration.GetElement(i); dest.vertexDeclaration.AddElement(element.Source, element.Offset, element.Type, element.Semantic, element.Index); } // Copy hardware shadow buffer if set up if (this.hardwareShadowVolWBuffer != null) { dest.hardwareShadowVolWBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(this.hardwareShadowVolWBuffer.VertexDeclaration, this.hardwareShadowVolWBuffer.VertexCount, this.hardwareShadowVolWBuffer.Usage, this.hardwareShadowVolWBuffer.HasShadowBuffer); // copy data dest.hardwareShadowVolWBuffer.CopyTo(this.hardwareShadowVolWBuffer, 0, 0, this.hardwareShadowVolWBuffer.Size, true); } // copy anim data dest.HWAnimationDataList = this.HWAnimationDataList; dest.HWAnimDataItemsUsed = this.HWAnimDataItemsUsed; return(dest); }
public unsafe void DebugLog(Log log) { log.Write("EdgeListBuilder Log"); log.Write("-------------------"); log.Write("Number of vertex sets: {0}", vertexDataList.Count); log.Write("Number of index sets: {0}", indexDataList.Count); int i, j; // Log original vertex data for (i = 0; i < vertexDataList.Count; i++) { VertexData vData = (VertexData)vertexDataList[i]; log.Write("."); log.Write("Original vertex set {0} - vertex count {1}", i, vData.vertexCount); VertexElement posElem = vData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position); HardwareVertexBuffer vbuf = vData.vertexBufferBinding.GetBuffer(posElem.Source); // lock the buffer for reading IntPtr basePtr = vbuf.Lock(BufferLocking.ReadOnly); byte *pBaseVertex = (byte *)basePtr.ToPointer(); float *pReal; for (j = 0; j < vData.vertexCount; j++) { pReal = (float *)(pBaseVertex + posElem.Offset); log.Write("Vertex {0}: ({1}, {2}, {3})", j, pReal[0], pReal[1], pReal[2]); pBaseVertex += vbuf.VertexSize; } vbuf.Unlock(); } // Log original index data for (i = 0; i < indexDataList.Count; i += 3) { IndexData iData = (IndexData)indexDataList[i]; log.Write("."); log.Write("Original triangle set {0} - index count {1} - vertex set {2})", i, iData.indexCount, indexDataVertexDataSetList[i]); // Get the indexes ready for reading short *p16Idx = null; int * p32Idx = null; IntPtr idxPtr = iData.indexBuffer.Lock(BufferLocking.ReadOnly); if (iData.indexBuffer.Type == IndexType.Size32) { p32Idx = (int *)idxPtr.ToPointer(); } else { p16Idx = (short *)idxPtr.ToPointer(); } for (j = 0; j < iData.indexCount / 3; j++) { if (iData.indexBuffer.Type == IndexType.Size32) { log.Write("Triangle {0}: ({1}, {2}, {3})", j, *p32Idx++, *p32Idx++, *p32Idx++); } else { log.Write("Triangle {0}: ({1}, {2}, {3})", j, *p16Idx++, *p16Idx++, *p16Idx++); } } iData.indexBuffer.Unlock(); // Log common vertex list log.Write("."); log.Write("Common vertex list - vertex count {0}", vertices.Count); for (i = 0; i < vertices.Count; i++) { CommonVertex c = (CommonVertex)vertices[i]; log.Write("Common vertex {0}: (vertexSet={1}, originalIndex={2}, position={3}", i, c.vertexSet, c.index, c.position); } } }
/// <summary> /// /// </summary> /// <param name="indexSet"></param> /// <param name="vertexSet"></param> protected void BuildTrianglesEdges(int indexSet, int vertexSet) { IndexData indexData = (IndexData)indexDataList[indexSet]; OperationType opType = operationTypes[indexSet]; int iterations = 0; switch (opType) { case OperationType.TriangleList: iterations = indexData.indexCount / 3; break; case OperationType.TriangleFan: case OperationType.TriangleStrip: iterations = indexData.indexCount - 2; break; } // locate postion element & the buffer to go with it VertexData vertexData = (VertexData)vertexDataList[vertexSet]; VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position); HardwareVertexBuffer posBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); IntPtr posPtr = posBuffer.Lock(BufferLocking.ReadOnly); IntPtr idxPtr = indexData.indexBuffer.Lock(BufferLocking.ReadOnly); unsafe { byte *pBaseVertex = (byte *)posPtr.ToPointer(); short *p16Idx = null; int * p32Idx = null; // counters used for pointer indexing int count16 = 0; int count32 = 0; if (indexData.indexBuffer.Type == IndexType.Size16) { p16Idx = (short *)idxPtr.ToPointer(); } else { p32Idx = (int *)idxPtr.ToPointer(); } float *pReal = null; int triStart = edgeData.triangles.Count; // iterate over all the groups of 3 indices edgeData.triangles.Capacity = triStart + iterations; for (int t = 0; t < iterations; t++) { EdgeData.Triangle tri = new EdgeData.Triangle(); tri.indexSet = indexSet; tri.vertexSet = vertexSet; int[] index = new int[3]; Vector3[] v = new Vector3[3]; for (int i = 0; i < 3; i++) { // Standard 3-index read for tri list or first tri in strip / fan if (opType == OperationType.TriangleList || t == 0) { if (indexData.indexBuffer.Type == IndexType.Size32) { index[i] = p32Idx[count32++]; } else { index[i] = p16Idx[count16++]; } } else { // Strips and fans are formed from last 2 indexes plus the // current one for triangles after the first if (indexData.indexBuffer.Type == IndexType.Size32) { index[i] = p32Idx[i - 2]; } else { index[i] = p16Idx[i - 2]; } // Perform single-index increment at the last tri index if (i == 2) { if (indexData.indexBuffer.Type == IndexType.Size32) { count32++; } else { count16++; } } } // populate tri original vertex index tri.vertIndex[i] = index[i]; // Retrieve the vertex position byte *pVertex = pBaseVertex + (index[i] * posBuffer.VertexSize); pReal = (float *)(pVertex + posElem.Offset); v[i].x = *pReal++; v[i].y = *pReal++; v[i].z = *pReal++; // find this vertex in the existing vertex map, or create it tri.sharedVertIndex[i] = FindOrCreateCommonVertex(v[i], vertexSet, indexSet, index[i]); } // Calculate triangle normal (NB will require recalculation for // skeletally animated meshes) tri.normal = MathUtil.CalculateFaceNormal(v[0], v[1], v[2]); // Add triangle to list edgeData.triangles.Add(tri); try { // create edges from common list if (tri.sharedVertIndex[0] < tri.sharedVertIndex[1]) { CreateEdge(vertexSet, triStart + t, tri.vertIndex[0], tri.vertIndex[1], tri.sharedVertIndex[0], tri.sharedVertIndex[1]); } if (tri.sharedVertIndex[1] < tri.sharedVertIndex[2]) { CreateEdge(vertexSet, triStart + t, tri.vertIndex[1], tri.vertIndex[2], tri.sharedVertIndex[1], tri.sharedVertIndex[2]); } if (tri.sharedVertIndex[2] < tri.sharedVertIndex[0]) { CreateEdge(vertexSet, triStart + t, tri.vertIndex[2], tri.vertIndex[0], tri.sharedVertIndex[2], tri.sharedVertIndex[0]); } } catch (Exception ex) { //Debug.WriteLine(ex.ToString()); //Debug.WriteLine(ex.StackTrace); // unlock those buffers! indexData.indexBuffer.Unlock(); posBuffer.Unlock(); throw ex; } } // for iterations } // unsafe // unlock those buffers! indexData.indexBuffer.Unlock(); posBuffer.Unlock(); }
public EntityShadowRenderable( Entity parent, HardwareIndexBuffer indexBuffer, VertexData vertexData, bool createSeperateLightCap, SubEntity subEntity ) : this( parent, indexBuffer, vertexData, createSeperateLightCap, subEntity, false ) { }
/// <summary> /// Rebind the source positions for temp buffer users. /// </summary> public void RebindPositionBuffer( VertexData vertexData, bool force ) { if ( force || this.currentVertexData != vertexData ) { this.currentVertexData = vertexData; this.positionBuffer = this.currentVertexData.vertexBufferBinding.GetBuffer( this.originalPosBufferBinding ); renderOperation.vertexData.vertexBufferBinding.SetBinding( 0, this.positionBuffer ); if ( lightCap != null ) { ( (EntityShadowRenderable)lightCap ).RebindPositionBuffer( vertexData, force ); } } }
/// <summary> /// Add a set of vertex geometry data to the edge builder. /// </summary> /// <remarks> /// You must add at least one set of vertex data to the builder before invoking the /// <see name="Build"/> method. /// </remarks> /// <param name="vertexData">Vertex data to consider for edge detection.</param> public void AddVertexData(VertexData vertexData) { this.vertexDataList.Add(vertexData); }
/// <summary> /// Clones this vertex data, potentially including replicating any vertex buffers. /// </summary> /// <param name="copyData"> /// If true, makes a copy the vertex buffer in addition to the definition. /// If false, the clone will refer to the same vertex buffer this object refers to. /// </param> /// <returns>A cloned vertex data object.</returns> public VertexData Clone( bool copyData ) { VertexData dest = new VertexData(); // Copy vertex buffers in turn Dictionary<short, HardwareVertexBuffer> bindings = vertexBufferBinding.Bindings; foreach ( short source in bindings.Keys ) { HardwareVertexBuffer srcbuf = bindings[ source ]; HardwareVertexBuffer dstBuf; if ( copyData ) { // create new buffer with the same settings dstBuf = HardwareBufferManager.Instance.CreateVertexBuffer( srcbuf.VertexDeclaration, srcbuf.VertexCount, srcbuf.Usage, srcbuf.HasShadowBuffer ); // copy data dstBuf.CopyData( srcbuf, 0, 0, srcbuf.Size, true ); } else { // don't copy, point at existing buffer dstBuf = srcbuf; } // Copy binding dest.vertexBufferBinding.SetBinding( source, dstBuf ); } // Basic vertex info dest.vertexStart = this.vertexStart; dest.vertexCount = this.vertexCount; // Copy elements for ( int i = 0; i < vertexDeclaration.ElementCount; i++ ) { VertexElement element = vertexDeclaration.GetElement( i ); dest.vertexDeclaration.AddElement( element.Source, element.Offset, element.Type, element.Semantic, element.Index ); } // Copy hardware shadow buffer if set up if ( hardwareShadowVolWBuffer != null ) { dest.hardwareShadowVolWBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( hardwareShadowVolWBuffer.VertexDeclaration, hardwareShadowVolWBuffer.VertexCount, hardwareShadowVolWBuffer.Usage, hardwareShadowVolWBuffer.HasShadowBuffer ); // copy data dest.hardwareShadowVolWBuffer.CopyData( hardwareShadowVolWBuffer, 0, 0, hardwareShadowVolWBuffer.Size,true ); } // copy anim data dest.HWAnimationDataList = HWAnimationDataList; dest.HWAnimDataItemsUsed = HWAnimDataItemsUsed; return dest; }
public List <TriangleVertices> Build() { List <TriangleVertices> triangles = new List <TriangleVertices>(); try { for (int ind = 0, indexSet = 0; ind < indexDataList.Count; ind++, indexSet++) { int vertexSet = (int)indexDataVertexDataSetList[ind]; IndexData indexData = (IndexData)indexDataList[indexSet]; OperationType opType = operationTypes[indexSet]; int iterations = 0; switch (opType) { case OperationType.TriangleList: iterations = indexData.indexCount / 3; break; case OperationType.TriangleFan: case OperationType.TriangleStrip: iterations = indexData.indexCount - 2; break; } // locate position element & the buffer to go with it VertexData vertexData = (VertexData)vertexDataList[vertexSet]; VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position); HardwareVertexBuffer posBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); try { IntPtr posPtr = posBuffer.Lock(BufferLocking.ReadOnly); IntPtr idxPtr = indexData.indexBuffer.Lock(BufferLocking.ReadOnly); unsafe { byte *pBaseVertex = (byte *)posPtr.ToPointer(); ushort *p16Idx = null; uint * p32Idx = null; // counters used for pointer indexing int count16 = 0; int count32 = 0; if (indexData.indexBuffer.Type == IndexType.Size16) { p16Idx = (ushort *)idxPtr.ToPointer(); } else { p32Idx = (uint *)idxPtr.ToPointer(); } float *pReal = null; int triStart = triangles.Count; // iterate over all the groups of 3 indices triangles.Capacity = triStart + iterations; uint[] index = new uint[3]; for (int t = 0; t < iterations; t++) { Vector3[] v = new Vector3[3]; TriangleVertices tri = new TriangleVertices(v); bool broken = false; for (int i = 0; i < 3; i++) { // Standard 3-index read for tri list or first tri in strip / fan if (opType == OperationType.TriangleList || t == 0) { if (indexData.indexBuffer.Type == IndexType.Size32) { index[i] = p32Idx[count32++]; } else { index[i] = p16Idx[count16++]; } } else { // Strips and fans are formed from last 2 indexes plus the // current one for triangles after the first if (indexData.indexBuffer.Type == IndexType.Size32) { index[i] = p32Idx[i - 2]; } else { index[i] = p16Idx[i - 2]; } // Perform single-index increment at the last tri index if (i == 2) { if (indexData.indexBuffer.Type == IndexType.Size32) { count32++; } else { count16++; } } } // Retrieve the vertex position if (index[i] >= posBuffer.VertexCount) { log.InfoFormat("TriangleListBuilder.Build: Error: index[i] {0} is not less than posBuffer.VertexCount {1}, iteration t {2}", index[i], posBuffer.VertexCount, t); broken = true; break; } Debug.Assert(index[i] < posBuffer.VertexCount); byte *pVertex = pBaseVertex + (index[i] * posBuffer.VertexSize); pReal = (float *)(pVertex + posElem.Offset); v[i].x = *pReal++; v[i].y = *pReal++; v[i].z = *pReal++; } if (!broken) { // Put the points in in counter-clockwise order if (((v[0].x - v[2].x) * (v[1].y - v[2].y) - (v[1].x - v[2].x) * (v[0].y - v[2].y)) < 0) { // Clockwise, so reverse points 1 and 2 Vector3 tmp = v[1]; v[1] = v[2]; v[2] = tmp; } // Debug.Assert(((v[0].x - v[2].x) * (v[1].y - v[2].y) - (v[1].x - v[2].x) * (v[0].y - v[2].y)) >= 0); // Add to the list of triangles triangles.Add(new TriangleVertices(v)); } } // for iterations } // unsafe } finally { // unlock those buffers! indexData.indexBuffer.Unlock(); posBuffer.Unlock(); } } return(triangles); } catch (Exception e) { log.ErrorFormat("TriangleListBuilder.Build: Exception raised during triangle building: {0}", e.Message); triangles.Clear(); return(triangles); } }
protected virtual void ReadGeometryPositions( short bindIdx, BinaryReader reader, VertexData data ) { data.vertexDeclaration.AddElement( bindIdx, 0, VertexElementType.Float3, VertexElementSemantic.Position ); // vertex buffers var vBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( data.vertexDeclaration.Clone( bindIdx ), data.vertexCount, mesh.VertexBufferUsage, mesh.UseVertexShadowBuffer ); var posData = vBuffer.Lock( BufferLocking.Discard ); // ram the floats into the buffer data ReadFloats( reader, data.vertexCount*3, posData ); // unlock the buffer vBuffer.Unlock(); // bind the position data data.vertexBufferBinding.SetBinding( bindIdx, vBuffer ); }
public Rectangle2D(bool includeTextureCoordinates) { // use identity projection and view matrices vertexData = new VertexData(); renderOperation.vertexData = vertexData; renderOperation.vertexData.vertexStart = 0; renderOperation.vertexData.vertexCount = 4; renderOperation.useIndices = false; renderOperation.operationType = OperationType.TriangleStrip; var decl = vertexData.vertexDeclaration; var binding = vertexData.vertexBufferBinding; decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); var buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); binding.SetBinding(POSITION, buffer); decl.AddElement(NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal); buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(NORMAL), renderOperation.vertexData.vertexCount, BufferUsage.StaticWriteOnly); binding.SetBinding(NORMAL, buffer); #if !AXIOM_SAFE_ONLY unsafe #endif { var pNormBuf = buffer.Lock(BufferLocking.Discard).ToFloatPointer(); var pNorm = 0; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 1.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 1.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 1.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm++] = 0.0f; pNormBuf[pNorm] = 1.0f; buffer.Unlock(); } if (includeTextureCoordinates) { decl.AddElement(TEXCOORD, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords); buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(TEXCOORD), vertexData.vertexCount, BufferUsage.StaticWriteOnly); binding.SetBinding(TEXCOORD, buffer); buffer.WriteData(0, buffer.Size, texCoords, true); } // TODO: Fix material = (Material)MaterialManager.Instance["BaseWhite"]; material.Lighting = false; }
protected virtual void ReadGeometryTexCoords( short bindIdx, BinaryReader reader, VertexData data, int coordSet ) { // get the number of texture dimensions (1D, 2D, 3D, etc) var dim = ReadShort( reader ); // add a vertex element for the current tex coord set data.vertexDeclaration.AddElement( bindIdx, 0, VertexElement.MultiplyTypeCount( VertexElementType.Float1, dim ), VertexElementSemantic.TexCoords, coordSet ); // create the vertex buffer for the tex coords var vBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( data.vertexDeclaration.Clone( bindIdx ), data.vertexCount, mesh.VertexBufferUsage, mesh.UseVertexShadowBuffer ); // lock the vertex buffer var texCoords = vBuffer.Lock( BufferLocking.Discard ); // blast the tex coord data into the buffer ReadFloats( reader, data.vertexCount*dim, texCoords ); // unlock the buffer to commit vBuffer.Unlock(); // bind the tex coord buffer data.vertexBufferBinding.SetBinding( bindIdx, vBuffer ); }
/// <summary> /// Utility method, extract info from the given VertexData /// </summary> public void ExtractFrom(VertexData sourceData) { // Release old buffer copies first HardwareBufferManager mgr = HardwareBufferManager.Instance; if (destPositionBuffer != null) { mgr.ReleaseVertexBufferCopy(destPositionBuffer); Debug.Assert(destPositionBuffer == null); } if (destNormalBuffer != null) { mgr.ReleaseVertexBufferCopy(destNormalBuffer); Debug.Assert(destNormalBuffer == null); } VertexDeclaration decl = sourceData.vertexDeclaration; VertexBufferBinding bind = sourceData.vertexBufferBinding; VertexElement posElem = decl.FindElementBySemantic(VertexElementSemantic.Position); VertexElement normElem = decl.FindElementBySemantic(VertexElementSemantic.Normal); VertexElement tanElem = decl.FindElementBySemantic(VertexElementSemantic.Tangent); VertexElement binormElem = decl.FindElementBySemantic(VertexElementSemantic.Binormal); Debug.Assert(posElem != null, "Positions are required"); posBindIndex = posElem.Source; srcPositionBuffer = bind.GetBuffer(posBindIndex); if (normElem == null) { posNormalShareBuffer = false; srcNormalBuffer = null; } else { normBindIndex = normElem.Source; if (normBindIndex == posBindIndex) { posNormalShareBuffer = true; srcNormalBuffer = null; } else { posNormalShareBuffer = false; srcNormalBuffer = bind.GetBuffer(normBindIndex); } } if (tanElem == null) { srcTangentBuffer = null; } else { tanBindIndex = tanElem.Source; srcTangentBuffer = bind.GetBuffer(tanBindIndex); } if (binormElem == null) { srcBinormalBuffer = null; } else { binormBindIndex = binormElem.Source; srcBinormalBuffer = bind.GetBuffer(binormBindIndex); } }
protected void WriteGeometry( BinaryWriter writer, VertexData vertexData ) { var start_offset = writer.Seek( 0, SeekOrigin.Current ); WriteChunk( writer, MeshChunkID.Geometry, 0 ); WriteUInt( writer, (uint)vertexData.vertexCount ); WriteGeometryVertexDeclaration( writer, vertexData.vertexDeclaration ); for ( short i = 0; i < vertexData.vertexBufferBinding.BindingCount; ++i ) { WriteGeometryVertexBuffer( writer, i, vertexData.vertexBufferBinding.GetBuffer( i ) ); } var end_offset = writer.Seek( 0, SeekOrigin.Current ); writer.Seek( (int)start_offset, SeekOrigin.Begin ); WriteChunk( writer, MeshChunkID.Geometry, (int)( end_offset - start_offset ) ); writer.Seek( (int)end_offset, SeekOrigin.Begin ); }
/// <summary> /// Allocate / reallocate vertex data /// Note that we allocate enough space for ALL the billboards in the pool, but only issue /// rendering operations for the sections relating to the active billboards /// </summary> private void CreateBuffers() { /* Alloc positions ( 1 or 4 verts per billboard, 3 components ) colours ( 1 x RGBA per vertex ) indices ( 6 per billboard ( 2 tris ) if not point rendering ) tex. coords ( 2D coords, 1 or 4 per billboard ) */ // LogManager.Instance.Write(string.Format("BillBoardSet.CreateBuffers entered; vertexData {0}, indexData {1}, mainBuffer {2}", // vertexData == null ? "null" : vertexData.ToString(), // indexData == null ? "null" : indexData.ToString(), // mainBuffer == null ? "null" : mainBuffer.ToString())); // Warn if user requested an invalid setup // Do it here so it only appears once if ( this.pointRendering && this.billboardType != BillboardType.Point ) { LogManager.Instance.Write( "Warning: BillboardSet {0} has point rendering enabled but is using a type " + "other than BillboardType.Point, this may not give you the results you " + "expect.", this.name ); } this.vertexData = new VertexData(); if ( this.pointRendering ) { this.vertexData.vertexCount = this.poolSize; } else { this.vertexData.vertexCount = this.poolSize * 4; } this.vertexData.vertexStart = 0; // Vertex declaration VertexDeclaration decl = this.vertexData.vertexDeclaration; VertexBufferBinding binding = this.vertexData.vertexBufferBinding; int offset = 0; decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Position ); offset += VertexElement.GetTypeSize( VertexElementType.Float3 ); decl.AddElement( 0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse ); offset += VertexElement.GetTypeSize( VertexElementType.Color ); // Texture coords irrelevant when enabled point rendering (generated // in point sprite mode, and unused in standard point mode) if ( !this.pointRendering ) { decl.AddElement( 0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 ); } this.mainBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( 0 ), this.vertexData.vertexCount, BufferUsage.DynamicWriteOnlyDiscardable ); // bind position and diffuses binding.SetBinding( 0, this.mainBuffer ); if ( !this.pointRendering ) { this.indexData = new IndexData(); // calc index buffer size this.indexData.indexStart = 0; this.indexData.indexCount = this.poolSize * 6; // create the index buffer this.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, this.indexData.indexCount, BufferUsage.StaticWriteOnly ); /* Create indexes (will be the same every frame) Using indexes because it means 1/3 less vertex transforms (4 instead of 6) Billboard layout relative to camera: 0-----1 | /| | / | |/ | 2-----3 */ // lock the index buffer IntPtr idxPtr = this.indexData.indexBuffer.Lock( BufferLocking.Discard ); unsafe { ushort* pIdx = (ushort*)idxPtr.ToPointer(); for ( int idx, idxOffset, bboard = 0; bboard < this.poolSize; ++bboard ) { // Do indexes idx = bboard * 6; idxOffset = bboard * 4; pIdx[ idx ] = (ushort)idxOffset; // + 0;, for clarity pIdx[ idx + 1 ] = (ushort)( idxOffset + 2 ); pIdx[ idx + 2 ] = (ushort)( idxOffset + 1 ); pIdx[ idx + 3 ] = (ushort)( idxOffset + 1 ); pIdx[ idx + 4 ] = (ushort)( idxOffset + 2 ); pIdx[ idx + 5 ] = (ushort)( idxOffset + 3 ); } // for } // unsafe // unlock the buffers this.indexData.indexBuffer.Unlock(); } this.buffersCreated = true; }
public Rectangle2D( bool includeTextureCoordinates ) { // use identity projection and view matrices vertexData = new VertexData(); renderOperation.vertexData = vertexData; renderOperation.vertexData.vertexStart = 0; renderOperation.vertexData.vertexCount = 4; renderOperation.useIndices = false; renderOperation.operationType = OperationType.TriangleStrip; var decl = vertexData.vertexDeclaration; var binding = vertexData.vertexBufferBinding; decl.AddElement( POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position ); var buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( POSITION ), vertexData.vertexCount, BufferUsage.StaticWriteOnly ); binding.SetBinding( POSITION, buffer ); decl.AddElement( NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal ); buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( NORMAL ), renderOperation.vertexData.vertexCount, BufferUsage.StaticWriteOnly ); binding.SetBinding( NORMAL, buffer ); #if !AXIOM_SAFE_ONLY unsafe #endif { var pNormBuf = buffer.Lock( BufferLocking.Discard ).ToFloatPointer(); var pNorm = 0; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 1.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 1.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 1.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm++ ] = 0.0f; pNormBuf[ pNorm ] = 1.0f; buffer.Unlock(); } if ( includeTextureCoordinates ) { decl.AddElement( TEXCOORD, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords ); buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( TEXCOORD ), vertexData.vertexCount, BufferUsage.StaticWriteOnly ); binding.SetBinding( TEXCOORD, buffer ); buffer.WriteData( 0, buffer.Size, texCoords, true ); } // TODO: Fix material = (Material)MaterialManager.Instance[ "BaseWhite" ]; material.Lighting = false; }
private void DestroyBuffers() { // LogManager.Instance.Write(string.Format("BillBoardSet.DestroyBuffers entered; vertexData {0}, indexData {1}, mainBuffer {2}", // vertexData == null ? "null" : vertexData.ToString(), // indexData == null ? "null" : indexData.ToString(), // mainBuffer == null ? "null" : mainBuffer.ToString())); this.vertexData = null; this.indexData = null; this.mainBuffer = null; this.buffersCreated = false; }
/// <summary> /// Internal method for preparing this Entity for use in animation. /// </summary> protected internal void PrepareTempBlendedBuffers() { if ( this.skelAnimVertexData != null ) { this.skelAnimVertexData = null; } if ( this.softwareVertexAnimVertexData != null ) { this.softwareVertexAnimVertexData = null; } if ( this.hardwareVertexAnimVertexData != null ) { this.hardwareVertexAnimVertexData = null; } if ( this.mesh.HasVertexAnimation ) { // Shared data if ( this.mesh.SharedVertexData != null && this.mesh.SharedVertexDataAnimationType != VertexAnimationType.None && this.tempVertexAnimInfo != null ) { // Create temporary vertex blend info // Prepare temp vertex data if needed // Clone without copying data, don't remove any blending info // (since if we skeletally animate too, we need it) this.softwareVertexAnimVertexData = this.mesh.SharedVertexData.Clone( false ); ExtractTempBufferInfo( this.softwareVertexAnimVertexData, this.tempVertexAnimInfo ); // Also clone for hardware usage, don't remove blend info since we'll // need it if we also hardware skeletally animate this.hardwareVertexAnimVertexData = this.mesh.SharedVertexData.Clone( false ); } } if ( HasSkeleton ) { // shared data if ( this.mesh.SharedVertexData != null ) { // Create temporary vertex blend info // Prepare temp vertex data if needed // Clone without copying data, remove blending info // (since blend is performed in software) this.skelAnimVertexData = CloneVertexDataRemoveBlendInfo( this.mesh.SharedVertexData ); ExtractTempBufferInfo( this.skelAnimVertexData, this.tempSkelAnimInfo ); } } // prepare temp blending buffers for subentites as well foreach ( var se in this.subEntityList ) { se.PrepareTempBlendBuffers(); } }
protected virtual void ReadGeometry( BinaryReader reader, VertexData data ) { data.vertexStart = 0; data.vertexCount = ReadInt( reader ); // find optional geometry chunks if ( !IsEOF( reader ) ) { var chunkID = ReadChunk( reader ); while ( !IsEOF( reader ) && ( chunkID == MeshChunkID.GeometryVertexDeclaration || chunkID == MeshChunkID.GeometryVertexBuffer ) ) { switch ( chunkID ) { case MeshChunkID.GeometryVertexDeclaration: ReadGeometryVertexDeclaration( reader, data ); break; case MeshChunkID.GeometryVertexBuffer: ReadGeometryVertexBuffer( reader, data ); break; } // get the next chunk if ( !IsEOF( reader ) ) { chunkID = ReadChunk( reader ); } } if ( !IsEOF( reader ) ) { // backpedal to start of non-submesh chunk Seek( reader, -ChunkOverheadSize ); } // TODO : Implement color conversions // Perform any necessary color conversion for an active rendersystem //if ( Root.Instance != null && Root.Instance.RenderSystem != null ) //{ // // We don't know the source type if it's VET_COLOUR, but assume ARGB // // since that's the most common. Won't get used unless the mesh is // // ambiguous anyway, which will have been warned about in the log // data.ConvertPackedColor( VertexElementType.Color, VertexElement.BestColorVertexElementType ); //} } }
/// <summary> /// Internal method for extracting metadata out of source vertex data /// for fast assignment of temporary buffers later. /// </summary> /// <param name="sourceData"></param> /// <param name="info"></param> protected internal void ExtractTempBufferInfo( VertexData sourceData, TempBlendedBufferInfo info ) { info.ExtractFrom( sourceData ); }
protected virtual void ReadGeometryVertexDeclaration( BinaryReader reader, VertexData data ) { // find optional geometry chunks if ( !IsEOF( reader ) ) { var chunkID = ReadChunk( reader ); while ( !IsEOF( reader ) && ( chunkID == MeshChunkID.GeometryVertexElement ) ) { switch ( chunkID ) { case MeshChunkID.GeometryVertexElement: ReadGeometryVertexElement( reader, data ); break; } // get the next chunk if ( !IsEOF( reader ) ) { chunkID = ReadChunk( reader ); } } if ( !IsEOF( reader ) ) { // backpedal to start of non-submesh chunk Seek( reader, -ChunkOverheadSize ); } } }
public EntityShadowRenderable( Entity parent, HardwareIndexBuffer indexBuffer, VertexData vertexData, bool createSeparateLightCap, SubEntity subEntity, bool isLightCap ) { this.parent = parent; // Save link to vertex data this.currentVertexData = vertexData; // Initialize render op renderOperation.indexData = new IndexData(); renderOperation.indexData.indexBuffer = indexBuffer; renderOperation.indexData.indexStart = 0; // index start and count are sorted out later // Create vertex data which just references position component (and 2 component) renderOperation.vertexData = new VertexData(); renderOperation.vertexData.vertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration(); renderOperation.vertexData.vertexBufferBinding = HardwareBufferManager.Instance.CreateVertexBufferBinding(); // Map in position data renderOperation.vertexData.vertexDeclaration.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ); this.originalPosBufferBinding = vertexData.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position ).Source; this.positionBuffer = vertexData.vertexBufferBinding.GetBuffer( this.originalPosBufferBinding ); renderOperation.vertexData.vertexBufferBinding.SetBinding( 0, this.positionBuffer ); // Map in w-coord buffer (if present) if ( vertexData.hardwareShadowVolWBuffer != null ) { renderOperation.vertexData.vertexDeclaration.AddElement( 1, 0, VertexElementType.Float1, VertexElementSemantic.TexCoords, 0 ); this.wBuffer = vertexData.hardwareShadowVolWBuffer; renderOperation.vertexData.vertexBufferBinding.SetBinding( 1, this.wBuffer ); } // Use same vertex start as input renderOperation.vertexData.vertexStart = vertexData.vertexStart; if ( isLightCap ) { // Use original vertex count, no extrusion renderOperation.vertexData.vertexCount = vertexData.vertexCount; } else { // Vertex count must take into account the doubling of the buffer, // because second half of the buffer is the extruded copy renderOperation.vertexData.vertexCount = vertexData.vertexCount*2; if ( createSeparateLightCap ) { // Create child light cap lightCap = new EntityShadowRenderable( parent, indexBuffer, vertexData, false, subEntity, true ); } } }
protected virtual void ReadGeometryVertexElement( BinaryReader reader, VertexData data ) { var source = ReadShort( reader ); var type = (VertexElementType)ReadUShort( reader ); var semantic = (VertexElementSemantic)ReadUShort( reader ); var offset = ReadShort( reader ); var index = ReadShort( reader ); // add the element to the declaration for the current vertex data data.vertexDeclaration.AddElement( source, offset, type, semantic, index ); if ( type == VertexElementType.Color ) { LogManager.Instance.Write( "Warning: VET_COLOUR element type is deprecated, you should use " + "one of the more specific types to indicate the byte order. " + "Use OgreMeshUpgrade on {0} as soon as possible. ", this.mesh.Name ); } }
/// <summary> /// /// </summary> /// <param name="disposeManagedResources"></param> protected override void dispose( bool disposeManagedResources ) { if ( !IsDisposed ) { if ( disposeManagedResources ) { // Dispose managed resources. if ( lightCap != null ) { if ( !lightCap.IsDisposed ) { lightCap.Dispose(); } lightCap = null; } if ( this.wBuffer != null ) { if ( !this.wBuffer.IsDisposed ) { this.wBuffer.Dispose(); } this.wBuffer = null; } if ( this.positionBuffer != null ) { if ( !this.positionBuffer.IsDisposed ) { this.positionBuffer.Dispose(); } this.positionBuffer = null; } if ( this.subEntity != null ) { if ( !this.subEntity.IsDisposed ) { this.subEntity.Dispose(); } this.subEntity = null; } if ( this.currentVertexData != null ) { if ( !this.currentVertexData.IsDisposed ) { this.currentVertexData.Dispose(); } this.currentVertexData = null; } } // There are no unmanaged resources to release, but // if we add them, they need to be released here. } // If it is available, make the call to the // base class's Dispose(Boolean) method base.dispose( disposeManagedResources ); }
protected virtual void ReadGeometryVertexBuffer( BinaryReader reader, VertexData data ) { // Index to bind this buffer to var bindIdx = ReadShort( reader ); // Per-vertex size, must agree with declaration at this index var vertexSize = ReadShort( reader ); // check for vertex data header var chunkID = ReadChunk( reader ); if ( chunkID != MeshChunkID.GeometryVertexBufferData ) { throw new AxiomException( "Can't find vertex buffer data area!" ); } // check that vertex size agrees if ( data.vertexDeclaration.GetVertexSize( bindIdx ) != vertexSize ) { throw new AxiomException( "Vertex buffer size does not agree with vertex declaration!" ); } // create/populate vertex buffer var buffer = HardwareBufferManager.Instance.CreateVertexBuffer( data.vertexDeclaration.Clone( bindIdx ), data.vertexCount, this.mesh.VertexBufferUsage, this.mesh.UseVertexShadowBuffer ); var bufferPtr = buffer.Lock( BufferLocking.Discard ); ReadBytes( reader, data.vertexCount*vertexSize, bufferPtr ); buffer.Unlock(); // set binding data.vertexBufferBinding.SetBinding( bindIdx, buffer ); }
/// <summary> /// Internal method - given vertex data which could be from the Mesh or /// any SubMesh, finds the corresponding SubEntity. /// </summary> /// <param name="original"></param> /// <returns></returns> protected SubEntity FindSubEntityForVertexData( VertexData original ) { if ( original == this.mesh.SharedVertexData ) { return null; } foreach ( var subEnt in this.subEntityList ) { if ( original == subEnt.SubMesh.vertexData ) { return subEnt; } } // none found return null; }
protected override void ReadGeometry( BinaryReader reader, VertexData data ) { short texCoordSet = 0; short bindIdx = 0; data.vertexStart = 0; data.vertexCount = ReadInt( reader ); ReadGeometryPositions( bindIdx++, reader, data ); if ( !IsEOF( reader ) ) { // check out the next chunk var chunkID = ReadChunk( reader ); // keep going as long as we have more optional buffer chunks while ( !IsEOF( reader ) && ( chunkID == MeshChunkID.GeometryNormals || chunkID == MeshChunkID.GeometryColors || chunkID == MeshChunkID.GeometryTexCoords ) ) { switch ( chunkID ) { case MeshChunkID.GeometryNormals: ReadGeometryNormals( bindIdx++, reader, data ); break; case MeshChunkID.GeometryColors: ReadGeometryColors( bindIdx++, reader, data ); break; case MeshChunkID.GeometryTexCoords: ReadGeometryTexCoords( bindIdx++, reader, data, texCoordSet++ ); break; } // switch // read the next chunk if ( !IsEOF( reader ) ) { chunkID = ReadChunk( reader ); } } // while if ( !IsEOF( reader ) ) { // skip back so the continuation of the calling loop can look at the next chunk // since we already read past it Seek( reader, -ChunkOverheadSize ); } } }
/// <summary> /// Add a set of vertex geometry data to the edge builder. /// </summary> /// <remarks> /// You must add at least one set of vertex data to the builder before invoking the /// <see name="Build"/> method. /// </remarks> /// <param name="vertexData">Vertex data to consider for edge detection.</param> public void AddVertexData( VertexData vertexData ) { vertexDataList.Add( vertexData ); }
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); }