protected override unsafe void OnLoad(EventArgs e) { LoadTex(); var green = new Texture("green.png"); var red = new Texture("red.png"); { batch = new QuadBatch <SpriteProgram, SpriteData, SpriteVertex>(4); batch.Shader.Make(new Vector2(800, 800), new Vector2(338, 338), green, red); batch.AddQuad(new SpriteData(new Rectangle(new Point(0, 0), new Size(200, 200)), new Rectangle(new Point(0, 0), new Size(200, 200)))); batch.AddQuad(new SpriteData(new Rectangle(new Point(300, 0), new Size(200, 200)), new Rectangle(new Point(100, 100), new Size(200, 200)))); batch.UpdateGpu(); } { batch2 = new QuadBatch <SpriteProgram, SpriteData, SpriteVertex>(4); batch2.Shader.Make(new Vector2(800, 800), new Vector2(338, 338), red, green); batch2.AddQuad(new SpriteData(new Rectangle(new Point(0, 300), new Size(200, 200)), new Rectangle(new Point(0, 0), new Size(200, 200)))); batch2.AddQuad(new SpriteData(new Rectangle(new Point(300, 300), new Size(200, 200)), new Rectangle(new Point(100, 100), new Size(200, 200)))); batch2.UpdateGpu(); } watch.Start(); // random final setup { //var x = GLFW.SetMouseButtonCallback; VSync = VSyncMode.Adaptive; GL.FrontFace(FrontFaceDirection.Cw); GL.PolygonMode(MaterialFace.Back, PolygonMode.Line); // make draw with lines if drawing backs //GL.ClearColor(0.0f, 0.0f, 1.0f, 0.0f); // set clear color } int total = 0; for (int currentNumber = 1; currentNumber < 1000; currentNumber++) { int iMod3 = currentNumber % 3; int iMod5 = currentNumber % 5; bool isDivisibleBy3 = iMod3 == 0; bool isDivisibleBy5 = iMod5 == 0; if (isDivisibleBy3 || isDivisibleBy5) { total += currentNumber; } } base.OnLoad(e); transform = Matrix4.CreateTranslation(new Vector3(100, 10, 0)); }
/// <summary> /// Adds a quad or image to the current batch of unrendered quads. If there is a state change, /// all previous quads are rendered at once, and the batch is reset. Note that the values for /// alpha and blend mode are taken from the current render state, not the quad. /// </summary> public void BatchQuad(Quad quad) { float alpha = _stateStackTop.Alpha; uint blendMode = _stateStackTop.BlendMode; Matrix modelViewMatrix = _stateStackTop.ModelViewMatrix; if (_quadBatchTop.IsStateChange(quad.Tinted, quad.Texture, alpha, quad.PremultipliedAlpha, blendMode, 1)) { FinishQuadBatch(); } _quadBatchTop.AddQuad(quad, alpha, blendMode, modelViewMatrix); }
/// <summary> /// Draws text into a quad batch. /// </summary> public void FillQuadBatch(QuadBatch quadBatch, float width, float height, string text, float size, uint color, HAlign hAlign, VAlign vAlign, bool autoScale, bool kerning) { List <CharLocation> charLocations = ArrangeCharsInArea(width, height, text, size, hAlign, vAlign, autoScale, kerning); _helperImage.Color = color; if (charLocations.Count > MAX_TEXT_CHAR_COUNT) { throw new InvalidDataException(string.Format("Bitmap font text is limited to {0} characters", MAX_TEXT_CHAR_COUNT)); } CharLocation charLocation; for (int i = 0; i < charLocations.Count; i++) { charLocation = charLocations[i]; _helperImage.Texture = charLocation.BitmapChar.Texture; _helperImage.X = charLocation.X; _helperImage.Y = charLocation.Y; _helperImage.ScaleX = _helperImage.ScaleY = charLocation.Scale; _helperImage.ReadjustSize(); quadBatch.AddQuad(_helperImage); } }
private QuadBatch RenderPasses(DisplayObject obj, RenderSupport support, bool intoCache) { Texture cacheTexture = null; Stage stage = obj.Stage; float scale = Resolution; if (stage == null) { throw new InvalidOperationException("Filtered object must be on the stage."); } // the bounds of the object in stage coordinates Rectangle boundsPOT; Rectangle bounds; CalcBounds(obj, stage, scale, !intoCache, out bounds, out boundsPOT); if (bounds.IsEmpty()) { DisposePassTextures(); return(intoCache ? new QuadBatch() : null); } UpdateBuffers(boundsPOT); UpdatePassTextures((int)boundsPOT.Width, (int)boundsPOT.Height, scale); support.FinishQuadBatch(); support.AddDrawCalls(NumPasses); support.PushState(Matrix.Create(), 1.0f, BlendMode.AUTO); // save original projection matrix and render target _projMatrix.CopyFromMatrix(support.ProjectionMatrix); Texture previousRenderTarget = support.RenderTarget; // use cache? if (intoCache) { cacheTexture = CreateTexture((int)boundsPOT.Width, (int)boundsPOT.Height, scale); } // draw the original object into a texture support.RenderTarget = _passTextures[0]; SparrowSharpApp.Context.ScissorBox = null; // we want the entire texture cleared support.Clear(); support.BlendMode = BlendMode.NORMAL; support.SetupOrthographicProjection(boundsPOT.Left, boundsPOT.Right, boundsPOT.Bottom, boundsPOT.Top); obj.Render(support); support.FinishQuadBatch(); // prepare drawing of actual filter passes support.ApplyBlendMode(true); support.ModelViewMatrix.Identity(); support.PushClipRect(bounds); GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferName); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferName); GL.EnableVertexAttribArray(VertexPosID); GL.VertexAttribPointer(VertexPosID, 2, VertexAttribPointerType.Float, false, Vertex.SIZE, (IntPtr)Vertex.POSITION_OFFSET); GL.EnableVertexAttribArray(TexCoordsID); GL.VertexAttribPointer(TexCoordsID, 2, VertexAttribPointerType.Float, false, Vertex.SIZE, (IntPtr)Vertex.TEXTURE_OFFSET); // draw all passes for (int i = 0; i < NumPasses; ++i) { if (i < NumPasses - 1) { // intermediate pass // draw into pass texture support.RenderTarget = PassTextureForPass(i + 1); support.Clear(); } else { // final pass if (intoCache) { // draw into cache texture support.RenderTarget = cacheTexture; support.Clear(); } else { // draw into back buffer, at original (stage) coordinates support.RenderTarget = previousRenderTarget; support.ProjectionMatrix = _projMatrix; support.ModelViewMatrix.Translate(OffsetX, OffsetY); support.BlendMode = obj.BlendMode; support.ApplyBlendMode(true); } } Texture passTexture = PassTextureForPass(i); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, passTexture.Name); ActivateWithPass(i, passTexture, support.MvpMatrix); GL.DrawElements(BeginMode.Triangles, 6, DrawElementsType.UnsignedShort, IntPtr.Zero); DeactivateWithPass(i, passTexture); } GL.DisableVertexAttribArray(VertexPosID); GL.DisableVertexAttribArray(TexCoordsID); support.PopState(); support.PopClipRect(); QuadBatch cache = null; if (intoCache) { // restore support settings support.RenderTarget = previousRenderTarget; support.ProjectionMatrix = _projMatrix; // Create an image containing the cache. To have a display object that contains // the filter output in object coordinates, we wrap it in a QuadBatch: that way, // we can modify it with a transformation matrix. cache = new QuadBatch(); Image image = new Image(cacheTexture); Matrix matrix = stage.TransformationMatrixToSpace(obj); // Note: the next line was originally: // matrix.Translate (bounds.X + OffsetX, bounds.Y + OffsetY); // this seems like a sparrow-s bug; fix is from Starling matrix.PrependTranslation(bounds.X + OffsetX, bounds.Top + OffsetY); cache.AddQuad(image, 1.0f, BlendMode.AUTO, matrix); } return(cache); }