/// <summary> /// Sets all properties of the given token so that it describes the current position /// within this instance. /// </summary> public BatchToken FillToken(BatchToken token) { token.BatchID = _cacheToken.BatchID; token.VertexID = _cacheToken.VertexID; token.IndexID = _cacheToken.IndexID; return(token); }
/// <summary> /// Restores the render state that was last pushed to the stack. If this changes /// blend mode, clipping rectangle, render target or culling, the current batch /// will be drawn right away. /// /// <para>If you pass a BatchToken, it will be updated to point to the current location within /// the render cache. That way, you can later reference this location to render a subset of /// the cache.</para> /// </summary> /// <exception cref="IndexOutOfRangeException">if the state stack is empty</exception> public void PopState(BatchToken token = null) { if (_stateStackPos < 0) { throw new IndexOutOfRangeException("Cannot pop empty state stack"); } _state.CopyFrom(_stateStack[_stateStackPos]); // -> might cause 'finishMeshBatch' _stateStackPos--; if (token != null) { _batchProcessor.FillToken(token); } }
// state stack /// <summary> /// Pushes the current render state to a stack from which it can be restored later. /// /// <para>If you pass a BatchToken, it will be updated to point to the current location within /// the render cache. That way, you can later reference this location to render a subset of /// the cache.</para> /// </summary> public void PushState(BatchToken token = null) { _stateStackPos++; if (_stateStackLength < _stateStackPos + 1) { _stateStackLength++; _stateStack.Add(new RenderState()); } if (token != null) { _batchProcessor.FillToken(token); } _stateStack[_stateStackPos].CopyFrom(_state); }
/// <summary> /// Draws all meshes from the render cache between <code>startToken</code> and /// (but not including) <code>endToken</code>. The render cache contains all meshes /// rendered in the previous frame. /// </summary> public void DrawFromCache(BatchToken startToken, BatchToken endToken) { MeshSubset subset = SMeshSubset; if (!startToken.Equals(endToken)) { PushState(); for (int i = startToken.BatchID; i <= endToken.BatchID; ++i) { var meshBatch = _batchProcessorPrev.GetBatchAt(i); subset.SetTo(); // resets subset if (i == startToken.BatchID) { subset.VertexId = startToken.VertexID; subset.IndexId = startToken.IndexID; subset.NumVertices = meshBatch.NumVertices - subset.VertexId; subset.NumIndices = meshBatch.NumIndices - subset.IndexId; } if (i == endToken.BatchID) { subset.NumVertices = endToken.VertexID - subset.VertexId; subset.NumIndices = endToken.IndexID - subset.IndexId; } if (subset.NumVertices != 0) { _state.Alpha = 1.0f; _state.BlendMode = meshBatch.BlendMode; _batchProcessor.AddMesh(meshBatch, _state, subset, true); } } PopState(); } }
/// <summary> /// Creates a new batch processor. /// </summary> public BatchProcessor() { _batches = new List <MeshBatch>(); _batchPool = new BatchPool(); _cacheToken = new BatchToken(); }