/// <summary> /// removes stream from buffer /// </summary> /// <param name="stream">stream to remove</param> public void RemoveBuffer(IGraphicsStream stream) { object key = getKey(stream); if (!table.Contains(key)) { throw new GraphicsException("can't remove stream!"); } // get list of data chunks ArrayList list = (ArrayList)table[key]; int index = 0; foreach (DataChunk chunk in list) { // if dataChunk with fitting physical buffer is found if (chunk.PhysicalBuffer == stream.PhysicalBuffer) { // remove stream from chunk chunk.Remove(stream); if (chunk.IsEmpty()) { list.RemoveAt(index); chunk.Dispose(); } return; } index++; } }
/// <summary> /// tries to add the graphicsStream to this chunk /// </summary> /// <param name="stream">stram to add</param> /// <returns>true if succeeded otherwise false</returns> public bool Add(IGraphicsStream stream) { // fast rejection if (Available < stream.Size) { return(false); } // test for free slots for (int i = 0; i < FreeSlots.Count; i++) { Slot slot = (Slot)FreeSlots[i]; if (slot.Size >= stream.Size) { // update stream stream.PhysicalBuffer = PhysicalBuffer; stream.Position = slot.Position; // update slot slot.Position += stream.Size; slot.Size -= stream.Size; FreeSlots[i] = slot; if (slot.Size == 0) { FreeSlots.RemoveAt(i); } // update chunk Available -= stream.Size; GraphicsStreams.Add(stream); return(true); } } return(false); }
/// <summary> /// removes stream from dataChunk /// </summary> /// <param name="stream">to remove</param> public void Remove(IGraphicsStream stream) { FreeSlots.Add(new Slot(stream.Position, stream.Size)); GraphicsStreams.Remove(stream); Available += stream.Size; OptimizeSlots(); }
/// <summary> /// constructor /// </summary> /// <param name="physicalBuffer"></param> /// <param name="graphicsStream"></param> public DataChunk(IPhysicalGraphicsBuffer physicalBuffer, IGraphicsStream graphicsStream) { PhysicalBuffer = physicalBuffer; Available = physicalBuffer.Size - graphicsStream.Size; GraphicsStreams = new ArrayList(); GraphicsStreams.Add(graphicsStream); FreeSlots = new ArrayList( ); FreeSlots.Add(new Slot(graphicsStream.Size, Available)); }
/// <summary> /// create new physical buffer for a given stream /// </summary> /// <param name="stream">to create physical buffer for</param> /// <returns>new physical buffer</returns> protected override IPhysicalGraphicsBuffer CreatePhysicalBuffer(IGraphicsStream stream) { int size = 12000; if (stream.Size > size) { size = stream.Size; } return(Device.Instance.PlugIn.CreateIndexBuffer(stream.Type, size)); }
/// <summary> /// creates new hashtable entry (key, ArrayList) for a given stream format /// </summary> /// <param name="key">key of entry</param> /// <param name="stream">stream to create list for</param> protected void Create(object key, IGraphicsStream stream) { // create new arraylist of DataChunks ArrayList list = new ArrayList(); // add list to table table.Add(key, list); // add dataChunk AddDataChunk(key, stream); }
//--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Methods //--------------------------------------------------------------- /// <summary> /// returns physical buffer /// </summary> /// <param name="stream">to return physical buffer fpr</param> /// <returns>physical buffer</returns> public virtual IPhysicalGraphicsBuffer GetBuffer(IGraphicsStream stream) { object key = getKey(stream); if (!table.Contains(key)) { Create(key, stream); } return(Insert(key, stream)); }
/// <summary> /// adds a new DataChunk for the given stream format /// </summary> /// <param name="key">of entry</param> /// <param name="stream">stream to create DataChunk for</param> /// <returns></returns> protected DataChunk AddDataChunk(object key, IGraphicsStream stream) { Log.Spam("Create stream " + stream.ToString()); ArrayList list = table[key] as ArrayList; IPhysicalGraphicsBuffer physical = CreatePhysicalBuffer(stream); DataChunk chunk = new DataChunk(physical); list.Add(chunk); return(chunk); }
/// <summary> /// copies VertexUnit data /// </summary> /// <param name="source">VertexUnit containing source streams</param> /// <param name="sourceIndex">index of source</param> /// <param name="dest">ertexUnit containing destination streams</param> /// <param name="destIndex">index of destination</param> /// <param name="length">number of elements to copy</param> public static void Copy(VertexUnit source, int sourceIndex, VertexUnit dest, int destIndex, int length) { if (source.Format != dest.Format) { throw new GraphicsException("Copy requires to vertexUnits with the same format"); } for (int i = 0; i < source.StreamCount; i++) { IGraphicsStream sourceStream = source[i]; IGraphicsStream destStream = dest[i]; Array.Copy(sourceStream.Data, sourceIndex, destStream.Data, destIndex, length); } }
/// <summary> /// Creates a new <see cref="VertexUnit"/>. /// </summary> /// <param name="format">The <see cref="VertexFormat"/> of the new format.</param> public VertexUnit Clone(VertexFormat format) { VertexUnit unit = new VertexUnit(format, size); for (int i = 0; i < format.Size; i++) { IGraphicsStream stream = unit[i]; if (this.format.Contains(stream.GetType(), format.GetUsageIndex(i))) { IGraphicsStream from = this[stream.GetType(), format.GetUsageIndex(i)]; Array.Copy(from.Data, stream.Data, from.Size); } } return(unit); }
//--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Methods //--------------------------------------------------------------- /// <summary> /// Reserves a new region in the physical buffer and returns the /// used (eventually newly created physical buffer). /// </summary> /// <remarks> /// Currently the <c>GetBuffer</c> method also ensures, that the space /// for all streams of a certain <see cref="VertexUnit"/> is reserved /// at the same time. This is because "older" cards like the Geforce3 and /// Radeon8500 don't support rendering multiple streams starting at a different index. /// </remarks> /// <param name="stream">To return physical buffer for.</param> /// <returns>Physical buffer.</returns> public override IPhysicalGraphicsBuffer GetBuffer(IGraphicsStream stream) { // reserve the space for all streams of the vertexunit at the same time // to ensure, they start with the same index. VertexUnit unit = (stream as IVertexStream).VertexUnit; if (!unit.HasOnlineData()) { for (int i = 0; i < unit.Count; i++) { if (!unit[i].IsSoftware) { unit[i].PhysicalBuffer = base.GetBuffer(unit[i]); } } return(stream.PhysicalBuffer); } return(null); }
/// <summary> /// insert stream into ArrayList of DataChunks (or append) /// </summary> /// <param name="key">key of entry</param> /// <param name="stream">stream to add</param> /// <returns>used physical buffer</returns> protected IPhysicalGraphicsBuffer Insert(object key, IGraphicsStream stream) { ArrayList list = (ArrayList)table[key]; DataChunk chunk; for (int i = 0; i < list.Count; i++) { chunk = (DataChunk)list[i]; if (chunk.Add(stream)) { list[i] = chunk; return(chunk.PhysicalBuffer); } } chunk = AddDataChunk(key, stream); if (chunk.Add(stream)) { list[list.Count - 1] = chunk; } return(chunk.PhysicalBuffer); }
/// <summary> /// Prepares a mesh for being used as a shadow Volume. /// </summary> /// <remarks>In fact the geometry is doubled and an FloatStream is added that contains 1.0f for /// vertices that are used for the near cap and 0.0f for the far cap.</remarks> /// <param name="mesh">The mesh to prepare.</param> public static void PrepareMesh(Mesh mesh) { SubSets subSets = mesh.SubSets; for (int iSubSet = 0; iSubSet < subSets.Count; iSubSet++) { VertexUnit vu = subSets[iSubSet].VertexUnit; IGraphicsStream[] streams = new IGraphicsStream[vu.StreamCount + 1]; for (int iStream = 0; iStream < vu.StreamCount; iStream++) { IGraphicsStream fromStream = vu[iStream]; IGraphicsStream toStream = null; using (Purple.Profiling.Profiler.Instance.Sample("Clone")) { toStream = fromStream.Clone(); } using (Purple.Profiling.Profiler.Instance.Sample("Resize")) { toStream.Resize(fromStream.Size * 2); } using (Purple.Profiling.Profiler.Instance.Sample("CopyTo")) { fromStream.Data.CopyTo(toStream.Data, fromStream.Size); } streams[iStream] = toStream; } using (Purple.Profiling.Profiler.Instance.Sample("FloatStream")) { FloatStream floatStream = new FloatStream(vu.Size * 2); for (int i = 0; i < vu.Size; i++) { floatStream[i] = 1.0f; floatStream[i + vu.Size] = 0.0f; } streams[vu.StreamCount] = floatStream; } vu = new VertexUnit(streams); subSets[iSubSet].VertexUnit = vu; } }
/// <summary> /// returns the hashtable key for a given stream format /// </summary> /// <param name="stream">stream to get key for</param> /// <returns>key object</returns> protected abstract object getKey(IGraphicsStream stream);
//--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Methods //--------------------------------------------------------------- /// <summary> /// returns the hashtable key for a given stream format /// </summary> /// <param name="stream">stream to get key for</param> /// <returns>key object</returns> protected override object getKey(IGraphicsStream stream) { return(stream.Type); }
/// <summary> /// create new physical buffer for a given stream /// </summary> /// <param name="stream">to create physical buffer for</param> /// <returns>new physical buffer</returns> protected abstract IPhysicalGraphicsBuffer CreatePhysicalBuffer(IGraphicsStream stream);
/// <summary> /// returns the hashtable key for a given stream format /// </summary> /// <param name="stream">stream to get key for</param> /// <returns>key object</returns> protected override object getKey(IGraphicsStream stream) { IVertexStream vertexStream = (IVertexStream)stream; return(new Key(vertexStream.VertexUnit.VertexDeclaration, vertexStream.VertexElement.Stream)); }
/// <summary> /// Initializes a new instance of the <see cref="T:PdfContent" /> class. /// </summary> /// <param name="gStream">The g stream.</param> internal PdfContent(IGraphicsStream gStream) { this.graphics = new PdfGraphics(base.Psw, gStream); }
/// <summary> /// copies the data of the stream to this stream /// </summary> /// <param name="stream">stream to take data from</param> public void Copy(IGraphicsStream stream) { System.Diagnostics.Debug.Assert(stream.Size <= this.Size); Array.Copy(stream.Data, this.Data, stream.Size); }