StarlingGraphics / Starling-Extension-Graphics

flash.display.Graphics style extension for the Starling Flash GPU rendering framework
https://github.com/StarlingGraphics/Starling-Extension-Graphics/wiki
MIT License
285 stars 88 forks source link

texturing a line #72

Closed AndreAhmed closed 10 years ago

AndreAhmed commented 10 years ago

Hi All,

I'm trying to a texture a single line, with a starling texture, but its not correct at all, the 2D Texture displays on the screen, and not interpolated over the line.

This is how I draw it:

               var lineShape:Shape = new Shape();
        lineShape.graphics.beginTextureFill(tex);

        lineShape.graphics.lineStyle(1, m_color);
        lineShape.graphics.moveTo(m_lineCoords[0].x, m_lineCoords[0].y);

        //lineShape.filter = blur;

        for (var i:uint = 1; i < m_lineCoords.length; i++)
        {
            lineShape.graphics.lineTo(m_lineCoords[i].x, m_lineCoords[i].y);
        }
        lineShape.graphics.endFill();
jonathanrpace commented 10 years ago

'beginTextureFill' will fill the area inside the line with a texture (much like beginFill fills the area with a flat colour).

Use lineTexture() instead. There's an example that does this here

https://github.com/StarlingGraphics/Starling-Extension-Graphics/blob/master/examples/05_Flowing_Lava_Example/src/FlowingLavaExample.as

AndreAhmed commented 10 years ago

Sorry but a general question to the flowinglava example: is it possible to to interpolate the texture, so that some parts of it appears, as a water flow or lava flow ? So the idea is to tweening the texture width,height, and flow like the flowing lava I have attached a picture for more info.

Thanks for the api.

IonSwitz commented 10 years ago

If you want to draw such a line with various thicknesses, you should check out the GraphicsEx API, which has such functionality. But, remember, if you continously change the thickness of the line you draw, the geometry has to be regenerated for each such change, and that might be very expensive for you.

AndreAhmed commented 10 years ago

No, I don't want to change the thickness of the line. I just want to change the texture of the line.

consider a line, a line with alpha 0, completely hidden, I want as the lava example, the lava flows into the line curve, but not constantly flow like the example. just flow like it is in a pipe one time, as long as the lava moves, the line gets constructed.

IonSwitz commented 10 years ago

That would also mean you have to reconstruct the geometry each frame, I'm afraid.

Maybe something could be done with a vertex/fragment shader, but I don't know how.

If you come up with a solution, feel free to share it, it sounds really cool

jonathanrpace commented 10 years ago

You could render a stroke twice - first layer using water texture (100% alpha), second layer lava (varying alpha).

You can't do this with the graphics API - but you can do it with a 'Stroke' primitive. https://github.com/StarlingGraphics/Starling-Extension-Graphics/blob/master/extension/src/starling/display/graphics/Stroke.as

Take a look at the 'addVertex' function.

This example uses primitives in this 'direct' way, so may prove useful as reference https://github.com/StarlingGraphics/Starling-Extension-Graphics/blob/master/examples/04_Fill_Stroke_Example/src/FillStrokeExample.as

AndreAhmed commented 10 years ago

4 This is a picture of what I really want to achieve.

The line will be completely hidden, then at each frame it gets constructed, as it feels like a water in a pipe is flowing. Thanks for the api

jonathanrpace commented 10 years ago

Afraid you're going to have to get your hands dirty with AGAL to achieve that - but certainly possible. You could re-use the vertex shader from the flowing lava example (which gives you the 'flow'), but you'd need a custom fragment shader for blending two textures together in this way.

AndreAhmed commented 10 years ago

Thanks for the reply. But Would you explain more why I need blending, I just want the line to be constructed as a flowing line, in steps, so the line is really 0 transparency, then it starts to get constructed, until the full line has a 100% transparency.

For example in bresenham line algorith, we draw each pixel to construct a line, if we render the pixels at 1pixel/5secs, we will see the line constructed and its like flowing.. I just want to achieve an effect like that :).

jonathanrpace commented 10 years ago

Sorry - I thought you wanted to blend two textures together (water and lava)?.

From your diagram it looks like you're after an alternative way to blend your alpha with the backbuffer.

Using Flash IDE as an example - standard alpha blending works like changing the 'color effect' alpha % for a graphic/movieclip. This intuitively multiplies the alpha of the whole image.

However, if you take an image with an interesting alpha channel (say, some perlin noise), and switch to 'advanced' under color effect, and slowly slide alpha value between -255 and 255 you'll see what I mean.

You could use this 'alpha offset' in a fragment shader to give the illusion bits of your texture 'breaking through'.

As Ion Switz pointed out, reconstructing geometry each frame could be very expensive - trying to achieve the same thing with a fragment shader could be much more GPU friendly.

IonSwitz commented 10 years ago

Then again, if you are doing straight lines, it might not be that expensive. The number of vertices won't be very high.

But you would have to calculate new points to draw to for each frame, add that to the line using the addVertex method described above, and basically addVertex your way forward with your line. I have no idea if it is possible to make that look good, especially with texture coordinates having to be calculated to make the texture stretch smoothly...

AndreAhmed commented 10 years ago

Why should I addVertex at the "rate" of which the line should have the flow effect ?

Is there an easier way for example If i have a line that's already drawn, can I scan and mask it with something to show gradually ?

@jonathanrpace Yea I really want the line and its texture to break through, but I didn't get 100% of your idea, would you show me a pseud-code for the algorithm ?

I'm really confused.

IonSwitz commented 10 years ago

If you wanted the line to grow, with a texture on it, I would recommend trying to do that by continously add points on the line you are drawing so the first frame looks like:

. .

Second frame like:

. . .

And third frame:

. . . .

and so on.

Then the line with the texture will be drawn in this growing fashion, with the vertex points making the line longer for each frame.

But maybe I don't understand what you desire to achieve

jonathanrpace commented 10 years ago

Standard alpha blend outputAlpha = textureAlpha * multiplier

'Offset' alpha blend outputAlpha = clamp( textureAlpha + offset ) // Where offset is a value between -1 and 1.

AndreAhmed commented 10 years ago

Thanks I will try both ideas, and will show ya the result :)

AndreAhmed commented 10 years ago

is it possible to to draw the shape(a line) to a texture ? like an FBO ?

jonathanrpace commented 10 years ago

In principle, yes. Flash's Context3D class supports texture render targets.

But as Starling is taking care of all this for you, this is a question better suited for the Starling project.