Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drawToBitmapData using a scale #525

Closed
divillysausages opened this issue Apr 15, 2014 · 6 comments
Closed

drawToBitmapData using a scale #525

divillysausages opened this issue Apr 15, 2014 · 6 comments

Comments

@divillysausages
Copy link

As mentioned in issue #517, when drawing the stage with a scale other than 1.0, the position of objects are offset on mobile (testing using an iPad mini & Galaxy S3).

Basically as scale approached 0.5, objects would be offset by the screen height; lower than 0.5 and they'd be off the screen.

2 things would fix it:

1) Applying an offset when calling setOrthographicProjection()
This needs to be separated between desktop (only tested on windows though) and mobile (maybe using SystemUtil?).

When setting up the RenderSupport:

var scale:Number    = 0.5;
var w:Number        = Starling.current.stage.stageWidth;
var h:Number        = Starling.current.stage.stageHeight;
var bmd:BitmapData  = new BitmapData( w * scale, h * scale, false, 0x00000000 );

// create our render support
var rs:RenderSupport = new RenderSupport;
if( SystemUtil.isDesktop )
    rs.setOrthographicProjection( 0.0, 0.0, w * 1.0 / scale, h * 1.0 / scale);
else
    rs.setOrthographicProjection( 0.0, ( h - ( h * 1.0 / scale ) ), w * 1.0 / scale, h * 1.0 / scale);

The w * 1.0 / scale and h * 1.0 / scale is there to fix the clipRect problem mentioned in #517

The y offset for the orthographic projection is needed, as if the RenderSupport.renderTarget is null, it'll render in the back buffer. Why it's necessary to correct the offset only for mobile, and only for the y axis is beyond me 😄

2) Use a renderTarget for the RenderSupport:
If the renderTarget is null, then it's rendered into the back buffer, so you can specify an empty target instead:

var scale:Number    = 0.5;
var w:Number        = Starling.current.stage.stageWidth;
var h:Number        = Starling.current.stage.stageHeight;
var bmd:BitmapData  = new BitmapData( w * scale, h * scale, false, 0x00000000 );

// create our render support
var rs:RenderSupport    = new RenderSupport;
rs.renderTarget         = new RenderTexture( w * scale, h * scale, false, 0 );
rs.setOrthographicProjection( 0.0, 0.0, w, h );

If we use a RenderTexture, then we don't have to set the width and height fix for the clipRects in the setOrthographicProjection call, though I'm not sure it's possible to get the resulting texture as a BitmapData? Only the Context3D class seems to have a drawToBitmapData() method.


In an somewhat related note, I found that calling Starling.current.context.present() at the end of all this to actually cause a flicker rather than prevent one, when using the first fix, as, because you're rendering to the back buffer, it'll show one frame (the one you just rendered) with the scale messed up.

You can either omit the call, or re-render the stage at scale 1.0. Something like this:

...
Starling.current.context.drawToBitmapData( bmd );

// re-render at 100% scale to avoid a screen flicker
rs.setOrthographicProjection( 0, 0.0, w, h );
rs.clear( this.stage.color );
stage.render( rs, 1.0 );
rs.finishQuadBatch();

Starling.current.context.present(); // required on some platforms to avoid flickering

This obviously has a downside of rendering twice just to get a screenshot.

@PrimaryFeather
Copy link
Contributor

Sorry for the delay!

As you expected, using a RenderTexture is unfortunately not possible, because we cannot read the bitmap data back from a texture. 😒

One more question, to see if I understand this correctly: if you do the same on Desktop, also with a non-zero scale factor, then it does work, right?

If that's the case, this definitely looks like a bug in stage3D to me. I think the best way to continue would be to create a small sample using just plain stage3D code, and to create a bug report on Adobe's bug tracker.

Could you try to create such a sample? That would be a huge help for me.
Here is a simple, minimal sample class that could be used as a starting point:
http://pastebin.com/MQyVALdb

You probably just need to add the context.drawToBitmapData() call (e.g. on mouse click) and compare what happens on mobile vs. Desktop. There must be some way to reproduce the difference without Starling.

Just ping me if you need any help, or if you're not successful with the test.
Thanks a lot in advance!

@divillysausages
Copy link
Author

Yep, on desktop there's no need for an offset. I'll try and create a test project sans Starling; I've not really touched raw Stage3D. It'll probably be after the weekend; Ludum Dare and all 😉

@PrimaryFeather
Copy link
Contributor

Thanks, I really appreciate your help! 😄

@vincentvictoria
Copy link

Just to let people know, the bug is still persistent in AIR SDK 14 - 7/8/2014 Release. 😒

I implemented the workaround as divillysausages suggested - checking SystemUtil.isDesktop & applying y offset - and it works fine on devices including iPod touch 5th generation(iOS 7), iPad 3(iOS 6) and LG Optimus G Pro (4.1.1).

Thanks divillysausages! 😄

@divillysausages
Copy link
Author

Yeah, I really need to get off my ass and write the test class for Daniel; it's been on my back burner for ages now :)

@PrimaryFeather
Copy link
Contributor

Since this sounds more like a stage3D issue, and since there hasn't been any progress for a while, I'm now closing this issue. Feel free to open it up again if you want to continue this discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants