private static void Render() { if (sprites.Count == 0) { return; } Axiom.Graphics.RenderSystem rs = Root.Instance.RenderSystem; var thisChunk = new Chunk(); var chunks = new List <Chunk>(); int newSize; newSize = sprites.Count * 6; if (newSize < MinimalHardwareBufferSize) { newSize = MinimalHardwareBufferSize; } // grow hardware buffer if needed if (hardwareBuffer == null || hardwareBuffer.VertexCount < newSize) { if (hardwareBuffer != null) { HardwareBuffer_Destroy(); } HardwareBuffer_Create(newSize); } // write quads to the hardware buffer, and remember chunks unsafe { var buffer = (Vertex *)hardwareBuffer.Lock(BufferLocking.Discard).Pin(); LinkedListNode <Sprite> node = sprites.First; Sprite currSpr; while (node != null) { currSpr = node.Value; thisChunk.Alpha = currSpr.Alpha; thisChunk.TexHandle = currSpr.TexHandle; for (int i = 0; i < 6; i++) { *buffer++ = new Vertex(currSpr.Pos[i], currSpr.UV[i]); } thisChunk.VertexCount += 6; node = node.Next; if (node == null || thisChunk.TexHandle != node.Value.TexHandle || thisChunk.Alpha != node.Value.Alpha) { chunks.Add(thisChunk); thisChunk.VertexCount = 0; } } } hardwareBuffer.Unlock(); // set up... RenderSystem_Setup(); // do the real render! // do the real render! Texture tp = null; renderOp.vertexData.vertexStart = 0; foreach (Chunk currChunk in chunks) { renderOp.vertexData.vertexCount = currChunk.VertexCount; tp = (Texture)TextureManager.Instance.GetByHandle(currChunk.TexHandle); rs.SetTexture(0, true, tp.Name); rs.SetTextureUnitFiltering(0, FilterOptions.Linear, FilterOptions.Linear, FilterOptions.Point); // set alpha var alphaBlendMode = new LayerBlendModeEx(); alphaBlendMode.alphaArg1 = 0; alphaBlendMode.alphaArg2 = currChunk.Alpha; alphaBlendMode.source1 = LayerBlendSource.Texture; alphaBlendMode.source2 = LayerBlendSource.Manual; alphaBlendMode.blendType = LayerBlendType.Alpha; alphaBlendMode.operation = LayerBlendOperationEx.Modulate; alphaBlendMode.blendFactor = currChunk.Alpha; rs.SetTextureBlendMode(0, alphaBlendMode); rs.Render(renderOp); renderOp.vertexData.vertexStart += currChunk.VertexCount; } if (tp != null) { tp.Dispose(); } // sprites go home! sprites.Clear(); }
public void Render(RenderSystem targetRenderSystem) { ((Axiom.SceneManagers.Multiverse.SceneManager)TerrainManager.Instance.SceneManager).SetTreeRenderPass(billboardMaterial.GetBestTechnique(0).GetPass(0), this); string lastTextureName = null; foreach (TreeBillboardRenderOp op in renderOps) { // set the texture if necessary if (op.textureName != lastTextureName) { targetRenderSystem.SetTexture(0, true, op.textureName); lastTextureName = op.textureName; } targetRenderSystem.SetAlphaRejectSettings(CompareFunction.Greater, (byte)op.alpha); targetRenderSystem.Render(op.renderOp); } }